public void MessageDescriptor()
        {
            MessageDescriptor messageType = TestAllTypes.Descriptor;
            MessageDescriptor nestedType  = TestAllTypes.Types.NestedMessage.Descriptor;

            Assert.AreEqual("TestAllTypes", messageType.Name);
            Assert.AreEqual("protobuf_unittest.TestAllTypes", messageType.FullName);
            Assert.AreEqual(UnitTestProtoFile.Descriptor, messageType.File);
            Assert.IsNull(messageType.ContainingType);
            Assert.AreEqual(DescriptorProtos.MessageOptions.DefaultInstance, messageType.Options);
            Assert.AreEqual("TestAllTypes", messageType.Proto.Name);

            Assert.AreEqual("NestedMessage", nestedType.Name);
            Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedMessage", nestedType.FullName);
            Assert.AreEqual(UnitTestProtoFile.Descriptor, nestedType.File);
            Assert.AreEqual(messageType, nestedType.ContainingType);

            FieldDescriptor field = messageType.Fields[0];

            Assert.AreEqual("optional_int32", field.Name);
            Assert.AreEqual(field, messageType.FindDescriptor <FieldDescriptor>("optional_int32"));
            Assert.IsNull(messageType.FindDescriptor <FieldDescriptor>("no_such_field"));
            Assert.AreEqual(field, messageType.FindFieldByNumber(1));
            Assert.IsNull(messageType.FindFieldByNumber(571283));
            for (int i = 0; i < messageType.Fields.Count; i++)
            {
                Assert.AreEqual(i, messageType.Fields[i].Index);
            }

            Assert.AreEqual(nestedType, messageType.NestedTypes[0]);
            Assert.AreEqual(nestedType, messageType.FindDescriptor <MessageDescriptor>("NestedMessage"));
            Assert.IsNull(messageType.FindDescriptor <MessageDescriptor>("NoSuchType"));
            for (int i = 0; i < messageType.NestedTypes.Count; i++)
            {
                Assert.AreEqual(i, messageType.NestedTypes[i].Index);
            }

            Assert.AreEqual(messageType.EnumTypes[0], messageType.FindDescriptor <EnumDescriptor>("NestedEnum"));
            Assert.IsNull(messageType.FindDescriptor <EnumDescriptor>("NoSuchType"));
            for (int i = 0; i < messageType.EnumTypes.Count; i++)
            {
                Assert.AreEqual(i, messageType.EnumTypes[i].Index);
            }
        }
        /// <summary>
        /// Indicates which field in the oneof is set for specified message
        /// </summary>
        public virtual FieldDescriptor GetOneofFieldDescriptor(TMessage message)
        {
            int fieldNumber = (int)caseDelegate(message);

            if (fieldNumber > 0)
            {
                return(descriptor.FindFieldByNumber(fieldNumber));
            }
            return(null);
        }
Esempio n. 3
0
 /// <summary>
 /// Central interception point for well-known type formatting. Any well-known types which
 /// don't need special handling can fall back to WriteMessage. We avoid assuming that the
 /// values are using the embedded well-known types, in order to allow for dynamic messages
 /// in the future.
 /// </summary>
 private void WriteWellKnownTypeValue(StringBuilder builder, MessageDescriptor descriptor, object value, bool inField)
 {
     if (value == null)
     {
         WriteNull(builder);
         return;
     }
     // For wrapper types, the value will be the (possibly boxed) "native" value,
     // so we can write it as if we were unconditionally writing the Value field for the wrapper type.
     if (descriptor.File == Int32Value.Descriptor.File)
     {
         WriteSingleValue(builder, descriptor.FindFieldByNumber(1), value);
         return;
     }
     if (descriptor.FullName == Timestamp.Descriptor.FullName)
     {
         MaybeWrapInString(builder, value, WriteTimestamp, inField);
         return;
     }
     if (descriptor.FullName == Duration.Descriptor.FullName)
     {
         MaybeWrapInString(builder, value, WriteDuration, inField);
         return;
     }
     if (descriptor.FullName == FieldMask.Descriptor.FullName)
     {
         MaybeWrapInString(builder, value, WriteFieldMask, inField);
         return;
     }
     if (descriptor.FullName == Struct.Descriptor.FullName)
     {
         WriteStruct(builder, (IMessage)value);
         return;
     }
     if (descriptor.FullName == ListValue.Descriptor.FullName)
     {
         var fieldAccessor = descriptor.Fields[ListValue.ValuesFieldNumber].Accessor;
         WriteList(builder, fieldAccessor, (IList)fieldAccessor.GetValue((IMessage)value));
         return;
     }
     if (descriptor.FullName == Value.Descriptor.FullName)
     {
         WriteStructFieldValue(builder, (IMessage)value);
         return;
     }
     WriteMessage(builder, (IMessage)value);
 }
