Selaa lähdekoodia

Down integrate from Google internal.

Jisi Liu 9 vuotta sitten
vanhempi
commit
cf14183bcd
100 muutettua tiedostoa jossa 9918 lisäystä ja 2057 poistoa
  1. 34 14
      java/core/src/main/java/com/google/protobuf/AbstractMessage.java
  2. 51 28
      java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java
  3. 45 40
      java/core/src/main/java/com/google/protobuf/AbstractParser.java
  4. 46 2
      java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java
  5. 44 25
      java/core/src/main/java/com/google/protobuf/BooleanArrayList.java
  6. 258 456
      java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
  7. 145 36
      java/core/src/main/java/com/google/protobuf/Descriptors.java
  8. 43 22
      java/core/src/main/java/com/google/protobuf/DoubleArrayList.java
  9. 36 4
      java/core/src/main/java/com/google/protobuf/DynamicMessage.java
  10. 1 0
      java/core/src/main/java/com/google/protobuf/Extension.java
  11. 19 0
      java/core/src/main/java/com/google/protobuf/FieldSet.java
  12. 42 22
      java/core/src/main/java/com/google/protobuf/FloatArrayList.java
  13. 152 103
      java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
  14. 926 141
      java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
  15. 42 22
      java/core/src/main/java/com/google/protobuf/IntArrayList.java
  16. 52 11
      java/core/src/main/java/com/google/protobuf/Internal.java
  17. 6 6
      java/core/src/main/java/com/google/protobuf/LazyField.java
  18. 41 0
      java/core/src/main/java/com/google/protobuf/LazyFieldLite.java
  19. 31 17
      java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java
  20. 42 22
      java/core/src/main/java/com/google/protobuf/LongArrayList.java
  21. 8 2
      java/core/src/main/java/com/google/protobuf/MapEntryLite.java
  22. 3 0
      java/core/src/main/java/com/google/protobuf/MapField.java
  23. 48 22
      java/core/src/main/java/com/google/protobuf/Message.java
  24. 21 0
      java/core/src/main/java/com/google/protobuf/MessageLite.java
  25. 95 56
      java/core/src/main/java/com/google/protobuf/MessageLiteToString.java
  26. 1 1
      java/core/src/main/java/com/google/protobuf/MessageOrBuilder.java
  27. 74 33
      java/core/src/main/java/com/google/protobuf/MessageReflection.java
  28. 14 8
      java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java
  29. 1 0
      java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java
  30. 7 1
      java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
  31. 3 1
      java/core/src/main/java/com/google/protobuf/RpcUtil.java
  32. 1 1
      java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java
  33. 79 27
      java/core/src/main/java/com/google/protobuf/SmallSortedMap.java
  34. 2 0
      java/core/src/main/java/com/google/protobuf/TextFormat.java
  35. 51 26
      java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
  36. 25 25
      java/core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java
  37. 15 4
      java/core/src/main/java/com/google/protobuf/WireFormat.java
  38. 33 8
      java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java
  39. 0 14
      java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java
  40. 2 0
      java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
  41. 503 273
      java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
  42. 0 14
      java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java
  43. 0 14
      java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java
  44. 1 1
      java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java
  45. 4 4
      java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
  46. 0 14
      java/core/src/test/java/com/google/protobuf/IntArrayListTest.java
  47. 660 32
      java/core/src/test/java/com/google/protobuf/LiteTest.java
  48. 0 14
      java/core/src/test/java/com/google/protobuf/LongArrayListTest.java
  49. 8 8
      java/core/src/test/java/com/google/protobuf/ParserTest.java
  50. 0 14
      java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java
  51. 13 7
      java/core/src/test/java/com/google/protobuf/ServiceTest.java
  52. 3 0
      java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java
  53. 2 407
      java/core/src/test/java/com/google/protobuf/TestUtil.java
  54. 559 0
      java/core/src/test/java/com/google/protobuf/TestUtilLite.java
  55. 4 1
      java/core/src/test/java/com/google/protobuf/TextFormatTest.java
  56. 1 0
      java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
  57. 5 5
      java/core/src/test/java/com/google/protobuf/WireFormatTest.java
  58. 0 3
      java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto
  59. 20 0
      java/lite/generate-sources-build.xml
  60. 43 0
      java/lite/generate-test-sources-build.xml
  61. 4 4
      java/lite/pom.xml
  62. 2 0
      java/pom.xml
  63. 553 0
      java/src/main/java/com/google/protobuf/AbstractMessage.java
  64. 386 0
      java/src/main/java/com/google/protobuf/AbstractMessageLite.java
  65. 258 0
      java/src/main/java/com/google/protobuf/AbstractParser.java
  66. 180 0
      java/src/main/java/com/google/protobuf/AbstractProtobufList.java
  67. 51 0
      java/src/main/java/com/google/protobuf/BlockingRpcChannel.java
  68. 64 0
      java/src/main/java/com/google/protobuf/BlockingService.java
  69. 5 1
      java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
  70. 37 8
      java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java
  71. 20 0
      java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
  72. 9 0
      java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java
  73. 50 0
      js/binary/utils.js
  74. 35 0
      js/binary/utils_test.js
  75. 134 0
      objectivec/google/google/protobuf/Any.pbobjc.h
  76. 93 0
      objectivec/google/google/protobuf/Any.pbobjc.m
  77. 262 0
      objectivec/google/google/protobuf/Api.pbobjc.h
  78. 348 0
      objectivec/google/google/protobuf/Api.pbobjc.m
  79. 101 0
      objectivec/google/google/protobuf/Duration.pbobjc.h
  80. 88 0
      objectivec/google/google/protobuf/Duration.pbobjc.m
  81. 53 0
      objectivec/google/google/protobuf/Empty.pbobjc.h
  82. 64 0
      objectivec/google/google/protobuf/Empty.pbobjc.m
  83. 202 0
      objectivec/google/google/protobuf/FieldMask.pbobjc.h
  84. 77 0
      objectivec/google/google/protobuf/FieldMask.pbobjc.m
  85. 54 0
      objectivec/google/google/protobuf/SourceContext.pbobjc.h
  86. 77 0
      objectivec/google/google/protobuf/SourceContext.pbobjc.m
  87. 167 0
      objectivec/google/google/protobuf/Struct.pbobjc.h
  88. 273 0
      objectivec/google/google/protobuf/Struct.pbobjc.m
  89. 113 0
      objectivec/google/google/protobuf/Timestamp.pbobjc.h
  90. 88 0
      objectivec/google/google/protobuf/Timestamp.pbobjc.m
  91. 373 0
      objectivec/google/google/protobuf/Type.pbobjc.h
  92. 693 0
      objectivec/google/google/protobuf/Type.pbobjc.m
  93. 182 0
      objectivec/google/google/protobuf/Wrappers.pbobjc.h
  94. 420 0
      objectivec/google/google/protobuf/Wrappers.pbobjc.m
  95. 4 0
      php/tests/autoload.php
  96. 7 2
      python/google/protobuf/descriptor.py
  97. 3 1
      python/google/protobuf/descriptor_pool.py
  98. 6 0
      python/google/protobuf/internal/api_implementation.py
  99. 16 30
      python/google/protobuf/internal/descriptor_pool_test.py
  100. 1 0
      python/google/protobuf/internal/descriptor_pool_test2.proto

+ 34 - 14
java/core/src/main/java/com/google/protobuf/AbstractMessage.java

@@ -50,17 +50,23 @@ import java.util.Map;
  *
  *
  * @author kenton@google.com Kenton Varda
  * @author kenton@google.com Kenton Varda
  */
  */
-public abstract class AbstractMessage extends AbstractMessageLite
-                                      implements Message {
+public abstract class AbstractMessage
+    // TODO(dweis): Update GeneratedMessage to parameterize with MessageType and BuilderType.
+    extends AbstractMessageLite
+    implements Message {
+  
+  @Override
   public boolean isInitialized() {
   public boolean isInitialized() {
     return MessageReflection.isInitialized(this);
     return MessageReflection.isInitialized(this);
   }
   }
 
 
 
 
+  @Override
   public List<String> findInitializationErrors() {
   public List<String> findInitializationErrors() {
     return MessageReflection.findMissingFields(this);
     return MessageReflection.findMissingFields(this);
   }
   }
 
 
+  @Override
   public String getInitializationErrorString() {
   public String getInitializationErrorString() {
     return MessageReflection.delimitWithCommas(findInitializationErrors());
     return MessageReflection.delimitWithCommas(findInitializationErrors());
   }
   }
@@ -83,12 +89,14 @@ public abstract class AbstractMessage extends AbstractMessageLite
     return TextFormat.printToString(this);
     return TextFormat.printToString(this);
   }
   }
 
 
+  @Override
   public void writeTo(final CodedOutputStream output) throws IOException {
   public void writeTo(final CodedOutputStream output) throws IOException {
     MessageReflection.writeMessageTo(this, getAllFields(), output, false);
     MessageReflection.writeMessageTo(this, getAllFields(), output, false);
   }
   }
 
 
   protected int memoizedSize = -1;
   protected int memoizedSize = -1;
 
 
+  @Override
   public int getSerializedSize() {
   public int getSerializedSize() {
     int size = memoizedSize;
     int size = memoizedSize;
     if (size != -1) {
     if (size != -1) {
@@ -288,8 +296,8 @@ public abstract class AbstractMessage extends AbstractMessageLite
    * other methods.
    * other methods.
    */
    */
   @SuppressWarnings("unchecked")
   @SuppressWarnings("unchecked")
-  public static abstract class Builder<BuilderType extends Builder>
-      extends AbstractMessageLite.Builder<BuilderType>
+  public static abstract class Builder<BuilderType extends Builder<BuilderType>>
+      extends AbstractMessageLite.Builder
       implements Message.Builder {
       implements Message.Builder {
     // The compiler produces an error if this is not declared explicitly.
     // The compiler produces an error if this is not declared explicitly.
     @Override
     @Override
@@ -314,6 +322,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
       throw new UnsupportedOperationException("clearOneof() is not implemented.");
       throw new UnsupportedOperationException("clearOneof() is not implemented.");
     }
     }
 
 
+    @Override
     public BuilderType clear() {
     public BuilderType clear() {
       for (final Map.Entry<FieldDescriptor, Object> entry :
       for (final Map.Entry<FieldDescriptor, Object> entry :
            getAllFields().entrySet()) {
            getAllFields().entrySet()) {
@@ -322,14 +331,22 @@ public abstract class AbstractMessage extends AbstractMessageLite
       return (BuilderType) this;
       return (BuilderType) this;
     }
     }
 
 
+    @Override
     public List<String> findInitializationErrors() {
     public List<String> findInitializationErrors() {
       return MessageReflection.findMissingFields(this);
       return MessageReflection.findMissingFields(this);
     }
     }
 
 
+    @Override
     public String getInitializationErrorString() {
     public String getInitializationErrorString() {
       return MessageReflection.delimitWithCommas(findInitializationErrors());
       return MessageReflection.delimitWithCommas(findInitializationErrors());
     }
     }
+    
+    @Override
+    protected BuilderType internalMergeFrom(AbstractMessageLite other) {
+      return mergeFrom((Message) other);
+    }
 
 
+    @Override
     public BuilderType mergeFrom(final Message other) {
     public BuilderType mergeFrom(final Message other) {
       if (other.getDescriptorForType() != getDescriptorForType()) {
       if (other.getDescriptorForType() != getDescriptorForType()) {
         throw new IllegalArgumentException(
         throw new IllegalArgumentException(
@@ -407,6 +424,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
       return (BuilderType) this;
       return (BuilderType) this;
     }
     }
 
 
+    @Override
     public BuilderType mergeUnknownFields(final UnknownFieldSet unknownFields) {
     public BuilderType mergeUnknownFields(final UnknownFieldSet unknownFields) {
       setUnknownFields(
       setUnknownFields(
         UnknownFieldSet.newBuilder(getUnknownFields())
         UnknownFieldSet.newBuilder(getUnknownFields())
@@ -415,17 +433,19 @@ public abstract class AbstractMessage extends AbstractMessageLite
       return (BuilderType) this;
       return (BuilderType) this;
     }
     }
 
 
+    @Override
     public Message.Builder getFieldBuilder(final FieldDescriptor field) {
     public Message.Builder getFieldBuilder(final FieldDescriptor field) {
       throw new UnsupportedOperationException(
       throw new UnsupportedOperationException(
           "getFieldBuilder() called on an unsupported message type.");
           "getFieldBuilder() called on an unsupported message type.");
     }
     }
 
 
-    public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field,
-        int index) {
+    @Override
+    public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field, int index) {
       throw new UnsupportedOperationException(
       throw new UnsupportedOperationException(
           "getRepeatedFieldBuilder() called on an unsupported message type.");
           "getRepeatedFieldBuilder() called on an unsupported message type.");
     }
     }
 
 
+    @Override
     public String toString() {
     public String toString() {
       return TextFormat.printToString(this);
       return TextFormat.printToString(this);
     }
     }
@@ -462,7 +482,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
     @Override
     @Override
     public BuilderType mergeFrom(final ByteString data)
     public BuilderType mergeFrom(final ByteString data)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {
-      return super.mergeFrom(data);
+      return (BuilderType) super.mergeFrom(data);
     }
     }
 
 
     @Override
     @Override
@@ -470,20 +490,20 @@ public abstract class AbstractMessage extends AbstractMessageLite
         final ByteString data,
         final ByteString data,
         final ExtensionRegistryLite extensionRegistry)
         final ExtensionRegistryLite extensionRegistry)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {
-      return super.mergeFrom(data, extensionRegistry);
+      return (BuilderType) super.mergeFrom(data, extensionRegistry);
     }
     }
 
 
     @Override
     @Override
     public BuilderType mergeFrom(final byte[] data)
     public BuilderType mergeFrom(final byte[] data)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {
-      return super.mergeFrom(data);
+      return (BuilderType) super.mergeFrom(data);
     }
     }
 
 
     @Override
     @Override
     public BuilderType mergeFrom(
     public BuilderType mergeFrom(
         final byte[] data, final int off, final int len)
         final byte[] data, final int off, final int len)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {
-      return super.mergeFrom(data, off, len);
+      return (BuilderType) super.mergeFrom(data, off, len);
     }
     }
 
 
     @Override
     @Override
@@ -491,7 +511,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
         final byte[] data,
         final byte[] data,
         final ExtensionRegistryLite extensionRegistry)
         final ExtensionRegistryLite extensionRegistry)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {
-      return super.mergeFrom(data, extensionRegistry);
+      return (BuilderType) super.mergeFrom(data, extensionRegistry);
     }
     }
 
 
     @Override
     @Override
@@ -499,13 +519,13 @@ public abstract class AbstractMessage extends AbstractMessageLite
         final byte[] data, final int off, final int len,
         final byte[] data, final int off, final int len,
         final ExtensionRegistryLite extensionRegistry)
         final ExtensionRegistryLite extensionRegistry)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {
-      return super.mergeFrom(data, off, len, extensionRegistry);
+      return (BuilderType) super.mergeFrom(data, off, len, extensionRegistry);
     }
     }
 
 
     @Override
     @Override
     public BuilderType mergeFrom(final InputStream input)
     public BuilderType mergeFrom(final InputStream input)
         throws IOException {
         throws IOException {
-      return super.mergeFrom(input);
+      return (BuilderType) super.mergeFrom(input);
     }
     }
 
 
     @Override
     @Override
@@ -513,7 +533,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
         final InputStream input,
         final InputStream input,
         final ExtensionRegistryLite extensionRegistry)
         final ExtensionRegistryLite extensionRegistry)
         throws IOException {
         throws IOException {
-      return super.mergeFrom(input, extensionRegistry);
+      return (BuilderType) super.mergeFrom(input, extensionRegistry);
     }
     }
 
 
     @Override
     @Override

+ 51 - 28
java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java

@@ -43,9 +43,13 @@ import java.util.Collection;
  *
  *
  * @author kenton@google.com Kenton Varda
  * @author kenton@google.com Kenton Varda
  */
  */
-public abstract class AbstractMessageLite implements MessageLite {
+public abstract class AbstractMessageLite<
+    MessageType extends AbstractMessageLite<MessageType, BuilderType>,
+    BuilderType extends AbstractMessageLite.Builder<MessageType, BuilderType>> 
+        implements MessageLite {
   protected int memoizedHashCode = 0;
   protected int memoizedHashCode = 0;
-
+  
+  @Override
   public ByteString toByteString() {
   public ByteString toByteString() {
     try {
     try {
       final ByteString.CodedBuilder out =
       final ByteString.CodedBuilder out =
@@ -59,6 +63,7 @@ public abstract class AbstractMessageLite implements MessageLite {
     }
     }
   }
   }
 
 
+  @Override
   public byte[] toByteArray() {
   public byte[] toByteArray() {
     try {
     try {
       final byte[] result = new byte[getSerializedSize()];
       final byte[] result = new byte[getSerializedSize()];
@@ -73,6 +78,7 @@ public abstract class AbstractMessageLite implements MessageLite {
     }
     }
   }
   }
 
 
+  @Override
   public void writeTo(final OutputStream output) throws IOException {
   public void writeTo(final OutputStream output) throws IOException {
     final int bufferSize =
     final int bufferSize =
         CodedOutputStream.computePreferredBufferSize(getSerializedSize());
         CodedOutputStream.computePreferredBufferSize(getSerializedSize());
@@ -82,6 +88,7 @@ public abstract class AbstractMessageLite implements MessageLite {
     codedOutput.flush();
     codedOutput.flush();
   }
   }
 
 
+  @Override
   public void writeDelimitedTo(final OutputStream output) throws IOException {
   public void writeDelimitedTo(final OutputStream output) throws IOException {
     final int serialized = getSerializedSize();
     final int serialized = getSerializedSize();
     final int bufferSize = CodedOutputStream.computePreferredBufferSize(
     final int bufferSize = CodedOutputStream.computePreferredBufferSize(
@@ -120,25 +127,27 @@ public abstract class AbstractMessageLite implements MessageLite {
    * other methods.
    * other methods.
    */
    */
   @SuppressWarnings("unchecked")
   @SuppressWarnings("unchecked")
-  public static abstract class Builder<BuilderType extends Builder>
+  public abstract static class Builder<
+      MessageType extends AbstractMessageLite<MessageType, BuilderType>,
+      BuilderType extends Builder<MessageType, BuilderType>>
       implements MessageLite.Builder {
       implements MessageLite.Builder {
     // The compiler produces an error if this is not declared explicitly.
     // The compiler produces an error if this is not declared explicitly.
     @Override
     @Override
     public abstract BuilderType clone();
     public abstract BuilderType clone();
 
 
-    public BuilderType mergeFrom(final CodedInputStream input)
-                                 throws IOException {
+    @Override
+    public BuilderType mergeFrom(final CodedInputStream input) throws IOException {
       return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry());
       return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry());
     }
     }
 
 
     // Re-defined here for return type covariance.
     // Re-defined here for return type covariance.
+    @Override
     public abstract BuilderType mergeFrom(
     public abstract BuilderType mergeFrom(
-        final CodedInputStream input,
-        final ExtensionRegistryLite extensionRegistry)
+        final CodedInputStream input, final ExtensionRegistryLite extensionRegistry)
         throws IOException;
         throws IOException;
 
 
-    public BuilderType mergeFrom(final ByteString data)
-        throws InvalidProtocolBufferException {
+    @Override
+    public BuilderType mergeFrom(final ByteString data) throws InvalidProtocolBufferException {
       try {
       try {
         final CodedInputStream input = data.newCodedInput();
         final CodedInputStream input = data.newCodedInput();
         mergeFrom(input);
         mergeFrom(input);
@@ -153,9 +162,9 @@ public abstract class AbstractMessageLite implements MessageLite {
       }
       }
     }
     }
 
 
+    @Override
     public BuilderType mergeFrom(
     public BuilderType mergeFrom(
-        final ByteString data,
-        final ExtensionRegistryLite extensionRegistry)
+        final ByteString data, final ExtensionRegistryLite extensionRegistry)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {
       try {
       try {
         final CodedInputStream input = data.newCodedInput();
         final CodedInputStream input = data.newCodedInput();
@@ -171,14 +180,14 @@ public abstract class AbstractMessageLite implements MessageLite {
       }
       }
     }
     }
 
 
-    public BuilderType mergeFrom(final byte[] data)
-        throws InvalidProtocolBufferException {
+    @Override
+    public BuilderType mergeFrom(final byte[] data) throws InvalidProtocolBufferException {
       return mergeFrom(data, 0, data.length);
       return mergeFrom(data, 0, data.length);
     }
     }
 
 
-    public BuilderType mergeFrom(final byte[] data, final int off,
-                                 final int len)
-                                 throws InvalidProtocolBufferException {
+    @Override
+    public BuilderType mergeFrom(final byte[] data, final int off, final int len)
+        throws InvalidProtocolBufferException {
       try {
       try {
         final CodedInputStream input =
         final CodedInputStream input =
             CodedInputStream.newInstance(data, off, len);
             CodedInputStream.newInstance(data, off, len);
@@ -194,15 +203,17 @@ public abstract class AbstractMessageLite implements MessageLite {
       }
       }
     }
     }
 
 
-    public BuilderType mergeFrom(
-        final byte[] data,
-        final ExtensionRegistryLite extensionRegistry)
+    @Override
+    public BuilderType mergeFrom(final byte[] data, final ExtensionRegistryLite extensionRegistry)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {
       return mergeFrom(data, 0, data.length, extensionRegistry);
       return mergeFrom(data, 0, data.length, extensionRegistry);
     }
     }
 
 
+    @Override
     public BuilderType mergeFrom(
     public BuilderType mergeFrom(
-        final byte[] data, final int off, final int len,
+        final byte[] data,
+        final int off,
+        final int len,
         final ExtensionRegistryLite extensionRegistry)
         final ExtensionRegistryLite extensionRegistry)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {
       try {
       try {
@@ -220,6 +231,7 @@ public abstract class AbstractMessageLite implements MessageLite {
       }
       }
     }
     }
 
 
+    @Override
     public BuilderType mergeFrom(final InputStream input) throws IOException {
     public BuilderType mergeFrom(final InputStream input) throws IOException {
       final CodedInputStream codedInput = CodedInputStream.newInstance(input);
       final CodedInputStream codedInput = CodedInputStream.newInstance(input);
       mergeFrom(codedInput);
       mergeFrom(codedInput);
@@ -227,10 +239,9 @@ public abstract class AbstractMessageLite implements MessageLite {
       return (BuilderType) this;
       return (BuilderType) this;
     }
     }
 
 
+    @Override
     public BuilderType mergeFrom(
     public BuilderType mergeFrom(
-        final InputStream input,
-        final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
+        final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException {
       final CodedInputStream codedInput = CodedInputStream.newInstance(input);
       final CodedInputStream codedInput = CodedInputStream.newInstance(input);
       mergeFrom(codedInput, extensionRegistry);
       mergeFrom(codedInput, extensionRegistry);
       codedInput.checkLastTagWas(0);
       codedInput.checkLastTagWas(0);
@@ -292,10 +303,9 @@ public abstract class AbstractMessageLite implements MessageLite {
       }
       }
     }
     }
 
 
+    @Override
     public boolean mergeDelimitedFrom(
     public boolean mergeDelimitedFrom(
-        final InputStream input,
-        final ExtensionRegistryLite extensionRegistry)
-        throws IOException {
+        final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException {
       final int firstByte = input.read();
       final int firstByte = input.read();
       if (firstByte == -1) {
       if (firstByte == -1) {
         return false;
         return false;
@@ -306,11 +316,24 @@ public abstract class AbstractMessageLite implements MessageLite {
       return true;
       return true;
     }
     }
 
 
-    public boolean mergeDelimitedFrom(final InputStream input)
-        throws IOException {
+    @Override
+    public boolean mergeDelimitedFrom(final InputStream input) throws IOException {
       return mergeDelimitedFrom(input,
       return mergeDelimitedFrom(input,
           ExtensionRegistryLite.getEmptyRegistry());
           ExtensionRegistryLite.getEmptyRegistry());
     }
     }
+    
+    @Override
+    @SuppressWarnings("unchecked") // isInstance takes care of this
+    public BuilderType mergeFrom(final MessageLite other) {
+      if (!getDefaultInstanceForType().getClass().isInstance(other)) {
+        throw new IllegalArgumentException(
+            "mergeFrom(MessageLite) can only merge messages of the same type.");
+      }
+        
+      return internalMergeFrom((MessageType) other);
+    }
+    
+    protected abstract BuilderType internalMergeFrom(MessageType message);
 
 
     /**
     /**
      * Construct an UninitializedMessageException reporting missing fields in
      * Construct an UninitializedMessageException reporting missing fields in

+ 45 - 40
java/core/src/main/java/com/google/protobuf/AbstractParser.java

@@ -78,26 +78,27 @@ public abstract class AbstractParser<MessageType extends MessageLite>
   private static final ExtensionRegistryLite EMPTY_REGISTRY
   private static final ExtensionRegistryLite EMPTY_REGISTRY
       = ExtensionRegistryLite.getEmptyRegistry();
       = ExtensionRegistryLite.getEmptyRegistry();
 
 
+  @Override
   public MessageType parsePartialFrom(CodedInputStream input)
   public MessageType parsePartialFrom(CodedInputStream input)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     return parsePartialFrom(input, EMPTY_REGISTRY);
     return parsePartialFrom(input, EMPTY_REGISTRY);
   }
   }
 
 
-  public MessageType parseFrom(CodedInputStream input,
-                               ExtensionRegistryLite extensionRegistry)
+  @Override
+  public MessageType parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     return checkMessageInitialized(
     return checkMessageInitialized(
         parsePartialFrom(input, extensionRegistry));
         parsePartialFrom(input, extensionRegistry));
   }
   }
 
 
-  public MessageType parseFrom(CodedInputStream input)
-      throws InvalidProtocolBufferException {
+  @Override
+  public MessageType parseFrom(CodedInputStream input) throws InvalidProtocolBufferException {
     return parseFrom(input, EMPTY_REGISTRY);
     return parseFrom(input, EMPTY_REGISTRY);
   }
   }
 
 
-  public MessageType parsePartialFrom(ByteString data,
-                                      ExtensionRegistryLite extensionRegistry)
-    throws InvalidProtocolBufferException {
+  @Override
+  public MessageType parsePartialFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
     MessageType message;
     MessageType message;
     try {
     try {
       CodedInputStream input = data.newCodedInput();
       CodedInputStream input = data.newCodedInput();
@@ -113,24 +114,25 @@ public abstract class AbstractParser<MessageType extends MessageLite>
     }
     }
   }
   }
 
 
-  public MessageType parsePartialFrom(ByteString data)
-      throws InvalidProtocolBufferException {
+  @Override
+  public MessageType parsePartialFrom(ByteString data) throws InvalidProtocolBufferException {
     return parsePartialFrom(data, EMPTY_REGISTRY);
     return parsePartialFrom(data, EMPTY_REGISTRY);
   }
   }
 
 
-  public MessageType parseFrom(ByteString data,
-                               ExtensionRegistryLite extensionRegistry)
+  @Override
+  public MessageType parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     return checkMessageInitialized(parsePartialFrom(data, extensionRegistry));
     return checkMessageInitialized(parsePartialFrom(data, extensionRegistry));
   }
   }
 
 
-  public MessageType parseFrom(ByteString data)
-      throws InvalidProtocolBufferException {
+  @Override
+  public MessageType parseFrom(ByteString data) throws InvalidProtocolBufferException {
     return parseFrom(data, EMPTY_REGISTRY);
     return parseFrom(data, EMPTY_REGISTRY);
   }
   }
 
 
-  public MessageType parsePartialFrom(byte[] data, int off, int len,
-                                      ExtensionRegistryLite extensionRegistry)
+  @Override
+  public MessageType parsePartialFrom(
+      byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     try {
     try {
       CodedInputStream input = CodedInputStream.newInstance(data, off, len);
       CodedInputStream input = CodedInputStream.newInstance(data, off, len);
@@ -146,47 +148,50 @@ public abstract class AbstractParser<MessageType extends MessageLite>
     }
     }
   }
   }
 
 
+  @Override
   public MessageType parsePartialFrom(byte[] data, int off, int len)
   public MessageType parsePartialFrom(byte[] data, int off, int len)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     return parsePartialFrom(data, off, len, EMPTY_REGISTRY);
     return parsePartialFrom(data, off, len, EMPTY_REGISTRY);
   }
   }
 
 
-  public MessageType parsePartialFrom(byte[] data,
-                                      ExtensionRegistryLite extensionRegistry)
+  @Override
+  public MessageType parsePartialFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     return parsePartialFrom(data, 0, data.length, extensionRegistry);
     return parsePartialFrom(data, 0, data.length, extensionRegistry);
   }
   }
 
 
-  public MessageType parsePartialFrom(byte[] data)
-      throws InvalidProtocolBufferException {
+  @Override
+  public MessageType parsePartialFrom(byte[] data) throws InvalidProtocolBufferException {
     return parsePartialFrom(data, 0, data.length, EMPTY_REGISTRY);
     return parsePartialFrom(data, 0, data.length, EMPTY_REGISTRY);
   }
   }
 
 
-  public MessageType parseFrom(byte[] data, int off, int len,
-                               ExtensionRegistryLite extensionRegistry)
+  @Override
+  public MessageType parseFrom(
+      byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     return checkMessageInitialized(
     return checkMessageInitialized(
         parsePartialFrom(data, off, len, extensionRegistry));
         parsePartialFrom(data, off, len, extensionRegistry));
   }
   }
 
 
+  @Override
   public MessageType parseFrom(byte[] data, int off, int len)
   public MessageType parseFrom(byte[] data, int off, int len)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     return parseFrom(data, off, len, EMPTY_REGISTRY);
     return parseFrom(data, off, len, EMPTY_REGISTRY);
   }
   }
 
 
-  public MessageType parseFrom(byte[] data,
-                               ExtensionRegistryLite extensionRegistry)
+  @Override
+  public MessageType parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     return parseFrom(data, 0, data.length, extensionRegistry);
     return parseFrom(data, 0, data.length, extensionRegistry);
   }
   }
 
 
-  public MessageType parseFrom(byte[] data)
-      throws InvalidProtocolBufferException {
+  @Override
+  public MessageType parseFrom(byte[] data) throws InvalidProtocolBufferException {
     return parseFrom(data, EMPTY_REGISTRY);
     return parseFrom(data, EMPTY_REGISTRY);
   }
   }
 
 
-  public MessageType parsePartialFrom(InputStream input,
-                                      ExtensionRegistryLite extensionRegistry)
+  @Override
+  public MessageType parsePartialFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     CodedInputStream codedInput = CodedInputStream.newInstance(input);
     CodedInputStream codedInput = CodedInputStream.newInstance(input);
     MessageType message = parsePartialFrom(codedInput, extensionRegistry);
     MessageType message = parsePartialFrom(codedInput, extensionRegistry);
@@ -198,26 +203,26 @@ public abstract class AbstractParser<MessageType extends MessageLite>
     return message;
     return message;
   }
   }
 
 
-  public MessageType parsePartialFrom(InputStream input)
-      throws InvalidProtocolBufferException {
+  @Override
+  public MessageType parsePartialFrom(InputStream input) throws InvalidProtocolBufferException {
     return parsePartialFrom(input, EMPTY_REGISTRY);
     return parsePartialFrom(input, EMPTY_REGISTRY);
   }
   }
 
 
-  public MessageType parseFrom(InputStream input,
-                               ExtensionRegistryLite extensionRegistry)
+  @Override
+  public MessageType parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     return checkMessageInitialized(
     return checkMessageInitialized(
         parsePartialFrom(input, extensionRegistry));
         parsePartialFrom(input, extensionRegistry));
   }
   }
 
 
-  public MessageType parseFrom(InputStream input)
-      throws InvalidProtocolBufferException {
+  @Override
+  public MessageType parseFrom(InputStream input) throws InvalidProtocolBufferException {
     return parseFrom(input, EMPTY_REGISTRY);
     return parseFrom(input, EMPTY_REGISTRY);
   }
   }
 
 
+  @Override
   public MessageType parsePartialDelimitedFrom(
   public MessageType parsePartialDelimitedFrom(
-      InputStream input,
-      ExtensionRegistryLite extensionRegistry)
+      InputStream input, ExtensionRegistryLite extensionRegistry)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     int size;
     int size;
     try {
     try {
@@ -233,21 +238,21 @@ public abstract class AbstractParser<MessageType extends MessageLite>
     return parsePartialFrom(limitedInput, extensionRegistry);
     return parsePartialFrom(limitedInput, extensionRegistry);
   }
   }
 
 
+  @Override
   public MessageType parsePartialDelimitedFrom(InputStream input)
   public MessageType parsePartialDelimitedFrom(InputStream input)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     return parsePartialDelimitedFrom(input, EMPTY_REGISTRY);
     return parsePartialDelimitedFrom(input, EMPTY_REGISTRY);
   }
   }
 
 
-  public MessageType parseDelimitedFrom(
-      InputStream input,
-      ExtensionRegistryLite extensionRegistry)
+  @Override
+  public MessageType parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
       throws InvalidProtocolBufferException {
       throws InvalidProtocolBufferException {
     return checkMessageInitialized(
     return checkMessageInitialized(
         parsePartialDelimitedFrom(input, extensionRegistry));
         parsePartialDelimitedFrom(input, extensionRegistry));
   }
   }
 
 
-  public MessageType parseDelimitedFrom(InputStream input)
-      throws InvalidProtocolBufferException {
+  @Override
+  public MessageType parseDelimitedFrom(InputStream input) throws InvalidProtocolBufferException {
     return parseDelimitedFrom(input, EMPTY_REGISTRY);
     return parseDelimitedFrom(input, EMPTY_REGISTRY);
   }
   }
 }
 }

+ 46 - 2
java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java

@@ -34,19 +34,25 @@ import com.google.protobuf.Internal.ProtobufList;
 
 
 import java.util.AbstractList;
 import java.util.AbstractList;
 import java.util.Collection;
 import java.util.Collection;
+import java.util.List;
+import java.util.RandomAccess;
 
 
 /**
 /**
  * An abstract implementation of {@link ProtobufList} which manages mutability semantics. All mutate
  * An abstract implementation of {@link ProtobufList} which manages mutability semantics. All mutate
- * methods are check if the list is mutable before proceeding. Subclasses must invoke
+ * methods must check if the list is mutable before proceeding. Subclasses must invoke
  * {@link #ensureIsMutable()} manually when overriding those methods.
  * {@link #ensureIsMutable()} manually when overriding those methods.
+ * <p>
+ * This implementation assumes all subclasses are array based, supporting random access.
  */
  */
 abstract class AbstractProtobufList<E> extends AbstractList<E> implements ProtobufList<E> {
 abstract class AbstractProtobufList<E> extends AbstractList<E> implements ProtobufList<E> {
 
 
+  protected static final int DEFAULT_CAPACITY = 10;
+
   /**
   /**
    * Whether or not this list is modifiable.
    * Whether or not this list is modifiable.
    */
    */
   private boolean isMutable;
   private boolean isMutable;
-  
+
   /**
   /**
    * Constructs a mutable list by default.
    * Constructs a mutable list by default.
    */
    */
@@ -54,6 +60,44 @@ abstract class AbstractProtobufList<E> extends AbstractList<E> implements Protob
     isMutable = true;
     isMutable = true;
   }
   }
 
 
+  @Override
+  public boolean equals(Object o) {
+    if (o == this) {
+      return true;
+    }
+    if (!(o instanceof List)) {
+      return false;
+    }
+    // Handle lists that do not support RandomAccess as efficiently as possible by using an iterator
+    // based approach in our super class. Otherwise our index based approach will avoid those
+    // allocations.
+    if (!(o instanceof RandomAccess)) {
+      return super.equals(o);
+    }
+
+    List<?> other = (List<?>) o;
+    final int size = size();
+    if (size != other.size()) {
+      return false;
+    }
+    for (int i = 0; i < size; i++) {
+      if (!get(i).equals(other.get(i))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    final int size = size();
+    int hashCode = 1;
+    for (int i = 0; i < size; i++) {
+      hashCode = (31 * hashCode) + get(i).hashCode();
+    }
+    return hashCode;
+  }
+
   @Override
   @Override
   public boolean add(E e) {
   public boolean add(E e) {
     ensureIsMutable();
     ensureIsMutable();

+ 44 - 25
java/core/src/main/java/com/google/protobuf/BooleanArrayList.java

@@ -34,7 +34,6 @@ import com.google.protobuf.Internal.BooleanList;
 
 
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
-import java.util.List;
 import java.util.RandomAccess;
 import java.util.RandomAccess;
 
 
 /**
 /**
@@ -45,8 +44,6 @@ import java.util.RandomAccess;
 final class BooleanArrayList
 final class BooleanArrayList
     extends AbstractProtobufList<Boolean> implements BooleanList, RandomAccess {
     extends AbstractProtobufList<Boolean> implements BooleanList, RandomAccess {
   
   
-  private static final int DEFAULT_CAPACITY = 10;
-  
   private static final BooleanArrayList EMPTY_LIST = new BooleanArrayList();
   private static final BooleanArrayList EMPTY_LIST = new BooleanArrayList();
   static {
   static {
     EMPTY_LIST.makeImmutable();
     EMPTY_LIST.makeImmutable();
@@ -60,7 +57,7 @@ final class BooleanArrayList
    * The backing store for the list.
    * The backing store for the list.
    */
    */
   private boolean[] array;
   private boolean[] array;
-  
+
   /**
   /**
    * The size of the list distinct from the length of the array. That is, it is the number of
    * The size of the list distinct from the length of the array. That is, it is the number of
    * elements set in the list.
    * elements set in the list.
@@ -71,35 +68,57 @@ final class BooleanArrayList
    * Constructs a new mutable {@code BooleanArrayList} with default capacity.
    * Constructs a new mutable {@code BooleanArrayList} with default capacity.
    */
    */
   BooleanArrayList() {
   BooleanArrayList() {
-    this(DEFAULT_CAPACITY);
+    this(new boolean[DEFAULT_CAPACITY], 0);
   }
   }
 
 
   /**
   /**
-   * Constructs a new mutable {@code BooleanArrayList} with the provided capacity.
+   * Constructs a new mutable {@code BooleanArrayList}.
    */
    */
-  BooleanArrayList(int capacity) {
-    array = new boolean[capacity];
-    size = 0;
+  private BooleanArrayList(boolean[] array, int size) {
+    this.array = array;
+    this.size = size;
   }
   }
-
-  /**
-   * Constructs a new mutable {@code BooleanArrayList} containing the same elements as
-   * {@code other}.
-   */
-  BooleanArrayList(List<Boolean> other) {
-    if (other instanceof BooleanArrayList) {
-      BooleanArrayList list = (BooleanArrayList) other;
-      array = list.array.clone();
-      size = list.size;
-    } else {
-      size = other.size();
-      array = new boolean[size];
-      for (int i = 0; i < size; i++) {
-        array[i] = other.get(i);
+  
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof BooleanArrayList)) {
+      return super.equals(o);
+    }
+    BooleanArrayList other = (BooleanArrayList) o;
+    if (size != other.size) {
+      return false;
+    }
+    
+    final boolean[] arr = other.array;
+    for (int i = 0; i < size; i++) {
+      if (array[i] != arr[i]) {
+        return false;
       }
       }
     }
     }
+    
+    return true;
   }
   }
-  
+
+  @Override
+  public int hashCode() {
+    int result = 1;
+    for (int i = 0; i < size; i++) {
+      result = (31 * result) + Internal.hashBoolean(array[i]);
+    }
+    return result;
+  }
+
+  @Override
+  public BooleanList mutableCopyWithCapacity(int capacity) {
+    if (capacity < size) {
+      throw new IllegalArgumentException();
+    }
+    return new BooleanArrayList(Arrays.copyOf(array, capacity), size);
+  }
+
   @Override
   @Override
   public Boolean get(int index) {
   public Boolean get(int index) {
     return getBoolean(index);
     return getBoolean(index);

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 258 - 456
java/core/src/main/java/com/google/protobuf/CodedOutputStream.java


+ 145 - 36
java/core/src/main/java/com/google/protobuf/Descriptors.java

@@ -74,16 +74,28 @@ public final class Descriptors {
    */
    */
   public static final class FileDescriptor extends GenericDescriptor {
   public static final class FileDescriptor extends GenericDescriptor {
     /** Convert the descriptor to its protocol message representation. */
     /** Convert the descriptor to its protocol message representation. */
-    public FileDescriptorProto toProto() { return proto; }
+    @Override
+    public FileDescriptorProto toProto() {
+      return proto;
+    }
 
 
     /** Get the file name. */
     /** Get the file name. */
-    public String getName() { return proto.getName(); }
+    @Override
+    public String getName() {
+      return proto.getName();
+    }
 
 
     /** Returns this object. */
     /** Returns this object. */
-    public FileDescriptor getFile() { return this; }
+    @Override
+    public FileDescriptor getFile() {
+      return this;
+    }
 
 
     /** Returns the same as getName(). */
     /** Returns the same as getName(). */
-    public String getFullName() { return proto.getName(); }
+    @Override
+    public String getFullName() {
+      return proto.getName();
+    }
 
 
     /**
     /**
      * Get the proto package name.  This is the package name given by the
      * Get the proto package name.  This is the package name given by the
@@ -582,10 +594,16 @@ public final class Descriptors {
     public int getIndex() { return index; }
     public int getIndex() { return index; }
 
 
     /** Convert the descriptor to its protocol message representation. */
     /** Convert the descriptor to its protocol message representation. */
-    public DescriptorProto toProto() { return proto; }
+    @Override
+    public DescriptorProto toProto() {
+      return proto;
+    }
 
 
     /** Get the type's unqualified name. */
     /** Get the type's unqualified name. */
-    public String getName() { return proto.getName(); }
+    @Override
+    public String getName() {
+      return proto.getName();
+    }
 
 
     /**
     /**
      * Get the type's fully-qualified name, within the proto language's
      * Get the type's fully-qualified name, within the proto language's
@@ -598,10 +616,16 @@ public final class Descriptors {
      * </pre>
      * </pre>
      * {@code Baz}'s full name is "foo.bar.Baz".
      * {@code Baz}'s full name is "foo.bar.Baz".
      */
      */
-    public String getFullName() { return fullName; }
+    @Override
+    public String getFullName() {
+      return fullName;
+    }
 
 
     /** Get the {@link FileDescriptor} containing this descriptor. */
     /** Get the {@link FileDescriptor} containing this descriptor. */
-    public FileDescriptor getFile() { return file; }
+    @Override
+    public FileDescriptor getFile() {
+      return file;
+    }
 
 
     /** If this is a nested type, get the outer descriptor, otherwise null. */
     /** If this is a nested type, get the outer descriptor, otherwise null. */
     public Descriptor getContainingType() { return containingType; }
     public Descriptor getContainingType() { return containingType; }
@@ -875,19 +899,31 @@ public final class Descriptors {
     public int getIndex() { return index; }
     public int getIndex() { return index; }
 
 
     /** Convert the descriptor to its protocol message representation. */
     /** Convert the descriptor to its protocol message representation. */
-    public FieldDescriptorProto toProto() { return proto; }
+    @Override
+    public FieldDescriptorProto toProto() {
+      return proto;
+    }
 
 
     /** Get the field's unqualified name. */
     /** Get the field's unqualified name. */
-    public String getName() { return proto.getName(); }
+    @Override
+    public String getName() {
+      return proto.getName();
+    }
 
 
     /** Get the field's number. */
     /** Get the field's number. */
-    public int getNumber() { return proto.getNumber(); }
+    @Override
+    public int getNumber() {
+      return proto.getNumber();
+    }
 
 
     /**
     /**
      * Get the field's fully-qualified name.
      * Get the field's fully-qualified name.
      * @see Descriptors.Descriptor#getFullName()
      * @see Descriptors.Descriptor#getFullName()
      */
      */
-    public String getFullName() { return fullName; }
+    @Override
+    public String getFullName() {
+      return fullName;
+    }
 
 
     /** Get the JSON name of this field. */
     /** Get the JSON name of this field. */
     public String getJsonName() {
     public String getJsonName() {
@@ -901,17 +937,22 @@ public final class Descriptors {
     public JavaType getJavaType() { return type.getJavaType(); }
     public JavaType getJavaType() { return type.getJavaType(); }
 
 
     /** For internal use only. */
     /** For internal use only. */
+    @Override
     public WireFormat.JavaType getLiteJavaType() {
     public WireFormat.JavaType getLiteJavaType() {
       return getLiteType().getJavaType();
       return getLiteType().getJavaType();
     }
     }
 
 
     /** Get the {@code FileDescriptor} containing this descriptor. */
     /** Get the {@code FileDescriptor} containing this descriptor. */
-    public FileDescriptor getFile() { return file; }
+    @Override
+    public FileDescriptor getFile() {
+      return file;
+    }
 
 
     /** Get the field's declared type. */
     /** Get the field's declared type. */
     public Type getType() { return type; }
     public Type getType() { return type; }
 
 
     /** For internal use only. */
     /** For internal use only. */
+    @Override
     public WireFormat.FieldType getLiteType() {
     public WireFormat.FieldType getLiteType() {
       return table[type.ordinal()];
       return table[type.ordinal()];
     }
     }
@@ -953,6 +994,7 @@ public final class Descriptors {
     }
     }
 
 
     /** Is this field declared repeated? */
     /** Is this field declared repeated? */
+    @Override
     public boolean isRepeated() {
     public boolean isRepeated() {
       return proto.getLabel() == FieldDescriptorProto.Label.LABEL_REPEATED;
       return proto.getLabel() == FieldDescriptorProto.Label.LABEL_REPEATED;
     }
     }
@@ -960,6 +1002,7 @@ public final class Descriptors {
     /** Does this field have the {@code [packed = true]} option or is this field
     /** Does this field have the {@code [packed = true]} option or is this field
      *  packable in proto3 and not explicitly setted to unpacked?
      *  packable in proto3 and not explicitly setted to unpacked?
      */
      */
+    @Override
     public boolean isPacked() {
     public boolean isPacked() {
       if (!isPackable()) {
       if (!isPackable()) {
         return false;
         return false;
@@ -1048,6 +1091,7 @@ public final class Descriptors {
     }
     }
 
 
     /** For enum fields, gets the field's type. */
     /** For enum fields, gets the field's type. */
+    @Override
     public EnumDescriptor getEnumType() {
     public EnumDescriptor getEnumType() {
       if (getJavaType() != JavaType.ENUM) {
       if (getJavaType() != JavaType.ENUM) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
@@ -1066,6 +1110,7 @@ public final class Descriptors {
      * @return negative, zero, or positive if {@code this} is less than,
      * @return negative, zero, or positive if {@code this} is less than,
      *         equal to, or greater than {@code other}, respectively.
      *         equal to, or greater than {@code other}, respectively.
      */
      */
+    @Override
     public int compareTo(final FieldDescriptor other) {
     public int compareTo(final FieldDescriptor other) {
       if (other.containingType != containingType) {
       if (other.containingType != containingType) {
         throw new IllegalArgumentException(
         throw new IllegalArgumentException(
@@ -1466,8 +1511,8 @@ public final class Descriptors {
      * For internal use only.  This is to satisfy the FieldDescriptorLite
      * For internal use only.  This is to satisfy the FieldDescriptorLite
      * interface.
      * interface.
      */
      */
-    public MessageLite.Builder internalMergeFrom(
-        MessageLite.Builder to, MessageLite from) {
+    @Override
+    public MessageLite.Builder internalMergeFrom(MessageLite.Builder to, MessageLite from) {
       // FieldDescriptors are only used with non-lite messages so we can just
       // FieldDescriptors are only used with non-lite messages so we can just
       // down-cast and call mergeFrom directly.
       // down-cast and call mergeFrom directly.
       return ((Message.Builder) to).mergeFrom((Message) from);
       return ((Message.Builder) to).mergeFrom((Message) from);
@@ -1487,19 +1532,31 @@ public final class Descriptors {
     public int getIndex() { return index; }
     public int getIndex() { return index; }
 
 
     /** Convert the descriptor to its protocol message representation. */
     /** Convert the descriptor to its protocol message representation. */
-    public EnumDescriptorProto toProto() { return proto; }
+    @Override
+    public EnumDescriptorProto toProto() {
+      return proto;
+    }
 
 
     /** Get the type's unqualified name. */
     /** Get the type's unqualified name. */
-    public String getName() { return proto.getName(); }
+    @Override
+    public String getName() {
+      return proto.getName();
+    }
 
 
     /**
     /**
      * Get the type's fully-qualified name.
      * Get the type's fully-qualified name.
      * @see Descriptors.Descriptor#getFullName()
      * @see Descriptors.Descriptor#getFullName()
      */
      */
-    public String getFullName() { return fullName; }
+    @Override
+    public String getFullName() {
+      return fullName;
+    }
 
 
     /** Get the {@link FileDescriptor} containing this descriptor. */
     /** Get the {@link FileDescriptor} containing this descriptor. */
-    public FileDescriptor getFile() { return file; }
+    @Override
+    public FileDescriptor getFile() {
+      return file;
+    }
 
 
     /** If this is a nested type, get the outer descriptor, otherwise null. */
     /** If this is a nested type, get the outer descriptor, otherwise null. */
     public Descriptor getContainingType() { return containingType; }
     public Descriptor getContainingType() { return containingType; }
@@ -1533,6 +1590,7 @@ public final class Descriptors {
      * @param number The value's number.
      * @param number The value's number.
      * @return the value's descriptor, or {@code null} if not found.
      * @return the value's descriptor, or {@code null} if not found.
      */
      */
+    @Override
     public EnumValueDescriptor findValueByNumber(final int number) {
     public EnumValueDescriptor findValueByNumber(final int number) {
       return file.pool.enumValuesByNumber.get(
       return file.pool.enumValuesByNumber.get(
         new DescriptorPool.DescriptorIntPair(this, number));
         new DescriptorPool.DescriptorIntPair(this, number));
@@ -1659,13 +1717,22 @@ public final class Descriptors {
     public int getIndex() { return index; }
     public int getIndex() { return index; }
 
 
     /** Convert the descriptor to its protocol message representation. */
     /** Convert the descriptor to its protocol message representation. */
-    public EnumValueDescriptorProto toProto() { return proto; }
+    @Override
+    public EnumValueDescriptorProto toProto() {
+      return proto;
+    }
 
 
     /** Get the value's unqualified name. */
     /** Get the value's unqualified name. */
-    public String getName() { return proto.getName(); }
+    @Override
+    public String getName() {
+      return proto.getName();
+    }
 
 
     /** Get the value's number. */
     /** Get the value's number. */
-    public int getNumber() { return proto.getNumber(); }
+    @Override
+    public int getNumber() {
+      return proto.getNumber();
+    }
 
 
     @Override
     @Override
     public String toString() { return proto.getName(); }
     public String toString() { return proto.getName(); }
@@ -1674,10 +1741,16 @@ public final class Descriptors {
      * Get the value's fully-qualified name.
      * Get the value's fully-qualified name.
      * @see Descriptors.Descriptor#getFullName()
      * @see Descriptors.Descriptor#getFullName()
      */
      */
-    public String getFullName() { return fullName; }
+    @Override
+    public String getFullName() {
+      return fullName;
+    }
 
 
     /** Get the {@link FileDescriptor} containing this descriptor. */
     /** Get the {@link FileDescriptor} containing this descriptor. */
-    public FileDescriptor getFile() { return file; }
+    @Override
+    public FileDescriptor getFile() {
+      return file;
+    }
 
 
     /** Get the value's enum type. */
     /** Get the value's enum type. */
     public EnumDescriptor getType() { return type; }
     public EnumDescriptor getType() { return type; }
@@ -1745,19 +1818,31 @@ public final class Descriptors {
     public int getIndex() { return index; }
     public int getIndex() { return index; }
 
 
     /** Convert the descriptor to its protocol message representation. */
     /** Convert the descriptor to its protocol message representation. */
-    public ServiceDescriptorProto toProto() { return proto; }
+    @Override
+    public ServiceDescriptorProto toProto() {
+      return proto;
+    }
 
 
     /** Get the type's unqualified name. */
     /** Get the type's unqualified name. */
-    public String getName() { return proto.getName(); }
+    @Override
+    public String getName() {
+      return proto.getName();
+    }
 
 
     /**
     /**
      * Get the type's fully-qualified name.
      * Get the type's fully-qualified name.
      * @see Descriptors.Descriptor#getFullName()
      * @see Descriptors.Descriptor#getFullName()
      */
      */
-    public String getFullName() { return fullName; }
+    @Override
+    public String getFullName() {
+      return fullName;
+    }
 
 
     /** Get the {@link FileDescriptor} containing this descriptor. */
     /** Get the {@link FileDescriptor} containing this descriptor. */
-    public FileDescriptor getFile() { return file; }
+    @Override
+    public FileDescriptor getFile() {
+      return file;
+    }
 
 
     /** Get the {@code ServiceOptions}, defined in {@code descriptor.proto}. */
     /** Get the {@code ServiceOptions}, defined in {@code descriptor.proto}. */
     public ServiceOptions getOptions() { return proto.getOptions(); }
     public ServiceOptions getOptions() { return proto.getOptions(); }
@@ -1835,19 +1920,31 @@ public final class Descriptors {
     public int getIndex() { return index; }
     public int getIndex() { return index; }
 
 
     /** Convert the descriptor to its protocol message representation. */
     /** Convert the descriptor to its protocol message representation. */
-    public MethodDescriptorProto toProto() { return proto; }
+    @Override
+    public MethodDescriptorProto toProto() {
+      return proto;
+    }
 
 
     /** Get the method's unqualified name. */
     /** Get the method's unqualified name. */
-    public String getName() { return proto.getName(); }
+    @Override
+    public String getName() {
+      return proto.getName();
+    }
 
 
     /**
     /**
      * Get the method's fully-qualified name.
      * Get the method's fully-qualified name.
      * @see Descriptors.Descriptor#getFullName()
      * @see Descriptors.Descriptor#getFullName()
      */
      */
-    public String getFullName() { return fullName; }
+    @Override
+    public String getFullName() {
+      return fullName;
+    }
 
 
     /** Get the {@link FileDescriptor} containing this descriptor. */
     /** Get the {@link FileDescriptor} containing this descriptor. */
-    public FileDescriptor getFile() { return file; }
+    @Override
+    public FileDescriptor getFile() {
+      return file;
+    }
 
 
     /** Get the method's service type. */
     /** Get the method's service type. */
     public ServiceDescriptor getService() { return service; }
     public ServiceDescriptor getService() { return service; }
@@ -2248,10 +2345,22 @@ public final class Descriptors {
      * that has the same name as an existing package.
      * that has the same name as an existing package.
      */
      */
     private static final class PackageDescriptor extends GenericDescriptor {
     private static final class PackageDescriptor extends GenericDescriptor {
-      public Message toProto()        { return file.toProto(); }
-      public String getName()         { return name;           }
-      public String getFullName()     { return fullName;       }
-      public FileDescriptor getFile() { return file;           }
+      @Override
+      public Message toProto() {
+        return file.toProto();
+      }
+      @Override
+      public String getName() {
+        return name;
+      }
+      @Override
+      public String getFullName() {
+        return fullName;
+      }
+      @Override
+      public FileDescriptor getFile() {
+        return file;
+      }
 
 
       PackageDescriptor(final String name, final String fullName,
       PackageDescriptor(final String name, final String fullName,
                         final FileDescriptor file) {
                         final FileDescriptor file) {

+ 43 - 22
java/core/src/main/java/com/google/protobuf/DoubleArrayList.java

@@ -34,7 +34,6 @@ import com.google.protobuf.Internal.DoubleList;
 
 
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
-import java.util.List;
 import java.util.RandomAccess;
 import java.util.RandomAccess;
 
 
 /**
 /**
@@ -45,8 +44,6 @@ import java.util.RandomAccess;
 final class DoubleArrayList
 final class DoubleArrayList
     extends AbstractProtobufList<Double> implements DoubleList, RandomAccess {
     extends AbstractProtobufList<Double> implements DoubleList, RandomAccess {
   
   
-  private static final int DEFAULT_CAPACITY = 10;
-  
   private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList();
   private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList();
   static {
   static {
     EMPTY_LIST.makeImmutable();
     EMPTY_LIST.makeImmutable();
@@ -71,32 +68,56 @@ final class DoubleArrayList
    * Constructs a new mutable {@code DoubleArrayList} with default capacity.
    * Constructs a new mutable {@code DoubleArrayList} with default capacity.
    */
    */
   DoubleArrayList() {
   DoubleArrayList() {
-    this(DEFAULT_CAPACITY);
-  }
-
-  /**
-   * Constructs a new mutable {@code DoubleArrayList} with the provided capacity.
-   */
-  DoubleArrayList(int capacity) {
-    array = new double[capacity];
-    size = 0;
+    this(new double[DEFAULT_CAPACITY], 0);
   }
   }
 
 
   /**
   /**
    * Constructs a new mutable {@code DoubleArrayList} containing the same elements as {@code other}.
    * Constructs a new mutable {@code DoubleArrayList} containing the same elements as {@code other}.
    */
    */
-  DoubleArrayList(List<Double> other) {
-    if (other instanceof DoubleArrayList) {
-      DoubleArrayList list = (DoubleArrayList) other;
-      array = list.array.clone();
-      size = list.size;
-    } else {
-      size = other.size();
-      array = new double[size];
-      for (int i = 0; i < size; i++) {
-        array[i] = other.get(i);
+  private DoubleArrayList(double[] array, int size) {
+    this.array = array;
+    this.size = size;
+  }
+  
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof DoubleArrayList)) {
+      return super.equals(o);
+    }
+    DoubleArrayList other = (DoubleArrayList) o;
+    if (size != other.size) {
+      return false;
+    }
+    
+    final double[] arr = other.array;
+    for (int i = 0; i < size; i++) {
+      if (array[i] != arr[i]) {
+        return false;
       }
       }
     }
     }
+    
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = 1;
+    for (int i = 0; i < size; i++) {
+      long bits = Double.doubleToLongBits(array[i]);
+      result = (31 * result) + Internal.hashLong(bits);
+    }
+    return result;
+  }
+
+  @Override
+  public DoubleList mutableCopyWithCapacity(int capacity) {
+    if (capacity < size) {
+      throw new IllegalArgumentException();
+    }
+    return new DoubleArrayList(Arrays.copyOf(array, capacity), size);
   }
   }
   
   
   @Override
   @Override

+ 36 - 4
java/core/src/main/java/com/google/protobuf/DynamicMessage.java

@@ -156,18 +156,22 @@ public final class DynamicMessage extends AbstractMessage {
   // -----------------------------------------------------------------
   // -----------------------------------------------------------------
   // Implementation of Message interface.
   // Implementation of Message interface.
 
 
+  @Override
   public Descriptor getDescriptorForType() {
   public Descriptor getDescriptorForType() {
     return type;
     return type;
   }
   }
 
 
+  @Override
   public DynamicMessage getDefaultInstanceForType() {
   public DynamicMessage getDefaultInstanceForType() {
     return getDefaultInstance(type);
     return getDefaultInstance(type);
   }
   }
 
 
+  @Override
   public Map<FieldDescriptor, Object> getAllFields() {
   public Map<FieldDescriptor, Object> getAllFields() {
     return fields.getAllFields();
     return fields.getAllFields();
   }
   }
 
 
+  @Override
   public boolean hasOneof(OneofDescriptor oneof) {
   public boolean hasOneof(OneofDescriptor oneof) {
     verifyOneofContainingType(oneof);
     verifyOneofContainingType(oneof);
     FieldDescriptor field = oneofCases[oneof.getIndex()];
     FieldDescriptor field = oneofCases[oneof.getIndex()];
@@ -177,16 +181,19 @@ public final class DynamicMessage extends AbstractMessage {
     return true;
     return true;
   }
   }
 
 
+  @Override
   public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
   public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
     verifyOneofContainingType(oneof);
     verifyOneofContainingType(oneof);
     return oneofCases[oneof.getIndex()];
     return oneofCases[oneof.getIndex()];
   }
   }
 
 
+  @Override
   public boolean hasField(FieldDescriptor field) {
   public boolean hasField(FieldDescriptor field) {
     verifyContainingType(field);
     verifyContainingType(field);
     return fields.hasField(field);
     return fields.hasField(field);
   }
   }
 
 
+  @Override
   public Object getField(FieldDescriptor field) {
   public Object getField(FieldDescriptor field) {
     verifyContainingType(field);
     verifyContainingType(field);
     Object result = fields.getField(field);
     Object result = fields.getField(field);
@@ -202,16 +209,19 @@ public final class DynamicMessage extends AbstractMessage {
     return result;
     return result;
   }
   }
 
 
+  @Override
   public int getRepeatedFieldCount(FieldDescriptor field) {
   public int getRepeatedFieldCount(FieldDescriptor field) {
     verifyContainingType(field);
     verifyContainingType(field);
     return fields.getRepeatedFieldCount(field);
     return fields.getRepeatedFieldCount(field);
   }
   }
 
 
+  @Override
   public Object getRepeatedField(FieldDescriptor field, int index) {
   public Object getRepeatedField(FieldDescriptor field, int index) {
     verifyContainingType(field);
     verifyContainingType(field);
     return fields.getRepeatedField(field, index);
     return fields.getRepeatedField(field, index);
   }
   }
 
 
+  @Override
   public UnknownFieldSet getUnknownFields() {
   public UnknownFieldSet getUnknownFields() {
     return unknownFields;
     return unknownFields;
   }
   }
@@ -264,19 +274,22 @@ public final class DynamicMessage extends AbstractMessage {
     return size;
     return size;
   }
   }
 
 
+  @Override
   public Builder newBuilderForType() {
   public Builder newBuilderForType() {
     return new Builder(type);
     return new Builder(type);
   }
   }
 
 
+  @Override
   public Builder toBuilder() {
   public Builder toBuilder() {
     return newBuilderForType().mergeFrom(this);
     return newBuilderForType().mergeFrom(this);
   }
   }
 
 
+  @Override
   public Parser<DynamicMessage> getParserForType() {
   public Parser<DynamicMessage> getParserForType() {
     return new AbstractParser<DynamicMessage>() {
     return new AbstractParser<DynamicMessage>() {
+      @Override
       public DynamicMessage parsePartialFrom(
       public DynamicMessage parsePartialFrom(
-          CodedInputStream input,
-          ExtensionRegistryLite extensionRegistry)
+          CodedInputStream input, ExtensionRegistryLite extensionRegistry)
           throws InvalidProtocolBufferException {
           throws InvalidProtocolBufferException {
         Builder builder = newBuilder(type);
         Builder builder = newBuilder(type);
         try {
         try {
@@ -370,6 +383,7 @@ public final class DynamicMessage extends AbstractMessage {
       }
       }
     }
     }
 
 
+    @Override
     public DynamicMessage build() {
     public DynamicMessage build() {
       if (!isInitialized()) {
       if (!isInitialized()) {
         throw newUninitializedMessageException(
         throw newUninitializedMessageException(
@@ -394,6 +408,7 @@ public final class DynamicMessage extends AbstractMessage {
       return buildPartial();
       return buildPartial();
     }
     }
 
 
+    @Override
     public DynamicMessage buildPartial() {
     public DynamicMessage buildPartial() {
       fields.makeImmutable();
       fields.makeImmutable();
       DynamicMessage result =
       DynamicMessage result =
@@ -411,22 +426,27 @@ public final class DynamicMessage extends AbstractMessage {
       return result;
       return result;
     }
     }
 
 
+    @Override
     public boolean isInitialized() {
     public boolean isInitialized() {
       return DynamicMessage.isInitialized(type, fields);
       return DynamicMessage.isInitialized(type, fields);
     }
     }
 
 
+    @Override
     public Descriptor getDescriptorForType() {
     public Descriptor getDescriptorForType() {
       return type;
       return type;
     }
     }
 
 
+    @Override
     public DynamicMessage getDefaultInstanceForType() {
     public DynamicMessage getDefaultInstanceForType() {
       return getDefaultInstance(type);
       return getDefaultInstance(type);
     }
     }
 
 
+    @Override
     public Map<FieldDescriptor, Object> getAllFields() {
     public Map<FieldDescriptor, Object> getAllFields() {
       return fields.getAllFields();
       return fields.getAllFields();
     }
     }
 
 
+    @Override
     public Builder newBuilderForField(FieldDescriptor field) {
     public Builder newBuilderForField(FieldDescriptor field) {
       verifyContainingType(field);
       verifyContainingType(field);
 
 
@@ -438,6 +458,7 @@ public final class DynamicMessage extends AbstractMessage {
       return new Builder(field.getMessageType());
       return new Builder(field.getMessageType());
     }
     }
 
 
+    @Override
     public boolean hasOneof(OneofDescriptor oneof) {
     public boolean hasOneof(OneofDescriptor oneof) {
       verifyOneofContainingType(oneof);
       verifyOneofContainingType(oneof);
       FieldDescriptor field = oneofCases[oneof.getIndex()];
       FieldDescriptor field = oneofCases[oneof.getIndex()];
@@ -447,11 +468,13 @@ public final class DynamicMessage extends AbstractMessage {
       return true;
       return true;
     }
     }
 
 
+    @Override
     public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
     public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
       verifyOneofContainingType(oneof);
       verifyOneofContainingType(oneof);
       return oneofCases[oneof.getIndex()];
       return oneofCases[oneof.getIndex()];
     }
     }
 
 
+    @Override
     public Builder clearOneof(OneofDescriptor oneof) {
     public Builder clearOneof(OneofDescriptor oneof) {
       verifyOneofContainingType(oneof);
       verifyOneofContainingType(oneof);
       FieldDescriptor field = oneofCases[oneof.getIndex()];
       FieldDescriptor field = oneofCases[oneof.getIndex()];
@@ -461,11 +484,13 @@ public final class DynamicMessage extends AbstractMessage {
       return this;
       return this;
     }
     }
 
 
+    @Override
     public boolean hasField(FieldDescriptor field) {
     public boolean hasField(FieldDescriptor field) {
       verifyContainingType(field);
       verifyContainingType(field);
       return fields.hasField(field);
       return fields.hasField(field);
     }
     }
 
 
+    @Override
     public Object getField(FieldDescriptor field) {
     public Object getField(FieldDescriptor field) {
       verifyContainingType(field);
       verifyContainingType(field);
       Object result = fields.getField(field);
       Object result = fields.getField(field);
@@ -481,6 +506,7 @@ public final class DynamicMessage extends AbstractMessage {
       return result;
       return result;
     }
     }
 
 
+    @Override
     public Builder setField(FieldDescriptor field, Object value) {
     public Builder setField(FieldDescriptor field, Object value) {
       verifyContainingType(field);
       verifyContainingType(field);
       ensureIsMutable();
       ensureIsMutable();
@@ -505,6 +531,7 @@ public final class DynamicMessage extends AbstractMessage {
       return this;
       return this;
     }
     }
 
 
+    @Override
     public Builder clearField(FieldDescriptor field) {
     public Builder clearField(FieldDescriptor field) {
       verifyContainingType(field);
       verifyContainingType(field);
       ensureIsMutable();
       ensureIsMutable();
@@ -519,24 +546,27 @@ public final class DynamicMessage extends AbstractMessage {
       return this;
       return this;
     }
     }
 
 
+    @Override
     public int getRepeatedFieldCount(FieldDescriptor field) {
     public int getRepeatedFieldCount(FieldDescriptor field) {
       verifyContainingType(field);
       verifyContainingType(field);
       return fields.getRepeatedFieldCount(field);
       return fields.getRepeatedFieldCount(field);
     }
     }
 
 
+    @Override
     public Object getRepeatedField(FieldDescriptor field, int index) {
     public Object getRepeatedField(FieldDescriptor field, int index) {
       verifyContainingType(field);
       verifyContainingType(field);
       return fields.getRepeatedField(field, index);
       return fields.getRepeatedField(field, index);
     }
     }
 
 
-    public Builder setRepeatedField(FieldDescriptor field,
-                                    int index, Object value) {
+    @Override
+    public Builder setRepeatedField(FieldDescriptor field, int index, Object value) {
       verifyContainingType(field);
       verifyContainingType(field);
       ensureIsMutable();
       ensureIsMutable();
       fields.setRepeatedField(field, index, value);
       fields.setRepeatedField(field, index, value);
       return this;
       return this;
     }
     }
 
 
+    @Override
     public Builder addRepeatedField(FieldDescriptor field, Object value) {
     public Builder addRepeatedField(FieldDescriptor field, Object value) {
       verifyContainingType(field);
       verifyContainingType(field);
       ensureIsMutable();
       ensureIsMutable();
@@ -544,10 +574,12 @@ public final class DynamicMessage extends AbstractMessage {
       return this;
       return this;
     }
     }
 
 
+    @Override
     public UnknownFieldSet getUnknownFields() {
     public UnknownFieldSet getUnknownFields() {
       return unknownFields;
       return unknownFields;
     }
     }
 
 
+    @Override
     public Builder setUnknownFields(UnknownFieldSet unknownFields) {
     public Builder setUnknownFields(UnknownFieldSet unknownFields) {
       if (getDescriptorForType().getFile().getSyntax()
       if (getDescriptorForType().getFile().getSyntax()
           == Descriptors.FileDescriptor.Syntax.PROTO3) {
           == Descriptors.FileDescriptor.Syntax.PROTO3) {

+ 1 - 0
java/core/src/main/java/com/google/protobuf/Extension.java

@@ -42,6 +42,7 @@ public abstract class Extension<ContainingType extends MessageLite, Type>
   public abstract Descriptors.FieldDescriptor getDescriptor();
   public abstract Descriptors.FieldDescriptor getDescriptor();
 
 
   /** Returns whether or not this extension is a Lite Extension. */
   /** Returns whether or not this extension is a Lite Extension. */
+  @Override
   final boolean isLite() {
   final boolean isLite() {
     return false;
     return false;
   }
   }

+ 19 - 0
java/core/src/main/java/com/google/protobuf/FieldSet.java

@@ -120,6 +120,25 @@ final class FieldSet<FieldDescriptorType extends
   public boolean isImmutable() {
   public boolean isImmutable() {
     return isImmutable;
     return isImmutable;
   }
   }
+  
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    
+    if (!(o instanceof FieldSet)) {
+      return false;
+    }
+    
+    FieldSet<?> other = (FieldSet<?>) o;
+    return other.fields.equals(other.fields);
+  }
+  
+  @Override
+  public int hashCode() {
+    return fields.hashCode();
+  }
 
 
   /**
   /**
    * Clones the FieldSet. The returned FieldSet will be mutable even if the
    * Clones the FieldSet. The returned FieldSet will be mutable even if the

+ 42 - 22
java/core/src/main/java/com/google/protobuf/FloatArrayList.java

@@ -34,7 +34,6 @@ import com.google.protobuf.Internal.FloatList;
 
 
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
-import java.util.List;
 import java.util.RandomAccess;
 import java.util.RandomAccess;
 
 
 /**
 /**
@@ -44,8 +43,6 @@ import java.util.RandomAccess;
  */
  */
 final class FloatArrayList extends AbstractProtobufList<Float> implements FloatList, RandomAccess {
 final class FloatArrayList extends AbstractProtobufList<Float> implements FloatList, RandomAccess {
   
   
-  private static final int DEFAULT_CAPACITY = 10;
-  
   private static final FloatArrayList EMPTY_LIST = new FloatArrayList();
   private static final FloatArrayList EMPTY_LIST = new FloatArrayList();
   static {
   static {
     EMPTY_LIST.makeImmutable();
     EMPTY_LIST.makeImmutable();
@@ -70,32 +67,55 @@ final class FloatArrayList extends AbstractProtobufList<Float> implements FloatL
    * Constructs a new mutable {@code FloatArrayList} with default capacity.
    * Constructs a new mutable {@code FloatArrayList} with default capacity.
    */
    */
   FloatArrayList() {
   FloatArrayList() {
-    this(DEFAULT_CAPACITY);
-  }
-
-  /**
-   * Constructs a new mutable {@code FloatArrayList} with the provided capacity.
-   */
-  FloatArrayList(int capacity) {
-    array = new float[capacity];
-    size = 0;
+    this(new float[DEFAULT_CAPACITY], 0);
   }
   }
 
 
   /**
   /**
    * Constructs a new mutable {@code FloatArrayList} containing the same elements as {@code other}.
    * Constructs a new mutable {@code FloatArrayList} containing the same elements as {@code other}.
    */
    */
-  FloatArrayList(List<Float> other) {
-    if (other instanceof FloatArrayList) {
-      FloatArrayList list = (FloatArrayList) other;
-      array = list.array.clone();
-      size = list.size;
-    } else {
-      size = other.size();
-      array = new float[size];
-      for (int i = 0; i < size; i++) {
-        array[i] = other.get(i);
+  private FloatArrayList(float[] array, int size) {
+    this.array = array;
+    this.size = size;
+  }
+  
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof FloatArrayList)) {
+      return super.equals(o);
+    }
+    FloatArrayList other = (FloatArrayList) o;
+    if (size != other.size) {
+      return false;
+    }
+    
+    final float[] arr = other.array;
+    for (int i = 0; i < size; i++) {
+      if (array[i] != arr[i]) {
+        return false;
       }
       }
     }
     }
+    
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = 1;
+    for (int i = 0; i < size; i++) {
+      result = (31 * result) + Float.floatToIntBits(array[i]);
+    }
+    return result;
+  }
+
+  @Override
+  public FloatList mutableCopyWithCapacity(int capacity) {
+    if (capacity < size) {
+      throw new IllegalArgumentException();
+    }
+    return new FloatArrayList(Arrays.copyOf(array, capacity), size);
   }
   }
   
   
   @Override
   @Override

+ 152 - 103
java/core/src/main/java/com/google/protobuf/GeneratedMessage.java

@@ -80,6 +80,7 @@ public abstract class GeneratedMessage extends AbstractMessage
     unknownFields = builder.getUnknownFields();
     unknownFields = builder.getUnknownFields();
   }
   }
 
 
+  @Override
   public Parser<? extends GeneratedMessage> getParserForType() {
   public Parser<? extends GeneratedMessage> getParserForType() {
     throw new UnsupportedOperationException(
     throw new UnsupportedOperationException(
         "This is supposed to be overridden by subclasses.");
         "This is supposed to be overridden by subclasses.");
@@ -102,7 +103,7 @@ public abstract class GeneratedMessage extends AbstractMessage
    */
    */
   protected abstract FieldAccessorTable internalGetFieldAccessorTable();
   protected abstract FieldAccessorTable internalGetFieldAccessorTable();
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public Descriptor getDescriptorForType() {
   public Descriptor getDescriptorForType() {
     return internalGetFieldAccessorTable().descriptor;
     return internalGetFieldAccessorTable().descriptor;
   }
   }
@@ -191,7 +192,7 @@ public abstract class GeneratedMessage extends AbstractMessage
     return true;
     return true;
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public Map<FieldDescriptor, Object> getAllFields() {
   public Map<FieldDescriptor, Object> getAllFields() {
     return Collections.unmodifiableMap(
     return Collections.unmodifiableMap(
         getAllFieldsMutable(/* getBytesForString = */ false));
         getAllFieldsMutable(/* getBytesForString = */ false));
@@ -212,22 +213,22 @@ public abstract class GeneratedMessage extends AbstractMessage
         getAllFieldsMutable(/* getBytesForString = */ true));
         getAllFieldsMutable(/* getBytesForString = */ true));
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public boolean hasOneof(final OneofDescriptor oneof) {
   public boolean hasOneof(final OneofDescriptor oneof) {
     return internalGetFieldAccessorTable().getOneof(oneof).has(this);
     return internalGetFieldAccessorTable().getOneof(oneof).has(this);
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
   public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
     return internalGetFieldAccessorTable().getOneof(oneof).get(this);
     return internalGetFieldAccessorTable().getOneof(oneof).get(this);
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public boolean hasField(final FieldDescriptor field) {
   public boolean hasField(final FieldDescriptor field) {
     return internalGetFieldAccessorTable().getField(field).has(this);
     return internalGetFieldAccessorTable().getField(field).has(this);
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public Object getField(final FieldDescriptor field) {
   public Object getField(final FieldDescriptor field) {
     return internalGetFieldAccessorTable().getField(field).get(this);
     return internalGetFieldAccessorTable().getField(field).get(this);
   }
   }
@@ -244,19 +245,19 @@ public abstract class GeneratedMessage extends AbstractMessage
     return internalGetFieldAccessorTable().getField(field).getRaw(this);
     return internalGetFieldAccessorTable().getField(field).getRaw(this);
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public int getRepeatedFieldCount(final FieldDescriptor field) {
   public int getRepeatedFieldCount(final FieldDescriptor field) {
     return internalGetFieldAccessorTable().getField(field)
     return internalGetFieldAccessorTable().getField(field)
       .getRepeatedCount(this);
       .getRepeatedCount(this);
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public Object getRepeatedField(final FieldDescriptor field, final int index) {
   public Object getRepeatedField(final FieldDescriptor field, final int index) {
     return internalGetFieldAccessorTable().getField(field)
     return internalGetFieldAccessorTable().getField(field)
       .getRepeated(this, index);
       .getRepeated(this, index);
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public UnknownFieldSet getUnknownFields() {
   public UnknownFieldSet getUnknownFields() {
     throw new UnsupportedOperationException(
     throw new UnsupportedOperationException(
         "This is supposed to be overridden by subclasses.");
         "This is supposed to be overridden by subclasses.");
@@ -380,7 +381,7 @@ public abstract class GeneratedMessage extends AbstractMessage
   }
   }
 
 
   @SuppressWarnings("unchecked")
   @SuppressWarnings("unchecked")
-  public abstract static class Builder <BuilderType extends Builder>
+  public abstract static class Builder <BuilderType extends Builder<BuilderType>>
       extends AbstractMessage.Builder<BuilderType> {
       extends AbstractMessage.Builder<BuilderType> {
 
 
     private BuilderParent builderParent;
     private BuilderParent builderParent;
@@ -444,6 +445,7 @@ public abstract class GeneratedMessage extends AbstractMessage
      * Called by the initialization and clear code paths to allow subclasses to
      * Called by the initialization and clear code paths to allow subclasses to
      * reset any of their builtin fields back to the initial values.
      * reset any of their builtin fields back to the initial values.
      */
      */
+    @Override
     public BuilderType clear() {
     public BuilderType clear() {
       unknownFields = UnknownFieldSet.getDefaultInstance();
       unknownFields = UnknownFieldSet.getDefaultInstance();
       onChanged();
       onChanged();
@@ -457,12 +459,12 @@ public abstract class GeneratedMessage extends AbstractMessage
      */
      */
     protected abstract FieldAccessorTable internalGetFieldAccessorTable();
     protected abstract FieldAccessorTable internalGetFieldAccessorTable();
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public Descriptor getDescriptorForType() {
     public Descriptor getDescriptorForType() {
       return internalGetFieldAccessorTable().descriptor;
       return internalGetFieldAccessorTable().descriptor;
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public Map<FieldDescriptor, Object> getAllFields() {
     public Map<FieldDescriptor, Object> getAllFields() {
       return Collections.unmodifiableMap(getAllFieldsMutable());
       return Collections.unmodifiableMap(getAllFieldsMutable());
     }
     }
@@ -510,39 +512,38 @@ public abstract class GeneratedMessage extends AbstractMessage
       return result;
       return result;
     }
     }
 
 
-    public Message.Builder newBuilderForField(
-        final FieldDescriptor field) {
+    @Override
+    public Message.Builder newBuilderForField(final FieldDescriptor field) {
       return internalGetFieldAccessorTable().getField(field).newBuilder();
       return internalGetFieldAccessorTable().getField(field).newBuilder();
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public Message.Builder getFieldBuilder(final FieldDescriptor field) {
     public Message.Builder getFieldBuilder(final FieldDescriptor field) {
       return internalGetFieldAccessorTable().getField(field).getBuilder(this);
       return internalGetFieldAccessorTable().getField(field).getBuilder(this);
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
-    public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field,
-        int index) {
+    @Override
+    public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field, int index) {
       return internalGetFieldAccessorTable().getField(field).getRepeatedBuilder(
       return internalGetFieldAccessorTable().getField(field).getRepeatedBuilder(
           this, index);
           this, index);
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public boolean hasOneof(final OneofDescriptor oneof) {
     public boolean hasOneof(final OneofDescriptor oneof) {
       return internalGetFieldAccessorTable().getOneof(oneof).has(this);
       return internalGetFieldAccessorTable().getOneof(oneof).has(this);
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
     public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
       return internalGetFieldAccessorTable().getOneof(oneof).get(this);
       return internalGetFieldAccessorTable().getOneof(oneof).get(this);
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public boolean hasField(final FieldDescriptor field) {
     public boolean hasField(final FieldDescriptor field) {
       return internalGetFieldAccessorTable().getField(field).has(this);
       return internalGetFieldAccessorTable().getField(field).has(this);
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public Object getField(final FieldDescriptor field) {
     public Object getField(final FieldDescriptor field) {
       Object object = internalGetFieldAccessorTable().getField(field).get(this);
       Object object = internalGetFieldAccessorTable().getField(field).get(this);
       if (field.isRepeated()) {
       if (field.isRepeated()) {
@@ -554,52 +555,52 @@ public abstract class GeneratedMessage extends AbstractMessage
       }
       }
     }
     }
 
 
-    public BuilderType setField(final FieldDescriptor field,
-                                final Object value) {
+    @Override
+    public BuilderType setField(final FieldDescriptor field, final Object value) {
       internalGetFieldAccessorTable().getField(field).set(this, value);
       internalGetFieldAccessorTable().getField(field).set(this, value);
       return (BuilderType) this;
       return (BuilderType) this;
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public BuilderType clearField(final FieldDescriptor field) {
     public BuilderType clearField(final FieldDescriptor field) {
       internalGetFieldAccessorTable().getField(field).clear(this);
       internalGetFieldAccessorTable().getField(field).clear(this);
       return (BuilderType) this;
       return (BuilderType) this;
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public BuilderType clearOneof(final OneofDescriptor oneof) {
     public BuilderType clearOneof(final OneofDescriptor oneof) {
       internalGetFieldAccessorTable().getOneof(oneof).clear(this);
       internalGetFieldAccessorTable().getOneof(oneof).clear(this);
       return (BuilderType) this;
       return (BuilderType) this;
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public int getRepeatedFieldCount(final FieldDescriptor field) {
     public int getRepeatedFieldCount(final FieldDescriptor field) {
       return internalGetFieldAccessorTable().getField(field)
       return internalGetFieldAccessorTable().getField(field)
           .getRepeatedCount(this);
           .getRepeatedCount(this);
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
-    public Object getRepeatedField(final FieldDescriptor field,
-                                   final int index) {
+    @Override
+    public Object getRepeatedField(final FieldDescriptor field, final int index) {
       return internalGetFieldAccessorTable().getField(field)
       return internalGetFieldAccessorTable().getField(field)
           .getRepeated(this, index);
           .getRepeated(this, index);
     }
     }
 
 
-    public BuilderType setRepeatedField(final FieldDescriptor field,
-                                        final int index, final Object value) {
+    @Override
+    public BuilderType setRepeatedField(
+        final FieldDescriptor field, final int index, final Object value) {
       internalGetFieldAccessorTable().getField(field)
       internalGetFieldAccessorTable().getField(field)
         .setRepeated(this, index, value);
         .setRepeated(this, index, value);
       return (BuilderType) this;
       return (BuilderType) this;
     }
     }
 
 
-    public BuilderType addRepeatedField(final FieldDescriptor field,
-                                        final Object value) {
+    @Override
+    public BuilderType addRepeatedField(final FieldDescriptor field, final Object value) {
       internalGetFieldAccessorTable().getField(field).addRepeated(this, value);
       internalGetFieldAccessorTable().getField(field).addRepeated(this, value);
       return (BuilderType) this;
       return (BuilderType) this;
     }
     }
 
 
-    public BuilderType setUnknownFields(
-        final UnknownFieldSet unknownFields) {
+    @Override
+    public BuilderType setUnknownFields(final UnknownFieldSet unknownFields) {
       this.unknownFields = unknownFields;
       this.unknownFields = unknownFields;
       onChanged();
       onChanged();
       return (BuilderType) this;
       return (BuilderType) this;
@@ -616,7 +617,7 @@ public abstract class GeneratedMessage extends AbstractMessage
       return (BuilderType) this;
       return (BuilderType) this;
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public boolean isInitialized() {
     public boolean isInitialized() {
       for (final FieldDescriptor field : getDescriptorForType().getFields()) {
       for (final FieldDescriptor field : getDescriptorForType().getFields()) {
         // Check that all required fields are present.
         // Check that all required fields are present.
@@ -646,7 +647,7 @@ public abstract class GeneratedMessage extends AbstractMessage
       return true;
       return true;
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public final UnknownFieldSet getUnknownFields() {
     public final UnknownFieldSet getUnknownFields() {
       return unknownFields;
       return unknownFields;
     }
     }
@@ -670,7 +671,7 @@ public abstract class GeneratedMessage extends AbstractMessage
      */
      */
     private class BuilderParentImpl implements BuilderParent {
     private class BuilderParentImpl implements BuilderParent {
 
 
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      @Override
       public void markDirty() {
       public void markDirty() {
         onChanged();
         onChanged();
       }
       }
@@ -735,6 +736,7 @@ public abstract class GeneratedMessage extends AbstractMessage
   public interface ExtendableMessageOrBuilder<
   public interface ExtendableMessageOrBuilder<
       MessageType extends ExtendableMessage> extends MessageOrBuilder {
       MessageType extends ExtendableMessage> extends MessageOrBuilder {
     // Re-define for return type covariance.
     // Re-define for return type covariance.
+    @Override
     Message getDefaultInstanceForType();
     Message getDefaultInstanceForType();
 
 
     /** Check if a singular extension is present. */
     /** Check if a singular extension is present. */
@@ -821,9 +823,8 @@ public abstract class GeneratedMessage extends AbstractMessage
     }
     }
 
 
     /** Check if a singular extension is present. */
     /** 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 ExtensionLite<MessageType, Type> extensionLite) {
+    @Override
+    public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) {
       Extension<MessageType, Type> extension = checkNotLite(extensionLite);
       Extension<MessageType, Type> extension = checkNotLite(extensionLite);
 
 
       verifyExtensionContainingType(extension);
       verifyExtensionContainingType(extension);
@@ -831,7 +832,7 @@ public abstract class GeneratedMessage extends AbstractMessage
     }
     }
 
 
     /** Get the number of elements in a repeated extension. */
     /** Get the number of elements in a repeated extension. */
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public final <Type> int getExtensionCount(
     public final <Type> int getExtensionCount(
         final ExtensionLite<MessageType, List<Type>> extensionLite) {
         final ExtensionLite<MessageType, List<Type>> extensionLite) {
       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
@@ -842,10 +843,9 @@ public abstract class GeneratedMessage extends AbstractMessage
     }
     }
 
 
     /** Get the value of an extension. */
     /** Get the value of an extension. */
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
-    public final <Type> Type getExtension(
-        final ExtensionLite<MessageType, Type> extensionLite) {
+    public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extensionLite) {
       Extension<MessageType, Type> extension = checkNotLite(extensionLite);
       Extension<MessageType, Type> extension = checkNotLite(extensionLite);
 
 
       verifyExtensionContainingType(extension);
       verifyExtensionContainingType(extension);
@@ -867,11 +867,10 @@ public abstract class GeneratedMessage extends AbstractMessage
     }
     }
 
 
     /** Get one element of a repeated extension. */
     /** Get one element of a repeated extension. */
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
     public final <Type> Type getExtension(
     public final <Type> Type getExtension(
-        final ExtensionLite<MessageType, List<Type>> extensionLite,
-        final int index) {
+        final ExtensionLite<MessageType, List<Type>> extensionLite, final int index) {
       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
 
 
       verifyExtensionContainingType(extension);
       verifyExtensionContainingType(extension);
@@ -1105,7 +1104,7 @@ public abstract class GeneratedMessage extends AbstractMessage
   @SuppressWarnings("unchecked")
   @SuppressWarnings("unchecked")
   public abstract static class ExtendableBuilder<
   public abstract static class ExtendableBuilder<
         MessageType extends ExtendableMessage,
         MessageType extends ExtendableMessage,
-        BuilderType extends ExtendableBuilder>
+        BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
       extends Builder<BuilderType>
       extends Builder<BuilderType>
       implements ExtendableMessageOrBuilder<MessageType> {
       implements ExtendableMessageOrBuilder<MessageType> {
 
 
@@ -1157,9 +1156,8 @@ public abstract class GeneratedMessage extends AbstractMessage
     }
     }
 
 
     /** Check if a singular extension is present. */
     /** 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 ExtensionLite<MessageType, Type> extensionLite) {
+    @Override
+    public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) {
       Extension<MessageType, Type> extension = checkNotLite(extensionLite);
       Extension<MessageType, Type> extension = checkNotLite(extensionLite);
 
 
       verifyExtensionContainingType(extension);
       verifyExtensionContainingType(extension);
@@ -1167,7 +1165,7 @@ public abstract class GeneratedMessage extends AbstractMessage
     }
     }
 
 
     /** Get the number of elements in a repeated extension. */
     /** Get the number of elements in a repeated extension. */
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public final <Type> int getExtensionCount(
     public final <Type> int getExtensionCount(
         final ExtensionLite<MessageType, List<Type>> extensionLite) {
         final ExtensionLite<MessageType, List<Type>> extensionLite) {
       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
@@ -1178,9 +1176,8 @@ public abstract class GeneratedMessage extends AbstractMessage
     }
     }
 
 
     /** Get the value of an extension. */
     /** Get the value of an extension. */
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
-    public final <Type> Type getExtension(
-        final ExtensionLite<MessageType, Type> extensionLite) {
+    @Override
+    public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extensionLite) {
       Extension<MessageType, Type> extension = checkNotLite(extensionLite);
       Extension<MessageType, Type> extension = checkNotLite(extensionLite);
 
 
       verifyExtensionContainingType(extension);
       verifyExtensionContainingType(extension);
@@ -1202,10 +1199,9 @@ public abstract class GeneratedMessage extends AbstractMessage
     }
     }
 
 
     /** Get one element of a repeated extension. */
     /** Get one element of a repeated extension. */
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public final <Type> Type getExtension(
     public final <Type> Type getExtension(
-        final ExtensionLite<MessageType, List<Type>> extensionLite,
-        final int index) {
+        final ExtensionLite<MessageType, List<Type>> extensionLite, final int index) {
       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
       Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
 
 
       verifyExtensionContainingType(extension);
       verifyExtensionContainingType(extension);
@@ -1458,10 +1454,9 @@ public abstract class GeneratedMessage extends AbstractMessage
     // obtained.
     // obtained.
     return new GeneratedExtension<ContainingType, Type>(
     return new GeneratedExtension<ContainingType, Type>(
         new CachedDescriptorRetriever() {
         new CachedDescriptorRetriever() {
-          //@Override (Java 1.6 override semantics, but we must support 1.5)
+          @Override
           public FieldDescriptor loadDescriptor() {
           public FieldDescriptor loadDescriptor() {
-            return scope.getDescriptorForType().getExtensions()
-                .get(descriptorIndex);
+            return scope.getDescriptorForType().getExtensions().get(descriptorIndex);
           }
           }
         },
         },
         singularType,
         singularType,
@@ -1489,6 +1484,7 @@ public abstract class GeneratedMessage extends AbstractMessage
     private volatile FieldDescriptor descriptor;
     private volatile FieldDescriptor descriptor;
     protected abstract FieldDescriptor loadDescriptor();
     protected abstract FieldDescriptor loadDescriptor();
 
 
+    @Override
     public FieldDescriptor getDescriptor() {
     public FieldDescriptor getDescriptor() {
       if (descriptor == null) {
       if (descriptor == null) {
         synchronized (this) {
         synchronized (this) {
@@ -1518,6 +1514,7 @@ public abstract class GeneratedMessage extends AbstractMessage
     // obtained.
     // obtained.
     return new GeneratedExtension<ContainingType, Type>(
     return new GeneratedExtension<ContainingType, Type>(
         new CachedDescriptorRetriever() {
         new CachedDescriptorRetriever() {
+          @Override
           protected FieldDescriptor loadDescriptor() {
           protected FieldDescriptor loadDescriptor() {
             return scope.getDescriptorForType().findFieldByName(name);
             return scope.getDescriptorForType().findFieldByName(name);
           }
           }
@@ -1544,17 +1541,18 @@ public abstract class GeneratedMessage extends AbstractMessage
     // used to obtain the extension's FieldDescriptor.
     // used to obtain the extension's FieldDescriptor.
     return new GeneratedExtension<ContainingType, Type>(
     return new GeneratedExtension<ContainingType, Type>(
         new CachedDescriptorRetriever() {
         new CachedDescriptorRetriever() {
+          @Override
           protected FieldDescriptor loadDescriptor() {
           protected FieldDescriptor loadDescriptor() {
             try {
             try {
-              Class clazz =
-                  singularType.getClassLoader().loadClass(descriptorOuterClass);
-              FileDescriptor file =
-                  (FileDescriptor) clazz.getField("descriptor").get(null);
+              Class clazz = singularType.getClassLoader().loadClass(descriptorOuterClass);
+              FileDescriptor file = (FileDescriptor) clazz.getField("descriptor").get(null);
               return file.findExtensionByName(extensionName);
               return file.findExtensionByName(extensionName);
             } catch (Exception e) {
             } catch (Exception e) {
               throw new RuntimeException(
               throw new RuntimeException(
-                  "Cannot load descriptors: " + descriptorOuterClass +
-                  " is not a valid descriptor class name", e);
+                  "Cannot load descriptors: "
+                      + descriptorOuterClass
+                      + " is not a valid descriptor class name",
+                  e);
             }
             }
           }
           }
         },
         },
@@ -1636,12 +1634,13 @@ public abstract class GeneratedMessage extends AbstractMessage
       if (descriptorRetriever != null) {
       if (descriptorRetriever != null) {
         throw new IllegalStateException("Already initialized.");
         throw new IllegalStateException("Already initialized.");
       }
       }
-      descriptorRetriever = new ExtensionDescriptorRetriever() {
-          //@Override (Java 1.6 override semantics, but we must support 1.5)
-          public FieldDescriptor getDescriptor() {
-            return descriptor;
-          }
-        };
+      descriptorRetriever =
+          new ExtensionDescriptorRetriever() {
+            @Override
+            public FieldDescriptor getDescriptor() {
+              return descriptor;
+            }
+          };
     }
     }
 
 
     private ExtensionDescriptorRetriever descriptorRetriever;
     private ExtensionDescriptorRetriever descriptorRetriever;
@@ -1651,6 +1650,7 @@ public abstract class GeneratedMessage extends AbstractMessage
     private final Method enumGetValueDescriptor;
     private final Method enumGetValueDescriptor;
     private final ExtensionType extensionType;
     private final ExtensionType extensionType;
 
 
+    @Override
     public FieldDescriptor getDescriptor() {
     public FieldDescriptor getDescriptor() {
       if (descriptorRetriever == null) {
       if (descriptorRetriever == null) {
         throw new IllegalStateException(
         throw new IllegalStateException(
@@ -1663,10 +1663,12 @@ public abstract class GeneratedMessage extends AbstractMessage
      * If the extension is an embedded message or group, returns the default
      * If the extension is an embedded message or group, returns the default
      * instance of the message.
      * instance of the message.
      */
      */
+    @Override
     public Message getMessageDefaultInstance() {
     public Message getMessageDefaultInstance() {
       return messageDefaultInstance;
       return messageDefaultInstance;
     }
     }
 
 
+    @Override
     protected ExtensionType getExtensionType() {
     protected ExtensionType getExtensionType() {
       return extensionType;
       return extensionType;
     }
     }
@@ -1677,7 +1679,7 @@ public abstract class GeneratedMessage extends AbstractMessage
      * EnumValueDescriptors but the native accessors use the generated enum
      * EnumValueDescriptors but the native accessors use the generated enum
      * type.
      * type.
      */
      */
-    // @Override
+    @Override
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
     protected Object fromReflectionType(final Object value) {
     protected Object fromReflectionType(final Object value) {
       FieldDescriptor descriptor = getDescriptor();
       FieldDescriptor descriptor = getDescriptor();
@@ -1702,7 +1704,7 @@ public abstract class GeneratedMessage extends AbstractMessage
      * Like {@link #fromReflectionType(Object)}, but if the type is a repeated
      * Like {@link #fromReflectionType(Object)}, but if the type is a repeated
      * type, this converts a single element.
      * type, this converts a single element.
      */
      */
-    // @Override
+    @Override
     protected Object singularFromReflectionType(final Object value) {
     protected Object singularFromReflectionType(final Object value) {
       FieldDescriptor descriptor = getDescriptor();
       FieldDescriptor descriptor = getDescriptor();
       switch (descriptor.getJavaType()) {
       switch (descriptor.getJavaType()) {
@@ -1726,7 +1728,7 @@ public abstract class GeneratedMessage extends AbstractMessage
      * EnumValueDescriptors but the native accessors use the generated enum
      * EnumValueDescriptors but the native accessors use the generated enum
      * type.
      * type.
      */
      */
-    // @Override
+    @Override
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
     protected Object toReflectionType(final Object value) {
     protected Object toReflectionType(final Object value) {
       FieldDescriptor descriptor = getDescriptor();
       FieldDescriptor descriptor = getDescriptor();
@@ -1750,7 +1752,7 @@ public abstract class GeneratedMessage extends AbstractMessage
      * Like {@link #toReflectionType(Object)}, but if the type is a repeated
      * Like {@link #toReflectionType(Object)}, but if the type is a repeated
      * type, this converts a single element.
      * type, this converts a single element.
      */
      */
-    // @Override
+    @Override
     protected Object singularToReflectionType(final Object value) {
     protected Object singularToReflectionType(final Object value) {
       FieldDescriptor descriptor = getDescriptor();
       FieldDescriptor descriptor = getDescriptor();
       switch (descriptor.getJavaType()) {
       switch (descriptor.getJavaType()) {
@@ -1761,22 +1763,22 @@ public abstract class GeneratedMessage extends AbstractMessage
       }
       }
     }
     }
 
 
-    // @Override
+    @Override
     public int getNumber() {
     public int getNumber() {
       return getDescriptor().getNumber();
       return getDescriptor().getNumber();
     }
     }
 
 
-    // @Override
+    @Override
     public WireFormat.FieldType getLiteType() {
     public WireFormat.FieldType getLiteType() {
       return getDescriptor().getLiteType();
       return getDescriptor().getLiteType();
     }
     }
 
 
-    // @Override
+    @Override
     public boolean isRepeated() {
     public boolean isRepeated() {
       return getDescriptor().isRepeated();
       return getDescriptor().isRepeated();
     }
     }
 
 
-    // @Override
+    @Override
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
     public Type getDefaultValue() {
     public Type getDefaultValue() {
       if (isRepeated()) {
       if (isRepeated()) {
@@ -2126,49 +2128,57 @@ public abstract class GeneratedMessage extends AbstractMessage
         return ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber();
         return ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber();
       }
       }
 
 
+      @Override
       public Object get(final GeneratedMessage message) {
       public Object get(final GeneratedMessage message) {
         return invokeOrDie(getMethod, message);
         return invokeOrDie(getMethod, message);
       }
       }
+      @Override
       public Object get(GeneratedMessage.Builder builder) {
       public Object get(GeneratedMessage.Builder builder) {
         return invokeOrDie(getMethodBuilder, builder);
         return invokeOrDie(getMethodBuilder, builder);
       }
       }
+      @Override
       public Object getRaw(final GeneratedMessage message) {
       public Object getRaw(final GeneratedMessage message) {
         return get(message);
         return get(message);
       }
       }
+      @Override
       public Object getRaw(GeneratedMessage.Builder builder) {
       public Object getRaw(GeneratedMessage.Builder builder) {
         return get(builder);
         return get(builder);
       }
       }
+      @Override
       public void set(final Builder builder, final Object value) {
       public void set(final Builder builder, final Object value) {
         invokeOrDie(setMethod, builder, value);
         invokeOrDie(setMethod, builder, value);
       }
       }
-      public Object getRepeated(final GeneratedMessage message,
-                                final int index) {
+      @Override
+      public Object getRepeated(final GeneratedMessage message, final int index) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "getRepeatedField() called on a singular field.");
           "getRepeatedField() called on a singular field.");
       }
       }
-      public Object getRepeatedRaw(final GeneratedMessage message,
-                                final int index) {
+      @Override
+      public Object getRepeatedRaw(final GeneratedMessage message, final int index) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "getRepeatedFieldRaw() called on a singular field.");
           "getRepeatedFieldRaw() called on a singular field.");
       }
       }
+      @Override
       public Object getRepeated(GeneratedMessage.Builder builder, int index) {
       public Object getRepeated(GeneratedMessage.Builder builder, int index) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "getRepeatedField() called on a singular field.");
           "getRepeatedField() called on a singular field.");
       }
       }
-      public Object getRepeatedRaw(GeneratedMessage.Builder builder,
-          int index) {
+      @Override
+      public Object getRepeatedRaw(GeneratedMessage.Builder builder, int index) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "getRepeatedFieldRaw() called on a singular field.");
           "getRepeatedFieldRaw() called on a singular field.");
       }
       }
-      public void setRepeated(final Builder builder, final int index,
-          final Object value) {
+      @Override
+      public void setRepeated(final Builder builder, final int index, final Object value) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "setRepeatedField() called on a singular field.");
           "setRepeatedField() called on a singular field.");
       }
       }
+      @Override
       public void addRepeated(final Builder builder, final Object value) {
       public void addRepeated(final Builder builder, final Object value) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "addRepeatedField() called on a singular field.");
           "addRepeatedField() called on a singular field.");
       }
       }
+      @Override
       public boolean has(final GeneratedMessage message) {
       public boolean has(final GeneratedMessage message) {
         if (!hasHasMethod) {
         if (!hasHasMethod) {
           if (isOneofField) {
           if (isOneofField) {
@@ -2178,6 +2188,7 @@ public abstract class GeneratedMessage extends AbstractMessage
         }
         }
         return (Boolean) invokeOrDie(hasMethod, message);
         return (Boolean) invokeOrDie(hasMethod, message);
       }
       }
+      @Override
       public boolean has(GeneratedMessage.Builder builder) {
       public boolean has(GeneratedMessage.Builder builder) {
         if (!hasHasMethod) {
         if (!hasHasMethod) {
           if (isOneofField) {
           if (isOneofField) {
@@ -2187,27 +2198,32 @@ public abstract class GeneratedMessage extends AbstractMessage
         }
         }
         return (Boolean) invokeOrDie(hasMethodBuilder, builder);
         return (Boolean) invokeOrDie(hasMethodBuilder, builder);
       }
       }
+      @Override
       public int getRepeatedCount(final GeneratedMessage message) {
       public int getRepeatedCount(final GeneratedMessage message) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "getRepeatedFieldSize() called on a singular field.");
           "getRepeatedFieldSize() called on a singular field.");
       }
       }
+      @Override
       public int getRepeatedCount(GeneratedMessage.Builder builder) {
       public int getRepeatedCount(GeneratedMessage.Builder builder) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "getRepeatedFieldSize() called on a singular field.");
           "getRepeatedFieldSize() called on a singular field.");
       }
       }
+      @Override
       public void clear(final Builder builder) {
       public void clear(final Builder builder) {
         invokeOrDie(clearMethod, builder);
         invokeOrDie(clearMethod, builder);
       }
       }
+      @Override
       public Message.Builder newBuilder() {
       public Message.Builder newBuilder() {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "newBuilderForField() called on a non-Message type.");
           "newBuilderForField() called on a non-Message type.");
       }
       }
+      @Override
       public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
       public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "getFieldBuilder() called on a non-Message type.");
           "getFieldBuilder() called on a non-Message type.");
       }
       }
-      public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder,
-          int index) {
+      @Override
+      public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder, int index) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "getRepeatedFieldBuilder() called on a non-Message type.");
           "getRepeatedFieldBuilder() called on a non-Message type.");
       }
       }
@@ -2251,18 +2267,23 @@ public abstract class GeneratedMessage extends AbstractMessage
         clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
         clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
       }
       }
 
 
+      @Override
       public Object get(final GeneratedMessage message) {
       public Object get(final GeneratedMessage message) {
         return invokeOrDie(getMethod, message);
         return invokeOrDie(getMethod, message);
       }
       }
+      @Override
       public Object get(GeneratedMessage.Builder builder) {
       public Object get(GeneratedMessage.Builder builder) {
         return invokeOrDie(getMethodBuilder, builder);
         return invokeOrDie(getMethodBuilder, builder);
       }
       }
+      @Override
       public Object getRaw(final GeneratedMessage message) {
       public Object getRaw(final GeneratedMessage message) {
         return get(message);
         return get(message);
       }
       }
+      @Override
       public Object getRaw(GeneratedMessage.Builder builder) {
       public Object getRaw(GeneratedMessage.Builder builder) {
         return get(builder);
         return get(builder);
       }
       }
+      @Override
       public void set(final Builder builder, final Object value) {
       public void set(final Builder builder, final Object value) {
         // Add all the elements individually.  This serves two purposes:
         // Add all the elements individually.  This serves two purposes:
         // 1) Verifies that each element has the correct type.
         // 1) Verifies that each element has the correct type.
@@ -2273,54 +2294,64 @@ public abstract class GeneratedMessage extends AbstractMessage
           addRepeated(builder, element);
           addRepeated(builder, element);
         }
         }
       }
       }
-      public Object getRepeated(final GeneratedMessage message,
-                                final int index) {
+      @Override
+      public Object getRepeated(final GeneratedMessage message, final int index) {
         return invokeOrDie(getRepeatedMethod, message, index);
         return invokeOrDie(getRepeatedMethod, message, index);
       }
       }
+      @Override
       public Object getRepeated(GeneratedMessage.Builder builder, int index) {
       public Object getRepeated(GeneratedMessage.Builder builder, int index) {
         return invokeOrDie(getRepeatedMethodBuilder, builder, index);
         return invokeOrDie(getRepeatedMethodBuilder, builder, index);
       }
       }
+      @Override
       public Object getRepeatedRaw(GeneratedMessage message, int index) {
       public Object getRepeatedRaw(GeneratedMessage message, int index) {
         return getRepeated(message, index);
         return getRepeated(message, index);
       }
       }
-      public Object getRepeatedRaw(GeneratedMessage.Builder builder,
-          int index) {
+      @Override
+      public Object getRepeatedRaw(GeneratedMessage.Builder builder, int index) {
         return getRepeated(builder, index);
         return getRepeated(builder, index);
       }
       }
-      public void setRepeated(final Builder builder,
-                              final int index, final Object value) {
+      @Override
+      public void setRepeated(final Builder builder, final int index, final Object value) {
         invokeOrDie(setRepeatedMethod, builder, index, value);
         invokeOrDie(setRepeatedMethod, builder, index, value);
       }
       }
+      @Override
       public void addRepeated(final Builder builder, final Object value) {
       public void addRepeated(final Builder builder, final Object value) {
         invokeOrDie(addRepeatedMethod, builder, value);
         invokeOrDie(addRepeatedMethod, builder, value);
       }
       }
+      @Override
       public boolean has(final GeneratedMessage message) {
       public boolean has(final GeneratedMessage message) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "hasField() called on a repeated field.");
           "hasField() called on a repeated field.");
       }
       }
+      @Override
       public boolean has(GeneratedMessage.Builder builder) {
       public boolean has(GeneratedMessage.Builder builder) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "hasField() called on a repeated field.");
           "hasField() called on a repeated field.");
       }
       }
+      @Override
       public int getRepeatedCount(final GeneratedMessage message) {
       public int getRepeatedCount(final GeneratedMessage message) {
         return (Integer) invokeOrDie(getCountMethod, message);
         return (Integer) invokeOrDie(getCountMethod, message);
       }
       }
+      @Override
       public int getRepeatedCount(GeneratedMessage.Builder builder) {
       public int getRepeatedCount(GeneratedMessage.Builder builder) {
         return (Integer) invokeOrDie(getCountMethodBuilder, builder);
         return (Integer) invokeOrDie(getCountMethodBuilder, builder);
       }
       }
+      @Override
       public void clear(final Builder builder) {
       public void clear(final Builder builder) {
         invokeOrDie(clearMethod, builder);
         invokeOrDie(clearMethod, builder);
       }
       }
+      @Override
       public Message.Builder newBuilder() {
       public Message.Builder newBuilder() {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "newBuilderForField() called on a non-Message type.");
           "newBuilderForField() called on a non-Message type.");
       }
       }
+      @Override
       public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
       public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "getFieldBuilder() called on a non-Message type.");
           "getFieldBuilder() called on a non-Message type.");
       }
       }
-      public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder,
-          int index) {
+      @Override
+      public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder, int index) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
           "getRepeatedFieldBuilder() called on a non-Message type.");
           "getRepeatedFieldBuilder() called on a non-Message type.");
       }
       }
@@ -2357,6 +2388,7 @@ public abstract class GeneratedMessage extends AbstractMessage
             field.getNumber());
             field.getNumber());
       }
       }
 
 
+      @Override
       public Object get(GeneratedMessage message) {
       public Object get(GeneratedMessage message) {
         List result = new ArrayList();
         List result = new ArrayList();
         for (int i = 0; i < getRepeatedCount(message); i++) {
         for (int i = 0; i < getRepeatedCount(message); i++) {
@@ -2365,6 +2397,7 @@ public abstract class GeneratedMessage extends AbstractMessage
         return Collections.unmodifiableList(result);
         return Collections.unmodifiableList(result);
       }
       }
 
 
+      @Override
       public Object get(Builder builder) {
       public Object get(Builder builder) {
         List result = new ArrayList();
         List result = new ArrayList();
         for (int i = 0; i < getRepeatedCount(builder); i++) {
         for (int i = 0; i < getRepeatedCount(builder); i++) {
@@ -2373,14 +2406,17 @@ public abstract class GeneratedMessage extends AbstractMessage
         return Collections.unmodifiableList(result);
         return Collections.unmodifiableList(result);
       }
       }
 
 
+      @Override
       public Object getRaw(GeneratedMessage message) {
       public Object getRaw(GeneratedMessage message) {
         return get(message);
         return get(message);
       }
       }
 
 
+      @Override
       public Object getRaw(GeneratedMessage.Builder builder) {
       public Object getRaw(GeneratedMessage.Builder builder) {
         return get(builder);
         return get(builder);
       }
       }
 
 
+      @Override
       public void set(Builder builder, Object value) {
       public void set(Builder builder, Object value) {
         clear(builder);
         clear(builder);
         for (Object entry : (List) value) {
         for (Object entry : (List) value) {
@@ -2388,63 +2424,76 @@ public abstract class GeneratedMessage extends AbstractMessage
         }
         }
       }
       }
 
 
+      @Override
       public Object getRepeated(GeneratedMessage message, int index) {
       public Object getRepeated(GeneratedMessage message, int index) {
         return getMapField(message).getList().get(index);
         return getMapField(message).getList().get(index);
       }
       }
 
 
+      @Override
       public Object getRepeated(Builder builder, int index) {
       public Object getRepeated(Builder builder, int index) {
         return getMapField(builder).getList().get(index);
         return getMapField(builder).getList().get(index);
       }
       }
 
 
+      @Override
       public Object getRepeatedRaw(GeneratedMessage message, int index) {
       public Object getRepeatedRaw(GeneratedMessage message, int index) {
         return getRepeated(message, index);
         return getRepeated(message, index);
       }
       }
 
 
+      @Override
       public Object getRepeatedRaw(Builder builder, int index) {
       public Object getRepeatedRaw(Builder builder, int index) {
         return getRepeated(builder, index);
         return getRepeated(builder, index);
       }
       }
 
 
+      @Override
       public void setRepeated(Builder builder, int index, Object value) {
       public void setRepeated(Builder builder, int index, Object value) {
         getMutableMapField(builder).getMutableList().set(index, (Message) value);
         getMutableMapField(builder).getMutableList().set(index, (Message) value);
       }
       }
 
 
+      @Override
       public void addRepeated(Builder builder, Object value) {
       public void addRepeated(Builder builder, Object value) {
         getMutableMapField(builder).getMutableList().add((Message) value);
         getMutableMapField(builder).getMutableList().add((Message) value);
       }
       }
 
 
+      @Override
       public boolean has(GeneratedMessage message) {
       public boolean has(GeneratedMessage message) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
             "hasField() is not supported for repeated fields.");
             "hasField() is not supported for repeated fields.");
       }
       }
 
 
+      @Override
       public boolean has(Builder builder) {
       public boolean has(Builder builder) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
             "hasField() is not supported for repeated fields.");
             "hasField() is not supported for repeated fields.");
       }
       }
 
 
+      @Override
       public int getRepeatedCount(GeneratedMessage message) {
       public int getRepeatedCount(GeneratedMessage message) {
         return getMapField(message).getList().size();
         return getMapField(message).getList().size();
       }
       }
 
 
+      @Override
       public int getRepeatedCount(Builder builder) {
       public int getRepeatedCount(Builder builder) {
         return getMapField(builder).getList().size();
         return getMapField(builder).getList().size();
       }
       }
 
 
+      @Override
       public void clear(Builder builder) {
       public void clear(Builder builder) {
         getMutableMapField(builder).getMutableList().clear();
         getMutableMapField(builder).getMutableList().clear();
       }
       }
 
 
+      @Override
       public com.google.protobuf.Message.Builder newBuilder() {
       public com.google.protobuf.Message.Builder newBuilder() {
         return mapEntryMessageDefaultInstance.newBuilderForType();
         return mapEntryMessageDefaultInstance.newBuilderForType();
       }
       }
 
 
+      @Override
       public com.google.protobuf.Message.Builder getBuilder(Builder builder) {
       public com.google.protobuf.Message.Builder getBuilder(Builder builder) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
             "Nested builder not supported for map fields.");
             "Nested builder not supported for map fields.");
       }
       }
 
 
-      public com.google.protobuf.Message.Builder getRepeatedBuilder(
-          Builder builder, int index) {
+      @Override
+      public com.google.protobuf.Message.Builder getRepeatedBuilder(Builder builder, int index) {
         throw new UnsupportedOperationException(
         throw new UnsupportedOperationException(
             "Nested builder not supported for map fields.");
             "Nested builder not supported for map fields.");
       }
       }

+ 926 - 141
java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java

@@ -31,6 +31,7 @@
 package com.google.protobuf;
 package com.google.protobuf;
 
 
 import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
 import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
+import com.google.protobuf.GeneratedMessageLite.EqualsVisitor.NotEqualsException;
 import com.google.protobuf.Internal.BooleanList;
 import com.google.protobuf.Internal.BooleanList;
 import com.google.protobuf.Internal.DoubleList;
 import com.google.protobuf.Internal.DoubleList;
 import com.google.protobuf.Internal.FloatList;
 import com.google.protobuf.Internal.FloatList;
@@ -59,24 +60,27 @@ import java.util.Map;
 public abstract class GeneratedMessageLite<
 public abstract class GeneratedMessageLite<
     MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
     MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
     BuilderType extends GeneratedMessageLite.Builder<MessageType, BuilderType>> 
     BuilderType extends GeneratedMessageLite.Builder<MessageType, BuilderType>> 
-        extends AbstractMessageLite {
+        extends AbstractMessageLite<MessageType, BuilderType> {
 
 
   /** For use by generated code only. Lazily initialized to reduce allocations. */
   /** For use by generated code only. Lazily initialized to reduce allocations. */
-  protected UnknownFieldSetLite unknownFields = null;
+  protected UnknownFieldSetLite unknownFields = UnknownFieldSetLite.getDefaultInstance();
   
   
   /** For use by generated code only.  */
   /** For use by generated code only.  */
   protected int memoizedSerializedSize = -1;
   protected int memoizedSerializedSize = -1;
   
   
+  @Override
   @SuppressWarnings("unchecked") // Guaranteed by runtime.
   @SuppressWarnings("unchecked") // Guaranteed by runtime.
   public final Parser<MessageType> getParserForType() {
   public final Parser<MessageType> getParserForType() {
     return (Parser<MessageType>) dynamicMethod(MethodToInvoke.GET_PARSER);
     return (Parser<MessageType>) dynamicMethod(MethodToInvoke.GET_PARSER);
   }
   }
 
 
+  @Override
   @SuppressWarnings("unchecked") // Guaranteed by runtime.
   @SuppressWarnings("unchecked") // Guaranteed by runtime.
   public final MessageType getDefaultInstanceForType() {
   public final MessageType getDefaultInstanceForType() {
     return (MessageType) dynamicMethod(MethodToInvoke.GET_DEFAULT_INSTANCE);
     return (MessageType) dynamicMethod(MethodToInvoke.GET_DEFAULT_INSTANCE);
   }
   }
 
 
+  @Override
   @SuppressWarnings("unchecked") // Guaranteed by runtime.
   @SuppressWarnings("unchecked") // Guaranteed by runtime.
   public final BuilderType newBuilderForType() {
   public final BuilderType newBuilderForType() {
     return (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER);
     return (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER);
@@ -99,7 +103,65 @@ public abstract class GeneratedMessageLite<
     return MessageLiteToString.toString(this, super.toString());
     return MessageLiteToString.toString(this, super.toString());
   }
   }
 
 
+  @SuppressWarnings("unchecked") // Guaranteed by runtime
+  @Override
+  public int hashCode() {
+    if (memoizedHashCode == 0) {
+      HashCodeVisitor visitor = new HashCodeVisitor();
+      visit(visitor, (MessageType) this);
+      memoizedHashCode = visitor.hashCode;
+    }
+    return memoizedHashCode;
+  }
+  
+  @SuppressWarnings("unchecked") // Guaranteed by runtime
+  int hashCode(HashCodeVisitor visitor) {
+    if (memoizedHashCode == 0) {
+      int inProgressHashCode = visitor.hashCode;
+      visitor.hashCode = 0;
+      visit(visitor, (MessageType) this);
+      memoizedHashCode = visitor.hashCode;
+      visitor.hashCode = inProgressHashCode;
+    }
+    return memoizedHashCode;
+  }
+  
+  @SuppressWarnings("unchecked") // Guaranteed by isInstance + runtime
+  @Override
+  public boolean equals(Object other) {
+    if (this == other) {
+      return true;
+    }
+    
+    if (!getDefaultInstanceForType().getClass().isInstance(other)) {
+      return false;
+    }
+    
+    try {
+      visit(EqualsVisitor.INSTANCE, (MessageType) other);
+    } catch (NotEqualsException e) {
+      return false;
+    }
+    return true;
+  }
+  
+  /**
+   * Same as {@link #equals(Object)} but throws {@code NotEqualsException}.
+   */
+  @SuppressWarnings("unchecked") // Guaranteed by isInstance + runtime
+  boolean equals(EqualsVisitor visitor, MessageLite other) {
+    if (this == other) {
+      return true;
+    }
+    
+    if (!getDefaultInstanceForType().getClass().isInstance(other)) {
+      return false;
+    }
 
 
+    visit(visitor, (MessageType) other);
+    return true;
+  }
+  
   // The general strategy for unknown fields is to use an UnknownFieldSetLite that is treated as
   // The general strategy for unknown fields is to use an UnknownFieldSetLite that is treated as
   // mutable during the parsing constructor and immutable after. This allows us to avoid
   // mutable during the parsing constructor and immutable after. This allows us to avoid
   // any unnecessary intermediary allocations while reducing the generated code size.
   // any unnecessary intermediary allocations while reducing the generated code size.
@@ -108,7 +170,7 @@ public abstract class GeneratedMessageLite<
    * Lazily initializes unknown fields.
    * Lazily initializes unknown fields.
    */
    */
   private final void ensureUnknownFieldsInitialized() {
   private final void ensureUnknownFieldsInitialized() {
-    if (unknownFields == null) {
+    if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
       unknownFields = UnknownFieldSetLite.newInstance();
       unknownFields = UnknownFieldSetLite.newInstance();
     }
     }
   }
   }
@@ -147,18 +209,18 @@ public abstract class GeneratedMessageLite<
   /**
   /**
    * Called by subclasses to complete parsing. For use by generated code only.
    * Called by subclasses to complete parsing. For use by generated code only.
    */
    */
-  protected void doneParsing() {
-    if (unknownFields == null) {
-      unknownFields = UnknownFieldSetLite.getDefaultInstance();
-    } else {
-      unknownFields.makeImmutable();
-    }
+  protected void makeImmutable() {
+    dynamicMethod(MethodToInvoke.MAKE_IMMUTABLE);
+
+    unknownFields.makeImmutable();
   }
   }
 
 
+  @Override
   public final boolean isInitialized() {
   public final boolean isInitialized() {
     return dynamicMethod(MethodToInvoke.IS_INITIALIZED, Boolean.TRUE) != null;
     return dynamicMethod(MethodToInvoke.IS_INITIALIZED, Boolean.TRUE) != null;
   }
   }
 
 
+  @Override
   public final BuilderType toBuilder() {
   public final BuilderType toBuilder() {
     BuilderType builder = (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER);
     BuilderType builder = (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER);
     builder.mergeFrom((MessageType) this);
     builder.mergeFrom((MessageType) this);
@@ -172,11 +234,14 @@ public abstract class GeneratedMessageLite<
    * For use by generated code only.
    * For use by generated code only.
    */
    */
   public static enum MethodToInvoke {
   public static enum MethodToInvoke {
+    // Rely on/modify instance state
     IS_INITIALIZED,
     IS_INITIALIZED,
-    PARSE_PARTIAL_FROM,
-    MERGE_FROM,
+    VISIT,
+    MERGE_FROM_STREAM,
     MAKE_IMMUTABLE,
     MAKE_IMMUTABLE,
-    NEW_INSTANCE,
+
+    // Rely on static state
+    NEW_MUTABLE_INSTANCE,
     NEW_BUILDER,
     NEW_BUILDER,
     GET_DEFAULT_INSTANCE,
     GET_DEFAULT_INSTANCE,
     GET_PARSER;
     GET_PARSER;
@@ -188,17 +253,18 @@ public abstract class GeneratedMessageLite<
    * builders in the runtime. This method bundles those operations to reduce the generated methods
    * builders in the runtime. This method bundles those operations to reduce the generated methods
    * count.
    * count.
    * <ul>
    * <ul>
-   * <li>{@code PARSE_PARTIAL_FROM} is parameterized with an {@link CodedInputStream} and
+   * <li>{@code MERGE_FROM_STREAM} is parameterized with an {@link CodedInputStream} and
    * {@link ExtensionRegistryLite}. It consumes the input stream, parsing the contents into the
    * {@link ExtensionRegistryLite}. It consumes the input stream, parsing the contents into the
    * returned protocol buffer. If parsing throws an {@link InvalidProtocolBufferException}, the
    * returned protocol buffer. If parsing throws an {@link InvalidProtocolBufferException}, the
-   * implementation wraps it in a RuntimeException
-   * <li>{@code NEW_INSTANCE} returns a new instance of the protocol buffer
+   * implementation wraps it in a RuntimeException.
+   * <li>{@code NEW_INSTANCE} returns a new instance of the protocol buffer that has not yet been
+   * made immutable. See {@code MAKE_IMMUTABLE}.
    * <li>{@code IS_INITIALIZED} is parameterized with a {@code Boolean} detailing whether to
    * <li>{@code IS_INITIALIZED} is parameterized with a {@code Boolean} detailing whether to
    * memoize. It returns {@code null} for false and the default instance for true. We optionally
    * memoize. It returns {@code null} for false and the default instance for true. We optionally
    * memoize to support the Builder case, where memoization is not desired.
    * memoize to support the Builder case, where memoization is not desired.
    * <li>{@code NEW_BUILDER} returns a {@code BuilderType} instance.
    * <li>{@code NEW_BUILDER} returns a {@code BuilderType} instance.
-   * <li>{@code MERGE_FROM} is parameterized with a {@code MessageType} and merges the fields from
-   * that instance into this instance.
+   * <li>{@code VISIT} is parameterized with a {@code Visitor} and a {@code MessageType} and
+   * recursively iterates through the fields side by side between this and the instance.
    * <li>{@code MAKE_IMMUTABLE} sets all internal fields to an immutable state.
    * <li>{@code MAKE_IMMUTABLE} sets all internal fields to an immutable state.
    * </ul>
    * </ul>
    * This method, plus the implementation of the Builder, enables the Builder class to be proguarded
    * This method, plus the implementation of the Builder, enables the Builder class to be proguarded
@@ -222,6 +288,11 @@ public abstract class GeneratedMessageLite<
     return dynamicMethod(method, null, null);
     return dynamicMethod(method, null, null);
   }
   }
 
 
+  void visit(Visitor visitor, MessageType other) {
+    dynamicMethod(MethodToInvoke.VISIT, visitor, other);
+    unknownFields = visitor.visitUnknownFields(unknownFields, other.unknownFields);
+  }
+  
   /**
   /**
    * Merge some unknown fields into the {@link UnknownFieldSetLite} for this
    * Merge some unknown fields into the {@link UnknownFieldSetLite} for this
    * message.
    * message.
@@ -236,7 +307,7 @@ public abstract class GeneratedMessageLite<
   public abstract static class Builder<
   public abstract static class Builder<
       MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
       MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
       BuilderType extends Builder<MessageType, BuilderType>>
       BuilderType extends Builder<MessageType, BuilderType>>
-          extends AbstractMessageLite.Builder<BuilderType> {
+          extends AbstractMessageLite.Builder<MessageType, BuilderType> {
 
 
     private final MessageType defaultInstance;
     private final MessageType defaultInstance;
     protected MessageType instance;
     protected MessageType instance;
@@ -244,7 +315,8 @@ public abstract class GeneratedMessageLite<
 
 
     protected Builder(MessageType defaultInstance) {
     protected Builder(MessageType defaultInstance) {
       this.defaultInstance = defaultInstance;
       this.defaultInstance = defaultInstance;
-      this.instance = (MessageType) defaultInstance.dynamicMethod(MethodToInvoke.NEW_INSTANCE);
+      this.instance =
+          (MessageType) defaultInstance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
       isBuilt = false;
       isBuilt = false;
     }
     }
 
 
@@ -254,26 +326,27 @@ public abstract class GeneratedMessageLite<
      */
      */
     protected void copyOnWrite() {
     protected void copyOnWrite() {
       if (isBuilt) {
       if (isBuilt) {
-        MessageType newInstance = (MessageType) instance.dynamicMethod(MethodToInvoke.NEW_INSTANCE);
-        newInstance.dynamicMethod(MethodToInvoke.MERGE_FROM, instance);
+        MessageType newInstance =
+            (MessageType) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
+        newInstance.visit(MergeFromVisitor.INSTANCE, instance);
         instance = newInstance;
         instance = newInstance;
         isBuilt = false;
         isBuilt = false;
       }
       }
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public final boolean isInitialized() {
     public final boolean isInitialized() {
       return GeneratedMessageLite.isInitialized(instance, false /* shouldMemoize */);
       return GeneratedMessageLite.isInitialized(instance, false /* shouldMemoize */);
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public final BuilderType clear() {
     public final BuilderType clear() {
       // No need to copy on write since we're dropping the instance anyways.
       // No need to copy on write since we're dropping the instance anyways.
-      instance = (MessageType) instance.dynamicMethod(MethodToInvoke.NEW_INSTANCE);
+      instance = (MessageType) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
       return (BuilderType) this;
       return (BuilderType) this;
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public BuilderType clone() {
     public BuilderType clone() {
       BuilderType builder =
       BuilderType builder =
           (BuilderType) getDefaultInstanceForType().newBuilderForType();
           (BuilderType) getDefaultInstanceForType().newBuilderForType();
@@ -281,20 +354,19 @@ public abstract class GeneratedMessageLite<
       return builder;
       return builder;
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public MessageType buildPartial() {
     public MessageType buildPartial() {
       if (isBuilt) {
       if (isBuilt) {
         return instance;
         return instance;
       }
       }
       
       
-      instance.dynamicMethod(MethodToInvoke.MAKE_IMMUTABLE);
-      instance.unknownFields.makeImmutable();
+      instance.makeImmutable();
       
       
       isBuilt = true;
       isBuilt = true;
       return instance;
       return instance;
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public final MessageType build() {
     public final MessageType build() {
       MessageType result = buildPartial();
       MessageType result = buildPartial();
       if (!result.isInitialized()) {
       if (!result.isInitialized()) {
@@ -303,32 +375,36 @@ public abstract class GeneratedMessageLite<
       return result;
       return result;
     }
     }
     
     
+    @Override
+    protected BuilderType internalMergeFrom(MessageType message) {
+      return mergeFrom(message);
+    }
+    
     /** All subclasses implement this. */
     /** All subclasses implement this. */
     public BuilderType mergeFrom(MessageType message) {
     public BuilderType mergeFrom(MessageType message) {
       copyOnWrite();
       copyOnWrite();
-      instance.dynamicMethod(MethodToInvoke.MERGE_FROM, message);
+      instance.visit(MergeFromVisitor.INSTANCE, message);
       return (BuilderType) this;
       return (BuilderType) this;
     }
     }
     
     
+    @Override
     public MessageType getDefaultInstanceForType() {
     public MessageType getDefaultInstanceForType() {
       return defaultInstance;
       return defaultInstance;
     }
     }
     
     
+    @Override
     public BuilderType mergeFrom(
     public BuilderType mergeFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      MessageType parsedMessage = null;
+        throws IOException {
+      copyOnWrite();
       try {
       try {
-        parsedMessage = parsePartialFrom(
-            (MessageType) getDefaultInstanceForType(), input, extensionRegistry);
-      } catch (InvalidProtocolBufferException e) {
-        parsedMessage = (MessageType) e.getUnfinishedMessage();
-        throw e;
-      } finally {
-        if (parsedMessage != null) {
-          mergeFrom(parsedMessage);
+        instance.dynamicMethod(MethodToInvoke.MERGE_FROM_STREAM, input, extensionRegistry);
+      } catch (RuntimeException e) {
+        if (e.getCause() instanceof IOException) {
+          throw (IOException) e.getCause();
         }
         }
+        throw e;
       }
       }
       return (BuilderType) this;
       return (BuilderType) this;
     }
     }
@@ -384,6 +460,12 @@ public abstract class GeneratedMessageLite<
       }
       }
       extensions.mergeFrom(((ExtendableMessage) other).extensions);
       extensions.mergeFrom(((ExtendableMessage) other).extensions);
     }
     }
+
+    @Override
+    final void visit(Visitor visitor, MessageType other) {
+      super.visit(visitor, other);
+      extensions = visitor.visitExtensions(extensions, other.extensions);
+    }
     
     
     /**
     /**
      * Parse an unknown field or an extension. For use by generated code only.
      * Parse an unknown field or an extension. For use by generated code only.
@@ -521,9 +603,8 @@ public abstract class GeneratedMessageLite<
     }
     }
 
 
     /** Check if a singular extension is present. */
     /** 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 ExtensionLite<MessageType, Type> extension) {
+    @Override
+    public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extension) {
       GeneratedExtension<MessageType, Type> extensionLite =
       GeneratedExtension<MessageType, Type> extensionLite =
           checkIsLite(extension);
           checkIsLite(extension);
       
       
@@ -532,7 +613,7 @@ public abstract class GeneratedMessageLite<
     }
     }
 
 
     /** Get the number of elements in a repeated extension. */
     /** Get the number of elements in a repeated extension. */
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public final <Type> int getExtensionCount(
     public final <Type> int getExtensionCount(
         final ExtensionLite<MessageType, List<Type>> extension) {
         final ExtensionLite<MessageType, List<Type>> extension) {
       GeneratedExtension<MessageType, List<Type>> extensionLite =
       GeneratedExtension<MessageType, List<Type>> extensionLite =
@@ -543,10 +624,9 @@ public abstract class GeneratedMessageLite<
     }
     }
 
 
     /** Get the value of an extension. */
     /** Get the value of an extension. */
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
-    public final <Type> Type getExtension(
-        final ExtensionLite<MessageType, Type> extension) {
+    public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extension) {
       GeneratedExtension<MessageType, Type> extensionLite =
       GeneratedExtension<MessageType, Type> extensionLite =
           checkIsLite(extension);
           checkIsLite(extension);
       
       
@@ -560,11 +640,10 @@ public abstract class GeneratedMessageLite<
     }
     }
 
 
     /** Get one element of a repeated extension. */
     /** Get one element of a repeated extension. */
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
     public final <Type> Type getExtension(
     public final <Type> Type getExtension(
-        final ExtensionLite<MessageType, List<Type>> extension,
-        final int index) {
+        final ExtensionLite<MessageType, List<Type>> extension, final int index) {
       GeneratedExtension<MessageType, List<Type>> extensionLite =
       GeneratedExtension<MessageType, List<Type>> extensionLite =
           checkIsLite(extension);
           checkIsLite(extension);
 
 
@@ -579,8 +658,8 @@ public abstract class GeneratedMessageLite<
     }
     }
 
 
     @Override
     @Override
-    protected final void doneParsing() {
-      super.doneParsing();
+    protected final void makeImmutable() {
+      super.makeImmutable();
       
       
       extensions.makeImmutable();
       extensions.makeImmutable();
     }
     }
@@ -669,7 +748,7 @@ public abstract class GeneratedMessageLite<
       instance.extensions = extensions;
       instance.extensions = extensions;
     }
     }
 
 
-    // @Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     protected void copyOnWrite() {
     protected void copyOnWrite() {
       if (!isBuilt) {
       if (!isBuilt) {
         return;
         return;
@@ -679,7 +758,7 @@ public abstract class GeneratedMessageLite<
       instance.extensions = instance.extensions.clone();
       instance.extensions = instance.extensions.clone();
     }
     }
 
 
-    // @Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public final MessageType buildPartial() {
     public final MessageType buildPartial() {
       if (isBuilt) {
       if (isBuilt) {
         return instance;
         return instance;
@@ -701,33 +780,30 @@ public abstract class GeneratedMessageLite<
     }
     }
 
 
     /** Check if a singular extension is present. */
     /** 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 ExtensionLite<MessageType, Type> extension) {
+    @Override
+    public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extension) {
       return instance.hasExtension(extension);
       return instance.hasExtension(extension);
     }
     }
 
 
     /** Get the number of elements in a repeated extension. */
     /** Get the number of elements in a repeated extension. */
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public final <Type> int getExtensionCount(
     public final <Type> int getExtensionCount(
         final ExtensionLite<MessageType, List<Type>> extension) {
         final ExtensionLite<MessageType, List<Type>> extension) {
       return instance.getExtensionCount(extension);
       return instance.getExtensionCount(extension);
     }
     }
 
 
     /** Get the value of an extension. */
     /** Get the value of an extension. */
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
-    public final <Type> Type getExtension(
-        final ExtensionLite<MessageType, Type> extension) {
+    public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extension) {
       return instance.getExtension(extension);
       return instance.getExtension(extension);
     }
     }
 
 
     /** Get one element of a repeated extension. */
     /** Get one element of a repeated extension. */
+    @Override
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
     public final <Type> Type getExtension(
     public final <Type> Type getExtension(
-        final ExtensionLite<MessageType, List<Type>> extension,
-        final int index) {
+        final ExtensionLite<MessageType, List<Type>> extension, final int index) {
       return instance.getExtension(extension, index);
       return instance.getExtension(extension, index);
     }
     }
 
 
@@ -859,37 +935,44 @@ public abstract class GeneratedMessageLite<
     final boolean isRepeated;
     final boolean isRepeated;
     final boolean isPacked;
     final boolean isPacked;
 
 
+    @Override
     public int getNumber() {
     public int getNumber() {
       return number;
       return number;
     }
     }
 
 
+    @Override
     public WireFormat.FieldType getLiteType() {
     public WireFormat.FieldType getLiteType() {
       return type;
       return type;
     }
     }
 
 
+    @Override
     public WireFormat.JavaType getLiteJavaType() {
     public WireFormat.JavaType getLiteJavaType() {
       return type.getJavaType();
       return type.getJavaType();
     }
     }
 
 
+    @Override
     public boolean isRepeated() {
     public boolean isRepeated() {
       return isRepeated;
       return isRepeated;
     }
     }
 
 
+    @Override
     public boolean isPacked() {
     public boolean isPacked() {
       return isPacked;
       return isPacked;
     }
     }
 
 
+    @Override
     public Internal.EnumLiteMap<?> getEnumType() {
     public Internal.EnumLiteMap<?> getEnumType() {
       return enumTypeMap;
       return enumTypeMap;
     }
     }
 
 
+    @Override
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
-    public MessageLite.Builder internalMergeFrom(
-        MessageLite.Builder to, MessageLite from) {
+    public MessageLite.Builder internalMergeFrom(MessageLite.Builder to, MessageLite from) {
       return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
       return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
     }
     }
 
 
 
 
+    @Override
     public int compareTo(ExtensionDescriptor other) {
     public int compareTo(ExtensionDescriptor other) {
       return number - other.number;
       return number - other.number;
     }
     }
@@ -984,6 +1067,7 @@ public abstract class GeneratedMessageLite<
     }
     }
 
 
     /** Get the field number. */
     /** Get the field number. */
+    @Override
     public int getNumber() {
     public int getNumber() {
       return descriptor.getNumber();
       return descriptor.getNumber();
     }
     }
@@ -993,6 +1077,7 @@ public abstract class GeneratedMessageLite<
      * If the extension is an embedded message or group, returns the default
      * If the extension is an embedded message or group, returns the default
      * instance of the message.
      * instance of the message.
      */
      */
+    @Override
     public MessageLite getMessageDefaultInstance() {
     public MessageLite getMessageDefaultInstance() {
       return messageDefaultInstance;
       return messageDefaultInstance;
     }
     }
@@ -1047,14 +1132,17 @@ public abstract class GeneratedMessageLite<
       }
       }
     }
     }
 
 
+    @Override
     public FieldType getLiteType() {
     public FieldType getLiteType() {
       return descriptor.getLiteType();
       return descriptor.getLiteType();
     }
     }
 
 
+    @Override
     public boolean isRepeated() {
     public boolean isRepeated() {
       return descriptor.isRepeated;
       return descriptor.isRepeated;
     }
     }
 
 
+    @Override
     public Type getDefaultValue() {
     public Type getDefaultValue() {
       return defaultValue;
       return defaultValue;
     }
     }
@@ -1139,112 +1227,72 @@ public abstract class GeneratedMessageLite<
   protected static final <T extends GeneratedMessageLite<T, ?>> boolean isInitialized(
   protected static final <T extends GeneratedMessageLite<T, ?>> boolean isInitialized(
       T message, boolean shouldMemoize) {
       T message, boolean shouldMemoize) {
     return message.dynamicMethod(MethodToInvoke.IS_INITIALIZED, shouldMemoize) != null;
     return message.dynamicMethod(MethodToInvoke.IS_INITIALIZED, shouldMemoize) != null;
-  }
+  } 
   
   
   protected static final <T extends GeneratedMessageLite<T, ?>> void makeImmutable(T message) {
   protected static final <T extends GeneratedMessageLite<T, ?>> void makeImmutable(T message) {
     message.dynamicMethod(MethodToInvoke.MAKE_IMMUTABLE);
     message.dynamicMethod(MethodToInvoke.MAKE_IMMUTABLE);
   }
   }
-  
-  protected static IntList newIntList() {
-    return new IntArrayList();
-  }
-  
-  protected static IntList newIntListWithCapacity(int capacity) {
-    return new IntArrayList(capacity);
-  }
-  
-  protected static IntList newIntList(List<Integer> toCopy) {
-    return new IntArrayList(toCopy);
-  }
-  
+
   protected static IntList emptyIntList() {
   protected static IntList emptyIntList() {
     return IntArrayList.emptyList();
     return IntArrayList.emptyList();
   }
   }
 
 
-  protected static LongList newLongList() {
-    return new LongArrayList();
+  protected static IntList mutableCopy(IntList list) {
+    int size = list.size();
+    return list.mutableCopyWithCapacity(
+        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
   }
   }
 
 
-  protected static LongList newLongListWithCapacity(int capacity) {
-    return new LongArrayList(capacity);
-  }
-  
-  protected static LongList newLongList(List<Long> toCopy) {
-    return new LongArrayList(toCopy);
-  }
-  
   protected static LongList emptyLongList() {
   protected static LongList emptyLongList() {
     return LongArrayList.emptyList();
     return LongArrayList.emptyList();
   }
   }
   
   
-  protected static FloatList newFloatList() {
-    return new FloatArrayList();
+  protected static LongList mutableCopy(LongList list) {
+    int size = list.size();
+    return list.mutableCopyWithCapacity(
+        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
   }
   }
-  
-  protected static FloatList newFloatListWithCapacity(int capacity) {
-    return new FloatArrayList(capacity);
-  }
-  
-  protected static FloatList newFloatList(List<Float> toCopy) {
-    return new FloatArrayList(toCopy);
-  }
-  
+
   protected static FloatList emptyFloatList() {
   protected static FloatList emptyFloatList() {
     return FloatArrayList.emptyList();
     return FloatArrayList.emptyList();
   }
   }
   
   
-  protected static DoubleList newDoubleList() {
-    return new DoubleArrayList();
+  protected static FloatList mutableCopy(FloatList list) {
+    int size = list.size();
+    return list.mutableCopyWithCapacity(
+        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
   }
   }
-  
-  protected static DoubleList newDoubleListWithCapacity(int capacity) {
-    return new DoubleArrayList(capacity);
-  }
-  
-  protected static DoubleList newDoubleList(List<Double> toCopy) {
-    return new DoubleArrayList(toCopy);
-  }
-  
+
   protected static DoubleList emptyDoubleList() {
   protected static DoubleList emptyDoubleList() {
     return DoubleArrayList.emptyList();
     return DoubleArrayList.emptyList();
   }
   }
   
   
-  protected static BooleanList newBooleanList() {
-    return new BooleanArrayList();
-  }
-  
-  protected static BooleanList newBooleanListWithCapacity(int capacity) {
-    return new BooleanArrayList(capacity);
+  protected static DoubleList mutableCopy(DoubleList list) {
+    int size = list.size();
+    return list.mutableCopyWithCapacity(
+        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
   }
   }
-  
-  protected static BooleanList newBooleanList(List<Boolean> toCopy) {
-    return new BooleanArrayList(toCopy);
-  }
-  
+
   protected static BooleanList emptyBooleanList() {
   protected static BooleanList emptyBooleanList() {
     return BooleanArrayList.emptyList();
     return BooleanArrayList.emptyList();
   }
   }
   
   
-  protected static <E> ProtobufList<E> newProtobufList() {
-    return new ProtobufArrayList<E>();
-  }
-  
-  protected static <E> ProtobufList<E> newProtobufList(List<E> toCopy) {
-    return new ProtobufArrayList<E>(toCopy);
-  }
-  
-  protected static <E> ProtobufList<E> newProtobufListWithCapacity(int capacity) {
-    return new ProtobufArrayList<E>(capacity);
+  protected static BooleanList mutableCopy(BooleanList list) {
+    int size = list.size();
+    return list.mutableCopyWithCapacity(
+        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
   }
   }
-  
+
   protected static <E> ProtobufList<E> emptyProtobufList() {
   protected static <E> ProtobufList<E> emptyProtobufList() {
     return ProtobufArrayList.emptyList();
     return ProtobufArrayList.emptyList();
   }
   }
-
-  protected static LazyStringArrayList emptyLazyStringArrayList() {
-    return LazyStringArrayList.emptyList();
-  }
   
   
+  protected static <E> ProtobufList<E> mutableCopy(ProtobufList<E> list) {
+    int size = list.size();
+    return list.mutableCopyWithCapacity(
+        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
+  }
+
   /**
   /**
    * A {@link Parser} implementation that delegates to the default instance.
    * A {@link Parser} implementation that delegates to the default instance.
    * <p>
    * <p>
@@ -1274,10 +1322,11 @@ public abstract class GeneratedMessageLite<
   static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
   static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
       T instance, CodedInputStream input, ExtensionRegistryLite extensionRegistry)
       T instance, CodedInputStream input, ExtensionRegistryLite extensionRegistry)
           throws InvalidProtocolBufferException {
           throws InvalidProtocolBufferException {
-    T result;
+    @SuppressWarnings("unchecked") // Guaranteed by protoc
+    T result = (T) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
     try {
     try {
-      result = (T) instance.dynamicMethod(
-          MethodToInvoke.PARSE_PARTIAL_FROM, input, extensionRegistry);
+      result.dynamicMethod(MethodToInvoke.MERGE_FROM_STREAM, input, extensionRegistry);
+      result.makeImmutable();
     } catch (RuntimeException e) {
     } catch (RuntimeException e) {
       if (e.getCause() instanceof InvalidProtocolBufferException) {
       if (e.getCause() instanceof InvalidProtocolBufferException) {
         throw (InvalidProtocolBufferException) e.getCause();
         throw (InvalidProtocolBufferException) e.getCause();
@@ -1454,4 +1503,740 @@ public abstract class GeneratedMessageLite<
     }
     }
     return message;
     return message;
   }
   }
+
+  /**
+   * An abstract visitor that the generated code calls into that we use to implement various
+   * features. Fields that are not members of oneofs are always visited. Members of a oneof are only
+   * visited when they are the set oneof case value on the "other" proto. The visitOneofNotSet
+   * method is invoked if other's oneof case is not set.
+   */
+  protected interface Visitor {
+    boolean visitBoolean(boolean minePresent, boolean mine, boolean otherPresent, boolean other);
+    int visitInt(boolean minePresent, int mine, boolean otherPresent, int other);
+    double visitDouble(boolean minePresent, double mine, boolean otherPresent, double other);
+    float visitFloat(boolean minePresent, float mine, boolean otherPresent, float other);
+    long visitLong(boolean minePresent, long mine, boolean otherPresent, long other);
+    String visitString(boolean minePresent, String mine, boolean otherPresent, String other);
+    ByteString visitByteString(
+        boolean minePresent, ByteString mine, boolean otherPresent, ByteString other);
+
+    Object visitOneofBoolean(boolean minePresent, Object mine, Object other);
+    Object visitOneofInt(boolean minePresent, Object mine, Object other);
+    Object visitOneofDouble(boolean minePresent, Object mine, Object other);
+    Object visitOneofFloat(boolean minePresent, Object mine, Object other);
+    Object visitOneofLong(boolean minePresent, Object mine, Object other);
+    Object visitOneofString(boolean minePresent, Object mine, Object other);
+    Object visitOneofByteString(boolean minePresent, Object mine, Object other);
+    Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other);
+    Object visitOneofMessage(boolean minePresent, Object mine, Object other);
+    void visitOneofNotSet(boolean minePresent);
+    
+    /**
+     * Message fields use null sentinals.
+     */
+    <T extends MessageLite> T visitMessage(T mine, T other);
+    LazyFieldLite visitLazyMessage(
+        boolean minePresent, LazyFieldLite mine, boolean otherPresent, LazyFieldLite other);
+
+    <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other);
+    BooleanList visitBooleanList(BooleanList mine, BooleanList other);
+    IntList visitIntList(IntList mine, IntList other);
+    DoubleList visitDoubleList(DoubleList mine, DoubleList other);
+    FloatList visitFloatList(FloatList mine, FloatList other);
+    LongList visitLongList(LongList mine, LongList other);
+    FieldSet<ExtensionDescriptor> visitExtensions(
+        FieldSet<ExtensionDescriptor> mine, FieldSet<ExtensionDescriptor> other);
+    UnknownFieldSetLite visitUnknownFields(UnknownFieldSetLite mine, UnknownFieldSetLite other);
+    <K, V> MapFieldLite<K, V> visitMap(MapFieldLite<K, V> mine, MapFieldLite<K, V> other);
+  }
+
+  /**
+   * Implements equals. Throws a {@link NotEqualsException} when not equal.
+   */
+  static class EqualsVisitor implements Visitor {
+
+    static final class NotEqualsException extends RuntimeException {}
+
+    static final EqualsVisitor INSTANCE = new EqualsVisitor();
+
+    static final NotEqualsException NOT_EQUALS = new NotEqualsException();
+
+    private EqualsVisitor() {}
+
+    @Override
+    public boolean visitBoolean(
+        boolean minePresent, boolean mine, boolean otherPresent, boolean other) {
+      if (minePresent != otherPresent || mine != other) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public int visitInt(boolean minePresent, int mine, boolean otherPresent, int other) {
+      if (minePresent != otherPresent || mine != other) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public double visitDouble(
+        boolean minePresent, double mine, boolean otherPresent, double other) {
+      if (minePresent != otherPresent || mine != other) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public float visitFloat(boolean minePresent, float mine, boolean otherPresent, float other) {
+      if (minePresent != otherPresent || mine != other) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public long visitLong(boolean minePresent, long mine, boolean otherPresent, long other) {
+      if (minePresent != otherPresent || mine != other) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public String visitString(
+        boolean minePresent, String mine, boolean otherPresent, String other) {
+      if (minePresent != otherPresent || !mine.equals(other)) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public ByteString visitByteString(
+        boolean minePresent, ByteString mine, boolean otherPresent, ByteString other) {
+      if (minePresent != otherPresent || !mine.equals(other)) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public Object visitOneofBoolean(boolean minePresent, Object mine, Object other) {
+      if (minePresent && mine.equals(other)) {
+        return mine;
+      }
+      throw NOT_EQUALS;
+    }
+
+    @Override
+    public Object visitOneofInt(boolean minePresent, Object mine, Object other) {
+      if (minePresent && mine.equals(other)) {
+        return mine;
+      }
+      throw NOT_EQUALS;
+    }
+
+    @Override
+    public Object visitOneofDouble(boolean minePresent, Object mine, Object other) {
+      if (minePresent && mine.equals(other)) {
+        return mine;
+      }
+      throw NOT_EQUALS;
+    }
+
+    @Override
+    public Object visitOneofFloat(boolean minePresent, Object mine, Object other) {
+      if (minePresent && mine.equals(other)) {
+        return mine;
+      }
+      throw NOT_EQUALS;
+    }
+
+    @Override
+    public Object visitOneofLong(boolean minePresent, Object mine, Object other) {
+      if (minePresent && mine.equals(other)) {
+        return mine;
+      }
+      throw NOT_EQUALS;
+    }
+
+    @Override
+    public Object visitOneofString(boolean minePresent, Object mine, Object other) {
+      if (minePresent && mine.equals(other)) {
+        return mine;
+      }
+      throw NOT_EQUALS;
+    }
+
+    @Override
+    public Object visitOneofByteString(boolean minePresent, Object mine, Object other) {
+      if (minePresent && mine.equals(other)) {
+        return mine;
+      }
+      throw NOT_EQUALS;
+    }
+
+    @Override
+    public Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other) {
+      if (minePresent && mine.equals(other)) {
+        return mine;
+      }
+      throw NOT_EQUALS;
+    }
+    
+    @Override
+    public Object visitOneofMessage(boolean minePresent, Object mine, Object other) {
+      if (minePresent && ((GeneratedMessageLite<?, ?>) mine).equals(this, (MessageLite) other)) {
+        return mine;
+      }
+      throw NOT_EQUALS;
+    }
+    
+    @Override
+    public void visitOneofNotSet(boolean minePresent) {
+      if (minePresent) {
+        throw NOT_EQUALS;
+      }
+    }
+
+    @Override
+    public <T extends MessageLite> T visitMessage(T mine, T other) {
+      if (mine == null && other == null) {
+        return null;
+      }
+
+      if (mine == null || other == null) {
+        throw NOT_EQUALS;
+      }
+
+      ((GeneratedMessageLite<?, ?>) mine).equals(this, other);
+
+      return mine;
+    }
+    
+    @Override
+    public LazyFieldLite visitLazyMessage(
+        boolean minePresent, LazyFieldLite mine, boolean otherPresent, LazyFieldLite other) {
+      if (!minePresent && !otherPresent) {
+        return mine;
+      } else if (minePresent && otherPresent && mine.equals(other)) {
+        return mine;
+      }
+      throw NOT_EQUALS;
+    }
+
+    @Override
+    public <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other) {
+      if (!mine.equals(other)) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public BooleanList visitBooleanList(BooleanList mine, BooleanList other) {
+      if (!mine.equals(other)) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public IntList visitIntList(IntList mine, IntList other) {
+      if (!mine.equals(other)) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public DoubleList visitDoubleList(DoubleList mine, DoubleList other) {
+      if (!mine.equals(other)) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public FloatList visitFloatList(FloatList mine, FloatList other) {
+      if (!mine.equals(other)) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public LongList visitLongList(LongList mine, LongList other) {
+      if (!mine.equals(other)) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public FieldSet<ExtensionDescriptor> visitExtensions(
+        FieldSet<ExtensionDescriptor> mine,
+        FieldSet<ExtensionDescriptor> other) {
+      if (!mine.equals(other)) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public UnknownFieldSetLite visitUnknownFields(
+        UnknownFieldSetLite mine,
+        UnknownFieldSetLite other) {
+      if (!mine.equals(other)) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+
+    @Override
+    public <K, V> MapFieldLite<K, V> visitMap(MapFieldLite<K, V> mine, MapFieldLite<K, V> other) {
+      if (!mine.equals(other)) {
+        throw NOT_EQUALS;
+      }
+      return mine;
+    }
+  }
+
+  /**
+   * Implements hashCode by accumulating state.
+   */
+  private static class HashCodeVisitor implements Visitor {
+
+    // The caller must ensure that the visitor is invoked parameterized with this and this such that
+    // other is this. This is required due to how oneof cases are handled. See the class comment
+    // on Visitor for more information.
+    
+    private int hashCode = 0;
+
+    @Override
+    public boolean visitBoolean(
+        boolean minePresent, boolean mine, boolean otherPresent, boolean other) {
+      hashCode = (53 * hashCode) + Internal.hashBoolean(mine);
+      return mine;
+    }
+
+    @Override
+    public int visitInt(boolean minePresent, int mine, boolean otherPresent, int other) {
+      hashCode = (53 * hashCode) + mine;
+      return mine;
+    }
+
+    @Override
+    public double visitDouble(
+        boolean minePresent, double mine, boolean otherPresent, double other) {
+      hashCode = (53 * hashCode) + Internal.hashLong(Double.doubleToLongBits(mine));
+      return mine;
+    }
+
+    @Override
+    public float visitFloat(boolean minePresent, float mine, boolean otherPresent, float other) {
+      hashCode = (53 * hashCode) + Float.floatToIntBits(mine);
+      return mine;
+    }
+
+    @Override
+    public long visitLong(boolean minePresent, long mine, boolean otherPresent, long other) {
+      hashCode = (53 * hashCode) + Internal.hashLong(mine);
+      return mine;
+    }
+
+    @Override
+    public String visitString(
+        boolean minePresent, String mine, boolean otherPresent, String other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+
+    @Override
+    public ByteString visitByteString(
+        boolean minePresent, ByteString mine, boolean otherPresent, ByteString other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+
+    @Override
+    public Object visitOneofBoolean(boolean minePresent, Object mine, Object other) {
+      hashCode = (53 * hashCode) + Internal.hashBoolean(((Boolean) mine));
+      return mine;
+    }
+
+    @Override
+    public Object visitOneofInt(boolean minePresent, Object mine, Object other) {
+      hashCode = (53 * hashCode) + (Integer) mine;
+      return mine;
+    }
+
+    @Override
+    public Object visitOneofDouble(boolean minePresent, Object mine, Object other) {
+      hashCode = (53 * hashCode) + Internal.hashLong(Double.doubleToLongBits((Double) mine));
+      return mine;
+    }
+
+    @Override
+    public Object visitOneofFloat(boolean minePresent, Object mine, Object other) {
+      hashCode = (53 * hashCode) + Float.floatToIntBits((Float) mine);
+      return mine;
+    }
+
+    @Override
+    public Object visitOneofLong(boolean minePresent, Object mine, Object other) {
+      hashCode = (53 * hashCode) + Internal.hashLong((Long) mine);
+      return mine;
+    }
+
+    @Override
+    public Object visitOneofString(boolean minePresent, Object mine, Object other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+
+    @Override
+    public Object visitOneofByteString(boolean minePresent, Object mine, Object other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+
+    @Override
+    public Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+    
+    @Override
+    public Object visitOneofMessage(boolean minePresent, Object mine, Object other) {
+      return visitMessage((MessageLite) mine, (MessageLite) other);
+    }
+
+    @Override
+    public void visitOneofNotSet(boolean minePresent) {
+      if (minePresent) {
+        throw new IllegalStateException(); // Can't happen if other == this. 
+      }
+    }
+
+    @Override
+    public <T extends MessageLite> T visitMessage(T mine, T other) {
+      final int protoHash;
+      if (mine != null) {
+        if (mine instanceof GeneratedMessageLite) {
+          protoHash = ((GeneratedMessageLite) mine).hashCode(this);
+        } else {
+          protoHash = mine.hashCode();
+        }
+      } else {
+        protoHash = 37;
+      }
+      hashCode = (53 * hashCode) + protoHash;
+      return mine;
+    }
+
+    @Override
+    public LazyFieldLite visitLazyMessage(
+        boolean minePresent, LazyFieldLite mine, boolean otherPresent, LazyFieldLite other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+
+    @Override
+    public <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+
+    @Override
+    public BooleanList visitBooleanList(BooleanList mine, BooleanList other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+
+    @Override
+    public IntList visitIntList(IntList mine, IntList other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+
+    @Override
+    public DoubleList visitDoubleList(DoubleList mine, DoubleList other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+
+    @Override
+    public FloatList visitFloatList(FloatList mine, FloatList other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+
+    @Override
+    public LongList visitLongList(LongList mine, LongList other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+
+    @Override
+    public FieldSet<ExtensionDescriptor> visitExtensions(
+        FieldSet<ExtensionDescriptor> mine,
+        FieldSet<ExtensionDescriptor> other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+
+    @Override
+    public UnknownFieldSetLite visitUnknownFields(
+        UnknownFieldSetLite mine,
+        UnknownFieldSetLite other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+    
+    @Override
+    public <K, V> MapFieldLite<K, V> visitMap(MapFieldLite<K, V> mine, MapFieldLite<K, V> other) {
+      hashCode = (53 * hashCode) + mine.hashCode();
+      return mine;
+    }
+  }
+
+  /**
+   * Implements field merging semantics over the visitor interface.
+   */
+  protected static class MergeFromVisitor implements Visitor {
+
+    public static final MergeFromVisitor INSTANCE = new MergeFromVisitor();
+
+    private MergeFromVisitor() {}
+
+    @Override
+    public boolean visitBoolean(
+        boolean minePresent, boolean mine, boolean otherPresent, boolean other) {
+      return otherPresent ? other : mine;
+    }
+
+    @Override
+    public int visitInt(boolean minePresent, int mine, boolean otherPresent, int other) {
+      return otherPresent ? other : mine;
+    }
+
+    @Override
+    public double visitDouble(
+        boolean minePresent, double mine, boolean otherPresent, double other) {
+      return otherPresent ? other : mine;
+    }
+
+    @Override
+    public float visitFloat(boolean minePresent, float mine, boolean otherPresent, float other) {
+      return otherPresent ? other : mine;
+    }
+
+    @Override
+    public long visitLong(boolean minePresent, long mine, boolean otherPresent, long other) {
+      return otherPresent ? other : mine;
+    }
+
+    @Override
+    public String visitString(
+        boolean minePresent, String mine, boolean otherPresent, String other) {
+      return otherPresent ? other : mine;
+    }
+
+    @Override
+    public ByteString visitByteString(
+        boolean minePresent, ByteString mine, boolean otherPresent, ByteString other) {
+      return otherPresent ? other : mine;
+    }
+
+    @Override
+    public Object visitOneofBoolean(boolean minePresent, Object mine, Object other) {
+      return other;
+    }
+
+    @Override
+    public Object visitOneofInt(boolean minePresent, Object mine, Object other) {
+      return other;
+    }
+
+    @Override
+    public Object visitOneofDouble(boolean minePresent, Object mine, Object other) {
+      return other;      
+    }
+
+    @Override
+    public Object visitOneofFloat(boolean minePresent, Object mine, Object other) {
+      return other;
+    }
+
+    @Override
+    public Object visitOneofLong(boolean minePresent, Object mine, Object other) {
+      return other;      
+    }
+
+    @Override
+    public Object visitOneofString(boolean minePresent, Object mine, Object other) {
+      return other;      
+    }
+
+    @Override
+    public Object visitOneofByteString(boolean minePresent, Object mine, Object other) {
+      return other;      
+    }
+
+    @Override
+    public Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other) {
+      if (minePresent) {
+        LazyFieldLite lazy = (LazyFieldLite) mine;
+        lazy.merge((LazyFieldLite) other);
+        return lazy;
+      }
+      return other;
+    }
+    
+    @Override
+    public Object visitOneofMessage(boolean minePresent, Object mine, Object other) {
+      if (minePresent) {
+        return visitMessage((MessageLite) mine, (MessageLite) other);
+      }
+      return other;
+    }
+    
+    @Override
+    public void visitOneofNotSet(boolean minePresent) {
+      return;
+    }
+
+    @SuppressWarnings("unchecked") // Guaranteed by runtime.
+    @Override
+    public <T extends MessageLite> T visitMessage(T mine, T other) {
+      if (mine != null && other != null) {
+        return (T) mine.toBuilder().mergeFrom(other).build();
+      }
+
+      return mine != null ? mine : other;
+    }
+
+    @Override
+    public LazyFieldLite visitLazyMessage(
+        boolean minePresent, LazyFieldLite mine, boolean otherPresent, LazyFieldLite other) {
+      // LazyFieldLite's are never null so we can just copy across. Necessary to avoid leakage
+      // from builder into immutable message.
+      // TODO(dweis): Change to null sentinels?
+      mine.merge(other);
+      return mine;
+    }
+
+    @Override
+    public <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other) {
+      int size = mine.size();
+      int otherSize = other.size();
+      if (size > 0 && otherSize > 0) {
+        if (!mine.isModifiable()) {
+          mine = mine.mutableCopyWithCapacity(size + otherSize);
+        }
+        mine.addAll(other);
+      }
+      
+      return size > 0 ? mine : other;
+    }
+
+    @Override
+    public BooleanList visitBooleanList(BooleanList mine, BooleanList other) {
+      int size = mine.size();
+      int otherSize = other.size();
+      if (size > 0 && otherSize > 0) {
+        if (!mine.isModifiable()) {
+          mine = mine.mutableCopyWithCapacity(size + otherSize);
+        }
+        mine.addAll(other);
+      }
+      
+      return size > 0 ? mine : other;
+    }
+
+    @Override
+    public IntList visitIntList(IntList mine, IntList other) {
+      int size = mine.size();
+      int otherSize = other.size();
+      if (size > 0 && otherSize > 0) {
+        if (!mine.isModifiable()) {
+          mine = mine.mutableCopyWithCapacity(size + otherSize);
+        }
+        mine.addAll(other);
+      }
+      
+      return size > 0 ? mine : other;
+    }
+
+    @Override
+    public DoubleList visitDoubleList(DoubleList mine, DoubleList other) {
+      int size = mine.size();
+      int otherSize = other.size();
+      if (size > 0 && otherSize > 0) {
+        if (!mine.isModifiable()) {
+          mine = mine.mutableCopyWithCapacity(size + otherSize);
+        }
+        mine.addAll(other);
+      }
+      
+      return size > 0 ? mine : other;
+    }
+
+    @Override
+    public FloatList visitFloatList(FloatList mine, FloatList other) {
+      int size = mine.size();
+      int otherSize = other.size();
+      if (size > 0 && otherSize > 0) {
+        if (!mine.isModifiable()) {
+          mine = mine.mutableCopyWithCapacity(size + otherSize);
+        }
+        mine.addAll(other);
+      }
+      
+      return size > 0 ? mine : other;
+    }
+
+    @Override
+    public LongList visitLongList(LongList mine, LongList other) {
+      int size = mine.size();
+      int otherSize = other.size();
+      if (size > 0 && otherSize > 0) {
+        if (!mine.isModifiable()) {
+          mine = mine.mutableCopyWithCapacity(size + otherSize);
+        }
+        mine.addAll(other);
+      }
+      
+      return size > 0 ? mine : other;
+    }
+
+    @Override
+    public FieldSet<ExtensionDescriptor> visitExtensions(
+        FieldSet<ExtensionDescriptor> mine,
+        FieldSet<ExtensionDescriptor> other) {
+      if (mine.isImmutable()) {
+        mine = mine.clone();
+      }
+      mine.mergeFrom(other);
+      return mine;
+    }
+
+    @Override
+    public UnknownFieldSetLite visitUnknownFields(
+        UnknownFieldSetLite mine,
+        UnknownFieldSetLite other) {
+      return other == UnknownFieldSetLite.getDefaultInstance()
+          ? mine : UnknownFieldSetLite.mutableCopyOf(mine, other);
+    }
+    
+    @Override
+    public <K, V> MapFieldLite<K, V> visitMap(MapFieldLite<K, V> mine, MapFieldLite<K, V> other) {
+      mine.mergeFrom(other);
+      return mine;
+    }
+  }
 }
 }

+ 42 - 22
java/core/src/main/java/com/google/protobuf/IntArrayList.java

@@ -34,7 +34,6 @@ import com.google.protobuf.Internal.IntList;
 
 
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
-import java.util.List;
 import java.util.RandomAccess;
 import java.util.RandomAccess;
 
 
 /**
 /**
@@ -44,8 +43,6 @@ import java.util.RandomAccess;
  */
  */
 final class IntArrayList extends AbstractProtobufList<Integer> implements IntList, RandomAccess {
 final class IntArrayList extends AbstractProtobufList<Integer> implements IntList, RandomAccess {
   
   
-  private static final int DEFAULT_CAPACITY = 10;
-  
   private static final IntArrayList EMPTY_LIST = new IntArrayList();
   private static final IntArrayList EMPTY_LIST = new IntArrayList();
   static {
   static {
     EMPTY_LIST.makeImmutable();
     EMPTY_LIST.makeImmutable();
@@ -70,32 +67,55 @@ final class IntArrayList extends AbstractProtobufList<Integer> implements IntLis
    * Constructs a new mutable {@code IntArrayList} with default capacity.
    * Constructs a new mutable {@code IntArrayList} with default capacity.
    */
    */
   IntArrayList() {
   IntArrayList() {
-    this(DEFAULT_CAPACITY);
-  }
-
-  /**
-   * Constructs a new mutable {@code IntArrayList} with the provided capacity.
-   */
-  IntArrayList(int capacity) {
-    array = new int[capacity];
-    size = 0;
+    this(new int[DEFAULT_CAPACITY], 0);
   }
   }
 
 
   /**
   /**
    * Constructs a new mutable {@code IntArrayList} containing the same elements as {@code other}.
    * Constructs a new mutable {@code IntArrayList} containing the same elements as {@code other}.
    */
    */
-  IntArrayList(List<Integer> other) {
-    if (other instanceof IntArrayList) {
-      IntArrayList list = (IntArrayList) other;
-      array = list.array.clone();
-      size = list.size;
-    } else {
-      size = other.size();
-      array = new int[size];
-      for (int i = 0; i < size; i++) {
-        array[i] = other.get(i);
+  private IntArrayList(int[] array, int size) {
+    this.array = array;
+    this.size = size;
+  }
+  
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof IntArrayList)) {
+      return super.equals(o);
+    }
+    IntArrayList other = (IntArrayList) o;
+    if (size != other.size) {
+      return false;
+    }
+    
+    final int[] arr = other.array;
+    for (int i = 0; i < size; i++) {
+      if (array[i] != arr[i]) {
+        return false;
       }
       }
     }
     }
+    
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = 1;
+    for (int i = 0; i < size; i++) {
+      result = (31 * result) + array[i];
+    }
+    return result;
+  }
+
+  @Override
+  public IntList mutableCopyWithCapacity(int capacity) {
+    if (capacity < size) {
+      throw new IllegalArgumentException();
+    }
+    return new IntArrayList(Arrays.copyOf(array, capacity), size);
   }
   }
   
   
   @Override
   @Override

+ 52 - 11
java/core/src/main/java/com/google/protobuf/Internal.java

@@ -41,6 +41,7 @@ import java.util.Arrays;
 import java.util.Iterator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
+import java.util.RandomAccess;
 import java.util.Set;
 import java.util.Set;
 
 
 /**
 /**
@@ -457,10 +458,13 @@ public final class Internal {
     public static <T extends EnumLite> Converter<Integer, T> newEnumConverter(
     public static <T extends EnumLite> Converter<Integer, T> newEnumConverter(
         final EnumLiteMap<T> enumMap, final T unrecognizedValue) {
         final EnumLiteMap<T> enumMap, final T unrecognizedValue) {
       return new Converter<Integer, T>() {
       return new Converter<Integer, T>() {
+        @Override
         public T doForward(Integer value) {
         public T doForward(Integer value) {
           T result = enumMap.findValueByNumber(value);
           T result = enumMap.findValueByNumber(value);
           return result == null ? unrecognizedValue : result;
           return result == null ? unrecognizedValue : result;
         }
         }
+
+        @Override
         public Integer doBackward(T value) {
         public Integer doBackward(T value) {
           return value.getNumber();
           return value.getNumber();
         }
         }
@@ -573,8 +577,10 @@ public final class Internal {
   /**
   /**
    * Extends {@link List} to add the capability to make the list immutable and inspect if it is
    * Extends {@link List} to add the capability to make the list immutable and inspect if it is
    * modifiable.
    * modifiable.
+   * <p>
+   * All implementations must support efficient random access.
    */
    */
-  public static interface ProtobufList<E> extends List<E> {
+  public static interface ProtobufList<E> extends List<E>, RandomAccess {
 
 
     /**
     /**
      * Makes this list immutable. All subsequent modifications will throw an
      * Makes this list immutable. All subsequent modifications will throw an
@@ -586,6 +592,11 @@ public final class Internal {
      * Returns whether this list can be modified via the publicly accessible {@link List} methods.
      * Returns whether this list can be modified via the publicly accessible {@link List} methods.
      */
      */
     boolean isModifiable();
     boolean isModifiable();
+
+    /**
+     * Returns a mutable clone of this list with the specified capacity.
+     */
+    ProtobufList<E> mutableCopyWithCapacity(int capacity);
   }
   }
 
 
   /**
   /**
@@ -600,14 +611,20 @@ public final class Internal {
     int getInt(int index);
     int getInt(int index);
 
 
     /**
     /**
-     * Like {@link #add(Object)} but more efficient in that it doesn't box the element.
+     * Like {@link #add(Integer)} but more efficient in that it doesn't box the element.
      */
      */
     void addInt(int element);
     void addInt(int element);
 
 
     /**
     /**
-     * Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
+     * Like {@link #set(int, Integer)} but more efficient in that it doesn't box the element.
      */
      */
     int setInt(int index, int element);
     int setInt(int index, int element);
+
+    /**
+     * Returns a mutable clone of this list with the specified capacity.
+     */
+    @Override
+    IntList mutableCopyWithCapacity(int capacity);
   }
   }
 
 
   /**
   /**
@@ -622,14 +639,20 @@ public final class Internal {
     boolean getBoolean(int index);
     boolean getBoolean(int index);
 
 
     /**
     /**
-     * Like {@link #add(Object)} but more efficient in that it doesn't box the element.
+     * Like {@link #add(Boolean)} but more efficient in that it doesn't box the element.
      */
      */
     void addBoolean(boolean element);
     void addBoolean(boolean element);
 
 
     /**
     /**
-     * Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
+     * Like {@link #set(int, Boolean)} but more efficient in that it doesn't box the element.
      */
      */
     boolean setBoolean(int index, boolean element);
     boolean setBoolean(int index, boolean element);
+
+    /**
+     * Returns a mutable clone of this list with the specified capacity.
+     */
+    @Override
+    BooleanList mutableCopyWithCapacity(int capacity);
   }
   }
 
 
   /**
   /**
@@ -644,14 +667,20 @@ public final class Internal {
     long getLong(int index);
     long getLong(int index);
 
 
     /**
     /**
-     * Like {@link #add(Object)} but more efficient in that it doesn't box the element.
+     * Like {@link #add(Long)} but more efficient in that it doesn't box the element.
      */
      */
     void addLong(long element);
     void addLong(long element);
 
 
     /**
     /**
-     * Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
+     * Like {@link #set(int, Long)} but more efficient in that it doesn't box the element.
      */
      */
     long setLong(int index, long element);
     long setLong(int index, long element);
+
+    /**
+     * Returns a mutable clone of this list with the specified capacity.
+     */
+    @Override
+    LongList mutableCopyWithCapacity(int capacity);
   }
   }
 
 
   /**
   /**
@@ -666,14 +695,20 @@ public final class Internal {
     double getDouble(int index);
     double getDouble(int index);
 
 
     /**
     /**
-     * Like {@link #add(Object)} but more efficient in that it doesn't box the element.
+     * Like {@link #add(Double)} but more efficient in that it doesn't box the element.
      */
      */
     void addDouble(double element);
     void addDouble(double element);
 
 
     /**
     /**
-     * Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
+     * Like {@link #set(int, Double)} but more efficient in that it doesn't box the element.
      */
      */
     double setDouble(int index, double element);
     double setDouble(int index, double element);
+
+    /**
+     * Returns a mutable clone of this list with the specified capacity.
+     */
+    @Override
+    DoubleList mutableCopyWithCapacity(int capacity);
   }
   }
 
 
   /**
   /**
@@ -688,13 +723,19 @@ public final class Internal {
     float getFloat(int index);
     float getFloat(int index);
 
 
     /**
     /**
-     * Like {@link #add(Object)} but more efficient in that it doesn't box the element.
+     * Like {@link #add(Float)} but more efficient in that it doesn't box the element.
      */
      */
     void addFloat(float element);
     void addFloat(float element);
 
 
     /**
     /**
-     * Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
+     * Like {@link #set(int, Float)} but more efficient in that it doesn't box the element.
      */
      */
     float setFloat(int index, float element);
     float setFloat(int index, float element);
+
+    /**
+     * Returns a mutable clone of this list with the specified capacity.
+     */
+    @Override
+    FloatList mutableCopyWithCapacity(int capacity);
   }
   }
 }
 }

+ 6 - 6
java/core/src/main/java/com/google/protobuf/LazyField.java

@@ -95,12 +95,12 @@ public class LazyField extends LazyFieldLite {
       this.entry = entry;
       this.entry = entry;
     }
     }
 
 
-    // @Override
+    @Override
     public K getKey() {
     public K getKey() {
       return entry.getKey();
       return entry.getKey();
     }
     }
 
 
-    // @Override
+    @Override
     public Object getValue() {
     public Object getValue() {
       LazyField field = entry.getValue();
       LazyField field = entry.getValue();
       if (field == null) {
       if (field == null) {
@@ -113,7 +113,7 @@ public class LazyField extends LazyFieldLite {
       return entry.getValue();
       return entry.getValue();
     }
     }
 
 
-    // @Override
+    @Override
     public Object setValue(Object value) {
     public Object setValue(Object value) {
       if (!(value instanceof MessageLite)) {
       if (!(value instanceof MessageLite)) {
         throw new IllegalArgumentException(
         throw new IllegalArgumentException(
@@ -131,13 +131,13 @@ public class LazyField extends LazyFieldLite {
       this.iterator = iterator;
       this.iterator = iterator;
     }
     }
 
 
-    // @Override
+    @Override
     public boolean hasNext() {
     public boolean hasNext() {
       return iterator.hasNext();
       return iterator.hasNext();
     }
     }
 
 
+    @Override
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
-    // @Override
     public Entry<K, Object> next() {
     public Entry<K, Object> next() {
       Entry<K, ?> entry = iterator.next();
       Entry<K, ?> entry = iterator.next();
       if (entry.getValue() instanceof LazyField) {
       if (entry.getValue() instanceof LazyField) {
@@ -146,7 +146,7 @@ public class LazyField extends LazyFieldLite {
       return (Entry<K, Object>) entry;
       return (Entry<K, Object>) entry;
     }
     }
 
 
-    // @Override
+    @Override
     public void remove() {
     public void remove() {
       iterator.remove();
       iterator.remove();
     }
     }

+ 41 - 0
java/core/src/main/java/com/google/protobuf/LazyFieldLite.java

@@ -135,6 +135,43 @@ public class LazyFieldLite {
     return lf;
     return lf;
   }
   }
 
 
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    
+    if (!(o instanceof LazyFieldLite)) {
+      return false;
+    }
+
+    LazyFieldLite other = (LazyFieldLite) o;
+    
+    // Lazy fields do not work well with equals... If both are delayedBytes, we do not have a
+    // mechanism to deserialize them so we rely on bytes equality. Otherwise we coerce into an
+    // actual message (if necessary) and call equals on the message itself. This implies that two
+    // messages can by unequal but then be turned equal simply be invoking a getter on a lazy field.
+    MessageLite value1 = value;
+    MessageLite value2 = other.value;
+    if (value1 == null && value2 == null) {
+      return toByteString().equals(other.toByteString());
+    } else if (value1 != null && value2 != null) {
+      return value1.equals(value2);
+    } else if (value1 != null) {
+      return value1.equals(other.getValue(value1.getDefaultInstanceForType()));
+    } else {
+      return getValue(value2.getDefaultInstanceForType()).equals(value2);
+    }
+  }
+  
+  @Override
+  public int hashCode() {
+    // We can't provide a memoizable hash code for lazy fields. The byte strings may have different
+    // hash codes but evaluate to equivalent messages. And we have no facility for constructing
+    // a message here if we were not already holding a value.
+    return 1;
+  }
+  
   /**
   /**
    * Determines whether this LazyFieldLite instance represents the default instance of this type.
    * Determines whether this LazyFieldLite instance represents the default instance of this type.
    */
    */
@@ -340,6 +377,8 @@ public class LazyFieldLite {
    * parsed. Be careful when using this method.
    * parsed. Be careful when using this method.
    */
    */
   public int getSerializedSize() {
   public int getSerializedSize() {
+    // We *must* return delayed bytes size if it was ever set because the dependent messages may
+    // have memoized serialized size based off of it.
     if (memoizedBytes != null) {
     if (memoizedBytes != null) {
       return memoizedBytes.size();
       return memoizedBytes.size();
     } else if (delayedBytes != null) {
     } else if (delayedBytes != null) {
@@ -358,6 +397,8 @@ public class LazyFieldLite {
     if (memoizedBytes != null) {
     if (memoizedBytes != null) {
       return memoizedBytes;
       return memoizedBytes;
     }
     }
+    // We *must* return delayed bytes if it was set because the dependent messages may have
+    // memoized serialized size based off of it.
     if (delayedBytes != null) {
     if (delayedBytes != null) {
       return delayedBytes;
       return delayedBytes;
     }
     }

+ 31 - 17
java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java

@@ -64,7 +64,7 @@ import java.util.RandomAccess;
  */
  */
 public class LazyStringArrayList extends AbstractProtobufList<String>
 public class LazyStringArrayList extends AbstractProtobufList<String>
     implements LazyStringList, RandomAccess {
     implements LazyStringList, RandomAccess {
-  
+
   private static final LazyStringArrayList EMPTY_LIST = new LazyStringArrayList();
   private static final LazyStringArrayList EMPTY_LIST = new LazyStringArrayList();
   static {
   static {
     EMPTY_LIST.makeImmutable();
     EMPTY_LIST.makeImmutable();
@@ -80,11 +80,11 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
   private final List<Object> list;
   private final List<Object> list;
 
 
   public LazyStringArrayList() {
   public LazyStringArrayList() {
-    list = new ArrayList<Object>();
+    this(DEFAULT_CAPACITY);
   }
   }
 
 
   public LazyStringArrayList(int intialCapacity) {
   public LazyStringArrayList(int intialCapacity) {
-    list = new ArrayList<Object>(intialCapacity);
+    this(new ArrayList<Object>(intialCapacity));
   }
   }
 
 
   public LazyStringArrayList(LazyStringList from) {
   public LazyStringArrayList(LazyStringList from) {
@@ -93,7 +93,21 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
   }
   }
 
 
   public LazyStringArrayList(List<String> from) {
   public LazyStringArrayList(List<String> from) {
-    list = new ArrayList<Object>(from);
+    this(new ArrayList<Object>(from));
+  }
+  
+  private LazyStringArrayList(ArrayList<Object> list) {
+    this.list = list;
+  }
+
+  @Override
+  public LazyStringArrayList mutableCopyWithCapacity(int capacity) {
+    if (capacity < size()) {
+      throw new IllegalArgumentException();
+    }
+    ArrayList<Object> newList = new ArrayList<Object>(capacity);
+    newList.addAll(list);
+    return new LazyStringArrayList(newList);
   }
   }
 
 
   @Override
   @Override
@@ -170,7 +184,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
     return ret;
     return ret;
   }
   }
 
 
-  // @Override
+  @Override
   public boolean addAllByteString(Collection<? extends ByteString> values) {
   public boolean addAllByteString(Collection<? extends ByteString> values) {
     ensureIsMutable();
     ensureIsMutable();
     boolean ret = list.addAll(values);
     boolean ret = list.addAll(values);
@@ -178,7 +192,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
     return ret;
     return ret;
   }
   }
 
 
-  // @Override
+  @Override
   public boolean addAllByteArray(Collection<byte[]> c) {
   public boolean addAllByteArray(Collection<byte[]> c) {
     ensureIsMutable();
     ensureIsMutable();
     boolean ret = list.addAll(c);
     boolean ret = list.addAll(c);
@@ -201,14 +215,14 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
     modCount++;
     modCount++;
   }
   }
 
 
-  // @Override
+  @Override
   public void add(ByteString element) {
   public void add(ByteString element) {
     ensureIsMutable();
     ensureIsMutable();
     list.add(element);
     list.add(element);
     modCount++;
     modCount++;
   }
   }
   
   
-  // @Override
+  @Override
   public void add(byte[] element) {
   public void add(byte[] element) {
     ensureIsMutable();
     ensureIsMutable();
     list.add(element);
     list.add(element);
@@ -220,7 +234,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
     return list.get(index);
     return list.get(index);
   }
   }
   
   
-  // @Override
+  @Override
   public ByteString getByteString(int index) {
   public ByteString getByteString(int index) {
     Object o = list.get(index);
     Object o = list.get(index);
     ByteString b = asByteString(o);
     ByteString b = asByteString(o);
@@ -230,7 +244,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
     return b;
     return b;
   }
   }
   
   
-  // @Override
+  @Override
   public byte[] getByteArray(int index) {
   public byte[] getByteArray(int index) {
     Object o = list.get(index);
     Object o = list.get(index);
     byte[] b = asByteArray(o);
     byte[] b = asByteArray(o);
@@ -240,7 +254,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
     return b;
     return b;
   }
   }
 
 
-  // @Override
+  @Override
   public void set(int index, ByteString s) {
   public void set(int index, ByteString s) {
     setAndReturn(index, s);
     setAndReturn(index, s);
   }
   }
@@ -250,7 +264,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
     return list.set(index, s);
     return list.set(index, s);
   }
   }
 
 
-  // @Override
+  @Override
   public void set(int index, byte[] s) {
   public void set(int index, byte[] s) {
     setAndReturn(index, s);
     setAndReturn(index, s);
   }
   }
@@ -290,12 +304,12 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
     }
     }
   }
   }
 
 
-  // @Override
+  @Override
   public List<?> getUnderlyingElements() {
   public List<?> getUnderlyingElements() {
     return Collections.unmodifiableList(list);
     return Collections.unmodifiableList(list);
   }
   }
 
 
-  // @Override
+  @Override
   public void mergeFrom(LazyStringList other) {
   public void mergeFrom(LazyStringList other) {
     ensureIsMutable();
     ensureIsMutable();
     for (Object o : other.getUnderlyingElements()) {
     for (Object o : other.getUnderlyingElements()) {
@@ -349,7 +363,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
     }
     }
   }
   }
   
   
-  // @Override
+  @Override
   public List<byte[]> asByteArrayList() {
   public List<byte[]> asByteArrayList() {
     return new ByteArrayListView(this);
     return new ByteArrayListView(this);
   }
   }
@@ -393,12 +407,12 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
     }
     }
   }
   }
 
 
-  // @Override
+  @Override
   public List<ByteString> asByteStringList() {
   public List<ByteString> asByteStringList() {
     return new ByteStringListView(this);
     return new ByteStringListView(this);
   }
   }
 
 
-  // @Override
+  @Override
   public LazyStringList getUnmodifiableView() {
   public LazyStringList getUnmodifiableView() {
     if (isModifiable()) {
     if (isModifiable()) {
       return new UnmodifiableLazyStringList(this);
       return new UnmodifiableLazyStringList(this);

+ 42 - 22
java/core/src/main/java/com/google/protobuf/LongArrayList.java

@@ -34,7 +34,6 @@ import com.google.protobuf.Internal.LongList;
 
 
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
-import java.util.List;
 import java.util.RandomAccess;
 import java.util.RandomAccess;
 
 
 /**
 /**
@@ -44,8 +43,6 @@ import java.util.RandomAccess;
  */
  */
 final class LongArrayList extends AbstractProtobufList<Long> implements LongList, RandomAccess {
 final class LongArrayList extends AbstractProtobufList<Long> implements LongList, RandomAccess {
   
   
-  private static final int DEFAULT_CAPACITY = 10;
-  
   private static final LongArrayList EMPTY_LIST = new LongArrayList();
   private static final LongArrayList EMPTY_LIST = new LongArrayList();
   static {
   static {
     EMPTY_LIST.makeImmutable();
     EMPTY_LIST.makeImmutable();
@@ -70,32 +67,55 @@ final class LongArrayList extends AbstractProtobufList<Long> implements LongList
    * Constructs a new mutable {@code LongArrayList} with default capacity.
    * Constructs a new mutable {@code LongArrayList} with default capacity.
    */
    */
   LongArrayList() {
   LongArrayList() {
-    this(DEFAULT_CAPACITY);
-  }
-
-  /**
-   * Constructs a new mutable {@code LongArrayList} with the provided capacity.
-   */
-  LongArrayList(int capacity) {
-    array = new long[capacity];
-    size = 0;
+    this(new long[DEFAULT_CAPACITY], 0);
   }
   }
 
 
   /**
   /**
    * Constructs a new mutable {@code LongArrayList} containing the same elements as {@code other}.
    * Constructs a new mutable {@code LongArrayList} containing the same elements as {@code other}.
    */
    */
-  LongArrayList(List<Long> other) {
-    if (other instanceof LongArrayList) {
-      LongArrayList list = (LongArrayList) other;
-      array = list.array.clone();
-      size = list.size;
-    } else {
-      size = other.size();
-      array = new long[size];
-      for (int i = 0; i < size; i++) {
-        array[i] = other.get(i);
+  private LongArrayList(long[] array, int size) {
+    this.array = array;
+    this.size = size;
+  }
+  
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof IntArrayList)) {
+      return super.equals(o);
+    }
+    LongArrayList other = (LongArrayList) o;
+    if (size != other.size) {
+      return false;
+    }
+    
+    final long[] arr = other.array;
+    for (int i = 0; i < size; i++) {
+      if (array[i] != arr[i]) {
+        return false;
       }
       }
     }
     }
+    
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = 1;
+    for (int i = 0; i < size; i++) {
+      result = (31 * result) + Internal.hashLong(array[i]);
+    }
+    return result;
+  }
+
+  @Override
+  public LongList mutableCopyWithCapacity(int capacity) {
+    if (capacity < size) {
+      throw new IllegalArgumentException();
+    }
+    return new LongArrayList(Arrays.copyOf(array, capacity), size);
   }
   }
   
   
   @Override
   @Override

+ 8 - 2
java/core/src/main/java/com/google/protobuf/MapEntryLite.java

@@ -41,7 +41,8 @@ import java.io.IOException;
  * 
  * 
  * Protobuf internal. Users shouldn't use.
  * Protobuf internal. Users shouldn't use.
  */
  */
-public class MapEntryLite<K, V> extends AbstractMessageLite {
+public class MapEntryLite<K, V>
+    extends AbstractMessageLite<MapEntryLite<K, V>, MapEntryLite.Builder<K, V>> {
   private static class Metadata<K, V> {
   private static class Metadata<K, V> {
     public final MapEntryLite<K, V> defaultInstance;
     public final MapEntryLite<K, V> defaultInstance;
     public final WireFormat.FieldType keyType;
     public final WireFormat.FieldType keyType;
@@ -233,7 +234,7 @@ public class MapEntryLite<K, V> extends AbstractMessageLite {
    * Builder used to create {@link MapEntryLite} messages.
    * Builder used to create {@link MapEntryLite} messages.
    */
    */
   public static class Builder<K, V>
   public static class Builder<K, V>
-      extends AbstractMessageLite.Builder<Builder<K, V>> {
+      extends AbstractMessageLite.Builder<MapEntryLite<K, V>, Builder<K, V>> {
     private final Metadata<K, V> metadata;
     private final Metadata<K, V> metadata;
     private K key;
     private K key;
     private V value;
     private V value;
@@ -327,5 +328,10 @@ public class MapEntryLite<K, V> extends AbstractMessageLite {
       this.value = entry.value;
       this.value = entry.value;
       return this;
       return this;
     }
     }
+
+    @Override
+    protected Builder<K, V> internalMergeFrom(MapEntryLite<K, V> message) {
+      throw new UnsupportedOperationException();
+    }
   }
   }
 }
 }

+ 3 - 0
java/core/src/main/java/com/google/protobuf/MapField.java

@@ -93,15 +93,18 @@ public class MapField<K, V> implements MutabilityOracle {
       this.defaultEntry = defaultEntry;
       this.defaultEntry = defaultEntry;
     }
     }
     
     
+    @Override
     public Message convertKeyAndValueToMessage(K key, V value) {
     public Message convertKeyAndValueToMessage(K key, V value) {
       return defaultEntry.newBuilderForType().setKey(key).setValue(value).buildPartial();
       return defaultEntry.newBuilderForType().setKey(key).setValue(value).buildPartial();
     }
     }
     
     
+    @Override
     public void convertMessageToKeyAndValue(Message message, Map<K, V> map) {
     public void convertMessageToKeyAndValue(Message message, Map<K, V> map) {
       MapEntry<K, V> entry = (MapEntry<K, V>) message;
       MapEntry<K, V> entry = (MapEntry<K, V>) message;
       map.put(entry.getKey(), entry.getValue());
       map.put(entry.getKey(), entry.getValue());
     }
     }
 
 
+    @Override
     public Message getMessageDefaultInstance() {
     public Message getMessageDefaultInstance() {
       return defaultEntry;
       return defaultEntry;
     }
     }

+ 48 - 22
java/core/src/main/java/com/google/protobuf/Message.java

@@ -51,6 +51,7 @@ import java.util.Map;
 public interface Message extends MessageLite, MessageOrBuilder {
 public interface Message extends MessageLite, MessageOrBuilder {
 
 
   // (From MessageLite, re-declared here only for return type covariance.)
   // (From MessageLite, re-declared here only for return type covariance.)
+  @Override
   Parser<? extends Message> getParserForType();
   Parser<? extends Message> getParserForType();
 
 
 
 
@@ -97,7 +98,10 @@ public interface Message extends MessageLite, MessageOrBuilder {
   // Builders
   // Builders
 
 
   // (From MessageLite, re-declared here only for return type covariance.)
   // (From MessageLite, re-declared here only for return type covariance.)
+  @Override
   Builder newBuilderForType();
   Builder newBuilderForType();
+
+  @Override
   Builder toBuilder();
   Builder toBuilder();
 
 
   /**
   /**
@@ -106,6 +110,7 @@ public interface Message extends MessageLite, MessageOrBuilder {
   interface Builder extends MessageLite.Builder, MessageOrBuilder {
   interface Builder extends MessageLite.Builder, MessageOrBuilder {
     // (From MessageLite.Builder, re-declared here only for return type
     // (From MessageLite.Builder, re-declared here only for return type
     // covariance.)
     // covariance.)
+    @Override
     Builder clear();
     Builder clear();
 
 
     /**
     /**
@@ -131,18 +136,27 @@ public interface Message extends MessageLite, MessageOrBuilder {
 
 
     // (From MessageLite.Builder, re-declared here only for return type
     // (From MessageLite.Builder, re-declared here only for return type
     // covariance.)
     // covariance.)
+    @Override
     Message build();
     Message build();
+
+    @Override
     Message buildPartial();
     Message buildPartial();
+
+    @Override
     Builder clone();
     Builder clone();
+
+    @Override
     Builder mergeFrom(CodedInputStream input) throws IOException;
     Builder mergeFrom(CodedInputStream input) throws IOException;
-    Builder mergeFrom(CodedInputStream input,
-                      ExtensionRegistryLite extensionRegistry)
-                      throws IOException;
+
+    @Override
+    Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
+        throws IOException;
 
 
     /**
     /**
      * Get the message's type's descriptor.
      * Get the message's type's descriptor.
      * See {@link Message#getDescriptorForType()}.
      * See {@link Message#getDescriptorForType()}.
      */
      */
+    @Override
     Descriptors.Descriptor getDescriptorForType();
     Descriptors.Descriptor getDescriptorForType();
 
 
     /**
     /**
@@ -240,27 +254,39 @@ public interface Message extends MessageLite, MessageOrBuilder {
 
 
     // (From MessageLite.Builder, re-declared here only for return type
     // (From MessageLite.Builder, re-declared here only for return type
     // covariance.)
     // covariance.)
+    @Override
     Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException;
     Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException;
-    Builder mergeFrom(ByteString data,
-                      ExtensionRegistryLite extensionRegistry)
-                      throws InvalidProtocolBufferException;
+
+    @Override
+    Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException;
+
+    @Override
     Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException;
     Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException;
-    Builder mergeFrom(byte[] data, int off, int len)
-                      throws InvalidProtocolBufferException;
-    Builder mergeFrom(byte[] data,
-                      ExtensionRegistryLite extensionRegistry)
-                      throws InvalidProtocolBufferException;
-    Builder mergeFrom(byte[] data, int off, int len,
-                      ExtensionRegistryLite extensionRegistry)
-                      throws InvalidProtocolBufferException;
+
+    @Override
+    Builder mergeFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException;
+
+    @Override
+    Builder mergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException;
+
+    @Override
+    Builder mergeFrom(byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException;
+
+    @Override
     Builder mergeFrom(InputStream input) throws IOException;
     Builder mergeFrom(InputStream input) throws IOException;
-    Builder mergeFrom(InputStream input,
-                      ExtensionRegistryLite extensionRegistry)
-                      throws IOException;
-    boolean mergeDelimitedFrom(InputStream input)
-                               throws IOException;
-    boolean mergeDelimitedFrom(InputStream input,
-                               ExtensionRegistryLite extensionRegistry)
-                               throws IOException;
+
+    @Override
+    Builder mergeFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
+        throws IOException;
+
+    @Override
+    boolean mergeDelimitedFrom(InputStream input) throws IOException;
+
+    @Override
+    boolean mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
+        throws IOException;
   }
   }
 }
 }

+ 21 - 0
java/core/src/main/java/com/google/protobuf/MessageLite.java

@@ -295,6 +295,27 @@ public interface MessageLite extends MessageLiteOrBuilder {
     Builder mergeFrom(InputStream input,
     Builder mergeFrom(InputStream input,
                       ExtensionRegistryLite extensionRegistry)
                       ExtensionRegistryLite extensionRegistry)
                       throws IOException;
                       throws IOException;
+    
+    /**
+     * Merge {@code other} into the message being built.  {@code other} must
+     * have the exact same type as {@code this} (i.e.
+     * {@code getClass().equals(getDefaultInstanceForType().getClass())}).
+     *
+     * Merging occurs as follows.  For each field:<br>
+     * * For singular primitive fields, if the field is set in {@code other},
+     *   then {@code other}'s value overwrites the value in this message.<br>
+     * * For singular message fields, if the field is set in {@code other},
+     *   it is merged into the corresponding sub-message of this message
+     *   using the same merging rules.<br>
+     * * For repeated fields, the elements in {@code other} are concatenated
+     *   with the elements in this message.
+     * * For oneof groups, if the other message has one of the fields set,
+     *   the group of this message is cleared and replaced by the field
+     *   of the other message, so that the oneof constraint is preserved.
+     *
+     * This is equivalent to the {@code Message::MergeFrom} method in C++.
+     */
+    Builder mergeFrom(MessageLite other);
 
 
     /**
     /**
      * Like {@link #mergeFrom(InputStream)}, but does not read until EOF.
      * Like {@link #mergeFrom(InputStream)}, but does not read until EOF.

+ 95 - 56
java/core/src/main/java/com/google/protobuf/MessageLiteToString.java

@@ -30,23 +30,24 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
-import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
 
 
 /**
 /**
  * Helps generate {@link String} representations of {@link MessageLite} protos.
  * Helps generate {@link String} representations of {@link MessageLite} protos.
  */
  */
+// TODO(dweis): Fix map fields.
 final class MessageLiteToString {
 final class MessageLiteToString {
-  /**
-   * Suffix for *_FIELD_NUMBER fields. This is used to reflectively detect proto fields that should
-   * be toString()ed.
-   */
-  private static final String FIELD_NUMBER_NAME_SUFFIX = "_FIELD_NUMBER";
 
 
+  private static final String LIST_SUFFIX = "List";
+  private static final String BUILDER_LIST_SUFFIX = "OrBuilderList";
+  private static final String BYTES_SUFFIX = "Bytes";
+  
   /**
   /**
    * Returns a {@link String} representation of the {@link MessageLite} object.  The first line of
    * Returns a {@link String} representation of the {@link MessageLite} object.  The first line of
    * the {@code String} representation representation includes a comment string to uniquely identify
    * the {@code String} representation representation includes a comment string to uniquely identify
@@ -73,52 +74,70 @@ final class MessageLiteToString {
     // Build a map of method name to method. We're looking for methods like getFoo(), hasFoo(), and
     // Build a map of method name to method. We're looking for methods like getFoo(), hasFoo(), and
     // getFooList() which might be useful for building an object's string representation.
     // getFooList() which might be useful for building an object's string representation.
     Map<String, Method> nameToNoArgMethod = new HashMap<String, Method>();
     Map<String, Method> nameToNoArgMethod = new HashMap<String, Method>();
+    Map<String, Method> nameToMethod = new HashMap<String, Method>();
+    Set<String> getters = new TreeSet<String>();
     for (Method method : messageLite.getClass().getDeclaredMethods()) {
     for (Method method : messageLite.getClass().getDeclaredMethods()) {
+      nameToMethod.put(method.getName(), method);
       if (method.getParameterTypes().length == 0) {
       if (method.getParameterTypes().length == 0) {
         nameToNoArgMethod.put(method.getName(), method);
         nameToNoArgMethod.put(method.getName(), method);
+
+        if (method.getName().startsWith("get")) {
+          getters.add(method.getName());
+        }
       }
       }
     }
     }
 
 
-    for (Field field : messageLite.getClass().getDeclaredFields()) {
-      String fieldName = field.getName();
-      // Skip all fields that aren't in a format like "FOO_BAR_FIELD_NUMBER"
-      if (!fieldName.endsWith(FIELD_NUMBER_NAME_SUFFIX)) {
-        continue;
+    for (String getter : getters) {
+      String suffix = getter.replaceFirst("get", "");
+      if (suffix.endsWith(LIST_SUFFIX) && !suffix.endsWith(BUILDER_LIST_SUFFIX)) {
+        String camelCase = suffix.substring(0, 1).toLowerCase()
+            + suffix.substring(1, suffix.length() - LIST_SUFFIX.length());
+        // Try to reflectively get the value and toString() the field as if it were repeated. This
+        // only works if the method names have not be proguarded out or renamed.
+        Method listMethod = nameToNoArgMethod.get("get" + suffix);
+        if (listMethod != null) {
+          printField(
+              buffer,
+              indent,
+              camelCaseToSnakeCase(camelCase),
+              GeneratedMessageLite.invokeOrDie(listMethod, messageLite));
+          continue;
+        }
       }
       }
 
 
-      // For "FOO_BAR_FIELD_NUMBER" his would be "FOO_BAR"
-      String upperUnderscore =
-          fieldName.substring(0, fieldName.length() - FIELD_NUMBER_NAME_SUFFIX.length());
-
-      // For "FOO_BAR_FIELD_NUMBER" his would be "FooBar"
-      String upperCamelCaseName = upperUnderscoreToUpperCamel(upperUnderscore);
+      Method setter = nameToMethod.get("set" + suffix);
+      if (setter == null) {
+        continue;
+      }
+      if (suffix.endsWith(BYTES_SUFFIX)
+          && nameToNoArgMethod.containsKey(
+              "get" + suffix.substring(0, suffix.length() - "Bytes".length()))) {
+        // Heuristic to skip bytes based accessors for string fields.
+        continue;
+      }
+      
+      String camelCase = suffix.substring(0, 1).toLowerCase() + suffix.substring(1);
 
 
       // Try to reflectively get the value and toString() the field as if it were optional. This
       // Try to reflectively get the value and toString() the field as if it were optional. This
       // only works if the method names have not be proguarded out or renamed.
       // only works if the method names have not be proguarded out or renamed.
-      Method getMethod = nameToNoArgMethod.get("get" + upperCamelCaseName);
-      Method hasMethod = nameToNoArgMethod.get("has" + upperCamelCaseName);
-      if (getMethod != null && hasMethod != null) {
-        if ((Boolean) GeneratedMessageLite.invokeOrDie(hasMethod, messageLite)) {
+      Method getMethod = nameToNoArgMethod.get("get" + suffix);
+      Method hasMethod = nameToNoArgMethod.get("has" + suffix);
+      // TODO(dweis): Fix proto3 semantics.
+      if (getMethod != null) {
+        Object value = GeneratedMessageLite.invokeOrDie(getMethod, messageLite);
+        final boolean hasValue = hasMethod == null
+            ? !isDefaultValue(value)
+            : (Boolean) GeneratedMessageLite.invokeOrDie(hasMethod, messageLite);
+         // TODO(dweis): This doesn't stop printing oneof case twice: value and enum style.
+        if (hasValue) {
           printField(
           printField(
               buffer,
               buffer,
               indent,
               indent,
-              upperUnderscore.toLowerCase(),
-              GeneratedMessageLite.invokeOrDie(getMethod, messageLite));
+              camelCaseToSnakeCase(camelCase),
+              value);
         }
         }
         continue;
         continue;
       }
       }
-
-      // Try to reflectively get the value and toString() the field as if it were repeated. This
-      // only works if the method names have not be proguarded out or renamed.
-      Method listMethod = nameToNoArgMethod.get("get" + upperCamelCaseName + "List");
-      if (listMethod != null) {
-        printField(
-            buffer,
-            indent,
-            upperUnderscore.toLowerCase(),
-            GeneratedMessageLite.invokeOrDie(listMethod, messageLite));
-        continue;
-      }
     }
     }
 
 
     if (messageLite instanceof GeneratedMessageLite.ExtendableMessage) {
     if (messageLite instanceof GeneratedMessageLite.ExtendableMessage) {
@@ -130,10 +149,39 @@ final class MessageLiteToString {
       }
       }
     }
     }
 
 
-    if (((GeneratedMessageLite) messageLite).unknownFields != null) {
-      ((GeneratedMessageLite) messageLite).unknownFields.printWithIndent(buffer, indent);
+    if (((GeneratedMessageLite<?, ?>) messageLite).unknownFields != null) {
+      ((GeneratedMessageLite<?, ?>) messageLite).unknownFields.printWithIndent(buffer, indent);
     }
     }
   }
   }
+  
+  private static boolean isDefaultValue(Object o) {
+    if (o instanceof Boolean) {
+      return !((Boolean) o);
+    }
+    if (o instanceof Integer) {
+      return ((Integer) o) == 0;
+    }
+    if (o instanceof Float) {
+      return ((Float) o) == 0f;
+    }
+    if (o instanceof Double) {
+      return ((Double) o) == 0d;
+    }
+    if (o instanceof String) {
+      return o.equals("");
+    }
+    if (o instanceof ByteString) {
+      return o.equals(ByteString.EMPTY);
+    }
+    if (o instanceof MessageLite) { // Can happen in oneofs.
+      return o == ((MessageLite) o).getDefaultInstanceForType();
+    }
+    if (o instanceof java.lang.Enum<?>) { // Catches oneof enums.
+      return ((java.lang.Enum<?>) o).ordinal() == 0;
+    }
+    
+    return false;
+  }
 
 
   /**
   /**
    * Formats a text proto field.
    * Formats a text proto field.
@@ -166,7 +214,7 @@ final class MessageLiteToString {
       buffer.append(": \"").append(TextFormatEscaper.escapeBytes((ByteString) object)).append('"');
       buffer.append(": \"").append(TextFormatEscaper.escapeBytes((ByteString) object)).append('"');
     } else if (object instanceof GeneratedMessageLite) {
     } else if (object instanceof GeneratedMessageLite) {
       buffer.append(" {");
       buffer.append(" {");
-      reflectivePrintWithIndent((GeneratedMessageLite) object, buffer, indent + 2);
+      reflectivePrintWithIndent((GeneratedMessageLite<?, ?>) object, buffer, indent + 2);
       buffer.append("\n");
       buffer.append("\n");
       for (int i = 0; i < indent; i++) {
       for (int i = 0; i < indent; i++) {
         buffer.append(' ');
         buffer.append(' ');
@@ -176,25 +224,16 @@ final class MessageLiteToString {
       buffer.append(": ").append(object.toString());
       buffer.append(": ").append(object.toString());
     }
     }
   }
   }
-
-  /**
-   * A Guava-less implementation of:
-   * {@code CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, upperUnderscore)}
-   */
-  private static String upperUnderscoreToUpperCamel(String upperUnderscore) {
-    String upperCamelCaseName = "";
-    boolean nextCharacterShouldBeUpper = true;
-    for (int i = 0; i < upperUnderscore.length(); i++) {
-      char ch = upperUnderscore.charAt(i);
-      if (ch == '_') {
-        nextCharacterShouldBeUpper = true;
-      } else if (nextCharacterShouldBeUpper){
-        upperCamelCaseName += Character.toUpperCase(ch);
-        nextCharacterShouldBeUpper = false;
-      } else {
-        upperCamelCaseName += Character.toLowerCase(ch);
+  
+  private static final String camelCaseToSnakeCase(String camelCase) {
+    StringBuilder builder = new StringBuilder();
+    for (int i = 0; i < camelCase.length(); i++) {
+      char ch = camelCase.charAt(i);
+      if (Character.isUpperCase(ch)) {
+        builder.append("_");
       }
       }
+      builder.append(Character.toLowerCase(ch));
     }
     }
-    return upperCamelCaseName;
+    return builder.toString();
   }
   }
 }
 }

+ 1 - 1
java/core/src/main/java/com/google/protobuf/MessageOrBuilder.java

@@ -42,7 +42,7 @@ import java.util.Map;
 public interface MessageOrBuilder extends MessageLiteOrBuilder {
 public interface MessageOrBuilder extends MessageLiteOrBuilder {
 
 
   // (From MessageLite, re-declared here only for return type covariance.)
   // (From MessageLite, re-declared here only for return type covariance.)
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   Message getDefaultInstanceForType();
   Message getDefaultInstanceForType();
 
 
   /**
   /**

+ 74 - 33
java/core/src/main/java/com/google/protobuf/MessageReflection.java

@@ -364,12 +364,14 @@ class MessageReflection {
      * Finishes the merge and returns the underlying object.
      * Finishes the merge and returns the underlying object.
      */
      */
     Object finish();
     Object finish();
+    
   }
   }
 
 
   static class BuilderAdapter implements MergeTarget {
   static class BuilderAdapter implements MergeTarget {
 
 
     private final Message.Builder builder;
     private final Message.Builder builder;
 
 
+    @Override
     public Descriptors.Descriptor getDescriptorForType() {
     public Descriptors.Descriptor getDescriptorForType() {
       return builder.getDescriptorForType();
       return builder.getDescriptorForType();
     }
     }
@@ -378,6 +380,7 @@ class MessageReflection {
       this.builder = builder;
       this.builder = builder;
     }
     }
 
 
+    @Override
     public Object getField(Descriptors.FieldDescriptor field) {
     public Object getField(Descriptors.FieldDescriptor field) {
       return builder.getField(field);
       return builder.getField(field);
     }
     }
@@ -387,25 +390,27 @@ class MessageReflection {
       return builder.hasField(field);
       return builder.hasField(field);
     }
     }
 
 
-    public MergeTarget setField(Descriptors.FieldDescriptor field,
-        Object value) {
+    @Override
+    public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
       builder.setField(field, value);
       builder.setField(field, value);
       return this;
       return this;
     }
     }
 
 
+    @Override
     public MergeTarget clearField(Descriptors.FieldDescriptor field) {
     public MergeTarget clearField(Descriptors.FieldDescriptor field) {
       builder.clearField(field);
       builder.clearField(field);
       return this;
       return this;
     }
     }
 
 
+    @Override
     public MergeTarget setRepeatedField(
     public MergeTarget setRepeatedField(
         Descriptors.FieldDescriptor field, int index, Object value) {
         Descriptors.FieldDescriptor field, int index, Object value) {
       builder.setRepeatedField(field, index, value);
       builder.setRepeatedField(field, index, value);
       return this;
       return this;
     }
     }
 
 
-    public MergeTarget addRepeatedField(
-        Descriptors.FieldDescriptor field, Object value) {
+    @Override
+    public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
       builder.addRepeatedField(field, value);
       builder.addRepeatedField(field, value);
       return this;
       return this;
     }
     }
@@ -426,25 +431,30 @@ class MessageReflection {
       return builder.getOneofFieldDescriptor(oneof);
       return builder.getOneofFieldDescriptor(oneof);
     }
     }
 
 
+    @Override
     public ContainerType getContainerType() {
     public ContainerType getContainerType() {
       return ContainerType.MESSAGE;
       return ContainerType.MESSAGE;
     }
     }
 
 
+    @Override
     public ExtensionRegistry.ExtensionInfo findExtensionByName(
     public ExtensionRegistry.ExtensionInfo findExtensionByName(
         ExtensionRegistry registry, String name) {
         ExtensionRegistry registry, String name) {
       return registry.findImmutableExtensionByName(name);
       return registry.findImmutableExtensionByName(name);
     }
     }
 
 
+    @Override
     public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
     public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
-        ExtensionRegistry registry, Descriptors.Descriptor containingType,
-        int fieldNumber) {
+        ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
       return registry.findImmutableExtensionByNumber(containingType,
       return registry.findImmutableExtensionByNumber(containingType,
           fieldNumber);
           fieldNumber);
     }
     }
 
 
-    public Object parseGroup(CodedInputStream input,
+    @Override
+    public Object parseGroup(
+        CodedInputStream input,
         ExtensionRegistryLite extensionRegistry,
         ExtensionRegistryLite extensionRegistry,
-        Descriptors.FieldDescriptor field, Message defaultInstance)
+        Descriptors.FieldDescriptor field,
+        Message defaultInstance)
         throws IOException {
         throws IOException {
       Message.Builder subBuilder;
       Message.Builder subBuilder;
       // When default instance is not null. The field is an extension field.
       // When default instance is not null. The field is an extension field.
@@ -463,9 +473,12 @@ class MessageReflection {
       return subBuilder.buildPartial();
       return subBuilder.buildPartial();
     }
     }
 
 
-    public Object parseMessage(CodedInputStream input,
+    @Override
+    public Object parseMessage(
+        CodedInputStream input,
         ExtensionRegistryLite extensionRegistry,
         ExtensionRegistryLite extensionRegistry,
-        Descriptors.FieldDescriptor field, Message defaultInstance)
+        Descriptors.FieldDescriptor field,
+        Message defaultInstance)
         throws IOException {
         throws IOException {
       Message.Builder subBuilder;
       Message.Builder subBuilder;
       // When default instance is not null. The field is an extension field.
       // When default instance is not null. The field is an extension field.
@@ -484,9 +497,12 @@ class MessageReflection {
       return subBuilder.buildPartial();
       return subBuilder.buildPartial();
     }
     }
 
 
-    public Object parseMessageFromBytes(ByteString bytes,
+    @Override
+    public Object parseMessageFromBytes(
+        ByteString bytes,
         ExtensionRegistryLite extensionRegistry,
         ExtensionRegistryLite extensionRegistry,
-        Descriptors.FieldDescriptor field, Message defaultInstance)
+        Descriptors.FieldDescriptor field,
+        Message defaultInstance)
         throws IOException {
         throws IOException {
       Message.Builder subBuilder;
       Message.Builder subBuilder;
       // When default instance is not null. The field is an extension field.
       // When default instance is not null. The field is an extension field.
@@ -505,8 +521,9 @@ class MessageReflection {
       return subBuilder.buildPartial();
       return subBuilder.buildPartial();
     }
     }
 
 
-    public MergeTarget newMergeTargetForField(Descriptors.FieldDescriptor field,
-        Message defaultInstance) {
+    @Override
+    public MergeTarget newMergeTargetForField(
+        Descriptors.FieldDescriptor field, Message defaultInstance) {
       if (defaultInstance != null) {
       if (defaultInstance != null) {
         return new BuilderAdapter(
         return new BuilderAdapter(
             defaultInstance.newBuilderForType());
             defaultInstance.newBuilderForType());
@@ -515,8 +532,8 @@ class MessageReflection {
       }
       }
     }
     }
 
 
-    public WireFormat.Utf8Validation
-        getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
+    @Override
+    public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
       if (descriptor.needsUtf8Check()) {
       if (descriptor.needsUtf8Check()) {
         return WireFormat.Utf8Validation.STRICT;
         return WireFormat.Utf8Validation.STRICT;
       }
       }
@@ -528,9 +545,11 @@ class MessageReflection {
       return WireFormat.Utf8Validation.LOOSE;
       return WireFormat.Utf8Validation.LOOSE;
     }
     }
 
 
+    @Override
     public Object finish() {
     public Object finish() {
       return builder.buildPartial();
       return builder.buildPartial();
     }
     }
+    
   }
   }
 
 
 
 
@@ -542,38 +561,43 @@ class MessageReflection {
       this.extensions = extensions;
       this.extensions = extensions;
     }
     }
 
 
+    @Override
     public Descriptors.Descriptor getDescriptorForType() {
     public Descriptors.Descriptor getDescriptorForType() {
       throw new UnsupportedOperationException(
       throw new UnsupportedOperationException(
           "getDescriptorForType() called on FieldSet object");
           "getDescriptorForType() called on FieldSet object");
     }
     }
 
 
+    @Override
     public Object getField(Descriptors.FieldDescriptor field) {
     public Object getField(Descriptors.FieldDescriptor field) {
       return extensions.getField(field);
       return extensions.getField(field);
     }
     }
 
 
+    @Override
     public boolean hasField(Descriptors.FieldDescriptor field) {
     public boolean hasField(Descriptors.FieldDescriptor field) {
       return extensions.hasField(field);
       return extensions.hasField(field);
     }
     }
 
 
-    public MergeTarget setField(Descriptors.FieldDescriptor field,
-        Object value) {
+    @Override
+    public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
       extensions.setField(field, value);
       extensions.setField(field, value);
       return this;
       return this;
     }
     }
 
 
+    @Override
     public MergeTarget clearField(Descriptors.FieldDescriptor field) {
     public MergeTarget clearField(Descriptors.FieldDescriptor field) {
       extensions.clearField(field);
       extensions.clearField(field);
       return this;
       return this;
     }
     }
 
 
+    @Override
     public MergeTarget setRepeatedField(
     public MergeTarget setRepeatedField(
         Descriptors.FieldDescriptor field, int index, Object value) {
         Descriptors.FieldDescriptor field, int index, Object value) {
       extensions.setRepeatedField(field, index, value);
       extensions.setRepeatedField(field, index, value);
       return this;
       return this;
     }
     }
 
 
-    public MergeTarget addRepeatedField(
-        Descriptors.FieldDescriptor field, Object value) {
+    @Override
+    public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
       extensions.addRepeatedField(field, value);
       extensions.addRepeatedField(field, value);
       return this;
       return this;
     }
     }
@@ -594,25 +618,31 @@ class MessageReflection {
       return null;
       return null;
     }
     }
 
 
+    @Override
     public ContainerType getContainerType() {
     public ContainerType getContainerType() {
       return ContainerType.EXTENSION_SET;
       return ContainerType.EXTENSION_SET;
     }
     }
 
 
+    @Override
     public ExtensionRegistry.ExtensionInfo findExtensionByName(
     public ExtensionRegistry.ExtensionInfo findExtensionByName(
         ExtensionRegistry registry, String name) {
         ExtensionRegistry registry, String name) {
       return registry.findImmutableExtensionByName(name);
       return registry.findImmutableExtensionByName(name);
     }
     }
 
 
+    @Override
     public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
     public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
-        ExtensionRegistry registry, Descriptors.Descriptor containingType,
-        int fieldNumber) {
+        ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
       return registry.findImmutableExtensionByNumber(containingType,
       return registry.findImmutableExtensionByNumber(containingType,
           fieldNumber);
           fieldNumber);
     }
     }
 
 
-    public Object parseGroup(CodedInputStream input,
-        ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
-        Message defaultInstance) throws IOException {
+    @Override
+    public Object parseGroup(
+        CodedInputStream input,
+        ExtensionRegistryLite registry,
+        Descriptors.FieldDescriptor field,
+        Message defaultInstance)
+        throws IOException {
       Message.Builder subBuilder =
       Message.Builder subBuilder =
           defaultInstance.newBuilderForType();
           defaultInstance.newBuilderForType();
       if (!field.isRepeated()) {
       if (!field.isRepeated()) {
@@ -625,9 +655,13 @@ class MessageReflection {
       return subBuilder.buildPartial();
       return subBuilder.buildPartial();
     }
     }
 
 
-    public Object parseMessage(CodedInputStream input,
-        ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
-        Message defaultInstance) throws IOException {
+    @Override
+    public Object parseMessage(
+        CodedInputStream input,
+        ExtensionRegistryLite registry,
+        Descriptors.FieldDescriptor field,
+        Message defaultInstance)
+        throws IOException {
       Message.Builder subBuilder =
       Message.Builder subBuilder =
           defaultInstance.newBuilderForType();
           defaultInstance.newBuilderForType();
       if (!field.isRepeated()) {
       if (!field.isRepeated()) {
@@ -640,9 +674,13 @@ class MessageReflection {
       return subBuilder.buildPartial();
       return subBuilder.buildPartial();
     }
     }
 
 
-    public Object parseMessageFromBytes(ByteString bytes,
-        ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
-        Message defaultInstance) throws IOException {
+    @Override
+    public Object parseMessageFromBytes(
+        ByteString bytes,
+        ExtensionRegistryLite registry,
+        Descriptors.FieldDescriptor field,
+        Message defaultInstance)
+        throws IOException {
       Message.Builder subBuilder =  defaultInstance.newBuilderForType();
       Message.Builder subBuilder =  defaultInstance.newBuilderForType();
       if (!field.isRepeated()) {
       if (!field.isRepeated()) {
         Message originalMessage = (Message) getField(field);
         Message originalMessage = (Message) getField(field);
@@ -654,14 +692,15 @@ class MessageReflection {
       return subBuilder.buildPartial();
       return subBuilder.buildPartial();
     }
     }
 
 
+    @Override
     public MergeTarget newMergeTargetForField(
     public MergeTarget newMergeTargetForField(
         Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
         Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
       throw new UnsupportedOperationException(
       throw new UnsupportedOperationException(
           "newMergeTargetForField() called on FieldSet object");
           "newMergeTargetForField() called on FieldSet object");
     }
     }
 
 
-    public WireFormat.Utf8Validation
-        getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
+    @Override
+    public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
       if (descriptor.needsUtf8Check()) {
       if (descriptor.needsUtf8Check()) {
         return WireFormat.Utf8Validation.STRICT;
         return WireFormat.Utf8Validation.STRICT;
       }
       }
@@ -669,10 +708,12 @@ class MessageReflection {
       return WireFormat.Utf8Validation.LOOSE;
       return WireFormat.Utf8Validation.LOOSE;
     }
     }
 
 
+    @Override
     public Object finish() {
     public Object finish() {
       throw new UnsupportedOperationException(
       throw new UnsupportedOperationException(
           "finish() called on FieldSet object");
           "finish() called on FieldSet object");
     }
     }
+    
   }
   }
 
 
   /**
   /**

+ 14 - 8
java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java

@@ -38,7 +38,7 @@ import java.util.List;
 /**
 /**
  * Implements {@link ProtobufList} for non-primitive and {@link String} types.
  * Implements {@link ProtobufList} for non-primitive and {@link String} types.
  */
  */
-class ProtobufArrayList<E> extends AbstractProtobufList<E> {
+final class ProtobufArrayList<E> extends AbstractProtobufList<E> {
 
 
   private static final ProtobufArrayList<Object> EMPTY_LIST = new ProtobufArrayList<Object>();
   private static final ProtobufArrayList<Object> EMPTY_LIST = new ProtobufArrayList<Object>();
   static {
   static {
@@ -51,17 +51,23 @@ class ProtobufArrayList<E> extends AbstractProtobufList<E> {
   }
   }
   
   
   private final List<E> list;
   private final List<E> list;
-  
+
   ProtobufArrayList() {
   ProtobufArrayList() {
-    list = new ArrayList<E>();
+    this(new ArrayList<E>(DEFAULT_CAPACITY));
   }
   }
   
   
-  ProtobufArrayList(List<E> toCopy) {
-    list = new ArrayList<E>(toCopy);
+  private ProtobufArrayList(List<E> list) {
+    this.list = list;
   }
   }
-  
-  ProtobufArrayList(int capacity) {
-    list = new ArrayList<E>(capacity);
+
+  @Override
+  public ProtobufArrayList<E> mutableCopyWithCapacity(int capacity) {
+    if (capacity < size()) {
+      throw new IllegalArgumentException();
+    }
+    List<E> newList = new ArrayList<E>(capacity);
+    newList.addAll(list);
+    return new ProtobufArrayList<E>(newList);
   }
   }
   
   
   @Override
   @Override

+ 1 - 0
java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java

@@ -42,6 +42,7 @@ public interface ProtocolMessageEnum extends Internal.EnumLite {
   /**
   /**
    * Return the value's numeric value as defined in the .proto file.
    * Return the value's numeric value as defined in the .proto file.
    */
    */
+  @Override
   int getNumber();
   int getNumber();
 
 
   /**
   /**

+ 7 - 1
java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java

@@ -579,7 +579,7 @@ public class RepeatedFieldBuilder
     }
     }
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public void markDirty() {
   public void markDirty() {
     onChanged();
     onChanged();
   }
   }
@@ -621,10 +621,12 @@ public class RepeatedFieldBuilder
       this.builder = builder;
       this.builder = builder;
     }
     }
 
 
+    @Override
     public int size() {
     public int size() {
       return this.builder.getCount();
       return this.builder.getCount();
     }
     }
 
 
+    @Override
     public MType get(int index) {
     public MType get(int index) {
       return builder.getMessage(index);
       return builder.getMessage(index);
     }
     }
@@ -654,10 +656,12 @@ public class RepeatedFieldBuilder
       this.builder = builder;
       this.builder = builder;
     }
     }
 
 
+    @Override
     public int size() {
     public int size() {
       return this.builder.getCount();
       return this.builder.getCount();
     }
     }
 
 
+    @Override
     public BType get(int index) {
     public BType get(int index) {
       return builder.getBuilder(index);
       return builder.getBuilder(index);
     }
     }
@@ -687,10 +691,12 @@ public class RepeatedFieldBuilder
       this.builder = builder;
       this.builder = builder;
     }
     }
 
 
+    @Override
     public int size() {
     public int size() {
       return this.builder.getCount();
       return this.builder.getCount();
     }
     }
 
 
+    @Override
     public IType get(int index) {
     public IType get(int index) {
       return builder.getMessageOrBuilder(index);
       return builder.getMessageOrBuilder(index);
     }
     }

+ 3 - 1
java/core/src/main/java/com/google/protobuf/RpcUtil.java

@@ -71,6 +71,7 @@ public final class RpcUtil {
       final Class<Type> originalClass,
       final Class<Type> originalClass,
       final Type defaultInstance) {
       final Type defaultInstance) {
     return new RpcCallback<Message>() {
     return new RpcCallback<Message>() {
+      @Override
       public void run(final Message parameter) {
       public void run(final Message parameter) {
         Type typedParameter;
         Type typedParameter;
         try {
         try {
@@ -107,8 +108,9 @@ public final class RpcUtil {
     return new RpcCallback<ParameterType>() {
     return new RpcCallback<ParameterType>() {
       private boolean alreadyCalled = false;
       private boolean alreadyCalled = false;
 
 
+      @Override
       public void run(final ParameterType parameter) {
       public void run(final ParameterType parameter) {
-        synchronized(this) {
+        synchronized (this) {
           if (alreadyCalled) {
           if (alreadyCalled) {
             throw new AlreadyCalledException();
             throw new AlreadyCalledException();
           }
           }

+ 1 - 1
java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java

@@ -234,7 +234,7 @@ public class SingleFieldBuilder
     }
     }
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public void markDirty() {
   public void markDirty() {
     onChanged();
     onChanged();
   }
   }

+ 79 - 27
java/core/src/main/java/com/google/protobuf/SmallSortedMap.java

@@ -411,22 +411,22 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
       this.value = value;
       this.value = value;
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public K getKey() {
     public K getKey() {
       return key;
       return key;
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public V getValue() {
     public V getValue() {
       return value;
       return value;
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public int compareTo(Entry other) {
     public int compareTo(Entry other) {
       return getKey().compareTo(other.getKey());
       return getKey().compareTo(other.getKey());
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public V setValue(V newValue) {
     public V setValue(V newValue) {
       checkMutable();
       checkMutable();
       final V oldValue = this.value;
       final V oldValue = this.value;
@@ -535,13 +535,13 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
     private boolean nextCalledBeforeRemove;
     private boolean nextCalledBeforeRemove;
     private Iterator<Map.Entry<K, V>> lazyOverflowIterator;
     private Iterator<Map.Entry<K, V>> lazyOverflowIterator;
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public boolean hasNext() {
     public boolean hasNext() {
       return (pos + 1) < entryList.size() ||
       return (pos + 1) < entryList.size() ||
           getOverflowIterator().hasNext();
           getOverflowIterator().hasNext();
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public Map.Entry<K, V> next() {
     public Map.Entry<K, V> next() {
       nextCalledBeforeRemove = true;
       nextCalledBeforeRemove = true;
       // Always increment pos so that we know whether the last returned value
       // Always increment pos so that we know whether the last returned value
@@ -552,7 +552,7 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
       return getOverflowIterator().next();
       return getOverflowIterator().next();
     }
     }
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public void remove() {
     public void remove() {
       if (!nextCalledBeforeRemove) {
       if (!nextCalledBeforeRemove) {
         throw new IllegalStateException("remove() was called before next()");
         throw new IllegalStateException("remove() was called before next()");
@@ -588,31 +588,83 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
    */
    */
   private static class EmptySet {
   private static class EmptySet {
 
 
-    private static final Iterator<Object> ITERATOR = new Iterator<Object>() {
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
-      public boolean hasNext() {
-        return false;
-      }
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
-      public Object next() {
-        throw new NoSuchElementException();
-      }
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
-      public void remove() {
-        throw new UnsupportedOperationException();
-      }
-    };
+    private static final Iterator<Object> ITERATOR =
+        new Iterator<Object>() {
+          @Override
+          public boolean hasNext() {
+            return false;
+          }
+          @Override
+          public Object next() {
+            throw new NoSuchElementException();
+          }
+          @Override
+          public void remove() {
+            throw new UnsupportedOperationException();
+          }
+        };
 
 
-    private static final Iterable<Object> ITERABLE = new Iterable<Object>() {
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
-      public Iterator<Object> iterator() {
-        return ITERATOR;
-      }
-    };
+    private static final Iterable<Object> ITERABLE =
+        new Iterable<Object>() {
+          @Override
+          public Iterator<Object> iterator() {
+            return ITERATOR;
+          }
+        };
 
 
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
     static <T> Iterable<T> iterable() {
     static <T> Iterable<T> iterable() {
       return (Iterable<T>) ITERABLE;
       return (Iterable<T>) ITERABLE;
     }
     }
   }
   }
+  
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    
+    if (!(o instanceof SmallSortedMap)) {
+      return super.equals(o);
+    }
+    
+    SmallSortedMap<?, ?> other = (SmallSortedMap<?, ?>) o;
+    final int size = size();
+    if (size != other.size()) {
+      return false;
+    }
+    
+    // Best effort try to avoid allocating an entry set.
+    final int numArrayEntries = getNumArrayEntries();
+    if (numArrayEntries != other.getNumArrayEntries()) {
+      return entrySet().equals(other.entrySet());
+    }
+    
+    for (int i = 0; i < numArrayEntries; i++) {
+      if (!getArrayEntryAt(i).equals(other.getArrayEntryAt(i))) {
+        return false;
+      }
+    }
+    
+    if (numArrayEntries != size) {
+      return overflowEntries.equals(other.overflowEntries);
+    }
+    
+    
+    return true;
+  }
+  
+  @Override
+  public int hashCode() {
+    int h = 0;
+    final int listSize = getNumArrayEntries();
+    for (int i = 0; i < listSize; i++) {
+      h += entryList.get(i).hashCode();
+    }
+    // Avoid the iterator allocation if possible.
+    if (getNumOverflowEntries() > 0) {
+      h += overflowEntries.hashCode();
+    }
+    return h;
+  }
 }
 }

+ 2 - 0
java/core/src/main/java/com/google/protobuf/TextFormat.java

@@ -965,11 +965,13 @@ public final class TextFormat {
      */
      */
     public boolean consumeBoolean() throws ParseException {
     public boolean consumeBoolean() throws ParseException {
       if (currentToken.equals("true")
       if (currentToken.equals("true")
+          || currentToken.equals("True")
           || currentToken.equals("t")
           || currentToken.equals("t")
           || currentToken.equals("1")) {
           || currentToken.equals("1")) {
         nextToken();
         nextToken();
         return true;
         return true;
       } else if (currentToken.equals("false")
       } else if (currentToken.equals("false")
+          || currentToken.equals("False")
           || currentToken.equals("f")
           || currentToken.equals("f")
           || currentToken.equals("0")) {
           || currentToken.equals("0")) {
         nextToken();
         nextToken();

+ 51 - 26
java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java

@@ -76,6 +76,7 @@ public final class UnknownFieldSet implements MessageLite {
   public static UnknownFieldSet getDefaultInstance() {
   public static UnknownFieldSet getDefaultInstance() {
     return defaultInstance;
     return defaultInstance;
   }
   }
+  @Override
   public UnknownFieldSet getDefaultInstanceForType() {
   public UnknownFieldSet getDefaultInstanceForType() {
     return defaultInstance;
     return defaultInstance;
   }
   }
@@ -126,6 +127,7 @@ public final class UnknownFieldSet implements MessageLite {
   }
   }
 
 
   /** Serializes the set and writes it to {@code output}. */
   /** Serializes the set and writes it to {@code output}. */
+  @Override
   public void writeTo(final CodedOutputStream output) throws IOException {
   public void writeTo(final CodedOutputStream output) throws IOException {
     for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
     for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
       entry.getValue().writeTo(entry.getKey(), output);
       entry.getValue().writeTo(entry.getKey(), output);
@@ -146,6 +148,7 @@ public final class UnknownFieldSet implements MessageLite {
    * Serializes the message to a {@code ByteString} and returns it. This is
    * Serializes the message to a {@code ByteString} and returns it. This is
    * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
    * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
    */
    */
+  @Override
   public ByteString toByteString() {
   public ByteString toByteString() {
     try {
     try {
       final ByteString.CodedBuilder out =
       final ByteString.CodedBuilder out =
@@ -163,6 +166,7 @@ public final class UnknownFieldSet implements MessageLite {
    * Serializes the message to a {@code byte} array and returns it.  This is
    * Serializes the message to a {@code byte} array and returns it.  This is
    * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
    * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
    */
    */
+  @Override
   public byte[] toByteArray() {
   public byte[] toByteArray() {
     try {
     try {
       final byte[] result = new byte[getSerializedSize()];
       final byte[] result = new byte[getSerializedSize()];
@@ -181,12 +185,14 @@ public final class UnknownFieldSet implements MessageLite {
    * Serializes the message and writes it to {@code output}.  This is just a
    * Serializes the message and writes it to {@code output}.  This is just a
    * trivial wrapper around {@link #writeTo(CodedOutputStream)}.
    * trivial wrapper around {@link #writeTo(CodedOutputStream)}.
    */
    */
+  @Override
   public void writeTo(final OutputStream output) throws IOException {
   public void writeTo(final OutputStream output) throws IOException {
     final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
     final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
     writeTo(codedOutput);
     writeTo(codedOutput);
     codedOutput.flush();
     codedOutput.flush();
   }
   }
 
 
+  @Override
   public void writeDelimitedTo(OutputStream output) throws IOException {
   public void writeDelimitedTo(OutputStream output) throws IOException {
     final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
     final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
     codedOutput.writeRawVarint32(getSerializedSize());
     codedOutput.writeRawVarint32(getSerializedSize());
@@ -195,6 +201,7 @@ public final class UnknownFieldSet implements MessageLite {
   }
   }
 
 
   /** Get the number of bytes required to encode this set. */
   /** Get the number of bytes required to encode this set. */
+  @Override
   public int getSerializedSize() {
   public int getSerializedSize() {
     int result = 0;
     int result = 0;
     for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
     for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
@@ -228,6 +235,7 @@ public final class UnknownFieldSet implements MessageLite {
     return result;
     return result;
   }
   }
 
 
+  @Override
   public boolean isInitialized() {
   public boolean isInitialized() {
     // UnknownFieldSets do not have required fields, so they are always
     // UnknownFieldSets do not have required fields, so they are always
     // initialized.
     // initialized.
@@ -258,10 +266,12 @@ public final class UnknownFieldSet implements MessageLite {
     return newBuilder().mergeFrom(input).build();
     return newBuilder().mergeFrom(input).build();
   }
   }
 
 
+  @Override
   public Builder newBuilderForType() {
   public Builder newBuilderForType() {
     return newBuilder();
     return newBuilder();
   }
   }
 
 
+  @Override
   public Builder toBuilder() {
   public Builder toBuilder() {
     return newBuilder().mergeFrom(this);
     return newBuilder().mergeFrom(this);
   }
   }
@@ -329,6 +339,7 @@ public final class UnknownFieldSet implements MessageLite {
      * in undefined behavior and can cause a {@code NullPointerException} to be
      * in undefined behavior and can cause a {@code NullPointerException} to be
      * thrown.
      * thrown.
      */
      */
+    @Override
     public UnknownFieldSet build() {
     public UnknownFieldSet build() {
       getFieldBuilder(0);  // Force lastField to be built.
       getFieldBuilder(0);  // Force lastField to be built.
       final UnknownFieldSet result;
       final UnknownFieldSet result;
@@ -341,6 +352,7 @@ public final class UnknownFieldSet implements MessageLite {
       return result;
       return result;
     }
     }
 
 
+    @Override
     public UnknownFieldSet buildPartial() {
     public UnknownFieldSet buildPartial() {
       // No required fields, so this is the same as build().
       // No required fields, so this is the same as build().
       return build();
       return build();
@@ -353,6 +365,7 @@ public final class UnknownFieldSet implements MessageLite {
           new UnknownFieldSet(fields));
           new UnknownFieldSet(fields));
     }
     }
 
 
+    @Override
     public UnknownFieldSet getDefaultInstanceForType() {
     public UnknownFieldSet getDefaultInstanceForType() {
       return UnknownFieldSet.getDefaultInstance();
       return UnknownFieldSet.getDefaultInstance();
     }
     }
@@ -364,6 +377,7 @@ public final class UnknownFieldSet implements MessageLite {
     }
     }
 
 
     /** Reset the builder to an empty set. */
     /** Reset the builder to an empty set. */
+    @Override
     public Builder clear() {
     public Builder clear() {
       reinitialize();
       reinitialize();
       return this;
       return this;
@@ -487,6 +501,7 @@ public final class UnknownFieldSet implements MessageLite {
      * Parse an entire message from {@code input} and merge its fields into
      * Parse an entire message from {@code input} and merge its fields into
      * this set.
      * this set.
      */
      */
+    @Override
     public Builder mergeFrom(final CodedInputStream input) throws IOException {
     public Builder mergeFrom(final CodedInputStream input) throws IOException {
       while (true) {
       while (true) {
         final int tag = input.readTag();
         final int tag = input.readTag();
@@ -536,8 +551,8 @@ public final class UnknownFieldSet implements MessageLite {
      * set being built.  This is just a small wrapper around
      * set being built.  This is just a small wrapper around
      * {@link #mergeFrom(CodedInputStream)}.
      * {@link #mergeFrom(CodedInputStream)}.
      */
      */
-    public Builder mergeFrom(final ByteString data)
-        throws InvalidProtocolBufferException {
+    @Override
+    public Builder mergeFrom(final ByteString data) throws InvalidProtocolBufferException {
       try {
       try {
         final CodedInputStream input = data.newCodedInput();
         final CodedInputStream input = data.newCodedInput();
         mergeFrom(input);
         mergeFrom(input);
@@ -557,8 +572,8 @@ public final class UnknownFieldSet implements MessageLite {
      * set being built.  This is just a small wrapper around
      * set being built.  This is just a small wrapper around
      * {@link #mergeFrom(CodedInputStream)}.
      * {@link #mergeFrom(CodedInputStream)}.
      */
      */
-    public Builder mergeFrom(final byte[] data)
-        throws InvalidProtocolBufferException {
+    @Override
+    public Builder mergeFrom(final byte[] data) throws InvalidProtocolBufferException {
       try {
       try {
         final CodedInputStream input = CodedInputStream.newInstance(data);
         final CodedInputStream input = CodedInputStream.newInstance(data);
         mergeFrom(input);
         mergeFrom(input);
@@ -578,6 +593,7 @@ public final class UnknownFieldSet implements MessageLite {
      * set being built.  This is just a small wrapper around
      * set being built.  This is just a small wrapper around
      * {@link #mergeFrom(CodedInputStream)}.
      * {@link #mergeFrom(CodedInputStream)}.
      */
      */
+    @Override
     public Builder mergeFrom(final InputStream input) throws IOException {
     public Builder mergeFrom(final InputStream input) throws IOException {
       final CodedInputStream codedInput = CodedInputStream.newInstance(input);
       final CodedInputStream codedInput = CodedInputStream.newInstance(input);
       mergeFrom(codedInput);
       mergeFrom(codedInput);
@@ -585,8 +601,8 @@ public final class UnknownFieldSet implements MessageLite {
       return this;
       return this;
     }
     }
 
 
-    public boolean mergeDelimitedFrom(InputStream input)
-        throws IOException {
+    @Override
+    public boolean mergeDelimitedFrom(InputStream input) throws IOException {
       final int firstByte = input.read();
       final int firstByte = input.read();
       if (firstByte == -1) {
       if (firstByte == -1) {
         return false;
         return false;
@@ -597,30 +613,29 @@ public final class UnknownFieldSet implements MessageLite {
       return true;
       return true;
     }
     }
 
 
-    public boolean mergeDelimitedFrom(
-        InputStream input,
-        ExtensionRegistryLite extensionRegistry) throws IOException {
+    @Override
+    public boolean mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
+        throws IOException {
       // UnknownFieldSet has no extensions.
       // UnknownFieldSet has no extensions.
       return mergeDelimitedFrom(input);
       return mergeDelimitedFrom(input);
     }
     }
 
 
-    public Builder mergeFrom(
-        CodedInputStream input,
-        ExtensionRegistryLite extensionRegistry) throws IOException {
+    @Override
+    public Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
+        throws IOException {
       // UnknownFieldSet has no extensions.
       // UnknownFieldSet has no extensions.
       return mergeFrom(input);
       return mergeFrom(input);
     }
     }
 
 
-    public Builder mergeFrom(
-        ByteString data,
-        ExtensionRegistryLite extensionRegistry)
+    @Override
+    public Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {
       // UnknownFieldSet has no extensions.
       // UnknownFieldSet has no extensions.
       return mergeFrom(data);
       return mergeFrom(data);
     }
     }
 
 
-    public Builder mergeFrom(byte[] data, int off, int len)
-        throws InvalidProtocolBufferException {
+    @Override
+    public Builder mergeFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException {
       try {
       try {
         final CodedInputStream input =
         final CodedInputStream input =
             CodedInputStream.newInstance(data, off, len);
             CodedInputStream.newInstance(data, off, len);
@@ -636,29 +651,37 @@ public final class UnknownFieldSet implements MessageLite {
       }
       }
     }
     }
 
 
-    public Builder mergeFrom(
-        byte[] data,
-        ExtensionRegistryLite extensionRegistry)
+    @Override
+    public Builder mergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {
       // UnknownFieldSet has no extensions.
       // UnknownFieldSet has no extensions.
       return mergeFrom(data);
       return mergeFrom(data);
     }
     }
 
 
-    public Builder mergeFrom(
-        byte[] data, int off, int len,
-        ExtensionRegistryLite extensionRegistry)
+    @Override
+    public Builder mergeFrom(byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {
       // UnknownFieldSet has no extensions.
       // UnknownFieldSet has no extensions.
       return mergeFrom(data, off, len);
       return mergeFrom(data, off, len);
     }
     }
 
 
-    public Builder mergeFrom(
-        InputStream input,
-        ExtensionRegistryLite extensionRegistry) throws IOException {
+    @Override
+    public Builder mergeFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
+        throws IOException {
       // UnknownFieldSet has no extensions.
       // UnknownFieldSet has no extensions.
       return mergeFrom(input);
       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() {
     public boolean isInitialized() {
       // UnknownFieldSets do not have required fields, so they are always
       // UnknownFieldSets do not have required fields, so they are always
       // initialized.
       // initialized.
@@ -987,6 +1010,7 @@ public final class UnknownFieldSet implements MessageLite {
    * Parser to implement MessageLite interface.
    * Parser to implement MessageLite interface.
    */
    */
   public static final class Parser extends AbstractParser<UnknownFieldSet> {
   public static final class Parser extends AbstractParser<UnknownFieldSet> {
+    @Override
     public UnknownFieldSet parsePartialFrom(
     public UnknownFieldSet parsePartialFrom(
         CodedInputStream input, ExtensionRegistryLite extensionRegistry)
         CodedInputStream input, ExtensionRegistryLite extensionRegistry)
         throws InvalidProtocolBufferException {
         throws InvalidProtocolBufferException {
@@ -1004,6 +1028,7 @@ public final class UnknownFieldSet implements MessageLite {
   }
   }
 
 
   private static final Parser PARSER = new Parser();
   private static final Parser PARSER = new Parser();
+  @Override
   public final Parser getParserForType() {
   public final Parser getParserForType() {
     return PARSER;
     return PARSER;
   }
   }

+ 25 - 25
java/core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java

@@ -68,42 +68,42 @@ public class UnmodifiableLazyStringList extends AbstractList<String>
     return list.size();
     return list.size();
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public ByteString getByteString(int index) {
   public ByteString getByteString(int index) {
     return list.getByteString(index);
     return list.getByteString(index);
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public void add(ByteString element) {
   public void add(ByteString element) {
     throw new UnsupportedOperationException();
     throw new UnsupportedOperationException();
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public void set(int index, ByteString element) {
   public void set(int index, ByteString element) {
     throw new UnsupportedOperationException();
     throw new UnsupportedOperationException();
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public boolean addAllByteString(Collection<? extends ByteString> element) {
   public boolean addAllByteString(Collection<? extends ByteString> element) {
     throw new UnsupportedOperationException();
     throw new UnsupportedOperationException();
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public byte[] getByteArray(int index) {
   public byte[] getByteArray(int index) {
     return list.getByteArray(index);
     return list.getByteArray(index);
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public void add(byte[] element) {
   public void add(byte[] element) {
     throw new UnsupportedOperationException();
     throw new UnsupportedOperationException();
   }
   }
   
   
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public void set(int index, byte[] element) {
   public void set(int index, byte[] element) {
     throw new UnsupportedOperationException();
     throw new UnsupportedOperationException();
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public boolean addAllByteArray(Collection<byte[]> element) {
   public boolean addAllByteArray(Collection<byte[]> element) {
     throw new UnsupportedOperationException();
     throw new UnsupportedOperationException();
   }
   }
@@ -113,47 +113,47 @@ public class UnmodifiableLazyStringList extends AbstractList<String>
     return new ListIterator<String>() {
     return new ListIterator<String>() {
       ListIterator<String> iter = list.listIterator(index);
       ListIterator<String> iter = list.listIterator(index);
 
 
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      @Override
       public boolean hasNext() {
       public boolean hasNext() {
         return iter.hasNext();
         return iter.hasNext();
       }
       }
 
 
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      @Override
       public String next() {
       public String next() {
         return iter.next();
         return iter.next();
       }
       }
 
 
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      @Override
       public boolean hasPrevious() {
       public boolean hasPrevious() {
         return iter.hasPrevious();
         return iter.hasPrevious();
       }
       }
 
 
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      @Override
       public String previous() {
       public String previous() {
         return iter.previous();
         return iter.previous();
       }
       }
 
 
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      @Override
       public int nextIndex() {
       public int nextIndex() {
         return iter.nextIndex();
         return iter.nextIndex();
       }
       }
 
 
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      @Override
       public int previousIndex() {
       public int previousIndex() {
         return iter.previousIndex();
         return iter.previousIndex();
       }
       }
 
 
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      @Override
       public void remove() {
       public void remove() {
         throw new UnsupportedOperationException();
         throw new UnsupportedOperationException();
       }
       }
 
 
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      @Override
       public void set(String o) {
       public void set(String o) {
         throw new UnsupportedOperationException();
         throw new UnsupportedOperationException();
       }
       }
 
 
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      @Override
       public void add(String o) {
       public void add(String o) {
         throw new UnsupportedOperationException();
         throw new UnsupportedOperationException();
       }
       }
@@ -165,45 +165,45 @@ public class UnmodifiableLazyStringList extends AbstractList<String>
     return new Iterator<String>() {
     return new Iterator<String>() {
       Iterator<String> iter = list.iterator();
       Iterator<String> iter = list.iterator();
 
 
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      @Override
       public boolean hasNext() {
       public boolean hasNext() {
         return iter.hasNext();
         return iter.hasNext();
       }
       }
 
 
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      @Override
       public String next() {
       public String next() {
         return iter.next();
         return iter.next();
       }
       }
 
 
-      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      @Override
       public void remove() {
       public void remove() {
         throw new UnsupportedOperationException();
         throw new UnsupportedOperationException();
       }
       }
     };
     };
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public List<?> getUnderlyingElements() {
   public List<?> getUnderlyingElements() {
     // The returned value is already unmodifiable.
     // The returned value is already unmodifiable.
     return list.getUnderlyingElements();
     return list.getUnderlyingElements();
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public void mergeFrom(LazyStringList other) {
   public void mergeFrom(LazyStringList other) {
     throw new UnsupportedOperationException();
     throw new UnsupportedOperationException();
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public List<byte[]> asByteArrayList() {
   public List<byte[]> asByteArrayList() {
     return Collections.unmodifiableList(list.asByteArrayList());
     return Collections.unmodifiableList(list.asByteArrayList());
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public List<ByteString> asByteStringList() {
   public List<ByteString> asByteStringList() {
     return Collections.unmodifiableList(list.asByteStringList());
     return Collections.unmodifiableList(list.asByteStringList());
   }
   }
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public LazyStringList getUnmodifiableView() {
   public LazyStringList getUnmodifiableView() {
     return this;
     return this;
   }
   }

+ 15 - 4
java/core/src/main/java/com/google/protobuf/WireFormat.java

@@ -116,16 +116,24 @@ public final class WireFormat {
     FIXED32 (JavaType.INT        , WIRETYPE_FIXED32         ),
     FIXED32 (JavaType.INT        , WIRETYPE_FIXED32         ),
     BOOL    (JavaType.BOOLEAN    , WIRETYPE_VARINT          ),
     BOOL    (JavaType.BOOLEAN    , WIRETYPE_VARINT          ),
     STRING  (JavaType.STRING     , WIRETYPE_LENGTH_DELIMITED) {
     STRING  (JavaType.STRING     , WIRETYPE_LENGTH_DELIMITED) {
-      public boolean isPackable() { return false; }
+      @Override
+      public boolean isPackable() {
+        return false; }
     },
     },
     GROUP   (JavaType.MESSAGE    , WIRETYPE_START_GROUP     ) {
     GROUP   (JavaType.MESSAGE    , WIRETYPE_START_GROUP     ) {
-      public boolean isPackable() { return false; }
+      @Override
+      public boolean isPackable() {
+        return false; }
     },
     },
     MESSAGE (JavaType.MESSAGE    , WIRETYPE_LENGTH_DELIMITED) {
     MESSAGE (JavaType.MESSAGE    , WIRETYPE_LENGTH_DELIMITED) {
-      public boolean isPackable() { return false; }
+      @Override
+      public boolean isPackable() {
+        return false; }
     },
     },
     BYTES   (JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED) {
     BYTES   (JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED) {
-      public boolean isPackable() { return false; }
+      @Override
+      public boolean isPackable() {
+        return false; }
     },
     },
     UINT32  (JavaType.INT        , WIRETYPE_VARINT          ),
     UINT32  (JavaType.INT        , WIRETYPE_VARINT          ),
     ENUM    (JavaType.ENUM       , WIRETYPE_VARINT          ),
     ENUM    (JavaType.ENUM       , WIRETYPE_VARINT          ),
@@ -170,18 +178,21 @@ public final class WireFormat {
   enum Utf8Validation {
   enum Utf8Validation {
     /** Eagerly parses to String; silently accepts invalid UTF8 bytes. */
     /** Eagerly parses to String; silently accepts invalid UTF8 bytes. */
     LOOSE {
     LOOSE {
+      @Override
       Object readString(CodedInputStream input) throws IOException {
       Object readString(CodedInputStream input) throws IOException {
         return input.readString();
         return input.readString();
       }
       }
     },
     },
     /** Eagerly parses to String; throws an IOException on invalid bytes. */
     /** Eagerly parses to String; throws an IOException on invalid bytes. */
     STRICT {
     STRICT {
+      @Override
       Object readString(CodedInputStream input) throws IOException {
       Object readString(CodedInputStream input) throws IOException {
         return input.readStringRequireUtf8();
         return input.readStringRequireUtf8();
       }
       }
     },
     },
     /** Keep data as ByteString; validation/conversion to String is lazy. */
     /** Keep data as ByteString; validation/conversion to String is lazy. */
     LAZY {
     LAZY {
+      @Override
       Object readString(CodedInputStream input) throws IOException {
       Object readString(CodedInputStream input) throws IOException {
         return input.readBytes();
         return input.readBytes();
       }
       }

+ 33 - 8
java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java

@@ -64,35 +64,44 @@ public class AbstractMessageTest extends TestCase {
       this.wrappedMessage = wrappedMessage;
       this.wrappedMessage = wrappedMessage;
     }
     }
 
 
+    @Override
     public Descriptors.Descriptor getDescriptorForType() {
     public Descriptors.Descriptor getDescriptorForType() {
       return wrappedMessage.getDescriptorForType();
       return wrappedMessage.getDescriptorForType();
     }
     }
+    @Override
     public AbstractMessageWrapper getDefaultInstanceForType() {
     public AbstractMessageWrapper getDefaultInstanceForType() {
       return new AbstractMessageWrapper(
       return new AbstractMessageWrapper(
         wrappedMessage.getDefaultInstanceForType());
         wrappedMessage.getDefaultInstanceForType());
     }
     }
+    @Override
     public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
     public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
       return wrappedMessage.getAllFields();
       return wrappedMessage.getAllFields();
     }
     }
+    @Override
     public boolean hasField(Descriptors.FieldDescriptor field) {
     public boolean hasField(Descriptors.FieldDescriptor field) {
       return wrappedMessage.hasField(field);
       return wrappedMessage.hasField(field);
     }
     }
+    @Override
     public Object getField(Descriptors.FieldDescriptor field) {
     public Object getField(Descriptors.FieldDescriptor field) {
       return wrappedMessage.getField(field);
       return wrappedMessage.getField(field);
     }
     }
+    @Override
     public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
     public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
       return wrappedMessage.getRepeatedFieldCount(field);
       return wrappedMessage.getRepeatedFieldCount(field);
     }
     }
-    public Object getRepeatedField(
-        Descriptors.FieldDescriptor field, int index) {
+    @Override
+    public Object getRepeatedField(Descriptors.FieldDescriptor field, int index) {
       return wrappedMessage.getRepeatedField(field, index);
       return wrappedMessage.getRepeatedField(field, index);
     }
     }
+    @Override
     public UnknownFieldSet getUnknownFields() {
     public UnknownFieldSet getUnknownFields() {
       return wrappedMessage.getUnknownFields();
       return wrappedMessage.getUnknownFields();
     }
     }
+    @Override
     public Builder newBuilderForType() {
     public Builder newBuilderForType() {
       return new Builder(wrappedMessage.newBuilderForType());
       return new Builder(wrappedMessage.newBuilderForType());
     }
     }
+    @Override
     public Builder toBuilder() {
     public Builder toBuilder() {
       return new Builder(wrappedMessage.toBuilder());
       return new Builder(wrappedMessage.toBuilder());
     }
     }
@@ -104,65 +113,80 @@ public class AbstractMessageTest extends TestCase {
         this.wrappedBuilder = wrappedBuilder;
         this.wrappedBuilder = wrappedBuilder;
       }
       }
 
 
+      @Override
       public AbstractMessageWrapper build() {
       public AbstractMessageWrapper build() {
         return new AbstractMessageWrapper(wrappedBuilder.build());
         return new AbstractMessageWrapper(wrappedBuilder.build());
       }
       }
+      @Override
       public AbstractMessageWrapper buildPartial() {
       public AbstractMessageWrapper buildPartial() {
         return new AbstractMessageWrapper(wrappedBuilder.buildPartial());
         return new AbstractMessageWrapper(wrappedBuilder.buildPartial());
       }
       }
+      @Override
       public Builder clone() {
       public Builder clone() {
         return new Builder(wrappedBuilder.clone());
         return new Builder(wrappedBuilder.clone());
       }
       }
+      @Override
       public boolean isInitialized() {
       public boolean isInitialized() {
         return clone().buildPartial().isInitialized();
         return clone().buildPartial().isInitialized();
       }
       }
+      @Override
       public Descriptors.Descriptor getDescriptorForType() {
       public Descriptors.Descriptor getDescriptorForType() {
         return wrappedBuilder.getDescriptorForType();
         return wrappedBuilder.getDescriptorForType();
       }
       }
+      @Override
       public AbstractMessageWrapper getDefaultInstanceForType() {
       public AbstractMessageWrapper getDefaultInstanceForType() {
         return new AbstractMessageWrapper(
         return new AbstractMessageWrapper(
           wrappedBuilder.getDefaultInstanceForType());
           wrappedBuilder.getDefaultInstanceForType());
       }
       }
+      @Override
       public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
       public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
         return wrappedBuilder.getAllFields();
         return wrappedBuilder.getAllFields();
       }
       }
+      @Override
       public Builder newBuilderForField(Descriptors.FieldDescriptor field) {
       public Builder newBuilderForField(Descriptors.FieldDescriptor field) {
         return new Builder(wrappedBuilder.newBuilderForField(field));
         return new Builder(wrappedBuilder.newBuilderForField(field));
       }
       }
+      @Override
       public boolean hasField(Descriptors.FieldDescriptor field) {
       public boolean hasField(Descriptors.FieldDescriptor field) {
         return wrappedBuilder.hasField(field);
         return wrappedBuilder.hasField(field);
       }
       }
+      @Override
       public Object getField(Descriptors.FieldDescriptor field) {
       public Object getField(Descriptors.FieldDescriptor field) {
         return wrappedBuilder.getField(field);
         return wrappedBuilder.getField(field);
       }
       }
+      @Override
       public Builder setField(Descriptors.FieldDescriptor field, Object value) {
       public Builder setField(Descriptors.FieldDescriptor field, Object value) {
         wrappedBuilder.setField(field, value);
         wrappedBuilder.setField(field, value);
         return this;
         return this;
       }
       }
+      @Override
       public Builder clearField(Descriptors.FieldDescriptor field) {
       public Builder clearField(Descriptors.FieldDescriptor field) {
         wrappedBuilder.clearField(field);
         wrappedBuilder.clearField(field);
         return this;
         return this;
       }
       }
+      @Override
       public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
       public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
         return wrappedBuilder.getRepeatedFieldCount(field);
         return wrappedBuilder.getRepeatedFieldCount(field);
       }
       }
-      public Object getRepeatedField(
-          Descriptors.FieldDescriptor field, int index) {
+      @Override
+      public Object getRepeatedField(Descriptors.FieldDescriptor field, int index) {
         return wrappedBuilder.getRepeatedField(field, index);
         return wrappedBuilder.getRepeatedField(field, index);
       }
       }
-      public Builder setRepeatedField(Descriptors.FieldDescriptor field,
-                                      int index, Object value) {
+      @Override
+      public Builder setRepeatedField(Descriptors.FieldDescriptor field, int index, Object value) {
         wrappedBuilder.setRepeatedField(field, index, value);
         wrappedBuilder.setRepeatedField(field, index, value);
         return this;
         return this;
       }
       }
-      public Builder addRepeatedField(
-          Descriptors.FieldDescriptor field, Object value) {
+      @Override
+      public Builder addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
         wrappedBuilder.addRepeatedField(field, value);
         wrappedBuilder.addRepeatedField(field, value);
         return this;
         return this;
       }
       }
+      @Override
       public UnknownFieldSet getUnknownFields() {
       public UnknownFieldSet getUnknownFields() {
         return wrappedBuilder.getUnknownFields();
         return wrappedBuilder.getUnknownFields();
       }
       }
+      @Override
       public Builder setUnknownFields(UnknownFieldSet unknownFields) {
       public Builder setUnknownFields(UnknownFieldSet unknownFields) {
         wrappedBuilder.setUnknownFields(unknownFields);
         wrappedBuilder.setUnknownFields(unknownFields);
         return this;
         return this;
@@ -172,6 +196,7 @@ public class AbstractMessageTest extends TestCase {
         return wrappedBuilder.getFieldBuilder(field);
         return wrappedBuilder.getFieldBuilder(field);
       }
       }
     }
     }
+    @Override
     public Parser<? extends Message> getParserForType() {
     public Parser<? extends Message> getParserForType() {
       return wrappedMessage.getParserForType();
       return wrappedMessage.getParserForType();
     }
     }

+ 0 - 14
java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java

@@ -73,20 +73,6 @@ public class BooleanArrayListTest extends TestCase {
     assertImmutable(list);
     assertImmutable(list);
   }
   }
   
   
-  public void testCopyConstructor() {
-    BooleanArrayList copy = new BooleanArrayList(TERTIARY_LIST);
-    assertEquals(TERTIARY_LIST, copy);
-
-    copy = new BooleanArrayList(BooleanArrayList.emptyList());
-    assertEquals(BooleanArrayList.emptyList(), copy);
-    
-    copy = new BooleanArrayList(asList(false, false, true));
-    assertEquals(asList(false, false, true), copy);
-
-    copy = new BooleanArrayList(Collections.<Boolean>emptyList());
-    assertEquals(BooleanArrayList.emptyList(), copy);
-  }
-  
   public void testModificationWithIteration() {
   public void testModificationWithIteration() {
     list.addAll(asList(true, false, false, true));
     list.addAll(asList(true, false, false, true));
     Iterator<Boolean> iterator = list.iterator();
     Iterator<Boolean> iterator = list.iterator();

+ 2 - 0
java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java

@@ -81,10 +81,12 @@ public class CodedInputStreamTest extends TestCase {
       this.blockSize = blockSize;
       this.blockSize = blockSize;
     }
     }
 
 
+    @Override
     public int read(byte[] b) throws IOException {
     public int read(byte[] b) throws IOException {
       return super.read(b, 0, Math.min(b.length, blockSize));
       return super.read(b, 0, Math.min(b.length, blockSize));
     }
     }
 
 
+    @Override
     public int read(byte[] b, int off, int len) throws IOException {
     public int read(byte[] b, int off, int len) throws IOException {
       return super.read(b, off, Math.min(len, blockSize));
       return super.read(b, off, Math.min(len, blockSize));
     }
     }

+ 503 - 273
java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java

@@ -30,6 +30,7 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
+import com.google.protobuf.CodedOutputStream.OutOfSpaceException;
 import protobuf_unittest.UnittestProto.SparseEnumMessage;
 import protobuf_unittest.UnittestProto.SparseEnumMessage;
 import protobuf_unittest.UnittestProto.TestAllTypes;
 import protobuf_unittest.UnittestProto.TestAllTypes;
 import protobuf_unittest.UnittestProto.TestPackedTypes;
 import protobuf_unittest.UnittestProto.TestPackedTypes;
@@ -50,118 +51,180 @@ import java.util.List;
  * @author kenton@google.com Kenton Varda
  * @author kenton@google.com Kenton Varda
  */
  */
 public class CodedOutputStreamTest extends TestCase {
 public class CodedOutputStreamTest extends TestCase {
-  /**
-   * Helper to construct a byte array from a bunch of bytes.  The inputs are
-   * actually ints so that I can use hex notation and not get stupid errors
-   * about precision.
-   */
-  private byte[] bytes(int... bytesAsInts) {
-    byte[] bytes = new byte[bytesAsInts.length];
-    for (int i = 0; i < bytesAsInts.length; i++) {
-      bytes[i] = (byte) bytesAsInts[i];
-    }
-    return bytes;
+  private interface Coder {
+    CodedOutputStream stream();
+
+    byte[] toByteArray();
+
+    OutputType getOutputType();
   }
   }
 
 
-  /** Arrays.asList() does not work with arrays of primitives.  :( */
-  private List<Byte> toList(byte[] bytes) {
-    List<Byte> result = new ArrayList<Byte>();
-    for (byte b : bytes) {
-      result.add(b);
+  private static final class OutputStreamCoder implements Coder {
+    private final CodedOutputStream stream;
+    private final ByteArrayOutputStream output;
+
+    OutputStreamCoder(int size) {
+      output = new ByteArrayOutputStream();
+      stream = CodedOutputStream.newInstance(output, size);
+    }
+
+    @Override
+    public CodedOutputStream stream() {
+      return stream;
+    }
+
+    @Override
+    public byte[] toByteArray() {
+      return output.toByteArray();
+    }
+
+    @Override
+    public OutputType getOutputType() {
+      return OutputType.STREAM;
     }
     }
-    return result;
   }
   }
 
 
-  private void assertEqualBytes(byte[] a, byte[] b) {
-    assertEquals(toList(a), toList(b));
+  private static final class ArrayCoder implements Coder {
+    private final CodedOutputStream stream;
+    private final byte[] bytes;
+
+    ArrayCoder(int size) {
+      bytes = new byte[size];
+      stream = CodedOutputStream.newInstance(bytes);
+    }
+
+    @Override
+    public CodedOutputStream stream() {
+      return stream;
+    }
+
+    @Override
+    public byte[] toByteArray() {
+      return Arrays.copyOf(bytes, stream.getTotalBytesWritten());
+    }
+
+    @Override
+    public OutputType getOutputType() {
+      return OutputType.ARRAY;
+    }
   }
   }
 
 
-  /**
-   * Writes the given value using writeRawVarint32() and writeRawVarint64() and
-   * checks that the result matches the given bytes.
-   */
-  private void assertWriteVarint(byte[] data, long value) throws Exception {
-    // Only test 32-bit write if the value fits into an int.
-    if (value == (int) value) {
-      ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
-      CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
-      output.writeRawVarint32((int) value);
-      output.flush();
-      assertEqualBytes(data, rawOutput.toByteArray());
+  private static final class NioHeapCoder implements Coder {
+    private final CodedOutputStream stream;
+    private final ByteBuffer buffer;
+    private final int initialPosition;
 
 
-      // Also try computing size.
-      assertEquals(data.length,
-                   CodedOutputStream.computeRawVarint32Size((int) value));
+    NioHeapCoder(int size) {
+      this(size, 0);
     }
     }
 
 
-    {
-      ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
-      CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
-      output.writeRawVarint64(value);
-      output.flush();
-      assertEqualBytes(data, rawOutput.toByteArray());
+    NioHeapCoder(int size, int initialPosition) {
+      this.initialPosition = initialPosition;
+      buffer = ByteBuffer.allocate(size);
+      buffer.position(initialPosition);
+      stream = CodedOutputStream.newInstance(buffer);
+    }
 
 
-      // Also try computing size.
-      assertEquals(data.length,
-                   CodedOutputStream.computeRawVarint64Size(value));
+    @Override
+    public CodedOutputStream stream() {
+      return stream;
     }
     }
 
 
-    // Try different block sizes.
-    for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
-      // Only test 32-bit write if the value fits into an int.
-      if (value == (int) value) {
-        ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
-        CodedOutputStream output =
-          CodedOutputStream.newInstance(rawOutput, blockSize);
-        output.writeRawVarint32((int) value);
-        output.flush();
-        assertEqualBytes(data, rawOutput.toByteArray());
-      }
+    @Override
+    public byte[] toByteArray() {
+      ByteBuffer dup = buffer.duplicate();
+      dup.position(initialPosition);
+      dup.limit(buffer.position());
 
 
-      {
-        ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
-        CodedOutputStream output =
-          CodedOutputStream.newInstance(rawOutput, blockSize);
-        output.writeRawVarint64(value);
-        output.flush();
-        assertEqualBytes(data, rawOutput.toByteArray());
-      }
+      byte[] bytes = new byte[dup.remaining()];
+      dup.get(bytes);
+      return bytes;
+    }
+
+    @Override
+    public OutputType getOutputType() {
+      return OutputType.NIO_HEAP;
     }
     }
   }
   }
 
 
-  private void assertVarintRoundTrip(long value) throws Exception {
-    {
-      ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
-      CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
-      output.writeRawVarint64(value);
-      output.flush();
-      byte[] bytes = rawOutput.toByteArray();
-      assertEquals(bytes.length, CodedOutputStream.computeRawVarint64Size(value));
-      CodedInputStream input = CodedInputStream.newInstance(new ByteArrayInputStream(bytes));
-      assertEquals(value, input.readRawVarint64());
+  private static final class NioDirectCoder implements Coder {
+    private final int initialPosition;
+    private final CodedOutputStream stream;
+    private final ByteBuffer buffer;
+
+    NioDirectCoder(int size) {
+      this(size, 0);
     }
     }
 
 
-    if (value == (int) value) {
-      ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
-      CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
-      output.writeRawVarint32((int) value);
-      output.flush();
-      byte[] bytes = rawOutput.toByteArray();
-      assertEquals(bytes.length, CodedOutputStream.computeRawVarint32Size((int) value));
-      CodedInputStream input = CodedInputStream.newInstance(new ByteArrayInputStream(bytes));
-      assertEquals(value, input.readRawVarint32());
+    NioDirectCoder(int size, int initialPosition) {
+      this.initialPosition = initialPosition;
+      buffer = ByteBuffer.allocateDirect(size);
+      buffer.position(initialPosition);
+      stream = CodedOutputStream.newInstance(buffer);
+    }
+
+    @Override
+    public CodedOutputStream stream() {
+      return stream;
+    }
+
+    @Override
+    public byte[] toByteArray() {
+      ByteBuffer dup = buffer.duplicate();
+      dup.position(initialPosition);
+      dup.limit(buffer.position());
+
+      byte[] bytes = new byte[dup.remaining()];
+      dup.get(bytes);
+      return bytes;
+    }
+
+    @Override
+    public OutputType getOutputType() {
+      return OutputType.NIO_DIRECT;
     }
     }
   }
   }
 
 
+  private enum OutputType {
+    ARRAY() {
+      @Override
+      Coder newCoder(int size) {
+        return new ArrayCoder(size);
+      }
+    },
+    NIO_HEAP() {
+      @Override
+      Coder newCoder(int size) {
+        return new NioHeapCoder(size);
+      }
+    },
+    NIO_DIRECT() {
+      @Override
+      Coder newCoder(int size) {
+        return new NioDirectCoder(size);
+      }
+    },
+    STREAM() {
+      @Override
+      Coder newCoder(int size) {
+        return new OutputStreamCoder(size);
+      }
+    };
+
+    abstract Coder newCoder(int size);
+  }
+
   /** Checks that invariants are maintained for varint round trip input and output. */
   /** Checks that invariants are maintained for varint round trip input and output. */
   public void testVarintRoundTrips() throws Exception {
   public void testVarintRoundTrips() throws Exception {
-    assertVarintRoundTrip(0L);
-    for (int bits = 0; bits < 64; bits++) {
-      long value = 1L << bits;
-      assertVarintRoundTrip(value);
-      assertVarintRoundTrip(value + 1);
-      assertVarintRoundTrip(value - 1);
-      assertVarintRoundTrip(-value);
+    for (OutputType outputType : OutputType.values()) {
+      assertVarintRoundTrip(outputType, 0L);
+      for (int bits = 0; bits < 64; bits++) {
+        long value = 1L << bits;
+        assertVarintRoundTrip(outputType, value);
+        assertVarintRoundTrip(outputType, value + 1);
+        assertVarintRoundTrip(outputType, value - 1);
+        assertVarintRoundTrip(outputType, -value);
+      }
     }
     }
   }
   }
 
 
@@ -173,70 +236,25 @@ public class CodedOutputStreamTest extends TestCase {
     // 14882
     // 14882
     assertWriteVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
     assertWriteVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
     // 2961488830
     // 2961488830
-    assertWriteVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
-      (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
-      (0x0bL << 28));
+    assertWriteVarint(
+        bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
+        (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | (0x0bL << 28));
 
 
     // 64-bit
     // 64-bit
     // 7256456126
     // 7256456126
-    assertWriteVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
-      (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
-      (0x1bL << 28));
+    assertWriteVarint(
+        bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
+        (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | (0x1bL << 28));
     // 41256202580718336
     // 41256202580718336
     assertWriteVarint(
     assertWriteVarint(
-      bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
-      (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
-      (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
+        bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
+        (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) | (0x43L << 28) | (0x49L << 35)
+        | (0x24L << 42) | (0x49L << 49));
     // 11964378330978735131
     // 11964378330978735131
     assertWriteVarint(
     assertWriteVarint(
-      bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
-      (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
-      (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
-      (0x05L << 49) | (0x26L << 56) | (0x01L << 63));
-  }
-
-  /**
-   * Parses the given bytes using writeRawLittleEndian32() and checks
-   * that the result matches the given value.
-   */
-  private void assertWriteLittleEndian32(byte[] data, int value)
-                                         throws Exception {
-    ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
-    CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
-    output.writeRawLittleEndian32(value);
-    output.flush();
-    assertEqualBytes(data, rawOutput.toByteArray());
-
-    // Try different block sizes.
-    for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
-      rawOutput = new ByteArrayOutputStream();
-      output = CodedOutputStream.newInstance(rawOutput, blockSize);
-      output.writeRawLittleEndian32(value);
-      output.flush();
-      assertEqualBytes(data, rawOutput.toByteArray());
-    }
-  }
-
-  /**
-   * Parses the given bytes using writeRawLittleEndian64() and checks
-   * that the result matches the given value.
-   */
-  private void assertWriteLittleEndian64(byte[] data, long value)
-                                         throws Exception {
-    ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
-    CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
-    output.writeRawLittleEndian64(value);
-    output.flush();
-    assertEqualBytes(data, rawOutput.toByteArray());
-
-    // Try different block sizes.
-    for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
-      rawOutput = new ByteArrayOutputStream();
-      output = CodedOutputStream.newInstance(rawOutput, blockSize);
-      output.writeRawLittleEndian64(value);
-      output.flush();
-      assertEqualBytes(data, rawOutput.toByteArray());
-    }
+        bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
+        (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) | (0x3bL << 28) | (0x56L << 35)
+        | (0x00L << 42) | (0x05L << 49) | (0x26L << 56) | (0x01L << 63));
   }
   }
 
 
   /** Tests writeRawLittleEndian32() and writeRawLittleEndian64(). */
   /** Tests writeRawLittleEndian32() and writeRawLittleEndian64(). */
@@ -245,141 +263,138 @@ public class CodedOutputStreamTest extends TestCase {
     assertWriteLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
     assertWriteLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
 
 
     assertWriteLittleEndian64(
     assertWriteLittleEndian64(
-      bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
-      0x123456789abcdef0L);
+        bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12), 0x123456789abcdef0L);
     assertWriteLittleEndian64(
     assertWriteLittleEndian64(
-      bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a),
-      0x9abcdef012345678L);
+        bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef012345678L);
   }
   }
 
 
   /** Test encodeZigZag32() and encodeZigZag64(). */
   /** Test encodeZigZag32() and encodeZigZag64(). */
   public void testEncodeZigZag() throws Exception {
   public void testEncodeZigZag() throws Exception {
-    assertEquals(0, CodedOutputStream.encodeZigZag32( 0));
+    assertEquals(0, CodedOutputStream.encodeZigZag32(0));
     assertEquals(1, CodedOutputStream.encodeZigZag32(-1));
     assertEquals(1, CodedOutputStream.encodeZigZag32(-1));
-    assertEquals(2, CodedOutputStream.encodeZigZag32( 1));
+    assertEquals(2, CodedOutputStream.encodeZigZag32(1));
     assertEquals(3, CodedOutputStream.encodeZigZag32(-2));
     assertEquals(3, CodedOutputStream.encodeZigZag32(-2));
     assertEquals(0x7FFFFFFE, CodedOutputStream.encodeZigZag32(0x3FFFFFFF));
     assertEquals(0x7FFFFFFE, CodedOutputStream.encodeZigZag32(0x3FFFFFFF));
     assertEquals(0x7FFFFFFF, CodedOutputStream.encodeZigZag32(0xC0000000));
     assertEquals(0x7FFFFFFF, CodedOutputStream.encodeZigZag32(0xC0000000));
     assertEquals(0xFFFFFFFE, CodedOutputStream.encodeZigZag32(0x7FFFFFFF));
     assertEquals(0xFFFFFFFE, CodedOutputStream.encodeZigZag32(0x7FFFFFFF));
     assertEquals(0xFFFFFFFF, CodedOutputStream.encodeZigZag32(0x80000000));
     assertEquals(0xFFFFFFFF, CodedOutputStream.encodeZigZag32(0x80000000));
 
 
-    assertEquals(0, CodedOutputStream.encodeZigZag64( 0));
+    assertEquals(0, CodedOutputStream.encodeZigZag64(0));
     assertEquals(1, CodedOutputStream.encodeZigZag64(-1));
     assertEquals(1, CodedOutputStream.encodeZigZag64(-1));
-    assertEquals(2, CodedOutputStream.encodeZigZag64( 1));
+    assertEquals(2, CodedOutputStream.encodeZigZag64(1));
     assertEquals(3, CodedOutputStream.encodeZigZag64(-2));
     assertEquals(3, CodedOutputStream.encodeZigZag64(-2));
-    assertEquals(0x000000007FFFFFFEL,
-                 CodedOutputStream.encodeZigZag64(0x000000003FFFFFFFL));
-    assertEquals(0x000000007FFFFFFFL,
-                 CodedOutputStream.encodeZigZag64(0xFFFFFFFFC0000000L));
-    assertEquals(0x00000000FFFFFFFEL,
-                 CodedOutputStream.encodeZigZag64(0x000000007FFFFFFFL));
-    assertEquals(0x00000000FFFFFFFFL,
-                 CodedOutputStream.encodeZigZag64(0xFFFFFFFF80000000L));
-    assertEquals(0xFFFFFFFFFFFFFFFEL,
-                 CodedOutputStream.encodeZigZag64(0x7FFFFFFFFFFFFFFFL));
-    assertEquals(0xFFFFFFFFFFFFFFFFL,
-                 CodedOutputStream.encodeZigZag64(0x8000000000000000L));
+    assertEquals(0x000000007FFFFFFEL, CodedOutputStream.encodeZigZag64(0x000000003FFFFFFFL));
+    assertEquals(0x000000007FFFFFFFL, CodedOutputStream.encodeZigZag64(0xFFFFFFFFC0000000L));
+    assertEquals(0x00000000FFFFFFFEL, CodedOutputStream.encodeZigZag64(0x000000007FFFFFFFL));
+    assertEquals(0x00000000FFFFFFFFL, CodedOutputStream.encodeZigZag64(0xFFFFFFFF80000000L));
+    assertEquals(0xFFFFFFFFFFFFFFFEL, CodedOutputStream.encodeZigZag64(0x7FFFFFFFFFFFFFFFL));
+    assertEquals(0xFFFFFFFFFFFFFFFFL, CodedOutputStream.encodeZigZag64(0x8000000000000000L));
 
 
     // Some easier-to-verify round-trip tests.  The inputs (other than 0, 1, -1)
     // Some easier-to-verify round-trip tests.  The inputs (other than 0, 1, -1)
     // were chosen semi-randomly via keyboard bashing.
     // were chosen semi-randomly via keyboard bashing.
-    assertEquals(0,
-      CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(0)));
-    assertEquals(1,
-      CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(1)));
-    assertEquals(-1,
-      CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-1)));
-    assertEquals(14927,
-      CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(14927)));
-    assertEquals(-3612,
-      CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-3612)));
-
-    assertEquals(0,
-      CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(0)));
-    assertEquals(1,
-      CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(1)));
-    assertEquals(-1,
-      CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-1)));
-    assertEquals(14927,
-      CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(14927)));
-    assertEquals(-3612,
-      CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-3612)));
-
-    assertEquals(856912304801416L,
-      CodedOutputStream.encodeZigZag64(
-        CodedInputStream.decodeZigZag64(
-          856912304801416L)));
-    assertEquals(-75123905439571256L,
-      CodedOutputStream.encodeZigZag64(
-        CodedInputStream.decodeZigZag64(
-          -75123905439571256L)));
+    assertEquals(0, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(0)));
+    assertEquals(1, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(1)));
+    assertEquals(-1, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-1)));
+    assertEquals(14927, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(14927)));
+    assertEquals(-3612, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-3612)));
+
+    assertEquals(0, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(0)));
+    assertEquals(1, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(1)));
+    assertEquals(-1, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-1)));
+    assertEquals(14927, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(14927)));
+    assertEquals(-3612, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-3612)));
+
+    assertEquals(
+        856912304801416L,
+        CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(856912304801416L)));
+    assertEquals(
+        -75123905439571256L,
+        CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-75123905439571256L)));
   }
   }
 
 
   /** Tests writing a whole message with every field type. */
   /** Tests writing a whole message with every field type. */
   public void testWriteWholeMessage() throws Exception {
   public void testWriteWholeMessage() throws Exception {
+    final byte[] expectedBytes = TestUtil.getGoldenMessage().toByteArray();
     TestAllTypes message = TestUtil.getAllSet();
     TestAllTypes message = TestUtil.getAllSet();
 
 
-    byte[] rawBytes = message.toByteArray();
-    assertEqualBytes(TestUtil.getGoldenMessage().toByteArray(), rawBytes);
+    for (OutputType outputType : OutputType.values()) {
+      Coder coder = outputType.newCoder(message.getSerializedSize());
+      message.writeTo(coder.stream());
+      coder.stream().flush();
+      byte[] rawBytes = coder.toByteArray();
+      assertEqualBytes(outputType, expectedBytes, rawBytes);
+    }
 
 
     // Try different block sizes.
     // Try different block sizes.
     for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
     for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
-      ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
-      CodedOutputStream output =
-        CodedOutputStream.newInstance(rawOutput, blockSize);
-      message.writeTo(output);
-      output.flush();
-      assertEqualBytes(rawBytes, rawOutput.toByteArray());
+      Coder coder = OutputType.STREAM.newCoder(blockSize);
+      message.writeTo(coder.stream());
+      coder.stream().flush();
+      assertEqualBytes(OutputType.STREAM, expectedBytes, coder.toByteArray());
     }
     }
   }
   }
 
 
-  /** Tests writing a whole message with every packed field type. Ensures the
-   * wire format of packed fields is compatible with C++. */
+  /**
+   * Tests writing a whole message with every packed field type. Ensures the
+   * wire format of packed fields is compatible with C++.
+   */
   public void testWriteWholePackedFieldsMessage() throws Exception {
   public void testWriteWholePackedFieldsMessage() throws Exception {
+    byte[] expectedBytes = TestUtil.getGoldenPackedFieldsMessage().toByteArray();
     TestPackedTypes message = TestUtil.getPackedSet();
     TestPackedTypes message = TestUtil.getPackedSet();
 
 
-    byte[] rawBytes = message.toByteArray();
-    assertEqualBytes(TestUtil.getGoldenPackedFieldsMessage().toByteArray(),
-                     rawBytes);
+    for (OutputType outputType : OutputType.values()) {
+      Coder coder = outputType.newCoder(message.getSerializedSize());
+      message.writeTo(coder.stream());
+      coder.stream().flush();
+      byte[] rawBytes = coder.toByteArray();
+      assertEqualBytes(outputType, expectedBytes, rawBytes);
+    }
   }
   }
 
 
-  /** Test writing a message containing a negative enum value. This used to
+  /**
+   * Test writing a message containing a negative enum value. This used to
    * fail because the size was not properly computed as a sign-extended varint.
    * fail because the size was not properly computed as a sign-extended varint.
    */
    */
   public void testWriteMessageWithNegativeEnumValue() throws Exception {
   public void testWriteMessageWithNegativeEnumValue() throws Exception {
-    SparseEnumMessage message = SparseEnumMessage.newBuilder()
-        .setSparseEnum(TestSparseEnum.SPARSE_E) .build();
+    SparseEnumMessage message =
+        SparseEnumMessage.newBuilder().setSparseEnum(TestSparseEnum.SPARSE_E).build();
     assertTrue(message.getSparseEnum().getNumber() < 0);
     assertTrue(message.getSparseEnum().getNumber() < 0);
-    byte[] rawBytes = message.toByteArray();
-    SparseEnumMessage message2 = SparseEnumMessage.parseFrom(rawBytes);
-    assertEquals(TestSparseEnum.SPARSE_E, message2.getSparseEnum());
+    for (OutputType outputType : OutputType.values()) {
+      Coder coder = outputType.newCoder(message.getSerializedSize());
+      message.writeTo(coder.stream());
+      coder.stream().flush();
+      byte[] rawBytes = coder.toByteArray();
+      SparseEnumMessage message2 = SparseEnumMessage.parseFrom(rawBytes);
+      assertEquals(TestSparseEnum.SPARSE_E, message2.getSparseEnum());
+    }
   }
   }
 
 
   /** Test getTotalBytesWritten() */
   /** Test getTotalBytesWritten() */
   public void testGetTotalBytesWritten() throws Exception {
   public void testGetTotalBytesWritten() throws Exception {
-    final int BUFFER_SIZE = 4 * 1024;
-    ByteArrayOutputStream outputStream = new ByteArrayOutputStream(BUFFER_SIZE);
-    CodedOutputStream codedStream = CodedOutputStream.newInstance(outputStream);
+    Coder coder = OutputType.STREAM.newCoder(4 * 1024);
+
+    // Write some some bytes (more than the buffer can hold) and verify that totalWritten
+    // is correct.
     byte[] value = "abcde".getBytes(Internal.UTF_8);
     byte[] value = "abcde".getBytes(Internal.UTF_8);
     for (int i = 0; i < 1024; ++i) {
     for (int i = 0; i < 1024; ++i) {
-      codedStream.writeRawBytes(value, 0, value.length);
+      coder.stream().writeRawBytes(value, 0, value.length);
     }
     }
+    assertEquals(value.length * 1024, coder.stream().getTotalBytesWritten());
+
+    // Now write an encoded string.
     String string =
     String string =
         "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
         "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
     // Ensure we take the slower fast path.
     // Ensure we take the slower fast path.
-    assertTrue(CodedOutputStream.computeRawVarint32Size(string.length())
-        != CodedOutputStream.computeRawVarint32Size(string.length() * Utf8.MAX_BYTES_PER_CHAR));
-    
-    codedStream.writeStringNoTag(string);
+    assertTrue(CodedOutputStream.computeUInt32SizeNoTag(string.length())
+        != CodedOutputStream.computeUInt32SizeNoTag(string.length() * Utf8.MAX_BYTES_PER_CHAR));
+
+    coder.stream().writeStringNoTag(string);
     int stringSize = CodedOutputStream.computeStringSizeNoTag(string);
     int stringSize = CodedOutputStream.computeStringSizeNoTag(string);
-    
-    // Make sure we have written more bytes than the buffer could hold. This is
-    // to make the test complete.
-    assertTrue(codedStream.getTotalBytesWritten() > BUFFER_SIZE);
-    
+
     // Verify that the total bytes written is correct
     // Verify that the total bytes written is correct
-    assertEquals((value.length * 1024) + stringSize, codedStream.getTotalBytesWritten());
+    assertEquals((value.length * 1024) + stringSize, coder.stream().getTotalBytesWritten());
   }
   }
-  
+
   // TODO(dweis): Write a comprehensive test suite for CodedOutputStream that covers more than just
   // TODO(dweis): Write a comprehensive test suite for CodedOutputStream that covers more than just
   //    this case.
   //    this case.
   public void testWriteStringNoTag_fastpath() throws Exception {
   public void testWriteStringNoTag_fastpath() throws Exception {
@@ -390,14 +405,16 @@ public class CodedOutputStreamTest extends TestCase {
       string += threeBytesPer;
       string += threeBytesPer;
     }
     }
     // These checks ensure we will tickle the slower fast path.
     // These checks ensure we will tickle the slower fast path.
-    assertEquals(1, CodedOutputStream.computeRawVarint32Size(string.length()));
+    assertEquals(1, CodedOutputStream.computeUInt32SizeNoTag(string.length()));
     assertEquals(
     assertEquals(
-        2, CodedOutputStream.computeRawVarint32Size(string.length() * Utf8.MAX_BYTES_PER_CHAR));
+        2, CodedOutputStream.computeUInt32SizeNoTag(string.length() * Utf8.MAX_BYTES_PER_CHAR));
     assertEquals(bufferSize, string.length() * Utf8.MAX_BYTES_PER_CHAR);
     assertEquals(bufferSize, string.length() * Utf8.MAX_BYTES_PER_CHAR);
-    
-    CodedOutputStream output =
-        CodedOutputStream.newInstance(ByteBuffer.allocate(bufferSize), bufferSize);
-    output.writeStringNoTag(string);
+
+    for (OutputType outputType : OutputType.values()) {
+      Coder coder = outputType.newCoder(bufferSize + 2);
+      coder.stream().writeStringNoTag(string);
+      coder.stream().flush();
+    }
   }
   }
 
 
   public void testWriteToByteBuffer() throws Exception {
   public void testWriteToByteBuffer() throws Exception {
@@ -464,83 +481,296 @@ public class CodedOutputStreamTest extends TestCase {
     byte[] destination = new byte[4];
     byte[] destination = new byte[4];
     CodedOutputStream codedStream = CodedOutputStream.newInstance(destination);
     CodedOutputStream codedStream = CodedOutputStream.newInstance(destination);
     codedStream.writeByteArrayNoTag(fullArray, 2, 2);
     codedStream.writeByteArrayNoTag(fullArray, 2, 2);
-    assertEqualBytes(bytes(0x02, 0x33, 0x44, 0x00), destination);
+    assertEqualBytes(OutputType.ARRAY, bytes(0x02, 0x33, 0x44, 0x00), destination);
     assertEquals(3, codedStream.getTotalBytesWritten());
     assertEquals(3, codedStream.getTotalBytesWritten());
   }
   }
-  
+
+  public void testSerializeUtf8_MultipleSmallWrites() throws Exception {
+    final String source = "abcdefghijklmnopqrstuvwxyz";
+
+    // Generate the expected output if the source string is written 2 bytes at a time.
+    ByteArrayOutputStream expectedBytesStream = new ByteArrayOutputStream();
+    for (int pos = 0; pos < source.length(); pos += 2) {
+      String substr = source.substring(pos, pos + 2);
+      expectedBytesStream.write(2);
+      expectedBytesStream.write(substr.getBytes(Internal.UTF_8));
+    }
+    final byte[] expectedBytes = expectedBytesStream.toByteArray();
+
+    // For each output type, write the source string 2 bytes at a time and verify the output.
+    for (OutputType outputType : OutputType.values()) {
+      Coder coder = outputType.newCoder(expectedBytes.length);
+      for (int pos = 0; pos < source.length(); pos += 2) {
+        String substr = source.substring(pos, pos + 2);
+        coder.stream().writeStringNoTag(substr);
+      }
+      coder.stream().flush();
+      assertEqualBytes(outputType, expectedBytes, coder.toByteArray());
+    }
+  }
+
   public void testSerializeInvalidUtf8() throws Exception {
   public void testSerializeInvalidUtf8() throws Exception {
-    String[] invalidStrings = new String[] {
-        newString(Character.MIN_HIGH_SURROGATE),
-        "foobar" + newString(Character.MIN_HIGH_SURROGATE),
-        newString(Character.MIN_LOW_SURROGATE),
+    String[] invalidStrings = new String[] {newString(Character.MIN_HIGH_SURROGATE),
+        "foobar" + newString(Character.MIN_HIGH_SURROGATE), newString(Character.MIN_LOW_SURROGATE),
         "foobar" + newString(Character.MIN_LOW_SURROGATE),
         "foobar" + newString(Character.MIN_LOW_SURROGATE),
-        newString(Character.MIN_HIGH_SURROGATE, Character.MIN_HIGH_SURROGATE)
-    };
-    
+        newString(Character.MIN_HIGH_SURROGATE, Character.MIN_HIGH_SURROGATE)};
+
     CodedOutputStream outputWithStream = CodedOutputStream.newInstance(new ByteArrayOutputStream());
     CodedOutputStream outputWithStream = CodedOutputStream.newInstance(new ByteArrayOutputStream());
     CodedOutputStream outputWithArray = CodedOutputStream.newInstance(new byte[10000]);
     CodedOutputStream outputWithArray = CodedOutputStream.newInstance(new byte[10000]);
+    CodedOutputStream outputWithByteBuffer =
+        CodedOutputStream.newInstance(ByteBuffer.allocate(10000));
     for (String s : invalidStrings) {
     for (String s : invalidStrings) {
       // TODO(dweis): These should all fail; instead they are corrupting data.
       // TODO(dweis): These should all fail; instead they are corrupting data.
       CodedOutputStream.computeStringSizeNoTag(s);
       CodedOutputStream.computeStringSizeNoTag(s);
       outputWithStream.writeStringNoTag(s);
       outputWithStream.writeStringNoTag(s);
       outputWithArray.writeStringNoTag(s);
       outputWithArray.writeStringNoTag(s);
+      outputWithByteBuffer.writeStringNoTag(s);
     }
     }
   }
   }
-  
-  private static String newString(char... chars) {
-    return new String(chars);
+
+  // TODO(nathanmittler): This test can be deleted once we properly throw IOException while
+  // encoding invalid UTF-8 strings.
+  public void testSerializeInvalidUtf8FollowedByOutOfSpace() throws Exception {
+    final int notEnoughBytes = 4;
+    CodedOutputStream outputWithArray = CodedOutputStream.newInstance(new byte[notEnoughBytes]);
+    CodedOutputStream outputWithByteBuffer =
+        CodedOutputStream.newInstance(ByteBuffer.allocate(notEnoughBytes));
+
+    String invalidString = newString(Character.MIN_HIGH_SURROGATE, 'f', 'o', 'o', 'b', 'a', 'r');
+    try {
+      outputWithArray.writeStringNoTag(invalidString);
+      fail("Expected OutOfSpaceException");
+    } catch (OutOfSpaceException e) {
+      assertTrue(e.getCause() instanceof IndexOutOfBoundsException);
+    }
+    try {
+      outputWithByteBuffer.writeStringNoTag(invalidString);
+      fail("Expected OutOfSpaceException");
+    } catch (OutOfSpaceException e) {
+      assertTrue(e.getCause() instanceof IndexOutOfBoundsException);
+    }
   }
   }
 
 
   /** Regression test for https://github.com/google/protobuf/issues/292 */
   /** Regression test for https://github.com/google/protobuf/issues/292 */
   public void testCorrectExceptionThrowWhenEncodingStringsWithoutEnoughSpace() throws Exception {
   public void testCorrectExceptionThrowWhenEncodingStringsWithoutEnoughSpace() throws Exception {
     String testCase = "Foooooooo";
     String testCase = "Foooooooo";
-    assertEquals(CodedOutputStream.computeRawVarint32Size(testCase.length()),
-        CodedOutputStream.computeRawVarint32Size(testCase.length() * 3));
+    assertEquals(
+        CodedOutputStream.computeUInt32SizeNoTag(testCase.length()),
+        CodedOutputStream.computeUInt32SizeNoTag(testCase.length() * 3));
     assertEquals(11, CodedOutputStream.computeStringSize(1, testCase));
     assertEquals(11, CodedOutputStream.computeStringSize(1, testCase));
     // Tag is one byte, varint describing string length is 1 byte, string length is 9 bytes.
     // Tag is one byte, varint describing string length is 1 byte, string length is 9 bytes.
     // An array of size 1 will cause a failure when trying to write the varint.
     // An array of size 1 will cause a failure when trying to write the varint.
-    for (int i = 0; i < 11; i++) {
-      CodedOutputStream output = CodedOutputStream.newInstance(new byte[i]);
-      try {
-        output.writeString(1, testCase);
-        fail("Should have thrown an out of space exception");
-      } catch (CodedOutputStream.OutOfSpaceException expected) {}
+    for (OutputType outputType :
+        new OutputType[] {OutputType.ARRAY, OutputType.NIO_HEAP, OutputType.NIO_DIRECT}) {
+      for (int i = 0; i < 11; i++) {
+        Coder coder = outputType.newCoder(i);
+        try {
+          coder.stream().writeString(1, testCase);
+          fail("Should have thrown an out of space exception");
+        } catch (CodedOutputStream.OutOfSpaceException expected) {
+        }
+      }
     }
     }
   }
   }
-  
+
   public void testDifferentStringLengths() throws Exception {
   public void testDifferentStringLengths() throws Exception {
     // Test string serialization roundtrip using strings of the following lengths,
     // Test string serialization roundtrip using strings of the following lengths,
     // with ASCII and Unicode characters requiring different UTF-8 byte counts per
     // with ASCII and Unicode characters requiring different UTF-8 byte counts per
     // char, hence causing the length delimiter varint to sometimes require more
     // char, hence causing the length delimiter varint to sometimes require more
     // bytes for the Unicode strings than the ASCII string of the same length.
     // bytes for the Unicode strings than the ASCII string of the same length.
     int[] lengths = new int[] {
     int[] lengths = new int[] {
-            0,
-            1,
-            (1 << 4) - 1,  // 1 byte for ASCII and Unicode
-            (1 << 7) - 1,  // 1 byte for ASCII, 2 bytes for Unicode
-            (1 << 11) - 1, // 2 bytes for ASCII and Unicode
-            (1 << 14) - 1, // 2 bytes for ASCII, 3 bytes for Unicode
-            (1 << 17) - 1, // 3 bytes for ASCII and Unicode
+        0,
+        1,
+        (1 << 4) - 1, // 1 byte for ASCII and Unicode
+        (1 << 7) - 1, // 1 byte for ASCII, 2 bytes for Unicode
+        (1 << 11) - 1, // 2 bytes for ASCII and Unicode
+        (1 << 14) - 1, // 2 bytes for ASCII, 3 bytes for Unicode
+        (1 << 17) - 1,
+        // 3 bytes for ASCII and Unicode
     };
     };
-    for (int i : lengths) {
-      testEncodingOfString('q', i);      // 1 byte per char
-      testEncodingOfString('\u07FF', i); // 2 bytes per char
-      testEncodingOfString('\u0981', i); // 3 bytes per char
+    for (OutputType outputType : OutputType.values()) {
+      for (int i : lengths) {
+        testEncodingOfString(outputType, 'q', i); // 1 byte per char
+        testEncodingOfString(outputType, '\u07FF', i); // 2 bytes per char
+        testEncodingOfString(outputType, '\u0981', i); // 3 bytes per char
+      }
     }
     }
   }
   }
 
 
-  private void testEncodingOfString(char c, int length) throws Exception {
+  public void testNioEncodersWithInitialOffsets() throws Exception {
+    String value = "abc";
+    for (Coder coder : new Coder[] {new NioHeapCoder(10, 2), new NioDirectCoder(10, 2)}) {
+      coder.stream().writeStringNoTag(value);
+      coder.stream().flush();
+      assertEqualBytes(coder.getOutputType(), new byte[]{3, 'a', 'b', 'c'}, coder.toByteArray());
+    }
+  }
+
+  /**
+   * Parses the given bytes using writeRawLittleEndian32() and checks
+   * that the result matches the given value.
+   */
+  private static void assertWriteLittleEndian32(byte[] data, int value) throws Exception {
+    for (OutputType outputType : OutputType.values()) {
+      Coder coder = outputType.newCoder(data.length);
+      coder.stream().writeFixed32NoTag(value);
+      coder.stream().flush();
+      assertEqualBytes(outputType, data, coder.toByteArray());
+    }
+
+    // Try different block sizes.
+    for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+      Coder coder = OutputType.STREAM.newCoder(blockSize);
+      coder.stream().writeFixed32NoTag(value);
+      coder.stream().flush();
+      assertEqualBytes(OutputType.STREAM, data, coder.toByteArray());
+    }
+  }
+
+  /**
+   * Parses the given bytes using writeRawLittleEndian64() and checks
+   * that the result matches the given value.
+   */
+  private static void assertWriteLittleEndian64(byte[] data, long value) throws Exception {
+    for (OutputType outputType : OutputType.values()) {
+      Coder coder = outputType.newCoder(data.length);
+      coder.stream().writeFixed64NoTag(value);
+      coder.stream().flush();
+      assertEqualBytes(outputType, data, coder.toByteArray());
+    }
+
+    // Try different block sizes.
+    for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+      Coder coder = OutputType.STREAM.newCoder(blockSize);
+      coder.stream().writeFixed64NoTag(value);
+      coder.stream().flush();
+      assertEqualBytes(OutputType.STREAM, data, coder.toByteArray());
+    }
+  }
+
+  private static String newString(char... chars) {
+    return new String(chars);
+  }
+
+  private static void testEncodingOfString(OutputType outputType, char c, int length)
+      throws Exception {
     String fullString = fullString(c, length);
     String fullString = fullString(c, length);
-    TestAllTypes testAllTypes = TestAllTypes.newBuilder()
-        .setOptionalString(fullString)
-        .build();
+    TestAllTypes testAllTypes = TestAllTypes.newBuilder().setOptionalString(fullString).build();
+    Coder coder = outputType.newCoder(testAllTypes.getSerializedSize());
+    testAllTypes.writeTo(coder.stream());
+    coder.stream().flush();
     assertEquals(
     assertEquals(
-        fullString, TestAllTypes.parseFrom(testAllTypes.toByteArray()).getOptionalString());
+        "OuputType: " + outputType,
+        fullString,
+        TestAllTypes.parseFrom(coder.toByteArray()).getOptionalString());
   }
   }
 
 
-  private String fullString(char c, int length) {
+  private static String fullString(char c, int length) {
     char[] result = new char[length];
     char[] result = new char[length];
     Arrays.fill(result, c);
     Arrays.fill(result, c);
     return new String(result);
     return new String(result);
   }
   }
+
+  /**
+   * Helper to construct a byte array from a bunch of bytes.  The inputs are
+   * actually ints so that I can use hex notation and not get stupid errors
+   * about precision.
+   */
+  private static byte[] bytes(int... bytesAsInts) {
+    byte[] bytes = new byte[bytesAsInts.length];
+    for (int i = 0; i < bytesAsInts.length; i++) {
+      bytes[i] = (byte) bytesAsInts[i];
+    }
+    return bytes;
+  }
+
+  /** Arrays.asList() does not work with arrays of primitives.  :( */
+  private static List<Byte> toList(byte[] bytes) {
+    List<Byte> result = new ArrayList<Byte>();
+    for (byte b : bytes) {
+      result.add(b);
+    }
+    return result;
+  }
+
+  private static void assertEqualBytes(OutputType outputType, byte[] a, byte[] b) {
+    assertEquals(outputType.name(), toList(a), toList(b));
+  }
+
+  /**
+   * Writes the given value using writeRawVarint32() and writeRawVarint64() and
+   * checks that the result matches the given bytes.
+   */
+  private static void assertWriteVarint(byte[] data, long value) throws Exception {
+    for (OutputType outputType : OutputType.values()) {
+      // Only test 32-bit write if the value fits into an int.
+      if (value == (int) value) {
+        Coder coder = outputType.newCoder(10);
+        coder.stream().writeUInt32NoTag((int) value);
+        coder.stream().flush();
+        assertEqualBytes(outputType, data, coder.toByteArray());
+
+        // Also try computing size.
+        assertEquals(data.length, CodedOutputStream.computeUInt32SizeNoTag((int) value));
+      }
+
+      {
+        Coder coder = outputType.newCoder(10);
+        coder.stream().writeUInt64NoTag(value);
+        coder.stream().flush();
+        assertEqualBytes(outputType, data, coder.toByteArray());
+
+        // Also try computing size.
+        assertEquals(data.length, CodedOutputStream.computeUInt64SizeNoTag(value));
+      }
+    }
+
+    // Try different block sizes.
+    for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+      // Only test 32-bit write if the value fits into an int.
+      if (value == (int) value) {
+        Coder coder = OutputType.STREAM.newCoder(blockSize);
+        coder.stream().writeUInt64NoTag((int) value);
+        coder.stream().flush();
+        assertEqualBytes(OutputType.STREAM, data, coder.toByteArray());
+
+        ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+        CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, blockSize);
+        output.writeUInt32NoTag((int) value);
+        output.flush();
+        assertEqualBytes(OutputType.STREAM, data, rawOutput.toByteArray());
+      }
+
+      {
+        Coder coder = OutputType.STREAM.newCoder(blockSize);
+        coder.stream().writeUInt64NoTag(value);
+        coder.stream().flush();
+        assertEqualBytes(OutputType.STREAM, data, coder.toByteArray());
+      }
+    }
+  }
+
+  private static void assertVarintRoundTrip(OutputType outputType, long value) throws Exception {
+    {
+      Coder coder = outputType.newCoder(10);
+      coder.stream().writeUInt64NoTag(value);
+      coder.stream().flush();
+      byte[] bytes = coder.toByteArray();
+      assertEquals(
+          outputType.name(), bytes.length, CodedOutputStream.computeUInt64SizeNoTag(value));
+      CodedInputStream input = CodedInputStream.newInstance(new ByteArrayInputStream(bytes));
+      assertEquals(outputType.name(), value, input.readRawVarint64());
+    }
+
+    if (value == (int) value) {
+      Coder coder = outputType.newCoder(10);
+      coder.stream().writeUInt32NoTag((int) value);
+      coder.stream().flush();
+      byte[] bytes = coder.toByteArray();
+      assertEquals(
+          outputType.name(), bytes.length, CodedOutputStream.computeUInt32SizeNoTag((int) value));
+      CodedInputStream input = CodedInputStream.newInstance(new ByteArrayInputStream(bytes));
+      assertEquals(outputType.name(), value, input.readRawVarint32());
+    }
+  }
 }
 }

+ 0 - 14
java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java

@@ -73,20 +73,6 @@ public class DoubleArrayListTest extends TestCase {
     assertImmutable(list);
     assertImmutable(list);
   }
   }
   
   
-  public void testCopyConstructor() {
-    DoubleArrayList copy = new DoubleArrayList(TERTIARY_LIST);
-    assertEquals(TERTIARY_LIST, copy);
-
-    copy = new DoubleArrayList(DoubleArrayList.emptyList());
-    assertEquals(DoubleArrayList.emptyList(), copy);
-    
-    copy = new DoubleArrayList(asList(1D, 2D, 3D));
-    assertEquals(asList(1D, 2D, 3D), copy);
-
-    copy = new DoubleArrayList(Collections.<Double>emptyList());
-    assertEquals(DoubleArrayList.emptyList(), copy);
-  }
-  
   public void testModificationWithIteration() {
   public void testModificationWithIteration() {
     list.addAll(asList(1D, 2D, 3D, 4D));
     list.addAll(asList(1D, 2D, 3D, 4D));
     Iterator<Double> iterator = list.iterator();
     Iterator<Double> iterator = list.iterator();

+ 0 - 14
java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java

@@ -73,20 +73,6 @@ public class FloatArrayListTest extends TestCase {
     assertImmutable(list);
     assertImmutable(list);
   }
   }
   
   
-  public void testCopyConstructor() {
-    FloatArrayList copy = new FloatArrayList(TERTIARY_LIST);
-    assertEquals(TERTIARY_LIST, copy);
-
-    copy = new FloatArrayList(FloatArrayList.emptyList());
-    assertEquals(FloatArrayList.emptyList(), copy);
-    
-    copy = new FloatArrayList(asList(1F, 2F, 3F));
-    assertEquals(asList(1F, 2F, 3F), copy);
-
-    copy = new FloatArrayList(Collections.<Float>emptyList());
-    assertEquals(FloatArrayList.emptyList(), copy);
-  }
-  
   public void testModificationWithIteration() {
   public void testModificationWithIteration() {
     list.addAll(asList(1F, 2F, 3F, 4F));
     list.addAll(asList(1F, 2F, 3F, 4F));
     Iterator<Float> iterator = list.iterator();
     Iterator<Float> iterator = list.iterator();

+ 1 - 1
java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java

@@ -41,7 +41,7 @@ package com.google.protobuf;
  */
  */
 public class ForceFieldBuildersPreRun implements Runnable {
 public class ForceFieldBuildersPreRun implements Runnable {
 
 
-  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  @Override
   public void run() {
   public void run() {
     GeneratedMessage.enableAlwaysUseFieldBuildersForTesting();
     GeneratedMessage.enableAlwaysUseFieldBuildersForTesting();
   }
   }

+ 4 - 4
java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java

@@ -723,7 +723,7 @@ public class GeneratedMessageTest extends TestCase {
 
 
   public void testLiteExtensionMessageOrBuilder() throws Exception {
   public void testLiteExtensionMessageOrBuilder() throws Exception {
     TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
     TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
-    TestUtil.setAllExtensions(builder);
+    TestUtilLite.setAllExtensions(builder);
     TestUtil.assertAllExtensionsSet(builder);
     TestUtil.assertAllExtensionsSet(builder);
 
 
     TestAllExtensionsLite message = builder.build();
     TestAllExtensionsLite message = builder.build();
@@ -732,8 +732,8 @@ public class GeneratedMessageTest extends TestCase {
 
 
   public void testLiteExtensionRepeatedSetters() throws Exception {
   public void testLiteExtensionRepeatedSetters() throws Exception {
     TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
     TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
-    TestUtil.setAllExtensions(builder);
-    TestUtil.modifyRepeatedExtensions(builder);
+    TestUtilLite.setAllExtensions(builder);
+    TestUtilLite.modifyRepeatedExtensions(builder);
     TestUtil.assertRepeatedExtensionsModified(builder);
     TestUtil.assertRepeatedExtensionsModified(builder);
 
 
     TestAllExtensionsLite message = builder.build();
     TestAllExtensionsLite message = builder.build();
@@ -760,7 +760,7 @@ public class GeneratedMessageTest extends TestCase {
   }
   }
 
 
   public void testLiteExtensionCopy() throws Exception {
   public void testLiteExtensionCopy() throws Exception {
-    TestAllExtensionsLite original = TestUtil.getAllLiteExtensionsSet();
+    TestAllExtensionsLite original = TestUtilLite.getAllLiteExtensionsSet();
     TestAllExtensionsLite copy =
     TestAllExtensionsLite copy =
         TestAllExtensionsLite.newBuilder(original).build();
         TestAllExtensionsLite.newBuilder(original).build();
     TestUtil.assertAllExtensionsSet(copy);
     TestUtil.assertAllExtensionsSet(copy);

+ 0 - 14
java/core/src/test/java/com/google/protobuf/IntArrayListTest.java

@@ -72,20 +72,6 @@ public class IntArrayListTest extends TestCase {
     list.makeImmutable();
     list.makeImmutable();
     assertImmutable(list);
     assertImmutable(list);
   }
   }
-  
-  public void testCopyConstructor() {
-    IntArrayList copy = new IntArrayList(TERTIARY_LIST);
-    assertEquals(TERTIARY_LIST, copy);
-
-    copy = new IntArrayList(IntArrayList.emptyList());
-    assertEquals(IntArrayList.emptyList(), copy);
-    
-    copy = new IntArrayList(asList(1, 2, 3));
-    assertEquals(asList(1, 2, 3), copy);
-
-    copy = new IntArrayList(Collections.<Integer>emptyList());
-    assertEquals(IntArrayList.emptyList(), copy);
-  }
 
 
   public void testModificationWithIteration() {
   public void testModificationWithIteration() {
     list.addAll(asList(1, 2, 3, 4));
     list.addAll(asList(1, 2, 3, 4));

+ 660 - 32
java/core/src/test/java/com/google/protobuf/LiteTest.java

@@ -33,17 +33,25 @@ package com.google.protobuf;
 import static java.util.Collections.emptyList;
 import static java.util.Collections.emptyList;
 import static java.util.Collections.singletonList;
 import static java.util.Collections.singletonList;
 
 
+import com.google.protobuf.UnittestImportLite.ImportEnumLite;
+import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
 import com.google.protobuf.UnittestLite;
 import com.google.protobuf.UnittestLite;
 import com.google.protobuf.UnittestLite.ForeignEnumLite;
 import com.google.protobuf.UnittestLite.ForeignEnumLite;
 import com.google.protobuf.UnittestLite.ForeignMessageLite;
 import com.google.protobuf.UnittestLite.ForeignMessageLite;
 import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
 import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
 import com.google.protobuf.UnittestLite.TestAllTypesLite;
 import com.google.protobuf.UnittestLite.TestAllTypesLite;
+import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum;
 import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage;
 import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage;
 import com.google.protobuf.UnittestLite.TestAllTypesLite.OneofFieldCase;
 import com.google.protobuf.UnittestLite.TestAllTypesLite.OneofFieldCase;
 import com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup;
 import com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup;
 import com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup;
 import com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup;
 import com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder;
 import com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder;
 import com.google.protobuf.UnittestLite.TestNestedExtensionLite;
 import com.google.protobuf.UnittestLite.TestNestedExtensionLite;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Bar;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestOneofEquals;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOneof;
 
 
 import junit.framework.TestCase;
 import junit.framework.TestCase;
 
 
@@ -59,6 +67,7 @@ import java.io.ObjectOutputStream;
  * @author kenton@google.com Kenton Varda
  * @author kenton@google.com Kenton Varda
  */
  */
 public class LiteTest extends TestCase {
 public class LiteTest extends TestCase {
+  @Override
   public void setUp() throws Exception {
   public void setUp() throws Exception {
     // Test that nested extensions are initialized correctly even if the outer
     // Test that nested extensions are initialized correctly even if the outer
     // class has not been accessed directly.  This was once a bug with lite
     // class has not been accessed directly.  This was once a bug with lite
@@ -302,11 +311,9 @@ public class LiteTest extends TestCase {
     assertEquals(
     assertEquals(
         ForeignMessageLite.getDefaultInstance(),
         ForeignMessageLite.getDefaultInstance(),
         message.getOptionalForeignMessage());
         message.getOptionalForeignMessage());
-    // LITE_RUNTIME doesn't implement equals so we compare on a property and
-    // ensure the property isn't set on foreignMessage.
-    assertEquals(3, builder.getOptionalForeignMessage().getC());
+    assertEquals(foreignMessageBuilder.build(), builder.getOptionalForeignMessage());
     messageAfterBuild = builder.build();
     messageAfterBuild = builder.build();
-    assertEquals(3, messageAfterBuild.getOptionalForeignMessage().getC());
+    assertEquals(foreignMessageBuilder.build(), messageAfterBuild.getOptionalForeignMessage());
     assertEquals(
     assertEquals(
         ForeignMessageLite.getDefaultInstance(),
         ForeignMessageLite.getDefaultInstance(),
         message.getOptionalForeignMessage());
         message.getOptionalForeignMessage());
@@ -314,7 +321,7 @@ public class LiteTest extends TestCase {
     assertEquals(
     assertEquals(
         ForeignMessageLite.getDefaultInstance(),
         ForeignMessageLite.getDefaultInstance(),
         builder.getOptionalForeignMessage());
         builder.getOptionalForeignMessage());
-    assertEquals(3, messageAfterBuild.getOptionalForeignMessage().getC());
+    assertEquals(foreignMessageBuilder.build(), messageAfterBuild.getOptionalForeignMessage());
 
 
     message = builder.build();
     message = builder.build();
     OptionalGroup optionalGroup = OptionalGroup.newBuilder()
     OptionalGroup optionalGroup = OptionalGroup.newBuilder()
@@ -339,17 +346,15 @@ public class LiteTest extends TestCase {
     builder.setOptionalGroup(optionalGroupBuilder);
     builder.setOptionalGroup(optionalGroupBuilder);
     assertEquals(
     assertEquals(
         OptionalGroup.getDefaultInstance(), message.getOptionalGroup());
         OptionalGroup.getDefaultInstance(), message.getOptionalGroup());
-    // LITE_RUNTIME doesn't implement equals so we compare on a property and
-    // ensure the property isn't set on optionalGroup.
-    assertEquals(3, builder.getOptionalGroup().getA());
+    assertEquals(optionalGroupBuilder.build(), builder.getOptionalGroup());
     messageAfterBuild = builder.build();
     messageAfterBuild = builder.build();
-    assertEquals(3, messageAfterBuild.getOptionalGroup().getA());
+    assertEquals(optionalGroupBuilder.build(), messageAfterBuild.getOptionalGroup());
     assertEquals(
     assertEquals(
         OptionalGroup.getDefaultInstance(), message.getOptionalGroup());
         OptionalGroup.getDefaultInstance(), message.getOptionalGroup());
     builder.clearOptionalGroup();
     builder.clearOptionalGroup();
     assertEquals(
     assertEquals(
         OptionalGroup.getDefaultInstance(), builder.getOptionalGroup());
         OptionalGroup.getDefaultInstance(), builder.getOptionalGroup());
-    assertEquals(3, messageAfterBuild.getOptionalGroup().getA());
+    assertEquals(optionalGroupBuilder.build(), messageAfterBuild.getOptionalGroup());
 
 
     message = builder.build();
     message = builder.build();
     builder.setOptionalInt32(1);
     builder.setOptionalInt32(1);
@@ -400,17 +405,16 @@ public class LiteTest extends TestCase {
     assertEquals(
     assertEquals(
         NestedMessage.getDefaultInstance(),
         NestedMessage.getDefaultInstance(),
         message.getOptionalLazyMessage());
         message.getOptionalLazyMessage());
-    // LITE_RUNTIME doesn't implement equals so we compare on a property.
-    assertEquals(3, builder.getOptionalLazyMessage().getBb());
+    assertEquals(nestedMessageBuilder.build(), builder.getOptionalLazyMessage());
     messageAfterBuild = builder.build();
     messageAfterBuild = builder.build();
-    assertEquals(3, messageAfterBuild.getOptionalLazyMessage().getBb());
+    assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getOptionalLazyMessage());
     assertEquals(
     assertEquals(
         NestedMessage.getDefaultInstance(),
         NestedMessage.getDefaultInstance(),
         message.getOptionalLazyMessage());
         message.getOptionalLazyMessage());
     builder.clearOptionalLazyMessage();
     builder.clearOptionalLazyMessage();
     assertEquals(
     assertEquals(
         NestedMessage.getDefaultInstance(), builder.getOptionalLazyMessage());
         NestedMessage.getDefaultInstance(), builder.getOptionalLazyMessage());
-    assertEquals(3, messageAfterBuild.getOptionalLazyMessage().getBb());
+    assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getOptionalLazyMessage());
 
 
     message = builder.build();
     message = builder.build();
     builder.setOptionalSfixed32(1);
     builder.setOptionalSfixed32(1);
@@ -1100,8 +1104,7 @@ public class LiteTest extends TestCase {
     assertEquals(0, message.getRepeatedForeignMessageCount());
     assertEquals(0, message.getRepeatedForeignMessageCount());
     builder.setRepeatedForeignMessage(
     builder.setRepeatedForeignMessage(
         0, ForeignMessageLite.getDefaultInstance());
         0, ForeignMessageLite.getDefaultInstance());
-    // LITE_RUNTIME doesn't implement equals so we compare on a property.
-    assertEquals(3, messageAfterBuild.getRepeatedForeignMessage(0).getC());
+    assertEquals(foreignMessageBuilder.build(), messageAfterBuild.getRepeatedForeignMessage(0));
     assertEquals(
     assertEquals(
         ForeignMessageLite.getDefaultInstance(),
         ForeignMessageLite.getDefaultInstance(),
         builder.getRepeatedForeignMessage(0));
         builder.getRepeatedForeignMessage(0));
@@ -1114,8 +1117,7 @@ public class LiteTest extends TestCase {
     builder.setRepeatedForeignMessage(0, foreignMessageBuilder);
     builder.setRepeatedForeignMessage(0, foreignMessageBuilder);
     assertEquals(
     assertEquals(
         foreignMessage, messageAfterBuild.getRepeatedForeignMessage(0));
         foreignMessage, messageAfterBuild.getRepeatedForeignMessage(0));
-    // LITE_RUNTIME doesn't implement equals so we compare on a property.
-    assertEquals(3, builder.getRepeatedForeignMessage(0).getC());
+    assertEquals(foreignMessageBuilder.build(), builder.getRepeatedForeignMessage(0));
     builder.clearRepeatedForeignMessage();
     builder.clearRepeatedForeignMessage();
 
 
     message = builder.build();
     message = builder.build();
@@ -1148,9 +1150,7 @@ public class LiteTest extends TestCase {
     messageAfterBuild = builder.build();
     messageAfterBuild = builder.build();
     assertEquals(0, message.getRepeatedGroupCount());
     assertEquals(0, message.getRepeatedGroupCount());
     builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance());
     builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance());
-    // LITE_RUNTIME doesn't implement equals so we compare on a property and
-    // ensure the property isn't set on repeatedGroup.
-    assertEquals(3, messageAfterBuild.getRepeatedGroup(0).getA());
+    assertEquals(repeatedGroupBuilder.build(), messageAfterBuild.getRepeatedGroup(0));
     assertEquals(
     assertEquals(
         RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0));
         RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0));
     builder.clearRepeatedGroup();
     builder.clearRepeatedGroup();
@@ -1160,9 +1160,7 @@ public class LiteTest extends TestCase {
     messageAfterBuild = builder.build();
     messageAfterBuild = builder.build();
     assertEquals(0, message.getRepeatedGroupCount());
     assertEquals(0, message.getRepeatedGroupCount());
     builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance());
     builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance());
-    // LITE_RUNTIME doesn't implement equals so we compare on a property and
-    // ensure the property isn't set on repeatedGroup.
-    assertEquals(3, messageAfterBuild.getRepeatedGroup(0).getA());
+    assertEquals(repeatedGroupBuilder.build(), messageAfterBuild.getRepeatedGroup(0));
     assertEquals(
     assertEquals(
         RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0));
         RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0));
     builder.clearRepeatedGroup();
     builder.clearRepeatedGroup();
@@ -1210,9 +1208,7 @@ public class LiteTest extends TestCase {
     messageAfterBuild = builder.build();
     messageAfterBuild = builder.build();
     assertEquals(0, message.getRepeatedLazyMessageCount());
     assertEquals(0, message.getRepeatedLazyMessageCount());
     builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance());
     builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance());
-    // LITE_RUNTIME doesn't implement equals so we compare on a property and
-    // ensure the property isn't set on repeatedGroup.
-    assertEquals(3, messageAfterBuild.getRepeatedLazyMessage(0).getBb());
+    assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getRepeatedLazyMessage(0));
     assertEquals(
     assertEquals(
         NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0));
         NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0));
     builder.clearRepeatedLazyMessage();
     builder.clearRepeatedLazyMessage();
@@ -1222,9 +1218,7 @@ public class LiteTest extends TestCase {
     messageAfterBuild = builder.build();
     messageAfterBuild = builder.build();
     assertEquals(0, message.getRepeatedLazyMessageCount());
     assertEquals(0, message.getRepeatedLazyMessageCount());
     builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance());
     builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance());
-    // LITE_RUNTIME doesn't implement equals so we compare on a property and
-    // ensure the property isn't set on repeatedGroup.
-    assertEquals(3, messageAfterBuild.getRepeatedLazyMessage(0).getBb());
+    assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getRepeatedLazyMessage(0));
     assertEquals(
     assertEquals(
         NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0));
         NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0));
     builder.clearRepeatedLazyMessage();
     builder.clearRepeatedLazyMessage();
@@ -1456,7 +1450,7 @@ public class LiteTest extends TestCase {
         .setOptionalFloat(2.72f)
         .setOptionalFloat(2.72f)
         .setOptionalDouble(3.14)
         .setOptionalDouble(3.14)
         .build();
         .build();
-    assertToStringEquals("optional_float: 2.72\noptional_double: 3.14", proto);
+    assertToStringEquals("optional_double: 3.14\noptional_float: 2.72", proto);
   }
   }
 
 
   public void testToStringStringFields() throws Exception {
   public void testToStringStringFields() throws Exception {
@@ -1511,7 +1505,7 @@ public class LiteTest extends TestCase {
             .setC(3))
             .setC(3))
         .build();
         .build();
     assertToStringEquals(
     assertToStringEquals(
-        "optional_foreign_message {\n  c: 3\n}\noptional_foreign_enum: FOREIGN_LITE_BAR",
+        "optional_foreign_enum: FOREIGN_LITE_BAR\noptional_foreign_message {\n  c: 3\n}",
         proto);
         proto);
   }
   }
 
 
@@ -1546,6 +1540,27 @@ public class LiteTest extends TestCase {
         "1: 123\n18: \"\\b\\a\"\n21: 3\n44: \"spam\"\n44: \"eggs\"",
         "1: 123\n18: \"\\b\\a\"\n21: 3\n44: \"spam\"\n44: \"eggs\"",
         messageWithUnknownFields);
         messageWithUnknownFields);
   }
   }
+  
+  public void testToStringLazyMessage() throws Exception {
+    TestAllTypesLite message = TestAllTypesLite.newBuilder()
+        .setOptionalLazyMessage(NestedMessage.newBuilder().setBb(1).build())
+        .build();
+    assertToStringEquals("optional_lazy_message {\n  bb: 1\n}", message);
+  }
+  
+  public void testToStringGroup() throws Exception {
+    TestAllTypesLite message = TestAllTypesLite.newBuilder()
+        .setOptionalGroup(OptionalGroup.newBuilder().setA(1).build())
+        .build();
+    assertToStringEquals("optional_group {\n  a: 1\n}", message);
+  }
+  
+  public void testToStringOneof() throws Exception {
+    TestAllTypesLite message = TestAllTypesLite.newBuilder()
+        .setOneofString("hello")
+        .build();
+    assertToStringEquals("oneof_string: \"hello\"", message);
+  }
 
 
   // Asserts that the toString() representation of the message matches the expected. This verifies
   // Asserts that the toString() representation of the message matches the expected. This verifies
   // the first line starts with a comment; but, does not factor in said comment as part of the
   // the first line starts with a comment; but, does not factor in said comment as part of the
@@ -1598,4 +1613,617 @@ public class LiteTest extends TestCase {
     assertEquals(11, message.getOneofLazyNestedMessage().getBb());
     assertEquals(11, message.getOneofLazyNestedMessage().getBb());
     assertEquals(22L, message.getOneofLazyNestedMessage().getCc());
     assertEquals(22L, message.getOneofLazyNestedMessage().getCc());
   }
   }
+
+  public void testMergeFromStream_repeatedField() throws Exception {
+    TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder()
+        .addRepeatedString("hello");
+    builder.mergeFrom(CodedInputStream.newInstance(builder.build().toByteArray()));
+
+    assertEquals(2, builder.getRepeatedStringCount());
+  }
+
+  public void testMergeFromStream_invalidBytes() throws Exception {
+    TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder()
+        .setDefaultBool(true);
+    try {
+      builder.mergeFrom(CodedInputStream.newInstance("Invalid bytes".getBytes(Internal.UTF_8)));
+      fail();
+    } catch (InvalidProtocolBufferException expected) {}
+  }
+  
+  public void testMergeFrom_sanity() throws Exception {
+    TestAllTypesLite one = TestUtilLite.getAllLiteSetBuilder().build();
+    byte[] bytes = one.toByteArray();
+    TestAllTypesLite two = TestAllTypesLite.parseFrom(bytes);
+    
+    one = one.toBuilder().mergeFrom(one).build();
+    two = two.toBuilder().mergeFrom(bytes).build();
+    assertEquals(one, two);
+    assertEquals(two, one);
+    assertEquals(one.hashCode(), two.hashCode());
+  }
+  
+  public void testEquals_notEqual() throws Exception {
+    TestAllTypesLite one = TestUtilLite.getAllLiteSetBuilder().build();
+    byte[] bytes = one.toByteArray();
+    TestAllTypesLite two = one.toBuilder().mergeFrom(one).mergeFrom(bytes).build();
+    
+    assertFalse(one.equals(two));
+    assertFalse(two.equals(one));
+    
+    assertFalse(one.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(one));
+    
+    TestAllTypesLite oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultBool(true)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultCord("")
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultCordBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultDouble(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultFixed32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultFixed64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultFloat(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultImportEnum(ImportEnumLite.IMPORT_LITE_BAR)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultInt32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultInt64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultNestedEnum(NestedEnum.BAR)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultSfixed32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultSfixed64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultSint32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultSint64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultString("")
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultStringBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultStringPiece("")
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultStringPieceBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultUint32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setDefaultUint64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedBool(true)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedCord("")
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedCordBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedDouble(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedFixed32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedFixed64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedFloat(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedImportEnum(ImportEnumLite.IMPORT_LITE_BAR)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedInt32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedInt64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedNestedEnum(NestedEnum.BAR)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedSfixed32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedSfixed64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedSint32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedSint64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedString("")
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedStringBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedStringPiece("")
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedStringPieceBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedUint32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedUint64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalBool(true)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalCord("")
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalCordBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalDouble(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalFixed32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalFixed64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalFloat(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalImportEnum(ImportEnumLite.IMPORT_LITE_BAR)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalInt32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalInt64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalNestedEnum(NestedEnum.BAR)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalSfixed32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalSfixed64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalSint32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalSint64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalString("")
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalStringBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalStringPiece("")
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalStringPieceBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalUint32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalUint64(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOneofBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOneofLazyNestedMessage(NestedMessage.getDefaultInstance())
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOneofNestedMessage(NestedMessage.getDefaultInstance())
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOneofString("")
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOneofStringBytes(ByteString.EMPTY)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOneofUint32(0)
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalForeignMessage(ForeignMessageLite.getDefaultInstance())
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalGroup(OptionalGroup.getDefaultInstance())
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalPublicImportMessage(PublicImportMessageLite.getDefaultInstance())
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .setOptionalLazyMessage(NestedMessage.getDefaultInstance())
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+    oneFieldSet = TestAllTypesLite.newBuilder()
+        .addRepeatedLazyMessage(NestedMessage.getDefaultInstance())
+        .build();
+    assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+    assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+  }
+
+  public void testEquals() throws Exception {
+    // Check that two identical objs are equal.
+    Foo foo1a = Foo.newBuilder()
+        .setValue(1)
+        .addBar(Bar.newBuilder().setName("foo1"))
+        .build();
+    Foo foo1b = Foo.newBuilder()
+        .setValue(1)
+        .addBar(Bar.newBuilder().setName("foo1"))
+        .build();
+    Foo foo2 = Foo.newBuilder()
+        .setValue(1)
+        .addBar(Bar.newBuilder().setName("foo2"))
+        .build();
+
+    // Check that equals is doing value rather than object equality.
+    assertEquals(foo1a, foo1b);
+    assertEquals(foo1a.hashCode(), foo1b.hashCode());
+
+    // Check that a diffeent object is not equal.
+    assertFalse(foo1a.equals(foo2));
+
+    // Check that two objects which have different types but the same field values are not
+    // considered to be equal.
+    Bar bar = Bar.newBuilder().setName("bar").build();
+    BarPrime barPrime = BarPrime.newBuilder().setName("bar").build();
+    assertFalse(bar.equals(barPrime));
+  }
+
+  public void testOneofEquals() throws Exception {
+    TestOneofEquals.Builder builder = TestOneofEquals.newBuilder();
+    TestOneofEquals message1 = builder.build();
+    // Set message2's name field to default value. The two messages should be different when we
+    // check with the oneof case.
+    builder.setName("");
+    TestOneofEquals message2 = builder.build();
+    assertFalse(message1.equals(message2));
+  }
+  
+  public void testEquals_sanity() throws Exception {
+    TestAllTypesLite one = TestUtilLite.getAllLiteSetBuilder().build();
+    TestAllTypesLite two = TestAllTypesLite.parseFrom(one.toByteArray());
+    assertEquals(one, two);
+    assertEquals(one.hashCode(), two.hashCode());
+    
+    assertEquals(
+        one.toBuilder().mergeFrom(two).build(),
+        two.toBuilder().mergeFrom(two.toByteArray()).build());
+  }
+
+  public void testEqualsAndHashCodeWithUnknownFields() throws InvalidProtocolBufferException {
+    Foo fooWithOnlyValue = Foo.newBuilder()
+        .setValue(1)
+        .build();
+
+    Foo fooWithValueAndExtension = fooWithOnlyValue.toBuilder()
+        .setValue(1)
+        .setExtension(Bar.fooExt, Bar.newBuilder()
+            .setName("name")
+            .build())
+        .build();
+
+    Foo fooWithValueAndUnknownFields = Foo.parseFrom(fooWithValueAndExtension.toByteArray());
+
+    assertEqualsAndHashCodeAreFalse(fooWithOnlyValue, fooWithValueAndUnknownFields);
+    assertEqualsAndHashCodeAreFalse(fooWithValueAndExtension, fooWithValueAndUnknownFields);
+  }
+  
+  // Test to ensure we avoid a class cast exception with oneofs.
+  public void testEquals_oneOfMessages() {
+    TestAllTypesLite mine = TestAllTypesLite.newBuilder()
+        .setOneofString("Hello")
+        .build();
+    
+    TestAllTypesLite other = TestAllTypesLite.newBuilder()
+        .setOneofNestedMessage(NestedMessage.getDefaultInstance())
+        .build();
+    
+    assertFalse(mine.equals(other));
+    assertFalse(other.equals(mine));
+  }
+
+  private void assertEqualsAndHashCodeAreFalse(Object o1, Object o2) {
+    assertFalse(o1.equals(o2));
+    assertFalse(o1.hashCode() == o2.hashCode());
+  }
+
+  public void testRecursiveHashcode() {
+    // This tests that we don't infinite loop.
+    TestRecursiveOneof.getDefaultInstance().hashCode();
+  }
 }
 }

+ 0 - 14
java/core/src/test/java/com/google/protobuf/LongArrayListTest.java

@@ -73,20 +73,6 @@ public class LongArrayListTest extends TestCase {
     assertImmutable(list);
     assertImmutable(list);
   }
   }
   
   
-  public void testCopyConstructor() {
-    LongArrayList copy = new LongArrayList(TERTIARY_LIST);
-    assertEquals(TERTIARY_LIST, copy);
-
-    copy = new LongArrayList(LongArrayList.emptyList());
-    assertEquals(LongArrayList.emptyList(), copy);
-    
-    copy = new LongArrayList(asList(1L, 2L, 3L));
-    assertEquals(asList(1L, 2L, 3L), copy);
-
-    copy = new LongArrayList(Collections.<Long>emptyList());
-    assertEquals(LongArrayList.emptyList(), copy);
-  }
-  
   public void testModificationWithIteration() {
   public void testModificationWithIteration() {
     list.addAll(asList(1L, 2L, 3L, 4L));
     list.addAll(asList(1L, 2L, 3L, 4L));
     Iterator<Long> iterator = list.iterator();
     Iterator<Long> iterator = list.iterator();

+ 8 - 8
java/core/src/test/java/com/google/protobuf/ParserTest.java

@@ -179,16 +179,16 @@ public class ParserTest extends TestCase {
   public void testParseExtensions() throws Exception {
   public void testParseExtensions() throws Exception {
     assertRoundTripEquals(TestUtil.getAllExtensionsSet(),
     assertRoundTripEquals(TestUtil.getAllExtensionsSet(),
                           TestUtil.getExtensionRegistry());
                           TestUtil.getExtensionRegistry());
-    assertRoundTripEquals(TestUtil.getAllLiteExtensionsSet(),
-                          TestUtil.getExtensionRegistryLite());
+    assertRoundTripEquals(
+        TestUtilLite.getAllLiteExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
   }
   }
 
 
   public void testParsePacked() throws Exception {
   public void testParsePacked() throws Exception {
     assertRoundTripEquals(TestUtil.getPackedSet());
     assertRoundTripEquals(TestUtil.getPackedSet());
     assertRoundTripEquals(TestUtil.getPackedExtensionsSet(),
     assertRoundTripEquals(TestUtil.getPackedExtensionsSet(),
                           TestUtil.getExtensionRegistry());
                           TestUtil.getExtensionRegistry());
-    assertRoundTripEquals(TestUtil.getLitePackedExtensionsSet(),
-                          TestUtil.getExtensionRegistryLite());
+    assertRoundTripEquals(
+        TestUtilLite.getLitePackedExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
   }
   }
 
 
   public void testParseDelimitedTo() throws Exception {
   public void testParseDelimitedTo() throws Exception {
@@ -198,8 +198,7 @@ public class ParserTest extends TestCase {
     normalMessage.writeDelimitedTo(output);
     normalMessage.writeDelimitedTo(output);
 
 
     // Write MessageLite with packed extension fields.
     // Write MessageLite with packed extension fields.
-    TestPackedExtensionsLite packedMessage =
-        TestUtil.getLitePackedExtensionsSet();
+    TestPackedExtensionsLite packedMessage = TestUtilLite.getLitePackedExtensionsSet();
     packedMessage.writeDelimitedTo(output);
     packedMessage.writeDelimitedTo(output);
 
 
     InputStream input = new ByteArrayInputStream(output.toByteArray());
     InputStream input = new ByteArrayInputStream(output.toByteArray());
@@ -208,8 +207,9 @@ public class ParserTest extends TestCase {
         normalMessage.getParserForType().parseDelimitedFrom(input));
         normalMessage.getParserForType().parseDelimitedFrom(input));
     assertMessageEquals(
     assertMessageEquals(
         packedMessage,
         packedMessage,
-        packedMessage.getParserForType().parseDelimitedFrom(
-            input, TestUtil.getExtensionRegistryLite()));
+        packedMessage
+            .getParserForType()
+            .parseDelimitedFrom(input, TestUtilLite.getExtensionRegistryLite()));
   }
   }
 
 
   public void testParseUnknownFields() throws Exception {
   public void testParseUnknownFields() throws Exception {

+ 0 - 14
java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java

@@ -63,20 +63,6 @@ public class ProtobufArrayListTest extends TestCase {
     assertImmutable(ProtobufArrayList.<Integer>emptyList());
     assertImmutable(ProtobufArrayList.<Integer>emptyList());
   }
   }
   
   
-  public void testCopyConstructor() {
-    ProtobufArrayList<Integer> copy = new ProtobufArrayList<Integer>(TERTIARY_LIST);
-    assertEquals(TERTIARY_LIST, copy);
-
-    copy = new ProtobufArrayList<Integer>(IntArrayList.emptyList());
-    assertEquals(ProtobufArrayList.emptyList(), copy);
-    
-    copy = new ProtobufArrayList<Integer>(asList(1, 2, 3));
-    assertEquals(asList(1, 2, 3), copy);
-
-    copy = new ProtobufArrayList<Integer>(Collections.<Integer>emptyList());
-    assertEquals(ProtobufArrayList.emptyList(), copy);
-  }
-  
   public void testModificationWithIteration() {
   public void testModificationWithIteration() {
     list.addAll(asList(1, 2, 3, 4));
     list.addAll(asList(1, 2, 3, 4));
     Iterator<Integer> iterator = list.iterator();
     Iterator<Integer> iterator = list.iterator();

+ 13 - 7
java/core/src/test/java/com/google/protobuf/ServiceTest.java

@@ -175,12 +175,14 @@ public class ServiceTest extends TestCase {
     MethodDescriptor fooMethod =
     MethodDescriptor fooMethod =
         ServiceWithNoOuter.getDescriptor().findMethodByName("Foo");
         ServiceWithNoOuter.getDescriptor().findMethodByName("Foo");
     MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance();
     MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance();
-    RpcCallback<Message> callback = new RpcCallback<Message>() {
-      public void run(Message parameter) {
-        // No reason this should be run.
-        fail();
-      }
-    };
+    RpcCallback<Message> callback =
+        new RpcCallback<Message>() {
+          @Override
+          public void run(Message parameter) {
+            // No reason this should be run.
+            fail();
+          }
+        };
     RpcCallback<TestAllTypes> specializedCallback =
     RpcCallback<TestAllTypes> specializedCallback =
         RpcUtil.specializeCallback(callback);
         RpcUtil.specializeCallback(callback);
 
 
@@ -290,7 +292,9 @@ public class ServiceTest extends TestCase {
     public boolean isCalled() { return called; }
     public boolean isCalled() { return called; }
 
 
     public void reset() { called = false; }
     public void reset() { called = false; }
-    public void run(Type message) { called = true; }
+    @Override
+    public void run(Type message) {
+      called = true; }
   }
   }
 
 
   /** Implementation of the wrapsCallback() argument matcher. */
   /** Implementation of the wrapsCallback() argument matcher. */
@@ -301,6 +305,7 @@ public class ServiceTest extends TestCase {
       this.callback = callback;
       this.callback = callback;
     }
     }
 
 
+    @Override
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
     public boolean matches(Object actual) {
     public boolean matches(Object actual) {
       if (!(actual instanceof RpcCallback)) {
       if (!(actual instanceof RpcCallback)) {
@@ -313,6 +318,7 @@ public class ServiceTest extends TestCase {
       return callback.isCalled();
       return callback.isCalled();
     }
     }
 
 
+    @Override
     public void appendTo(StringBuffer buffer) {
     public void appendTo(StringBuffer buffer) {
       buffer.append("wrapsCallback(mockCallback)");
       buffer.append("wrapsCallback(mockCallback)");
     }
     }

+ 3 - 0
java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java

@@ -56,14 +56,17 @@ public class SmallSortedMapTest extends TestCase {
       this.value = value;
       this.value = value;
     }
     }
 
 
+    @Override
     public K getKey() {
     public K getKey() {
       return key;
       return key;
     }
     }
 
 
+    @Override
     public V getValue() {
     public V getValue() {
       return value;
       return value;
     }
     }
 
 
+    @Override
     public V setValue(V value) {
     public V setValue(V value) {
       V oldValue = this.value;
       V oldValue = this.value;
       this.value = value;
       this.value = value;

+ 2 - 407
java/core/src/test/java/com/google/protobuf/TestUtil.java

@@ -30,8 +30,6 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
-import static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite;
-import static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite;
 import static com.google.protobuf.UnittestLite.defaultBoolExtensionLite;
 import static com.google.protobuf.UnittestLite.defaultBoolExtensionLite;
 import static com.google.protobuf.UnittestLite.defaultBytesExtensionLite;
 import static com.google.protobuf.UnittestLite.defaultBytesExtensionLite;
 import static com.google.protobuf.UnittestLite.defaultCordExtensionLite;
 import static com.google.protobuf.UnittestLite.defaultCordExtensionLite;
@@ -216,12 +214,7 @@ import static protobuf_unittest.UnittestProto.repeatedUint32Extension;
 import static protobuf_unittest.UnittestProto.repeatedUint64Extension;
 import static protobuf_unittest.UnittestProto.repeatedUint64Extension;
 
 
 import com.google.protobuf.UnittestImportLite.ImportEnumLite;
 import com.google.protobuf.UnittestImportLite.ImportEnumLite;
-import com.google.protobuf.UnittestImportLite.ImportMessageLite;
-import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
-import com.google.protobuf.UnittestLite;
 import com.google.protobuf.UnittestLite.ForeignEnumLite;
 import com.google.protobuf.UnittestLite.ForeignEnumLite;
-import com.google.protobuf.UnittestLite.ForeignMessageLite;
-import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
 import com.google.protobuf.UnittestLite.TestAllExtensionsLiteOrBuilder;
 import com.google.protobuf.UnittestLite.TestAllExtensionsLiteOrBuilder;
 import com.google.protobuf.UnittestLite.TestAllTypesLite;
 import com.google.protobuf.UnittestLite.TestAllTypesLite;
 import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
 import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
@@ -286,16 +279,6 @@ public final class TestUtil {
     return builder;
     return builder;
   }
   }
 
 
-  /**
-   * Get a {@code TestAllTypesLite.Builder} with all fields set as they would be by
-   * {@link #setAllFields(TestAllTypesLite.Builder)}.
-   */
-  public static TestAllTypesLite.Builder getAllLiteSetBuilder() {
-    TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder();
-    setAllFields(builder);
-    return builder;
-  }
-
   /**
   /**
    * Get a {@code TestAllExtensions} with all fields set as they would be by
    * Get a {@code TestAllExtensions} with all fields set as they would be by
    * {@link #setAllExtensions(TestAllExtensions.Builder)}.
    * {@link #setAllExtensions(TestAllExtensions.Builder)}.
@@ -306,12 +289,6 @@ public final class TestUtil {
     return builder.build();
     return builder.build();
   }
   }
 
 
-  public static TestAllExtensionsLite getAllLiteExtensionsSet() {
-    TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
-    setAllExtensions(builder);
-    return builder.build();
-  }
-
   public static TestPackedTypes getPackedSet() {
   public static TestPackedTypes getPackedSet() {
     TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
     TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
     setPackedFields(builder);
     setPackedFields(builder);
@@ -330,157 +307,6 @@ public final class TestUtil {
     return builder.build();
     return builder.build();
   }
   }
 
 
-  public static TestPackedExtensionsLite getLitePackedExtensionsSet() {
-    TestPackedExtensionsLite.Builder builder =
-        TestPackedExtensionsLite.newBuilder();
-    setPackedExtensions(builder);
-    return builder.build();
-  }
-  
-  /**
-   * Set every field of {@code builder} to the values expected by
-   * {@code assertAllFieldsSet()}.
-   */
-  public static void setAllFields(TestAllTypesLite.Builder builder) {
-    builder.setOptionalInt32   (101);
-    builder.setOptionalInt64   (102);
-    builder.setOptionalUint32  (103);
-    builder.setOptionalUint64  (104);
-    builder.setOptionalSint32  (105);
-    builder.setOptionalSint64  (106);
-    builder.setOptionalFixed32 (107);
-    builder.setOptionalFixed64 (108);
-    builder.setOptionalSfixed32(109);
-    builder.setOptionalSfixed64(110);
-    builder.setOptionalFloat   (111);
-    builder.setOptionalDouble  (112);
-    builder.setOptionalBool    (true);
-    builder.setOptionalString  ("115");
-    builder.setOptionalBytes   (toBytes("116"));
-
-    builder.setOptionalGroup(
-        TestAllTypesLite.OptionalGroup.newBuilder().setA(117).build());
-    builder.setOptionalNestedMessage(
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(118).build());
-    builder.setOptionalForeignMessage(
-        ForeignMessageLite.newBuilder().setC(119).build());
-    builder.setOptionalImportMessage(
-        ImportMessageLite.newBuilder().setD(120).build());
-    builder.setOptionalPublicImportMessage(
-        PublicImportMessageLite.newBuilder().setE(126).build());
-    builder.setOptionalLazyMessage(
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(127).build());
-
-    builder.setOptionalNestedEnum (TestAllTypesLite.NestedEnum.BAZ);
-    builder.setOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAZ);
-    builder.setOptionalImportEnum (ImportEnumLite.IMPORT_LITE_BAZ);
-
-    builder.setOptionalStringPiece("124");
-    builder.setOptionalCord("125");
-
-    // -----------------------------------------------------------------
-
-    builder.addRepeatedInt32   (201);
-    builder.addRepeatedInt64   (202);
-    builder.addRepeatedUint32  (203);
-    builder.addRepeatedUint64  (204);
-    builder.addRepeatedSint32  (205);
-    builder.addRepeatedSint64  (206);
-    builder.addRepeatedFixed32 (207);
-    builder.addRepeatedFixed64 (208);
-    builder.addRepeatedSfixed32(209);
-    builder.addRepeatedSfixed64(210);
-    builder.addRepeatedFloat   (211);
-    builder.addRepeatedDouble  (212);
-    builder.addRepeatedBool    (true);
-    builder.addRepeatedString  ("215");
-    builder.addRepeatedBytes   (toBytes("216"));
-
-    builder.addRepeatedGroup(
-        TestAllTypesLite.RepeatedGroup.newBuilder().setA(217).build());
-    builder.addRepeatedNestedMessage(
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(218).build());
-    builder.addRepeatedForeignMessage(
-        ForeignMessageLite.newBuilder().setC(219).build());
-    builder.addRepeatedImportMessage(
-        ImportMessageLite.newBuilder().setD(220).build());
-    builder.addRepeatedLazyMessage(
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(227).build());
-
-    builder.addRepeatedNestedEnum (TestAllTypesLite.NestedEnum.BAR);
-    builder.addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR);
-    builder.addRepeatedImportEnum (ImportEnumLite.IMPORT_LITE_BAR);
-
-    builder.addRepeatedStringPiece("224");
-    builder.addRepeatedCord("225");
-
-    // Add a second one of each field.
-    builder.addRepeatedInt32   (301);
-    builder.addRepeatedInt64   (302);
-    builder.addRepeatedUint32  (303);
-    builder.addRepeatedUint64  (304);
-    builder.addRepeatedSint32  (305);
-    builder.addRepeatedSint64  (306);
-    builder.addRepeatedFixed32 (307);
-    builder.addRepeatedFixed64 (308);
-    builder.addRepeatedSfixed32(309);
-    builder.addRepeatedSfixed64(310);
-    builder.addRepeatedFloat   (311);
-    builder.addRepeatedDouble  (312);
-    builder.addRepeatedBool    (false);
-    builder.addRepeatedString  ("315");
-    builder.addRepeatedBytes   (toBytes("316"));
-
-    builder.addRepeatedGroup(
-        TestAllTypesLite.RepeatedGroup.newBuilder().setA(317).build());
-    builder.addRepeatedNestedMessage(
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(318).build());
-    builder.addRepeatedForeignMessage(
-        ForeignMessageLite.newBuilder().setC(319).build());
-    builder.addRepeatedImportMessage(
-        ImportMessageLite.newBuilder().setD(320).build());
-    builder.addRepeatedLazyMessage(
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(327).build());
-
-    builder.addRepeatedNestedEnum (TestAllTypesLite.NestedEnum.BAZ);
-    builder.addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAZ);
-    builder.addRepeatedImportEnum (ImportEnumLite.IMPORT_LITE_BAZ);
-
-    builder.addRepeatedStringPiece("324");
-    builder.addRepeatedCord("325");
-
-    // -----------------------------------------------------------------
-
-    builder.setDefaultInt32   (401);
-    builder.setDefaultInt64   (402);
-    builder.setDefaultUint32  (403);
-    builder.setDefaultUint64  (404);
-    builder.setDefaultSint32  (405);
-    builder.setDefaultSint64  (406);
-    builder.setDefaultFixed32 (407);
-    builder.setDefaultFixed64 (408);
-    builder.setDefaultSfixed32(409);
-    builder.setDefaultSfixed64(410);
-    builder.setDefaultFloat   (411);
-    builder.setDefaultDouble  (412);
-    builder.setDefaultBool    (false);
-    builder.setDefaultString  ("415");
-    builder.setDefaultBytes   (toBytes("416"));
-
-    builder.setDefaultNestedEnum (TestAllTypesLite.NestedEnum.FOO);
-    builder.setDefaultForeignEnum(ForeignEnumLite.FOREIGN_LITE_FOO);
-    builder.setDefaultImportEnum (ImportEnumLite.IMPORT_LITE_FOO);
-
-    builder.setDefaultStringPiece("424");
-    builder.setDefaultCord("425");
-
-    builder.setOneofUint32(601);
-    builder.setOneofNestedMessage(
-        TestAllTypesLite.NestedMessage.newBuilder().setBb(602).build());
-    builder.setOneofString("603");
-    builder.setOneofBytes(toBytes("604"));
-  }
-
   /**
   /**
    * Set every field of {@code message} to the values expected by
    * Set every field of {@code message} to the values expected by
    * {@code assertAllFieldsSet()}.
    * {@code assertAllFieldsSet()}.
@@ -1370,23 +1196,13 @@ public final class TestUtil {
     return registry.getUnmodifiable();
     return registry.getUnmodifiable();
   }
   }
 
 
-  public static ExtensionRegistryLite getExtensionRegistryLite() {
-    ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
-    registerAllExtensionsLite(registry);
-    return registry.getUnmodifiable();
-  }
-
   /**
   /**
    * Register all of {@code TestAllExtensions}'s extensions with the
    * Register all of {@code TestAllExtensions}'s extensions with the
    * given {@link ExtensionRegistry}.
    * given {@link ExtensionRegistry}.
    */
    */
   public static void registerAllExtensions(ExtensionRegistry registry) {
   public static void registerAllExtensions(ExtensionRegistry registry) {
     UnittestProto.registerAllExtensions(registry);
     UnittestProto.registerAllExtensions(registry);
-    registerAllExtensionsLite(registry);
-  }
-
-  public static void registerAllExtensionsLite(ExtensionRegistryLite registry) {
-    UnittestLite.registerAllExtensions(registry);
+    TestUtilLite.registerAllExtensionsLite(registry);
   }
   }
 
 
   /**
   /**
@@ -2179,195 +1995,6 @@ public final class TestUtil {
   // ===================================================================
   // ===================================================================
   // Lite extensions
   // Lite extensions
 
 
-  /**
-   * Set every field of {@code message} to the values expected by
-   * {@code assertAllExtensionsSet()}.
-   */
-  public static void setAllExtensions(TestAllExtensionsLite.Builder message) {
-    message.setExtension(optionalInt32ExtensionLite   , 101);
-    message.setExtension(optionalInt64ExtensionLite   , 102L);
-    message.setExtension(optionalUint32ExtensionLite  , 103);
-    message.setExtension(optionalUint64ExtensionLite  , 104L);
-    message.setExtension(optionalSint32ExtensionLite  , 105);
-    message.setExtension(optionalSint64ExtensionLite  , 106L);
-    message.setExtension(optionalFixed32ExtensionLite , 107);
-    message.setExtension(optionalFixed64ExtensionLite , 108L);
-    message.setExtension(optionalSfixed32ExtensionLite, 109);
-    message.setExtension(optionalSfixed64ExtensionLite, 110L);
-    message.setExtension(optionalFloatExtensionLite   , 111F);
-    message.setExtension(optionalDoubleExtensionLite  , 112D);
-    message.setExtension(optionalBoolExtensionLite    , true);
-    message.setExtension(optionalStringExtensionLite  , "115");
-    message.setExtension(optionalBytesExtensionLite   , toBytes("116"));
-
-    message.setExtension(optionalGroupExtensionLite,
-      OptionalGroup_extension_lite.newBuilder().setA(117).build());
-    message.setExtension(optionalNestedMessageExtensionLite,
-      TestAllTypesLite.NestedMessage.newBuilder().setBb(118).build());
-    message.setExtension(optionalForeignMessageExtensionLite,
-      ForeignMessageLite.newBuilder().setC(119).build());
-    message.setExtension(optionalImportMessageExtensionLite,
-      ImportMessageLite.newBuilder().setD(120).build());
-    message.setExtension(optionalPublicImportMessageExtensionLite,
-      PublicImportMessageLite.newBuilder().setE(126).build());
-    message.setExtension(optionalLazyMessageExtensionLite,
-      TestAllTypesLite.NestedMessage.newBuilder().setBb(127).build());
-
-    message.setExtension(optionalNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
-    message.setExtension(optionalForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
-    message.setExtension(optionalImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
-
-    message.setExtension(optionalStringPieceExtensionLite, "124");
-    message.setExtension(optionalCordExtensionLite, "125");
-
-    // -----------------------------------------------------------------
-
-    message.addExtension(repeatedInt32ExtensionLite   , 201);
-    message.addExtension(repeatedInt64ExtensionLite   , 202L);
-    message.addExtension(repeatedUint32ExtensionLite  , 203);
-    message.addExtension(repeatedUint64ExtensionLite  , 204L);
-    message.addExtension(repeatedSint32ExtensionLite  , 205);
-    message.addExtension(repeatedSint64ExtensionLite  , 206L);
-    message.addExtension(repeatedFixed32ExtensionLite , 207);
-    message.addExtension(repeatedFixed64ExtensionLite , 208L);
-    message.addExtension(repeatedSfixed32ExtensionLite, 209);
-    message.addExtension(repeatedSfixed64ExtensionLite, 210L);
-    message.addExtension(repeatedFloatExtensionLite   , 211F);
-    message.addExtension(repeatedDoubleExtensionLite  , 212D);
-    message.addExtension(repeatedBoolExtensionLite    , true);
-    message.addExtension(repeatedStringExtensionLite  , "215");
-    message.addExtension(repeatedBytesExtensionLite   , toBytes("216"));
-
-    message.addExtension(repeatedGroupExtensionLite,
-      RepeatedGroup_extension_lite.newBuilder().setA(217).build());
-    message.addExtension(repeatedNestedMessageExtensionLite,
-      TestAllTypesLite.NestedMessage.newBuilder().setBb(218).build());
-    message.addExtension(repeatedForeignMessageExtensionLite,
-      ForeignMessageLite.newBuilder().setC(219).build());
-    message.addExtension(repeatedImportMessageExtensionLite,
-      ImportMessageLite.newBuilder().setD(220).build());
-    message.addExtension(repeatedLazyMessageExtensionLite,
-      TestAllTypesLite.NestedMessage.newBuilder().setBb(227).build());
-
-    message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAR);
-    message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
-    message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAR);
-
-    message.addExtension(repeatedStringPieceExtensionLite, "224");
-    message.addExtension(repeatedCordExtensionLite, "225");
-
-    // Add a second one of each field.
-    message.addExtension(repeatedInt32ExtensionLite   , 301);
-    message.addExtension(repeatedInt64ExtensionLite   , 302L);
-    message.addExtension(repeatedUint32ExtensionLite  , 303);
-    message.addExtension(repeatedUint64ExtensionLite  , 304L);
-    message.addExtension(repeatedSint32ExtensionLite  , 305);
-    message.addExtension(repeatedSint64ExtensionLite  , 306L);
-    message.addExtension(repeatedFixed32ExtensionLite , 307);
-    message.addExtension(repeatedFixed64ExtensionLite , 308L);
-    message.addExtension(repeatedSfixed32ExtensionLite, 309);
-    message.addExtension(repeatedSfixed64ExtensionLite, 310L);
-    message.addExtension(repeatedFloatExtensionLite   , 311F);
-    message.addExtension(repeatedDoubleExtensionLite  , 312D);
-    message.addExtension(repeatedBoolExtensionLite    , false);
-    message.addExtension(repeatedStringExtensionLite  , "315");
-    message.addExtension(repeatedBytesExtensionLite   , toBytes("316"));
-
-    message.addExtension(repeatedGroupExtensionLite,
-      RepeatedGroup_extension_lite.newBuilder().setA(317).build());
-    message.addExtension(repeatedNestedMessageExtensionLite,
-      TestAllTypesLite.NestedMessage.newBuilder().setBb(318).build());
-    message.addExtension(repeatedForeignMessageExtensionLite,
-      ForeignMessageLite.newBuilder().setC(319).build());
-    message.addExtension(repeatedImportMessageExtensionLite,
-      ImportMessageLite.newBuilder().setD(320).build());
-    message.addExtension(repeatedLazyMessageExtensionLite,
-      TestAllTypesLite.NestedMessage.newBuilder().setBb(327).build());
-
-    message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
-    message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
-    message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
-
-    message.addExtension(repeatedStringPieceExtensionLite, "324");
-    message.addExtension(repeatedCordExtensionLite, "325");
-
-    // -----------------------------------------------------------------
-
-    message.setExtension(defaultInt32ExtensionLite   , 401);
-    message.setExtension(defaultInt64ExtensionLite   , 402L);
-    message.setExtension(defaultUint32ExtensionLite  , 403);
-    message.setExtension(defaultUint64ExtensionLite  , 404L);
-    message.setExtension(defaultSint32ExtensionLite  , 405);
-    message.setExtension(defaultSint64ExtensionLite  , 406L);
-    message.setExtension(defaultFixed32ExtensionLite , 407);
-    message.setExtension(defaultFixed64ExtensionLite , 408L);
-    message.setExtension(defaultSfixed32ExtensionLite, 409);
-    message.setExtension(defaultSfixed64ExtensionLite, 410L);
-    message.setExtension(defaultFloatExtensionLite   , 411F);
-    message.setExtension(defaultDoubleExtensionLite  , 412D);
-    message.setExtension(defaultBoolExtensionLite    , false);
-    message.setExtension(defaultStringExtensionLite  , "415");
-    message.setExtension(defaultBytesExtensionLite   , toBytes("416"));
-
-    message.setExtension(defaultNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.FOO);
-    message.setExtension(defaultForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_FOO);
-    message.setExtension(defaultImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_FOO);
-
-    message.setExtension(defaultStringPieceExtensionLite, "424");
-    message.setExtension(defaultCordExtensionLite, "425");
-
-    message.setExtension(oneofUint32ExtensionLite, 601);
-    message.setExtension(oneofNestedMessageExtensionLite,
-      TestAllTypesLite.NestedMessage.newBuilder().setBb(602).build());
-    message.setExtension(oneofStringExtensionLite, "603");
-    message.setExtension(oneofBytesExtensionLite, toBytes("604"));
-  }
-
-  // -------------------------------------------------------------------
-
-  /**
-   * Modify the repeated extensions of {@code message} to contain the values
-   * expected by {@code assertRepeatedExtensionsModified()}.
-   */
-  public static void modifyRepeatedExtensions(
-      TestAllExtensionsLite.Builder message) {
-    message.setExtension(repeatedInt32ExtensionLite   , 1, 501);
-    message.setExtension(repeatedInt64ExtensionLite   , 1, 502L);
-    message.setExtension(repeatedUint32ExtensionLite  , 1, 503);
-    message.setExtension(repeatedUint64ExtensionLite  , 1, 504L);
-    message.setExtension(repeatedSint32ExtensionLite  , 1, 505);
-    message.setExtension(repeatedSint64ExtensionLite  , 1, 506L);
-    message.setExtension(repeatedFixed32ExtensionLite , 1, 507);
-    message.setExtension(repeatedFixed64ExtensionLite , 1, 508L);
-    message.setExtension(repeatedSfixed32ExtensionLite, 1, 509);
-    message.setExtension(repeatedSfixed64ExtensionLite, 1, 510L);
-    message.setExtension(repeatedFloatExtensionLite   , 1, 511F);
-    message.setExtension(repeatedDoubleExtensionLite  , 1, 512D);
-    message.setExtension(repeatedBoolExtensionLite    , 1, true);
-    message.setExtension(repeatedStringExtensionLite  , 1, "515");
-    message.setExtension(repeatedBytesExtensionLite   , 1, toBytes("516"));
-
-    message.setExtension(repeatedGroupExtensionLite, 1,
-      RepeatedGroup_extension_lite.newBuilder().setA(517).build());
-    message.setExtension(repeatedNestedMessageExtensionLite, 1,
-      TestAllTypesLite.NestedMessage.newBuilder().setBb(518).build());
-    message.setExtension(repeatedForeignMessageExtensionLite, 1,
-      ForeignMessageLite.newBuilder().setC(519).build());
-    message.setExtension(repeatedImportMessageExtensionLite, 1,
-      ImportMessageLite.newBuilder().setD(520).build());
-    message.setExtension(repeatedLazyMessageExtensionLite, 1,
-      TestAllTypesLite.NestedMessage.newBuilder().setBb(527).build());
-
-    message.setExtension(repeatedNestedEnumExtensionLite , 1, TestAllTypesLite.NestedEnum.FOO);
-    message.setExtension(repeatedForeignEnumExtensionLite, 1, ForeignEnumLite.FOREIGN_LITE_FOO);
-    message.setExtension(repeatedImportEnumExtensionLite , 1, ImportEnumLite.IMPORT_LITE_FOO);
-
-    message.setExtension(repeatedStringPieceExtensionLite, 1, "524");
-    message.setExtension(repeatedCordExtensionLite, 1, "525");
-  }
-
-  // -------------------------------------------------------------------
-
   /**
   /**
    * Assert (using {@code junit.framework.Assert}} that all extensions of
    * Assert (using {@code junit.framework.Assert}} that all extensions of
    * {@code message} are set to the values assigned by {@code setAllExtensions}.
    * {@code message} are set to the values assigned by {@code setAllExtensions}.
@@ -2867,38 +2494,6 @@ public final class TestUtil {
     assertEqualsExactType("525", message.getExtension(repeatedCordExtensionLite, 1));
     assertEqualsExactType("525", message.getExtension(repeatedCordExtensionLite, 1));
   }
   }
 
 
-  public static void setPackedExtensions(TestPackedExtensionsLite.Builder message) {
-    message.addExtension(packedInt32ExtensionLite   , 601);
-    message.addExtension(packedInt64ExtensionLite   , 602L);
-    message.addExtension(packedUint32ExtensionLite  , 603);
-    message.addExtension(packedUint64ExtensionLite  , 604L);
-    message.addExtension(packedSint32ExtensionLite  , 605);
-    message.addExtension(packedSint64ExtensionLite  , 606L);
-    message.addExtension(packedFixed32ExtensionLite , 607);
-    message.addExtension(packedFixed64ExtensionLite , 608L);
-    message.addExtension(packedSfixed32ExtensionLite, 609);
-    message.addExtension(packedSfixed64ExtensionLite, 610L);
-    message.addExtension(packedFloatExtensionLite   , 611F);
-    message.addExtension(packedDoubleExtensionLite  , 612D);
-    message.addExtension(packedBoolExtensionLite    , true);
-    message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
-    // Add a second one of each field.
-    message.addExtension(packedInt32ExtensionLite   , 701);
-    message.addExtension(packedInt64ExtensionLite   , 702L);
-    message.addExtension(packedUint32ExtensionLite  , 703);
-    message.addExtension(packedUint64ExtensionLite  , 704L);
-    message.addExtension(packedSint32ExtensionLite  , 705);
-    message.addExtension(packedSint64ExtensionLite  , 706L);
-    message.addExtension(packedFixed32ExtensionLite , 707);
-    message.addExtension(packedFixed64ExtensionLite , 708L);
-    message.addExtension(packedSfixed32ExtensionLite, 709);
-    message.addExtension(packedSfixed64ExtensionLite, 710L);
-    message.addExtension(packedFloatExtensionLite   , 711F);
-    message.addExtension(packedDoubleExtensionLite  , 712D);
-    message.addExtension(packedBoolExtensionLite    , false);
-    message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
-  }
-
   public static void assertPackedExtensionsSet(TestPackedExtensionsLite message) {
   public static void assertPackedExtensionsSet(TestPackedExtensionsLite message) {
     Assert.assertEquals(2, message.getExtensionCount(packedInt32ExtensionLite   ));
     Assert.assertEquals(2, message.getExtensionCount(packedInt32ExtensionLite   ));
     Assert.assertEquals(2, message.getExtensionCount(packedInt64ExtensionLite   ));
     Assert.assertEquals(2, message.getExtensionCount(packedInt64ExtensionLite   ));
@@ -4250,7 +3845,7 @@ public final class TestUtil {
 
 
     private int invalidations;
     private int invalidations;
 
 
-    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @Override
     public void markDirty() {
     public void markDirty() {
       invalidations++;
       invalidations++;
     }
     }

+ 559 - 0
java/core/src/test/java/com/google/protobuf/TestUtilLite.java

@@ -0,0 +1,559 @@
+// 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 static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite;
+import static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite;
+import static com.google.protobuf.UnittestLite.defaultBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultCordExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultStringExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofStringExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalCordExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalForeignMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalGroupExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalLazyMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalPublicImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalStringExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.packedDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.packedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.packedInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedCordExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedForeignMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedGroupExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedLazyMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedStringExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedUint64ExtensionLite;
+
+import com.google.protobuf.UnittestImportLite.ImportEnumLite;
+import com.google.protobuf.UnittestImportLite.ImportMessageLite;
+import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
+import com.google.protobuf.UnittestLite.ForeignEnumLite;
+import com.google.protobuf.UnittestLite.ForeignMessageLite;
+import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
+import com.google.protobuf.UnittestLite.TestAllTypesLite;
+import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
+
+/**
+ * Contains methods for setting fields of {@code TestAllTypesLite}, {@code TestAllExtensionsLite},
+ * and {@code TestPackedExtensionsLite}. This is analogous to the functionality in TestUtil.java but
+ * does not depend on the presence of any non-lite protos.
+ *
+ * <p>This code is not to be used outside of {@code com.google.protobuf} and
+ * subpackages.
+ */
+public final class TestUtilLite {
+  private TestUtilLite() {}
+
+  /** Helper to convert a String to ByteString. */
+  static ByteString toBytes(String str) {
+    return ByteString.copyFrom(str.getBytes(Internal.UTF_8));
+  }
+
+  /**
+   * Get a {@code TestAllTypesLite.Builder} with all fields set as they would be by
+   * {@link #setAllFields(TestAllTypesLite.Builder)}.
+   */
+  public static TestAllTypesLite.Builder getAllLiteSetBuilder() {
+    TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder();
+    setAllFields(builder);
+    return builder;
+  }
+
+  /**
+   * Get a {@code TestAllExtensionsLite} with all fields set as they would be by
+   * {@link #setAllExtensions(TestAllExtensionsLite.Builder)}.
+   */
+  public static TestAllExtensionsLite getAllLiteExtensionsSet() {
+    TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
+    setAllExtensions(builder);
+    return builder.build();
+  }
+
+  public static TestPackedExtensionsLite getLitePackedExtensionsSet() {
+    TestPackedExtensionsLite.Builder builder = TestPackedExtensionsLite.newBuilder();
+    setPackedExtensions(builder);
+    return builder.build();
+  }
+  
+  /**
+   * Set every field of {@code builder} to the values expected by
+   * {@code assertAllFieldsSet()}.
+   */
+  public static void setAllFields(TestAllTypesLite.Builder builder) {
+    builder.setOptionalInt32   (101);
+    builder.setOptionalInt64   (102);
+    builder.setOptionalUint32  (103);
+    builder.setOptionalUint64  (104);
+    builder.setOptionalSint32  (105);
+    builder.setOptionalSint64  (106);
+    builder.setOptionalFixed32 (107);
+    builder.setOptionalFixed64 (108);
+    builder.setOptionalSfixed32(109);
+    builder.setOptionalSfixed64(110);
+    builder.setOptionalFloat   (111);
+    builder.setOptionalDouble  (112);
+    builder.setOptionalBool    (true);
+    builder.setOptionalString  ("115");
+    builder.setOptionalBytes   (toBytes("116"));
+
+    builder.setOptionalGroup(
+        TestAllTypesLite.OptionalGroup.newBuilder().setA(117).build());
+    builder.setOptionalNestedMessage(
+        TestAllTypesLite.NestedMessage.newBuilder().setBb(118).build());
+    builder.setOptionalForeignMessage(
+        ForeignMessageLite.newBuilder().setC(119).build());
+    builder.setOptionalImportMessage(
+        ImportMessageLite.newBuilder().setD(120).build());
+    builder.setOptionalPublicImportMessage(
+        PublicImportMessageLite.newBuilder().setE(126).build());
+    builder.setOptionalLazyMessage(
+        TestAllTypesLite.NestedMessage.newBuilder().setBb(127).build());
+
+    builder.setOptionalNestedEnum (TestAllTypesLite.NestedEnum.BAZ);
+    builder.setOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAZ);
+    builder.setOptionalImportEnum (ImportEnumLite.IMPORT_LITE_BAZ);
+
+    builder.setOptionalStringPiece("124");
+    builder.setOptionalCord("125");
+
+    // -----------------------------------------------------------------
+
+    builder.addRepeatedInt32   (201);
+    builder.addRepeatedInt64   (202);
+    builder.addRepeatedUint32  (203);
+    builder.addRepeatedUint64  (204);
+    builder.addRepeatedSint32  (205);
+    builder.addRepeatedSint64  (206);
+    builder.addRepeatedFixed32 (207);
+    builder.addRepeatedFixed64 (208);
+    builder.addRepeatedSfixed32(209);
+    builder.addRepeatedSfixed64(210);
+    builder.addRepeatedFloat   (211);
+    builder.addRepeatedDouble  (212);
+    builder.addRepeatedBool    (true);
+    builder.addRepeatedString  ("215");
+    builder.addRepeatedBytes   (toBytes("216"));
+
+    builder.addRepeatedGroup(
+        TestAllTypesLite.RepeatedGroup.newBuilder().setA(217).build());
+    builder.addRepeatedNestedMessage(
+        TestAllTypesLite.NestedMessage.newBuilder().setBb(218).build());
+    builder.addRepeatedForeignMessage(
+        ForeignMessageLite.newBuilder().setC(219).build());
+    builder.addRepeatedImportMessage(
+        ImportMessageLite.newBuilder().setD(220).build());
+    builder.addRepeatedLazyMessage(
+        TestAllTypesLite.NestedMessage.newBuilder().setBb(227).build());
+
+    builder.addRepeatedNestedEnum (TestAllTypesLite.NestedEnum.BAR);
+    builder.addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR);
+    builder.addRepeatedImportEnum (ImportEnumLite.IMPORT_LITE_BAR);
+
+    builder.addRepeatedStringPiece("224");
+    builder.addRepeatedCord("225");
+
+    // Add a second one of each field.
+    builder.addRepeatedInt32   (301);
+    builder.addRepeatedInt64   (302);
+    builder.addRepeatedUint32  (303);
+    builder.addRepeatedUint64  (304);
+    builder.addRepeatedSint32  (305);
+    builder.addRepeatedSint64  (306);
+    builder.addRepeatedFixed32 (307);
+    builder.addRepeatedFixed64 (308);
+    builder.addRepeatedSfixed32(309);
+    builder.addRepeatedSfixed64(310);
+    builder.addRepeatedFloat   (311);
+    builder.addRepeatedDouble  (312);
+    builder.addRepeatedBool    (false);
+    builder.addRepeatedString  ("315");
+    builder.addRepeatedBytes   (toBytes("316"));
+
+    builder.addRepeatedGroup(
+        TestAllTypesLite.RepeatedGroup.newBuilder().setA(317).build());
+    builder.addRepeatedNestedMessage(
+        TestAllTypesLite.NestedMessage.newBuilder().setBb(318).build());
+    builder.addRepeatedForeignMessage(
+        ForeignMessageLite.newBuilder().setC(319).build());
+    builder.addRepeatedImportMessage(
+        ImportMessageLite.newBuilder().setD(320).build());
+    builder.addRepeatedLazyMessage(
+        TestAllTypesLite.NestedMessage.newBuilder().setBb(327).build());
+
+    builder.addRepeatedNestedEnum (TestAllTypesLite.NestedEnum.BAZ);
+    builder.addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAZ);
+    builder.addRepeatedImportEnum (ImportEnumLite.IMPORT_LITE_BAZ);
+
+    builder.addRepeatedStringPiece("324");
+    builder.addRepeatedCord("325");
+
+    // -----------------------------------------------------------------
+
+    builder.setDefaultInt32   (401);
+    builder.setDefaultInt64   (402);
+    builder.setDefaultUint32  (403);
+    builder.setDefaultUint64  (404);
+    builder.setDefaultSint32  (405);
+    builder.setDefaultSint64  (406);
+    builder.setDefaultFixed32 (407);
+    builder.setDefaultFixed64 (408);
+    builder.setDefaultSfixed32(409);
+    builder.setDefaultSfixed64(410);
+    builder.setDefaultFloat   (411);
+    builder.setDefaultDouble  (412);
+    builder.setDefaultBool    (false);
+    builder.setDefaultString  ("415");
+    builder.setDefaultBytes   (toBytes("416"));
+
+    builder.setDefaultNestedEnum (TestAllTypesLite.NestedEnum.FOO);
+    builder.setDefaultForeignEnum(ForeignEnumLite.FOREIGN_LITE_FOO);
+    builder.setDefaultImportEnum (ImportEnumLite.IMPORT_LITE_FOO);
+
+    builder.setDefaultStringPiece("424");
+    builder.setDefaultCord("425");
+
+    builder.setOneofUint32(601);
+    builder.setOneofNestedMessage(
+        TestAllTypesLite.NestedMessage.newBuilder().setBb(602).build());
+    builder.setOneofString("603");
+    builder.setOneofBytes(toBytes("604"));
+  }
+
+  /**
+   * Get an unmodifiable {@link ExtensionRegistryLite} containing all the
+   * extensions of {@code TestAllExtensionsLite}.
+   */
+  public static ExtensionRegistryLite getExtensionRegistryLite() {
+    ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
+    registerAllExtensionsLite(registry);
+    return registry.getUnmodifiable();
+  }
+
+  /**
+   * Register all of {@code TestAllExtensionsLite}'s extensions with the
+   * given {@link ExtensionRegistryLite}.
+   */
+  public static void registerAllExtensionsLite(ExtensionRegistryLite registry) {
+    UnittestLite.registerAllExtensions(registry);
+  }
+
+  // ===================================================================
+  // Lite extensions
+
+  /**
+   * Set every field of {@code message} to the values expected by
+   * {@code assertAllExtensionsSet()}.
+   */
+  public static void setAllExtensions(TestAllExtensionsLite.Builder message) {
+    message.setExtension(optionalInt32ExtensionLite   , 101);
+    message.setExtension(optionalInt64ExtensionLite   , 102L);
+    message.setExtension(optionalUint32ExtensionLite  , 103);
+    message.setExtension(optionalUint64ExtensionLite  , 104L);
+    message.setExtension(optionalSint32ExtensionLite  , 105);
+    message.setExtension(optionalSint64ExtensionLite  , 106L);
+    message.setExtension(optionalFixed32ExtensionLite , 107);
+    message.setExtension(optionalFixed64ExtensionLite , 108L);
+    message.setExtension(optionalSfixed32ExtensionLite, 109);
+    message.setExtension(optionalSfixed64ExtensionLite, 110L);
+    message.setExtension(optionalFloatExtensionLite   , 111F);
+    message.setExtension(optionalDoubleExtensionLite  , 112D);
+    message.setExtension(optionalBoolExtensionLite    , true);
+    message.setExtension(optionalStringExtensionLite  , "115");
+    message.setExtension(optionalBytesExtensionLite   , toBytes("116"));
+
+    message.setExtension(optionalGroupExtensionLite,
+      OptionalGroup_extension_lite.newBuilder().setA(117).build());
+    message.setExtension(optionalNestedMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(118).build());
+    message.setExtension(optionalForeignMessageExtensionLite,
+      ForeignMessageLite.newBuilder().setC(119).build());
+    message.setExtension(optionalImportMessageExtensionLite,
+      ImportMessageLite.newBuilder().setD(120).build());
+    message.setExtension(optionalPublicImportMessageExtensionLite,
+      PublicImportMessageLite.newBuilder().setE(126).build());
+    message.setExtension(optionalLazyMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(127).build());
+
+    message.setExtension(optionalNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
+    message.setExtension(optionalForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
+    message.setExtension(optionalImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
+
+    message.setExtension(optionalStringPieceExtensionLite, "124");
+    message.setExtension(optionalCordExtensionLite, "125");
+
+    // -----------------------------------------------------------------
+
+    message.addExtension(repeatedInt32ExtensionLite   , 201);
+    message.addExtension(repeatedInt64ExtensionLite   , 202L);
+    message.addExtension(repeatedUint32ExtensionLite  , 203);
+    message.addExtension(repeatedUint64ExtensionLite  , 204L);
+    message.addExtension(repeatedSint32ExtensionLite  , 205);
+    message.addExtension(repeatedSint64ExtensionLite  , 206L);
+    message.addExtension(repeatedFixed32ExtensionLite , 207);
+    message.addExtension(repeatedFixed64ExtensionLite , 208L);
+    message.addExtension(repeatedSfixed32ExtensionLite, 209);
+    message.addExtension(repeatedSfixed64ExtensionLite, 210L);
+    message.addExtension(repeatedFloatExtensionLite   , 211F);
+    message.addExtension(repeatedDoubleExtensionLite  , 212D);
+    message.addExtension(repeatedBoolExtensionLite    , true);
+    message.addExtension(repeatedStringExtensionLite  , "215");
+    message.addExtension(repeatedBytesExtensionLite   , toBytes("216"));
+
+    message.addExtension(repeatedGroupExtensionLite,
+      RepeatedGroup_extension_lite.newBuilder().setA(217).build());
+    message.addExtension(repeatedNestedMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(218).build());
+    message.addExtension(repeatedForeignMessageExtensionLite,
+      ForeignMessageLite.newBuilder().setC(219).build());
+    message.addExtension(repeatedImportMessageExtensionLite,
+      ImportMessageLite.newBuilder().setD(220).build());
+    message.addExtension(repeatedLazyMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(227).build());
+
+    message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAR);
+    message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
+    message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAR);
+
+    message.addExtension(repeatedStringPieceExtensionLite, "224");
+    message.addExtension(repeatedCordExtensionLite, "225");
+
+    // Add a second one of each field.
+    message.addExtension(repeatedInt32ExtensionLite   , 301);
+    message.addExtension(repeatedInt64ExtensionLite   , 302L);
+    message.addExtension(repeatedUint32ExtensionLite  , 303);
+    message.addExtension(repeatedUint64ExtensionLite  , 304L);
+    message.addExtension(repeatedSint32ExtensionLite  , 305);
+    message.addExtension(repeatedSint64ExtensionLite  , 306L);
+    message.addExtension(repeatedFixed32ExtensionLite , 307);
+    message.addExtension(repeatedFixed64ExtensionLite , 308L);
+    message.addExtension(repeatedSfixed32ExtensionLite, 309);
+    message.addExtension(repeatedSfixed64ExtensionLite, 310L);
+    message.addExtension(repeatedFloatExtensionLite   , 311F);
+    message.addExtension(repeatedDoubleExtensionLite  , 312D);
+    message.addExtension(repeatedBoolExtensionLite    , false);
+    message.addExtension(repeatedStringExtensionLite  , "315");
+    message.addExtension(repeatedBytesExtensionLite   , toBytes("316"));
+
+    message.addExtension(repeatedGroupExtensionLite,
+      RepeatedGroup_extension_lite.newBuilder().setA(317).build());
+    message.addExtension(repeatedNestedMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(318).build());
+    message.addExtension(repeatedForeignMessageExtensionLite,
+      ForeignMessageLite.newBuilder().setC(319).build());
+    message.addExtension(repeatedImportMessageExtensionLite,
+      ImportMessageLite.newBuilder().setD(320).build());
+    message.addExtension(repeatedLazyMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(327).build());
+
+    message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
+    message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
+    message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
+
+    message.addExtension(repeatedStringPieceExtensionLite, "324");
+    message.addExtension(repeatedCordExtensionLite, "325");
+
+    // -----------------------------------------------------------------
+
+    message.setExtension(defaultInt32ExtensionLite   , 401);
+    message.setExtension(defaultInt64ExtensionLite   , 402L);
+    message.setExtension(defaultUint32ExtensionLite  , 403);
+    message.setExtension(defaultUint64ExtensionLite  , 404L);
+    message.setExtension(defaultSint32ExtensionLite  , 405);
+    message.setExtension(defaultSint64ExtensionLite  , 406L);
+    message.setExtension(defaultFixed32ExtensionLite , 407);
+    message.setExtension(defaultFixed64ExtensionLite , 408L);
+    message.setExtension(defaultSfixed32ExtensionLite, 409);
+    message.setExtension(defaultSfixed64ExtensionLite, 410L);
+    message.setExtension(defaultFloatExtensionLite   , 411F);
+    message.setExtension(defaultDoubleExtensionLite  , 412D);
+    message.setExtension(defaultBoolExtensionLite    , false);
+    message.setExtension(defaultStringExtensionLite  , "415");
+    message.setExtension(defaultBytesExtensionLite   , toBytes("416"));
+
+    message.setExtension(defaultNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.FOO);
+    message.setExtension(defaultForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_FOO);
+    message.setExtension(defaultImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_FOO);
+
+    message.setExtension(defaultStringPieceExtensionLite, "424");
+    message.setExtension(defaultCordExtensionLite, "425");
+
+    message.setExtension(oneofUint32ExtensionLite, 601);
+    message.setExtension(oneofNestedMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(602).build());
+    message.setExtension(oneofStringExtensionLite, "603");
+    message.setExtension(oneofBytesExtensionLite, toBytes("604"));
+  }
+
+  // -------------------------------------------------------------------
+
+  /**
+   * Modify the repeated extensions of {@code message} to contain the values
+   * expected by {@code assertRepeatedExtensionsModified()}.
+   */
+  public static void modifyRepeatedExtensions(
+      TestAllExtensionsLite.Builder message) {
+    message.setExtension(repeatedInt32ExtensionLite   , 1, 501);
+    message.setExtension(repeatedInt64ExtensionLite   , 1, 502L);
+    message.setExtension(repeatedUint32ExtensionLite  , 1, 503);
+    message.setExtension(repeatedUint64ExtensionLite  , 1, 504L);
+    message.setExtension(repeatedSint32ExtensionLite  , 1, 505);
+    message.setExtension(repeatedSint64ExtensionLite  , 1, 506L);
+    message.setExtension(repeatedFixed32ExtensionLite , 1, 507);
+    message.setExtension(repeatedFixed64ExtensionLite , 1, 508L);
+    message.setExtension(repeatedSfixed32ExtensionLite, 1, 509);
+    message.setExtension(repeatedSfixed64ExtensionLite, 1, 510L);
+    message.setExtension(repeatedFloatExtensionLite   , 1, 511F);
+    message.setExtension(repeatedDoubleExtensionLite  , 1, 512D);
+    message.setExtension(repeatedBoolExtensionLite    , 1, true);
+    message.setExtension(repeatedStringExtensionLite  , 1, "515");
+    message.setExtension(repeatedBytesExtensionLite   , 1, toBytes("516"));
+
+    message.setExtension(repeatedGroupExtensionLite, 1,
+      RepeatedGroup_extension_lite.newBuilder().setA(517).build());
+    message.setExtension(repeatedNestedMessageExtensionLite, 1,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(518).build());
+    message.setExtension(repeatedForeignMessageExtensionLite, 1,
+      ForeignMessageLite.newBuilder().setC(519).build());
+    message.setExtension(repeatedImportMessageExtensionLite, 1,
+      ImportMessageLite.newBuilder().setD(520).build());
+    message.setExtension(repeatedLazyMessageExtensionLite, 1,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(527).build());
+
+    message.setExtension(repeatedNestedEnumExtensionLite , 1, TestAllTypesLite.NestedEnum.FOO);
+    message.setExtension(repeatedForeignEnumExtensionLite, 1, ForeignEnumLite.FOREIGN_LITE_FOO);
+    message.setExtension(repeatedImportEnumExtensionLite , 1, ImportEnumLite.IMPORT_LITE_FOO);
+
+    message.setExtension(repeatedStringPieceExtensionLite, 1, "524");
+    message.setExtension(repeatedCordExtensionLite, 1, "525");
+  }
+
+  public static void setPackedExtensions(TestPackedExtensionsLite.Builder message) {
+    message.addExtension(packedInt32ExtensionLite   , 601);
+    message.addExtension(packedInt64ExtensionLite   , 602L);
+    message.addExtension(packedUint32ExtensionLite  , 603);
+    message.addExtension(packedUint64ExtensionLite  , 604L);
+    message.addExtension(packedSint32ExtensionLite  , 605);
+    message.addExtension(packedSint64ExtensionLite  , 606L);
+    message.addExtension(packedFixed32ExtensionLite , 607);
+    message.addExtension(packedFixed64ExtensionLite , 608L);
+    message.addExtension(packedSfixed32ExtensionLite, 609);
+    message.addExtension(packedSfixed64ExtensionLite, 610L);
+    message.addExtension(packedFloatExtensionLite   , 611F);
+    message.addExtension(packedDoubleExtensionLite  , 612D);
+    message.addExtension(packedBoolExtensionLite    , true);
+    message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
+    // Add a second one of each field.
+    message.addExtension(packedInt32ExtensionLite   , 701);
+    message.addExtension(packedInt64ExtensionLite   , 702L);
+    message.addExtension(packedUint32ExtensionLite  , 703);
+    message.addExtension(packedUint64ExtensionLite  , 704L);
+    message.addExtension(packedSint32ExtensionLite  , 705);
+    message.addExtension(packedSint64ExtensionLite  , 706L);
+    message.addExtension(packedFixed32ExtensionLite , 707);
+    message.addExtension(packedFixed64ExtensionLite , 708L);
+    message.addExtension(packedSfixed32ExtensionLite, 709);
+    message.addExtension(packedSfixed64ExtensionLite, 710L);
+    message.addExtension(packedFloatExtensionLite   , 711F);
+    message.addExtension(packedDoubleExtensionLite  , 712D);
+    message.addExtension(packedBoolExtensionLite    , false);
+    message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
+  }
+}

+ 4 - 1
java/core/src/test/java/com/google/protobuf/TextFormatTest.java

@@ -775,11 +775,14 @@ public class TextFormatTest extends TestCase {
   public void testParseBoolean() throws Exception {
   public void testParseBoolean() throws Exception {
     String goodText =
     String goodText =
         "repeated_bool: t  repeated_bool : 0\n" +
         "repeated_bool: t  repeated_bool : 0\n" +
-        "repeated_bool :f repeated_bool:1";
+        "repeated_bool :f repeated_bool:1\n" +
+        "repeated_bool: False repeated_bool: True";
     String goodTextCanonical =
     String goodTextCanonical =
         "repeated_bool: true\n" +
         "repeated_bool: true\n" +
         "repeated_bool: false\n" +
         "repeated_bool: false\n" +
         "repeated_bool: false\n" +
         "repeated_bool: false\n" +
+        "repeated_bool: true\n" +
+        "repeated_bool: false\n" +
         "repeated_bool: true\n";
         "repeated_bool: true\n";
     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
     TextFormat.merge(goodText, builder);
     TextFormat.merge(goodText, builder);

+ 1 - 0
java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java

@@ -50,6 +50,7 @@ import java.util.Map;
  * @author kenton@google.com (Kenton Varda)
  * @author kenton@google.com (Kenton Varda)
  */
  */
 public class UnknownFieldSetTest extends TestCase {
 public class UnknownFieldSetTest extends TestCase {
+  @Override
   public void setUp() throws Exception {
   public void setUp() throws Exception {
     descriptor = TestAllTypes.getDescriptor();
     descriptor = TestAllTypes.getDescriptor();
     allFields = TestUtil.getAllSet();
     allFields = TestUtil.getAllSet();

+ 5 - 5
java/core/src/test/java/com/google/protobuf/WireFormatTest.java

@@ -132,7 +132,7 @@ public class WireFormatTest extends TestCase {
     // so if we serialize a TestAllExtensions then parse it as TestAllTypes
     // so if we serialize a TestAllExtensions then parse it as TestAllTypes
     // it should work.
     // it should work.
 
 
-    TestAllExtensionsLite message = TestUtil.getAllLiteExtensionsSet();
+    TestAllExtensionsLite message = TestUtilLite.getAllLiteExtensionsSet();
     ByteString rawBytes = message.toByteString();
     ByteString rawBytes = message.toByteString();
     assertEquals(rawBytes.size(), message.getSerializedSize());
     assertEquals(rawBytes.size(), message.getSerializedSize());
 
 
@@ -144,7 +144,7 @@ public class WireFormatTest extends TestCase {
   public void testSerializePackedExtensionsLite() throws Exception {
   public void testSerializePackedExtensionsLite() throws Exception {
     // TestPackedTypes and TestPackedExtensions should have compatible wire
     // TestPackedTypes and TestPackedExtensions should have compatible wire
     // formats; check that they serialize to the same string.
     // formats; check that they serialize to the same string.
-    TestPackedExtensionsLite message = TestUtil.getLitePackedExtensionsSet();
+    TestPackedExtensionsLite message = TestUtilLite.getLitePackedExtensionsSet();
     ByteString rawBytes = message.toByteString();
     ByteString rawBytes = message.toByteString();
 
 
     TestPackedTypes message2 = TestUtil.getPackedSet();
     TestPackedTypes message2 = TestUtil.getPackedSet();
@@ -190,7 +190,7 @@ public class WireFormatTest extends TestCase {
     TestAllTypes message = TestUtil.getAllSet();
     TestAllTypes message = TestUtil.getAllSet();
     ByteString rawBytes = message.toByteString();
     ByteString rawBytes = message.toByteString();
 
 
-    ExtensionRegistryLite registry_lite = TestUtil.getExtensionRegistryLite();
+    ExtensionRegistryLite registry_lite = TestUtilLite.getExtensionRegistryLite();
 
 
     TestAllExtensionsLite message2 =
     TestAllExtensionsLite message2 =
       TestAllExtensionsLite.parseFrom(rawBytes, registry_lite);
       TestAllExtensionsLite.parseFrom(rawBytes, registry_lite);
@@ -208,10 +208,10 @@ public class WireFormatTest extends TestCase {
 
 
   public void testParsePackedExtensionsLite() throws Exception {
   public void testParsePackedExtensionsLite() throws Exception {
     // Ensure that packed extensions can be properly parsed.
     // Ensure that packed extensions can be properly parsed.
-    TestPackedExtensionsLite message = TestUtil.getLitePackedExtensionsSet();
+    TestPackedExtensionsLite message = TestUtilLite.getLitePackedExtensionsSet();
     ByteString rawBytes = message.toByteString();
     ByteString rawBytes = message.toByteString();
 
 
-    ExtensionRegistryLite registry = TestUtil.getExtensionRegistryLite();
+    ExtensionRegistryLite registry = TestUtilLite.getExtensionRegistryLite();
 
 
     TestPackedExtensionsLite message2 =
     TestPackedExtensionsLite message2 =
         TestPackedExtensionsLite.parseFrom(rawBytes, registry);
         TestPackedExtensionsLite.parseFrom(rawBytes, registry);

+ 0 - 3
java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto

@@ -34,9 +34,6 @@ syntax = "proto2";
 
 
 package protobuf_unittest.lite_equals_and_hash;
 package protobuf_unittest.lite_equals_and_hash;
 
 
-// This proto definition is used to test that java_generate_equals_and_hash
-// works correctly with the LITE_RUNTIME.
-option java_generate_equals_and_hash = true;
 option optimize_for = LITE_RUNTIME;
 option optimize_for = LITE_RUNTIME;
 
 
 message TestOneofEquals {
 message TestOneofEquals {

+ 20 - 0
java/lite/generate-sources-build.xml

@@ -0,0 +1,20 @@
+<project name="generate-sources">
+    <echo message="Running protoc ..."/>
+    <mkdir dir="${generated.sources.lite.dir}"/>
+    <exec executable="${protoc}">
+        <arg value="--java_out=lite:${generated.sources.lite.dir}"/>
+        <arg value="--proto_path=${protobuf.source.dir}"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/any.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/api.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/descriptor.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/duration.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/empty.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/field_mask.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/source_context.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/struct.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/timestamp.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/type.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/wrappers.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/compiler/plugin.proto"/>
+    </exec>
+</project>

+ 43 - 0
java/lite/generate-test-sources-build.xml

@@ -0,0 +1,43 @@
+<project name="generate-test-sources">
+    <mkdir dir="${generated.testsources.lite.dir}"/>
+    <exec executable="${protoc}">
+        <arg value="--java_out=lite:${generated.testsources.lite.dir}"/>
+        <arg value="--proto_path=${protobuf.source.dir}"/>
+        <arg value="--proto_path=${test.proto.dir}"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest_import.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest_import_public.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest_mset.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest_mset_wire_format.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest_optimize_for.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest_custom_options.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest_lite.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest_import_lite.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest_import_public_lite.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest_lite_imports_nonlite.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest_enormous_descriptor.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest_no_generic_services.proto"/>
+        <arg value="${protobuf.source.dir}/google/protobuf/unittest_well_known_types.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/lazy_fields_lite.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/lite_equals_and_hash.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/multiple_files_test.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/nested_builders_test.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/nested_extension.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/nested_extension_lite.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/non_nested_extension.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/non_nested_extension_lite.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/outer_class_name_test.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/outer_class_name_test2.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/outer_class_name_test3.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/test_bad_identifiers.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/test_check_utf8.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/test_check_utf8_size.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/test_custom_options.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/any_test.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/field_presence_test.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/map_for_proto2_lite_test.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/map_for_proto2_test.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/map_test.proto"/>
+        <arg value="${test.proto.dir}/com/google/protobuf/map_initialization_order_test.proto"/>
+    </exec>
+</project>

+ 4 - 4
java/lite/pom.xml

@@ -50,7 +50,7 @@
             <phase>generate-sources</phase>
             <phase>generate-sources</phase>
             <configuration>
             <configuration>
               <target>
               <target>
-                <ant antfile="${core.root}/generate-sources-build.xml"/>
+                <ant antfile="generate-sources-build.xml"/>
               </target>
               </target>
             </configuration>
             </configuration>
             <goals>
             <goals>
@@ -64,7 +64,7 @@
             <phase>generate-test-sources</phase>
             <phase>generate-test-sources</phase>
             <configuration>
             <configuration>
               <target>
               <target>
-                <ant antfile="${core.root}/generate-test-sources-build.xml"/>
+                <ant antfile="generate-test-sources-build.xml"/>
               </target>
               </target>
             </configuration>
             </configuration>
             <goals>
             <goals>
@@ -78,8 +78,8 @@
       <plugin>
       <plugin>
         <artifactId>maven-compiler-plugin</artifactId>
         <artifactId>maven-compiler-plugin</artifactId>
         <configuration>
         <configuration>
-          <generatedSourcesDirectory>${generated.sources.dir}</generatedSourcesDirectory>
-          <generatedTestSourcesDirectory>${generated.testsources.dir}</generatedTestSourcesDirectory>
+          <generatedSourcesDirectory>${generated.sources.lite.dir}</generatedSourcesDirectory>
+          <generatedTestSourcesDirectory>${generated.testsources.lite.dir}</generatedTestSourcesDirectory>
           <includes>
           <includes>
             <include>**/AbstractMessageLite.java</include>
             <include>**/AbstractMessageLite.java</include>
             <include>**/AbstractParser.java</include>
             <include>**/AbstractParser.java</include>

+ 2 - 0
java/pom.xml

@@ -33,6 +33,8 @@
     <test.proto.dir>src/test/proto</test.proto.dir>
     <test.proto.dir>src/test/proto</test.proto.dir>
     <generated.sources.dir>${project.build.directory}/generated-sources</generated.sources.dir>
     <generated.sources.dir>${project.build.directory}/generated-sources</generated.sources.dir>
     <generated.testsources.dir>${project.build.directory}/generated-test-sources</generated.testsources.dir>
     <generated.testsources.dir>${project.build.directory}/generated-test-sources</generated.testsources.dir>
+    <generated.sources.lite.dir>${project.build.directory}/generated-sources-lite</generated.sources.lite.dir>
+    <generated.testsources.lite.dir>${project.build.directory}/generated-test-sources-lite</generated.testsources.lite.dir>
   </properties>
   </properties>
 
 
   <licenses>
   <licenses>

+ 553 - 0
java/src/main/java/com/google/protobuf/AbstractMessage.java

@@ -0,0 +1,553 @@
+// 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.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.OneofDescriptor;
+import com.google.protobuf.Internal.EnumLite;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A partial implementation of the {@link Message} interface which implements
+ * as many methods of that interface as possible in terms of other methods.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public abstract class AbstractMessage
+    // TODO(dweis): Update GeneratedMessage to parameterize with MessageType and BuilderType.
+    extends AbstractMessageLite
+    implements Message {
+  
+  @Override
+  public boolean isInitialized() {
+    return MessageReflection.isInitialized(this);
+  }
+
+
+  @Override
+  public List<String> findInitializationErrors() {
+    return MessageReflection.findMissingFields(this);
+  }
+
+  @Override
+  public String getInitializationErrorString() {
+    return MessageReflection.delimitWithCommas(findInitializationErrors());
+  }
+
+  /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+  @Override
+  public boolean hasOneof(OneofDescriptor oneof) {
+    throw new UnsupportedOperationException("hasOneof() is not implemented.");
+  }
+
+  /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+  @Override
+  public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
+    throw new UnsupportedOperationException(
+        "getOneofFieldDescriptor() is not implemented.");
+  }
+
+  @Override
+  public final String toString() {
+    return TextFormat.printToString(this);
+  }
+
+  @Override
+  public void writeTo(final CodedOutputStream output) throws IOException {
+    MessageReflection.writeMessageTo(this, getAllFields(), output, false);
+  }
+
+  protected int memoizedSize = -1;
+
+  @Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) {
+      return size;
+    }
+
+    memoizedSize = MessageReflection.getSerializedSize(this, getAllFields());
+    return memoizedSize;
+  }
+
+  @Override
+  public boolean equals(final Object other) {
+    if (other == this) {
+      return true;
+    }
+    if (!(other instanceof Message)) {
+      return false;
+    }
+    final Message otherMessage = (Message) other;
+    if (getDescriptorForType() != otherMessage.getDescriptorForType()) {
+      return false;
+    }
+    return compareFields(getAllFields(), otherMessage.getAllFields()) &&
+        getUnknownFields().equals(otherMessage.getUnknownFields());
+  }
+
+  @Override
+  public int hashCode() {
+    int hash = memoizedHashCode;
+    if (hash == 0) {
+      hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      hash = hashFields(hash, getAllFields());
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+    }
+    return hash;
+  }
+  
+  private static ByteString toByteString(Object value) {
+    if (value instanceof byte[]) {
+      return ByteString.copyFrom((byte[]) value);
+    } else {
+      return (ByteString) value;
+    }
+  }
+ 
+  /**
+   * Compares two bytes fields. The parameters must be either a byte array or a
+   * ByteString object. They can be of different type though.
+   */
+  private static boolean compareBytes(Object a, Object b) {
+    if (a instanceof byte[] && b instanceof byte[]) {
+      return Arrays.equals((byte[])a, (byte[])b);
+    }
+    return toByteString(a).equals(toByteString(b));
+  }
+  
+  /**
+   * Converts a list of MapEntry messages into a Map used for equals() and
+   * hashCode().
+   */
+  @SuppressWarnings({"rawtypes", "unchecked"})
+  private static Map convertMapEntryListToMap(List list) {
+    if (list.isEmpty()) {
+      return Collections.emptyMap();
+    }
+    Map result = new HashMap();
+    Iterator iterator = list.iterator();
+    Message entry = (Message) iterator.next();
+    Descriptors.Descriptor descriptor = entry.getDescriptorForType();
+    Descriptors.FieldDescriptor key = descriptor.findFieldByName("key");
+    Descriptors.FieldDescriptor value = descriptor.findFieldByName("value");
+    Object fieldValue = entry.getField(value);
+    if (fieldValue instanceof EnumValueDescriptor) {
+      fieldValue = ((EnumValueDescriptor) fieldValue).getNumber();
+    }
+    result.put(entry.getField(key), fieldValue);
+    while (iterator.hasNext()) {
+      entry = (Message) iterator.next();
+      fieldValue = entry.getField(value);
+      if (fieldValue instanceof EnumValueDescriptor) {
+        fieldValue = ((EnumValueDescriptor) fieldValue).getNumber();
+      }
+      result.put(entry.getField(key), fieldValue);
+    }
+    return result;
+  }
+  
+  /**
+   * Compares two map fields. The parameters must be a list of MapEntry
+   * messages.
+   */
+  @SuppressWarnings({"rawtypes", "unchecked"})
+  private static boolean compareMapField(Object a, Object b) {
+    Map ma = convertMapEntryListToMap((List) a);
+    Map mb = convertMapEntryListToMap((List) b);
+    return MapFieldLite.equals(ma, mb);
+  }
+  
+  /**
+   * Compares two set of fields.
+   * This method is used to implement {@link AbstractMessage#equals(Object)}
+   * and {@link AbstractMutableMessage#equals(Object)}. It takes special care
+   * of bytes fields because immutable messages and mutable messages use
+   * different Java type to reprensent a bytes field and this method should be
+   * able to compare immutable messages, mutable messages and also an immutable
+   * message to a mutable message.
+   */
+  static boolean compareFields(Map<FieldDescriptor, Object> a,
+      Map<FieldDescriptor, Object> b) {
+    if (a.size() != b.size()) {
+      return false;
+    }
+    for (FieldDescriptor descriptor : a.keySet()) {
+      if (!b.containsKey(descriptor)) {
+        return false;
+      }
+      Object value1 = a.get(descriptor);
+      Object value2 = b.get(descriptor);
+      if (descriptor.getType() == FieldDescriptor.Type.BYTES) {
+        if (descriptor.isRepeated()) {
+          List list1 = (List) value1;
+          List list2 = (List) value2;
+          if (list1.size() != list2.size()) {
+            return false;
+          }
+          for (int i = 0; i < list1.size(); i++) {
+            if (!compareBytes(list1.get(i), list2.get(i))) {
+              return false;
+            }
+          }
+        } else {
+          // Compares a singular bytes field.
+          if (!compareBytes(value1, value2)) {
+            return false;
+          }
+        }
+      } else if (descriptor.isMapField()) {
+        if (!compareMapField(value1, value2)) {
+          return false;
+        }
+      } else {
+        // Compare non-bytes fields.
+        if (!value1.equals(value2)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+  
+  /**
+   * Calculates the hash code of a map field. {@code value} must be a list of
+   * MapEntry messages.
+   */
+  @SuppressWarnings("unchecked")
+  private static int hashMapField(Object value) {
+    return MapFieldLite.calculateHashCodeForMap(convertMapEntryListToMap((List) value));
+  }
+
+  /** Get a hash code for given fields and values, using the given seed. */
+  @SuppressWarnings("unchecked")
+  protected static int hashFields(int hash, Map<FieldDescriptor, Object> map) {
+    for (Map.Entry<FieldDescriptor, Object> entry : map.entrySet()) {
+      FieldDescriptor field = entry.getKey();
+      Object value = entry.getValue();
+      hash = (37 * hash) + field.getNumber();
+      if (field.isMapField()) {
+        hash = (53 * hash) + hashMapField(value);
+      } else if (field.getType() != FieldDescriptor.Type.ENUM){
+        hash = (53 * hash) + value.hashCode();
+      } else if (field.isRepeated()) {
+        List<? extends EnumLite> list = (List<? extends EnumLite>) value;
+        hash = (53 * hash) + Internal.hashEnumList(list);
+      } else {
+        hash = (53 * hash) + Internal.hashEnum((EnumLite) value);
+      }
+    }
+    return hash;
+  }
+
+  /**
+   * Package private helper method for AbstractParser to create
+   * UninitializedMessageException with missing field information.
+   */
+  @Override
+  UninitializedMessageException newUninitializedMessageException() {
+    return Builder.newUninitializedMessageException(this);
+  }
+
+  // =================================================================
+
+  /**
+   * A partial implementation of the {@link Message.Builder} interface which
+   * implements as many methods of that interface as possible in terms of
+   * other methods.
+   */
+  @SuppressWarnings("unchecked")
+  public static abstract class Builder<BuilderType extends Builder<BuilderType>>
+      extends AbstractMessageLite.Builder
+      implements Message.Builder {
+    // The compiler produces an error if this is not declared explicitly.
+    @Override
+    public abstract BuilderType clone();
+
+    /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+    @Override
+    public boolean hasOneof(OneofDescriptor oneof) {
+      throw new UnsupportedOperationException("hasOneof() is not implemented.");
+    }
+
+    /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+    @Override
+    public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
+      throw new UnsupportedOperationException(
+          "getOneofFieldDescriptor() is not implemented.");
+    }
+
+    /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+    @Override
+    public BuilderType clearOneof(OneofDescriptor oneof) {
+      throw new UnsupportedOperationException("clearOneof() is not implemented.");
+    }
+
+    @Override
+    public BuilderType clear() {
+      for (final Map.Entry<FieldDescriptor, Object> entry :
+           getAllFields().entrySet()) {
+        clearField(entry.getKey());
+      }
+      return (BuilderType) this;
+    }
+
+    @Override
+    public List<String> findInitializationErrors() {
+      return MessageReflection.findMissingFields(this);
+    }
+
+    @Override
+    public String getInitializationErrorString() {
+      return MessageReflection.delimitWithCommas(findInitializationErrors());
+    }
+    
+    @Override
+    protected BuilderType internalMergeFrom(AbstractMessageLite other) {
+      return mergeFrom((Message) other);
+    }
+
+    @Override
+    public BuilderType mergeFrom(final Message other) {
+      if (other.getDescriptorForType() != getDescriptorForType()) {
+        throw new IllegalArgumentException(
+          "mergeFrom(Message) can only merge messages of the same type.");
+      }
+
+      // Note:  We don't attempt to verify that other's fields have valid
+      //   types.  Doing so would be a losing battle.  We'd have to verify
+      //   all sub-messages as well, and we'd have to make copies of all of
+      //   them to insure that they don't change after verification (since
+      //   the Message interface itself cannot enforce immutability of
+      //   implementations).
+      // TODO(kenton):  Provide a function somewhere called makeDeepCopy()
+      //   which allows people to make secure deep copies of messages.
+
+      for (final Map.Entry<FieldDescriptor, Object> entry :
+           other.getAllFields().entrySet()) {
+        final FieldDescriptor field = entry.getKey();
+        if (field.isRepeated()) {
+          for (final Object element : (List)entry.getValue()) {
+            addRepeatedField(field, element);
+          }
+        } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+          final Message existingValue = (Message)getField(field);
+          if (existingValue == existingValue.getDefaultInstanceForType()) {
+            setField(field, entry.getValue());
+          } else {
+            setField(field,
+              existingValue.newBuilderForType()
+                .mergeFrom(existingValue)
+                .mergeFrom((Message)entry.getValue())
+                .build());
+          }
+        } else {
+          setField(field, entry.getValue());
+        }
+      }
+
+      mergeUnknownFields(other.getUnknownFields());
+
+      return (BuilderType) this;
+    }
+
+    @Override
+    public BuilderType mergeFrom(final CodedInputStream input)
+                                 throws IOException {
+      return mergeFrom(input, ExtensionRegistry.getEmptyRegistry());
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final CodedInputStream input,
+        final ExtensionRegistryLite extensionRegistry)
+        throws IOException {
+      final UnknownFieldSet.Builder unknownFields =
+        UnknownFieldSet.newBuilder(getUnknownFields());
+      while (true) {
+        final int tag = input.readTag();
+        if (tag == 0) {
+          break;
+        }
+
+        MessageReflection.BuilderAdapter builderAdapter =
+            new MessageReflection.BuilderAdapter(this);
+        if (!MessageReflection.mergeFieldFrom(input, unknownFields,
+                                              extensionRegistry,
+                                              getDescriptorForType(),
+                                              builderAdapter,
+                                              tag)) {
+          // end group tag
+          break;
+        }
+      }
+      setUnknownFields(unknownFields.build());
+      return (BuilderType) this;
+    }
+
+    @Override
+    public BuilderType mergeUnknownFields(final UnknownFieldSet unknownFields) {
+      setUnknownFields(
+        UnknownFieldSet.newBuilder(getUnknownFields())
+                       .mergeFrom(unknownFields)
+                       .build());
+      return (BuilderType) this;
+    }
+
+    @Override
+    public Message.Builder getFieldBuilder(final FieldDescriptor field) {
+      throw new UnsupportedOperationException(
+          "getFieldBuilder() called on an unsupported message type.");
+    }
+
+    @Override
+    public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field, int index) {
+      throw new UnsupportedOperationException(
+          "getRepeatedFieldBuilder() called on an unsupported message type.");
+    }
+
+    @Override
+    public String toString() {
+      return TextFormat.printToString(this);
+    }
+
+    /**
+     * Construct an UninitializedMessageException reporting missing fields in
+     * the given message.
+     */
+    protected static UninitializedMessageException
+        newUninitializedMessageException(Message message) {
+      return new UninitializedMessageException(
+          MessageReflection.findMissingFields(message));
+    }
+
+    // ===============================================================
+    // The following definitions seem to be required in order to make javac
+    // not produce weird errors like:
+    //
+    // java/com/google/protobuf/DynamicMessage.java:203: types
+    //   com.google.protobuf.AbstractMessage.Builder<
+    //     com.google.protobuf.DynamicMessage.Builder> and
+    //   com.google.protobuf.AbstractMessage.Builder<
+    //     com.google.protobuf.DynamicMessage.Builder> are incompatible; both
+    //   define mergeFrom(com.google.protobuf.ByteString), but with unrelated
+    //   return types.
+    //
+    // Strangely, these lines are only needed if javac is invoked separately
+    // on AbstractMessage.java and AbstractMessageLite.java.  If javac is
+    // invoked on both simultaneously, it works.  (Or maybe the important
+    // point is whether or not DynamicMessage.java is compiled together with
+    // AbstractMessageLite.java -- not sure.)  I suspect this is a compiler
+    // bug.
+
+    @Override
+    public BuilderType mergeFrom(final ByteString data)
+        throws InvalidProtocolBufferException {
+      return (BuilderType) super.mergeFrom(data);
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final ByteString data,
+        final ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      return (BuilderType) super.mergeFrom(data, extensionRegistry);
+    }
+
+    @Override
+    public BuilderType mergeFrom(final byte[] data)
+        throws InvalidProtocolBufferException {
+      return (BuilderType) super.mergeFrom(data);
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final byte[] data, final int off, final int len)
+        throws InvalidProtocolBufferException {
+      return (BuilderType) super.mergeFrom(data, off, len);
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final byte[] data,
+        final ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      return (BuilderType) super.mergeFrom(data, extensionRegistry);
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final byte[] data, final int off, final int len,
+        final ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      return (BuilderType) super.mergeFrom(data, off, len, extensionRegistry);
+    }
+
+    @Override
+    public BuilderType mergeFrom(final InputStream input)
+        throws IOException {
+      return (BuilderType) super.mergeFrom(input);
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final InputStream input,
+        final ExtensionRegistryLite extensionRegistry)
+        throws IOException {
+      return (BuilderType) super.mergeFrom(input, extensionRegistry);
+    }
+
+    @Override
+    public boolean mergeDelimitedFrom(final InputStream input)
+        throws IOException {
+      return super.mergeDelimitedFrom(input);
+    }
+
+    @Override
+    public boolean mergeDelimitedFrom(
+        final InputStream input,
+        final ExtensionRegistryLite extensionRegistry)
+        throws IOException {
+      return super.mergeDelimitedFrom(input, extensionRegistry);
+    }
+  }
+}

+ 386 - 0
java/src/main/java/com/google/protobuf/AbstractMessageLite.java

@@ -0,0 +1,386 @@
+// 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 java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collection;
+
+/**
+ * A partial implementation of the {@link MessageLite} interface which
+ * implements as many methods of that interface as possible in terms of other
+ * methods.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public abstract class AbstractMessageLite<
+    MessageType extends AbstractMessageLite<MessageType, BuilderType>,
+    BuilderType extends AbstractMessageLite.Builder<MessageType, BuilderType>> 
+        implements MessageLite {
+  protected int memoizedHashCode = 0;
+  
+  @Override
+  public ByteString toByteString() {
+    try {
+      final ByteString.CodedBuilder out =
+        ByteString.newCodedBuilder(getSerializedSize());
+      writeTo(out.getCodedOutput());
+      return out.build();
+    } catch (IOException e) {
+      throw new RuntimeException(
+        "Serializing to a ByteString threw an IOException (should " +
+        "never happen).", e);
+    }
+  }
+
+  @Override
+  public byte[] toByteArray() {
+    try {
+      final byte[] result = new byte[getSerializedSize()];
+      final CodedOutputStream output = CodedOutputStream.newInstance(result);
+      writeTo(output);
+      output.checkNoSpaceLeft();
+      return result;
+    } catch (IOException e) {
+      throw new RuntimeException(
+        "Serializing to a byte array threw an IOException " +
+        "(should never happen).", e);
+    }
+  }
+
+  @Override
+  public void writeTo(final OutputStream output) throws IOException {
+    final int bufferSize =
+        CodedOutputStream.computePreferredBufferSize(getSerializedSize());
+    final CodedOutputStream codedOutput =
+        CodedOutputStream.newInstance(output, bufferSize);
+    writeTo(codedOutput);
+    codedOutput.flush();
+  }
+
+  @Override
+  public void writeDelimitedTo(final OutputStream output) throws IOException {
+    final int serialized = getSerializedSize();
+    final int bufferSize = CodedOutputStream.computePreferredBufferSize(
+        CodedOutputStream.computeRawVarint32Size(serialized) + serialized);
+    final CodedOutputStream codedOutput =
+        CodedOutputStream.newInstance(output, bufferSize);
+    codedOutput.writeRawVarint32(serialized);
+    writeTo(codedOutput);
+    codedOutput.flush();
+  }
+
+
+  /**
+   * Package private helper method for AbstractParser to create
+   * UninitializedMessageException.
+   */
+  UninitializedMessageException newUninitializedMessageException() {
+    return new UninitializedMessageException(this);
+  }
+
+  protected static void checkByteStringIsUtf8(ByteString byteString)
+      throws IllegalArgumentException {
+    if (!byteString.isValidUtf8()) {
+      throw new IllegalArgumentException("Byte string is not UTF-8.");
+    }
+  }
+
+  protected static <T> void addAll(final Iterable<T> values,
+      final Collection<? super T> list) {
+    Builder.addAll(values, list);
+  }
+  
+  /**
+   * A partial implementation of the {@link Message.Builder} interface which
+   * implements as many methods of that interface as possible in terms of
+   * other methods.
+   */
+  @SuppressWarnings("unchecked")
+  public abstract static class Builder<
+      MessageType extends AbstractMessageLite<MessageType, BuilderType>,
+      BuilderType extends Builder<MessageType, BuilderType>>
+      implements MessageLite.Builder {
+    // The compiler produces an error if this is not declared explicitly.
+    @Override
+    public abstract BuilderType clone();
+
+    @Override
+    public BuilderType mergeFrom(final CodedInputStream input) throws IOException {
+      return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry());
+    }
+
+    // Re-defined here for return type covariance.
+    @Override
+    public abstract BuilderType mergeFrom(
+        final CodedInputStream input, final ExtensionRegistryLite extensionRegistry)
+        throws IOException;
+
+    @Override
+    public BuilderType mergeFrom(final ByteString data) throws InvalidProtocolBufferException {
+      try {
+        final CodedInputStream input = data.newCodedInput();
+        mergeFrom(input);
+        input.checkLastTagWas(0);
+        return (BuilderType) this;
+      } catch (InvalidProtocolBufferException e) {
+        throw e;
+      } catch (IOException e) {
+        throw new RuntimeException(
+          "Reading from a ByteString threw an IOException (should " +
+          "never happen).", e);
+      }
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final ByteString data, final ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      try {
+        final CodedInputStream input = data.newCodedInput();
+        mergeFrom(input, extensionRegistry);
+        input.checkLastTagWas(0);
+        return (BuilderType) this;
+      } catch (InvalidProtocolBufferException e) {
+        throw e;
+      } catch (IOException e) {
+        throw new RuntimeException(
+          "Reading from a ByteString threw an IOException (should " +
+          "never happen).", e);
+      }
+    }
+
+    @Override
+    public BuilderType mergeFrom(final byte[] data) throws InvalidProtocolBufferException {
+      return mergeFrom(data, 0, data.length);
+    }
+
+    @Override
+    public BuilderType mergeFrom(final byte[] data, final int off, final int len)
+        throws InvalidProtocolBufferException {
+      try {
+        final CodedInputStream input =
+            CodedInputStream.newInstance(data, off, len);
+        mergeFrom(input);
+        input.checkLastTagWas(0);
+        return (BuilderType) 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 BuilderType mergeFrom(final byte[] data, final ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      return mergeFrom(data, 0, data.length, extensionRegistry);
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final byte[] data,
+        final int off,
+        final int len,
+        final ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      try {
+        final CodedInputStream input =
+            CodedInputStream.newInstance(data, off, len);
+        mergeFrom(input, extensionRegistry);
+        input.checkLastTagWas(0);
+        return (BuilderType) 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 BuilderType mergeFrom(final InputStream input) throws IOException {
+      final CodedInputStream codedInput = CodedInputStream.newInstance(input);
+      mergeFrom(codedInput);
+      codedInput.checkLastTagWas(0);
+      return (BuilderType) this;
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException {
+      final CodedInputStream codedInput = CodedInputStream.newInstance(input);
+      mergeFrom(codedInput, extensionRegistry);
+      codedInput.checkLastTagWas(0);
+      return (BuilderType) this;
+    }
+
+    /**
+     * An InputStream implementations which reads from some other InputStream
+     * but is limited to a particular number of bytes.  Used by
+     * mergeDelimitedFrom().  This is intentionally package-private so that
+     * UnknownFieldSet can share it.
+     */
+    static final class LimitedInputStream extends FilterInputStream {
+      private int limit;
+
+      LimitedInputStream(InputStream in, int limit) {
+        super(in);
+        this.limit = limit;
+      }
+
+      @Override
+      public int available() throws IOException {
+        return Math.min(super.available(), limit);
+      }
+
+      @Override
+      public int read() throws IOException {
+        if (limit <= 0) {
+          return -1;
+        }
+        final int result = super.read();
+        if (result >= 0) {
+          --limit;
+        }
+        return result;
+      }
+
+      @Override
+      public int read(final byte[] b, final int off, int len)
+                      throws IOException {
+        if (limit <= 0) {
+          return -1;
+        }
+        len = Math.min(len, limit);
+        final int result = super.read(b, off, len);
+        if (result >= 0) {
+          limit -= result;
+        }
+        return result;
+      }
+
+      @Override
+      public long skip(final long n) throws IOException {
+        final long result = super.skip(Math.min(n, limit));
+        if (result >= 0) {
+          limit -= result;
+        }
+        return result;
+      }
+    }
+
+    @Override
+    public boolean mergeDelimitedFrom(
+        final InputStream input, final ExtensionRegistryLite extensionRegistry) 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, extensionRegistry);
+      return true;
+    }
+
+    @Override
+    public boolean mergeDelimitedFrom(final InputStream input) throws IOException {
+      return mergeDelimitedFrom(input,
+          ExtensionRegistryLite.getEmptyRegistry());
+    }
+    
+    @Override
+    @SuppressWarnings("unchecked") // isInstance takes care of this
+    public BuilderType mergeFrom(final MessageLite other) {
+      if (!getDefaultInstanceForType().getClass().isInstance(other)) {
+        throw new IllegalArgumentException(
+            "mergeFrom(MessageLite) can only merge messages of the same type.");
+      }
+        
+      return internalMergeFrom((MessageType) other);
+    }
+    
+    protected abstract BuilderType internalMergeFrom(MessageType message);
+
+    /**
+     * Construct an UninitializedMessageException reporting missing fields in
+     * the given message.
+     */
+    protected static UninitializedMessageException
+        newUninitializedMessageException(MessageLite message) {
+      return new UninitializedMessageException(message);
+    }
+
+    /**
+     * Adds the {@code values} to the {@code list}.  This is a helper method
+     * used by generated code.  Users should ignore it.
+     *
+     * @throws NullPointerException if {@code values} or any of the elements of
+     * {@code values} is null. When that happens, some elements of
+     * {@code values} may have already been added to the result {@code list}.
+     */
+    protected static <T> void addAll(final Iterable<T> values,
+                                     final Collection<? super T> list) {
+      if (values == null) {
+        throw new NullPointerException();
+      }
+      if (values instanceof LazyStringList) {
+        // For StringOrByteStringLists, check the underlying elements to avoid
+        // forcing conversions of ByteStrings to Strings.
+        checkForNullValues(((LazyStringList) values).getUnderlyingElements());
+        list.addAll((Collection<T>) values);
+      } else if (values instanceof Collection) {
+        checkForNullValues(values);
+        list.addAll((Collection<T>) values);
+      } else {
+        for (final T value : values) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          list.add(value);
+        }
+      }
+    }
+
+    private static void checkForNullValues(final Iterable<?> values) {
+      for (final Object value : values) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+      }
+    }
+  }
+}

+ 258 - 0
java/src/main/java/com/google/protobuf/AbstractParser.java

@@ -0,0 +1,258 @@
+// 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;
+
+/**
+ * A partial implementation of the {@link Parser} interface which implements
+ * as many methods of that interface as possible in terms of other methods.
+ *
+ * Note: This class implements all the convenience methods in the
+ * {@link Parser} interface. See {@link Parser} for related javadocs.
+ * Subclasses need to implement
+ * {@link Parser#parsePartialFrom(CodedInputStream, ExtensionRegistryLite)}
+ *
+ * @author liujisi@google.com (Pherl Liu)
+ */
+public abstract class AbstractParser<MessageType extends MessageLite>
+    implements Parser<MessageType> {
+  /**
+   * Creates an UninitializedMessageException for MessageType.
+   */
+  private UninitializedMessageException
+      newUninitializedMessageException(MessageType message) {
+    if (message instanceof AbstractMessageLite) {
+      return ((AbstractMessageLite) message).newUninitializedMessageException();
+    }
+    return new UninitializedMessageException(message);
+  }
+
+  /**
+   * Helper method to check if message is initialized.
+   *
+   * @throws InvalidProtocolBufferException if it is not initialized.
+   * @return The message to check.
+   */
+  private MessageType checkMessageInitialized(MessageType message)
+      throws InvalidProtocolBufferException {
+    if (message != null && !message.isInitialized()) {
+      throw newUninitializedMessageException(message)
+          .asInvalidProtocolBufferException()
+          .setUnfinishedMessage(message);
+    }
+    return message;
+  }
+
+  private static final ExtensionRegistryLite EMPTY_REGISTRY
+      = ExtensionRegistryLite.getEmptyRegistry();
+
+  @Override
+  public MessageType parsePartialFrom(CodedInputStream input)
+      throws InvalidProtocolBufferException {
+    return parsePartialFrom(input, EMPTY_REGISTRY);
+  }
+
+  @Override
+  public MessageType parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return checkMessageInitialized(
+        parsePartialFrom(input, extensionRegistry));
+  }
+
+  @Override
+  public MessageType parseFrom(CodedInputStream input) throws InvalidProtocolBufferException {
+    return parseFrom(input, EMPTY_REGISTRY);
+  }
+
+  @Override
+  public MessageType parsePartialFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    MessageType message;
+    try {
+      CodedInputStream input = data.newCodedInput();
+      message = parsePartialFrom(input, extensionRegistry);
+      try {
+        input.checkLastTagWas(0);
+      } catch (InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(message);
+      }
+      return message;
+    } catch (InvalidProtocolBufferException e) {
+      throw e;
+    }
+  }
+
+  @Override
+  public MessageType parsePartialFrom(ByteString data) throws InvalidProtocolBufferException {
+    return parsePartialFrom(data, EMPTY_REGISTRY);
+  }
+
+  @Override
+  public MessageType parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return checkMessageInitialized(parsePartialFrom(data, extensionRegistry));
+  }
+
+  @Override
+  public MessageType parseFrom(ByteString data) throws InvalidProtocolBufferException {
+    return parseFrom(data, EMPTY_REGISTRY);
+  }
+
+  @Override
+  public MessageType parsePartialFrom(
+      byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    try {
+      CodedInputStream input = CodedInputStream.newInstance(data, off, len);
+      MessageType message = parsePartialFrom(input, extensionRegistry);
+      try {
+        input.checkLastTagWas(0);
+      } catch (InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(message);
+      }
+      return message;
+    } catch (InvalidProtocolBufferException e) {
+      throw e;
+    }
+  }
+
+  @Override
+  public MessageType parsePartialFrom(byte[] data, int off, int len)
+      throws InvalidProtocolBufferException {
+    return parsePartialFrom(data, off, len, EMPTY_REGISTRY);
+  }
+
+  @Override
+  public MessageType parsePartialFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return parsePartialFrom(data, 0, data.length, extensionRegistry);
+  }
+
+  @Override
+  public MessageType parsePartialFrom(byte[] data) throws InvalidProtocolBufferException {
+    return parsePartialFrom(data, 0, data.length, EMPTY_REGISTRY);
+  }
+
+  @Override
+  public MessageType parseFrom(
+      byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return checkMessageInitialized(
+        parsePartialFrom(data, off, len, extensionRegistry));
+  }
+
+  @Override
+  public MessageType parseFrom(byte[] data, int off, int len)
+      throws InvalidProtocolBufferException {
+    return parseFrom(data, off, len, EMPTY_REGISTRY);
+  }
+
+  @Override
+  public MessageType parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return parseFrom(data, 0, data.length, extensionRegistry);
+  }
+
+  @Override
+  public MessageType parseFrom(byte[] data) throws InvalidProtocolBufferException {
+    return parseFrom(data, EMPTY_REGISTRY);
+  }
+
+  @Override
+  public MessageType parsePartialFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    CodedInputStream codedInput = CodedInputStream.newInstance(input);
+    MessageType message = parsePartialFrom(codedInput, extensionRegistry);
+    try {
+      codedInput.checkLastTagWas(0);
+    } catch (InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(message);
+    }
+    return message;
+  }
+
+  @Override
+  public MessageType parsePartialFrom(InputStream input) throws InvalidProtocolBufferException {
+    return parsePartialFrom(input, EMPTY_REGISTRY);
+  }
+
+  @Override
+  public MessageType parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return checkMessageInitialized(
+        parsePartialFrom(input, extensionRegistry));
+  }
+
+  @Override
+  public MessageType parseFrom(InputStream input) throws InvalidProtocolBufferException {
+    return parseFrom(input, EMPTY_REGISTRY);
+  }
+
+  @Override
+  public MessageType parsePartialDelimitedFrom(
+      InputStream input, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    int size;
+    try {
+      int firstByte = input.read();
+      if (firstByte == -1) {
+        return null;
+      }
+      size = CodedInputStream.readRawVarint32(firstByte, input);
+    } catch (IOException e) {
+      throw new InvalidProtocolBufferException(e.getMessage());
+    }
+    InputStream limitedInput = new LimitedInputStream(input, size);
+    return parsePartialFrom(limitedInput, extensionRegistry);
+  }
+
+  @Override
+  public MessageType parsePartialDelimitedFrom(InputStream input)
+      throws InvalidProtocolBufferException {
+    return parsePartialDelimitedFrom(input, EMPTY_REGISTRY);
+  }
+
+  @Override
+  public MessageType parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return checkMessageInitialized(
+        parsePartialDelimitedFrom(input, extensionRegistry));
+  }
+
+  @Override
+  public MessageType parseDelimitedFrom(InputStream input) throws InvalidProtocolBufferException {
+    return parseDelimitedFrom(input, EMPTY_REGISTRY);
+  }
+}

+ 180 - 0
java/src/main/java/com/google/protobuf/AbstractProtobufList.java

@@ -0,0 +1,180 @@
+// 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.Internal.ProtobufList;
+
+import java.util.AbstractList;
+import java.util.Collection;
+import java.util.List;
+import java.util.RandomAccess;
+
+/**
+ * An abstract implementation of {@link ProtobufList} which manages mutability semantics. All mutate
+ * methods must check if the list is mutable before proceeding. Subclasses must invoke
+ * {@link #ensureIsMutable()} manually when overriding those methods.
+ * <p>
+ * This implementation assumes all subclasses are array based, supporting random access.
+ */
+abstract class AbstractProtobufList<E> extends AbstractList<E> implements ProtobufList<E> {
+
+  protected static final int DEFAULT_CAPACITY = 10;
+
+  /**
+   * Whether or not this list is modifiable.
+   */
+  private boolean isMutable;
+
+  /**
+   * Constructs a mutable list by default.
+   */
+  AbstractProtobufList() {
+    isMutable = true;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (o == this) {
+      return true;
+    }
+    if (!(o instanceof List)) {
+      return false;
+    }
+    // Handle lists that do not support RandomAccess as efficiently as possible by using an iterator
+    // based approach in our super class. Otherwise our index based approach will avoid those
+    // allocations.
+    if (!(o instanceof RandomAccess)) {
+      return super.equals(o);
+    }
+
+    List<?> other = (List<?>) o;
+    final int size = size();
+    if (size != other.size()) {
+      return false;
+    }
+    for (int i = 0; i < size; i++) {
+      if (!get(i).equals(other.get(i))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    final int size = size();
+    int hashCode = 1;
+    for (int i = 0; i < size; i++) {
+      hashCode = (31 * hashCode) + get(i).hashCode();
+    }
+    return hashCode;
+  }
+
+  @Override
+  public boolean add(E e) {
+    ensureIsMutable();
+    return super.add(e);
+  }
+
+  @Override
+  public void add(int index, E element) {
+    ensureIsMutable();
+    super.add(index, element);
+  }
+
+  @Override
+  public boolean addAll(Collection<? extends E> c) {
+    ensureIsMutable();
+    return super.addAll(c);
+  }
+  
+  @Override
+  public boolean addAll(int index, Collection<? extends E> c) {
+    ensureIsMutable();
+    return super.addAll(index, c);
+  }
+
+  @Override
+  public void clear() {
+    ensureIsMutable();
+    super.clear();
+  }
+  
+  @Override
+  public boolean isModifiable() {
+    return isMutable;
+  }
+  
+  @Override
+  public final void makeImmutable() {
+    isMutable = false;
+  }
+  
+  @Override
+  public E remove(int index) {
+    ensureIsMutable();
+    return super.remove(index);
+  }
+  
+  @Override
+  public boolean remove(Object o) {
+    ensureIsMutable();
+    return super.remove(o);
+  }
+  
+  @Override
+  public boolean removeAll(Collection<?> c) {
+    ensureIsMutable();
+    return super.removeAll(c);
+  }
+  
+  @Override
+  public boolean retainAll(Collection<?> c) {
+    ensureIsMutable();
+    return super.retainAll(c);
+  }
+  
+  @Override
+  public E set(int index, E element) {
+    ensureIsMutable();
+    return super.set(index, element);
+  }
+  
+  /**
+   * Throws an {@link UnsupportedOperationException} if the list is immutable. Subclasses are
+   * responsible for invoking this method on mutate operations.
+   */
+  protected void ensureIsMutable() {
+    if (!isMutable) {
+      throw new UnsupportedOperationException();
+    }
+  }
+}

+ 51 - 0
java/src/main/java/com/google/protobuf/BlockingRpcChannel.java

@@ -0,0 +1,51 @@
+// 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;
+
+/**
+ * <p>Abstract interface for a blocking RPC channel.  {@code BlockingRpcChannel}
+ * is the blocking equivalent to {@link RpcChannel}.
+ *
+ * @author kenton@google.com Kenton Varda
+ * @author cpovirk@google.com Chris Povirk
+ */
+public interface BlockingRpcChannel {
+  /**
+   * Call the given method of the remote service and blocks until it returns.
+   * {@code callBlockingMethod()} is the blocking equivalent to
+   * {@link RpcChannel#callMethod}.
+   */
+  Message callBlockingMethod(
+      Descriptors.MethodDescriptor method,
+      RpcController controller,
+      Message request,
+      Message responsePrototype) throws ServiceException;
+}

+ 64 - 0
java/src/main/java/com/google/protobuf/BlockingService.java

@@ -0,0 +1,64 @@
+// 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;
+
+/**
+ * Blocking equivalent to {@link Service}.
+ *
+ * @author kenton@google.com Kenton Varda
+ * @author cpovirk@google.com Chris Povirk
+ */
+public interface BlockingService {
+  /**
+   * Equivalent to {@link Service#getDescriptorForType}.
+   */
+  Descriptors.ServiceDescriptor getDescriptorForType();
+
+  /**
+   * Equivalent to {@link Service#callMethod}, except that
+   * {@code callBlockingMethod()} returns the result of the RPC or throws a
+   * {@link ServiceException} if there is a failure, rather than passing the
+   * information to a callback.
+   */
+  Message callBlockingMethod(Descriptors.MethodDescriptor method,
+                             RpcController controller,
+                             Message request) throws ServiceException;
+
+  /**
+   * Equivalent to {@link Service#getRequestPrototype}.
+   */
+  Message getRequestPrototype(Descriptors.MethodDescriptor method);
+
+  /**
+   * Equivalent to {@link Service#getResponsePrototype}.
+   */
+  Message getResponsePrototype(Descriptors.MethodDescriptor method);
+}

+ 5 - 1
java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java

@@ -264,7 +264,11 @@ class FieldMaskTree {
             }
             }
           }
           }
         } else {
         } else {
-          destination.setField(field, source.getField(field));
+          if (source.hasField(field) || !options.replacePrimitiveFields()) {
+            destination.setField(field, source.getField(field));
+          } else {
+            destination.clearField(field);
+          }
         }
         }
       }
       }
     }
     }

+ 37 - 8
java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java

@@ -211,14 +211,19 @@ public class FieldMaskUtil {
   public static FieldMask normalize(FieldMask mask) {
   public static FieldMask normalize(FieldMask mask) {
     return new FieldMaskTree(mask).toFieldMask();
     return new FieldMaskTree(mask).toFieldMask();
   }
   }
-  
+
   /**
   /**
-   * Creates an union of two FieldMasks.
+   * Creates a union of two or more FieldMasks.
    */
    */
-  public static FieldMask union(FieldMask mask1, FieldMask mask2) {
-    return new FieldMaskTree(mask1).mergeFromFieldMask(mask2).toFieldMask();
+  public static FieldMask union(
+      FieldMask firstMask, FieldMask secondMask, FieldMask... otherMasks) {
+    FieldMaskTree maskTree = new FieldMaskTree(firstMask).mergeFromFieldMask(secondMask);
+    for (FieldMask mask : otherMasks) {
+      maskTree.mergeFromFieldMask(mask);
+    }
+    return maskTree.toFieldMask();
   }
   }
-  
+
   /**
   /**
    * Calculates the intersection of two FieldMasks.
    * Calculates the intersection of two FieldMasks.
    */
    */
@@ -237,6 +242,9 @@ public class FieldMaskUtil {
   public static final class MergeOptions {
   public static final class MergeOptions {
     private boolean replaceMessageFields = false;
     private boolean replaceMessageFields = false;
     private boolean replaceRepeatedFields = false;
     private boolean replaceRepeatedFields = false;
+    // TODO(b/28277137): change the default behavior to always replace primitive fields after
+    // fixing all failing TAP tests.
+    private boolean replacePrimitiveFields = false;
 
 
     /**
     /**
      * Whether to replace message fields (i.e., discard existing content in
      * Whether to replace message fields (i.e., discard existing content in
@@ -257,7 +265,23 @@ public class FieldMaskUtil {
     public boolean replaceRepeatedFields() {
     public boolean replaceRepeatedFields() {
       return replaceRepeatedFields;
       return replaceRepeatedFields;
     }
     }
-    
+
+    /**
+     * Whether to replace primitive (non-repeated and non-message) fields in
+     * destination message fields with the source primitive fields (i.e., if the
+     * field is set in the source, the value is copied to the
+     * destination; if the field is unset in the source, the field is cleared
+     * from the destination) when merging.
+     *
+     * <p>Default behavior is to always set the value of the source primitive
+     * field to the destination primitive field, and if the source field is
+     * unset, the default value of the source field is copied to the
+     * destination.
+     */
+    public boolean replacePrimitiveFields() {
+      return replacePrimitiveFields;
+    }
+
     public void setReplaceMessageFields(boolean value) {
     public void setReplaceMessageFields(boolean value) {
       replaceMessageFields = value;
       replaceMessageFields = value;
     }
     }
@@ -265,10 +289,15 @@ public class FieldMaskUtil {
     public void setReplaceRepeatedFields(boolean value) {
     public void setReplaceRepeatedFields(boolean value) {
       replaceRepeatedFields = value;
       replaceRepeatedFields = value;
     }
     }
+
+    public void setReplacePrimitiveFields(boolean value) {
+      replacePrimitiveFields = value;
+    }
   }
   }
-  
+
   /**
   /**
-   * Merges fields specified by a FieldMask from one message to another.
+   * Merges fields specified by a FieldMask from one message to another with the
+   * specified merge options.
    */
    */
   public static void merge(FieldMask mask, Message source,
   public static void merge(FieldMask mask, Message source,
       Message.Builder destination, MergeOptions options) {
       Message.Builder destination, MergeOptions options) {

+ 20 - 0
java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java

@@ -237,5 +237,25 @@ public class FieldMaskTreeTest extends TestCase {
     builder.getPayloadBuilder().setOptionalUint32(2000);
     builder.getPayloadBuilder().setOptionalUint32(2000);
     new FieldMaskTree().addFieldPath("payload").merge(clearedSource, builder, options);
     new FieldMaskTree().addFieldPath("payload").merge(clearedSource, builder, options);
     assertEquals(false, builder.hasPayload());
     assertEquals(false, builder.hasPayload());
+
+    // Test merging unset primitive fields.
+    builder = source.toBuilder();
+    builder.getPayloadBuilder().clearOptionalInt32();
+    NestedTestAllTypes sourceWithPayloadInt32Unset = builder.build();
+    builder = source.toBuilder();
+    new FieldMaskTree()
+        .addFieldPath("payload.optional_int32")
+        .merge(sourceWithPayloadInt32Unset, builder, options);
+    assertEquals(true, builder.getPayload().hasOptionalInt32());
+    assertEquals(0, builder.getPayload().getOptionalInt32());
+
+    // Change to clear unset primitive fields.
+    options.setReplacePrimitiveFields(true);
+    builder = source.toBuilder();
+    new FieldMaskTree()
+        .addFieldPath("payload.optional_int32")
+        .merge(sourceWithPayloadInt32Unset, builder, options);
+    assertEquals(true, builder.hasPayload());
+    assertEquals(false, builder.getPayload().hasOptionalInt32());
   }
   }
 }
 }

+ 9 - 0
java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java

@@ -152,6 +152,15 @@ public class FieldMaskUtilTest extends TestCase {
     FieldMask result = FieldMaskUtil.union(mask1, mask2);
     FieldMask result = FieldMaskUtil.union(mask1, mask2);
     assertEquals("bar,foo", FieldMaskUtil.toString(result));
     assertEquals("bar,foo", FieldMaskUtil.toString(result));
   }
   }
+
+  public void testUnion_usingVarArgs() throws Exception {
+    FieldMask mask1 = FieldMaskUtil.fromString("foo");
+    FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar.quz");
+    FieldMask mask3 = FieldMaskUtil.fromString("bar.quz");
+    FieldMask mask4 = FieldMaskUtil.fromString("bar");
+    FieldMask result = FieldMaskUtil.union(mask1, mask2, mask3, mask4);
+    assertEquals("bar,foo", FieldMaskUtil.toString(result));
+  }
   
   
   public void testIntersection() throws Exception {
   public void testIntersection() throws Exception {
     // Only test a simple case here and expect
     // Only test a simple case here and expect

+ 50 - 0
js/binary/utils.js

@@ -567,6 +567,56 @@ jspb.utils.hash64ArrayToDecimalStrings = function(hashes, signed) {
 };
 };
 
 
 
 
+/**
+ * Converts a signed or unsigned decimal string into its hash string
+ * representation.
+ * @param {string} dec
+ * @return {string}
+ */
+jspb.utils.decimalStringToHash64 = function(dec) {
+  goog.asserts.assert(dec.length > 0);
+
+  // Check for minus sign.
+  var minus = false;
+  if (dec[0] === '-') {
+    minus = true;
+    dec = dec.slice(1);
+  }
+
+  // Store result as a byte array.
+  var resultBytes = [0, 0, 0, 0, 0, 0, 0, 0];
+
+  // Set result to m*result + c.
+  function muladd(m, c) {
+    for (var i = 0; i < 8 && (m !== 1 || c > 0); i++) {
+      var r = m * resultBytes[i] + c;
+      resultBytes[i] = r & 0xFF;
+      c = r >>> 8;
+    }
+  }
+
+  // Negate the result bits.
+  function neg() {
+    for (var i = 0; i < 8; i++) {
+      resultBytes[i] = (~resultBytes[i]) & 0xFF;
+    }
+  }
+
+  // For each decimal digit, set result to 10*result + digit.
+  for (var i = 0; i < dec.length; i++) {
+    muladd(10, jspb.utils.DIGITS.indexOf(dec[i]));
+  }
+
+  // If there's a minus sign, convert into two's complement.
+  if (minus) {
+    neg();
+    muladd(1, 1);
+  }
+
+  return String.fromCharCode.apply(null, resultBytes);
+};
+
+
 /**
 /**
  * Converts an 8-character hash string into its hexadecimal representation.
  * Converts an 8-character hash string into its hexadecimal representation.
  * @param {string} hash
  * @param {string} hash

+ 35 - 0
js/binary/utils_test.js

@@ -197,6 +197,41 @@ describe('binaryUtilsTest', function() {
     assertEquals('123456789123456789', result[2]);
     assertEquals('123456789123456789', result[2]);
   });
   });
 
 
+  /*
+   * Going from decimal strings to hash strings should be lossless.
+   */
+  it('testDecimalToHashConversion', function() {
+    var result;
+    var convert = jspb.utils.decimalStringToHash64;
+
+    result = convert('0');
+    assertEquals(String.fromCharCode.apply(null,
+      [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result);
+
+    result = convert('-1');
+    assertEquals(String.fromCharCode.apply(null,
+      [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result);
+
+    result = convert('18446744073709551615');
+    assertEquals(String.fromCharCode.apply(null,
+      [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result);
+
+    result = convert('9223372036854775808');
+    assertEquals(String.fromCharCode.apply(null,
+      [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result);
+
+    result = convert('-9223372036854775808');
+    assertEquals(String.fromCharCode.apply(null,
+      [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result);
+
+    result = convert('123456789123456789');
+    assertEquals(String.fromCharCode.apply(null,
+      [0x15, 0x5F, 0xD0, 0xAC, 0x4B, 0x9B, 0xB6, 0x01]), result);
+
+    result = convert('-123456789123456789');
+    assertEquals(String.fromCharCode.apply(null,
+      [0xEB, 0xA0, 0x2F, 0x53, 0xB4, 0x64, 0x49, 0xFE]), result);
+  });
 
 
   /**
   /**
    * Going from hash strings to hex strings should be lossless.
    * Going from hash strings to hex strings should be lossless.

+ 134 - 0
objectivec/google/google/protobuf/Any.pbobjc.h

@@ -0,0 +1,134 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/any.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
+#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+CF_EXTERN_C_BEGIN
+
+NS_ASSUME_NONNULL_BEGIN
+
+#pragma mark - GPBAnyRoot
+
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
+@interface GPBAnyRoot : GPBRootObject
+@end
+
+#pragma mark - GPBAny
+
+typedef GPB_ENUM(GPBAny_FieldNumber) {
+  GPBAny_FieldNumber_TypeURL = 1,
+  GPBAny_FieldNumber_Value = 2,
+};
+
+/// `Any` contains an arbitrary serialized protocol buffer message along with a
+/// URL that describes the type of the serialized message.
+///
+/// Protobuf library provides support to pack/unpack Any values in the form
+/// of utility functions or additional generated methods of the Any type.
+///
+/// Example 1: Pack and unpack a message in C++.
+///
+///     Foo foo = ...;
+///     Any any;
+///     any.PackFrom(foo);
+///     ...
+///     if (any.UnpackTo(&foo)) {
+///       ...
+///     }
+///
+/// Example 2: Pack and unpack a message in Java.
+///
+///     Foo foo = ...;
+///     Any any = Any.pack(foo);
+///     ...
+///     if (any.is(Foo.class)) {
+///       foo = any.unpack(Foo.class);
+///     }
+///
+/// The pack methods provided by protobuf library will by default use
+/// 'type.googleapis.com/full.type.name' as the type URL and the unpack
+/// methods only use the fully qualified type name after the last '/'
+/// in the type URL, for example "foo.bar.com/x/y.z" will yield type
+/// name "y.z".
+///
+///
+/// JSON
+/// ====
+/// The JSON representation of an `Any` value uses the regular
+/// representation of the deserialized, embedded message, with an
+/// additional field `\@type` which contains the type URL. Example:
+///
+///     package google.profile;
+///     message Person {
+///       string first_name = 1;
+///       string last_name = 2;
+///     }
+///
+///     {
+///       "\@type": "type.googleapis.com/google.profile.Person",
+///       "firstName": <string>,
+///       "lastName": <string>
+///     }
+///
+/// If the embedded message type is well-known and has a custom JSON
+/// representation, that representation will be embedded adding a field
+/// `value` which holds the custom JSON in addition to the `\@type`
+/// field. Example (for message [google.protobuf.Duration][]):
+///
+///     {
+///       "\@type": "type.googleapis.com/google.protobuf.Duration",
+///       "value": "1.212s"
+///     }
+@interface GPBAny : GPBMessage
+
+/// A URL/resource name whose content describes the type of the
+/// serialized protocol buffer message.
+///
+/// For URLs which use the schema `http`, `https`, or no schema, the
+/// following restrictions and interpretations apply:
+///
+/// * If no schema is provided, `https` is assumed.
+/// * The last segment of the URL's path must represent the fully
+///   qualified name of the type (as in `path/google.protobuf.Duration`).
+///   The name should be in a canonical form (e.g., leading "." is
+///   not accepted).
+/// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
+///   value in binary format, or produce an error.
+/// * Applications are allowed to cache lookup results based on the
+///   URL, or have them precompiled into a binary to avoid any
+///   lookup. Therefore, binary compatibility needs to be preserved
+///   on changes to types. (Use versioned type names to manage
+///   breaking changes.)
+///
+/// Schemas other than `http`, `https` (or the empty schema) might be
+/// used with implementation specific semantics.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *typeURL;
+
+/// Must be a valid serialized protocol buffer of the above specified type.
+@property(nonatomic, readwrite, copy, null_resettable) NSData *value;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+CF_EXTERN_C_END
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 93 - 0
objectivec/google/google/protobuf/Any.pbobjc.m

@@ -0,0 +1,93 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/any.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Any.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+#pragma mark - GPBAnyRoot
+
+@implementation GPBAnyRoot
+
+@end
+
+#pragma mark - GPBAnyRoot_FileDescriptor
+
+static GPBFileDescriptor *GPBAnyRoot_FileDescriptor(void) {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety of the singleton.
+  static GPBFileDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBAny
+
+@implementation GPBAny
+
+@dynamic typeURL;
+@dynamic value;
+
+typedef struct GPBAny__storage_ {
+  uint32_t _has_storage_[1];
+  NSString *typeURL;
+  NSData *value;
+} GPBAny__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "typeURL",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBAny_FieldNumber_TypeURL,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBAny__storage_, typeURL),
+        .flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "value",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBAny_FieldNumber_Value,
+        .hasIndex = 1,
+        .offset = (uint32_t)offsetof(GPBAny__storage_, value),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeBytes,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBAny class]
+                                     rootClass:[GPBAnyRoot class]
+                                          file:GPBAnyRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBAny__storage_)
+                                         flags:0];
+#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
+    static const char *extraTextFormatInfo =
+        "\001\001\004\241!!\000";
+    [localDescriptor setupExtraTextInfo:extraTextFormatInfo];
+#endif  // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 262 - 0
objectivec/google/google/protobuf/Api.pbobjc.h

@@ -0,0 +1,262 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/api.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
+#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+CF_EXTERN_C_BEGIN
+
+@class GPBMethod;
+@class GPBMixin;
+@class GPBOption;
+@class GPBSourceContext;
+GPB_ENUM_FWD_DECLARE(GPBSyntax);
+
+NS_ASSUME_NONNULL_BEGIN
+
+#pragma mark - GPBApiRoot
+
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
+@interface GPBApiRoot : GPBRootObject
+@end
+
+#pragma mark - GPBApi
+
+typedef GPB_ENUM(GPBApi_FieldNumber) {
+  GPBApi_FieldNumber_Name = 1,
+  GPBApi_FieldNumber_MethodsArray = 2,
+  GPBApi_FieldNumber_OptionsArray = 3,
+  GPBApi_FieldNumber_Version = 4,
+  GPBApi_FieldNumber_SourceContext = 5,
+  GPBApi_FieldNumber_MixinsArray = 6,
+  GPBApi_FieldNumber_Syntax = 7,
+};
+
+/// Api is a light-weight descriptor for a protocol buffer service.
+@interface GPBApi : GPBMessage
+
+/// The fully qualified name of this api, including package name
+/// followed by the api's simple name.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+
+/// The methods of this api, in unspecified order.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBMethod*> *methodsArray;
+/// The number of items in @c methodsArray without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger methodsArray_Count;
+
+/// Any metadata attached to the API.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger optionsArray_Count;
+
+/// A version string for this api. If specified, must have the form
+/// `major-version.minor-version`, as in `1.10`. If the minor version
+/// is omitted, it defaults to zero. If the entire version field is
+/// empty, the major version is derived from the package name, as
+/// outlined below. If the field is not empty, the version in the
+/// package name will be verified to be consistent with what is
+/// provided here.
+///
+/// The versioning schema uses [semantic
+/// versioning](http://semver.org) where the major version number
+/// indicates a breaking change and the minor version an additive,
+/// non-breaking change. Both version numbers are signals to users
+/// what to expect from different versions, and should be carefully
+/// chosen based on the product plan.
+///
+/// The major version is also reflected in the package name of the
+/// API, which must end in `v<major-version>`, as in
+/// `google.feature.v1`. For major versions 0 and 1, the suffix can
+/// be omitted. Zero major versions must only be used for
+/// experimental, none-GA apis.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *version;
+
+/// Source context for the protocol buffer service represented by this
+/// message.
+@property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext;
+/// Test to see if @c sourceContext has been set.
+@property(nonatomic, readwrite) BOOL hasSourceContext;
+
+/// Included APIs. See [Mixin][].
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBMixin*> *mixinsArray;
+/// The number of items in @c mixinsArray without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger mixinsArray_Count;
+
+/// The source syntax of the service.
+@property(nonatomic, readwrite) enum GPBSyntax syntax;
+
+@end
+
+/// Fetches the raw value of a @c GPBApi's @c syntax property, even
+/// if the value was not defined by the enum at the time the code was generated.
+int32_t GPBApi_Syntax_RawValue(GPBApi *message);
+/// Sets the raw value of an @c GPBApi's @c syntax property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
+void SetGPBApi_Syntax_RawValue(GPBApi *message, int32_t value);
+
+#pragma mark - GPBMethod
+
+typedef GPB_ENUM(GPBMethod_FieldNumber) {
+  GPBMethod_FieldNumber_Name = 1,
+  GPBMethod_FieldNumber_RequestTypeURL = 2,
+  GPBMethod_FieldNumber_RequestStreaming = 3,
+  GPBMethod_FieldNumber_ResponseTypeURL = 4,
+  GPBMethod_FieldNumber_ResponseStreaming = 5,
+  GPBMethod_FieldNumber_OptionsArray = 6,
+  GPBMethod_FieldNumber_Syntax = 7,
+};
+
+/// Method represents a method of an api.
+@interface GPBMethod : GPBMessage
+
+/// The simple name of this method.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+
+/// A URL of the input message type.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *requestTypeURL;
+
+/// If true, the request is streamed.
+@property(nonatomic, readwrite) BOOL requestStreaming;
+
+/// The URL of the output message type.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *responseTypeURL;
+
+/// If true, the response is streamed.
+@property(nonatomic, readwrite) BOOL responseStreaming;
+
+/// Any metadata attached to the method.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger optionsArray_Count;
+
+/// The source syntax of this method.
+@property(nonatomic, readwrite) enum GPBSyntax syntax;
+
+@end
+
+/// Fetches the raw value of a @c GPBMethod's @c syntax property, even
+/// if the value was not defined by the enum at the time the code was generated.
+int32_t GPBMethod_Syntax_RawValue(GPBMethod *message);
+/// Sets the raw value of an @c GPBMethod's @c syntax property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
+void SetGPBMethod_Syntax_RawValue(GPBMethod *message, int32_t value);
+
+#pragma mark - GPBMixin
+
+typedef GPB_ENUM(GPBMixin_FieldNumber) {
+  GPBMixin_FieldNumber_Name = 1,
+  GPBMixin_FieldNumber_Root = 2,
+};
+
+/// Declares an API to be included in this API. The including API must
+/// redeclare all the methods from the included API, but documentation
+/// and options are inherited as follows:
+///
+/// - If after comment and whitespace stripping, the documentation
+///   string of the redeclared method is empty, it will be inherited
+///   from the original method.
+///
+/// - Each annotation belonging to the service config (http,
+///   visibility) which is not set in the redeclared method will be
+///   inherited.
+///
+/// - If an http annotation is inherited, the path pattern will be
+///   modified as follows. Any version prefix will be replaced by the
+///   version of the including API plus the [root][] path if specified.
+///
+/// Example of a simple mixin:
+///
+///     package google.acl.v1;
+///     service AccessControl {
+///       // Get the underlying ACL object.
+///       rpc GetAcl(GetAclRequest) returns (Acl) {
+///         option (google.api.http).get = "/v1/{resource=**}:getAcl";
+///       }
+///     }
+///
+///     package google.storage.v2;
+///     service Storage {
+///       rpc GetAcl(GetAclRequest) returns (Acl);
+///
+///       // Get a data record.
+///       rpc GetData(GetDataRequest) returns (Data) {
+///         option (google.api.http).get = "/v2/{resource=**}";
+///       }
+///     }
+///
+/// Example of a mixin configuration:
+///
+///     apis:
+///     - name: google.storage.v2.Storage
+///       mixins:
+///       - name: google.acl.v1.AccessControl
+///
+/// The mixin construct implies that all methods in `AccessControl` are
+/// also declared with same name and request/response types in
+/// `Storage`. A documentation generator or annotation processor will
+/// see the effective `Storage.GetAcl` method after inherting
+/// documentation and annotations as follows:
+///
+///     service Storage {
+///       // Get the underlying ACL object.
+///       rpc GetAcl(GetAclRequest) returns (Acl) {
+///         option (google.api.http).get = "/v2/{resource=**}:getAcl";
+///       }
+///       ...
+///     }
+///
+/// Note how the version in the path pattern changed from `v1` to `v2`.
+///
+/// If the `root` field in the mixin is specified, it should be a
+/// relative path under which inherited HTTP paths are placed. Example:
+///
+///     apis:
+///     - name: google.storage.v2.Storage
+///       mixins:
+///       - name: google.acl.v1.AccessControl
+///         root: acls
+///
+/// This implies the following inherited HTTP annotation:
+///
+///     service Storage {
+///       // Get the underlying ACL object.
+///       rpc GetAcl(GetAclRequest) returns (Acl) {
+///         option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
+///       }
+///       ...
+///     }
+@interface GPBMixin : GPBMessage
+
+/// The fully qualified name of the API which is included.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+
+/// If non-empty specifies a path under which inherited HTTP paths
+/// are rooted.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *root;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+CF_EXTERN_C_END
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 348 - 0
objectivec/google/google/protobuf/Api.pbobjc.m

@@ -0,0 +1,348 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/api.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Api.pbobjc.h"
+#import "google/protobuf/SourceContext.pbobjc.h"
+#import "google/protobuf/Type.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+#pragma mark - GPBApiRoot
+
+@implementation GPBApiRoot
+
++ (GPBExtensionRegistry*)extensionRegistry {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety and initialization of registry.
+  static GPBExtensionRegistry* registry = nil;
+  if (!registry) {
+    GPBDebugCheckRuntimeVersion();
+    registry = [[GPBExtensionRegistry alloc] init];
+    [registry addExtensions:[GPBSourceContextRoot extensionRegistry]];
+    [registry addExtensions:[GPBTypeRoot extensionRegistry]];
+  }
+  return registry;
+}
+
+@end
+
+#pragma mark - GPBApiRoot_FileDescriptor
+
+static GPBFileDescriptor *GPBApiRoot_FileDescriptor(void) {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety of the singleton.
+  static GPBFileDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBApi
+
+@implementation GPBApi
+
+@dynamic name;
+@dynamic methodsArray, methodsArray_Count;
+@dynamic optionsArray, optionsArray_Count;
+@dynamic version;
+@dynamic hasSourceContext, sourceContext;
+@dynamic mixinsArray, mixinsArray_Count;
+@dynamic syntax;
+
+typedef struct GPBApi__storage_ {
+  uint32_t _has_storage_[1];
+  GPBSyntax syntax;
+  NSString *name;
+  NSMutableArray *methodsArray;
+  NSMutableArray *optionsArray;
+  NSString *version;
+  GPBSourceContext *sourceContext;
+  NSMutableArray *mixinsArray;
+} GPBApi__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "name",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBApi_FieldNumber_Name,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBApi__storage_, name),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "methodsArray",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBMethod),
+        .number = GPBApi_FieldNumber_MethodsArray,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBApi__storage_, methodsArray),
+        .flags = GPBFieldRepeated,
+        .dataType = GPBDataTypeMessage,
+      },
+      {
+        .name = "optionsArray",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
+        .number = GPBApi_FieldNumber_OptionsArray,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBApi__storage_, optionsArray),
+        .flags = GPBFieldRepeated,
+        .dataType = GPBDataTypeMessage,
+      },
+      {
+        .name = "version",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBApi_FieldNumber_Version,
+        .hasIndex = 1,
+        .offset = (uint32_t)offsetof(GPBApi__storage_, version),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "sourceContext",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceContext),
+        .number = GPBApi_FieldNumber_SourceContext,
+        .hasIndex = 2,
+        .offset = (uint32_t)offsetof(GPBApi__storage_, sourceContext),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeMessage,
+      },
+      {
+        .name = "mixinsArray",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBMixin),
+        .number = GPBApi_FieldNumber_MixinsArray,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBApi__storage_, mixinsArray),
+        .flags = GPBFieldRepeated,
+        .dataType = GPBDataTypeMessage,
+      },
+      {
+        .name = "syntax",
+        .dataTypeSpecific.enumDescFunc = GPBSyntax_EnumDescriptor,
+        .number = GPBApi_FieldNumber_Syntax,
+        .hasIndex = 3,
+        .offset = (uint32_t)offsetof(GPBApi__storage_, syntax),
+        .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
+        .dataType = GPBDataTypeEnum,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBApi class]
+                                     rootClass:[GPBApiRoot class]
+                                          file:GPBApiRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBApi__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+int32_t GPBApi_Syntax_RawValue(GPBApi *message) {
+  GPBDescriptor *descriptor = [GPBApi descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBApi_FieldNumber_Syntax];
+  return GPBGetMessageInt32Field(message, field);
+}
+
+void SetGPBApi_Syntax_RawValue(GPBApi *message, int32_t value) {
+  GPBDescriptor *descriptor = [GPBApi descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBApi_FieldNumber_Syntax];
+  GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax);
+}
+
+#pragma mark - GPBMethod
+
+@implementation GPBMethod
+
+@dynamic name;
+@dynamic requestTypeURL;
+@dynamic requestStreaming;
+@dynamic responseTypeURL;
+@dynamic responseStreaming;
+@dynamic optionsArray, optionsArray_Count;
+@dynamic syntax;
+
+typedef struct GPBMethod__storage_ {
+  uint32_t _has_storage_[1];
+  GPBSyntax syntax;
+  NSString *name;
+  NSString *requestTypeURL;
+  NSString *responseTypeURL;
+  NSMutableArray *optionsArray;
+} GPBMethod__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "name",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBMethod_FieldNumber_Name,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBMethod__storage_, name),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "requestTypeURL",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBMethod_FieldNumber_RequestTypeURL,
+        .hasIndex = 1,
+        .offset = (uint32_t)offsetof(GPBMethod__storage_, requestTypeURL),
+        .flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "requestStreaming",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBMethod_FieldNumber_RequestStreaming,
+        .hasIndex = 2,
+        .offset = 3,  // Stored in _has_storage_ to save space.
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeBool,
+      },
+      {
+        .name = "responseTypeURL",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBMethod_FieldNumber_ResponseTypeURL,
+        .hasIndex = 4,
+        .offset = (uint32_t)offsetof(GPBMethod__storage_, responseTypeURL),
+        .flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "responseStreaming",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBMethod_FieldNumber_ResponseStreaming,
+        .hasIndex = 5,
+        .offset = 6,  // Stored in _has_storage_ to save space.
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeBool,
+      },
+      {
+        .name = "optionsArray",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
+        .number = GPBMethod_FieldNumber_OptionsArray,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBMethod__storage_, optionsArray),
+        .flags = GPBFieldRepeated,
+        .dataType = GPBDataTypeMessage,
+      },
+      {
+        .name = "syntax",
+        .dataTypeSpecific.enumDescFunc = GPBSyntax_EnumDescriptor,
+        .number = GPBMethod_FieldNumber_Syntax,
+        .hasIndex = 7,
+        .offset = (uint32_t)offsetof(GPBMethod__storage_, syntax),
+        .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
+        .dataType = GPBDataTypeEnum,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBMethod class]
+                                     rootClass:[GPBApiRoot class]
+                                          file:GPBApiRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBMethod__storage_)
+                                         flags:0];
+#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
+    static const char *extraTextFormatInfo =
+        "\002\002\007\244\241!!\000\004\010\244\241!!\000";
+    [localDescriptor setupExtraTextInfo:extraTextFormatInfo];
+#endif  // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+int32_t GPBMethod_Syntax_RawValue(GPBMethod *message) {
+  GPBDescriptor *descriptor = [GPBMethod descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBMethod_FieldNumber_Syntax];
+  return GPBGetMessageInt32Field(message, field);
+}
+
+void SetGPBMethod_Syntax_RawValue(GPBMethod *message, int32_t value) {
+  GPBDescriptor *descriptor = [GPBMethod descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBMethod_FieldNumber_Syntax];
+  GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax);
+}
+
+#pragma mark - GPBMixin
+
+@implementation GPBMixin
+
+@dynamic name;
+@dynamic root;
+
+typedef struct GPBMixin__storage_ {
+  uint32_t _has_storage_[1];
+  NSString *name;
+  NSString *root;
+} GPBMixin__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "name",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBMixin_FieldNumber_Name,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBMixin__storage_, name),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "root",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBMixin_FieldNumber_Root,
+        .hasIndex = 1,
+        .offset = (uint32_t)offsetof(GPBMixin__storage_, root),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBMixin class]
+                                     rootClass:[GPBApiRoot class]
+                                          file:GPBApiRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBMixin__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 101 - 0
objectivec/google/google/protobuf/Duration.pbobjc.h

@@ -0,0 +1,101 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/duration.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
+#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+CF_EXTERN_C_BEGIN
+
+NS_ASSUME_NONNULL_BEGIN
+
+#pragma mark - GPBDurationRoot
+
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
+@interface GPBDurationRoot : GPBRootObject
+@end
+
+#pragma mark - GPBDuration
+
+typedef GPB_ENUM(GPBDuration_FieldNumber) {
+  GPBDuration_FieldNumber_Seconds = 1,
+  GPBDuration_FieldNumber_Nanos = 2,
+};
+
+/// A Duration represents a signed, fixed-length span of time represented
+/// as a count of seconds and fractions of seconds at nanosecond
+/// resolution. It is independent of any calendar and concepts like "day"
+/// or "month". It is related to Timestamp in that the difference between
+/// two Timestamp values is a Duration and it can be added or subtracted
+/// from a Timestamp. Range is approximately +-10,000 years.
+///
+/// Example 1: Compute Duration from two Timestamps in pseudo code.
+///
+///     Timestamp start = ...;
+///     Timestamp end = ...;
+///     Duration duration = ...;
+///
+///     duration.seconds = end.seconds - start.seconds;
+///     duration.nanos = end.nanos - start.nanos;
+///
+///     if (duration.seconds < 0 && duration.nanos > 0) {
+///       duration.seconds += 1;
+///       duration.nanos -= 1000000000;
+///     } else if (durations.seconds > 0 && duration.nanos < 0) {
+///       duration.seconds -= 1;
+///       duration.nanos += 1000000000;
+///     }
+///
+/// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
+///
+///     Timestamp start = ...;
+///     Duration duration = ...;
+///     Timestamp end = ...;
+///
+///     end.seconds = start.seconds + duration.seconds;
+///     end.nanos = start.nanos + duration.nanos;
+///
+///     if (end.nanos < 0) {
+///       end.seconds -= 1;
+///       end.nanos += 1000000000;
+///     } else if (end.nanos >= 1000000000) {
+///       end.seconds += 1;
+///       end.nanos -= 1000000000;
+///     }
+@interface GPBDuration : GPBMessage
+
+/// Signed seconds of the span of time. Must be from -315,576,000,000
+/// to +315,576,000,000 inclusive.
+@property(nonatomic, readwrite) int64_t seconds;
+
+/// Signed fractions of a second at nanosecond resolution of the span
+/// of time. Durations less than one second are represented with a 0
+/// `seconds` field and a positive or negative `nanos` field. For durations
+/// of one second or more, a non-zero value for the `nanos` field must be
+/// of the same sign as the `seconds` field. Must be from -999,999,999
+/// to +999,999,999 inclusive.
+@property(nonatomic, readwrite) int32_t nanos;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+CF_EXTERN_C_END
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 88 - 0
objectivec/google/google/protobuf/Duration.pbobjc.m

@@ -0,0 +1,88 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/duration.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Duration.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+#pragma mark - GPBDurationRoot
+
+@implementation GPBDurationRoot
+
+@end
+
+#pragma mark - GPBDurationRoot_FileDescriptor
+
+static GPBFileDescriptor *GPBDurationRoot_FileDescriptor(void) {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety of the singleton.
+  static GPBFileDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBDuration
+
+@implementation GPBDuration
+
+@dynamic seconds;
+@dynamic nanos;
+
+typedef struct GPBDuration__storage_ {
+  uint32_t _has_storage_[1];
+  int32_t nanos;
+  int64_t seconds;
+} GPBDuration__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "seconds",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBDuration_FieldNumber_Seconds,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBDuration__storage_, seconds),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeInt64,
+      },
+      {
+        .name = "nanos",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBDuration_FieldNumber_Nanos,
+        .hasIndex = 1,
+        .offset = (uint32_t)offsetof(GPBDuration__storage_, nanos),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeInt32,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBDuration class]
+                                     rootClass:[GPBDurationRoot class]
+                                          file:GPBDurationRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBDuration__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 53 - 0
objectivec/google/google/protobuf/Empty.pbobjc.h

@@ -0,0 +1,53 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/empty.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
+#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+CF_EXTERN_C_BEGIN
+
+NS_ASSUME_NONNULL_BEGIN
+
+#pragma mark - GPBEmptyRoot
+
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
+@interface GPBEmptyRoot : GPBRootObject
+@end
+
+#pragma mark - GPBEmpty
+
+/// A generic empty message that you can re-use to avoid defining duplicated
+/// empty messages in your APIs. A typical example is to use it as the request
+/// or the response type of an API method. For instance:
+///
+///     service Foo {
+///       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
+///     }
+///
+/// The JSON representation for `Empty` is empty JSON object `{}`.
+@interface GPBEmpty : GPBMessage
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+CF_EXTERN_C_END
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 64 - 0
objectivec/google/google/protobuf/Empty.pbobjc.m

@@ -0,0 +1,64 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/empty.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Empty.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+#pragma mark - GPBEmptyRoot
+
+@implementation GPBEmptyRoot
+
+@end
+
+#pragma mark - GPBEmptyRoot_FileDescriptor
+
+static GPBFileDescriptor *GPBEmptyRoot_FileDescriptor(void) {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety of the singleton.
+  static GPBFileDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBEmpty
+
+@implementation GPBEmpty
+
+
+typedef struct GPBEmpty__storage_ {
+  uint32_t _has_storage_[1];
+} GPBEmpty__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBEmpty class]
+                                     rootClass:[GPBEmptyRoot class]
+                                          file:GPBEmptyRoot_FileDescriptor()
+                                        fields:NULL
+                                    fieldCount:0
+                                   storageSize:sizeof(GPBEmpty__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 202 - 0
objectivec/google/google/protobuf/FieldMask.pbobjc.h

@@ -0,0 +1,202 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/field_mask.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
+#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+CF_EXTERN_C_BEGIN
+
+NS_ASSUME_NONNULL_BEGIN
+
+#pragma mark - GPBFieldMaskRoot
+
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
+@interface GPBFieldMaskRoot : GPBRootObject
+@end
+
+#pragma mark - GPBFieldMask
+
+typedef GPB_ENUM(GPBFieldMask_FieldNumber) {
+  GPBFieldMask_FieldNumber_PathsArray = 1,
+};
+
+/// `FieldMask` represents a set of symbolic field paths, for example:
+///
+///     paths: "f.a"
+///     paths: "f.b.d"
+///
+/// Here `f` represents a field in some root message, `a` and `b`
+/// fields in the message found in `f`, and `d` a field found in the
+/// message in `f.b`.
+///
+/// Field masks are used to specify a subset of fields that should be
+/// returned by a get operation or modified by an update operation.
+/// Field masks also have a custom JSON encoding (see below).
+///
+/// # Field Masks in Projections
+///
+/// When used in the context of a projection, a response message or
+/// sub-message is filtered by the API to only contain those fields as
+/// specified in the mask. For example, if the mask in the previous
+/// example is applied to a response message as follows:
+///
+///     f {
+///       a : 22
+///       b {
+///         d : 1
+///         x : 2
+///       }
+///       y : 13
+///     }
+///     z: 8
+///
+/// The result will not contain specific values for fields x,y and z
+/// (their value will be set to the default, and omitted in proto text
+/// output):
+///
+///
+///     f {
+///       a : 22
+///       b {
+///         d : 1
+///       }
+///     }
+///
+/// A repeated field is not allowed except at the last position of a
+/// field mask.
+///
+/// If a FieldMask object is not present in a get operation, the
+/// operation applies to all fields (as if a FieldMask of all fields
+/// had been specified).
+///
+/// Note that a field mask does not necessarily apply to the
+/// top-level response message. In case of a REST get operation, the
+/// field mask applies directly to the response, but in case of a REST
+/// list operation, the mask instead applies to each individual message
+/// in the returned resource list. In case of a REST custom method,
+/// other definitions may be used. Where the mask applies will be
+/// clearly documented together with its declaration in the API.  In
+/// any case, the effect on the returned resource/resources is required
+/// behavior for APIs.
+///
+/// # Field Masks in Update Operations
+///
+/// A field mask in update operations specifies which fields of the
+/// targeted resource are going to be updated. The API is required
+/// to only change the values of the fields as specified in the mask
+/// and leave the others untouched. If a resource is passed in to
+/// describe the updated values, the API ignores the values of all
+/// fields not covered by the mask.
+///
+/// In order to reset a field's value to the default, the field must
+/// be in the mask and set to the default value in the provided resource.
+/// Hence, in order to reset all fields of a resource, provide a default
+/// instance of the resource and set all fields in the mask, or do
+/// not provide a mask as described below.
+///
+/// If a field mask is not present on update, the operation applies to
+/// all fields (as if a field mask of all fields has been specified).
+/// Note that in the presence of schema evolution, this may mean that
+/// fields the client does not know and has therefore not filled into
+/// the request will be reset to their default. If this is unwanted
+/// behavior, a specific service may require a client to always specify
+/// a field mask, producing an error if not.
+///
+/// As with get operations, the location of the resource which
+/// describes the updated values in the request message depends on the
+/// operation kind. In any case, the effect of the field mask is
+/// required to be honored by the API.
+///
+/// ## Considerations for HTTP REST
+///
+/// The HTTP kind of an update operation which uses a field mask must
+/// be set to PATCH instead of PUT in order to satisfy HTTP semantics
+/// (PUT must only be used for full updates).
+///
+/// # JSON Encoding of Field Masks
+///
+/// In JSON, a field mask is encoded as a single string where paths are
+/// separated by a comma. Fields name in each path are converted
+/// to/from lower-camel naming conventions.
+///
+/// As an example, consider the following message declarations:
+///
+///     message Profile {
+///       User user = 1;
+///       Photo photo = 2;
+///     }
+///     message User {
+///       string display_name = 1;
+///       string address = 2;
+///     }
+///
+/// In proto a field mask for `Profile` may look as such:
+///
+///     mask {
+///       paths: "user.display_name"
+///       paths: "photo"
+///     }
+///
+/// In JSON, the same mask is represented as below:
+///
+///     {
+///       mask: "user.displayName,photo"
+///     }
+///
+/// # Field Masks and Oneof Fields
+///
+/// Field masks treat fields in oneofs just as regular fields. Consider the
+/// following message:
+///
+///     message SampleMessage {
+///       oneof test_oneof {
+///         string name = 4;
+///         SubMessage sub_message = 9;
+///       }
+///     }
+///
+/// The field mask can be:
+///
+///     mask {
+///       paths: "name"
+///     }
+///
+/// Or:
+///
+///     mask {
+///       paths: "sub_message"
+///     }
+///
+/// Note that oneof type names ("test_oneof" in this case) cannot be used in
+/// paths.
+@interface GPBFieldMask : GPBMessage
+
+/// The set of field mask paths.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<NSString*> *pathsArray;
+/// The number of items in @c pathsArray without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger pathsArray_Count;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+CF_EXTERN_C_END
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 77 - 0
objectivec/google/google/protobuf/FieldMask.pbobjc.m

@@ -0,0 +1,77 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/field_mask.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/FieldMask.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+#pragma mark - GPBFieldMaskRoot
+
+@implementation GPBFieldMaskRoot
+
+@end
+
+#pragma mark - GPBFieldMaskRoot_FileDescriptor
+
+static GPBFileDescriptor *GPBFieldMaskRoot_FileDescriptor(void) {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety of the singleton.
+  static GPBFileDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBFieldMask
+
+@implementation GPBFieldMask
+
+@dynamic pathsArray, pathsArray_Count;
+
+typedef struct GPBFieldMask__storage_ {
+  uint32_t _has_storage_[1];
+  NSMutableArray *pathsArray;
+} GPBFieldMask__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "pathsArray",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBFieldMask_FieldNumber_PathsArray,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBFieldMask__storage_, pathsArray),
+        .flags = GPBFieldRepeated,
+        .dataType = GPBDataTypeString,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBFieldMask class]
+                                     rootClass:[GPBFieldMaskRoot class]
+                                          file:GPBFieldMaskRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBFieldMask__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 54 - 0
objectivec/google/google/protobuf/SourceContext.pbobjc.h

@@ -0,0 +1,54 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/source_context.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
+#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+CF_EXTERN_C_BEGIN
+
+NS_ASSUME_NONNULL_BEGIN
+
+#pragma mark - GPBSourceContextRoot
+
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
+@interface GPBSourceContextRoot : GPBRootObject
+@end
+
+#pragma mark - GPBSourceContext
+
+typedef GPB_ENUM(GPBSourceContext_FieldNumber) {
+  GPBSourceContext_FieldNumber_FileName = 1,
+};
+
+/// `SourceContext` represents information about the source of a
+/// protobuf element, like the file in which it is defined.
+@interface GPBSourceContext : GPBMessage
+
+/// The path-qualified name of the .proto file that contained the associated
+/// protobuf element.  For example: `"google/protobuf/source.proto"`.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *fileName;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+CF_EXTERN_C_END
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 77 - 0
objectivec/google/google/protobuf/SourceContext.pbobjc.m

@@ -0,0 +1,77 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/source_context.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/SourceContext.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+#pragma mark - GPBSourceContextRoot
+
+@implementation GPBSourceContextRoot
+
+@end
+
+#pragma mark - GPBSourceContextRoot_FileDescriptor
+
+static GPBFileDescriptor *GPBSourceContextRoot_FileDescriptor(void) {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety of the singleton.
+  static GPBFileDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBSourceContext
+
+@implementation GPBSourceContext
+
+@dynamic fileName;
+
+typedef struct GPBSourceContext__storage_ {
+  uint32_t _has_storage_[1];
+  NSString *fileName;
+} GPBSourceContext__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "fileName",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBSourceContext_FieldNumber_FileName,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBSourceContext__storage_, fileName),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBSourceContext class]
+                                     rootClass:[GPBSourceContextRoot class]
+                                          file:GPBSourceContextRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBSourceContext__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 167 - 0
objectivec/google/google/protobuf/Struct.pbobjc.h

@@ -0,0 +1,167 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/struct.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
+#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+CF_EXTERN_C_BEGIN
+
+@class GPBListValue;
+@class GPBStruct;
+@class GPBValue;
+
+NS_ASSUME_NONNULL_BEGIN
+
+#pragma mark - Enum GPBNullValue
+
+/// `NullValue` is a singleton enumeration to represent the null value for the
+/// `Value` type union.
+///
+///  The JSON representation for `NullValue` is JSON `null`.
+typedef GPB_ENUM(GPBNullValue) {
+  /// Value used if any message's field encounters a value that is not defined
+  /// by this enum. The message will also have C functions to get/set the rawValue
+  /// of the field.
+  GPBNullValue_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
+  /// Null value.
+  GPBNullValue_NullValue = 0,
+};
+
+GPBEnumDescriptor *GPBNullValue_EnumDescriptor(void);
+
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
+BOOL GPBNullValue_IsValidValue(int32_t value);
+
+#pragma mark - GPBStructRoot
+
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
+@interface GPBStructRoot : GPBRootObject
+@end
+
+#pragma mark - GPBStruct
+
+typedef GPB_ENUM(GPBStruct_FieldNumber) {
+  GPBStruct_FieldNumber_Fields = 1,
+};
+
+/// `Struct` represents a structured data value, consisting of fields
+/// which map to dynamically typed values. In some languages, `Struct`
+/// might be supported by a native representation. For example, in
+/// scripting languages like JS a struct is represented as an
+/// object. The details of that representation are described together
+/// with the proto support for the language.
+///
+/// The JSON representation for `Struct` is JSON object.
+@interface GPBStruct : GPBMessage
+
+/// Unordered map of dynamically typed values.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableDictionary<NSString*, GPBValue*> *fields;
+/// The number of items in @c fields without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger fields_Count;
+
+@end
+
+#pragma mark - GPBValue
+
+typedef GPB_ENUM(GPBValue_FieldNumber) {
+  GPBValue_FieldNumber_NullValue = 1,
+  GPBValue_FieldNumber_NumberValue = 2,
+  GPBValue_FieldNumber_StringValue = 3,
+  GPBValue_FieldNumber_BoolValue = 4,
+  GPBValue_FieldNumber_StructValue = 5,
+  GPBValue_FieldNumber_ListValue = 6,
+};
+
+typedef GPB_ENUM(GPBValue_Kind_OneOfCase) {
+  GPBValue_Kind_OneOfCase_GPBUnsetOneOfCase = 0,
+  GPBValue_Kind_OneOfCase_NullValue = 1,
+  GPBValue_Kind_OneOfCase_NumberValue = 2,
+  GPBValue_Kind_OneOfCase_StringValue = 3,
+  GPBValue_Kind_OneOfCase_BoolValue = 4,
+  GPBValue_Kind_OneOfCase_StructValue = 5,
+  GPBValue_Kind_OneOfCase_ListValue = 6,
+};
+
+/// `Value` represents a dynamically typed value which can be either
+/// null, a number, a string, a boolean, a recursive struct value, or a
+/// list of values. A producer of value is expected to set one of that
+/// variants, absence of any variant indicates an error.
+///
+/// The JSON representation for `Value` is JSON value.
+@interface GPBValue : GPBMessage
+
+/// The kind of value.
+@property(nonatomic, readonly) GPBValue_Kind_OneOfCase kindOneOfCase;
+
+/// Represents a null value.
+@property(nonatomic, readwrite) GPBNullValue nullValue;
+
+/// Represents a double value.
+@property(nonatomic, readwrite) double numberValue;
+
+/// Represents a string value.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *stringValue;
+
+/// Represents a boolean value.
+@property(nonatomic, readwrite) BOOL boolValue;
+
+/// Represents a structured value.
+@property(nonatomic, readwrite, strong, null_resettable) GPBStruct *structValue;
+
+/// Represents a repeated `Value`.
+@property(nonatomic, readwrite, strong, null_resettable) GPBListValue *listValue;
+
+@end
+
+/// Fetches the raw value of a @c GPBValue's @c nullValue property, even
+/// if the value was not defined by the enum at the time the code was generated.
+int32_t GPBValue_NullValue_RawValue(GPBValue *message);
+/// Sets the raw value of an @c GPBValue's @c nullValue property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
+void SetGPBValue_NullValue_RawValue(GPBValue *message, int32_t value);
+
+/// Clears whatever value was set for the oneof 'kind'.
+void GPBValue_ClearKindOneOfCase(GPBValue *message);
+
+#pragma mark - GPBListValue
+
+typedef GPB_ENUM(GPBListValue_FieldNumber) {
+  GPBListValue_FieldNumber_ValuesArray = 1,
+};
+
+/// `ListValue` is a wrapper around a repeated field of values.
+///
+/// The JSON representation for `ListValue` is JSON array.
+@interface GPBListValue : GPBMessage
+
+/// Repeated field of dynamically typed values.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBValue*> *valuesArray;
+/// The number of items in @c valuesArray without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger valuesArray_Count;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+CF_EXTERN_C_END
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 273 - 0
objectivec/google/google/protobuf/Struct.pbobjc.m

@@ -0,0 +1,273 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/struct.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Struct.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+#pragma mark - GPBStructRoot
+
+@implementation GPBStructRoot
+
+@end
+
+#pragma mark - GPBStructRoot_FileDescriptor
+
+static GPBFileDescriptor *GPBStructRoot_FileDescriptor(void) {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety of the singleton.
+  static GPBFileDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - Enum GPBNullValue
+
+GPBEnumDescriptor *GPBNullValue_EnumDescriptor(void) {
+  static GPBEnumDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static const char *valueNames =
+        "NullValue\000";
+    static const int32_t values[] = {
+        GPBNullValue_NullValue,
+    };
+    GPBEnumDescriptor *worker =
+        [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBNullValue)
+                                       valueNames:valueNames
+                                           values:values
+                                            count:(uint32_t)(sizeof(values) / sizeof(int32_t))
+                                     enumVerifier:GPBNullValue_IsValidValue];
+    if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) {
+      [worker release];
+    }
+  }
+  return descriptor;
+}
+
+BOOL GPBNullValue_IsValidValue(int32_t value__) {
+  switch (value__) {
+    case GPBNullValue_NullValue:
+      return YES;
+    default:
+      return NO;
+  }
+}
+
+#pragma mark - GPBStruct
+
+@implementation GPBStruct
+
+@dynamic fields, fields_Count;
+
+typedef struct GPBStruct__storage_ {
+  uint32_t _has_storage_[1];
+  NSMutableDictionary *fields;
+} GPBStruct__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "fields",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBValue),
+        .number = GPBStruct_FieldNumber_Fields,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBStruct__storage_, fields),
+        .flags = GPBFieldMapKeyString,
+        .dataType = GPBDataTypeMessage,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBStruct class]
+                                     rootClass:[GPBStructRoot class]
+                                          file:GPBStructRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBStruct__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBValue
+
+@implementation GPBValue
+
+@dynamic kindOneOfCase;
+@dynamic nullValue;
+@dynamic numberValue;
+@dynamic stringValue;
+@dynamic boolValue;
+@dynamic structValue;
+@dynamic listValue;
+
+typedef struct GPBValue__storage_ {
+  uint32_t _has_storage_[2];
+  GPBNullValue nullValue;
+  NSString *stringValue;
+  GPBStruct *structValue;
+  GPBListValue *listValue;
+  double numberValue;
+} GPBValue__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "nullValue",
+        .dataTypeSpecific.enumDescFunc = GPBNullValue_EnumDescriptor,
+        .number = GPBValue_FieldNumber_NullValue,
+        .hasIndex = -1,
+        .offset = (uint32_t)offsetof(GPBValue__storage_, nullValue),
+        .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
+        .dataType = GPBDataTypeEnum,
+      },
+      {
+        .name = "numberValue",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBValue_FieldNumber_NumberValue,
+        .hasIndex = -1,
+        .offset = (uint32_t)offsetof(GPBValue__storage_, numberValue),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeDouble,
+      },
+      {
+        .name = "stringValue",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBValue_FieldNumber_StringValue,
+        .hasIndex = -1,
+        .offset = (uint32_t)offsetof(GPBValue__storage_, stringValue),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "boolValue",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBValue_FieldNumber_BoolValue,
+        .hasIndex = -1,
+        .offset = 0,  // Stored in _has_storage_ to save space.
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeBool,
+      },
+      {
+        .name = "structValue",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBStruct),
+        .number = GPBValue_FieldNumber_StructValue,
+        .hasIndex = -1,
+        .offset = (uint32_t)offsetof(GPBValue__storage_, structValue),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeMessage,
+      },
+      {
+        .name = "listValue",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBListValue),
+        .number = GPBValue_FieldNumber_ListValue,
+        .hasIndex = -1,
+        .offset = (uint32_t)offsetof(GPBValue__storage_, listValue),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeMessage,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBValue class]
+                                     rootClass:[GPBStructRoot class]
+                                          file:GPBStructRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBValue__storage_)
+                                         flags:0];
+    static const char *oneofs[] = {
+      "kind",
+    };
+    [localDescriptor setupOneofs:oneofs
+                           count:(uint32_t)(sizeof(oneofs) / sizeof(char*))
+                   firstHasIndex:-1];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+int32_t GPBValue_NullValue_RawValue(GPBValue *message) {
+  GPBDescriptor *descriptor = [GPBValue descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBValue_FieldNumber_NullValue];
+  return GPBGetMessageInt32Field(message, field);
+}
+
+void SetGPBValue_NullValue_RawValue(GPBValue *message, int32_t value) {
+  GPBDescriptor *descriptor = [GPBValue descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBValue_FieldNumber_NullValue];
+  GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax);
+}
+
+void GPBValue_ClearKindOneOfCase(GPBValue *message) {
+  GPBDescriptor *descriptor = [message descriptor];
+  GPBOneofDescriptor *oneof = descriptor->oneofs_[0];
+  GPBMaybeClearOneof(message, oneof, -1, 0);
+}
+#pragma mark - GPBListValue
+
+@implementation GPBListValue
+
+@dynamic valuesArray, valuesArray_Count;
+
+typedef struct GPBListValue__storage_ {
+  uint32_t _has_storage_[1];
+  NSMutableArray *valuesArray;
+} GPBListValue__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "valuesArray",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBValue),
+        .number = GPBListValue_FieldNumber_ValuesArray,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBListValue__storage_, valuesArray),
+        .flags = GPBFieldRepeated,
+        .dataType = GPBDataTypeMessage,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBListValue class]
+                                     rootClass:[GPBStructRoot class]
+                                          file:GPBStructRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBListValue__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 113 - 0
objectivec/google/google/protobuf/Timestamp.pbobjc.h

@@ -0,0 +1,113 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/timestamp.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
+#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+CF_EXTERN_C_BEGIN
+
+NS_ASSUME_NONNULL_BEGIN
+
+#pragma mark - GPBTimestampRoot
+
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
+@interface GPBTimestampRoot : GPBRootObject
+@end
+
+#pragma mark - GPBTimestamp
+
+typedef GPB_ENUM(GPBTimestamp_FieldNumber) {
+  GPBTimestamp_FieldNumber_Seconds = 1,
+  GPBTimestamp_FieldNumber_Nanos = 2,
+};
+
+/// A Timestamp represents a point in time independent of any time zone
+/// or calendar, represented as seconds and fractions of seconds at
+/// nanosecond resolution in UTC Epoch time. It is encoded using the
+/// Proleptic Gregorian Calendar which extends the Gregorian calendar
+/// backwards to year one. It is encoded assuming all minutes are 60
+/// seconds long, i.e. leap seconds are "smeared" so that no leap second
+/// table is needed for interpretation. Range is from
+/// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
+/// By restricting to that range, we ensure that we can convert to
+/// and from  RFC 3339 date strings.
+/// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
+///
+/// Example 1: Compute Timestamp from POSIX `time()`.
+///
+///     Timestamp timestamp;
+///     timestamp.set_seconds(time(NULL));
+///     timestamp.set_nanos(0);
+///
+/// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
+///
+///     struct timeval tv;
+///     gettimeofday(&tv, NULL);
+///
+///     Timestamp timestamp;
+///     timestamp.set_seconds(tv.tv_sec);
+///     timestamp.set_nanos(tv.tv_usec * 1000);
+///
+/// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
+///
+///     FILETIME ft;
+///     GetSystemTimeAsFileTime(&ft);
+///     UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+///
+///     // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
+///     // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
+///     Timestamp timestamp;
+///     timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
+///     timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
+///
+/// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
+///
+///     long millis = System.currentTimeMillis();
+///
+///     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
+///         .setNanos((int) ((millis % 1000) * 1000000)).build();
+///
+///
+/// Example 5: Compute Timestamp from current time in Python.
+///
+///     now = time.time()
+///     seconds = int(now)
+///     nanos = int((now - seconds) * 10**9)
+///     timestamp = Timestamp(seconds=seconds, nanos=nanos)
+@interface GPBTimestamp : GPBMessage
+
+/// Represents seconds of UTC time since Unix epoch
+/// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
+/// 9999-12-31T23:59:59Z inclusive.
+@property(nonatomic, readwrite) int64_t seconds;
+
+/// Non-negative fractions of a second at nanosecond resolution. Negative
+/// second values with fractions must still have non-negative nanos values
+/// that count forward in time. Must be from 0 to 999,999,999
+/// inclusive.
+@property(nonatomic, readwrite) int32_t nanos;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+CF_EXTERN_C_END
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 88 - 0
objectivec/google/google/protobuf/Timestamp.pbobjc.m

@@ -0,0 +1,88 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/timestamp.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Timestamp.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+#pragma mark - GPBTimestampRoot
+
+@implementation GPBTimestampRoot
+
+@end
+
+#pragma mark - GPBTimestampRoot_FileDescriptor
+
+static GPBFileDescriptor *GPBTimestampRoot_FileDescriptor(void) {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety of the singleton.
+  static GPBFileDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBTimestamp
+
+@implementation GPBTimestamp
+
+@dynamic seconds;
+@dynamic nanos;
+
+typedef struct GPBTimestamp__storage_ {
+  uint32_t _has_storage_[1];
+  int32_t nanos;
+  int64_t seconds;
+} GPBTimestamp__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "seconds",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBTimestamp_FieldNumber_Seconds,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBTimestamp__storage_, seconds),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeInt64,
+      },
+      {
+        .name = "nanos",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBTimestamp_FieldNumber_Nanos,
+        .hasIndex = 1,
+        .offset = (uint32_t)offsetof(GPBTimestamp__storage_, nanos),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeInt32,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBTimestamp class]
+                                     rootClass:[GPBTimestampRoot class]
+                                          file:GPBTimestampRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBTimestamp__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 373 - 0
objectivec/google/google/protobuf/Type.pbobjc.h

@@ -0,0 +1,373 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/type.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
+#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+CF_EXTERN_C_BEGIN
+
+@class GPBAny;
+@class GPBEnumValue;
+@class GPBField;
+@class GPBOption;
+@class GPBSourceContext;
+
+NS_ASSUME_NONNULL_BEGIN
+
+#pragma mark - Enum GPBSyntax
+
+/// The syntax in which a protocol buffer element is defined.
+typedef GPB_ENUM(GPBSyntax) {
+  /// Value used if any message's field encounters a value that is not defined
+  /// by this enum. The message will also have C functions to get/set the rawValue
+  /// of the field.
+  GPBSyntax_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
+  /// Syntax `proto2`.
+  GPBSyntax_SyntaxProto2 = 0,
+
+  /// Syntax `proto3`.
+  GPBSyntax_SyntaxProto3 = 1,
+};
+
+GPBEnumDescriptor *GPBSyntax_EnumDescriptor(void);
+
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
+BOOL GPBSyntax_IsValidValue(int32_t value);
+
+#pragma mark - Enum GPBField_Kind
+
+/// Basic field types.
+typedef GPB_ENUM(GPBField_Kind) {
+  /// Value used if any message's field encounters a value that is not defined
+  /// by this enum. The message will also have C functions to get/set the rawValue
+  /// of the field.
+  GPBField_Kind_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
+  /// Field type unknown.
+  GPBField_Kind_TypeUnknown = 0,
+
+  /// Field type double.
+  GPBField_Kind_TypeDouble = 1,
+
+  /// Field type float.
+  GPBField_Kind_TypeFloat = 2,
+
+  /// Field type int64.
+  GPBField_Kind_TypeInt64 = 3,
+
+  /// Field type uint64.
+  GPBField_Kind_TypeUint64 = 4,
+
+  /// Field type int32.
+  GPBField_Kind_TypeInt32 = 5,
+
+  /// Field type fixed64.
+  GPBField_Kind_TypeFixed64 = 6,
+
+  /// Field type fixed32.
+  GPBField_Kind_TypeFixed32 = 7,
+
+  /// Field type bool.
+  GPBField_Kind_TypeBool = 8,
+
+  /// Field type string.
+  GPBField_Kind_TypeString = 9,
+
+  /// Field type group. Proto2 syntax only, and deprecated.
+  GPBField_Kind_TypeGroup = 10,
+
+  /// Field type message.
+  GPBField_Kind_TypeMessage = 11,
+
+  /// Field type bytes.
+  GPBField_Kind_TypeBytes = 12,
+
+  /// Field type uint32.
+  GPBField_Kind_TypeUint32 = 13,
+
+  /// Field type enum.
+  GPBField_Kind_TypeEnum = 14,
+
+  /// Field type sfixed32.
+  GPBField_Kind_TypeSfixed32 = 15,
+
+  /// Field type sfixed64.
+  GPBField_Kind_TypeSfixed64 = 16,
+
+  /// Field type sint32.
+  GPBField_Kind_TypeSint32 = 17,
+
+  /// Field type sint64.
+  GPBField_Kind_TypeSint64 = 18,
+};
+
+GPBEnumDescriptor *GPBField_Kind_EnumDescriptor(void);
+
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
+BOOL GPBField_Kind_IsValidValue(int32_t value);
+
+#pragma mark - Enum GPBField_Cardinality
+
+/// Whether a field is optional, required, or repeated.
+typedef GPB_ENUM(GPBField_Cardinality) {
+  /// Value used if any message's field encounters a value that is not defined
+  /// by this enum. The message will also have C functions to get/set the rawValue
+  /// of the field.
+  GPBField_Cardinality_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
+  /// For fields with unknown cardinality.
+  GPBField_Cardinality_CardinalityUnknown = 0,
+
+  /// For optional fields.
+  GPBField_Cardinality_CardinalityOptional = 1,
+
+  /// For required fields. Proto2 syntax only.
+  GPBField_Cardinality_CardinalityRequired = 2,
+
+  /// For repeated fields.
+  GPBField_Cardinality_CardinalityRepeated = 3,
+};
+
+GPBEnumDescriptor *GPBField_Cardinality_EnumDescriptor(void);
+
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
+BOOL GPBField_Cardinality_IsValidValue(int32_t value);
+
+#pragma mark - GPBTypeRoot
+
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
+@interface GPBTypeRoot : GPBRootObject
+@end
+
+#pragma mark - GPBType
+
+typedef GPB_ENUM(GPBType_FieldNumber) {
+  GPBType_FieldNumber_Name = 1,
+  GPBType_FieldNumber_FieldsArray = 2,
+  GPBType_FieldNumber_OneofsArray = 3,
+  GPBType_FieldNumber_OptionsArray = 4,
+  GPBType_FieldNumber_SourceContext = 5,
+  GPBType_FieldNumber_Syntax = 6,
+};
+
+/// A protocol buffer message type.
+@interface GPBType : GPBMessage
+
+/// The fully qualified message name.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+
+/// The list of fields.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBField*> *fieldsArray;
+/// The number of items in @c fieldsArray without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger fieldsArray_Count;
+
+/// The list of types appearing in `oneof` definitions in this type.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<NSString*> *oneofsArray;
+/// The number of items in @c oneofsArray without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger oneofsArray_Count;
+
+/// The protocol buffer options.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger optionsArray_Count;
+
+/// The source context.
+@property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext;
+/// Test to see if @c sourceContext has been set.
+@property(nonatomic, readwrite) BOOL hasSourceContext;
+
+/// The source syntax.
+@property(nonatomic, readwrite) GPBSyntax syntax;
+
+@end
+
+/// Fetches the raw value of a @c GPBType's @c syntax property, even
+/// if the value was not defined by the enum at the time the code was generated.
+int32_t GPBType_Syntax_RawValue(GPBType *message);
+/// Sets the raw value of an @c GPBType's @c syntax property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
+void SetGPBType_Syntax_RawValue(GPBType *message, int32_t value);
+
+#pragma mark - GPBField
+
+typedef GPB_ENUM(GPBField_FieldNumber) {
+  GPBField_FieldNumber_Kind = 1,
+  GPBField_FieldNumber_Cardinality = 2,
+  GPBField_FieldNumber_Number = 3,
+  GPBField_FieldNumber_Name = 4,
+  GPBField_FieldNumber_TypeURL = 6,
+  GPBField_FieldNumber_OneofIndex = 7,
+  GPBField_FieldNumber_Packed = 8,
+  GPBField_FieldNumber_OptionsArray = 9,
+  GPBField_FieldNumber_JsonName = 10,
+  GPBField_FieldNumber_DefaultValue = 11,
+};
+
+/// A single field of a message type.
+@interface GPBField : GPBMessage
+
+/// The field type.
+@property(nonatomic, readwrite) GPBField_Kind kind;
+
+/// The field cardinality.
+@property(nonatomic, readwrite) GPBField_Cardinality cardinality;
+
+/// The field number.
+@property(nonatomic, readwrite) int32_t number;
+
+/// The field name.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+
+/// The field type URL, without the scheme, for message or enumeration
+/// types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *typeURL;
+
+/// The index of the field type in `Type.oneofs`, for message or enumeration
+/// types. The first type has index 1; zero means the type is not in the list.
+@property(nonatomic, readwrite) int32_t oneofIndex;
+
+/// Whether to use alternative packed wire representation.
+@property(nonatomic, readwrite) BOOL packed;
+
+/// The protocol buffer options.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger optionsArray_Count;
+
+/// The field JSON name.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *jsonName;
+
+/// The string value of the default value of this field. Proto2 syntax only.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *defaultValue;
+
+@end
+
+/// Fetches the raw value of a @c GPBField's @c kind property, even
+/// if the value was not defined by the enum at the time the code was generated.
+int32_t GPBField_Kind_RawValue(GPBField *message);
+/// Sets the raw value of an @c GPBField's @c kind property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
+void SetGPBField_Kind_RawValue(GPBField *message, int32_t value);
+
+/// Fetches the raw value of a @c GPBField's @c cardinality property, even
+/// if the value was not defined by the enum at the time the code was generated.
+int32_t GPBField_Cardinality_RawValue(GPBField *message);
+/// Sets the raw value of an @c GPBField's @c cardinality property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
+void SetGPBField_Cardinality_RawValue(GPBField *message, int32_t value);
+
+#pragma mark - GPBEnum
+
+typedef GPB_ENUM(GPBEnum_FieldNumber) {
+  GPBEnum_FieldNumber_Name = 1,
+  GPBEnum_FieldNumber_EnumvalueArray = 2,
+  GPBEnum_FieldNumber_OptionsArray = 3,
+  GPBEnum_FieldNumber_SourceContext = 4,
+  GPBEnum_FieldNumber_Syntax = 5,
+};
+
+/// Enum type definition.
+@interface GPBEnum : GPBMessage
+
+/// Enum type name.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+
+/// Enum value definitions.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBEnumValue*> *enumvalueArray;
+/// The number of items in @c enumvalueArray without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger enumvalueArray_Count;
+
+/// Protocol buffer options.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger optionsArray_Count;
+
+/// The source context.
+@property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext;
+/// Test to see if @c sourceContext has been set.
+@property(nonatomic, readwrite) BOOL hasSourceContext;
+
+/// The source syntax.
+@property(nonatomic, readwrite) GPBSyntax syntax;
+
+@end
+
+/// Fetches the raw value of a @c GPBEnum's @c syntax property, even
+/// if the value was not defined by the enum at the time the code was generated.
+int32_t GPBEnum_Syntax_RawValue(GPBEnum *message);
+/// Sets the raw value of an @c GPBEnum's @c syntax property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
+void SetGPBEnum_Syntax_RawValue(GPBEnum *message, int32_t value);
+
+#pragma mark - GPBEnumValue
+
+typedef GPB_ENUM(GPBEnumValue_FieldNumber) {
+  GPBEnumValue_FieldNumber_Name = 1,
+  GPBEnumValue_FieldNumber_Number = 2,
+  GPBEnumValue_FieldNumber_OptionsArray = 3,
+};
+
+/// Enum value definition.
+@interface GPBEnumValue : GPBMessage
+
+/// Enum value name.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+
+/// Enum value number.
+@property(nonatomic, readwrite) int32_t number;
+
+/// Protocol buffer options.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
+@property(nonatomic, readonly) NSUInteger optionsArray_Count;
+
+@end
+
+#pragma mark - GPBOption
+
+typedef GPB_ENUM(GPBOption_FieldNumber) {
+  GPBOption_FieldNumber_Name = 1,
+  GPBOption_FieldNumber_Value = 2,
+};
+
+/// A protocol buffer option, which can be attached to a message, field,
+/// enumeration, etc.
+@interface GPBOption : GPBMessage
+
+/// The option's name. For example, `"java_package"`.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
+
+/// The option's value. For example, `"com.google.protobuf"`.
+@property(nonatomic, readwrite, strong, null_resettable) GPBAny *value;
+/// Test to see if @c value has been set.
+@property(nonatomic, readwrite) BOOL hasValue;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+CF_EXTERN_C_END
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 693 - 0
objectivec/google/google/protobuf/Type.pbobjc.m

@@ -0,0 +1,693 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/type.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Type.pbobjc.h"
+#import "google/protobuf/Any.pbobjc.h"
+#import "google/protobuf/SourceContext.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+#pragma mark - GPBTypeRoot
+
+@implementation GPBTypeRoot
+
++ (GPBExtensionRegistry*)extensionRegistry {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety and initialization of registry.
+  static GPBExtensionRegistry* registry = nil;
+  if (!registry) {
+    GPBDebugCheckRuntimeVersion();
+    registry = [[GPBExtensionRegistry alloc] init];
+    [registry addExtensions:[GPBAnyRoot extensionRegistry]];
+    [registry addExtensions:[GPBSourceContextRoot extensionRegistry]];
+  }
+  return registry;
+}
+
+@end
+
+#pragma mark - GPBTypeRoot_FileDescriptor
+
+static GPBFileDescriptor *GPBTypeRoot_FileDescriptor(void) {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety of the singleton.
+  static GPBFileDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - Enum GPBSyntax
+
+GPBEnumDescriptor *GPBSyntax_EnumDescriptor(void) {
+  static GPBEnumDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static const char *valueNames =
+        "SyntaxProto2\000SyntaxProto3\000";
+    static const int32_t values[] = {
+        GPBSyntax_SyntaxProto2,
+        GPBSyntax_SyntaxProto3,
+    };
+    GPBEnumDescriptor *worker =
+        [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBSyntax)
+                                       valueNames:valueNames
+                                           values:values
+                                            count:(uint32_t)(sizeof(values) / sizeof(int32_t))
+                                     enumVerifier:GPBSyntax_IsValidValue];
+    if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) {
+      [worker release];
+    }
+  }
+  return descriptor;
+}
+
+BOOL GPBSyntax_IsValidValue(int32_t value__) {
+  switch (value__) {
+    case GPBSyntax_SyntaxProto2:
+    case GPBSyntax_SyntaxProto3:
+      return YES;
+    default:
+      return NO;
+  }
+}
+
+#pragma mark - GPBType
+
+@implementation GPBType
+
+@dynamic name;
+@dynamic fieldsArray, fieldsArray_Count;
+@dynamic oneofsArray, oneofsArray_Count;
+@dynamic optionsArray, optionsArray_Count;
+@dynamic hasSourceContext, sourceContext;
+@dynamic syntax;
+
+typedef struct GPBType__storage_ {
+  uint32_t _has_storage_[1];
+  GPBSyntax syntax;
+  NSString *name;
+  NSMutableArray *fieldsArray;
+  NSMutableArray *oneofsArray;
+  NSMutableArray *optionsArray;
+  GPBSourceContext *sourceContext;
+} GPBType__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "name",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBType_FieldNumber_Name,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBType__storage_, name),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "fieldsArray",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBField),
+        .number = GPBType_FieldNumber_FieldsArray,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBType__storage_, fieldsArray),
+        .flags = GPBFieldRepeated,
+        .dataType = GPBDataTypeMessage,
+      },
+      {
+        .name = "oneofsArray",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBType_FieldNumber_OneofsArray,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBType__storage_, oneofsArray),
+        .flags = GPBFieldRepeated,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "optionsArray",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
+        .number = GPBType_FieldNumber_OptionsArray,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBType__storage_, optionsArray),
+        .flags = GPBFieldRepeated,
+        .dataType = GPBDataTypeMessage,
+      },
+      {
+        .name = "sourceContext",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceContext),
+        .number = GPBType_FieldNumber_SourceContext,
+        .hasIndex = 1,
+        .offset = (uint32_t)offsetof(GPBType__storage_, sourceContext),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeMessage,
+      },
+      {
+        .name = "syntax",
+        .dataTypeSpecific.enumDescFunc = GPBSyntax_EnumDescriptor,
+        .number = GPBType_FieldNumber_Syntax,
+        .hasIndex = 2,
+        .offset = (uint32_t)offsetof(GPBType__storage_, syntax),
+        .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
+        .dataType = GPBDataTypeEnum,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBType class]
+                                     rootClass:[GPBTypeRoot class]
+                                          file:GPBTypeRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBType__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+int32_t GPBType_Syntax_RawValue(GPBType *message) {
+  GPBDescriptor *descriptor = [GPBType descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBType_FieldNumber_Syntax];
+  return GPBGetMessageInt32Field(message, field);
+}
+
+void SetGPBType_Syntax_RawValue(GPBType *message, int32_t value) {
+  GPBDescriptor *descriptor = [GPBType descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBType_FieldNumber_Syntax];
+  GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax);
+}
+
+#pragma mark - GPBField
+
+@implementation GPBField
+
+@dynamic kind;
+@dynamic cardinality;
+@dynamic number;
+@dynamic name;
+@dynamic typeURL;
+@dynamic oneofIndex;
+@dynamic packed;
+@dynamic optionsArray, optionsArray_Count;
+@dynamic jsonName;
+@dynamic defaultValue;
+
+typedef struct GPBField__storage_ {
+  uint32_t _has_storage_[1];
+  GPBField_Kind kind;
+  GPBField_Cardinality cardinality;
+  int32_t number;
+  int32_t oneofIndex;
+  NSString *name;
+  NSString *typeURL;
+  NSMutableArray *optionsArray;
+  NSString *jsonName;
+  NSString *defaultValue;
+} GPBField__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "kind",
+        .dataTypeSpecific.enumDescFunc = GPBField_Kind_EnumDescriptor,
+        .number = GPBField_FieldNumber_Kind,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBField__storage_, kind),
+        .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
+        .dataType = GPBDataTypeEnum,
+      },
+      {
+        .name = "cardinality",
+        .dataTypeSpecific.enumDescFunc = GPBField_Cardinality_EnumDescriptor,
+        .number = GPBField_FieldNumber_Cardinality,
+        .hasIndex = 1,
+        .offset = (uint32_t)offsetof(GPBField__storage_, cardinality),
+        .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
+        .dataType = GPBDataTypeEnum,
+      },
+      {
+        .name = "number",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBField_FieldNumber_Number,
+        .hasIndex = 2,
+        .offset = (uint32_t)offsetof(GPBField__storage_, number),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeInt32,
+      },
+      {
+        .name = "name",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBField_FieldNumber_Name,
+        .hasIndex = 3,
+        .offset = (uint32_t)offsetof(GPBField__storage_, name),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "typeURL",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBField_FieldNumber_TypeURL,
+        .hasIndex = 4,
+        .offset = (uint32_t)offsetof(GPBField__storage_, typeURL),
+        .flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "oneofIndex",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBField_FieldNumber_OneofIndex,
+        .hasIndex = 5,
+        .offset = (uint32_t)offsetof(GPBField__storage_, oneofIndex),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeInt32,
+      },
+      {
+        .name = "packed",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBField_FieldNumber_Packed,
+        .hasIndex = 6,
+        .offset = 7,  // Stored in _has_storage_ to save space.
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeBool,
+      },
+      {
+        .name = "optionsArray",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
+        .number = GPBField_FieldNumber_OptionsArray,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBField__storage_, optionsArray),
+        .flags = GPBFieldRepeated,
+        .dataType = GPBDataTypeMessage,
+      },
+      {
+        .name = "jsonName",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBField_FieldNumber_JsonName,
+        .hasIndex = 8,
+        .offset = (uint32_t)offsetof(GPBField__storage_, jsonName),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "defaultValue",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBField_FieldNumber_DefaultValue,
+        .hasIndex = 9,
+        .offset = (uint32_t)offsetof(GPBField__storage_, defaultValue),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBField class]
+                                     rootClass:[GPBTypeRoot class]
+                                          file:GPBTypeRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBField__storage_)
+                                         flags:0];
+#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
+    static const char *extraTextFormatInfo =
+        "\001\006\004\241!!\000";
+    [localDescriptor setupExtraTextInfo:extraTextFormatInfo];
+#endif  // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+int32_t GPBField_Kind_RawValue(GPBField *message) {
+  GPBDescriptor *descriptor = [GPBField descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Kind];
+  return GPBGetMessageInt32Field(message, field);
+}
+
+void SetGPBField_Kind_RawValue(GPBField *message, int32_t value) {
+  GPBDescriptor *descriptor = [GPBField descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Kind];
+  GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax);
+}
+
+int32_t GPBField_Cardinality_RawValue(GPBField *message) {
+  GPBDescriptor *descriptor = [GPBField descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Cardinality];
+  return GPBGetMessageInt32Field(message, field);
+}
+
+void SetGPBField_Cardinality_RawValue(GPBField *message, int32_t value) {
+  GPBDescriptor *descriptor = [GPBField descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Cardinality];
+  GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax);
+}
+
+#pragma mark - Enum GPBField_Kind
+
+GPBEnumDescriptor *GPBField_Kind_EnumDescriptor(void) {
+  static GPBEnumDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static const char *valueNames =
+        "TypeUnknown\000TypeDouble\000TypeFloat\000TypeInt"
+        "64\000TypeUint64\000TypeInt32\000TypeFixed64\000Type"
+        "Fixed32\000TypeBool\000TypeString\000TypeGroup\000Ty"
+        "peMessage\000TypeBytes\000TypeUint32\000TypeEnum\000"
+        "TypeSfixed32\000TypeSfixed64\000TypeSint32\000Typ"
+        "eSint64\000";
+    static const int32_t values[] = {
+        GPBField_Kind_TypeUnknown,
+        GPBField_Kind_TypeDouble,
+        GPBField_Kind_TypeFloat,
+        GPBField_Kind_TypeInt64,
+        GPBField_Kind_TypeUint64,
+        GPBField_Kind_TypeInt32,
+        GPBField_Kind_TypeFixed64,
+        GPBField_Kind_TypeFixed32,
+        GPBField_Kind_TypeBool,
+        GPBField_Kind_TypeString,
+        GPBField_Kind_TypeGroup,
+        GPBField_Kind_TypeMessage,
+        GPBField_Kind_TypeBytes,
+        GPBField_Kind_TypeUint32,
+        GPBField_Kind_TypeEnum,
+        GPBField_Kind_TypeSfixed32,
+        GPBField_Kind_TypeSfixed64,
+        GPBField_Kind_TypeSint32,
+        GPBField_Kind_TypeSint64,
+    };
+    GPBEnumDescriptor *worker =
+        [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBField_Kind)
+                                       valueNames:valueNames
+                                           values:values
+                                            count:(uint32_t)(sizeof(values) / sizeof(int32_t))
+                                     enumVerifier:GPBField_Kind_IsValidValue];
+    if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) {
+      [worker release];
+    }
+  }
+  return descriptor;
+}
+
+BOOL GPBField_Kind_IsValidValue(int32_t value__) {
+  switch (value__) {
+    case GPBField_Kind_TypeUnknown:
+    case GPBField_Kind_TypeDouble:
+    case GPBField_Kind_TypeFloat:
+    case GPBField_Kind_TypeInt64:
+    case GPBField_Kind_TypeUint64:
+    case GPBField_Kind_TypeInt32:
+    case GPBField_Kind_TypeFixed64:
+    case GPBField_Kind_TypeFixed32:
+    case GPBField_Kind_TypeBool:
+    case GPBField_Kind_TypeString:
+    case GPBField_Kind_TypeGroup:
+    case GPBField_Kind_TypeMessage:
+    case GPBField_Kind_TypeBytes:
+    case GPBField_Kind_TypeUint32:
+    case GPBField_Kind_TypeEnum:
+    case GPBField_Kind_TypeSfixed32:
+    case GPBField_Kind_TypeSfixed64:
+    case GPBField_Kind_TypeSint32:
+    case GPBField_Kind_TypeSint64:
+      return YES;
+    default:
+      return NO;
+  }
+}
+
+#pragma mark - Enum GPBField_Cardinality
+
+GPBEnumDescriptor *GPBField_Cardinality_EnumDescriptor(void) {
+  static GPBEnumDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static const char *valueNames =
+        "CardinalityUnknown\000CardinalityOptional\000C"
+        "ardinalityRequired\000CardinalityRepeated\000";
+    static const int32_t values[] = {
+        GPBField_Cardinality_CardinalityUnknown,
+        GPBField_Cardinality_CardinalityOptional,
+        GPBField_Cardinality_CardinalityRequired,
+        GPBField_Cardinality_CardinalityRepeated,
+    };
+    GPBEnumDescriptor *worker =
+        [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBField_Cardinality)
+                                       valueNames:valueNames
+                                           values:values
+                                            count:(uint32_t)(sizeof(values) / sizeof(int32_t))
+                                     enumVerifier:GPBField_Cardinality_IsValidValue];
+    if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) {
+      [worker release];
+    }
+  }
+  return descriptor;
+}
+
+BOOL GPBField_Cardinality_IsValidValue(int32_t value__) {
+  switch (value__) {
+    case GPBField_Cardinality_CardinalityUnknown:
+    case GPBField_Cardinality_CardinalityOptional:
+    case GPBField_Cardinality_CardinalityRequired:
+    case GPBField_Cardinality_CardinalityRepeated:
+      return YES;
+    default:
+      return NO;
+  }
+}
+
+#pragma mark - GPBEnum
+
+@implementation GPBEnum
+
+@dynamic name;
+@dynamic enumvalueArray, enumvalueArray_Count;
+@dynamic optionsArray, optionsArray_Count;
+@dynamic hasSourceContext, sourceContext;
+@dynamic syntax;
+
+typedef struct GPBEnum__storage_ {
+  uint32_t _has_storage_[1];
+  GPBSyntax syntax;
+  NSString *name;
+  NSMutableArray *enumvalueArray;
+  NSMutableArray *optionsArray;
+  GPBSourceContext *sourceContext;
+} GPBEnum__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "name",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBEnum_FieldNumber_Name,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBEnum__storage_, name),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "enumvalueArray",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBEnumValue),
+        .number = GPBEnum_FieldNumber_EnumvalueArray,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBEnum__storage_, enumvalueArray),
+        .flags = GPBFieldRepeated,
+        .dataType = GPBDataTypeMessage,
+      },
+      {
+        .name = "optionsArray",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
+        .number = GPBEnum_FieldNumber_OptionsArray,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBEnum__storage_, optionsArray),
+        .flags = GPBFieldRepeated,
+        .dataType = GPBDataTypeMessage,
+      },
+      {
+        .name = "sourceContext",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceContext),
+        .number = GPBEnum_FieldNumber_SourceContext,
+        .hasIndex = 1,
+        .offset = (uint32_t)offsetof(GPBEnum__storage_, sourceContext),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeMessage,
+      },
+      {
+        .name = "syntax",
+        .dataTypeSpecific.enumDescFunc = GPBSyntax_EnumDescriptor,
+        .number = GPBEnum_FieldNumber_Syntax,
+        .hasIndex = 2,
+        .offset = (uint32_t)offsetof(GPBEnum__storage_, syntax),
+        .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
+        .dataType = GPBDataTypeEnum,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBEnum class]
+                                     rootClass:[GPBTypeRoot class]
+                                          file:GPBTypeRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBEnum__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+int32_t GPBEnum_Syntax_RawValue(GPBEnum *message) {
+  GPBDescriptor *descriptor = [GPBEnum descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBEnum_FieldNumber_Syntax];
+  return GPBGetMessageInt32Field(message, field);
+}
+
+void SetGPBEnum_Syntax_RawValue(GPBEnum *message, int32_t value) {
+  GPBDescriptor *descriptor = [GPBEnum descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBEnum_FieldNumber_Syntax];
+  GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax);
+}
+
+#pragma mark - GPBEnumValue
+
+@implementation GPBEnumValue
+
+@dynamic name;
+@dynamic number;
+@dynamic optionsArray, optionsArray_Count;
+
+typedef struct GPBEnumValue__storage_ {
+  uint32_t _has_storage_[1];
+  int32_t number;
+  NSString *name;
+  NSMutableArray *optionsArray;
+} GPBEnumValue__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "name",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBEnumValue_FieldNumber_Name,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBEnumValue__storage_, name),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "number",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBEnumValue_FieldNumber_Number,
+        .hasIndex = 1,
+        .offset = (uint32_t)offsetof(GPBEnumValue__storage_, number),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeInt32,
+      },
+      {
+        .name = "optionsArray",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
+        .number = GPBEnumValue_FieldNumber_OptionsArray,
+        .hasIndex = GPBNoHasBit,
+        .offset = (uint32_t)offsetof(GPBEnumValue__storage_, optionsArray),
+        .flags = GPBFieldRepeated,
+        .dataType = GPBDataTypeMessage,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBEnumValue class]
+                                     rootClass:[GPBTypeRoot class]
+                                          file:GPBTypeRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBEnumValue__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBOption
+
+@implementation GPBOption
+
+@dynamic name;
+@dynamic hasValue, value;
+
+typedef struct GPBOption__storage_ {
+  uint32_t _has_storage_[1];
+  NSString *name;
+  GPBAny *value;
+} GPBOption__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "name",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBOption_FieldNumber_Name,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBOption__storage_, name),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+      {
+        .name = "value",
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBAny),
+        .number = GPBOption_FieldNumber_Value,
+        .hasIndex = 1,
+        .offset = (uint32_t)offsetof(GPBOption__storage_, value),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeMessage,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBOption class]
+                                     rootClass:[GPBTypeRoot class]
+                                          file:GPBTypeRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBOption__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 182 - 0
objectivec/google/google/protobuf/Wrappers.pbobjc.h

@@ -0,0 +1,182 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/wrappers.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
+#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+CF_EXTERN_C_BEGIN
+
+NS_ASSUME_NONNULL_BEGIN
+
+#pragma mark - GPBWrappersRoot
+
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+///   + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
+@interface GPBWrappersRoot : GPBRootObject
+@end
+
+#pragma mark - GPBDoubleValue
+
+typedef GPB_ENUM(GPBDoubleValue_FieldNumber) {
+  GPBDoubleValue_FieldNumber_Value = 1,
+};
+
+/// Wrapper message for `double`.
+///
+/// The JSON representation for `DoubleValue` is JSON number.
+@interface GPBDoubleValue : GPBMessage
+
+/// The double value.
+@property(nonatomic, readwrite) double value;
+
+@end
+
+#pragma mark - GPBFloatValue
+
+typedef GPB_ENUM(GPBFloatValue_FieldNumber) {
+  GPBFloatValue_FieldNumber_Value = 1,
+};
+
+/// Wrapper message for `float`.
+///
+/// The JSON representation for `FloatValue` is JSON number.
+@interface GPBFloatValue : GPBMessage
+
+/// The float value.
+@property(nonatomic, readwrite) float value;
+
+@end
+
+#pragma mark - GPBInt64Value
+
+typedef GPB_ENUM(GPBInt64Value_FieldNumber) {
+  GPBInt64Value_FieldNumber_Value = 1,
+};
+
+/// Wrapper message for `int64`.
+///
+/// The JSON representation for `Int64Value` is JSON string.
+@interface GPBInt64Value : GPBMessage
+
+/// The int64 value.
+@property(nonatomic, readwrite) int64_t value;
+
+@end
+
+#pragma mark - GPBUInt64Value
+
+typedef GPB_ENUM(GPBUInt64Value_FieldNumber) {
+  GPBUInt64Value_FieldNumber_Value = 1,
+};
+
+/// Wrapper message for `uint64`.
+///
+/// The JSON representation for `UInt64Value` is JSON string.
+@interface GPBUInt64Value : GPBMessage
+
+/// The uint64 value.
+@property(nonatomic, readwrite) uint64_t value;
+
+@end
+
+#pragma mark - GPBInt32Value
+
+typedef GPB_ENUM(GPBInt32Value_FieldNumber) {
+  GPBInt32Value_FieldNumber_Value = 1,
+};
+
+/// Wrapper message for `int32`.
+///
+/// The JSON representation for `Int32Value` is JSON number.
+@interface GPBInt32Value : GPBMessage
+
+/// The int32 value.
+@property(nonatomic, readwrite) int32_t value;
+
+@end
+
+#pragma mark - GPBUInt32Value
+
+typedef GPB_ENUM(GPBUInt32Value_FieldNumber) {
+  GPBUInt32Value_FieldNumber_Value = 1,
+};
+
+/// Wrapper message for `uint32`.
+///
+/// The JSON representation for `UInt32Value` is JSON number.
+@interface GPBUInt32Value : GPBMessage
+
+/// The uint32 value.
+@property(nonatomic, readwrite) uint32_t value;
+
+@end
+
+#pragma mark - GPBBoolValue
+
+typedef GPB_ENUM(GPBBoolValue_FieldNumber) {
+  GPBBoolValue_FieldNumber_Value = 1,
+};
+
+/// Wrapper message for `bool`.
+///
+/// The JSON representation for `BoolValue` is JSON `true` and `false`.
+@interface GPBBoolValue : GPBMessage
+
+/// The bool value.
+@property(nonatomic, readwrite) BOOL value;
+
+@end
+
+#pragma mark - GPBStringValue
+
+typedef GPB_ENUM(GPBStringValue_FieldNumber) {
+  GPBStringValue_FieldNumber_Value = 1,
+};
+
+/// Wrapper message for `string`.
+///
+/// The JSON representation for `StringValue` is JSON string.
+@interface GPBStringValue : GPBMessage
+
+/// The string value.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *value;
+
+@end
+
+#pragma mark - GPBBytesValue
+
+typedef GPB_ENUM(GPBBytesValue_FieldNumber) {
+  GPBBytesValue_FieldNumber_Value = 1,
+};
+
+/// Wrapper message for `bytes`.
+///
+/// The JSON representation for `BytesValue` is JSON string.
+@interface GPBBytesValue : GPBMessage
+
+/// The bytes value.
+@property(nonatomic, readwrite, copy, null_resettable) NSData *value;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+CF_EXTERN_C_END
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 420 - 0
objectivec/google/google/protobuf/Wrappers.pbobjc.m

@@ -0,0 +1,420 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/wrappers.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Wrappers.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+#pragma mark - GPBWrappersRoot
+
+@implementation GPBWrappersRoot
+
+@end
+
+#pragma mark - GPBWrappersRoot_FileDescriptor
+
+static GPBFileDescriptor *GPBWrappersRoot_FileDescriptor(void) {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety of the singleton.
+  static GPBFileDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBDoubleValue
+
+@implementation GPBDoubleValue
+
+@dynamic value;
+
+typedef struct GPBDoubleValue__storage_ {
+  uint32_t _has_storage_[1];
+  double value;
+} GPBDoubleValue__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBDoubleValue_FieldNumber_Value,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBDoubleValue__storage_, value),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeDouble,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBDoubleValue class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBDoubleValue__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBFloatValue
+
+@implementation GPBFloatValue
+
+@dynamic value;
+
+typedef struct GPBFloatValue__storage_ {
+  uint32_t _has_storage_[1];
+  float value;
+} GPBFloatValue__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBFloatValue_FieldNumber_Value,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBFloatValue__storage_, value),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeFloat,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBFloatValue class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBFloatValue__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBInt64Value
+
+@implementation GPBInt64Value
+
+@dynamic value;
+
+typedef struct GPBInt64Value__storage_ {
+  uint32_t _has_storage_[1];
+  int64_t value;
+} GPBInt64Value__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBInt64Value_FieldNumber_Value,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBInt64Value__storage_, value),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeInt64,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBInt64Value class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBInt64Value__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBUInt64Value
+
+@implementation GPBUInt64Value
+
+@dynamic value;
+
+typedef struct GPBUInt64Value__storage_ {
+  uint32_t _has_storage_[1];
+  uint64_t value;
+} GPBUInt64Value__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBUInt64Value_FieldNumber_Value,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBUInt64Value__storage_, value),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeUInt64,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBUInt64Value class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBUInt64Value__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBInt32Value
+
+@implementation GPBInt32Value
+
+@dynamic value;
+
+typedef struct GPBInt32Value__storage_ {
+  uint32_t _has_storage_[1];
+  int32_t value;
+} GPBInt32Value__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBInt32Value_FieldNumber_Value,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBInt32Value__storage_, value),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeInt32,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBInt32Value class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBInt32Value__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBUInt32Value
+
+@implementation GPBUInt32Value
+
+@dynamic value;
+
+typedef struct GPBUInt32Value__storage_ {
+  uint32_t _has_storage_[1];
+  uint32_t value;
+} GPBUInt32Value__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBUInt32Value_FieldNumber_Value,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBUInt32Value__storage_, value),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeUInt32,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBUInt32Value class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBUInt32Value__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBBoolValue
+
+@implementation GPBBoolValue
+
+@dynamic value;
+
+typedef struct GPBBoolValue__storage_ {
+  uint32_t _has_storage_[1];
+} GPBBoolValue__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBBoolValue_FieldNumber_Value,
+        .hasIndex = 0,
+        .offset = 1,  // Stored in _has_storage_ to save space.
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeBool,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBBoolValue class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBBoolValue__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBStringValue
+
+@implementation GPBStringValue
+
+@dynamic value;
+
+typedef struct GPBStringValue__storage_ {
+  uint32_t _has_storage_[1];
+  NSString *value;
+} GPBStringValue__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBStringValue_FieldNumber_Value,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBStringValue__storage_, value),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeString,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBStringValue class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBStringValue__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBBytesValue
+
+@implementation GPBBytesValue
+
+@dynamic value;
+
+typedef struct GPBBytesValue__storage_ {
+  uint32_t _has_storage_[1];
+  NSData *value;
+} GPBBytesValue__storage_;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = nil;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .dataTypeSpecific.className = NULL,
+        .number = GPBBytesValue_FieldNumber_Value,
+        .hasIndex = 0,
+        .offset = (uint32_t)offsetof(GPBBytesValue__storage_, value),
+        .flags = GPBFieldOptional,
+        .dataType = GPBDataTypeBytes,
+      },
+    };
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBBytesValue class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
+                                   storageSize:sizeof(GPBBytesValue__storage_)
+                                         flags:0];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
+  }
+  return descriptor;
+}
+
+@end
+
+
+#pragma clang diagnostic pop
+
+// @@protoc_insertion_point(global_scope)

+ 4 - 0
php/tests/autoload.php

@@ -0,0 +1,4 @@
+<?php
+
+require_once('test.pb.php');
+require_once('test_util.php');

+ 7 - 2
python/google/protobuf/descriptor.py

@@ -783,6 +783,8 @@ class FileDescriptor(DescriptorBase):
   serialized_pb: (str) Byte string of serialized
   serialized_pb: (str) Byte string of serialized
     descriptor_pb2.FileDescriptorProto.
     descriptor_pb2.FileDescriptorProto.
   dependencies: List of other FileDescriptors this FileDescriptor depends on.
   dependencies: List of other FileDescriptors this FileDescriptor depends on.
+  public_dependencies: A list of FileDescriptors, subset of the dependencies
+    above, which were declared as "public".
   message_types_by_name: Dict of message names of their descriptors.
   message_types_by_name: Dict of message names of their descriptors.
   enum_types_by_name: Dict of enum names and their descriptors.
   enum_types_by_name: Dict of enum names and their descriptors.
   extensions_by_name: Dict of extension names and their descriptors.
   extensions_by_name: Dict of extension names and their descriptors.
@@ -794,7 +796,8 @@ class FileDescriptor(DescriptorBase):
     _C_DESCRIPTOR_CLASS = _message.FileDescriptor
     _C_DESCRIPTOR_CLASS = _message.FileDescriptor
 
 
     def __new__(cls, name, package, options=None, serialized_pb=None,
     def __new__(cls, name, package, options=None, serialized_pb=None,
-                dependencies=None, syntax=None, pool=None):
+                dependencies=None, public_dependencies=None,
+                syntax=None, pool=None):
       # FileDescriptor() is called from various places, not only from generated
       # FileDescriptor() is called from various places, not only from generated
       # files, to register dynamic proto files and messages.
       # files, to register dynamic proto files and messages.
       if serialized_pb:
       if serialized_pb:
@@ -805,7 +808,8 @@ class FileDescriptor(DescriptorBase):
         return super(FileDescriptor, cls).__new__(cls)
         return super(FileDescriptor, cls).__new__(cls)
 
 
   def __init__(self, name, package, options=None, serialized_pb=None,
   def __init__(self, name, package, options=None, serialized_pb=None,
-               dependencies=None, syntax=None, pool=None):
+               dependencies=None, public_dependencies=None,
+               syntax=None, pool=None):
     """Constructor."""
     """Constructor."""
     super(FileDescriptor, self).__init__(options, 'FileOptions')
     super(FileDescriptor, self).__init__(options, 'FileOptions')
 
 
@@ -822,6 +826,7 @@ class FileDescriptor(DescriptorBase):
     self.enum_types_by_name = {}
     self.enum_types_by_name = {}
     self.extensions_by_name = {}
     self.extensions_by_name = {}
     self.dependencies = (dependencies or [])
     self.dependencies = (dependencies or [])
+    self.public_dependencies = (public_dependencies or [])
 
 
     if (api_implementation.Type() == 'cpp' and
     if (api_implementation.Type() == 'cpp' and
         self.serialized_pb is not None):
         self.serialized_pb is not None):

+ 3 - 1
python/google/protobuf/descriptor_pool.py

@@ -319,6 +319,7 @@ class DescriptorPool(object):
     if file_proto.name not in self._file_descriptors:
     if file_proto.name not in self._file_descriptors:
       built_deps = list(self._GetDeps(file_proto.dependency))
       built_deps = list(self._GetDeps(file_proto.dependency))
       direct_deps = [self.FindFileByName(n) for n in file_proto.dependency]
       direct_deps = [self.FindFileByName(n) for n in file_proto.dependency]
+      public_deps = [direct_deps[i] for i in file_proto.public_dependency]
 
 
       file_descriptor = descriptor.FileDescriptor(
       file_descriptor = descriptor.FileDescriptor(
           pool=self,
           pool=self,
@@ -327,7 +328,8 @@ class DescriptorPool(object):
           syntax=file_proto.syntax,
           syntax=file_proto.syntax,
           options=file_proto.options,
           options=file_proto.options,
           serialized_pb=file_proto.SerializeToString(),
           serialized_pb=file_proto.SerializeToString(),
-          dependencies=direct_deps)
+          dependencies=direct_deps,
+          public_dependencies=public_deps)
       if _USE_C_DESCRIPTORS:
       if _USE_C_DESCRIPTORS:
         # When using C++ descriptors, all objects defined in the file were added
         # When using C++ descriptors, all objects defined in the file were added
         # to the C++ database when the FileDescriptor was built above.
         # to the C++ database when the FileDescriptor was built above.

+ 6 - 0
python/google/protobuf/internal/api_implementation.py

@@ -32,6 +32,7 @@
 """
 """
 
 
 import os
 import os
+import warnings
 import sys
 import sys
 
 
 try:
 try:
@@ -78,6 +79,11 @@ _implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION',
 if _implementation_type != 'python':
 if _implementation_type != 'python':
   _implementation_type = 'cpp'
   _implementation_type = 'cpp'
 
 
+if 'PyPy' in sys.version and _implementation_type == 'cpp':
+  warnings.warn('PyPy does not work yet with cpp protocol buffers. '
+                'Falling back to the python implementation.')
+  _implementation_type = 'python'
+
 # This environment variable can be used to switch between the two
 # This environment variable can be used to switch between the two
 # 'cpp' implementations, overriding the compile-time constants in the
 # 'cpp' implementations, overriding the compile-time constants in the
 # _api_implementation module. Right now only '2' is supported. Any other
 # _api_implementation module. Right now only '2' is supported. Any other

+ 16 - 30
python/google/protobuf/internal/descriptor_pool_test.py

@@ -51,6 +51,7 @@ from google.protobuf.internal import descriptor_pool_test1_pb2
 from google.protobuf.internal import descriptor_pool_test2_pb2
 from google.protobuf.internal import descriptor_pool_test2_pb2
 from google.protobuf.internal import factory_test1_pb2
 from google.protobuf.internal import factory_test1_pb2
 from google.protobuf.internal import factory_test2_pb2
 from google.protobuf.internal import factory_test2_pb2
+from google.protobuf.internal import more_messages_pb2
 from google.protobuf import descriptor
 from google.protobuf import descriptor
 from google.protobuf import descriptor_database
 from google.protobuf import descriptor_database
 from google.protobuf import descriptor_pool
 from google.protobuf import descriptor_pool
@@ -60,11 +61,8 @@ from google.protobuf import symbol_database
 
 
 class DescriptorPoolTest(unittest.TestCase):
 class DescriptorPoolTest(unittest.TestCase):
 
 
-  def CreatePool(self):
-    return descriptor_pool.DescriptorPool()
-
   def setUp(self):
   def setUp(self):
-    self.pool = self.CreatePool()
+    self.pool = descriptor_pool.DescriptorPool()
     self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString(
     self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString(
         factory_test1_pb2.DESCRIPTOR.serialized_pb)
         factory_test1_pb2.DESCRIPTOR.serialized_pb)
     self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString(
     self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString(
@@ -275,10 +273,13 @@ class DescriptorPoolTest(unittest.TestCase):
     self.testFindMessageTypeByName()
     self.testFindMessageTypeByName()
 
 
   def testComplexNesting(self):
   def testComplexNesting(self):
+    more_messages_desc = descriptor_pb2.FileDescriptorProto.FromString(
+        more_messages_pb2.DESCRIPTOR.serialized_pb)
     test1_desc = descriptor_pb2.FileDescriptorProto.FromString(
     test1_desc = descriptor_pb2.FileDescriptorProto.FromString(
         descriptor_pool_test1_pb2.DESCRIPTOR.serialized_pb)
         descriptor_pool_test1_pb2.DESCRIPTOR.serialized_pb)
     test2_desc = descriptor_pb2.FileDescriptorProto.FromString(
     test2_desc = descriptor_pb2.FileDescriptorProto.FromString(
         descriptor_pool_test2_pb2.DESCRIPTOR.serialized_pb)
         descriptor_pool_test2_pb2.DESCRIPTOR.serialized_pb)
+    self.pool.Add(more_messages_desc)
     self.pool.Add(test1_desc)
     self.pool.Add(test1_desc)
     self.pool.Add(test2_desc)
     self.pool.Add(test2_desc)
     TEST1_FILE.CheckFile(self, self.pool)
     TEST1_FILE.CheckFile(self, self.pool)
@@ -350,25 +351,15 @@ class DescriptorPoolTest(unittest.TestCase):
     _CheckDefaultValues(message_class())
     _CheckDefaultValues(message_class())
 
 
 
 
-@unittest.skipIf(api_implementation.Type() != 'cpp',
-                 'explicit tests of the C++ implementation')
-class CppDescriptorPoolTest(DescriptorPoolTest):
-  # TODO(amauryfa): remove when descriptor_pool.DescriptorPool() creates true
-  # C++ descriptor pool object for C++ implementation.
-
-  def CreatePool(self):
-    # pylint: disable=g-import-not-at-top
-    from google.protobuf.pyext import _message
-    return _message.DescriptorPool()
-
-
 class ProtoFile(object):
 class ProtoFile(object):
 
 
-  def __init__(self, name, package, messages, dependencies=None):
+  def __init__(self, name, package, messages, dependencies=None,
+               public_dependencies=None):
     self.name = name
     self.name = name
     self.package = package
     self.package = package
     self.messages = messages
     self.messages = messages
     self.dependencies = dependencies or []
     self.dependencies = dependencies or []
+    self.public_dependencies = public_dependencies or []
 
 
   def CheckFile(self, test, pool):
   def CheckFile(self, test, pool):
     file_desc = pool.FindFileByName(self.name)
     file_desc = pool.FindFileByName(self.name)
@@ -376,6 +367,8 @@ class ProtoFile(object):
     test.assertEqual(self.package, file_desc.package)
     test.assertEqual(self.package, file_desc.package)
     dependencies_names = [f.name for f in file_desc.dependencies]
     dependencies_names = [f.name for f in file_desc.dependencies]
     test.assertEqual(self.dependencies, dependencies_names)
     test.assertEqual(self.dependencies, dependencies_names)
+    public_dependencies_names = [f.name for f in file_desc.public_dependencies]
+    test.assertEqual(self.public_dependencies, public_dependencies_names)
     for name, msg_type in self.messages.items():
     for name, msg_type in self.messages.items():
       msg_type.CheckType(test, None, name, file_desc)
       msg_type.CheckType(test, None, name, file_desc)
 
 
@@ -613,18 +606,9 @@ class AddDescriptorTest(unittest.TestCase):
       pool.FindFileContainingSymbol(
       pool.FindFileContainingSymbol(
           'protobuf_unittest.TestAllTypes')
           'protobuf_unittest.TestAllTypes')
 
 
-  def _GetDescriptorPoolClass(self):
-    # Test with both implementations of descriptor pools.
-    if api_implementation.Type() == 'cpp':
-      # pylint: disable=g-import-not-at-top
-      from google.protobuf.pyext import _message
-      return _message.DescriptorPool
-    else:
-      return descriptor_pool.DescriptorPool
-
   def testEmptyDescriptorPool(self):
   def testEmptyDescriptorPool(self):
-    # Check that an empty DescriptorPool() contains no message.
-    pool = self._GetDescriptorPoolClass()()
+    # Check that an empty DescriptorPool() contains no messages.
+    pool = descriptor_pool.DescriptorPool()
     proto_file_name = descriptor_pb2.DESCRIPTOR.name
     proto_file_name = descriptor_pb2.DESCRIPTOR.name
     self.assertRaises(KeyError, pool.FindFileByName, proto_file_name)
     self.assertRaises(KeyError, pool.FindFileByName, proto_file_name)
     # Add the above file to the pool
     # Add the above file to the pool
@@ -636,7 +620,7 @@ class AddDescriptorTest(unittest.TestCase):
 
 
   def testCustomDescriptorPool(self):
   def testCustomDescriptorPool(self):
     # Create a new pool, and add a file descriptor.
     # Create a new pool, and add a file descriptor.
-    pool = self._GetDescriptorPoolClass()()
+    pool = descriptor_pool.DescriptorPool()
     file_desc = descriptor_pb2.FileDescriptorProto(
     file_desc = descriptor_pb2.FileDescriptorProto(
         name='some/file.proto', package='package')
         name='some/file.proto', package='package')
     file_desc.message_type.add(name='Message')
     file_desc.message_type.add(name='Message')
@@ -757,7 +741,9 @@ TEST2_FILE = ProtoFile(
              ExtensionField(1001, 'DescriptorPoolTest1')),
              ExtensionField(1001, 'DescriptorPoolTest1')),
         ]),
         ]),
     },
     },
-    dependencies=['google/protobuf/internal/descriptor_pool_test1.proto'])
+    dependencies=['google/protobuf/internal/descriptor_pool_test1.proto',
+                  'google/protobuf/internal/more_messages.proto'],
+    public_dependencies=['google/protobuf/internal/more_messages.proto'])
 
 
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':

+ 1 - 0
python/google/protobuf/internal/descriptor_pool_test2.proto

@@ -33,6 +33,7 @@ syntax = "proto2";
 package google.protobuf.python.internal;
 package google.protobuf.python.internal;
 
 
 import "google/protobuf/internal/descriptor_pool_test1.proto";
 import "google/protobuf/internal/descriptor_pool_test1.proto";
+import public "google/protobuf/internal/more_messages.proto";
 
 
 
 
 message DescriptorPoolTest3 {
 message DescriptorPoolTest3 {

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä