// 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.Descriptors.FieldDescriptor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * Reflection utility methods shared by both mutable and immutable messages.
 *
 * @author liujisi@google.com (Pherl Liu)
 */
class MessageReflection {

  static void writeMessageTo(
      Message message,
      Map<FieldDescriptor, Object> fields,
      CodedOutputStream output,
      boolean alwaysWriteRequiredFields)
      throws IOException {
    final boolean isMessageSet =
        message.getDescriptorForType().getOptions().getMessageSetWireFormat();
    if (alwaysWriteRequiredFields) {
      fields = new TreeMap<FieldDescriptor, Object>(fields);
      for (final FieldDescriptor field :
          message.getDescriptorForType().getFields()) {
        if (field.isRequired() && !fields.containsKey(field)) {
          fields.put(field, message.getField(field));
        }
      }
    }
    for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
        fields.entrySet()) {
      final Descriptors.FieldDescriptor field = entry.getKey();
      final Object value = entry.getValue();
      if (isMessageSet && field.isExtension() &&
          field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE &&
          !field.isRepeated()) {
        output.writeMessageSetExtension(field.getNumber(), (Message) value);
      } else {
        FieldSet.writeField(field, value, output);
      }
    }

    final UnknownFieldSet unknownFields = message.getUnknownFields();
    if (isMessageSet) {
      unknownFields.writeAsMessageSetTo(output);
    } else {
      unknownFields.writeTo(output);
    }
  }

  static int getSerializedSize(
      Message message,
      Map<FieldDescriptor, Object> fields) {
    int size = 0;
    final boolean isMessageSet =
        message.getDescriptorForType().getOptions().getMessageSetWireFormat();

    for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
        fields.entrySet()) {
      final Descriptors.FieldDescriptor field = entry.getKey();
      final Object value = entry.getValue();
      if (isMessageSet && field.isExtension() &&
          field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE &&
          !field.isRepeated()) {
        size += CodedOutputStream.computeMessageSetExtensionSize(
            field.getNumber(), (Message) value);
      } else {
        size += FieldSet.computeFieldSize(field, value);
      }
    }

    final UnknownFieldSet unknownFields = message.getUnknownFields();
    if (isMessageSet) {
      size += unknownFields.getSerializedSizeAsMessageSet();
    } else {
      size += unknownFields.getSerializedSize();
    }
    return size;
  }

  static String delimitWithCommas(List<String> parts) {
    StringBuilder result = new StringBuilder();
    for (String part : parts) {
      if (result.length() > 0) {
        result.append(", ");
      }
      result.append(part);
    }
    return result.toString();
  }

  @SuppressWarnings("unchecked")
  static boolean isInitialized(MessageOrBuilder message) {
    // Check that all required fields are present.
    for (final Descriptors.FieldDescriptor field : message
        .getDescriptorForType()
        .getFields()) {
      if (field.isRequired()) {
        if (!message.hasField(field)) {
          return false;
        }
      }
    }

    // Check that embedded messages are initialized.
    for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
        message.getAllFields().entrySet()) {
      final Descriptors.FieldDescriptor field = entry.getKey();
      if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
        if (field.isRepeated()) {
          for (final Message element
              : (List<Message>) entry.getValue()) {
            if (!element.isInitialized()) {
              return false;
            }
          }
        } else {
          if (!((Message) entry.getValue()).isInitialized()) {
            return false;
          }
        }
      }
    }

    return true;
  }

  private static String subMessagePrefix(final String prefix,
      final Descriptors.FieldDescriptor field,
      final int index) {
    final StringBuilder result = new StringBuilder(prefix);
    if (field.isExtension()) {
      result.append('(')
          .append(field.getFullName())
          .append(')');
    } else {
      result.append(field.getName());
    }
    if (index != -1) {
      result.append('[')
          .append(index)
          .append(']');
    }
    result.append('.');
    return result.toString();
  }

  private static void findMissingFields(final MessageOrBuilder message,
      final String prefix,
      final List<String> results) {
    for (final Descriptors.FieldDescriptor field :
        message.getDescriptorForType().getFields()) {
      if (field.isRequired() && !message.hasField(field)) {
        results.add(prefix + field.getName());
      }
    }

    for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
        message.getAllFields().entrySet()) {
      final Descriptors.FieldDescriptor field = entry.getKey();
      final Object value = entry.getValue();

      if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
        if (field.isRepeated()) {
          int i = 0;
          for (final Object element : (List) value) {
            findMissingFields((MessageOrBuilder) element,
                subMessagePrefix(prefix, field, i++),
                results);
          }
        } else {
          if (message.hasField(field)) {
            findMissingFields((MessageOrBuilder) value,
                subMessagePrefix(prefix, field, -1),
                results);
          }
        }
      }
    }
  }

  /**
   * Populates {@code this.missingFields} with the full "path" of each missing
   * required field in the given message.
   */
  static List<String> findMissingFields(
      final MessageOrBuilder message) {
    final List<String> results = new ArrayList<String>();
    findMissingFields(message, "", results);
    return results;
  }

  static interface MergeTarget {
    enum ContainerType {
      MESSAGE, EXTENSION_SET
    }

    /**
     * Returns the descriptor for the target.
     */
    public Descriptors.Descriptor getDescriptorForType();

    public ContainerType getContainerType();

    public ExtensionRegistry.ExtensionInfo findExtensionByName(
        ExtensionRegistry registry, String name);

    public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
        ExtensionRegistry registry, Descriptors.Descriptor containingType,
        int fieldNumber);

    /**
     * Obtains the value of the given field, or the default value if it is not
     * set.  For primitive fields, the boxed primitive value is returned. For
     * enum fields, the EnumValueDescriptor for the value is returned. For
     * embedded message fields, the sub-message is returned.  For repeated
     * fields, a java.util.List is returned.
     */
    public Object getField(Descriptors.FieldDescriptor field);

    /**
     * Returns true if the given field is set.  This is exactly equivalent to
     * calling the generated "has" accessor method corresponding to the field.
     *
     * @throws IllegalArgumentException The field is a repeated field, or {@code
     *     field.getContainingType() != getDescriptorForType()}.
     */
    boolean hasField(Descriptors.FieldDescriptor field);

    /**
     * Sets a field to the given value.  The value must be of the correct type
     * for this field, i.e. the same type that
     * {@link Message#getField(Descriptors.FieldDescriptor)}
     * would return.
     */
    MergeTarget setField(Descriptors.FieldDescriptor field, Object value);

    /**
     * Clears the field.  This is exactly equivalent to calling the generated
     * "clear" accessor method corresponding to the field.
     */
    MergeTarget clearField(Descriptors.FieldDescriptor field);

    /**
     * Sets an element of a repeated field to the given value.  The value must
     * be of the correct type for this field, i.e. the same type that {@link
     * Message#getRepeatedField(Descriptors.FieldDescriptor, int)} would return.
     *
     * @throws IllegalArgumentException The field is not a repeated field, or
     *                                  {@code field.getContainingType() !=
     *                                  getDescriptorForType()}.
     */
    MergeTarget setRepeatedField(Descriptors.FieldDescriptor field,
        int index, Object value);

    /**
     * Like {@code setRepeatedField}, but appends the value as a new element.
     *
     * @throws IllegalArgumentException The field is not a repeated field, or
     *                                  {@code field.getContainingType() !=
     *                                  getDescriptorForType()}.
     */
    MergeTarget addRepeatedField(Descriptors.FieldDescriptor field,
        Object value);

    /**
     * Returns true if the given oneof is set.
     *
     * @throws IllegalArgumentException if
     *           {@code oneof.getContainingType() != getDescriptorForType()}.
     */
    boolean hasOneof(Descriptors.OneofDescriptor oneof);

    /**
     * Clears the oneof.  This is exactly equivalent to calling the generated
     * "clear" accessor method corresponding to the oneof.
     */
    MergeTarget clearOneof(Descriptors.OneofDescriptor oneof);

    /**
     * Obtains the FieldDescriptor if the given oneof is set. Returns null
     * if no field is set.
     */
    Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof);

    /**
     * Parse the input stream into a sub field group defined based on either
     * FieldDescriptor or the default instance.
     */
    Object parseGroup(CodedInputStream input, ExtensionRegistryLite registry,
        Descriptors.FieldDescriptor descriptor, Message defaultInstance)
        throws IOException;

    /**
     * Parse the input stream into a sub field message defined based on either
     * FieldDescriptor or the default instance.
     */
    Object parseMessage(CodedInputStream input, ExtensionRegistryLite registry,
        Descriptors.FieldDescriptor descriptor, Message defaultInstance)
        throws IOException;

    /**
     * Parse from a ByteString into a sub field message defined based on either
     * FieldDescriptor or the default instance.  There isn't a varint indicating
     * the length of the message at the beginning of the input ByteString.
     */
    Object parseMessageFromBytes(
        ByteString bytes, ExtensionRegistryLite registry,
        Descriptors.FieldDescriptor descriptor, Message defaultInstance)
        throws IOException;

    /**
     * Returns the UTF8 validation level for the field.
     */
    WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor
        descriptor);

    /**
     * Returns a new merge target for a sub-field. When defaultInstance is
     * provided, it indicates the descriptor is for an extension type, and
     * implementations should create a new instance from the defaultInstance
     * prototype directly.
     */
    MergeTarget newMergeTargetForField(
        Descriptors.FieldDescriptor descriptor,
        Message defaultInstance);

    /**
     * Finishes the merge and returns the underlying object.
     */
    Object finish();
  }

  static class BuilderAdapter implements MergeTarget {

    private final Message.Builder builder;

    @Override
    public Descriptors.Descriptor getDescriptorForType() {
      return builder.getDescriptorForType();
    }

    public BuilderAdapter(Message.Builder builder) {
      this.builder = builder;
    }

    @Override
    public Object getField(Descriptors.FieldDescriptor field) {
      return builder.getField(field);
    }

    @Override
    public boolean hasField(Descriptors.FieldDescriptor field) {
      return builder.hasField(field);
    }

    @Override
    public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
      builder.setField(field, value);
      return this;
    }

    @Override
    public MergeTarget clearField(Descriptors.FieldDescriptor field) {
      builder.clearField(field);
      return this;
    }

    @Override
    public MergeTarget setRepeatedField(
        Descriptors.FieldDescriptor field, int index, Object value) {
      builder.setRepeatedField(field, index, value);
      return this;
    }

    @Override
    public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
      builder.addRepeatedField(field, value);
      return this;
    }

    @Override
    public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
      return builder.hasOneof(oneof);
    }

    @Override
    public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
      builder.clearOneof(oneof);
      return this;
    }

    @Override
    public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
      return builder.getOneofFieldDescriptor(oneof);
    }

    @Override
    public ContainerType getContainerType() {
      return ContainerType.MESSAGE;
    }

    @Override
    public ExtensionRegistry.ExtensionInfo findExtensionByName(
        ExtensionRegistry registry, String name) {
      return registry.findImmutableExtensionByName(name);
    }

    @Override
    public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
        ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
      return registry.findImmutableExtensionByNumber(containingType,
          fieldNumber);
    }

    @Override
    public Object parseGroup(
        CodedInputStream input,
        ExtensionRegistryLite extensionRegistry,
        Descriptors.FieldDescriptor field,
        Message defaultInstance)
        throws IOException {
      Message.Builder subBuilder;
      // When default instance is not null. The field is an extension field.
      if (defaultInstance != null) {
        subBuilder = defaultInstance.newBuilderForType();
      } else {
        subBuilder = builder.newBuilderForField(field);
      }
      if (!field.isRepeated()) {
        Message originalMessage = (Message) getField(field);
        if (originalMessage != null) {
          subBuilder.mergeFrom(originalMessage);
        }
      }
      input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
      return subBuilder.buildPartial();
    }

    @Override
    public Object parseMessage(
        CodedInputStream input,
        ExtensionRegistryLite extensionRegistry,
        Descriptors.FieldDescriptor field,
        Message defaultInstance)
        throws IOException {
      Message.Builder subBuilder;
      // When default instance is not null. The field is an extension field.
      if (defaultInstance != null) {
        subBuilder = defaultInstance.newBuilderForType();
      } else {
        subBuilder = builder.newBuilderForField(field);
      }
      if (!field.isRepeated()) {
        Message originalMessage = (Message) getField(field);
        if (originalMessage != null) {
          subBuilder.mergeFrom(originalMessage);
        }
      }
      input.readMessage(subBuilder, extensionRegistry);
      return subBuilder.buildPartial();
    }

    @Override
    public Object parseMessageFromBytes(
        ByteString bytes,
        ExtensionRegistryLite extensionRegistry,
        Descriptors.FieldDescriptor field,
        Message defaultInstance)
        throws IOException {
      Message.Builder subBuilder;
      // When default instance is not null. The field is an extension field.
      if (defaultInstance != null) {
        subBuilder = defaultInstance.newBuilderForType();
      } else {
        subBuilder = builder.newBuilderForField(field);
      }
      if (!field.isRepeated()) {
        Message originalMessage = (Message) getField(field);
        if (originalMessage != null) {
          subBuilder.mergeFrom(originalMessage);
        }
      }
      subBuilder.mergeFrom(bytes, extensionRegistry);
      return subBuilder.buildPartial();
    }

    @Override
    public MergeTarget newMergeTargetForField(
        Descriptors.FieldDescriptor field, Message defaultInstance) {
      if (defaultInstance != null) {
        return new BuilderAdapter(
            defaultInstance.newBuilderForType());
      } else {
        return new BuilderAdapter(builder.newBuilderForField(field));
      }
    }

    @Override
    public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
      if (descriptor.needsUtf8Check()) {
        return WireFormat.Utf8Validation.STRICT;
      }
      // TODO(liujisi): support lazy strings for repeated fields.
      if (!descriptor.isRepeated()
          && builder instanceof GeneratedMessage.Builder) {
        return WireFormat.Utf8Validation.LAZY;
      }
      return WireFormat.Utf8Validation.LOOSE;
    }

    @Override
    public Object finish() {
      return builder.buildPartial();
    }
  }


  static class ExtensionAdapter implements MergeTarget {

    private final FieldSet<Descriptors.FieldDescriptor> extensions;

    ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions) {
      this.extensions = extensions;
    }

    @Override
    public Descriptors.Descriptor getDescriptorForType() {
      throw new UnsupportedOperationException(
          "getDescriptorForType() called on FieldSet object");
    }

    @Override
    public Object getField(Descriptors.FieldDescriptor field) {
      return extensions.getField(field);
    }

    @Override
    public boolean hasField(Descriptors.FieldDescriptor field) {
      return extensions.hasField(field);
    }

    @Override
    public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
      extensions.setField(field, value);
      return this;
    }

    @Override
    public MergeTarget clearField(Descriptors.FieldDescriptor field) {
      extensions.clearField(field);
      return this;
    }

    @Override
    public MergeTarget setRepeatedField(
        Descriptors.FieldDescriptor field, int index, Object value) {
      extensions.setRepeatedField(field, index, value);
      return this;
    }

    @Override
    public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
      extensions.addRepeatedField(field, value);
      return this;
    }

    @Override
    public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
      return false;
    }

    @Override
    public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
      // Nothing to clear.
      return this;
    }

    @Override
    public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
      return null;
    }

    @Override
    public ContainerType getContainerType() {
      return ContainerType.EXTENSION_SET;
    }

    @Override
    public ExtensionRegistry.ExtensionInfo findExtensionByName(
        ExtensionRegistry registry, String name) {
      return registry.findImmutableExtensionByName(name);
    }

    @Override
    public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
        ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
      return registry.findImmutableExtensionByNumber(containingType,
          fieldNumber);
    }

    @Override
    public Object parseGroup(
        CodedInputStream input,
        ExtensionRegistryLite registry,
        Descriptors.FieldDescriptor field,
        Message defaultInstance)
        throws IOException {
      Message.Builder subBuilder =
          defaultInstance.newBuilderForType();
      if (!field.isRepeated()) {
        Message originalMessage = (Message) getField(field);
        if (originalMessage != null) {
          subBuilder.mergeFrom(originalMessage);
        }
      }
      input.readGroup(field.getNumber(), subBuilder, registry);
      return subBuilder.buildPartial();
    }

    @Override
    public Object parseMessage(
        CodedInputStream input,
        ExtensionRegistryLite registry,
        Descriptors.FieldDescriptor field,
        Message defaultInstance)
        throws IOException {
      Message.Builder subBuilder =
          defaultInstance.newBuilderForType();
      if (!field.isRepeated()) {
        Message originalMessage = (Message) getField(field);
        if (originalMessage != null) {
          subBuilder.mergeFrom(originalMessage);
        }
      }
      input.readMessage(subBuilder, registry);
      return subBuilder.buildPartial();
    }

    @Override
    public Object parseMessageFromBytes(
        ByteString bytes,
        ExtensionRegistryLite registry,
        Descriptors.FieldDescriptor field,
        Message defaultInstance)
        throws IOException {
      Message.Builder subBuilder =  defaultInstance.newBuilderForType();
      if (!field.isRepeated()) {
        Message originalMessage = (Message) getField(field);
        if (originalMessage != null) {
          subBuilder.mergeFrom(originalMessage);
        }
      }
      subBuilder.mergeFrom(bytes, registry);
      return subBuilder.buildPartial();
    }

    @Override
    public MergeTarget newMergeTargetForField(
        Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
      throw new UnsupportedOperationException(
          "newMergeTargetForField() called on FieldSet object");
    }

    @Override
    public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
      if (descriptor.needsUtf8Check()) {
        return WireFormat.Utf8Validation.STRICT;
      }
      // TODO(liujisi): support lazy strings for ExtesnsionSet.
      return WireFormat.Utf8Validation.LOOSE;
    }

    @Override
    public Object finish() {
      throw new UnsupportedOperationException(
          "finish() called on FieldSet object");
    }
  }

  /**
   * Parses a single field into MergeTarget. The target can be Message.Builder, FieldSet or
   * MutableMessage.
   *
   * <p>Package-private because it is used by GeneratedMessage.ExtendableMessage.
   *
   * @param tag The tag, which should have already been read.
   * @param unknownFields If not null, unknown fields will be merged to this {@link
   *     UnknownFieldSet}, otherwise unknown fields will be discarded.
   * @return {@code true} unless the tag is an end-group tag.
   */
  static boolean mergeFieldFrom(
      CodedInputStream input,
      UnknownFieldSet.Builder unknownFields,
      ExtensionRegistryLite extensionRegistry,
      Descriptors.Descriptor type,
      MergeTarget target,
      int tag)
      throws IOException {
    if (type.getOptions().getMessageSetWireFormat() &&
        tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
      mergeMessageSetExtensionFromCodedStream(
          input, unknownFields, extensionRegistry, type, target);
      return true;
    }

    final int wireType = WireFormat.getTagWireType(tag);
    final int fieldNumber = WireFormat.getTagFieldNumber(tag);

    final Descriptors.FieldDescriptor field;
    Message defaultInstance = null;

    if (type.isExtensionNumber(fieldNumber)) {
      // extensionRegistry may be either ExtensionRegistry or
      // ExtensionRegistryLite.  Since the type we are parsing is a full
      // message, only a full ExtensionRegistry could possibly contain
      // extensions of it.  Otherwise we will treat the registry as if it
      // were empty.
      if (extensionRegistry instanceof ExtensionRegistry) {
        final ExtensionRegistry.ExtensionInfo extension =
            target.findExtensionByNumber((ExtensionRegistry) extensionRegistry,
                type, fieldNumber);
        if (extension == null) {
          field = null;
        } else {
          field = extension.descriptor;
          defaultInstance = extension.defaultInstance;
          if (defaultInstance == null &&
              field.getJavaType()
                  == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
            throw new IllegalStateException(
                "Message-typed extension lacked default instance: " +
                    field.getFullName());
          }
        }
      } else {
        field = null;
      }
    } else if (target.getContainerType() == MergeTarget.ContainerType.MESSAGE) {
      field = type.findFieldByNumber(fieldNumber);
    } else {
      field = null;
    }

    boolean unknown = false;
    boolean packed = false;
    if (field == null) {
      unknown = true;  // Unknown field.
    } else if (wireType == FieldSet.getWireFormatForFieldType(
        field.getLiteType(),
        false  /* isPacked */)) {
      packed = false;
    } else if (field.isPackable() &&
        wireType == FieldSet.getWireFormatForFieldType(
            field.getLiteType(),
            true  /* isPacked */)) {
      packed = true;
    } else {
      unknown = true;  // Unknown wire type.
    }

    if (unknown) {  // Unknown field or wrong wire type.  Skip.
      if (unknownFields != null) {
        return unknownFields.mergeFieldFrom(tag, input);
      } else {
        return input.skipField(tag);
      }
    }

    if (packed) {
      final int length = input.readRawVarint32();
      final int limit = input.pushLimit(length);
      if (field.getLiteType() == WireFormat.FieldType.ENUM) {
        while (input.getBytesUntilLimit() > 0) {
          final int rawValue = input.readEnum();
          if (field.getFile().supportsUnknownEnumValue()) {
            target.addRepeatedField(field,
                field.getEnumType().findValueByNumberCreatingIfUnknown(rawValue));
          } else {
            final Object value = field.getEnumType().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;
            }
            target.addRepeatedField(field, value);
          }
        }
      } else {
        while (input.getBytesUntilLimit() > 0) {
          final Object value = WireFormat.readPrimitiveField(
              input, field.getLiteType(), target.getUtf8Validation(field));
          target.addRepeatedField(field, value);
        }
      }
      input.popLimit(limit);
    } else {
      final Object value;
      switch (field.getType()) {
        case GROUP: {
          value = target
              .parseGroup(input, extensionRegistry, field, defaultInstance);
          break;
        }
        case MESSAGE: {
          value = target
              .parseMessage(input, extensionRegistry, field, defaultInstance);
          break;
        }
        case ENUM:
          final int rawValue = input.readEnum();
          if (field.getFile().supportsUnknownEnumValue()) {
            value = field.getEnumType().findValueByNumberCreatingIfUnknown(rawValue);
          } else {
            value = field.getEnumType().findValueByNumber(rawValue);
            // If the number isn't recognized as a valid value for this enum,
            // drop it.
            if (value == null) {
              if (unknownFields != null) {
                unknownFields.mergeVarintField(fieldNumber, rawValue);
              }
              return true;
            }
          }
          break;
        default:
          value = WireFormat.readPrimitiveField(
              input, field.getLiteType(), target.getUtf8Validation(field));
          break;
      }

      if (field.isRepeated()) {
        target.addRepeatedField(field, value);
      } else {
        target.setField(field, value);
      }
    }

    return true;
  }

  /**
   * Called by {@code #mergeFieldFrom()} to parse a MessageSet extension into
   * MergeTarget.
   */
  private static void mergeMessageSetExtensionFromCodedStream(
      CodedInputStream input,
      UnknownFieldSet.Builder unknownFields,
      ExtensionRegistryLite extensionRegistry,
      Descriptors.Descriptor type,
      MergeTarget target) throws IOException {

    // 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"
    ExtensionRegistry.ExtensionInfo extension = null;

    // Read bytes from input, if we get it's type first then parse it eagerly,
    // otherwise we store the raw bytes in a local variable.
    while (true) {
      final int tag = input.readTag();
      if (tag == 0) {
        break;
      }

      if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
        typeId = input.readUInt32();
        if (typeId != 0) {
          // extensionRegistry may be either ExtensionRegistry or
          // ExtensionRegistryLite. Since the type we are parsing is a full
          // message, only a full ExtensionRegistry could possibly contain
          // extensions of it. Otherwise we will treat the registry as if it
          // were empty.
          if (extensionRegistry instanceof ExtensionRegistry) {
            extension = target.findExtensionByNumber(
                (ExtensionRegistry) extensionRegistry, type, typeId);
          }
        }

      } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
        if (typeId != 0) {
          if (extension != null &&
              ExtensionRegistryLite.isEagerlyParseMessageSets()) {
            // We already know the type, so we can parse directly from the
            // input with no copying.  Hooray!
            eagerlyMergeMessageSetExtension(
                input, extension, extensionRegistry, target);
            rawBytes = null;
            continue;
          }
        }
        // We haven't seen a type ID yet or we want parse message lazily.
        rawBytes = input.readBytes();

      } else { // Unknown tag. Skip it.
        if (!input.skipField(tag)) {
          break; // End of group
        }
      }
    }
    input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG);

    // Process the raw bytes.
    if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID.
      if (extension != null) { // We known the type
        mergeMessageSetExtensionFromBytes(
            rawBytes, extension, extensionRegistry, target);
      } else { // We don't know how to parse this. Ignore it.
        if (rawBytes != null && unknownFields != null) {
          unknownFields.mergeField(typeId, UnknownFieldSet.Field.newBuilder()
              .addLengthDelimited(rawBytes).build());
        }
      }
    }
  }

  private static void mergeMessageSetExtensionFromBytes(
      ByteString rawBytes,
      ExtensionRegistry.ExtensionInfo extension,
      ExtensionRegistryLite extensionRegistry,
      MergeTarget target) throws IOException {

    Descriptors.FieldDescriptor field = extension.descriptor;
    boolean hasOriginalValue = target.hasField(field);

    if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) {
      // If the field already exists, we just parse the field.
      Object value = target.parseMessageFromBytes(
          rawBytes, extensionRegistry,field, extension.defaultInstance);
      target.setField(field, value);
    } else {
      // Use LazyField to load MessageSet lazily.
      LazyField lazyField = new LazyField(
          extension.defaultInstance, extensionRegistry, rawBytes);
      target.setField(field, lazyField);
    }
  }

  private static void eagerlyMergeMessageSetExtension(
      CodedInputStream input,
      ExtensionRegistry.ExtensionInfo extension,
      ExtensionRegistryLite extensionRegistry,
      MergeTarget target) throws IOException {
    Descriptors.FieldDescriptor field = extension.descriptor;
    Object value = target.parseMessage(input, extensionRegistry, field,
                                       extension.defaultInstance);
    target.setField(field, value);
  }
}
