content: // Protocol Buffers - Google's data interchange format
  // Copyright 2008 Google Inc.  All rights reserved.
  // https://developers.google.com/protocol-buffers/
  //
  // 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.
  
  package com.google.protobuf;
  
  import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.List;
  import java.util.ListIterator;
  import java.util.Map;
  import java.util.TreeMap;
  
  /**
   * {@code UnknownFieldSet} is 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
   * compiled before the new types were added.
   *
   * <p>Every {@link Message} contains an {@code UnknownFieldSet} (and every
   * {@link Message.Builder} contains an {@link Builder}).
   *
   * <p>Most users will never need to use this class.
   *
   * @author kenton@google.com Kenton Varda
   */
  public final class UnknownFieldSet implements MessageLite {
  
    private UnknownFieldSet() {
      fields = null;
    }
  
    /** Create a new {@link Builder}. */
    public static Builder newBuilder() {
      return Builder.create();
    }
  
    /**
     * Create a new {@link Builder} and initialize it to be a copy
     * of {@code copyFrom}.
     */
    public static Builder newBuilder(final UnknownFieldSet copyFrom) {
      return newBuilder().mergeFrom(copyFrom);
    }
  
    /** Get an empty {@code UnknownFieldSet}. */
    public static UnknownFieldSet getDefaultInstance() {
      return defaultInstance;
    }
    @Override
    public UnknownFieldSet getDefaultInstanceForType() {
      return defaultInstance;
    }
    private static final UnknownFieldSet defaultInstance =
      new UnknownFieldSet(Collections.<Integer, Field>emptyMap(),
          Collections.<Integer, Field>emptyMap());
  
    /**
     * Construct an {@code UnknownFieldSet} around the given map.  The map is
     * expected to be immutable.
     */
    UnknownFieldSet(final Map<Integer, Field> fields,
        final Map<Integer, Field> fieldsDescending) {
      this.fields = fields;
    }
    private final Map<Integer, Field> fields;
  
  
    @Override
    public boolean equals(final Object other) {
      if (this == other) {
        return true;
      }
      return (other instanceof UnknownFieldSet) &&
             fields.equals(((UnknownFieldSet) other).fields);
    }
  
    @Override
    public int hashCode() {
      return fields.hashCode();
    }
  
    /** Get a map of fields in the set by number. */
    public Map<Integer, Field> asMap() {
      return fields;
    }
  
    /** Check if the given field number is present in the set. */
    public boolean hasField(final int number) {
      return fields.containsKey(number);
    }
  
    /**
     * Get a field by number.  Returns an empty field if not present.  Never
     * returns {@code null}.
     */
    public Field getField(final int number) {
      final Field result = fields.get(number);
      return (result == null) ? Field.getDefaultInstance() : result;
    }
  
    /** Serializes the set and writes it to {@code output}. */
    @Override
    public void writeTo(final CodedOutputStream output) throws IOException {
      for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
        Field field = entry.getValue();
        field.writeTo(entry.getKey(), output);
      }
    }
  
    /**
     * Converts the set to a string in protocol buffer text format. This is
     * just a trivial wrapper around
     * {@link TextFormat#printToString(UnknownFieldSet)}.
     */
    @Override
    public String toString() {
      return TextFormat.printToString(this);
    }
  
    /**
     * Serializes the message to a {@code ByteString} and returns it. This is
     * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
     */
    @Override
    public ByteString toByteString() {
      try {
        final ByteString.CodedBuilder out =
          ByteString.newCodedBuilder(getSerializedSize());
        writeTo(out.getCodedOutput());
        return out.build();
      } catch (final IOException e) {
        throw new RuntimeException(
          "Serializing to a ByteString threw an IOException (should " +
          "never happen).", e);
      }
    }
  
    /**
     * Serializes the message to a {@code byte} array and returns it.  This is
     * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
     */
    @Override
    public byte[] toByteArray() {
      try {
        final byte[] result = new byte[getSerializedSize()];
        final CodedOutputStream output = CodedOutputStream.newInstance(result);
        writeTo(output);
        output.checkNoSpaceLeft();
        return result;
      } catch (final IOException e) {
        throw new RuntimeException(
          "Serializing to a byte array threw an IOException " +
          "(should never happen).", e);
      }
    }
  
    /**
     * Serializes the message and writes it to {@code output}.  This is just a
     * trivial wrapper around {@link #writeTo(CodedOutputStream)}.
     */
    @Override
    public void writeTo(final OutputStream output) throws IOException {
      final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
      writeTo(codedOutput);
      codedOutput.flush();
    }
  
    @Override
    public void writeDelimitedTo(OutputStream output) throws IOException {
      final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
      codedOutput.writeRawVarint32(getSerializedSize());
      writeTo(codedOutput);
      codedOutput.flush();
    }
  
    /** Get the number of bytes required to encode this set. */
    @Override
    public int getSerializedSize() {
      int result = 0;
      for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
        result += entry.getValue().getSerializedSize(entry.getKey());
      }
      return result;
    }
  
    /**
     * Serializes the set and writes it to {@code output} using
     * {@code MessageSet} wire format.
     */
    public void writeAsMessageSetTo(final CodedOutputStream output)
        throws IOException {
      for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
        entry.getValue().writeAsMessageSetExtensionTo(
          entry.getKey(), output);
      }
    }
  
  
    /** Get the number of bytes required to encode this set using {@code MessageSet} wire format. */
    public int getSerializedSizeAsMessageSet() {
      int result = 0;
      for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
        result += entry.getValue().getSerializedSizeAsMessageSetExtension(
          entry.getKey());
      }
      return result;
    }
  
    @Override
    public boolean isInitialized() {
      // UnknownFieldSets do not have required fields, so they are always
      // initialized.
      return true;
    }
  
    /** Parse an {@code UnknownFieldSet} from the given input stream. */
    public static UnknownFieldSet parseFrom(final CodedInputStream input)
                                            throws IOException {
      return newBuilder().mergeFrom(input).build();
    }
  
    /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */
    public static UnknownFieldSet parseFrom(final ByteString data)
        throws InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).build();
    }
  
    /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */
    public static UnknownFieldSet parseFrom(final byte[] data)
        throws InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).build();
    }
  
    /** Parse an {@code UnknownFieldSet} from {@code input} and return it. */
    public static UnknownFieldSet parseFrom(final InputStream input)
                                            throws IOException {
      return newBuilder().mergeFrom(input).build();
    }
  
    @Override
    public Builder newBuilderForType() {
      return newBuilder();
    }
  
    @Override
    public Builder toBuilder() {
      return newBuilder().mergeFrom(this);
    }
  
    /**
     * Builder for {@link UnknownFieldSet}s.
     *
     * <p>Note that this class maintains {@link Field.Builder}s for all fields
     * in the set.  Thus, adding one element to an existing {@link Field} does not
     * require making a copy.  This is important for efficient parsing of
     * unknown repeated fields.  However, it implies that {@link Field}s cannot
     * be constructed independently, nor can two {@link UnknownFieldSet}s share
     * the same {@code Field} object.
     *
     * <p>Use {@link UnknownFieldSet#newBuilder()} to construct a {@code Builder}.
     */
    public static final class Builder implements MessageLite.Builder {
      // This constructor should never be called directly (except from 'create').
      private Builder() {}
  
      private Map<Integer, Field> 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 Field.Builder lastField;
  
      private static Builder create() {
        Builder builder = new Builder();
        builder.reinitialize();
        return builder;
      }
  
      /**
       * Get a field builder for the given field number which includes any
       * values that already exist.
       */
      private Field.Builder getFieldBuilder(final 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;
        } else {
          final Field existing = fields.get(number);
          lastFieldNumber = number;
          lastField = Field.newBuilder();
          if (existing != null) {
            lastField.mergeFrom(existing);
          }
          return lastField;
        }
      }
  
      /**
       * Build the {@link UnknownFieldSet} and return it.
       *
       * <p>Once {@code build()} has been called, the {@code Builder} will no
       * longer be usable.  Calling any method after {@code build()} will result
       * in undefined behavior and can cause a {@code NullPointerException} to be
       * thrown.
       */
      @Override
      public UnknownFieldSet build() {
        getFieldBuilder(0); // Force lastField to be built.
        final UnknownFieldSet result;
        if (fields.isEmpty()) {
          result = getDefaultInstance();
        } else {
          Map<Integer, Field> descendingFields = null;
          result = new UnknownFieldSet(Collections.unmodifiableMap(fields), descendingFields);
        }
        fields = null;
        return result;
      }
  
      @Override
      public UnknownFieldSet buildPartial() {
        // No required fields, so this is the same as build().
        return build();
      }
  
      @Override
      public Builder clone() {
        getFieldBuilder(0);  // Force lastField to be built.
        Map<Integer, Field> descendingFields = null;
        return UnknownFieldSet.newBuilder().mergeFrom(
            new UnknownFieldSet(fields, descendingFields));
      }
  
      @Override
      public UnknownFieldSet getDefaultInstanceForType() {
        return UnknownFieldSet.getDefaultInstance();
      }
  
      private void reinitialize() {
        fields = Collections.emptyMap();
        lastFieldNumber = 0;
        lastField = null;
      }
  
      /** Reset the builder to an empty set. */
      @Override
      public Builder clear() {
        reinitialize();
        return this;
      }
      
      /** Clear fields from the set with a given field number. */
      public Builder clearField(final int number) {
        if (number == 0) {
          throw new IllegalArgumentException("Zero is not a valid field number.");
        }
        if (lastField != null && lastFieldNumber == number) {
          // Discard this.
          lastField = null;
          lastFieldNumber = 0;
        }
        if (fields.containsKey(number)) {
          fields.remove(number);
        }
        return this;
      }
  
      /**
       * Merge the fields from {@code other} into this set.  If a field number
       * exists in both sets, {@code other}'s values for that field will be
       * appended to the values in this set.
       */
      public Builder mergeFrom(final UnknownFieldSet other) {
        if (other != getDefaultInstance()) {
          for (final Map.Entry<Integer, Field> entry : other.fields.entrySet()) {
            mergeField(entry.getKey(), entry.getValue());
          }
        }
        return this;
      }
  
      /**
       * Add a field to the {@code UnknownFieldSet}.  If a field with the same
       * number already exists, the two are merged.
       */
      public Builder mergeField(final int number, final Field field) {
        if (number == 0) {
          throw new IllegalArgumentException("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;
      }
  
      /**
       * Convenience method for merging a new field containing a single varint
       * value.  This is used in particular when an unknown enum value is
       * encountered.
       */
      public Builder mergeVarintField(final int number, final int value) {
        if (number == 0) {
          throw new IllegalArgumentException("Zero is not a valid field number.");
        }
        getFieldBuilder(number).addVarint(value);
        return this;
      }
  
  
      /**
       * Convenience method for merging a length-delimited field.
       *
       * <p>For use by generated code only.
       */
      public Builder mergeLengthDelimitedField(
          final int number, final ByteString value) {  
        if (number == 0) {
          throw new IllegalArgumentException("Zero is not a valid field number.");
        }
        getFieldBuilder(number).addLengthDelimited(value);
        return this;
      }
  
      /** Check if the given field number is present in the set. */
      public boolean hasField(final int number) {
        if (number == 0) {
          throw new IllegalArgumentException("Zero is not a valid field number.");
        }
        return number == lastFieldNumber || fields.containsKey(number);
      }
  
      /**
       * Add a field to the {@code UnknownFieldSet}.  If a field with the same
       * number already exists, it is removed.
       */
      public Builder addField(final int number, final Field field) {
        if (number == 0) {
          throw new IllegalArgumentException("Zero is not a valid field number.");
        }
        if (lastField != null && lastFieldNumber == number) {
          // Discard this.
          lastField = null;
          lastFieldNumber = 0;
        }
        if (fields.isEmpty()) {
          fields = new TreeMap<Integer,Field>();
        }
        fields.put(number, field);
        return this;
      }
  
      /**
       * Get all present {@code Field}s as an immutable {@code Map}.  If more
       * fields are added, the changes may or may not be reflected in this map.
       */
      public Map<Integer, Field> asMap() {
        getFieldBuilder(0);  // Force lastField to be built.
        return Collections.unmodifiableMap(fields);
      }
  
      /**
       * Parse an entire message from {@code input} and merge its fields into
       * this set.
       */
      @Override
      public Builder mergeFrom(final CodedInputStream input) throws IOException {
        while (true) {
          final int tag = input.readTag();
          if (tag == 0 || !mergeFieldFrom(tag, input)) {
            break;
          }
        }
        return this;
      }
  
      /**
       * Parse a single field from {@code input} and merge it into this set.
       * @param tag The field's tag number, which was already parsed.
       * @return {@code false} if the tag is an end group tag.
       */
      public boolean mergeFieldFrom(final int tag, final CodedInputStream input)
                                    throws IOException {
        final int number = WireFormat.getTagFieldNumber(tag);
        switch (WireFormat.getTagWireType(tag)) {
          case WireFormat.WIRETYPE_VARINT:
            getFieldBuilder(number).addVarint(input.readInt64());
            return true;
          case WireFormat.WIRETYPE_FIXED64:
            getFieldBuilder(number).addFixed64(input.readFixed64());
            return true;
          case WireFormat.WIRETYPE_LENGTH_DELIMITED:
            getFieldBuilder(number).addLengthDelimited(input.readBytes());
            return true;
          case WireFormat.WIRETYPE_START_GROUP:
            final Builder subBuilder = newBuilder();
            input.readGroup(number, subBuilder,
                            ExtensionRegistry.getEmptyRegistry());
            getFieldBuilder(number).addGroup(subBuilder.build());
            return true;
          case WireFormat.WIRETYPE_END_GROUP:
            return false;
          case WireFormat.WIRETYPE_FIXED32:
            getFieldBuilder(number).addFixed32(input.readFixed32());
            return true;
          default:
            throw InvalidProtocolBufferException.invalidWireType();
        }
      }
  
      /**
       * Parse {@code data} as an {@code UnknownFieldSet} and merge it with the
       * set being built.  This is just a small wrapper around
       * {@link #mergeFrom(CodedInputStream)}.
       */
      @Override
      public Builder mergeFrom(final ByteString data) throws InvalidProtocolBufferException {
        try {
          final CodedInputStream input = data.newCodedInput();
          mergeFrom(input);
          input.checkLastTagWas(0);
          return this;
        } catch (final InvalidProtocolBufferException e) {
          throw e;
        } catch (final IOException e) {
          throw new RuntimeException(
            "Reading from a ByteString threw an IOException (should " +
            "never happen).", e);
        }
      }
  
      /**
       * Parse {@code data} as an {@code UnknownFieldSet} and merge it with the
       * set being built.  This is just a small wrapper around
       * {@link #mergeFrom(CodedInputStream)}.
       */
      @Override
      public Builder mergeFrom(final byte[] data) throws InvalidProtocolBufferException {
        try {
          final CodedInputStream input = CodedInputStream.newInstance(data);
          mergeFrom(input);
          input.checkLastTagWas(0);
          return this;
        } catch (final InvalidProtocolBufferException e) {
          throw e;
        } catch (final IOException e) {
          throw new RuntimeException(
            "Reading from a byte array threw an IOException (should " +
            "never happen).", e);
        }
      }
  
      /**
       * Parse an {@code UnknownFieldSet} from {@code input} and merge it with the
       * set being built.  This is just a small wrapper around
       * {@link #mergeFrom(CodedInputStream)}.
       */
      @Override
      public Builder mergeFrom(final InputStream input) throws IOException {
        final CodedInputStream codedInput = CodedInputStream.newInstance(input);
        mergeFrom(codedInput);
        codedInput.checkLastTagWas(0);
        return this;
      }
  
      @Override
      public boolean mergeDelimitedFrom(InputStream input) throws IOException {
        final int firstByte = input.read();
        if (firstByte == -1) {
          return false;
        }
        final int size = CodedInputStream.readRawVarint32(firstByte, input);
        final InputStream limitedInput = new LimitedInputStream(input, size);
        mergeFrom(limitedInput);
        return true;
      }
  
      @Override
      public boolean mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
          throws IOException {
        // UnknownFieldSet has no extensions.
        return mergeDelimitedFrom(input);
      }
  
      @Override
      public Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
          throws IOException {
        // UnknownFieldSet has no extensions.
        return mergeFrom(input);
      }
  
      @Override
      public Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
          throws InvalidProtocolBufferException {
        // UnknownFieldSet has no extensions.
        return mergeFrom(data);
      }
  
      @Override
      public Builder mergeFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException {
        try {
          final CodedInputStream input =
              CodedInputStream.newInstance(data, off, len);
          mergeFrom(input);
          input.checkLastTagWas(0);
          return this;
        } catch (InvalidProtocolBufferException e) {
          throw e;
        } catch (IOException e) {
          throw new RuntimeException(
            "Reading from a byte array threw an IOException (should " +
            "never happen).", e);
        }
      }
  
      @Override
      public Builder mergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
          throws InvalidProtocolBufferException {
        // UnknownFieldSet has no extensions.
        return mergeFrom(data);
      }
  
      @Override
      public Builder mergeFrom(byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
          throws InvalidProtocolBufferException {
        // UnknownFieldSet has no extensions.
        return mergeFrom(data, off, len);
      }
  
      @Override
      public Builder mergeFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
          throws IOException {
        // UnknownFieldSet has no extensions.
        return mergeFrom(input);
      }
  
      @Override
      public Builder mergeFrom(MessageLite m) {
        if (m instanceof UnknownFieldSet) {
          return mergeFrom((UnknownFieldSet) m);
        }
        throw new IllegalArgumentException(
            "mergeFrom(MessageLite) can only merge messages of the same type.");
      }
  
      @Override
      public boolean isInitialized() {
        // UnknownFieldSets do not have required fields, so they are always
        // initialized.
        return true;
      }
    }
  
    /**
     * Represents a single field in an {@code UnknownFieldSet}.
     *
     * <p>A {@code Field} consists of five lists of values.  The lists correspond
     * to the five "wire types" used in the protocol buffer binary format.
     * The wire type of each field can be determined from the encoded form alone,
     * without knowing the field's declared type.  So, we are able to parse
     * unknown values at least this far and separate them.  Normally, only one
     * of the five lists will contain any values, since it is impossible to
     * define a valid message type that declares two different types for the
     * same field number.  However, the code is designed to allow for the case
     * where the same unknown field number is encountered using multiple different
     * wire types.
     *
     * <p>{@code Field} is an immutable class.  To construct one, you must use a
     * {@link Builder}.
     *
     * @see UnknownFieldSet
     */
    public static final class Field {
      private Field() {}
  
      /** Construct a new {@link Builder}. */
      public static Builder newBuilder() {
        return Builder.create();
      }
  
      /**
       * Construct a new {@link Builder} and initialize it to a copy of
       * {@code copyFrom}.
       */
      public static Builder newBuilder(final Field copyFrom) {
        return newBuilder().mergeFrom(copyFrom);
      }
  
      /** Get an empty {@code Field}. */
      public static Field getDefaultInstance() {
        return fieldDefaultInstance;
      }
      private static final Field fieldDefaultInstance = newBuilder().build();
  
      /** Get the list of varint values for this field. */
      public List<Long> getVarintList()               { return varint;          }
  
      /** Get the list of fixed32 values for this field. */
      public List<Integer> getFixed32List()           { return fixed32;         }
  
      /** Get the list of fixed64 values for this field. */
      public List<Long> getFixed64List()              { return fixed64;         }
  
      /** Get the list of length-delimited values for this field. */
      public List<ByteString> getLengthDelimitedList() { return lengthDelimited; }
  
      /**
       * Get the list of embedded group values for this field.  These are
       * represented using {@link UnknownFieldSet}s rather than {@link Message}s
       * since the group's type is presumably unknown.
       */
      public List<UnknownFieldSet> getGroupList()      { return group;           }
  
      @Override
      public boolean equals(final Object other) {
        if (this == other) {
          return true;
        }
        if (!(other instanceof Field)) {
          return false;
        }
        return Arrays.equals(getIdentityArray(),
            ((Field) other).getIdentityArray());
      }
  
      @Override
      public int hashCode() {
        return Arrays.hashCode(getIdentityArray());
      }
  
      /**
       * Returns the array of objects to be used to uniquely identify this
       * {@link Field} instance.
       */
      private Object[] getIdentityArray() {
        return new Object[] {
            varint,
            fixed32,
            fixed64,
            lengthDelimited,
            group};
      }
  
      /**
       * Serializes the field, including field number, and writes it to
       * {@code output}.
       */
      public void writeTo(final int fieldNumber, final CodedOutputStream output)
                          throws IOException {
        for (final long value : varint) {
          output.writeUInt64(fieldNumber, value);
        }
        for (final int value : fixed32) {
          output.writeFixed32(fieldNumber, value);
        }
        for (final long value : fixed64) {
          output.writeFixed64(fieldNumber, value);
        }
        for (final ByteString value : lengthDelimited) {
          output.writeBytes(fieldNumber, value);
        }
        for (final UnknownFieldSet value : group) {
          output.writeGroup(fieldNumber, value);
        }
      }
  
      /**
       * Get the number of bytes required to encode this field, including field
       * number.
       */
      public int getSerializedSize(final int fieldNumber) {
        int result = 0;
        for (final long value : varint) {
          result += CodedOutputStream.computeUInt64Size(fieldNumber, value);
        }
        for (final int value : fixed32) {
          result += CodedOutputStream.computeFixed32Size(fieldNumber, value);
        }
        for (final long value : fixed64) {
          result += CodedOutputStream.computeFixed64Size(fieldNumber, value);
        }
        for (final ByteString value : lengthDelimited) {
          result += CodedOutputStream.computeBytesSize(fieldNumber, value);
        }
        for (final UnknownFieldSet value : group) {
          result += CodedOutputStream.computeGroupSize(fieldNumber, value);
        }
        return result;
      }
  
      /**
       * Serializes the field, including field number, and writes it to
       * {@code output}, using {@code MessageSet} wire format.
       */
      public void writeAsMessageSetExtensionTo(
          final int fieldNumber,
          final CodedOutputStream output)
          throws IOException {
        for (final ByteString value : lengthDelimited) {
          output.writeRawMessageSetExtension(fieldNumber, value);
        }
      }
  
  
      /**
       * Get the number of bytes required to encode this field, including field number, using {@code
       * MessageSet} wire format.
       */
      public int getSerializedSizeAsMessageSetExtension(final int fieldNumber) {
        int result = 0;
        for (final ByteString value : lengthDelimited) {
          result += CodedOutputStream.computeRawMessageSetExtensionSize(
            fieldNumber, value);
        }
        return result;
      }
  
      private List<Long> varint;
      private List<Integer> fixed32;
      private List<Long> fixed64;
      private List<ByteString> lengthDelimited;
      private List<UnknownFieldSet> group;
  
      /**
       * Used to build a {@link Field} within an {@link UnknownFieldSet}.
       *
       * <p>Use {@link Field#newBuilder()} to construct a {@code Builder}.
       */
      public static final class Builder {
        // This constructor should never be called directly (except from 'create').
        private Builder() {}
  
        private static Builder create() {
          Builder builder = new Builder();
          builder.result = new Field();
          return builder;
        }
  
        private Field result;
  
        /**
         * Build the field.  After {@code build()} has been called, the
         * {@code Builder} is no longer usable.  Calling any other method will
         * result in undefined behavior and can cause a
         * {@code NullPointerException} to be thrown.
         */
        public Field build() {
          if (result.varint == null) {
            result.varint = Collections.emptyList();
          } else {
            result.varint = Collections.unmodifiableList(result.varint);
          }
          if (result.fixed32 == null) {
            result.fixed32 = Collections.emptyList();
          } else {
            result.fixed32 = Collections.unmodifiableList(result.fixed32);
          }
          if (result.fixed64 == null) {
            result.fixed64 = Collections.emptyList();
          } else {
            result.fixed64 = Collections.unmodifiableList(result.fixed64);
          }
          if (result.lengthDelimited == null) {
            result.lengthDelimited = Collections.emptyList();
          } else {
            result.lengthDelimited =
              Collections.unmodifiableList(result.lengthDelimited);
          }
          if (result.group == null) {
            result.group = Collections.emptyList();
          } else {
            result.group = Collections.unmodifiableList(result.group);
          }
  
          final Field returnMe = result;
          result = null;
          return returnMe;
        }
  
        /** Discard the field's contents. */
        public Builder clear() {
          result = new Field();
          return this;
        }
  
        /**
         * Merge the values in {@code other} into this field.  For each list
         * of values, {@code other}'s values are append to the ones in this
         * field.
         */
        public Builder mergeFrom(final Field other) {
          if (!other.varint.isEmpty()) {
            if (result.varint == null) {
              result.varint = new ArrayList<Long>();
            }
            result.varint.addAll(other.varint);
          }
          if (!other.fixed32.isEmpty()) {
            if (result.fixed32 == null) {
              result.fixed32 = new ArrayList<Integer>();
            }
            result.fixed32.addAll(other.fixed32);
          }
          if (!other.fixed64.isEmpty()) {
            if (result.fixed64 == null) {
              result.fixed64 = new ArrayList<Long>();
            }
            result.fixed64.addAll(other.fixed64);
          }
          if (!other.lengthDelimited.isEmpty()) {
            if (result.lengthDelimited == null) {
              result.lengthDelimited = new ArrayList<ByteString>();
            }
            result.lengthDelimited.addAll(other.lengthDelimited);
          }
          if (!other.group.isEmpty()) {
            if (result.group == null) {
              result.group = new ArrayList<UnknownFieldSet>();
            }
            result.group.addAll(other.group);
          }
          return this;
        }
  
        /** Add a varint value. */
        public Builder addVarint(final long value) {
          if (result.varint == null) {
            result.varint = new ArrayList<Long>();
          }
          result.varint.add(value);
          return this;
        }
  
        /** Add a fixed32 value. */
        public Builder addFixed32(final int value) {
          if (result.fixed32 == null) {
            result.fixed32 = new ArrayList<Integer>();
          }
          result.fixed32.add(value);
          return this;
        }
  
        /** Add a fixed64 value. */
        public Builder addFixed64(final long value) {
          if (result.fixed64 == null) {
            result.fixed64 = new ArrayList<Long>();
          }
          result.fixed64.add(value);
          return this;
        }
  
        /** Add a length-delimited value. */
        public Builder addLengthDelimited(final ByteString value) {
          if (result.lengthDelimited == null) {
            result.lengthDelimited = new ArrayList<ByteString>();
          }
          result.lengthDelimited.add(value);
          return this;
        }
  
        /** Add an embedded group. */
        public Builder addGroup(final UnknownFieldSet value) {
          if (result.group == null) {
            result.group = new ArrayList<UnknownFieldSet>();
          }
          result.group.add(value);
          return this;
        }
      }
    }
  
    /**
     * Parser to implement MessageLite interface.
     */
    public static final class Parser extends AbstractParser<UnknownFieldSet> {
      @Override
      public UnknownFieldSet parsePartialFrom(
          CodedInputStream input, ExtensionRegistryLite extensionRegistry)
          throws InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input);
        } catch (InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (IOException e) {
          throw new InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    }
  
    private static final Parser PARSER = new Parser();
    @Override
    public final Parser getParserForType() {
      return PARSER;
    }
  }
  