forked from dotnet/extensions
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Expose a schema transformer on AIJsonSchemaCreateOptions. (dotnet#5677)
* Expose a schema transformer on AIJsonSchemaCreateOptions. * Address feedback * Disable caching if a transformer is specified. * Remove `FilterDisallowedKeywords`. * Document caching. * Apply suggestions from code review
- Loading branch information
1 parent
1f47a84
commit 7f2d900
Showing
6 changed files
with
215 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
src/Libraries/Microsoft.Extensions.AI.Abstractions/Utilities/AIJsonSchemaCreateContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Text.Json.Schema; | ||
using System.Text.Json.Serialization.Metadata; | ||
|
||
#pragma warning disable CA1815 // Override equals and operator equals on value types | ||
|
||
namespace Microsoft.Extensions.AI; | ||
|
||
/// <summary> | ||
/// Defines the context in which a JSON schema within a type graph is being generated. | ||
/// </summary> | ||
/// <remarks> | ||
/// This struct is being passed to the user-provided <see cref="AIJsonSchemaCreateOptions.TransformSchemaNode"/> | ||
/// callback by the <see cref="AIJsonUtilities.CreateJsonSchema"/> method and cannot be instantiated directly. | ||
/// </remarks> | ||
public readonly struct AIJsonSchemaCreateContext | ||
{ | ||
private readonly JsonSchemaExporterContext _exporterContext; | ||
|
||
internal AIJsonSchemaCreateContext(JsonSchemaExporterContext exporterContext) | ||
{ | ||
_exporterContext = exporterContext; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the path to the schema document currently being generated. | ||
/// </summary> | ||
public ReadOnlySpan<string> Path => _exporterContext.Path; | ||
|
||
/// <summary> | ||
/// Gets the <see cref="JsonTypeInfo"/> for the type being processed. | ||
/// </summary> | ||
public JsonTypeInfo TypeInfo => _exporterContext.TypeInfo; | ||
|
||
/// <summary> | ||
/// Gets the type info for the polymorphic base type if generated as a derived type. | ||
/// </summary> | ||
public JsonTypeInfo? BaseTypeInfo => _exporterContext.BaseTypeInfo; | ||
|
||
/// <summary> | ||
/// Gets the <see cref="JsonPropertyInfo"/> if the schema is being generated for a property. | ||
/// </summary> | ||
public JsonPropertyInfo? PropertyInfo => _exporterContext.PropertyInfo; | ||
|
||
/// <summary> | ||
/// Gets the declaring type of the property or parameter being processed. | ||
/// </summary> | ||
public Type? DeclaringType => | ||
#if NET9_0_OR_GREATER | ||
_exporterContext.PropertyInfo?.DeclaringType; | ||
#else | ||
_exporterContext.DeclaringType; | ||
#endif | ||
|
||
/// <summary> | ||
/// Gets the <see cref="ICustomAttributeProvider"/> corresponding to the property or field being processed. | ||
/// </summary> | ||
public ICustomAttributeProvider? PropertyAttributeProvider => | ||
#if NET9_0_OR_GREATER | ||
_exporterContext.PropertyInfo?.AttributeProvider; | ||
#else | ||
_exporterContext.PropertyAttributeProvider; | ||
#endif | ||
|
||
/// <summary> | ||
/// Gets the <see cref="System.Reflection.ICustomAttributeProvider"/> of the | ||
/// constructor parameter associated with the accompanying <see cref="PropertyInfo"/>. | ||
/// </summary> | ||
public ICustomAttributeProvider? ParameterAttributeProvider => | ||
#if NET9_0_OR_GREATER | ||
_exporterContext.PropertyInfo?.AssociatedParameter?.AttributeProvider; | ||
#else | ||
_exporterContext.ParameterInfo; | ||
#endif | ||
|
||
/// <summary> | ||
/// Retrieves a custom attribute of a specified type that is applied to the specified schema node context. | ||
/// </summary> | ||
/// <typeparam name="TAttribute">The type of attribute to search for.</typeparam> | ||
/// <param name="inherit">If <see langword="true"/>, specifies to also search the ancestors of the context members for custom attributes.</param> | ||
/// <returns>The first occurrence of <typeparamref name="TAttribute"/> if found, or <see langword="null"/> otherwise.</returns> | ||
/// <remarks> | ||
/// This helper method resolves attributes from context locations in the following order: | ||
/// <list type="number"> | ||
/// <item>Attributes specified on the property of the context, if specified.</item> | ||
/// <item>Attributes specified on the constructor parameter of the context, if specified.</item> | ||
/// <item>Attributes specified on the type of the context.</item> | ||
/// </list> | ||
/// </remarks> | ||
public TAttribute? GetCustomAttribute<TAttribute>(bool inherit = false) | ||
where TAttribute : Attribute | ||
{ | ||
return GetCustomAttr(PropertyAttributeProvider) ?? | ||
GetCustomAttr(ParameterAttributeProvider) ?? | ||
GetCustomAttr(TypeInfo.Type); | ||
|
||
TAttribute? GetCustomAttr(ICustomAttributeProvider? provider) => | ||
(TAttribute?)provider?.GetCustomAttributes(typeof(TAttribute), inherit).FirstOrDefault(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.