A class which represents an arbitrary set of fields of some message type. This is used to implement DynamicMessage, and also to represent extensions in GeneratedMessage. This class is internal, since outside users should probably be using DynamicMessage. As in the Java implementation, this class goes against the rest of the framework in terms of mutability. Instead of having a mutable Builder class and an immutable FieldSet class, FieldSet just has a MakeImmutable() method. This is safe so long as all callers are careful not to let a mutable FieldSet escape into the open. This would be impossible to guarantee if this were a public class, of course. All repeated fields are stored as IList[object] even TODO(jonskeet): Finish this comment!
Пример #1
0
 internal Builder(MessageDescriptor type)
 {
     this.type          = type;
     this.fields        = FieldSet.CreateInstance();
     this.unknownFields = UnknownFieldSet.DefaultInstance;
     this.oneofCase     = new FieldDescriptor[type.Proto.OneofDeclCount];
 }
Пример #2
0
 internal object this[IFieldDescriptorLite field, int index]
 {
     get
     {
         if (!field.IsRepeated)
         {
             throw new ArgumentException("Indexer specifying field and index can only be called on repeated fields.");
         }
         return(((IList <object>) this[field])[index]);
     }
     set
     {
         if (!field.IsRepeated)
         {
             throw new ArgumentException("Indexer specifying field and index can only be called on repeated fields.");
         }
         FieldSet.VerifyType(field, value);
         object obj;
         if (!this.fields.TryGetValue(field, out obj))
         {
             throw new ArgumentOutOfRangeException();
         }
         ((IList <object>)obj)[index] = value;
     }
 }
Пример #3
0
 /// <summary>
 /// Creates a DynamicMessage with the given FieldSet.
 /// </summary>
 /// <param name="type"></param>
 /// <param name="fields"></param>
 /// <param name="unknownFields"></param>
 private DynamicMessage(MessageDescriptor type, FieldSet fields,
                        FieldDescriptor[] oneofCase, UnknownFieldSet unknownFields)
 {
     this.type          = type;
     this.fields        = fields;
     this.oneofCase     = oneofCase;
     this.unknownFields = unknownFields;
 }
Пример #4
0
 internal ExtensionWriter(ExtendableMessageLite <TMessage, TBuilder> message)
 {
     extensions = message.extensions;
     iterator   = message.extensions.GetEnumerator();
     if (iterator.MoveNext())
     {
         next = iterator.Current;
     }
 }
Пример #5
0
            public override DynamicMessage BuildPartial()
            {
                fields.MakeImmutable();
                DynamicMessage result = new DynamicMessage(type, fields, unknownFields);

                fields        = null;
                unknownFields = null;
                return(result);
            }
Пример #6
0
 internal ExtensionWriter(ExtendableMessageLite <TMessage, TBuilder> message)
 {
     this.extensions = message.extensions;
     this.iterator   = message.extensions.GetEnumerator();
     if (this.iterator.MoveNext())
     {
         this.next = new KeyValuePair <IFieldDescriptorLite, object>?(this.iterator.Current);
     }
 }
Пример #7
0
 public void MergeFrom(FieldSet other)
 {
     using (IEnumerator <KeyValuePair <IFieldDescriptorLite, object> > enumerator = other.fields.GetEnumerator())
     {
         while (enumerator.MoveNext())
         {
             KeyValuePair <IFieldDescriptorLite, object> current = enumerator.Current;
             this.MergeField(current.Key, current.Value);
         }
     }
 }
            public override DynamicMessage BuildPartial()
            {
                if (fields == null)
                {
                    throw new InvalidOperationException("Build() has already been called on this Builder.");
                }
                fields.MakeImmutable();
                DynamicMessage result = new DynamicMessage(type, fields, unknownFields);

                fields        = null;
                unknownFields = null;
                return(result);
            }
Пример #9
0
        /// <summary>
        /// Implementation of both <c>MergeFrom</c> methods.
        /// </summary>
        /// <param name="otherFields"></param>
        public void MergeFrom(FieldSet other)
        {
            // Note:  We don't attempt to verify that other's fields have valid
            //   types.  Doing so would be a losing battle.  We'd have to verify
            //   all sub-messages as well, and we'd have to make copies of all of
            //   them to insure that they don't change after verification (since
            //   the IMessageLite interface itself cannot enforce immutability of
            //   implementations).
            // TODO(jonskeet):  Provide a function somewhere called MakeDeepCopy()
            //   which allows people to make secure deep copies of messages.

            foreach (KeyValuePair <IFieldDescriptorLite, object> entry in other.fields)
            {
                MergeField(entry.Key, entry.Value);
            }
        }
