#region Copyright notice and license

// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#endregion

using System;
using System.Collections.Generic;
using System.IO;
using Google.ProtocolBuffers.Collections;
using Google.ProtocolBuffers.Descriptors;

namespace Google.ProtocolBuffers
{
    /// <summary>
    /// Used to keep track of fields which were seen when parsing a protocol message
    /// but whose field numbers or types are unrecognized. This most frequently
    /// occurs when new fields are added to a message type and then messages containing
    /// those fields are read by old software that was built before the new types were
    /// added.
    /// 
    /// Every message contains an UnknownFieldSet.
    /// 
    /// Most users will never need to use this class directly.
    /// </summary>
    public sealed partial class UnknownFieldSet : IMessageLite
    {
        private static readonly UnknownFieldSet defaultInstance =
            new UnknownFieldSet(new Dictionary<int, UnknownField>());

        private readonly IDictionary<int, UnknownField> fields;

        private UnknownFieldSet(IDictionary<int, UnknownField> fields)
        {
            this.fields = fields;
        }

        /// <summary>
        /// Creates a new unknown field set builder.
        /// </summary>
        public static Builder CreateBuilder()
        {
            return new Builder();
        }

        /// <summary>
        /// Creates a new unknown field set builder 
        /// and initialize it from <paramref name="original"/>.
        /// </summary>
        public static Builder CreateBuilder(UnknownFieldSet original)
        {
            return new Builder().MergeFrom(original);
        }

        public static UnknownFieldSet DefaultInstance
        {
            get { return defaultInstance; }
        }

        /// <summary>
        /// Returns a read-only view of the mapping from field numbers to values.
        /// </summary>
        public IDictionary<int, UnknownField> FieldDictionary
        {
            get { return Dictionaries.AsReadOnly(fields); }
        }

        /// <summary>
        /// Checks whether or not the given field number is present in the set.
        /// </summary>
        public bool HasField(int field)
        {
            return fields.ContainsKey(field);
        }

        /// <summary>
        /// Fetches a field by number, returning an empty field if not present.
        /// Never returns null.
        /// </summary>
        public UnknownField this[int number]
        {
            get
            {
                UnknownField ret;
                if (!fields.TryGetValue(number, out ret))
                {
                    ret = UnknownField.DefaultInstance;
                }
                return ret;
            }
        }

        /// <summary>
        /// Serializes the set and writes it to <paramref name="output"/>.
        /// </summary>
        public void WriteTo(ICodedOutputStream output)
        {
            // Avoid creating enumerator for the most common code path.
            if (fields.Count > 0)
            {
                foreach (KeyValuePair<int, UnknownField> entry in fields)
                {
                    entry.Value.WriteTo(entry.Key, output);
                }
            }
        }

        /// <summary>
        /// Gets the number of bytes required to encode this set.
        /// </summary>
        public int SerializedSize
        {
            get
            {
                // Avoid creating enumerator for the most common code path.
                if (fields.Count == 0)
                {
                    return 0;
                }

                int result = 0;
                foreach (KeyValuePair<int, UnknownField> entry in fields)
                {
                    result += entry.Value.GetSerializedSize(entry.Key);
                }
                return result;
            }
        }

        /// <summary>
        /// Converts the set to a string in protocol buffer text format. This
        /// is just a trivial wrapper around TextFormat.PrintToString.
        /// </summary>
        public override String ToString()
        {
            return TextFormat.PrintToString(this);
        }

        /// <summary>
        /// Converts the set to a string in protocol buffer text format. This
        /// is just a trivial wrapper around TextFormat.PrintToString.
        /// </summary>
        public void PrintTo(TextWriter writer)
        {
            TextFormat.Print(this, writer);
        }

        /// <summary>
        /// Serializes the message to a ByteString and returns it. This is
        /// just a trivial wrapper around WriteTo(ICodedOutputStream).
        /// </summary>
        /// <returns></returns>
        public ByteString ToByteString()
        {
            ByteString.CodedBuilder codedBuilder = new ByteString.CodedBuilder(SerializedSize);
            WriteTo(codedBuilder.CodedOutput);
            return codedBuilder.Build();
        }

        /// <summary>
        /// Serializes the message to a byte array and returns it. This is
        /// just a trivial wrapper around WriteTo(ICodedOutputStream).
        /// </summary>
        /// <returns></returns>
        public byte[] ToByteArray()
        {
            byte[] data = new byte[SerializedSize];
            CodedOutputStream output = CodedOutputStream.CreateInstance(data);
            WriteTo(output);
            output.CheckNoSpaceLeft();
            return data;
        }

