Skip to content

Commit

Permalink
Add missing APIs to contract customization (#71797)
Browse files Browse the repository at this point in the history
* Add missing APIs to contract customization

* Address feedback
  • Loading branch information
eiriktsarpalis authored Jul 8, 2022
1 parent 65e922c commit 2f7fdb9
Show file tree
Hide file tree
Showing 16 changed files with 642 additions and 50 deletions.
10 changes: 10 additions & 0 deletions src/libraries/System.Text.Json/ref/System.Text.Json.cs
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,9 @@ public JsonSerializerOptions(System.Text.Json.JsonSerializerOptions options) { }
[System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Getting a converter for a type may require reflection which depends on runtime code generation.")]
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Getting a converter for a type may require reflection which depends on unreferenced code.")]
public System.Text.Json.Serialization.JsonConverter GetConverter(System.Type typeToConvert) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Getting a metadata for a type may require reflection which depends on unreferenced code.")]
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Getting a metadata for a type may require reflection which depends on runtime code generation.")]
public System.Text.Json.Serialization.Metadata.JsonTypeInfo GetTypeInfo(System.Type type) { throw null; }
}
public enum JsonTokenType : byte
{
Expand Down Expand Up @@ -1148,11 +1151,14 @@ public JsonPolymorphismOptions() { }
public abstract partial class JsonPropertyInfo
{
internal JsonPropertyInfo() { }
public System.Reflection.ICustomAttributeProvider? AttributeProvider { get { throw null; } set { } }
public System.Text.Json.Serialization.JsonConverter? CustomConverter { get { throw null; } set { } }
public System.Func<object, object?>? Get { get { throw null; } set { } }
public bool IsExtensionData { get { throw null; } set { } }
public string Name { get { throw null; } set { } }
public System.Text.Json.Serialization.JsonNumberHandling? NumberHandling { get { throw null; } set { } }
public System.Text.Json.JsonSerializerOptions Options { get { throw null; } }
public int Order { get { throw null; } set { } }
public System.Type PropertyType { get { throw null; } }
public System.Action<object, object?>? Set { get { throw null; } set { } }
public System.Func<object, object?, bool>? ShouldSerialize { get { throw null; } set { } }
Expand Down Expand Up @@ -1183,6 +1189,10 @@ internal JsonTypeInfo() { }
public System.Func<object>? CreateObject { get { throw null; } set { } }
public System.Text.Json.Serialization.Metadata.JsonTypeInfoKind Kind { get { throw null; } }
public System.Text.Json.Serialization.JsonNumberHandling? NumberHandling { get { throw null; } set { } }
public System.Action<object>? OnDeserialized { get { throw null; } set { } }
public System.Action<object>? OnDeserializing { get { throw null; } set { } }
public System.Action<object>? OnSerialized { get { throw null; } set { } }
public System.Action<object>? OnSerializing { get { throw null; } set { } }
public System.Text.Json.JsonSerializerOptions Options { get { throw null; } }
public System.Text.Json.Serialization.Metadata.JsonPolymorphismOptions? PolymorphismOptions { get { throw null; } set { } }
public System.Collections.Generic.IList<System.Text.Json.Serialization.Metadata.JsonPropertyInfo> Properties { get { throw null; } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace System.Text.Json.Serialization
/// </summary>
internal abstract class ConfigurationList<TItem> : IList<TItem>
{
private readonly List<TItem> _list;
protected readonly List<TItem> _list;

public ConfigurationList(IList<TItem>? source = null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ private static JsonTypeInfo GetTypeInfo(JsonSerializerOptions? options, Type run
options ??= JsonSerializerOptions.Default;
options.InitializeForReflectionSerializer();

return options.GetJsonTypeInfoForRootType(runtimeType);
return options.GetTypeInfoForRootType(runtimeType);
}

private static JsonTypeInfo GetTypeInfo(JsonSerializerContext context, Type type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,55 @@ public sealed partial class JsonSerializerOptions
// Simple LRU cache for the public (de)serialize entry points that avoid some lookups in _cachingContext.
private volatile JsonTypeInfo? _lastTypeInfo;

/// <summary>
/// Gets the <see cref="JsonTypeInfo"/> contract metadata resolved by the current <see cref="JsonSerializerOptions"/> instance.
/// </summary>
/// <param name="type">The type to resolve contract metadata for.</param>
/// <returns>The contract metadata resolved for <paramref name="type"/>.</returns>
/// <remarks>
/// Returned metadata can be downcast to <see cref="JsonTypeInfo{T}"/> and used with the relevant <see cref="JsonSerializer"/> overloads.
///
/// If the <see cref="JsonSerializerOptions"/> instance is locked for modification, the method will return a cached instance for the metadata.
/// </remarks>
[RequiresUnreferencedCode("Getting a metadata for a type may require reflection which depends on unreferenced code.")]
[RequiresDynamicCode("Getting a metadata for a type may require reflection which depends on runtime code generation.")]
public JsonTypeInfo GetTypeInfo(Type type)
{
if (type is null)
{
ThrowHelper.ThrowArgumentNullException(nameof(type));
}

if (JsonTypeInfo.IsInvalidForSerialization(type))
{
ThrowHelper.ThrowArgumentException_CannotSerializeInvalidType(nameof(type), type, null, null);
}

_typeInfoResolver ??= DefaultJsonTypeInfoResolver.RootDefaultInstance();

JsonTypeInfo? typeInfo;
if (IsLockedInstance)
{
typeInfo = GetCachingContext()?.GetOrAddJsonTypeInfo(type);
typeInfo?.EnsureConfigured();
}
else
{
typeInfo = GetTypeInfoNoCaching(type);
}

if (typeInfo is null)
{
ThrowHelper.ThrowNotSupportedException_NoMetadataForType(type);
}

return typeInfo;
}

/// <summary>
/// This method returns configured non-null JsonTypeInfo
/// </summary>
internal JsonTypeInfo GetJsonTypeInfoCached(Type type)
internal JsonTypeInfo GetTypeInfoCached(Type type)
{
JsonTypeInfo? typeInfo = null;

Expand All @@ -45,7 +90,7 @@ internal JsonTypeInfo GetJsonTypeInfoCached(Type type)
return typeInfo;
}

internal bool TryGetJsonTypeInfoCached(Type type, [NotNullWhen(true)] out JsonTypeInfo? typeInfo)
internal bool TryGetTypeInfoCached(Type type, [NotNullWhen(true)] out JsonTypeInfo? typeInfo)
{
if (_cachingContext == null)
{
Expand All @@ -61,13 +106,13 @@ internal bool TryGetJsonTypeInfoCached(Type type, [NotNullWhen(true)] out JsonTy
/// This has an LRU cache that is intended only for public API calls that specify the root type.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal JsonTypeInfo GetJsonTypeInfoForRootType(Type type)
internal JsonTypeInfo GetTypeInfoForRootType(Type type)
{
JsonTypeInfo? jsonTypeInfo = _lastTypeInfo;

if (jsonTypeInfo?.Type != type)
{
jsonTypeInfo = GetJsonTypeInfoCached(type);
jsonTypeInfo = GetTypeInfoCached(type);
_lastTypeInfo = jsonTypeInfo;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ internal static JsonConverter GetConverterForMember(
JsonConverterAttribute? converterAttribute = memberInfo.GetUniqueCustomAttribute<JsonConverterAttribute>(inherit: false);
customConverter = converterAttribute is null ? null : GetConverterFromAttribute(converterAttribute, typeToConvert, memberInfo, options);

return options.TryGetJsonTypeInfoCached(typeToConvert, out JsonTypeInfo? typeInfo)
return options.TryGetTypeInfoCached(typeToConvert, out JsonTypeInfo? typeInfo)
? typeInfo.Converter
: GetConverterForType(typeToConvert, options);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public JsonTypeInfo JsonTypeInfo
{
Debug.Assert(Options != null);
Debug.Assert(ShouldDeserialize);
return _jsonTypeInfo ??= Options.GetJsonTypeInfoCached(PropertyType);
return _jsonTypeInfo ??= Options.GetTypeInfoCached(PropertyType);
}
set
{
Expand Down Expand Up @@ -97,7 +97,7 @@ public static JsonParameterInfo CreateIgnoredParameterPlaceholder(
Type parameterType = parameterInfo.ParameterType;

DefaultValueHolder holder;
if (matchingProperty.Options.TryGetJsonTypeInfoCached(parameterType, out JsonTypeInfo? typeInfo))
if (matchingProperty.Options.TryGetTypeInfoCached(parameterType, out JsonTypeInfo? typeInfo))
{
holder = typeInfo.DefaultValueHolder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ internal JsonIgnoreCondition? IgnoreCondition
/// Setting a custom attribute provider will have no impact on the contract model,
/// but serves as metadata for downstream contract modifiers.
/// </remarks>
internal ICustomAttributeProvider? AttributeProvider
public ICustomAttributeProvider? AttributeProvider
{
get => _attributeProvider;
set
Expand All @@ -166,7 +166,7 @@ internal ICustomAttributeProvider? AttributeProvider
/// Properties annotated with <see cref="JsonExtensionDataAttribute"/>
/// will appear here when using <see cref="DefaultJsonTypeInfoResolver"/> or <see cref="JsonSerializerContext"/>.
/// </remarks>
internal bool IsExtensionData
public bool IsExtensionData
{
get => _isExtensionDataProperty;
set
Expand Down Expand Up @@ -631,7 +631,7 @@ public string Name
/// When using <see cref="DefaultJsonTypeInfoResolver"/>, properties annotated
/// with the <see cref="JsonPropertyOrderAttribute"/> will map to this value.
/// </remarks>
internal int Order
public int Order
{
get => _order;
set
Expand Down Expand Up @@ -757,7 +757,7 @@ internal JsonTypeInfo JsonTypeInfo
else
{
// GetOrAddJsonTypeInfo already ensures it's configured.
_jsonTypeInfo = Options.GetJsonTypeInfoCached(PropertyType);
_jsonTypeInfo = Options.GetTypeInfoCached(PropertyType);
}

return _jsonTypeInfo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public Func<object>? CreateObject
/// <remarks>
/// Types implementing <see cref="IJsonOnSerializing"/> will map to this callback.
/// </remarks>
internal Action<object>? OnSerializing
public Action<object>? OnSerializing
{
get => _onSerializing;
set
Expand All @@ -75,7 +75,7 @@ internal Action<object>? OnSerializing
/// <remarks>
/// Types implementing <see cref="IJsonOnSerialized"/> will map to this callback.
/// </remarks>
internal Action<object>? OnSerialized
public Action<object>? OnSerialized
{
get => _onSerialized;
set
Expand All @@ -97,7 +97,7 @@ internal Action<object>? OnSerialized
/// <remarks>
/// Types implementing <see cref="IJsonOnSerializing"/> will map to this callback.
/// </remarks>
internal Action<object>? OnDeserializing
public Action<object>? OnDeserializing
{
get => _onDeserializing;
set
Expand All @@ -119,7 +119,7 @@ internal Action<object>? OnDeserializing
/// <remarks>
/// Types implementing <see cref="IJsonOnDeserialized"/> will map to this callback.
/// </remarks>
internal Action<object>? OnDeserialized
public Action<object>? OnDeserialized
{
get => _onDeserialized;
set
Expand Down Expand Up @@ -226,7 +226,7 @@ internal JsonTypeInfo? ElementTypeInfo
{
// GetOrAddJsonTypeInfo already ensures JsonTypeInfo is configured
// also see comment on JsonPropertyInfo.JsonTypeInfo
_elementTypeInfo = Options.GetJsonTypeInfoCached(ElementType);
_elementTypeInfo = Options.GetTypeInfoCached(ElementType);
}
}
else
Expand Down Expand Up @@ -268,7 +268,7 @@ internal JsonTypeInfo? KeyTypeInfo

// GetOrAddJsonTypeInfo already ensures JsonTypeInfo is configured
// also see comment on JsonPropertyInfo.JsonTypeInfo
_keyTypeInfo = Options.GetJsonTypeInfoCached(KeyType);
_keyTypeInfo = Options.GetTypeInfoCached(KeyType);
}
}
else
Expand Down Expand Up @@ -735,7 +735,7 @@ internal void InitializePropertyCache()
ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameConflict(Type, property.Name);
}

isOrderSpecified = property.Order != 0;
isOrderSpecified |= property.Order != 0;
}

if (isOrderSpecified)
Expand Down Expand Up @@ -934,7 +934,7 @@ public JsonPropertyInfoList(JsonTypeInfo jsonTypeInfo)
{
if (jsonTypeInfo.ExtensionDataProperty is not null)
{
Add(jsonTypeInfo.ExtensionDataProperty);
_list.Add(jsonTypeInfo.ExtensionDataProperty);
}

_jsonTypeInfo = jsonTypeInfo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ public DerivedJsonTypeInfo(Type type, object? typeDiscriminator)
public Type DerivedType { get; }
public object? TypeDiscriminator { get; }
public JsonTypeInfo GetJsonTypeInfo(JsonSerializerOptions options)
=> _jsonTypeInfo ??= options.GetJsonTypeInfoCached(DerivedType);
=> _jsonTypeInfo ??= options.GetTypeInfoCached(DerivedType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ private void EnsurePushCapacity()

public void Initialize(Type type, JsonSerializerOptions options, bool supportContinuation)
{
JsonTypeInfo jsonTypeInfo = options.GetJsonTypeInfoForRootType(type);
JsonTypeInfo jsonTypeInfo = options.GetTypeInfoForRootType(type);
Initialize(jsonTypeInfo, supportContinuation);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ private void EnsurePushCapacity()
/// </summary>
public JsonConverter Initialize(Type type, JsonSerializerOptions options, bool supportContinuation, bool supportAsync)
{
JsonTypeInfo jsonTypeInfo = options.GetJsonTypeInfoForRootType(type);
JsonTypeInfo jsonTypeInfo = options.GetTypeInfoForRootType(type);
return Initialize(jsonTypeInfo, supportContinuation, supportAsync);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public JsonConverter InitializePolymorphicReEntry(Type runtimeType, JsonSerializ
// if the current element is the same type as the previous element.
if (PolymorphicJsonTypeInfo?.PropertyType != runtimeType)
{
JsonTypeInfo typeInfo = options.GetJsonTypeInfoCached(runtimeType);
JsonTypeInfo typeInfo = options.GetTypeInfoCached(runtimeType);
PolymorphicJsonTypeInfo = typeInfo.PropertyInfoForTypeInfo;
}

Expand Down
Loading

0 comments on commit 2f7fdb9

Please sign in to comment.