Пример #10
0
        internal void AddRepeatedField(IFieldDescriptorLite field, object value)
        {
            if (!field.IsRepeated)
            {
                throw new ArgumentException("AddRepeatedField can only be called on repeated fields.");
            }
            FieldSet.VerifyType(field, value);
            object obj;

            if (!this.fields.TryGetValue(field, out obj))
            {
                obj = new List <object>();
                this.fields[field] = obj;
            }
            ((IList <object>)obj).Add(value);
        }
Пример #11
0
 internal object this[IFieldDescriptorLite field]
 {
     get
     {
         object result;
         if (this.fields.TryGetValue(field, out result))
         {
             return(result);
         }
         if (field.MappedType != MappedType.Message)
         {
             return(field.DefaultValue);
         }
         if (field.IsRepeated)
         {
             return(new List <object>());
         }
         return(null);
     }
     set
     {
         if (field.IsRepeated)
         {
             List <object> list = value as List <object>;
             if (list == null)
             {
                 throw new ArgumentException("Wrong object type used with protocol message reflection.");
             }
             List <object> list2 = new List <object>(list);
             using (List <object> .Enumerator enumerator = list2.GetEnumerator())
             {
                 while (enumerator.MoveNext())
                 {
                     object current = enumerator.Current;
                     FieldSet.VerifyType(field, current);
                 }
             }
             value = list2;
         }
         else
         {
             FieldSet.VerifyType(field, value);
         }
         this.fields[field] = value;
     }
 }