Esempio n. 4
0
 /// <summary>
 /// Central interception point for well-known type formatting. Any well-known types which
 /// don't need special handling can fall back to WriteMessage. We avoid assuming that the
 /// values are using the embedded well-known types, in order to allow for dynamic messages
 /// in the future.
 /// </summary>
 private void WriteWellKnownTypeValue(StringBuilder builder, MessageDescriptor descriptor, object value, bool inField)
 {
     if (value == null)
     {
         WriteNull(builder);
         return;
     }
     // For wrapper types, the value will be the (possibly boxed) "native" value,
     // so we can write it as if we were unconditionally writing the Value field for the wrapper type.
     if (descriptor.File == Int32Value.Descriptor.File)
     {
         WriteSingleValue(builder, descriptor.FindFieldByNumber(1), value);
         return;
     }
     if (descriptor.FullName == Timestamp.Descriptor.FullName)
     {
         MaybeWrapInString(builder, value, WriteTimestamp, inField);
         return;
     }
     if (descriptor.FullName == Duration.Descriptor.FullName)
     {
         MaybeWrapInString(builder, value, WriteDuration, inField);
         return;
     }
     if (descriptor.FullName == FieldMask.Descriptor.FullName)
     {
         MaybeWrapInString(builder, value, WriteFieldMask, inField);
         return;
     }
     if (descriptor.FullName == Struct.Descriptor.FullName)
     {
         WriteStruct(builder, (IMessage) value);
         return;
     }
     if (descriptor.FullName == ListValue.Descriptor.FullName)
     {
         var fieldAccessor = descriptor.Fields[ListValue.ValuesFieldNumber].Accessor;
         WriteList(builder, fieldAccessor, (IList) fieldAccessor.GetValue(value));
         return;
     }
     if (descriptor.FullName == Value.Descriptor.FullName)
     {
         WriteStructFieldValue(builder, (IMessage) value);
         return;
     }
     WriteMessage(builder, (IMessage) value);
 }
