Пример #1
0
        private void MergeStructValue(IMessage message, JsonTokenizer tokenizer)
        {
            var firstToken = tokenizer.Next();
            var fields     = message.Descriptor.Fields;

            switch (firstToken.Type)
            {
            case JsonToken.TokenType.Null:
                fields[Value.NullValueFieldNumber].Accessor.SetValue(message, 0);
                return;

            case JsonToken.TokenType.StringValue:
                fields[Value.StringValueFieldNumber].Accessor.SetValue(message, firstToken.StringValue);
                return;

            case JsonToken.TokenType.Number:
                fields[Value.NumberValueFieldNumber].Accessor.SetValue(message, firstToken.NumberValue);
                return;

            case JsonToken.TokenType.False:
            case JsonToken.TokenType.True:
                fields[Value.BoolValueFieldNumber].Accessor.SetValue(message, firstToken.Type == JsonToken.TokenType.True);
                return;

            case JsonToken.TokenType.StartObject:
            {
                var field         = fields[Value.StructValueFieldNumber];
                var structMessage = NewMessageForField(field);
                tokenizer.PushBack(firstToken);
                Merge(structMessage, tokenizer);
                field.Accessor.SetValue(message, structMessage);
                return;
            }

            case JsonToken.TokenType.StartArray:
            {
                var field = fields[Value.ListValueFieldNumber];
                var list  = NewMessageForField(field);
                tokenizer.PushBack(firstToken);
                Merge(list, tokenizer);
                field.Accessor.SetValue(message, list);
                return;
            }

            default:
                throw new InvalidOperationException("Unexpected token type: " + firstToken.Type);
            }
        }
Пример #2
0
        private void MergeRepeatedField(IMessage message, FieldDescriptor field, JsonTokenizer tokenizer)
        {
            var token = tokenizer.Next();

            if (token.Type != JsonToken.TokenType.StartArray)
            {
                throw new InvalidProtocolBufferException("Repeated field value was not an array. Token type: " + token.Type);
            }

            IList list = (IList)field.Accessor.GetValue(message);

            while (true)
            {
                token = tokenizer.Next();
                if (token.Type == JsonToken.TokenType.EndArray)
                {
                    return;
                }
                tokenizer.PushBack(token);
                if (token.Type == JsonToken.TokenType.Null)
                {
                    throw new InvalidProtocolBufferException("Repeated field elements cannot be null");
                }
                list.Add(ParseSingleValue(field, tokenizer));
            }
        }
Пример #3
0
        private void MergeField(IMessage message, FieldDescriptor field, JsonTokenizer tokenizer)
        {
            var token = tokenizer.Next();

            if (token.Type == JsonToken.TokenType.Null)
            {
                // Note: different from Java API, which just ignores it.
                // TODO: Bring it more in line? Discuss...
                field.Accessor.Clear(message);
                return;
            }
            tokenizer.PushBack(token);

            if (field.IsMap)
            {
                MergeMapField(message, field, tokenizer);
            }
            else if (field.IsRepeated)
            {
                MergeRepeatedField(message, field, tokenizer);
            }
            else
            {
                var value = ParseSingleValue(field, tokenizer);
                field.Accessor.SetValue(message, value);
            }
        }
Пример #4
0
        private void MergeField(IMessage message, FieldDescriptor field, JsonTokenizer tokenizer)
        {
            var token = tokenizer.Next();

            if (token.Type == JsonToken.TokenType.Null)
            {
                // Clear the field if we see a null token, unless it's for a singular field of type
                // google.protobuf.Value.
                // Note: different from Java API, which just ignores it.
                // TODO: Bring it more in line? Discuss...
                if (field.IsMap || field.IsRepeated || !IsGoogleProtobufValueField(field))
                {
                    field.Accessor.Clear(message);
                    return;
                }
            }
            tokenizer.PushBack(token);

            if (field.IsMap)
            {
                MergeMapField(message, field, tokenizer);
            }
            else if (field.IsRepeated)
            {
                MergeRepeatedField(message, field, tokenizer);
            }
            else
            {
                var value = ParseSingleValue(field, tokenizer);
                field.Accessor.SetValue(message, value);
            }
        }
Пример #5
0
        public void CanPushBackEndDocument()
        {
            var tokenizer = new JsonTokenizer(new StringReader("null"));

            Assert.AreEqual(JsonToken.Null, tokenizer.Next());
            Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
            tokenizer.PushBack(JsonToken.EndDocument);
            Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
            Assert.Throws <InvalidOperationException>(() => tokenizer.Next());
        }
