<PackageReference Include="System.Text.Json" Version="9.0.5" />

ReadStack

struct ReadStack
using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; namespace System.Text.Json { [StructLayout(LayoutKind.Auto)] [DebuggerDisplay("{DebuggerDisplay,nq}")] internal struct ReadStack { public ReadStackFrame Current; private ReadStackFrame[] _stack; private int _count; private int _continuationCount; public ReferenceResolver ReferenceResolver; public bool SupportContinuation; public string ReferenceId; public object PolymorphicTypeDiscriminator; public bool PreserveReferences; public ref ReadStackFrame Parent { [System.Runtime.CompilerServices.IsReadOnly] get { return ref _stack[_count - 2]; } } public JsonPropertyInfo ParentProperty { [System.Runtime.CompilerServices.IsReadOnly] get { if (!Current.HasParentObject) return null; return Parent.JsonPropertyInfo; } } public bool IsContinuation { [System.Runtime.CompilerServices.IsReadOnly] get { return _continuationCount != 0; } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string DebuggerDisplay { get { return $"""{JsonPath()}""{Current.JsonTypeInfo?.Converter.ConverterStrategy}""{Current.JsonTypeInfo?.Type.Name}"; } } private void EnsurePushCapacity() { if (_stack == null) _stack = new ReadStackFrame[4]; else if (_count - 1 == _stack.Length) { Array.Resize(ref _stack, 2 * _stack.Length); } } internal void Initialize(JsonTypeInfo jsonTypeInfo, bool supportContinuation = false) { JsonSerializerOptions options = jsonTypeInfo.Options; if (options.ReferenceHandlingStrategy == ReferenceHandlingStrategy.Preserve) { ReferenceResolver = options.ReferenceHandler.CreateResolver(false); PreserveReferences = true; } Current.JsonTypeInfo = jsonTypeInfo; Current.JsonPropertyInfo = jsonTypeInfo.PropertyInfoForTypeInfo; Current.NumberHandling = Current.JsonPropertyInfo.EffectiveNumberHandling; Current.CanContainMetadata = (PreserveReferences || (jsonTypeInfo.PolymorphicTypeResolver?.UsesTypeDiscriminators ?? false)); SupportContinuation = supportContinuation; } public void Push() { if (_continuationCount == 0) { if (_count == 0) _count = 1; else { JsonTypeInfo jsonTypeInfo = Current.JsonPropertyInfo?.JsonTypeInfo ?? Current.CtorArgumentState.JsonParameterInfo.JsonTypeInfo; JsonNumberHandling? numberHandling = Current.NumberHandling; EnsurePushCapacity(); _stack[_count - 1] = Current; Current = default(ReadStackFrame); _count++; Current.JsonTypeInfo = jsonTypeInfo; Current.JsonPropertyInfo = jsonTypeInfo.PropertyInfoForTypeInfo; Current.NumberHandling = (numberHandling ?? Current.JsonPropertyInfo.EffectiveNumberHandling); Current.CanContainMetadata = (PreserveReferences || (jsonTypeInfo.PolymorphicTypeResolver?.UsesTypeDiscriminators ?? false)); } } else { if (_count++ > 0) { _stack[_count - 2] = Current; Current = _stack[_count - 1]; } if (_continuationCount == _count) _continuationCount = 0; } SetConstructorArgumentState(); } public void Pop(bool success) { if (!success) { if (_continuationCount == 0) { if (_count == 1) { _continuationCount = 1; _count = 0; return; } EnsurePushCapacity(); _continuationCount = _count--; } else if (--_count == 0) { return; } _stack[_count] = Current; Current = _stack[_count - 1]; } else if (--_count > 0) { Current = _stack[_count - 1]; } } public JsonConverter InitializePolymorphicReEntry(JsonTypeInfo derivedJsonTypeInfo) { Current.PolymorphicJsonTypeInfo = Current.JsonTypeInfo; Current.JsonTypeInfo = derivedJsonTypeInfo; Current.JsonPropertyInfo = derivedJsonTypeInfo.PropertyInfoForTypeInfo; ref JsonNumberHandling? numberHandling = ref Current.NumberHandling; JsonNumberHandling? nullable = numberHandling; if (!nullable.HasValue) numberHandling = Current.JsonPropertyInfo.NumberHandling; Current.PolymorphicSerializationState = PolymorphicSerializationState.PolymorphicReEntryStarted; SetConstructorArgumentState(); return derivedJsonTypeInfo.Converter; } public JsonConverter ResumePolymorphicReEntry() { ref JsonTypeInfo jsonTypeInfo = ref Current.JsonTypeInfo; ref JsonTypeInfo polymorphicJsonTypeInfo = ref Current.PolymorphicJsonTypeInfo; JsonTypeInfo polymorphicJsonTypeInfo2 = Current.PolymorphicJsonTypeInfo; JsonTypeInfo jsonTypeInfo2 = Current.JsonTypeInfo; jsonTypeInfo = polymorphicJsonTypeInfo2; polymorphicJsonTypeInfo = jsonTypeInfo2; Current.PolymorphicSerializationState = PolymorphicSerializationState.PolymorphicReEntryStarted; return Current.JsonTypeInfo.Converter; } public void ExitPolymorphicConverter(bool success) { ref JsonTypeInfo jsonTypeInfo = ref Current.JsonTypeInfo; ref JsonTypeInfo polymorphicJsonTypeInfo = ref Current.PolymorphicJsonTypeInfo; JsonTypeInfo polymorphicJsonTypeInfo2 = Current.PolymorphicJsonTypeInfo; JsonTypeInfo jsonTypeInfo2 = Current.JsonTypeInfo; jsonTypeInfo = polymorphicJsonTypeInfo2; polymorphicJsonTypeInfo = jsonTypeInfo2; Current.PolymorphicSerializationState = ((!success) ? PolymorphicSerializationState.PolymorphicReEntrySuspended : PolymorphicSerializationState.None); } public string JsonPath() { StringBuilder stringBuilder = new StringBuilder("$"); int continuationCount = _continuationCount; (int, bool) valueTuple; switch (continuationCount) { case 0: valueTuple = (_count - 1, true); break; case 1: valueTuple = (0, true); break; default: valueTuple = (continuationCount, false); break; } (int, bool) valueTuple2 = valueTuple; int item = valueTuple2.Item1; bool item2 = valueTuple2.Item2; for (int i = 0; i < item; i++) { <JsonPath>g__AppendStackFrame|22_0(stringBuilder, ref _stack[i]); } if (item2) <JsonPath>g__AppendStackFrame|22_0(stringBuilder, ref Current); return stringBuilder.ToString(); } public JsonTypeInfo GetTopJsonTypeInfoWithParameterizedConstructor() { for (int i = 0; i < _count - 1; i++) { if (_stack[i].JsonTypeInfo.UsesParameterizedConstructor) return _stack[i].JsonTypeInfo; } return Current.JsonTypeInfo; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void SetConstructorArgumentState() { if (Current.JsonTypeInfo.UsesParameterizedConstructor) { ref ArgumentState ctorArgumentState = ref Current.CtorArgumentState; if (ctorArgumentState == null) ctorArgumentState = new ArgumentState(); } } } }