Esempio n. 5
0
            /// <summary>
            /// Like <see cref="MergeFrom(ICodedInputStream, ExtensionRegistry, IBuilder)" />
            /// but parses a single field.
            /// </summary>
            /// <param name="input">The input to read the field from</param>
            /// <param name="extensionRegistry">Registry to use when an extension field is encountered</param>
            /// <param name="builder">Builder to merge field into, if it's a known field</param>
            /// <param name="tag">The tag, which should already have been read from the input</param>
            /// <returns>true unless the tag is an end-group tag</returns>
            internal bool MergeFieldFrom(ICodedInputStream input,
                                         ExtensionRegistry extensionRegistry, IBuilder builder, uint tag,
                                         string fieldName)
            {
                if (tag == 0 && fieldName != null)
                {
                    FieldDescriptor fieldByName = builder.DescriptorForType.FindFieldByName(fieldName);
                    if (fieldByName != null)
                    {
                        tag = WireFormat.MakeTag(fieldByName);
                    }
                    else
                    {
                        ExtensionInfo extension = extensionRegistry.FindByName(builder.DescriptorForType, fieldName);
                        if (extension != null)
                        {
                            tag = WireFormat.MakeTag(extension.Descriptor);
                        }
                    }
                }

                MessageDescriptor type = builder.DescriptorForType;

                if (type.Options.MessageSetWireFormat && tag == WireFormat.MessageSetTag.ItemStart)
                {
                    MergeMessageSetExtensionFromCodedStream(input, extensionRegistry, builder);
                    return(true);
                }

                WireFormat.WireType wireType = WireFormat.GetTagWireType(tag);
                int fieldNumber = WireFormat.GetTagFieldNumber(tag);

                FieldDescriptor field;
                IMessageLite    defaultFieldInstance = null;

                if (type.IsExtensionNumber(fieldNumber))
                {
                    ExtensionInfo extension = extensionRegistry[type, fieldNumber];
                    if (extension == null)
                    {
                        field = null;
                    }
                    else
                    {
                        field = extension.Descriptor;
                        defaultFieldInstance = extension.DefaultInstance;
                    }
                }
                else
                {
                    field = type.FindFieldByNumber(fieldNumber);
                }

                // Unknown field or wrong wire type. Skip.
                if (field == null)
                {
                    return(MergeFieldFrom(tag, input));
                }
                if (wireType != WireFormat.GetWireType(field))
                {
                    WireFormat.WireType expectedType = WireFormat.GetWireType(field.FieldType);
                    if (wireType == expectedType)
                    {
                        //Allowed as of 2.3, this is unpacked data for a packed array
                    }
                    else if (field.IsRepeated && wireType == WireFormat.WireType.LengthDelimited &&
                             (expectedType == WireFormat.WireType.Varint || expectedType == WireFormat.WireType.Fixed32 ||
                              expectedType == WireFormat.WireType.Fixed64))
                    {
                        //Allowed as of 2.3, this is packed data for an unpacked array
                    }
                    else
                    {
                        return(MergeFieldFrom(tag, input));
                    }
                }

                switch (field.FieldType)
                {
                case FieldType.Group:
                case FieldType.Message:
                {
                    IBuilderLite subBuilder = (defaultFieldInstance != null)
                                                          ? defaultFieldInstance.WeakCreateBuilderForType()
                                                          : builder.CreateBuilderForField(field);
                    if (!field.IsRepeated)
                    {
                        subBuilder.WeakMergeFrom((IMessageLite)builder[field]);
                        if (field.FieldType == FieldType.Group)
                        {
                            input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry);
                        }
                        else
                        {
                            input.ReadMessage(subBuilder, extensionRegistry);
                        }
                        builder[field] = subBuilder.WeakBuild();
                    }
                    else
                    {
                        List <IMessageLite> list = new List <IMessageLite>();
                        if (field.FieldType == FieldType.Group)
                        {
                            input.ReadGroupArray(tag, fieldName, list, subBuilder.WeakDefaultInstanceForType,
                                                 extensionRegistry);
                        }
                        else
                        {
                            input.ReadMessageArray(tag, fieldName, list, subBuilder.WeakDefaultInstanceForType,
                                                   extensionRegistry);
                        }

                        foreach (IMessageLite m in list)
                        {
                            builder.WeakAddRepeatedField(field, m);
                        }
                        return(true);
                    }
                    break;
                }

                case FieldType.Enum:
                {
                    if (!field.IsRepeated)
                    {
                        object    unknown;
                        IEnumLite value = null;
                        if (input.ReadEnum(ref value, out unknown, field.EnumType))
                        {
                            builder[field] = value;
                        }
                        else if (unknown is int)
                        {
                            MergeVarintField(fieldNumber, (ulong)(int)unknown);
                        }
                    }
                    else
                    {
                        ICollection <object> unknown;
                        List <IEnumLite>     list = new List <IEnumLite>();
                        input.ReadEnumArray(tag, fieldName, list, out unknown, field.EnumType);

                        foreach (IEnumLite en in list)
                        {
                            builder.WeakAddRepeatedField(field, en);
                        }

                        if (unknown != null)
                        {
                            foreach (object oval in unknown)
                            {
                                if (oval is int)
                                {
                                    MergeVarintField(fieldNumber, (ulong)(int)oval);
                                }
                            }
                        }
                    }
                    break;
                }

                default:
                {
                    if (!field.IsRepeated)
                    {
                        object value = null;
                        if (input.ReadPrimitiveField(field.FieldType, ref value))
                        {
                            builder[field] = value;
                        }
                    }
                    else
                    {
                        List <object> list = new List <object>();
                        input.ReadPrimitiveArray(field.FieldType, tag, fieldName, list);
                        foreach (object oval in list)
                        {
                            builder.WeakAddRepeatedField(field, oval);
                        }
                    }
                    break;
                }
                }
                return(true);
            }
