public JsonProperty(JsonDynamicObject obj, Utf8String name)
 {
     _object = obj;
     _name   = name;
 }
 public JsonValue(JsonValueType type)
 {
     _type   = type;
     _value  = default(Utf8String);
     _object = null;
 }
 public JsonValue(Utf8String value, JsonValueType type = JsonValueType.String)
 {
     _value  = value;
     _object = null;
     _type   = type;
 }
 public JsonValue(JsonDynamicObject obj)
 {
     _value  = default(Utf8String);
     _object = obj;
     _type   = JsonValueType.Object;
 }
        public static JsonDynamicObject Parse(ReadOnlySpan <byte> utf8, int expectedNumberOfProperties = -1)
        {
            Stack <JsonDynamicObject> stack = new Stack <JsonDynamicObject>();

            if (expectedNumberOfProperties == -1)
            {
                expectedNumberOfProperties = utf8.Length >> 3;
            }
            var properties = new Dictionary <JsonProperty, JsonValue>(expectedNumberOfProperties);

            stack.Push(new JsonDynamicObject(properties));

            var reader = new JsonReader(utf8, SymbolTable.InvariantUtf8);

            while (reader.Read())
            {
                switch (reader.TokenType)
                {
                case JsonTokenType.PropertyName:
                    var name = new Utf8String(reader.Value);
                    reader.Read();     // Move to the value token
                    var type     = reader.ValueType;
                    var current  = stack.Peek();
                    var property = new JsonProperty(current, name);
                    switch (type)
                    {
                    case JsonValueType.String:
                        current._properties[property] = new JsonValue(new Utf8String(reader.Value));
                        break;

                    case JsonValueType.Object:         // TODO: could this be lazy? Could this reuse the root JsonObject (which would store non-allocating JsonDom)?
                        var newObj = new JsonDynamicObject(properties);
                        current._properties[property] = new JsonValue(newObj);
                        stack.Push(newObj);
                        break;

                    case JsonValueType.True:
                        current._properties[property] = new JsonValue(type);
                        break;

                    case JsonValueType.False:
                        current._properties[property] = new JsonValue(type);
                        break;

                    case JsonValueType.Null:
                        current._properties[property] = new JsonValue(type);
                        break;

                    case JsonValueType.Number:
                        current._properties[property] = new JsonValue(new Utf8String(reader.Value), type);
                        break;

                    case JsonValueType.Array:
                        throw new NotImplementedException("array support not implemented yet.");

                    default:
                        throw new NotSupportedException();
                    }
                    break;

                case JsonTokenType.StartObject:
                    break;

                case JsonTokenType.EndObject:
                    if (stack.Count != 1)
                    {
                        stack.Pop();
                    }
                    break;

                case JsonTokenType.StartArray:
                    throw new NotImplementedException("array support not implemented yet.");

                case JsonTokenType.EndArray:
                case JsonTokenType.Value:
                    break;

                default:
                    throw new NotSupportedException();
                }
            }

            return(stack.Peek());
        }