        /// <summary>
        /// Serializes the message and writes it to <paramref name="output"/>. This is
        /// just a trivial wrapper around WriteTo(ICodedOutputStream).
        /// </summary>
        /// <param name="output"></param>
        public void WriteTo(Stream output)
        {
            CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output);
            WriteTo(codedOutput);
            codedOutput.Flush();
        }

        /// <summary>
        /// Serializes the set and writes it to <paramref name="output"/> using
        /// the MessageSet wire format.
        /// </summary>
        public void WriteAsMessageSetTo(ICodedOutputStream output)
        {
            // Avoid creating enumerator for the most common code path.
            if (fields.Count > 0)
            {
                foreach (KeyValuePair<int, UnknownField> entry in fields)
                {
                    entry.Value.WriteAsMessageSetExtensionTo(entry.Key, output);
                }
            }
        }

        /// <summary>
        /// Gets the number of bytes required to encode this set using the MessageSet
        /// wire format.
        /// </summary>
        public int SerializedSizeAsMessageSet
        {
            get
            {
                // Avoid creating enumerator for the most common code path.
                if (fields.Count == 0)
                {
                    return 0;
                }

                int result = 0;
                foreach (KeyValuePair<int, UnknownField> entry in fields)
                {
                    result += entry.Value.GetSerializedSizeAsMessageSetExtension(entry.Key);
                }
                return result;
            }
        }

        public override bool Equals(object other)
        {
            if (ReferenceEquals(this, other))
            {
                return true;
            }
            UnknownFieldSet otherSet = other as UnknownFieldSet;
            return otherSet != null && Dictionaries.Equals(fields, otherSet.fields);
        }

        public override int GetHashCode()
        {
            return Dictionaries.GetHashCode(fields);
        }

        /// <summary>
        /// Parses an UnknownFieldSet from the given input.
        /// </summary>
        public static UnknownFieldSet ParseFrom(ICodedInputStream input)
        {
            return CreateBuilder().MergeFrom(input).Build();
        }

        /// <summary>
        /// Parses an UnknownFieldSet from the given data.
        /// </summary>
        public static UnknownFieldSet ParseFrom(ByteString data)
        {
            return CreateBuilder().MergeFrom(data).Build();
        }

        /// <summary>
        /// Parses an UnknownFieldSet from the given data.
        /// </summary>
        public static UnknownFieldSet ParseFrom(byte[] data)
        {
            return CreateBuilder().MergeFrom(data).Build();
        }

        /// <summary>
        /// Parses an UnknownFieldSet from the given input.
        /// </summary>
        public static UnknownFieldSet ParseFrom(Stream input)
        {
            return CreateBuilder().MergeFrom(input).Build();
        }

        #region IMessageLite Members

        public bool IsInitialized
        {
            get { return fields != null; }
        }

