< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 52
Coverable lines: 52
Total lines: 177
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 20
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
EndConstructorParameter()100%110%
EndProperty()100%110%
EndElement()100%110%
IsProcessingDictionary()100%110%
IsProcessingEnumerable()100%110%
MarkPropertyAsRead(...)0%660%
InitializePropertiesValidationState(...)0%440%
ValidateAllRequiredPropertiesAreRead(...)0%440%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections;
 5using System.Collections.Generic;
 6using System.Diagnostics;
 7using System.Runtime.CompilerServices;
 8using System.Runtime.InteropServices;
 9using System.Text.Json.Serialization;
 10using System.Text.Json.Serialization.Metadata;
 11
 12namespace System.Text.Json
 13{
 14    [StructLayout(LayoutKind.Auto)]
 15    [DebuggerDisplay("{DebuggerDisplay,nq}")]
 16    internal struct ReadStackFrame
 17    {
 18        // Current property values.
 19        public JsonPropertyInfo? JsonPropertyInfo;
 20        public StackFramePropertyState PropertyState;
 21        public bool UseExtensionProperty;
 22
 23        // Support JSON Path on exceptions and non-string Dictionary keys.
 24        // This is Utf8 since we don't want to convert to string until an exception is thrown.
 25        // For dictionary keys we don't want to convert to TKey until we have both key and value when parsing the dictio
 26        public byte[]? JsonPropertyName;
 27        public string? JsonPropertyNameAsString; // This is used for string dictionary keys and re-entry cases that spec
 28
 29        // Stores the non-string dictionary keys for continuation.
 30        public object? DictionaryKey;
 31
 32        /// <summary>
 33        /// Records the Utf8JsonReader Depth at the start of the current value.
 34        /// </summary>
 35        public int OriginalDepth;
 36#if DEBUG
 37        /// <summary>
 38        /// Records the Utf8JsonReader TokenType at the start of the current value.
 39        /// Only used to validate debug builds.
 40        /// </summary>
 41        public JsonTokenType OriginalTokenType;
 42#endif
 43
 44        // Current object (POCO or IEnumerable).
 45        public object? ReturnValue; // The current return value used for re-entry.
 46        public JsonTypeInfo JsonTypeInfo;
 47        public StackFrameObjectState ObjectState; // State tracking the current object.
 48
 49        // Current object can contain metadata
 50        public bool CanContainMetadata;
 51        public MetadataPropertyName LatestMetadataPropertyName;
 52        public MetadataPropertyName MetadataPropertyNames;
 53
 54        // Serialization state for value serialized by the current frame.
 55        public PolymorphicSerializationState PolymorphicSerializationState;
 56
 57        // Holds any entered polymorphic JsonTypeInfo metadata.
 58        public JsonTypeInfo? PolymorphicJsonTypeInfo;
 59
 60        // Gets the initial JsonTypeInfo metadata used when deserializing the current value.
 61        public JsonTypeInfo BaseJsonTypeInfo
 062            => PolymorphicSerializationState == PolymorphicSerializationState.PolymorphicReEntryStarted
 063                ? PolymorphicJsonTypeInfo!
 064                : JsonTypeInfo;
 65
 66        // For performance, we order the properties by the first deserialize and PropertyIndex helps find the right slot
 67        public int PropertyIndex;
 68
 69        // Tracks newly encounentered UTF-8 encoded properties during the current deserialization, to be appended to the
 70        public PropertyRefCacheBuilder? PropertyRefCacheBuilder;
 71
 72        // Holds relevant state when deserializing objects with parameterized constructors.
 73        public ArgumentState? CtorArgumentState;
 74
 75        // Whether to use custom number handling.
 76        public JsonNumberHandling? NumberHandling;
 77
 78        // Represents known (non-extension) properties which have value assigned.
 79        // Each bit corresponds to a property.
 80        // False means that property is not set (not yet occurred in the payload).
 81        // Length of the BitArray is equal to number of non-extension properties.
 82        // Every JsonPropertyInfo has PropertyIndex property which maps to an index in this BitArray.
 83        public BitArray? AssignedProperties;
 84
 85        // Tracks state related to property population.
 86        public bool HasParentObject;
 87        public bool IsPopulating;
 88
 89        public void EndConstructorParameter()
 090        {
 091            CtorArgumentState!.JsonParameterInfo = null;
 092            JsonPropertyName = null;
 093            PropertyState = StackFramePropertyState.None;
 094        }
 95
 96        public void EndProperty()
 097        {
 098            JsonPropertyInfo = null!;
 099            JsonPropertyName = null;
 0100            JsonPropertyNameAsString = null;
 0101            PropertyState = StackFramePropertyState.None;
 102
 103            // No need to clear these since they are overwritten each time:
 104            //  NumberHandling
 105            //  UseExtensionProperty
 0106        }
 107
 108        public void EndElement()
 0109        {
 0110            JsonPropertyNameAsString = null;
 0111            PropertyState = StackFramePropertyState.None;
 0112        }
 113
 114        /// <summary>
 115        /// Is the current object a Dictionary.
 116        /// </summary>
 0117        public bool IsProcessingDictionary() => JsonTypeInfo.Kind is JsonTypeInfoKind.Dictionary;
 118
 119        /// <summary>
 120        /// Is the current object an Enumerable.
 121        /// </summary>
 0122        public bool IsProcessingEnumerable() => JsonTypeInfo.Kind is JsonTypeInfoKind.Enumerable;
 123
 124        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 125        public void MarkPropertyAsRead(JsonPropertyInfo propertyInfo)
 0126        {
 0127            if (AssignedProperties is { })
 0128            {
 0129                if (!propertyInfo.Options.AllowDuplicateProperties)
 0130                {
 0131                    if (AssignedProperties[propertyInfo.PropertyIndex])
 0132                    {
 0133                        ThrowHelper.ThrowJsonException_DuplicatePropertyNotAllowed(propertyInfo);
 134                    }
 0135                }
 136
 0137                AssignedProperties[propertyInfo.PropertyIndex] = true;
 0138            }
 0139        }
 140
 141        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 142        internal void InitializePropertiesValidationState(JsonTypeInfo typeInfo)
 0143        {
 0144            Debug.Assert(AssignedProperties is null);
 145
 0146            if (typeInfo.ShouldTrackRequiredProperties || !typeInfo.Options.AllowDuplicateProperties)
 0147            {
 148                // This may be slightly larger than required (e.g. if there's an extension property)
 0149                AssignedProperties = new BitArray(typeInfo.Properties.Count);
 0150            }
 0151        }
 152
 153        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 154        internal void ValidateAllRequiredPropertiesAreRead(JsonTypeInfo typeInfo)
 0155        {
 0156            if (typeInfo.ShouldTrackRequiredProperties)
 0157            {
 0158                Debug.Assert(AssignedProperties is not null);
 0159                Debug.Assert(typeInfo.OptionalPropertiesMask is not null);
 160
 161                // All properties must be either assigned or optional
 0162                BitArray assignedOrNotRequiredPropertiesSet = AssignedProperties.Or(typeInfo.OptionalPropertiesMask);
 163
 0164                if (!assignedOrNotRequiredPropertiesSet.HasAllSet())
 0165                {
 0166                    ThrowHelper.ThrowJsonException_JsonRequiredPropertyMissing(typeInfo, assignedOrNotRequiredProperties
 167                }
 0168            }
 169
 0170            AssignedProperties = null;
 0171        }
 172
 173        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
 0174        private string DebuggerDisplay => $"ConverterStrategy.{JsonTypeInfo?.Converter.ConverterStrategy}, {JsonTypeInfo
 175    }
 176}
 177