root/third_party/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. getParserForType
  2. parseUnknownField
  3. makeExtensionsImmutable
  4. SuppressWarnings
  5. clear
  6. clone
  7. mergeFrom
  8. getDefaultInstanceForType
  9. parseUnknownField
  10. hasExtension
  11. getExtensionCount
  12. getExtension
  13. getExtension
  14. verifyExtensionContainingType
  15. hasExtension
  16. getExtensionCount
  17. SuppressWarnings
  18. getExtension
  19. SuppressWarnings
  20. getExtension
  21. extensionsAreInitialized
  22. parseUnknownField
  23. makeExtensionsImmutable
  24. writeUntil
  25. newExtensionWriter
  26. newMessageSetExtensionWriter
  27. extensionsSerializedSize
  28. extensionsSerializedSizeAsMessageSet
  29. SuppressWarnings
  30. clear
  31. ensureExtensionsIsMutable
  32. buildExtensions
  33. verifyExtensionContainingType
  34. hasExtension
  35. getExtensionCount
  36. SuppressWarnings
  37. getExtension
  38. SuppressWarnings
  39. getExtension
  40. clone
  41. setExtension
  42. setExtension
  43. addExtension
  44. clearExtension
  45. extensionsAreInitialized
  46. parseUnknownField
  47. mergeExtensionFields
  48. parseUnknownField
  49. newSingularGeneratedExtension
  50. newRepeatedGeneratedExtension
  51. getNumber
  52. getLiteType
  53. getLiteJavaType
  54. isRepeated
  55. isPacked
  56. getEnumType
  57. SuppressWarnings
  58. internalMergeFrom
  59. compareTo
  60. getContainingTypeDefaultInstance
  61. getNumber
  62. getMessageDefaultInstance
  63. SuppressWarnings
  64. readResolve
  65. writeReplace

// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// 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.

package com.google.protobuf;

import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Lite version of {@link GeneratedMessage}.
 *
 * @author kenton@google.com Kenton Varda
 */