Пример #12
0
        protected override bool ParseUnknownField(CodedInputStream input,
                                                  ExtensionRegistry extensionRegistry, uint tag)
        {
            FieldSet extensions = MessageBeingBuilt.Extensions;

            WireFormat.WireType wireType = WireFormat.GetTagWireType(tag);
            int fieldNumber = WireFormat.GetTagFieldNumber(tag);
            IGeneratedExtensionLite extension = extensionRegistry[DefaultInstanceForType, fieldNumber];

            bool unknown = false;
            bool packed  = false;

            if (extension == null)
            {
                unknown = true; // Unknown field.
            }
            else if (wireType == FieldMappingAttribute.WireTypeFromFieldType(extension.Descriptor.FieldType, false /* isPacked */))
            {
                packed = false; // Normal, unpacked value.
            }
            else if (extension.Descriptor.IsRepeated &&
                     //?? just returns true ?? extension.Descriptor.type.isPackable() &&
                     wireType == FieldMappingAttribute.WireTypeFromFieldType(extension.Descriptor.FieldType, true /* isPacked */))
            {
                packed = true; // Packed value.
            }
            else
            {
                unknown = true; // Wrong wire type.
            }

            if (unknown) // Unknown field or wrong wire type.  Skip.
            {
                return(input.SkipField(tag));
            }

            if (packed)
            {
                int length = (int)Math.Min(int.MaxValue, input.ReadRawVarint32());
                int limit  = input.PushLimit(length);
                if (extension.Descriptor.FieldType == FieldType.Enum)
                {
                    while (!input.ReachedLimit)
                    {
                        int    rawValue = input.ReadEnum();
                        Object value    =
                            extension.Descriptor.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);
                        }
                        extensions.AddRepeatedField(extension.Descriptor, value);
                    }
                }
                else
                {
                    while (!input.ReachedLimit)
                    {
                        Object value = input.ReadPrimitiveField(extension.Descriptor.FieldType);
                        extensions.AddRepeatedField(extension.Descriptor, value);
                    }
                }
                input.PopLimit(limit);
            }
            else
            {
                Object value;
                switch (extension.Descriptor.MappedType)
                {
                case MappedType.Message: {
                    IBuilderLite subBuilder = null;
                    if (!extension.Descriptor.IsRepeated)
                    {
                        IMessageLite existingValue = extensions[extension.Descriptor] as IMessageLite;
                        if (existingValue != null)
                        {
                            subBuilder = existingValue.WeakToBuilder();
                        }
                    }
                    if (subBuilder == null)
                    {
                        subBuilder = extension.MessageDefaultInstance.WeakCreateBuilderForType();
                    }
                    if (extension.Descriptor.FieldType == FieldType.Group)
                    {
                        input.ReadGroup(extension.Number, subBuilder, extensionRegistry);
                    }
                    else
                    {
                        input.ReadMessage(subBuilder, extensionRegistry);
                    }
                    value = subBuilder.WeakBuild();
                    break;
                }

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

                default:
                    value = input.ReadPrimitiveField(extension.Descriptor.FieldType);
                    break;
                }

                if (extension.Descriptor.IsRepeated)
                {
                    extensions.AddRepeatedField(extension.Descriptor, value);
                }
                else
                {
                    extensions[extension.Descriptor] = value;
                }
            }

            return(true);
        }
        protected override bool ParseUnknownField(ICodedInputStream input,
                                                  ExtensionRegistry extensionRegistry, uint tag, string fieldName)
        {
            FieldSet extensions = MessageBeingBuilt.Extensions;

            WireFormat.WireType wireType = WireFormat.GetTagWireType(tag);
            int fieldNumber = WireFormat.GetTagFieldNumber(tag);
            IGeneratedExtensionLite extension = extensionRegistry[DefaultInstanceForType, fieldNumber];

            if (extension == null) //unknown field
            {
                return(input.SkipField());
            }

            IFieldDescriptorLite field = extension.Descriptor;


            // Unknown field or wrong wire type. Skip.
            if (field == null)
            {
                return(input.SkipField());
            }
            WireFormat.WireType expectedType = field.IsPacked
                                                   ? WireFormat.WireType.LengthDelimited
                                                   : WireFormat.GetWireType(field.FieldType);
            if (wireType != expectedType)
            {
                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(input.SkipField());
                }
            }
            if (!field.IsRepeated && wireType != WireFormat.GetWireType(field.FieldType)) //invalid wire type
            {
                return(input.SkipField());
            }

            switch (field.FieldType)
            {
            case FieldType.Group:
            case FieldType.Message:
            {
                if (!field.IsRepeated)
                {
                    IMessageLite message    = extensions[extension.Descriptor] as IMessageLite;
                    IBuilderLite subBuilder = (message ?? extension.MessageDefaultInstance).WeakToBuilder();

                    if (field.FieldType == FieldType.Group)
                    {
                        input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry);
                    }
                    else
                    {
                        input.ReadMessage(subBuilder, extensionRegistry);
                    }

                    extensions[field] = subBuilder.WeakBuild();
                }
                else
                {
                    List <IMessageLite> list = new List <IMessageLite>();
                    if (field.FieldType == FieldType.Group)
                    {
                        input.ReadGroupArray(tag, fieldName, list, extension.MessageDefaultInstance,
                                             extensionRegistry);
                    }
                    else
                    {
                        input.ReadMessageArray(tag, fieldName, list, extension.MessageDefaultInstance,
                                               extensionRegistry);
                    }

                    foreach (IMessageLite m in list)
                    {
                        extensions.AddRepeatedField(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))
                    {
                        extensions[field] = value;
                    }
                }
                else
                {
                    ICollection <object> unknown;
                    List <IEnumLite>     list = new List <IEnumLite>();
                    input.ReadEnumArray(tag, fieldName, list, out unknown, field.EnumType);

                    foreach (IEnumLite en in list)
                    {
                        extensions.AddRepeatedField(field, en);
                    }
                }
                break;
            }

            default:
            {
                if (!field.IsRepeated)
                {
                    object value = null;
                    if (input.ReadPrimitiveField(field.FieldType, ref value))
                    {
                        extensions[field] = value;
                    }
                }
                else
                {
                    List <object> list = new List <object>();
                    input.ReadPrimitiveArray(field.FieldType, tag, fieldName, list);
                    foreach (object oval in list)
                    {
                        extensions.AddRepeatedField(field, oval);
                    }
                }
                break;
            }
            }

            return(true);
        }
Пример #14
0
 /// <summary>
 /// Creates a DynamicMessage with the given FieldSet.
 /// </summary>
 /// <param name="type"></param>
 /// <param name="fields"></param>
 /// <param name="unknownFields"></param>
 private DynamicMessage(MessageDescriptor type, FieldSet fields, UnknownFieldSet unknownFields)
 {
     this.type          = type;
     this.fields        = fields;
     this.unknownFields = unknownFields;
 }
Пример #15
0
 internal Builder(MessageDescriptor type)
 {
     this.type          = type;
     this.fields        = FieldSet.CreateInstance();
     this.unknownFields = UnknownFieldSet.DefaultInstance;
 }
Пример #16
0
 /// <summary>
 /// Like <see cref="MergeFrom(IMessage)"/>, but merges from another <c>FieldSet</c>.
 /// </summary>
 public void MergeFrom(FieldSet other)
 {
     MergeFields(other.fields);
 }
Пример #17
0
 /// <summary>
 /// Like <see cref="MergeFrom(IMessage)"/>, but merges from another <c>FieldSet</c>.
 /// </summary>
 public void MergeFrom(FieldSet other)
 {
     MergeFields(other.fields);
 }