Пример #6
0
        private void MergeStruct(IMessage message, JsonTokenizer tokenizer)
        {
            var token = tokenizer.Next();

            if (token.Type != JsonToken.TokenType.StartObject)
            {
                throw new InvalidProtocolBufferException("Expected object value for Struct");
            }
            tokenizer.PushBack(token);

            var field = message.Descriptor.Fields[Struct.FieldsFieldNumber];

            MergeMapField(message, field, tokenizer);
        }
Пример #7
0
        public void ObjectDepth_WithPushBack()
        {
            string json      = "{}";
            var    tokenizer = new JsonTokenizer(new StringReader(json));

            Assert.AreEqual(0, tokenizer.ObjectDepth);
            var token = tokenizer.Next();

            Assert.AreEqual(1, tokenizer.ObjectDepth);
            // When we push back a "start object", we should effectively be back to the previous depth.
            tokenizer.PushBack(token);
            Assert.AreEqual(0, tokenizer.ObjectDepth);
            // Read the same token again, and get back to depth 1
            token = tokenizer.Next();
            Assert.AreEqual(1, tokenizer.ObjectDepth);

            // Now the same in reverse, with EndObject
            token = tokenizer.Next();
            Assert.AreEqual(0, tokenizer.ObjectDepth);
            tokenizer.PushBack(token);
            Assert.AreEqual(1, tokenizer.ObjectDepth);
            tokenizer.Next();
            Assert.AreEqual(0, tokenizer.ObjectDepth);
        }
Пример #8
0
        private object ParseSingleValue(FieldDescriptor field, JsonTokenizer tokenizer)
        {
            var token = tokenizer.Next();

            if (token.Type == JsonToken.TokenType.Null)
            {
                if (field.FieldType == FieldType.Message && field.MessageType.FullName == Value.Descriptor.FullName)
                {
                    return(new Value {
                        NullValue = NullValue.NULL_VALUE
                    });
                }
                return(null);
            }

            var fieldType = field.FieldType;

            if (fieldType == FieldType.Message)
            {
                // Parse wrapper types as their constituent types.
                // TODO: What does this mean for null?
                if (field.MessageType.IsWrapperType)
                {
                    field     = field.MessageType.Fields[WrappersReflection.WrapperValueFieldNumber];
                    fieldType = field.FieldType;
                }
                else
                {
                    // TODO: Merge the current value in message? (Public API currently doesn't make this relevant as we don't expose merging.)
                    tokenizer.PushBack(token);
                    IMessage subMessage = NewMessageForField(field);
                    Merge(subMessage, tokenizer);
                    return(subMessage);
                }
            }

            switch (token.Type)
            {
            case JsonToken.TokenType.True:
            case JsonToken.TokenType.False:
                if (fieldType == FieldType.Bool)
                {
                    return(token.Type == JsonToken.TokenType.True);
                }
                // Fall through to "we don't support this type for this case"; could duplicate the behaviour of the default
                // case instead, but this way we'd only need to change one place.
                goto default;

            case JsonToken.TokenType.StringValue:
                return(ParseSingleStringValue(field, token.StringValue));

            // Note: not passing the number value itself here, as we may end up storing the string value in the token too.
            case JsonToken.TokenType.Number:
                return(ParseSingleNumberValue(field, token));

            case JsonToken.TokenType.Null:
                throw new NotImplementedException("Haven't worked out what to do for null yet");

            default:
                throw new InvalidProtocolBufferException("Unsupported JSON token type " + token.Type + " for field type " + fieldType);
            }
        }
Пример #9
0
 public void CanPushBackEndDocument()
 {
     var tokenizer = new JsonTokenizer(new StringReader("null"));
     Assert.AreEqual(JsonToken.Null, tokenizer.Next());
     Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
     tokenizer.PushBack(JsonToken.EndDocument);
     Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
     Assert.Throws<InvalidOperationException>(() => tokenizer.Next());
 }
Пример #10
0
        public void ObjectDepth_WithPushBack()
        {
            string json = "{}";
            var tokenizer = new JsonTokenizer(new StringReader(json));
            Assert.AreEqual(0, tokenizer.ObjectDepth);
            var token = tokenizer.Next();
            Assert.AreEqual(1, tokenizer.ObjectDepth);
            // When we push back a "start object", we should effectively be back to the previous depth.
            tokenizer.PushBack(token);
            Assert.AreEqual(0, tokenizer.ObjectDepth);
            // Read the same token again, and get back to depth 1
            token = tokenizer.Next();
            Assert.AreEqual(1, tokenizer.ObjectDepth);

            // Now the same in reverse, with EndObject
            token = tokenizer.Next();
            Assert.AreEqual(0, tokenizer.ObjectDepth);
            tokenizer.PushBack(token);
            Assert.AreEqual(1, tokenizer.ObjectDepth);
            tokenizer.Next();
            Assert.AreEqual(0, tokenizer.ObjectDepth);
        }