public abstract class GeneratedMessageLite extends AbstractMessageLite
    implements Serializable {
  private static final long serialVersionUID = 1L;

  protected GeneratedMessageLite() {
  }

  protected GeneratedMessageLite(Builder builder) {
  }

  public Parser<? extends MessageLite> getParserForType() {
    throw new UnsupportedOperationException(
        "This is supposed to be overridden by subclasses.");
  }

  /**
   * Called by subclasses to parse an unknown field.
   * @return {@code true} unless the tag is an end-group tag.
   */
  protected boolean parseUnknownField(
      CodedInputStream input,
      ExtensionRegistryLite extensionRegistry,
      int tag) throws IOException {
    return input.skipField(tag);
  }

  /**
   * Used by parsing constructors in generated classes.
   */
  protected void makeExtensionsImmutable() {
    // Noop for messages without extensions.
  }

  @SuppressWarnings("unchecked")
  public abstract static class Builder<MessageType extends GeneratedMessageLite,
                                       BuilderType extends Builder>
      extends AbstractMessageLite.Builder<BuilderType> {
    protected Builder() {}

    //@Override (Java 1.6 override semantics, but we must support 1.5)
    public BuilderType clear() {
      return (BuilderType) this;
    }

    // This is implemented here only to work around an apparent bug in the
    // Java compiler and/or build system.  See bug #1898463.  The mere presence
    // of this dummy clone() implementation makes it go away.
    @Override
    public BuilderType clone() {
      throw new UnsupportedOperationException(
          "This is supposed to be overridden by subclasses.");
    }

    /** All subclasses implement this. */
    public abstract BuilderType mergeFrom(MessageType message);

    // Defined here for return type covariance.
    public abstract MessageType getDefaultInstanceForType();

    /**
     * Called by subclasses to parse an unknown field.
     * @return {@code true} unless the tag is an end-group tag.
     */
    protected boolean parseUnknownField(
        CodedInputStream input,
        ExtensionRegistryLite extensionRegistry,
        int tag) throws IOException {
      return input.skipField(tag);
    }
  }

  // =================================================================
  // Extensions-related stuff

  /**
   * Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}.
   */
  public interface ExtendableMessageOrBuilder<
      MessageType extends ExtendableMessage> extends MessageLiteOrBuilder {

    /** Check if a singular extension is present. */
    <Type> boolean hasExtension(
        GeneratedExtension<MessageType, Type> extension);

    /** Get the number of elements in a repeated extension. */
    <Type> int getExtensionCount(
        GeneratedExtension<MessageType, List<Type>> extension);

    /** Get the value of an extension. */
    <Type> Type getExtension(GeneratedExtension<MessageType, Type> extension);

    /** Get one element of a repeated extension. */
    <Type> Type getExtension(
        GeneratedExtension<MessageType, List<Type>> extension,
        int index);
  }

  /**
   * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}.
   */
  public abstract static class ExtendableMessage<
        MessageType extends ExtendableMessage<MessageType>>
      extends GeneratedMessageLite
      implements ExtendableMessageOrBuilder<MessageType> {

    private final FieldSet<ExtensionDescriptor> extensions;

    protected ExtendableMessage() {
      this.extensions = FieldSet.newFieldSet();
    }

    protected ExtendableMessage(ExtendableBuilder<MessageType, ?> builder) {
      this.extensions = builder.buildExtensions();
    }

    private void verifyExtensionContainingType(
        final GeneratedExtension<MessageType, ?> extension) {
      if (extension.getContainingTypeDefaultInstance() !=
          getDefaultInstanceForType()) {
        // This can only happen if someone uses unchecked operations.
        throw new IllegalArgumentException(
          "This extension is for a different message type.  Please make " +
          "sure that you are not suppressing any generics type warnings.");
      }
    }

    /** Check if a singular extension is present. */
    //@Override (Java 1.6 override semantics, but we must support 1.5)
    public final <Type> boolean hasExtension(
        final GeneratedExtension<MessageType, Type> extension) {
      verifyExtensionContainingType(extension);
      return extensions.hasField(extension.descriptor);
    }

    /** Get the number of elements in a repeated extension. */
    //@Override (Java 1.6 override semantics, but we must support 1.5)
    public final <Type> int getExtensionCount(
        final GeneratedExtension<MessageType, List<Type>> extension) {
      verifyExtensionContainingType(extension);
      return extensions.getRepeatedFieldCount(extension.descriptor);
    }

    /** Get the value of an extension. */
    //@Override (Java 1.6 override semantics, but we must support 1.5)
    @SuppressWarnings("unchecked")
    public final <Type> Type getExtension(
        final GeneratedExtension<MessageType, Type> extension) {
      verifyExtensionContainingType(extension);
      final Object value = extensions.getField(extension.descriptor);
      if (value == null) {
        return extension.defaultValue;
      } else {
        return (Type) value;
      }
    }

    /** Get one element of a repeated extension. */
    //@Override (Java 1.6 override semantics, but we must support 1.5)
    @SuppressWarnings("unchecked")
    public final <Type> Type getExtension(
        final GeneratedExtension<MessageType, List<Type>> extension,
        final int index) {
      verifyExtensionContainingType(extension);
      return (Type) extensions.getRepeatedField(extension.descriptor, index);
    }

    /** Called by subclasses to check if all extensions are initialized. */
    protected boolean extensionsAreInitialized() {
      return extensions.isInitialized();
    }

    /**
     * Called by subclasses to parse an unknown field or an extension.
     * @return {@code true} unless the tag is an end-group tag.
     */
    @Override
    protected boolean parseUnknownField(
        CodedInputStream input,
        ExtensionRegistryLite extensionRegistry,
        int tag) throws IOException {
      return GeneratedMessageLite.parseUnknownField(
          extensions,
          getDefaultInstanceForType(),
          input,
          extensionRegistry,
          tag);
    }

    /**
     * Used by parsing constructors in generated classes.
     */
    @Override
    protected void makeExtensionsImmutable() {
      extensions.makeImmutable();
    }

    /**
     * Used by subclasses to serialize extensions.  Extension ranges may be
     * interleaved with field numbers, but we must write them in canonical
     * (sorted by field number) order.  ExtensionWriter helps us write
     * individual ranges of extensions at once.
     */
    protected class ExtensionWriter {
      // Imagine how much simpler this code would be if Java iterators had
      // a way to get the next element without advancing the iterator.

      private final Iterator<Map.Entry<ExtensionDescriptor, Object>> iter =
            extensions.iterator();
      private Map.Entry<ExtensionDescriptor, Object> next;
      private final boolean messageSetWireFormat;

      private ExtensionWriter(boolean messageSetWireFormat) {
        if (iter.hasNext()) {
          next = iter.next();
        }
        this.messageSetWireFormat = messageSetWireFormat;
      }

      public void writeUntil(final int end, final CodedOutputStream output)
                             throws IOException {
        while (next != null && next.getKey().getNumber() < end) {
          ExtensionDescriptor extension = next.getKey();
          if (messageSetWireFormat && extension.getLiteJavaType() ==
                  WireFormat.JavaType.MESSAGE &&
              !extension.isRepeated()) {
            output.writeMessageSetExtension(extension.getNumber(),
                                            (MessageLite) next.getValue());
          } else {
            FieldSet.writeField(extension, next.getValue(), output);
          }
          if (iter.hasNext()) {
            next = iter.next();
          } else {
            next = null;
          }
        }
      }
    }

    protected ExtensionWriter newExtensionWriter() {
      return new ExtensionWriter(false);
    }
    protected ExtensionWriter newMessageSetExtensionWriter() {
      return new ExtensionWriter(true);
    }

    /** Called by subclasses to compute the size of extensions. */
    protected int extensionsSerializedSize() {
      return extensions.getSerializedSize();
    }
    protected int extensionsSerializedSizeAsMessageSet() {
      return extensions.getMessageSetSerializedSize();
    }
  }

  /**
   * Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}.
   */
  @SuppressWarnings("unchecked")
  public abstract static class ExtendableBuilder<
        MessageType extends ExtendableMessage<MessageType>,
        BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
      extends Builder<MessageType, BuilderType>
      implements ExtendableMessageOrBuilder<MessageType> {
    protected ExtendableBuilder() {}

    private FieldSet<ExtensionDescriptor> extensions = FieldSet.emptySet();
    private boolean extensionsIsMutable;

    @Override
    public BuilderType clear() {
      extensions.clear();
      extensionsIsMutable = false;
      return super.clear();
    }

    private void ensureExtensionsIsMutable() {
      if (!extensionsIsMutable) {
        extensions = extensions.clone();
        extensionsIsMutable = true;
      }
    }

    /**
     * Called by the build code path to create a copy of the extensions for
     * building the message.
     */
    private FieldSet<ExtensionDescriptor> buildExtensions() {
      extensions.makeImmutable();
      extensionsIsMutable = false;
      return extensions;
    }

    private void verifyExtensionContainingType(
        final GeneratedExtension<MessageType, ?> extension) {
      if (extension.getContainingTypeDefaultInstance() !=
          getDefaultInstanceForType()) {
        // This can only happen if someone uses unchecked operations.
        throw new IllegalArgumentException(
          "This extension is for a different message type.  Please make " +
          "sure that you are not suppressing any generics type warnings.");
      }
    }

    /** Check if a singular extension is present. */
    //@Override (Java 1.6 override semantics, but we must support 1.5)
    public final <Type> boolean hasExtension(
        final GeneratedExtension<MessageType, Type> extension) {
      verifyExtensionContainingType(extension);
      return extensions.hasField(extension.descriptor);
    }

    /** Get the number of elements in a repeated extension. */
    //@Override (Java 1.6 override semantics, but we must support 1.5)
    public final <Type> int getExtensionCount(
        final GeneratedExtension<MessageType, List<Type>> extension) {
      verifyExtensionContainingType(extension);
      return extensions.getRepeatedFieldCount(extension.descriptor);
    }

    /** Get the value of an extension. */
    //@Override (Java 1.6 override semantics, but we must support 1.5)
    @SuppressWarnings("unchecked")
    public final <Type> Type getExtension(
        final GeneratedExtension<MessageType, Type> extension) {
      verifyExtensionContainingType(extension);
      final Object value = extensions.getField(extension.descriptor);
      if (value == null) {
        return extension.defaultValue;
      } else {
        return (Type) value;
      }
    }

    /** Get one element of a repeated extension. */
    @SuppressWarnings("unchecked")
    //@Override (Java 1.6 override semantics, but we must support 1.5)
    public final <Type> Type getExtension(
        final GeneratedExtension<MessageType, List<Type>> extension,
        final int index) {
      verifyExtensionContainingType(extension);
      return (Type) extensions.getRepeatedField(extension.descriptor, index);
    }

    // This is implemented here only to work around an apparent bug in the
    // Java compiler and/or build system.  See bug #1898463.  The mere presence
    // of this dummy clone() implementation makes it go away.
    @Override
    public BuilderType clone() {
      throw new UnsupportedOperationException(
          "This is supposed to be overridden by subclasses.");
    }

    /** Set the value of an extension. */
    public final <Type> BuilderType setExtension(
        final GeneratedExtension<MessageType, Type> extension,
        final Type value) {
      verifyExtensionContainingType(extension);
      ensureExtensionsIsMutable();
      extensions.setField(extension.descriptor, value);
      return (BuilderType) this;
    }

    /** Set the value of one element of a repeated extension. */
    public final <Type> BuilderType setExtension(
        final GeneratedExtension<MessageType, List<Type>> extension,
        final int index, final Type value) {
      verifyExtensionContainingType(extension);
      ensureExtensionsIsMutable();
      extensions.setRepeatedField(extension.descriptor, index, value);
      return (BuilderType) this;
    }

    /** Append a value to a repeated extension. */
    public final <Type> BuilderType addExtension(
        final GeneratedExtension<MessageType, List<Type>> extension,
        final Type value) {
      verifyExtensionContainingType(extension);
      ensureExtensionsIsMutable();
      extensions.addRepeatedField(extension.descriptor, value);
      return (BuilderType) this;
    }

    /** Clear an extension. */
    public final <Type> BuilderType clearExtension(
        final GeneratedExtension<MessageType, ?> extension) {
      verifyExtensionContainingType(extension);
      ensureExtensionsIsMutable();
      extensions.clearField(extension.descriptor);
      return (BuilderType) this;
    }

    /** Called by subclasses to check if all extensions are initialized. */
    protected boolean extensionsAreInitialized() {
      return extensions.isInitialized();
    }

    /**
     * Called by subclasses to parse an unknown field or an extension.
     * @return {@code true} unless the tag is an end-group tag.
     */
    @Override
    protected boolean parseUnknownField(
        CodedInputStream input,
        ExtensionRegistryLite extensionRegistry,
        int tag) throws IOException {
      ensureExtensionsIsMutable();
      return GeneratedMessageLite.parseUnknownField(
          extensions,
          getDefaultInstanceForType(),
          input,
          extensionRegistry,
          tag);
    }

    protected final void mergeExtensionFields(final MessageType other) {
      ensureExtensionsIsMutable();
      extensions.mergeFrom(((ExtendableMessage) other).extensions);
    }
  }

  // -----------------------------------------------------------------

  /**
   * Parse an unknown field or an extension.
   * @return {@code true} unless the tag is an end-group tag.
   */
  private static <MessageType extends MessageLite>
      boolean parseUnknownField(
          FieldSet<ExtensionDescriptor> extensions,
          MessageType defaultInstance,
          CodedInputStream input,
          ExtensionRegistryLite extensionRegistry,
          int tag) throws IOException {
    int wireType = WireFormat.getTagWireType(tag);
    int fieldNumber = WireFormat.getTagFieldNumber(tag);

    GeneratedExtension<MessageType, ?> extension =
      extensionRegistry.findLiteExtensionByNumber(
          defaultInstance, fieldNumber);

    boolean unknown = false;
    boolean packed = false;
    if (extension == null) {
      unknown = true;  // Unknown field.
    } else if (wireType == FieldSet.getWireFormatForFieldType(
                 extension.descriptor.getLiteType(),
                 false  /* isPacked */)) {
      packed = false;  // Normal, unpacked value.
    } else if (extension.descriptor.isRepeated &&
               extension.descriptor.type.isPackable() &&
               wireType == FieldSet.getWireFormatForFieldType(
                 extension.descriptor.getLiteType(),
                 true  /* isPacked */)) {
      packed = true;  // Packed value.
    } else {
      unknown = true;  // Wrong wire type.
    }

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

    if (packed) {
      int length = input.readRawVarint32();
      int limit = input.pushLimit(length);
      if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) {
        while (input.getBytesUntilLimit() > 0) {
          int rawValue = input.readEnum();
          Object value =
              extension.descriptor.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;
          }
          extensions.addRepeatedField(extension.descriptor, value);
        }
      } else {
        while (input.getBytesUntilLimit() > 0) {
          Object value =
            FieldSet.readPrimitiveField(input,
                                        extension.descriptor.getLiteType());
          extensions.addRepeatedField(extension.descriptor, value);
        }
      }
      input.popLimit(limit);
    } else {
      Object value;
      switch (extension.descriptor.getLiteJavaType()) {
        case MESSAGE: {
          MessageLite.Builder subBuilder = null;
          if (!extension.descriptor.isRepeated()) {
            MessageLite existingValue =
                (MessageLite) extensions.getField(extension.descriptor);
            if (existingValue != null) {
              subBuilder = existingValue.toBuilder();
            }
          }
          if (subBuilder == null) {
            subBuilder = extension.messageDefaultInstance.newBuilderForType();
          }
          if (extension.descriptor.getLiteType() ==
              WireFormat.FieldType.GROUP) {
            input.readGroup(extension.getNumber(),
                            subBuilder, extensionRegistry);
          } else {
            input.readMessage(subBuilder, extensionRegistry);
          }
          value = subBuilder.build();
          break;
        }
        case ENUM:
          int rawValue = input.readEnum();
          value = extension.descriptor.getEnumType()
                           .findValueByNumber(rawValue);
          // If the number isn't recognized as a valid value for this enum,
          // drop it.
          if (value == null) {
            return true;
          }
          break;
        default:
          value = FieldSet.readPrimitiveField(input,
              extension.descriptor.getLiteType());
          break;
      }

      if (extension.descriptor.isRepeated()) {
        extensions.addRepeatedField(extension.descriptor, value);
      } else {
        extensions.setField(extension.descriptor, value);
      }
    }

    return true;
  }

  // -----------------------------------------------------------------

  /** For use by generated code only. */
  public static <ContainingType extends MessageLite, Type>
      GeneratedExtension<ContainingType, Type>
          newSingularGeneratedExtension(
              final ContainingType containingTypeDefaultInstance,
              final Type defaultValue,
              final MessageLite messageDefaultInstance,
              final Internal.EnumLiteMap<?> enumTypeMap,
              final int number,
              final WireFormat.FieldType type) {
    return new GeneratedExtension<ContainingType, Type>(
        containingTypeDefaultInstance,
        defaultValue,
        messageDefaultInstance,
        new ExtensionDescriptor(enumTypeMap, number, type,
                                false /* isRepeated */,
                                false /* isPacked */));
  }

  /** For use by generated code only. */
  public static <ContainingType extends MessageLite, Type>
      GeneratedExtension<ContainingType, Type>
          newRepeatedGeneratedExtension(
              final ContainingType containingTypeDefaultInstance,
              final MessageLite messageDefaultInstance,
              final Internal.EnumLiteMap<?> enumTypeMap,
              final int number,
              final WireFormat.FieldType type,
              final boolean isPacked) {
    @SuppressWarnings("unchecked")  // Subclasses ensure Type is a List
    Type emptyList = (Type) Collections.emptyList();
    return new GeneratedExtension<ContainingType, Type>(
        containingTypeDefaultInstance,
        emptyList,
        messageDefaultInstance,
        new ExtensionDescriptor(
            enumTypeMap, number, type, true /* isRepeated */, isPacked));
  }

  private static final class ExtensionDescriptor
      implements FieldSet.FieldDescriptorLite<
        ExtensionDescriptor> {
    private ExtensionDescriptor(
        final Internal.EnumLiteMap<?> enumTypeMap,
        final int number,
        final WireFormat.FieldType type,
        final boolean isRepeated,
        final boolean isPacked) {
      this.enumTypeMap = enumTypeMap;
      this.number = number;
      this.type = type;
      this.isRepeated = isRepeated;
      this.isPacked = isPacked;
    }

    private final Internal.EnumLiteMap<?> enumTypeMap;
    private final int number;
    private final WireFormat.FieldType type;
    private final boolean isRepeated;
    private final boolean isPacked;

    public int getNumber() {
      return number;
    }

    public WireFormat.FieldType getLiteType() {
      return type;
    }

    public WireFormat.JavaType getLiteJavaType() {
      return type.getJavaType();
    }

    public boolean isRepeated() {
      return isRepeated;
    }

    public boolean isPacked() {
      return isPacked;
    }

    public Internal.EnumLiteMap<?> getEnumType() {
      return enumTypeMap;
    }

    @SuppressWarnings("unchecked")
    public MessageLite.Builder internalMergeFrom(
        MessageLite.Builder to, MessageLite from) {
      return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
    }

    public int compareTo(ExtensionDescriptor other) {
      return number - other.number;
    }
  }

  /**
   * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
   *
   * Users should ignore the contents of this class and only use objects of
   * this type as parameters to extension accessors and ExtensionRegistry.add().
   */
  public static final class GeneratedExtension<
      ContainingType extends MessageLite, Type> {

    private GeneratedExtension(
        final ContainingType containingTypeDefaultInstance,
        final Type defaultValue,
        final MessageLite messageDefaultInstance,
        final ExtensionDescriptor descriptor) {
      // Defensive checks to verify the correct initialization order of
      // GeneratedExtensions and their related GeneratedMessages.
      if (containingTypeDefaultInstance == null) {
        throw new IllegalArgumentException(
            "Null containingTypeDefaultInstance");
      }
      if (descriptor.getLiteType() == WireFormat.FieldType.MESSAGE &&
          messageDefaultInstance == null) {
        throw new IllegalArgumentException(
            "Null messageDefaultInstance");
      }
      this.containingTypeDefaultInstance = containingTypeDefaultInstance;
      this.defaultValue = defaultValue;
      this.messageDefaultInstance = messageDefaultInstance;
      this.descriptor = descriptor;
    }

    private final ContainingType containingTypeDefaultInstance;
    private final Type defaultValue;
    private final MessageLite messageDefaultInstance;
    private final ExtensionDescriptor descriptor;

    /**
     * Default instance of the type being extended, used to identify that type.
     */
    public ContainingType getContainingTypeDefaultInstance() {
      return containingTypeDefaultInstance;
    }

    /** Get the field number. */
    public int getNumber() {
      return descriptor.getNumber();
    }

    /**
     * If the extension is an embedded message, this is the default instance of
     * that type.
     */
    public MessageLite getMessageDefaultInstance() {
      return messageDefaultInstance;
    }
  }

  /**
   * A serialized (serializable) form of the generated message.  Stores the
   * message as a class name and a byte array.
   */
  static final class SerializedForm implements Serializable {
    private static final long serialVersionUID = 0L;

    private String messageClassName;
    private byte[] asBytes;

    /**
     * Creates the serialized form by calling {@link com.google.protobuf.MessageLite#toByteArray}.
     * @param regularForm the message to serialize
     */
    SerializedForm(MessageLite regularForm) {
      messageClassName = regularForm.getClass().getName();
      asBytes = regularForm.toByteArray();
    }

    /**
     * When read from an ObjectInputStream, this method converts this object
     * back to the regular form.  Part of Java's serialization magic.
     * @return a GeneratedMessage of the type that was serialized
     */
    @SuppressWarnings("unchecked")
    protected Object readResolve() throws ObjectStreamException {
      try {
        Class messageClass = Class.forName(messageClassName);
        Method newBuilder = messageClass.getMethod("newBuilder");
        MessageLite.Builder builder =
            (MessageLite.Builder) newBuilder.invoke(null);
        builder.mergeFrom(asBytes);
        return builder.buildPartial();
      } catch (ClassNotFoundException e) {
        throw new RuntimeException("Unable to find proto buffer class", e);
      } catch (NoSuchMethodException e) {
        throw new RuntimeException("Unable to find newBuilder method", e);
      } catch (IllegalAccessException e) {
        throw new RuntimeException("Unable to call newBuilder method", e);
      } catch (InvocationTargetException e) {
        throw new RuntimeException("Error calling newBuilder", e.getCause());
      } catch (InvalidProtocolBufferException e) {
        throw new RuntimeException("Unable to understand proto buffer", e);
      }
    }
  }

  /**
   * Replaces this object in the output stream with a serialized form.
   * Part of Java's serialization magic.  Generated sub-classes must override
   * this method by calling {@code return super.writeReplace();}
   * @return a SerializedForm of this message
   */
  protected Object writeReplace() throws ObjectStreamException {
    return new SerializedForm(this);
  }
}

/* [<][>][^][v][top][bottom][index][help] */