Пример #18
0
        protected override bool ParseUnknownField(ICodedInputStream input, ExtensionRegistry extensionRegistry, uint tag, string fieldName)
        {
            TMessage messageBeingBuilt = this.MessageBeingBuilt;
            FieldSet extensions        = messageBeingBuilt.Extensions;

            WireFormat.WireType tagWireType = WireFormat.GetTagWireType(tag);
            int tagFieldNumber = WireFormat.GetTagFieldNumber(tag);
            IGeneratedExtensionLite generatedExtensionLite = extensionRegistry[this.DefaultInstanceForType, tagFieldNumber];

            if (generatedExtensionLite == null)
            {
                return(input.SkipField());
            }
            IFieldDescriptorLite descriptor = generatedExtensionLite.Descriptor;

            if (descriptor == null)
            {
                return(input.SkipField());
            }
            WireFormat.WireType wireType = descriptor.IsPacked ? WireFormat.WireType.LengthDelimited : WireFormat.GetWireType(descriptor.FieldType);
            if (tagWireType != wireType)
            {
                wireType = WireFormat.GetWireType(descriptor.FieldType);
                if (tagWireType != wireType && (!descriptor.IsRepeated || tagWireType != WireFormat.WireType.LengthDelimited || (wireType != WireFormat.WireType.Varint && wireType != WireFormat.WireType.Fixed32 && wireType != WireFormat.WireType.Fixed64)))
                {
                    return(input.SkipField());
                }
            }
            if (!descriptor.IsRepeated && tagWireType != WireFormat.GetWireType(descriptor.FieldType))
            {
                return(input.SkipField());
            }
            FieldType fieldType = descriptor.FieldType;

            switch (fieldType)
            {
            case FieldType.Group:
            case FieldType.Message:
            {
                if (descriptor.IsRepeated)
                {
                    List <IMessageLite> list = new List <IMessageLite>();
                    if (descriptor.FieldType == FieldType.Group)
                    {
                        input.ReadGroupArray <IMessageLite>(tag, fieldName, list, generatedExtensionLite.MessageDefaultInstance, extensionRegistry);
                    }
                    else
                    {
                        input.ReadMessageArray <IMessageLite>(tag, fieldName, list, generatedExtensionLite.MessageDefaultInstance, extensionRegistry);
                    }
                    using (List <IMessageLite> .Enumerator enumerator = list.GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            IMessageLite current = enumerator.Current;
                            extensions.AddRepeatedField(descriptor, current);
                        }
                    }
                    return(true);
                }
                IMessageLite messageLite = extensions[generatedExtensionLite.Descriptor] as IMessageLite;
                IBuilderLite builderLite = (messageLite ?? generatedExtensionLite.MessageDefaultInstance).WeakToBuilder();
                if (descriptor.FieldType == FieldType.Group)
                {
                    input.ReadGroup(descriptor.FieldNumber, builderLite, extensionRegistry);
                }
                else
                {
                    input.ReadMessage(builderLite, extensionRegistry);
                }
                extensions[descriptor] = builderLite.WeakBuild();
                break;
            }

            default:
                if (fieldType == FieldType.Enum)
                {
                    if (!descriptor.IsRepeated)
                    {
                        IEnumLite value = null;
                        object    obj;
                        if (input.ReadEnum(ref value, out obj, descriptor.EnumType))
                        {
                            extensions[descriptor] = value;
                            break;
                        }
                        break;
                    }
                    else
                    {
                        List <IEnumLite>     list2 = new List <IEnumLite>();
                        ICollection <object> collection;
                        input.ReadEnumArray(tag, fieldName, list2, out collection, descriptor.EnumType);
                        using (List <IEnumLite> .Enumerator enumerator2 = list2.GetEnumerator())
                        {
                            while (enumerator2.MoveNext())
                            {
                                IEnumLite current2 = enumerator2.Current;
                                extensions.AddRepeatedField(descriptor, current2);
                            }
                            break;
                        }
                    }
                }
                if (!descriptor.IsRepeated)
                {
                    object value2 = null;
                    if (input.ReadPrimitiveField(descriptor.FieldType, ref value2))
                    {
                        extensions[descriptor] = value2;
                    }
                }
                else
                {
                    List <object> list3 = new List <object>();
                    input.ReadPrimitiveArray(descriptor.FieldType, tag, fieldName, list3);
                    using (List <object> .Enumerator enumerator3 = list3.GetEnumerator())
                    {
                        while (enumerator3.MoveNext())
                        {
                            object current3 = enumerator3.Current;
                            extensions.AddRepeatedField(descriptor, current3);
                        }
                    }
                }
                break;
            }
            return(true);
        }