        public void WriteDelimitedTo(Stream output)
        {
            CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output);
            codedOutput.WriteRawVarint32((uint) SerializedSize);
            WriteTo(codedOutput);
            codedOutput.Flush();
        }

        public IBuilderLite WeakCreateBuilderForType()
        {
            return new Builder();
        }

        public IBuilderLite WeakToBuilder()
        {
            return new Builder(fields);
        }

        public IMessageLite WeakDefaultInstanceForType
        {
            get { return defaultInstance; }
        }

        #endregion

        /// <summary>
        /// Builder for UnknownFieldSets.
        /// </summary>
        public sealed partial class Builder : IBuilderLite
        {
            /// <summary>
            /// Mapping from number to field. Note that by using a SortedList we ensure
            /// that the fields will be serialized in ascending order.
            /// </summary>
            private IDictionary<int, UnknownField> fields;

            // Optimization:  We keep around a builder for the last field that was
            // modified so that we can efficiently add to it multiple times in a
            // row (important when parsing an unknown repeated field).
            private int lastFieldNumber;
            private UnknownField.Builder lastField;

            internal Builder()
            {
                fields = new SortedDictionary<int, UnknownField>();
            }

            internal Builder(IDictionary<int, UnknownField> dictionary)
            {
                fields = new SortedDictionary<int, UnknownField>(dictionary);
            }

            /// <summary>
            /// Returns a field builder for the specified field number, including any values
            /// which already exist.
            /// </summary>
            private UnknownField.Builder GetFieldBuilder(int number)
            {
                if (lastField != null)
                {
                    if (number == lastFieldNumber)
                    {
                        return lastField;
                    }
                    // Note: AddField() will reset lastField and lastFieldNumber.
                    AddField(lastFieldNumber, lastField.Build());
                }
                if (number == 0)
                {
                    return null;
                }

                lastField = UnknownField.CreateBuilder();
                UnknownField existing;
                if (fields.TryGetValue(number, out existing))
                {
                    lastField.MergeFrom(existing);
                }
                lastFieldNumber = number;
                return lastField;
            }

            /// <summary>
            /// Build the UnknownFieldSet and return it. Once this method has been called,
            /// this instance will no longer be usable. Calling any method after this
            /// will throw a NullReferenceException.
            /// </summary>
            public UnknownFieldSet Build()
            {
                GetFieldBuilder(0); // Force lastField to be built.
                UnknownFieldSet result = fields.Count == 0 ? DefaultInstance : new UnknownFieldSet(fields);
                fields = null;
                return result;
            }

            /// <summary>
            /// Adds a field to the set. If a field with the same number already exists, it
            /// is replaced.
            /// </summary>
            public Builder AddField(int number, UnknownField field)
            {
                if (number == 0)
                {
                    throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
                }
                if (lastField != null && lastFieldNumber == number)
                {
                    // Discard this.
                    lastField = null;
                    lastFieldNumber = 0;
                }
                fields[number] = field;
                return this;
            }

            /// <summary>
            /// Resets the builder to an empty set.
            /// </summary>
            public Builder Clear()
            {
                fields.Clear();
                lastFieldNumber = 0;
                lastField = null;
                return this;
            }

            /// <summary>
            /// Parse an entire message from <paramref name="input"/> and merge
            /// its fields into this set.
            /// </summary>
            public Builder MergeFrom(ICodedInputStream input)
            {
                uint tag;
                string name;
                while (input.ReadTag(out tag, out name))
                {
                    if (tag == 0)
                    {
                        if (input.SkipField())
                        {
                            continue; //can't merge unknown without field tag
                        }
                        break;
                    }

                    if (!MergeFieldFrom(tag, input))
                    {
                        break;
                    }
                }
                return this;
            }

            /// <summary>
            /// Parse a single field from <paramref name="input"/> and merge it
            /// into this set.
            /// </summary>
            /// <param name="tag">The field's tag number, which was already parsed.</param>
            /// <param name="input">The coded input stream containing the field</param>
            /// <returns>false if the tag is an "end group" tag, true otherwise</returns>
            public bool MergeFieldFrom(uint tag, ICodedInputStream input)
            {
                if (tag == 0)
                {
                    input.SkipField();
                    return true;
                }

                int number = WireFormat.GetTagFieldNumber(tag);
                switch (WireFormat.GetTagWireType(tag))
                {
                    case WireFormat.WireType.Varint:
                        {
                            ulong uint64 = 0;
                            if (input.ReadUInt64(ref uint64))
                            {
                                GetFieldBuilder(number).AddVarint(uint64);
                            }
                            return true;
                        }
                    case WireFormat.WireType.Fixed32:
                        {
                            uint uint32 = 0;
                            if (input.ReadFixed32(ref uint32))
                            {
                                GetFieldBuilder(number).AddFixed32(uint32);
                            }
                            return true;
                        }
                    case WireFormat.WireType.Fixed64:
                        {
                            ulong uint64 = 0;
                            if (input.ReadFixed64(ref uint64))
                            {
                                GetFieldBuilder(number).AddFixed64(uint64);
                            }
                            return true;
                        }
                    case WireFormat.WireType.LengthDelimited:
                        {
                            ByteString bytes = null;
                            if (input.ReadBytes(ref bytes))
                            {
                                GetFieldBuilder(number).AddLengthDelimited(bytes);
                            }
                            return true;
                        }
                    case WireFormat.WireType.StartGroup:
                        {
                            Builder subBuilder = CreateBuilder();
#pragma warning disable 0612
                            input.ReadUnknownGroup(number, subBuilder);
#pragma warning restore 0612
                            GetFieldBuilder(number).AddGroup(subBuilder.Build());
                            return true;
                        }
                    case WireFormat.WireType.EndGroup:
                        return false;
                    default:
                        throw InvalidProtocolBufferException.InvalidWireType();
                }
            }

            /// <summary>
            /// Parses <paramref name="input"/> as an UnknownFieldSet and merge it
            /// with the set being built. This is just a small wrapper around
            /// MergeFrom(ICodedInputStream).
            /// </summary>
            public Builder MergeFrom(Stream input)
            {
                CodedInputStream codedInput = CodedInputStream.CreateInstance(input);
                MergeFrom(codedInput);
                codedInput.CheckLastTagWas(0);
                return this;
            }

            /// <summary>
            /// Parses <paramref name="data"/> as an UnknownFieldSet and merge it
            /// with the set being built. This is just a small wrapper around
            /// MergeFrom(ICodedInputStream).
            /// </summary>
            public Builder MergeFrom(ByteString data)
            {
                CodedInputStream input = data.CreateCodedInput();
                MergeFrom(input);
                input.CheckLastTagWas(0);
                return this;
            }

            /// <summary>
            /// Parses <paramref name="data"/> as an UnknownFieldSet and merge it
            /// with the set being built. This is just a small wrapper around
            /// MergeFrom(ICodedInputStream).
            /// </summary>
            public Builder MergeFrom(byte[] data)
            {
                CodedInputStream input = CodedInputStream.CreateInstance(data);
                MergeFrom(input);
                input.CheckLastTagWas(0);
                return this;
            }

            /// <summary>
            /// Convenience method for merging a new field containing a single varint
            /// value.  This is used in particular when an unknown enum value is
            /// encountered.
            /// </summary>
            public Builder MergeVarintField(int number, ulong value)
            {
                if (number == 0)
                {
                    throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
                }
                GetFieldBuilder(number).AddVarint(value);
                return this;
            }

            /// <summary>
            /// Merges the fields from <paramref name="other"/> into this set.
            /// If a field number exists in both sets, the values in <paramref name="other"/>
            /// will be appended to the values in this set.
            /// </summary>
            public Builder MergeFrom(UnknownFieldSet other)
            {
                if (other != DefaultInstance)
                {
                    foreach (KeyValuePair<int, UnknownField> entry in other.fields)
                    {
                        MergeField(entry.Key, entry.Value);
                    }
                }
                return this;
            }

            /// <summary>
            /// Checks if the given field number is present in the set.
            /// </summary>
            public bool HasField(int number)
            {
                if (number == 0)
                {
                    throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
                }
                return number == lastFieldNumber || fields.ContainsKey(number);
            }

            /// <summary>
            /// Adds a field to the unknown field set. If a field with the same
            /// number already exists, the two are merged.
            /// </summary>
            public Builder MergeField(int number, UnknownField field)
            {
                if (number == 0)
                {
                    throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
                }
                if (HasField(number))
                {
                    GetFieldBuilder(number).MergeFrom(field);
                }
                else
                {
                    // Optimization:  We could call getFieldBuilder(number).mergeFrom(field)
                    // in this case, but that would create a copy of the Field object.
                    // We'd rather reuse the one passed to us, so call AddField() instead.
                    AddField(number, field);
                }
                return this;
            }

            internal void MergeFrom(ICodedInputStream input, ExtensionRegistry extensionRegistry, IBuilder builder)
            {
                uint tag;
                string name;
                while (input.ReadTag(out tag, out name))
                {
                    if (tag == 0 && name != null)
                    {
                        FieldDescriptor fieldByName = builder.DescriptorForType.FindFieldByName(name);
                        if (fieldByName != null)
                        {
                            tag = WireFormat.MakeTag(fieldByName);
                        }
                        else
                        {
                            ExtensionInfo extension = extensionRegistry.FindByName(builder.DescriptorForType, name);
                            if (extension != null)
                            {
                                tag = WireFormat.MakeTag(extension.Descriptor);
                            }
                        }
                    }
                    if (tag == 0)
                    {
                        if (input.SkipField())
                        {
                            continue; //can't merge unknown without field tag
                        }
                        break;
                    }

                    if (!MergeFieldFrom(input, extensionRegistry, builder, tag, name))
                    {
                        // end group tag
                        break;
                    }
                }
            }

            /// <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;
            }

            /// <summary>
            /// Called by MergeFieldFrom to parse a MessageSet extension.
            /// </summary>
            private void MergeMessageSetExtensionFromCodedStream(ICodedInputStream input,
                                                                 ExtensionRegistry extensionRegistry, IBuilder builder)
            {
                MessageDescriptor type = builder.DescriptorForType;

                // The wire format for MessageSet is:
                //   message MessageSet {
                //     repeated group Item = 1 {
                //       required int32 typeId = 2;
                //       required bytes message = 3;
                //     }
                //   }
                // "typeId" is the extension's field number.  The extension can only be
                // a message type, where "message" contains the encoded bytes of that
                // message.
                //
                // In practice, we will probably never see a MessageSet item in which
                // the message appears before the type ID, or where either field does not
                // appear exactly once.  However, in theory such cases are valid, so we
                // should be prepared to accept them.

                int typeId = 0;
                ByteString rawBytes = null; // If we encounter "message" before "typeId"
                IBuilderLite subBuilder = null;
                FieldDescriptor field = null;

                uint lastTag = WireFormat.MessageSetTag.ItemStart;
                uint tag;
                string name;
                while (input.ReadTag(out tag, out name))
                {
                    if (tag == 0 && name != null)
                    {
                        if (name == "type_id")
                        {
                            tag = WireFormat.MessageSetTag.TypeID;
                        }
                        else if (name == "message")
                        {
                            tag = WireFormat.MessageSetTag.Message;
                        }
                    }
                    if (tag == 0)
                    {
                        if (input.SkipField())
                        {
                            continue; //can't merge unknown without field tag
                        }
                        break;
                    }

                    lastTag = tag;
                    if (tag == WireFormat.MessageSetTag.TypeID)
                    {
                        typeId = 0;
                        // Zero is not a valid type ID.
                        if (input.ReadInt32(ref typeId) && typeId != 0)
                        {
                            ExtensionInfo extension = extensionRegistry[type, typeId];
                            if (extension != null)
                            {
                                field = extension.Descriptor;
                                subBuilder = extension.DefaultInstance.WeakCreateBuilderForType();
                                IMessageLite originalMessage = (IMessageLite) builder[field];
                                if (originalMessage != null)
                                {
                                    subBuilder.WeakMergeFrom(originalMessage);
                                }
                                if (rawBytes != null)
                                {
                                    // We already encountered the message.  Parse it now.
                                    // TODO(jonskeet): Check this is okay. It's subtly different from the Java, as it doesn't create an input stream from rawBytes.
                                    // In fact, why don't we just call MergeFrom(rawBytes)? And what about the extension registry?
                                    subBuilder.WeakMergeFrom(rawBytes.CreateCodedInput());
                                    rawBytes = null;
                                }
                            }
                            else
                            {
                                // Unknown extension number.  If we already saw data, put it
                                // in rawBytes.
                                if (rawBytes != null)
                                {
                                    MergeField(typeId, UnknownField.CreateBuilder().AddLengthDelimited(rawBytes).Build());
                                    rawBytes = null;
                                }
                            }
                        }
                    }
                    else if (tag == WireFormat.MessageSetTag.Message)
                    {
                        if (subBuilder != null)
                        {
                            // We already know the type, so we can parse directly from the input
                            // with no copying.  Hooray!
                            input.ReadMessage(subBuilder, extensionRegistry);
                        }
                        else if (input.ReadBytes(ref rawBytes))
                        {
                            if (typeId != 0)
                            {
                                // We don't know how to parse this.  Ignore it.
                                MergeField(typeId,
                                           UnknownField.CreateBuilder().AddLengthDelimited(rawBytes).Build());
                            }
                        }
                    }
                    else
                    {
                        // Unknown tag.  Skip it.
                        if (!input.SkipField())
                        {
                            break; // end of group
                        }
                    }
                }

                if (lastTag != WireFormat.MessageSetTag.ItemEnd)
                {
                    throw InvalidProtocolBufferException.InvalidEndTag();
                }

                if (subBuilder != null)
                {
                    builder[field] = subBuilder.WeakBuild();
                }
            }

            #region IBuilderLite Members

            bool IBuilderLite.IsInitialized
            {
                get { return fields != null; }
            }

            IBuilderLite IBuilderLite.WeakClear()
            {
                return Clear();
            }

            IBuilderLite IBuilderLite.WeakMergeFrom(IMessageLite message)
            {
                return MergeFrom((UnknownFieldSet) message);
            }

            IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data)
            {
                return MergeFrom(data);
            }

            IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data, ExtensionRegistry registry)
            {
                return MergeFrom(data);
            }

            IBuilderLite IBuilderLite.WeakMergeFrom(ICodedInputStream input)
            {
                return MergeFrom(input);
            }

            IBuilderLite IBuilderLite.WeakMergeFrom(ICodedInputStream input, ExtensionRegistry registry)
            {
                return MergeFrom(input);
            }

            IMessageLite IBuilderLite.WeakBuild()
            {
                return Build();
            }

            IMessageLite IBuilderLite.WeakBuildPartial()
            {
                return Build();
            }

            IBuilderLite IBuilderLite.WeakClone()
            {
                return Build().WeakToBuilder();
            }

            IMessageLite IBuilderLite.WeakDefaultInstanceForType
            {
                get { return DefaultInstance; }
            }

            #endregion
        }
    }
}