Esempio n. 6
0
            /// <summary>
            /// Like <see cref="MergeFrom(CodedInputStream, ExtensionRegistry, IBuilder)" />
            /// but parses a single field.
            /// </summary>
            /// <param name="input">The input to read the field from</param>
            /// <param name="extensionRegistry">Registry to use when an extension field is encountered</param>
            /// <param name="builder">Builder to merge field into, if it's a known field</param>
            /// <param name="tag">The tag, which should already have been read from the input</param>
            /// <returns>true unless the tag is an end-group tag</returns>
            internal bool MergeFieldFrom(CodedInputStream input,
                                         ExtensionRegistry extensionRegistry, IBuilder builder, uint tag)
            {
                MessageDescriptor type = builder.DescriptorForType;

                if (type.Options.MessageSetWireFormat && tag == WireFormat.MessageSetTag.ItemStart)
                {
                    MergeMessageSetExtensionFromCodedStream(input, extensionRegistry, builder);
                    return(true);
                }

                WireFormat.WireType wireType = WireFormat.GetTagWireType(tag);
                int fieldNumber = WireFormat.GetTagFieldNumber(tag);

                FieldDescriptor field;
                IMessage        defaultFieldInstance = null;

                if (type.IsExtensionNumber(fieldNumber))
                {
                    ExtensionInfo extension = extensionRegistry[type, fieldNumber];
                    if (extension == null)
                    {
                        field = null;
                    }
                    else
                    {
                        field = extension.Descriptor;
                        defaultFieldInstance = extension.DefaultInstance;
                    }
                }
                else
                {
                    field = type.FindFieldByNumber(fieldNumber);
                }

                // Unknown field or wrong wire type. Skip.
                if (field == null || wireType != WireFormat.GetWireType(field))
                {
                    return(MergeFieldFrom(tag, input));
                }

                if (field.IsPacked)
                {
                    int length = (int)input.ReadRawVarint32();
                    int limit  = input.PushLimit(length);
                    if (field.FieldType == FieldType.Enum)
                    {
                        while (!input.ReachedLimit)
                        {
                            int    rawValue = input.ReadEnum();
                            object value    = field.EnumType.FindValueByNumber(rawValue);
                            if (value == null)
                            {
                                // If the number isn't recognized as a valid value for this
                                // enum, drop it (don't even add it to unknownFields).
                                return(true);
                            }
                            builder.WeakAddRepeatedField(field, value);
                        }
                    }
                    else
                    {
                        while (!input.ReachedLimit)
                        {
                            Object value = input.ReadPrimitiveField(field.FieldType);
                            builder.WeakAddRepeatedField(field, value);
                        }
                    }
                    input.PopLimit(limit);
                }
                else
                {
                    object value;
                    switch (field.FieldType)
                    {
                    case FieldType.Group:
                    case FieldType.Message: {
                        IBuilder subBuilder;
                        if (defaultFieldInstance != null)
                        {
                            subBuilder = defaultFieldInstance.WeakCreateBuilderForType();
                        }
                        else
                        {
                            subBuilder = builder.CreateBuilderForField(field);
                        }
                        if (!field.IsRepeated)
                        {
                            subBuilder.WeakMergeFrom((IMessage)builder[field]);
                        }
                        if (field.FieldType == FieldType.Group)
                        {
                            input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry);
                        }
                        else
                        {
                            input.ReadMessage(subBuilder, extensionRegistry);
                        }
                        value = subBuilder.WeakBuild();
                        break;
                    }

                    case FieldType.Enum: {
                        int rawValue = input.ReadEnum();
                        value = field.EnumType.FindValueByNumber(rawValue);
                        // If the number isn't recognized as a valid value for this enum,
                        // drop it.
                        if (value == null)
                        {
                            MergeVarintField(fieldNumber, (ulong)rawValue);
                            return(true);
                        }
                        break;
                    }

                    default:
                        value = input.ReadPrimitiveField(field.FieldType);
                        break;
                    }
                    if (field.IsRepeated)
                    {
                        builder.WeakAddRepeatedField(field, value);
                    }
                    else
                    {
                        builder[field] = value;
                    }
                }
                return(true);
            }