/// <summary> /// Creates serialization metadata for a collection. /// </summary> public JsonTypeInfoInternal( JsonSerializerOptions options, JsonCollectionInfoValues <T> collectionInfo, Func <JsonConverter <T> > converterCreator, object?createObjectWithArgs = null, object?addFunc = null) : base(typeof(T), options) { if (collectionInfo == null) { throw new ArgumentNullException(nameof(collectionInfo)); } ConverterStrategy strategy = collectionInfo.KeyInfo == null ? ConverterStrategy.Enumerable : ConverterStrategy.Dictionary; JsonConverter <T> converter = new JsonMetadataServicesConverter <T>(converterCreator, strategy); KeyType = converter.KeyType; ElementType = converter.ElementType; KeyTypeInfo = collectionInfo.KeyInfo; ElementTypeInfo = collectionInfo.ElementInfo ?? throw new ArgumentNullException(nameof(collectionInfo.ElementInfo)); NumberHandling = collectionInfo.NumberHandling; PropertyInfoForTypeInfo = JsonMetadataServices.CreateJsonPropertyInfoForClassInfo(typeof(T), this, converter, options); SerializeHandler = collectionInfo.SerializeHandler; CreateObjectWithArgs = createObjectWithArgs; AddMethodDelegate = addFunc; SetCreateObjectFunc(collectionInfo.ObjectCreator); }
public JsonMetadataServicesConverter(Func <JsonConverter <T> > converterCreator, ConverterStrategy converterStrategy, Type?keyType, Type?elementType) { _converterCreator = converterCreator ?? throw new ArgumentNullException(nameof(converterCreator)); _converterStrategy = converterStrategy; _keyType = keyType; _elementType = elementType; }
internal string GetDebugInfo() { ConverterStrategy strat = PropertyInfoForTypeInfo.ConverterStrategy; string jtiTypeName = GetType().Name; string typeName = Type.FullName !; bool propCacheInitialized = PropertyCache != null; StringBuilder sb = new(); sb.AppendLine("{"); sb.AppendLine($" GetType: {jtiTypeName},"); sb.AppendLine($" Type: {typeName},"); sb.AppendLine($" ConverterStrategy: {strat},"); sb.AppendLine($" IsConfigured: {_isConfigured},"); sb.AppendLine($" HasPropertyCache: {propCacheInitialized},"); if (propCacheInitialized) { sb.AppendLine(" Properties: {"); foreach (var property in PropertyCache !.List) { JsonPropertyInfo pi = property.Value !; sb.AppendLine($" {property.Key}:"); sb.AppendLine($"{pi.GetDebugInfo(indent: 6)},"); } sb.AppendLine(" },"); } sb.AppendLine("}"); return(sb.ToString()); }
internal JsonTypeInfo(Type type, JsonSerializerOptions options, ConverterStrategy converterStrategy) { Type = type; Options = options ?? throw new ArgumentNullException(nameof(options)); // Setting this option is deferred to the initialization methods of the various metadada info types. PropertyInfoForTypeInfo = null !; }
public NullableConverter(JsonConverter <T> elementConverter) { _elementConverter = elementConverter; ConverterStrategy = elementConverter.ConverterStrategy; IsInternalConverterForNumberType = elementConverter.IsInternalConverterForNumberType; // temporary workaround for JsonConverter base constructor needing to access // ConverterStrategy when calculating `CanUseDirectReadOrWrite`. CanUseDirectReadOrWrite = elementConverter.ConverterStrategy == ConverterStrategy.Value; }
internal abstract void Initialize( Type parentClassType, Type declaredPropertyType, ConverterStrategy converterStrategy, MemberInfo?memberInfo, bool isVirtual, JsonConverter converter, JsonIgnoreCondition?ignoreCondition, JsonSerializerOptions options, JsonTypeInfo?jsonTypeInfo = null);
public JsonMetadataServicesConverter(Func<JsonConverter<T>> converterCreator, ConverterStrategy converterStrategy) { if (converterCreator is null) { ThrowHelper.ThrowArgumentNullException(nameof(converterCreator)); } _converterCreator = converterCreator; _converterStrategy = converterStrategy; }
internal static bool SingleValueReadWithReadAhead(ConverterStrategy converterStrategy, ref Utf8JsonReader reader, ref ReadStack state) { bool readAhead = state.ReadAhead && converterStrategy == ConverterStrategy.Value; if (!readAhead) { return(reader.Read()); } return(DoSingleValueReadWithReadAhead(ref reader, ref state)); }
public NullableConverter(JsonConverter <T> elementConverter) { _elementConverter = elementConverter; IsInternalConverterForNumberType = elementConverter.IsInternalConverterForNumberType; // Workaround for the base constructor depending on the (still unset) ConverterStrategy // to derive the CanUseDirectReadOrWrite and RequiresReadAhead values. ConverterStrategy = elementConverter.ConverterStrategy; CanUseDirectReadOrWrite = elementConverter.CanUseDirectReadOrWrite; RequiresReadAhead = elementConverter.RequiresReadAhead; }
public FSharpValueOptionConverter(JsonConverter <TElement> elementConverter) { _elementConverter = elementConverter; _optionValueGetter = FSharpCoreReflectionProxy.Instance.CreateFSharpValueOptionValueGetter <TValueOption, TElement>(); _optionConstructor = FSharpCoreReflectionProxy.Instance.CreateFSharpValueOptionSomeConstructor <TValueOption, TElement>(); // Workaround for the base constructor depending on the (still unset) ConverterStrategy // to derive the CanUseDirectReadOrWrite and RequiresReadAhead values. _converterStrategy = elementConverter.ConverterStrategy; CanUseDirectReadOrWrite = elementConverter.CanUseDirectReadOrWrite; RequiresReadAhead = elementConverter.RequiresReadAhead; }
public FSharpValueOptionConverter(JsonConverter <TElement> elementConverter) { _elementConverter = elementConverter; _optionValueGetter = FSharpCoreReflectionProxy.Instance.CreateFSharpValueOptionValueGetter <TValueOption, TElement>(); _optionConstructor = FSharpCoreReflectionProxy.Instance.CreateFSharpValueOptionSomeConstructor <TValueOption, TElement>(); // temporary workaround for JsonConverter base constructor needing to access // ConverterStrategy when calculating `CanUseDirectReadOrWrite`. // TODO move `CanUseDirectReadOrWrite` from JsonConverter to JsonTypeInfo. _converterStrategy = _elementConverter.ConverterStrategy; CanUseDirectReadOrWrite = _converterStrategy == ConverterStrategy.Value; }
public void Push() { if (_continuationCount == 0) { if (_count == 0) { // Performance optimization: reuse the first stackframe on the first push operation. // NB need to be careful when making writes to Current _before_ the first `Push` // operation is performed. _count = 1; } else { JsonTypeInfo jsonTypeInfo = Current.JsonPropertyInfo?.JsonTypeInfo ?? Current.CtorArgumentState !.JsonParameterInfo !.JsonTypeInfo; JsonNumberHandling?numberHandling = Current.NumberHandling; ConverterStrategy converterStrategy = Current.JsonTypeInfo.PropertyInfoForTypeInfo.ConverterStrategy; EnsurePushCapacity(); _stack[_count - 1] = Current; Current = default; _count++; Current.JsonTypeInfo = jsonTypeInfo; Current.JsonPropertyInfo = jsonTypeInfo.PropertyInfoForTypeInfo; // Allow number handling on property to win over handling on type. Current.NumberHandling = numberHandling ?? Current.JsonPropertyInfo.NumberHandling; } } else { // We are re-entering a continuation, adjust indices accordingly if (_count++ > 0) { _stack[_count - 2] = Current; Current = _stack[_count - 1]; } // check if we are done if (_continuationCount == _count) { _continuationCount = 0; } } SetConstructorArgumentState(); #if DEBUG // Ensure the method is always exercised in debug builds. _ = JsonPath(); #endif }
internal JsonTypeInfo(Type type, JsonSerializerOptions options, ConverterStrategy converterStrategy) { // Options setting for object class types is deferred till initialization. if (converterStrategy != ConverterStrategy.Object && options == null) { throw new ArgumentNullException(nameof(options)); } Options = options !; Type = type; // Setting this option is deferred to the initialization methods of the various metadada info types. PropertyInfoForTypeInfo = null !; }
internal virtual void Initialize( Type parentClassType, Type declaredPropertyType, ConverterStrategy converterStrategy, MemberInfo?memberInfo, bool isVirtual, JsonConverter converter, JsonIgnoreCondition?ignoreCondition, JsonNumberHandling?parentTypeNumberHandling, JsonSerializerOptions options) { Debug.Assert(converter != null); DeclaringType = parentClassType; PropertyType = declaredPropertyType; ConverterStrategy = converterStrategy; MemberInfo = memberInfo; IsVirtual = isVirtual; ConverterBase = converter; Options = options; }
internal virtual void Initialize( Type parentClassType, Type declaredPropertyType, Type?runtimePropertyType, ConverterStrategy runtimeClassType, MemberInfo?memberInfo, JsonConverter converter, JsonIgnoreCondition?ignoreCondition, JsonNumberHandling?parentTypeNumberHandling, JsonSerializerOptions options) { Debug.Assert(converter != null); ClrName = memberInfo?.Name; DeclaringType = parentClassType; DeclaredPropertyType = declaredPropertyType; RuntimePropertyType = runtimePropertyType; ConverterStrategy = runtimeClassType; MemberInfo = memberInfo; ConverterBase = converter; Options = options; }
public void Push() { if (_continuationCount == 0) { if (_count == 0) { // The first stack frame is held in Current. _count = 1; } else { JsonTypeInfo jsonTypeInfo; JsonNumberHandling?numberHandling = Current.NumberHandling; ConverterStrategy converterStrategy = Current.JsonTypeInfo.PropertyInfoForTypeInfo.ConverterStrategy; if (converterStrategy == ConverterStrategy.Object) { if (Current.JsonPropertyInfo != null) { jsonTypeInfo = Current.JsonPropertyInfo.RuntimeTypeInfo; } else { jsonTypeInfo = Current.CtorArgumentState !.JsonParameterInfo !.RuntimeTypeInfo; } } else if (converterStrategy == ConverterStrategy.Value) { // Although ConverterStrategy.Value doesn't push, a custom custom converter may re-enter serialization. jsonTypeInfo = Current.JsonPropertyInfo !.RuntimeTypeInfo; } else { Debug.Assert(((ConverterStrategy.Enumerable | ConverterStrategy.Dictionary) & converterStrategy) != 0); jsonTypeInfo = Current.JsonTypeInfo.ElementTypeInfo !; } AddCurrent(); Current.Reset(); Current.JsonTypeInfo = jsonTypeInfo; Current.JsonPropertyInfo = jsonTypeInfo.PropertyInfoForTypeInfo; // Allow number handling on property to win over handling on type. Current.NumberHandling = numberHandling ?? Current.JsonPropertyInfo.NumberHandling; } } else if (_continuationCount == 1) { // No need for a push since there is only one stack frame. Debug.Assert(_count == 1); _continuationCount = 0; } else { // A continuation; adjust the index. Current = _previous[_count - 1]; // Check if we are done. if (_count == _continuationCount) { _continuationCount = 0; } else { _count++; } } SetConstructorArgumentState(); }
public JsonMetadataServicesConverter(Func <JsonConverter <T> > converterCreator, ConverterStrategy converterStrategy) { _converterCreator = converterCreator ?? throw new ArgumentNullException(nameof(converterCreator)); _converterStrategy = converterStrategy; }
internal JsonTypeInfo(Type type, JsonSerializerOptions options, ConverterStrategy converterStrategy) : base(type, options, converterStrategy) { }
public void Push() { if (_continuationCount == 0) { if (_count == 0) { // The first stack frame is held in Current. _count = 1; } else { JsonTypeInfo jsonTypeInfo; JsonNumberHandling?numberHandling = Current.NumberHandling; ConverterStrategy converterStrategy = Current.JsonTypeInfo.PropertyInfoForTypeInfo.ConverterStrategy; if (converterStrategy == ConverterStrategy.Object) { if (Current.JsonPropertyInfo != null) { jsonTypeInfo = Current.JsonPropertyInfo.RuntimeTypeInfo; } else { jsonTypeInfo = Current.CtorArgumentState !.JsonParameterInfo !.RuntimeTypeInfo; } } else if (converterStrategy == ConverterStrategy.Value) { // Although ConverterStrategy.Value doesn't push, a custom custom converter may re-enter serialization. jsonTypeInfo = Current.JsonPropertyInfo !.RuntimeTypeInfo; } else { Debug.Assert(((ConverterStrategy.Enumerable | ConverterStrategy.Dictionary) & converterStrategy) != 0); jsonTypeInfo = Current.JsonTypeInfo.ElementTypeInfo !; } EnsurePushCapacity(); _stack[_count - 1] = Current; Current = default; _count++; Current.JsonTypeInfo = jsonTypeInfo; Current.JsonPropertyInfo = jsonTypeInfo.PropertyInfoForTypeInfo; // Allow number handling on property to win over handling on type. Current.NumberHandling = numberHandling ?? Current.JsonPropertyInfo.NumberHandling; } } else { // We are re-entering a continuation, adjust indices accordingly if (_count++ > 0) { Current = _stack[_count - 1]; } // check if we are done if (_continuationCount == _count) { _continuationCount = 0; } } SetConstructorArgumentState(); #if DEBUG // Ensure the method is always exercised in debug builds. _ = JsonPath(); #endif }
internal override void Initialize( Type parentClassType, Type declaredPropertyType, Type?runtimePropertyType, ConverterStrategy runtimeClassType, MemberInfo?memberInfo, bool isVirtual, JsonConverter converter, JsonIgnoreCondition?ignoreCondition, JsonNumberHandling?parentTypeNumberHandling, JsonSerializerOptions options) { base.Initialize( parentClassType, declaredPropertyType, runtimePropertyType, runtimeClassType, memberInfo, isVirtual, converter, ignoreCondition, parentTypeNumberHandling, options); switch (memberInfo) { case PropertyInfo propertyInfo: { bool useNonPublicAccessors = GetAttribute <JsonIncludeAttribute>(propertyInfo) != null; MethodInfo?getMethod = propertyInfo.GetMethod; if (getMethod != null && (getMethod.IsPublic || useNonPublicAccessors)) { HasGetter = true; Get = options.MemberAccessorStrategy.CreatePropertyGetter <T>(propertyInfo); } MethodInfo?setMethod = propertyInfo.SetMethod; if (setMethod != null && (setMethod.IsPublic || useNonPublicAccessors)) { HasSetter = true; Set = options.MemberAccessorStrategy.CreatePropertySetter <T>(propertyInfo); } MemberType = MemberTypes.Property; break; } case FieldInfo fieldInfo: { Debug.Assert(fieldInfo.IsPublic); HasGetter = true; Get = options.MemberAccessorStrategy.CreateFieldGetter <T>(fieldInfo); if (!fieldInfo.IsInitOnly) { HasSetter = true; Set = options.MemberAccessorStrategy.CreateFieldSetter <T>(fieldInfo); } MemberType = MemberTypes.Field; break; } default: { IsForTypeInfo = true; HasGetter = true; HasSetter = true; break; } } _converterIsExternalAndPolymorphic = !converter.IsInternalConverter && DeclaredPropertyType != converter.TypeToConvert; PropertyTypeCanBeNull = DeclaredPropertyType.CanBeNull(); _propertyTypeEqualsTypeToConvert = typeof(T) == DeclaredPropertyType; GetPolicies(ignoreCondition, parentTypeNumberHandling); }
private static JsonConverter GetConverter(JsonCollectionInfoValues <T> collectionInfo, Func <JsonConverter <T> > converterCreator) { ConverterStrategy strategy = collectionInfo.KeyInfo == null ? ConverterStrategy.Enumerable : ConverterStrategy.Dictionary; return(new JsonMetadataServicesConverter <T>(converterCreator, strategy)); }
private bool UseConverterStrategy(ConverterStrategy strategy) { return (this.converterStrategy & strategy) == strategy; }
public JsonMetadataServicesConverter(JsonConverter<T> converter) { _converter = converter; _converterStrategy = converter.ConverterStrategy; }
/// <summary> /// Creates serialization metadata given JsonSerializerOptions and a ConverterStrategy. /// </summary> public JsonTypeInfoInternal(JsonSerializerOptions options, ConverterStrategy converterStrategy) : base(typeof(T), options, converterStrategy) { }
internal override void Initialize( Type parentClassType, Type declaredPropertyType, ConverterStrategy converterStrategy, MemberInfo?memberInfo, bool isVirtual, JsonConverter converter, JsonIgnoreCondition?ignoreCondition, JsonSerializerOptions options, JsonTypeInfo?jsonTypeInfo = null) { Debug.Assert(converter != null); PropertyType = declaredPropertyType; ConverterStrategy = converterStrategy; if (jsonTypeInfo != null) { JsonTypeInfo = jsonTypeInfo; } ConverterBase = converter; Options = options; DeclaringType = parentClassType; MemberInfo = memberInfo; IsVirtual = isVirtual; IgnoreCondition = ignoreCondition; if (memberInfo != null) { switch (memberInfo) { case PropertyInfo propertyInfo: { bool useNonPublicAccessors = GetAttribute <JsonIncludeAttribute>(propertyInfo) != null; MethodInfo?getMethod = propertyInfo.GetMethod; if (getMethod != null && (getMethod.IsPublic || useNonPublicAccessors)) { HasGetter = true; Get = options.MemberAccessorStrategy.CreatePropertyGetter <T>(propertyInfo); } MethodInfo?setMethod = propertyInfo.SetMethod; if (setMethod != null && (setMethod.IsPublic || useNonPublicAccessors)) { HasSetter = true; Set = options.MemberAccessorStrategy.CreatePropertySetter <T>(propertyInfo); } MemberType = MemberTypes.Property; break; } case FieldInfo fieldInfo: { Debug.Assert(fieldInfo.IsPublic); HasGetter = true; Get = options.MemberAccessorStrategy.CreateFieldGetter <T>(fieldInfo); if (!fieldInfo.IsInitOnly) { HasSetter = true; Set = options.MemberAccessorStrategy.CreateFieldSetter <T>(fieldInfo); } MemberType = MemberTypes.Field; break; } default: { Debug.Fail($"Invalid memberInfo type: {memberInfo.GetType().FullName}"); break; } } GetPolicies(); } else { IsForTypeInfo = true; HasGetter = true; HasSetter = true; } }