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

WriteStack

struct WriteStack
using System.Collections.Generic; using System.Diagnostics; using System.IO.Pipelines; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; namespace System.Text.Json { [StructLayout(LayoutKind.Auto)] [DebuggerDisplay("{DebuggerDisplay,nq}")] internal struct WriteStack { public WriteStackFrame Current; private WriteStackFrame[] _stack; private int _count; private int _continuationCount; private byte _indexOffset; public CancellationToken CancellationToken; public bool SuppressFlush; public Task PendingTask; public List<IAsyncDisposable> CompletedAsyncDisposables; public int FlushThreshold; public PipeWriter PipeWriter; public ReferenceResolver ReferenceResolver; public bool SupportContinuation; public bool SupportAsync; public string NewReferenceId; public object PolymorphicTypeDiscriminator; public PolymorphicTypeResolver PolymorphicTypeResolver; public int CurrentDepth { [System.Runtime.CompilerServices.IsReadOnly] get { return _count; } } public ref WriteStackFrame Parent { [System.Runtime.CompilerServices.IsReadOnly] get { return ref _stack[_count - _indexOffset - 1]; } } public bool IsContinuation { [System.Runtime.CompilerServices.IsReadOnly] get { return _continuationCount != 0; } } public bool CurrentContainsMetadata { [System.Runtime.CompilerServices.IsReadOnly] get { if (NewReferenceId == null) return PolymorphicTypeDiscriminator != null; return true; } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string DebuggerDisplay { get { return $"""{PropertyPath()}""{Current.JsonPropertyInfo?.EffectiveConverter.ConverterStrategy}""{Current.JsonTypeInfo?.Type.Name}"; } } private void EnsurePushCapacity() { if (_stack == null) _stack = new WriteStackFrame[4]; else if (_count - _indexOffset == _stack.Length) { Array.Resize(ref _stack, 2 * _stack.Length); } } internal void Initialize(JsonTypeInfo jsonTypeInfo, object rootValueBoxed = null, bool supportContinuation = false, bool supportAsync = false) { Current.JsonTypeInfo = jsonTypeInfo; Current.JsonPropertyInfo = jsonTypeInfo.PropertyInfoForTypeInfo; Current.NumberHandling = Current.JsonPropertyInfo.EffectiveNumberHandling; SupportContinuation = supportContinuation; SupportAsync = supportAsync; JsonSerializerOptions options = jsonTypeInfo.Options; if (options.ReferenceHandlingStrategy != 0) { ReferenceResolver = options.ReferenceHandler.CreateResolver(true); if (options.ReferenceHandlingStrategy == ReferenceHandlingStrategy.IgnoreCycles && rootValueBoxed != null && jsonTypeInfo.Type.IsValueType) ReferenceResolver.PushReferenceForCycleDetection(rootValueBoxed); } } [System.Runtime.CompilerServices.IsReadOnly] public JsonTypeInfo PeekNestedJsonTypeInfo() { if (_count != 0) return Current.JsonPropertyInfo.JsonTypeInfo; return Current.JsonTypeInfo; } public void Push() { if (_continuationCount == 0) { if (_count == 0 && Current.PolymorphicSerializationState == PolymorphicSerializationState.None) { _count = 1; _indexOffset = 1; } else { JsonTypeInfo nestedJsonTypeInfo = Current.GetNestedJsonTypeInfo(); JsonNumberHandling? numberHandling = Current.NumberHandling; EnsurePushCapacity(); _stack[_count - _indexOffset] = Current; Current = default(WriteStackFrame); _count++; Current.JsonTypeInfo = nestedJsonTypeInfo; Current.JsonPropertyInfo = nestedJsonTypeInfo.PropertyInfoForTypeInfo; Current.NumberHandling = (numberHandling ?? Current.JsonPropertyInfo.EffectiveNumberHandling); } } else { if (_count++ > 0 || _indexOffset == 0) Current = _stack[_count - _indexOffset]; if (_continuationCount == _count) _continuationCount = 0; } } public void Pop(bool success) { if (!success) { if (_continuationCount == 0) { if (_count == 1 && _indexOffset > 0) { _continuationCount = 1; _count = 0; return; } EnsurePushCapacity(); _continuationCount = _count--; } else if (--_count == 0 && _indexOffset > 0) { return; } int num = _count - _indexOffset; _stack[num + 1] = Current; Current = _stack[num]; } else if (--_count > 0 || _indexOffset == 0) { Current = _stack[_count - _indexOffset]; } } public void AddCompletedAsyncDisposable(IAsyncDisposable asyncDisposable) { (CompletedAsyncDisposables ?? (CompletedAsyncDisposables = new List<IAsyncDisposable>())).Add(asyncDisposable); } [System.Runtime.CompilerServices.IsReadOnly] [AsyncStateMachine(typeof(<DisposeCompletedAsyncDisposables>d__31))] public ValueTask DisposeCompletedAsyncDisposables() { <DisposeCompletedAsyncDisposables>d__31 stateMachine = default(<DisposeCompletedAsyncDisposables>d__31); stateMachine.<>t__builder = AsyncValueTaskMethodBuilder.Create(); stateMachine.<>4__this = this; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } [System.Runtime.CompilerServices.IsReadOnly] public void DisposePendingDisposablesOnException() { Exception exception = null; <DisposePendingDisposablesOnException>g__DisposeFrame|32_0(Current.CollectionEnumerator, ref exception); int num = Math.Max(_count, _continuationCount); for (int i = 0; i < num - 1; i++) { <DisposePendingDisposablesOnException>g__DisposeFrame|32_0(_stack[i].CollectionEnumerator, ref exception); } if (exception != null) ExceptionDispatchInfo.Capture(exception).Throw(); } [System.Runtime.CompilerServices.IsReadOnly] [AsyncStateMachine(typeof(<DisposePendingDisposablesOnExceptionAsync>d__33))] public ValueTask DisposePendingDisposablesOnExceptionAsync() { <DisposePendingDisposablesOnExceptionAsync>d__33 stateMachine = default(<DisposePendingDisposablesOnExceptionAsync>d__33); stateMachine.<>t__builder = AsyncValueTaskMethodBuilder.Create(); stateMachine.<>4__this = this; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } public string PropertyPath() { 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 = 1; i <= item; i++) { <PropertyPath>g__AppendStackFrame|34_0(stringBuilder, ref _stack[i - _indexOffset]); } if (item2) <PropertyPath>g__AppendStackFrame|34_0(stringBuilder, ref Current); return stringBuilder.ToString(); } } }