aboutsummaryrefslogtreecommitdiffhomepage
path: root/java/core
diff options
context:
space:
mode:
authorGravatar Jisi Liu <jisi.liu@gmail.com>2016-04-28 14:34:59 -0700
committerGravatar Jisi Liu <jisi.liu@gmail.com>2016-04-28 14:34:59 -0700
commitcf14183bcd5485b4a71541599ddce0b35eb71352 (patch)
tree12f6e5eb731d7a70cdac4cdafc8b3131629413e2 /java/core
parentf00300d7f04f1c38a7d70e271f9232b94dd0e326 (diff)
Down integrate from Google internal.
Diffstat (limited to 'java/core')
-rw-r--r--java/core/src/main/java/com/google/protobuf/AbstractMessage.java48
-rw-r--r--java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java79
-rw-r--r--java/core/src/main/java/com/google/protobuf/AbstractParser.java85
-rw-r--r--java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java48
-rw-r--r--java/core/src/main/java/com/google/protobuf/BooleanArrayList.java69
-rw-r--r--java/core/src/main/java/com/google/protobuf/CodedOutputStream.java2368
-rw-r--r--java/core/src/main/java/com/google/protobuf/Descriptors.java181
-rw-r--r--java/core/src/main/java/com/google/protobuf/DoubleArrayList.java65
-rw-r--r--java/core/src/main/java/com/google/protobuf/DynamicMessage.java40
-rw-r--r--java/core/src/main/java/com/google/protobuf/Extension.java1
-rw-r--r--java/core/src/main/java/com/google/protobuf/FieldSet.java19
-rw-r--r--java/core/src/main/java/com/google/protobuf/FloatArrayList.java64
-rw-r--r--java/core/src/main/java/com/google/protobuf/GeneratedMessage.java255
-rw-r--r--java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java1067
-rw-r--r--java/core/src/main/java/com/google/protobuf/IntArrayList.java64
-rw-r--r--java/core/src/main/java/com/google/protobuf/Internal.java63
-rw-r--r--java/core/src/main/java/com/google/protobuf/LazyField.java12
-rw-r--r--java/core/src/main/java/com/google/protobuf/LazyFieldLite.java41
-rw-r--r--java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java48
-rw-r--r--java/core/src/main/java/com/google/protobuf/LongArrayList.java64
-rw-r--r--java/core/src/main/java/com/google/protobuf/MapEntryLite.java10
-rw-r--r--java/core/src/main/java/com/google/protobuf/MapField.java3
-rw-r--r--java/core/src/main/java/com/google/protobuf/Message.java70
-rw-r--r--java/core/src/main/java/com/google/protobuf/MessageLite.java21
-rw-r--r--java/core/src/main/java/com/google/protobuf/MessageLiteToString.java151
-rw-r--r--java/core/src/main/java/com/google/protobuf/MessageOrBuilder.java2
-rw-r--r--java/core/src/main/java/com/google/protobuf/MessageReflection.java107
-rw-r--r--java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java22
-rw-r--r--java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java1
-rw-r--r--java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java8
-rw-r--r--java/core/src/main/java/com/google/protobuf/RpcUtil.java4
-rw-r--r--java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java2
-rw-r--r--java/core/src/main/java/com/google/protobuf/SmallSortedMap.java106
-rw-r--r--java/core/src/main/java/com/google/protobuf/TextFormat.java2
-rw-r--r--java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java77
-rw-r--r--java/core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java50
-rw-r--r--java/core/src/main/java/com/google/protobuf/WireFormat.java19
-rw-r--r--java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java41
-rw-r--r--java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java14
-rw-r--r--java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java2
-rw-r--r--java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java776
-rw-r--r--java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java14
-rw-r--r--java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java14
-rw-r--r--java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java2
-rw-r--r--java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java8
-rw-r--r--java/core/src/test/java/com/google/protobuf/IntArrayListTest.java14
-rw-r--r--java/core/src/test/java/com/google/protobuf/LiteTest.java692
-rw-r--r--java/core/src/test/java/com/google/protobuf/LongArrayListTest.java14
-rw-r--r--java/core/src/test/java/com/google/protobuf/ParserTest.java16
-rw-r--r--java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java14
-rw-r--r--java/core/src/test/java/com/google/protobuf/ServiceTest.java20
-rw-r--r--java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java3
-rw-r--r--java/core/src/test/java/com/google/protobuf/TestUtil.java409
-rw-r--r--java/core/src/test/java/com/google/protobuf/TestUtilLite.java559
-rw-r--r--java/core/src/test/java/com/google/protobuf/TextFormatTest.java5
-rw-r--r--java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java1
-rw-r--r--java/core/src/test/java/com/google/protobuf/WireFormatTest.java10
-rw-r--r--java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto3
58 files changed, 5886 insertions, 2081 deletions
diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
index 9f418f2b..03c0d579 100644
--- a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
@@ -50,17 +50,23 @@ import java.util.Map;
*
* @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() {
return MessageReflection.isInitialized(this);
}
+ @Override
public List<String> findInitializationErrors() {
return MessageReflection.findMissingFields(this);
}
+ @Override
public String getInitializationErrorString() {
return MessageReflection.delimitWithCommas(findInitializationErrors());
}
@@ -83,12 +89,14 @@ public abstract class AbstractMessage extends AbstractMessageLite
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) {
@@ -288,8 +296,8 @@ public abstract class AbstractMessage extends AbstractMessageLite
* other methods.
*/
@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 {
// The compiler produces an error if this is not declared explicitly.
@Override
@@ -314,6 +322,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
throw new UnsupportedOperationException("clearOneof() is not implemented.");
}
+ @Override
public BuilderType clear() {
for (final Map.Entry<FieldDescriptor, Object> entry :
getAllFields().entrySet()) {
@@ -322,14 +331,22 @@ public abstract class AbstractMessage extends AbstractMessageLite
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(
@@ -407,6 +424,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
return (BuilderType) this;
}
+ @Override
public BuilderType mergeUnknownFields(final UnknownFieldSet unknownFields) {
setUnknownFields(
UnknownFieldSet.newBuilder(getUnknownFields())
@@ -415,17 +433,19 @@ public abstract class AbstractMessage extends AbstractMessageLite
return (BuilderType) this;
}
+ @Override
public Message.Builder getFieldBuilder(final FieldDescriptor field) {
throw new UnsupportedOperationException(
"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(
"getRepeatedFieldBuilder() called on an unsupported message type.");
}
+ @Override
public String toString() {
return TextFormat.printToString(this);
}
@@ -462,7 +482,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
@Override
public BuilderType mergeFrom(final ByteString data)
throws InvalidProtocolBufferException {
- return super.mergeFrom(data);
+ return (BuilderType) super.mergeFrom(data);
}
@Override
@@ -470,20 +490,20 @@ public abstract class AbstractMessage extends AbstractMessageLite
final ByteString data,
final ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
- return super.mergeFrom(data, extensionRegistry);
+ return (BuilderType) super.mergeFrom(data, extensionRegistry);
}
@Override
public BuilderType mergeFrom(final byte[] data)
throws InvalidProtocolBufferException {
- return super.mergeFrom(data);
+ return (BuilderType) super.mergeFrom(data);
}
@Override
public BuilderType mergeFrom(
final byte[] data, final int off, final int len)
throws InvalidProtocolBufferException {
- return super.mergeFrom(data, off, len);
+ return (BuilderType) super.mergeFrom(data, off, len);
}
@Override
@@ -491,7 +511,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
final byte[] data,
final ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
- return super.mergeFrom(data, extensionRegistry);
+ return (BuilderType) super.mergeFrom(data, extensionRegistry);
}
@Override
@@ -499,13 +519,13 @@ public abstract class AbstractMessage extends AbstractMessageLite
final byte[] data, final int off, final int len,
final ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
- return super.mergeFrom(data, off, len, extensionRegistry);
+ return (BuilderType) super.mergeFrom(data, off, len, extensionRegistry);
}
@Override
public BuilderType mergeFrom(final InputStream input)
throws IOException {
- return super.mergeFrom(input);
+ return (BuilderType) super.mergeFrom(input);
}
@Override
@@ -513,7 +533,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
final InputStream input,
final ExtensionRegistryLite extensionRegistry)
throws IOException {
- return super.mergeFrom(input, extensionRegistry);
+ return (BuilderType) super.mergeFrom(input, extensionRegistry);
}
@Override
diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java b/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java
index 12384983..43736dd1 100644
--- a/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java
+++ b/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java
@@ -43,9 +43,13 @@ import java.util.Collection;
*
* @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;
-
+
+ @Override
public ByteString toByteString() {
try {
final ByteString.CodedBuilder out =
@@ -59,6 +63,7 @@ public abstract class AbstractMessageLite implements MessageLite {
}
}
+ @Override
public byte[] toByteArray() {
try {
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 {
final int bufferSize =
CodedOutputStream.computePreferredBufferSize(getSerializedSize());
@@ -82,6 +88,7 @@ public abstract class AbstractMessageLite implements MessageLite {
codedOutput.flush();
}
+ @Override
public void writeDelimitedTo(final OutputStream output) throws IOException {
final int serialized = getSerializedSize();
final int bufferSize = CodedOutputStream.computePreferredBufferSize(
@@ -120,25 +127,27 @@ public abstract class AbstractMessageLite implements MessageLite {
* other methods.
*/
@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 {
// The compiler produces an error if this is not declared explicitly.
@Override
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());
}
// Re-defined here for return type covariance.
+ @Override
public abstract BuilderType mergeFrom(
- final CodedInputStream input,
- final ExtensionRegistryLite extensionRegistry)
+ final CodedInputStream input, final ExtensionRegistryLite extensionRegistry)
throws IOException;
- public BuilderType mergeFrom(final ByteString data)
- throws InvalidProtocolBufferException {
+ @Override
+ public BuilderType mergeFrom(final ByteString data) throws InvalidProtocolBufferException {
try {
final CodedInputStream input = data.newCodedInput();
mergeFrom(input);
@@ -153,9 +162,9 @@ public abstract class AbstractMessageLite implements MessageLite {
}
}
+ @Override
public BuilderType mergeFrom(
- final ByteString data,
- final ExtensionRegistryLite extensionRegistry)
+ final ByteString data, final ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
try {
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);
}
- 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 {
final CodedInputStream input =
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 {
return mergeFrom(data, 0, data.length, extensionRegistry);
}
+ @Override
public BuilderType mergeFrom(
- final byte[] data, final int off, final int len,
+ final byte[] data,
+ final int off,
+ final int len,
final ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
try {
@@ -220,6 +231,7 @@ public abstract class AbstractMessageLite implements MessageLite {
}
}
+ @Override
public BuilderType mergeFrom(final InputStream input) throws IOException {
final CodedInputStream codedInput = CodedInputStream.newInstance(input);
mergeFrom(codedInput);
@@ -227,10 +239,9 @@ public abstract class AbstractMessageLite implements MessageLite {
return (BuilderType) this;
}
+ @Override
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);
mergeFrom(codedInput, extensionRegistry);
codedInput.checkLastTagWas(0);
@@ -292,10 +303,9 @@ public abstract class AbstractMessageLite implements MessageLite {
}
}
+ @Override
public boolean mergeDelimitedFrom(
- final InputStream input,
- final ExtensionRegistryLite extensionRegistry)
- throws IOException {
+ final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException {
final int firstByte = input.read();
if (firstByte == -1) {
return false;
@@ -306,11 +316,24 @@ public abstract class AbstractMessageLite implements MessageLite {
return true;
}
- public boolean mergeDelimitedFrom(final InputStream input)
- throws IOException {
+ @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
diff --git a/java/core/src/main/java/com/google/protobuf/AbstractParser.java b/java/core/src/main/java/com/google/protobuf/AbstractParser.java
index 1a4c6311..66b0ee3b 100644
--- a/java/core/src/main/java/com/google/protobuf/AbstractParser.java
+++ b/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
= ExtensionRegistryLite.getEmptyRegistry();
+ @Override
public MessageType parsePartialFrom(CodedInputStream input)
throws InvalidProtocolBufferException {
return parsePartialFrom(input, EMPTY_REGISTRY);
}
- public MessageType parseFrom(CodedInputStream input,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
return checkMessageInitialized(
parsePartialFrom(input, extensionRegistry));
}
- public MessageType parseFrom(CodedInputStream input)
- throws InvalidProtocolBufferException {
+ @Override
+ public MessageType parseFrom(CodedInputStream input) throws InvalidProtocolBufferException {
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;
try {
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);
}
- public MessageType parseFrom(ByteString data,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
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);
}
- 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 {
try {
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)
throws InvalidProtocolBufferException {
return parsePartialFrom(data, off, len, EMPTY_REGISTRY);
}
- public MessageType parsePartialFrom(byte[] data,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parsePartialFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
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);
}
- 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 {
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);
}
- public MessageType parseFrom(byte[] data,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
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);
}
- public MessageType parsePartialFrom(InputStream input,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parsePartialFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
CodedInputStream codedInput = CodedInputStream.newInstance(input);
MessageType message = parsePartialFrom(codedInput, extensionRegistry);
@@ -198,26 +203,26 @@ public abstract class AbstractParser<MessageType extends MessageLite>
return message;
}
- public MessageType parsePartialFrom(InputStream input)
- throws InvalidProtocolBufferException {
+ @Override
+ public MessageType parsePartialFrom(InputStream input) throws InvalidProtocolBufferException {
return parsePartialFrom(input, EMPTY_REGISTRY);
}
- public MessageType parseFrom(InputStream input,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
return checkMessageInitialized(
parsePartialFrom(input, extensionRegistry));
}
- public MessageType parseFrom(InputStream input)
- throws InvalidProtocolBufferException {
+ @Override
+ public MessageType parseFrom(InputStream input) throws InvalidProtocolBufferException {
return parseFrom(input, EMPTY_REGISTRY);
}
+ @Override
public MessageType parsePartialDelimitedFrom(
- InputStream input,
- ExtensionRegistryLite extensionRegistry)
+ InputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
int size;
try {
@@ -233,21 +238,21 @@ public abstract class AbstractParser<MessageType extends MessageLite>
return parsePartialFrom(limitedInput, extensionRegistry);
}
+ @Override
public MessageType parsePartialDelimitedFrom(InputStream input)
throws InvalidProtocolBufferException {
return parsePartialDelimitedFrom(input, EMPTY_REGISTRY);
}
- public MessageType parseDelimitedFrom(
- InputStream input,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
return checkMessageInitialized(
parsePartialDelimitedFrom(input, extensionRegistry));
}
- public MessageType parseDelimitedFrom(InputStream input)
- throws InvalidProtocolBufferException {
+ @Override
+ public MessageType parseDelimitedFrom(InputStream input) throws InvalidProtocolBufferException {
return parseDelimitedFrom(input, EMPTY_REGISTRY);
}
}
diff --git a/java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java b/java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java
index bb6446b2..b17db6e0 100644
--- a/java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java
+++ b/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.Collection;
+import java.util.List;
+import java.util.RandomAccess;
/**
* 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.
+ * <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.
*/
@@ -55,6 +61,44 @@ abstract class AbstractProtobufList<E> extends AbstractList<E> implements Protob
}
@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);
diff --git a/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java b/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java
index 70e042f5..8b2820b6 100644
--- a/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java
+++ b/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.Collection;
-import java.util.List;
import java.util.RandomAccess;
/**
@@ -45,8 +44,6 @@ import java.util.RandomAccess;
final class BooleanArrayList
extends AbstractProtobufList<Boolean> implements BooleanList, RandomAccess {
- private static final int DEFAULT_CAPACITY = 10;
-
private static final BooleanArrayList EMPTY_LIST = new BooleanArrayList();
static {
EMPTY_LIST.makeImmutable();
@@ -60,7 +57,7 @@ final class BooleanArrayList
* The backing store for the list.
*/
private boolean[] array;
-
+
/**
* The size of the list distinct from the length of the array. That is, it is the number of
* elements set in the list.
@@ -71,35 +68,57 @@ final class BooleanArrayList
* Constructs a new mutable {@code BooleanArrayList} with default capacity.
*/
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
public Boolean get(int index) {
return getBoolean(index);
diff --git a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
index b92394b8..ad174d0f 100644
--- a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
+++ b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
@@ -30,11 +30,18 @@
package com.google.protobuf;
+import static java.lang.Math.max;
+
import com.google.protobuf.Utf8.UnpairedSurrogateException;
import java.io.IOException;
import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -50,23 +57,21 @@ import java.util.logging.Logger;
*
* <p>This class is totally unsynchronized.
*/
-public final class CodedOutputStream {
+public abstract class CodedOutputStream extends ByteOutput {
private static final Logger logger = Logger.getLogger(CodedOutputStream.class.getName());
+ private static final sun.misc.Unsafe UNSAFE = getUnsafe();
+ private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = supportsUnsafeArrayOperations();
+ private static final long ARRAY_BASE_OFFSET = byteArrayBaseOffset();
- private static final int LITTLE_ENDIAN_64_SIZE = 8;
+ private static final int FIXED_32_SIZE = 4;
+ private static final int FIXED_64_SIZE = 8;
+ private static final int MAX_VARINT_SIZE = 10;
/**
* @deprecated Use {@link #computeFixed32SizeNoTag(int)} instead.
*/
- @Deprecated public static final int LITTLE_ENDIAN_32_SIZE = 4;
-
- // TODO(dweis): Consider migrating to a ByteBuffer.
- private final byte[] buffer;
- private final int limit;
- private int position;
- private int totalBytesWritten = 0;
-
- private final OutputStream output;
+ @Deprecated
+ public static final int LITTLE_ENDIAN_32_SIZE = FIXED_32_SIZE;
/**
* The buffer size used in {@link #newInstance(OutputStream)}.
@@ -87,34 +92,27 @@ public final class CodedOutputStream {
return dataLength;
}
- private CodedOutputStream(final byte[] buffer, final int offset, final int length) {
- output = null;
- this.buffer = buffer;
- position = offset;
- limit = offset + length;
- }
-
- private CodedOutputStream(final OutputStream output, final byte[] buffer) {
- this.output = output;
- this.buffer = buffer;
- position = 0;
- limit = buffer.length;
- }
-
/**
- * Create a new {@code CodedOutputStream} wrapping the given
- * {@code OutputStream}.
+ * Create a new {@code CodedOutputStream} wrapping the given {@code OutputStream}.
+ *
+ * <p> NOTE: The provided {@link OutputStream} <strong>MUST NOT</strong> retain access or
+ * modify the provided byte arrays. Doing so may result in corrupted data, which would be
+ * difficult to debug.
*/
public static CodedOutputStream newInstance(final OutputStream output) {
return newInstance(output, DEFAULT_BUFFER_SIZE);
}
/**
- * Create a new {@code CodedOutputStream} wrapping the given
- * {@code OutputStream} with a given buffer size.
+ * Create a new {@code CodedOutputStream} wrapping the given {@code OutputStream} with a given
+ * buffer size.
+ *
+ * <p> NOTE: The provided {@link OutputStream} <strong>MUST NOT</strong> retain access or
+ * modify the provided byte arrays. Doing so may result in corrupted data, which would be
+ * difficult to debug.
*/
public static CodedOutputStream newInstance(final OutputStream output, final int bufferSize) {
- return new CodedOutputStream(output, new byte[bufferSize]);
+ return new OutputStreamEncoder(output, bufferSize);
}
/**
@@ -137,160 +135,144 @@ public final class CodedOutputStream {
*/
public static CodedOutputStream newInstance(
final byte[] flatArray, final int offset, final int length) {
- return new CodedOutputStream(flatArray, offset, length);
+ return new ArrayEncoder(flatArray, offset, length);
}
/**
- * Create a new {@code CodedOutputStream} that writes to the given ByteBuffer.
+ * Create a new {@code CodedOutputStream} that writes to the given {@link ByteBuffer}.
*/
public static CodedOutputStream newInstance(ByteBuffer byteBuffer) {
- return newInstance(byteBuffer, DEFAULT_BUFFER_SIZE);
+ if (byteBuffer.hasArray()) {
+ return new NioHeapEncoder(byteBuffer);
+ }
+ return new NioEncoder(byteBuffer);
}
/**
- * Create a new {@code CodedOutputStream} that writes to the given ByteBuffer.
+ * Create a new {@code CodedOutputStream} that writes to the given {@link ByteBuffer}.
+ *
+ * @deprecated the size parameter is no longer used since use of an internal buffer is useless
+ * (and wasteful) when writing to a {@link ByteBuffer}. Use {@link #newInstance(ByteBuffer)}
+ * instead.
*/
- public static CodedOutputStream newInstance(ByteBuffer byteBuffer, int bufferSize) {
- return newInstance(new ByteBufferOutputStream(byteBuffer), bufferSize);
+ @Deprecated
+ public static CodedOutputStream newInstance(ByteBuffer byteBuffer,
+ @SuppressWarnings("unused") int unused) {
+ return newInstance(byteBuffer);
}
- private static class ByteBufferOutputStream extends OutputStream {
- private final ByteBuffer byteBuffer;
-
- public ByteBufferOutputStream(ByteBuffer byteBuffer) {
- this.byteBuffer = byteBuffer;
+ /**
+ * Create a new {@code CodedOutputStream} that writes to the provided {@link ByteOutput}.
+ *
+ * <p> NOTE: The {@link ByteOutput} <strong>MUST NOT</strong> modify the provided buffers. Doing
+ * so may result in corrupted data, which would be difficult to debug.
+ *
+ * @param byteOutput the output target for encoded bytes.
+ * @param bufferSize the size of the internal scratch buffer to be used for string encoding.
+ * Setting this to {@code 0} will disable buffering, requiring an allocation for each encoded
+ * string.
+ */
+ static CodedOutputStream newInstance(ByteOutput byteOutput, int bufferSize) {
+ if (bufferSize < 0) {
+ throw new IllegalArgumentException("bufferSize must be positive");
}
- @Override
- public void write(int b) throws IOException {
- byteBuffer.put((byte) b);
- }
+ return new ByteOutputEncoder(byteOutput, bufferSize);
+ }
- @Override
- public void write(byte[] data, int offset, int length) throws IOException {
- byteBuffer.put(data, offset, length);
- }
+ // Disallow construction outside of this class.
+ private CodedOutputStream() {
}
// -----------------------------------------------------------------
/** Encode and write a tag. */
- public void writeTag(final int fieldNumber, final int wireType) throws IOException {
- writeRawVarint32(WireFormat.makeTag(fieldNumber, wireType));
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeTag(int fieldNumber, int wireType) throws IOException;
/** Write an {@code int32} field, including tag, to the stream. */
- public void writeInt32(final int fieldNumber, final int value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeInt32NoTag(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeInt32(int fieldNumber, int value) throws IOException;
/** Write a {@code uint32} field, including tag, to the stream. */
- public void writeUInt32(final int fieldNumber, final int value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeUInt32NoTag(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeUInt32(int fieldNumber, int value) throws IOException;
/** Write a {@code sint32} field, including tag, to the stream. */
- public void writeSInt32(final int fieldNumber, final int value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeSInt32NoTag(value);
+ public final void writeSInt32(final int fieldNumber, final int value) throws IOException {
+ writeUInt32(fieldNumber, encodeZigZag32(value));
}
/** Write a {@code fixed32} field, including tag, to the stream. */
- public void writeFixed32(final int fieldNumber, final int value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
- writeFixed32NoTag(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeFixed32(int fieldNumber, int value) throws IOException;
/** Write an {@code sfixed32} field, including tag, to the stream. */
- public void writeSFixed32(final int fieldNumber, final int value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
- writeSFixed32NoTag(value);
+ public final void writeSFixed32(final int fieldNumber, final int value) throws IOException {
+ writeFixed32(fieldNumber, value);
}
/** Write an {@code int64} field, including tag, to the stream. */
- public void writeInt64(final int fieldNumber, final long value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeInt64NoTag(value);
+ public final void writeInt64(final int fieldNumber, final long value) throws IOException {
+ writeUInt64(fieldNumber, value);
}
/** Write a {@code uint64} field, including tag, to the stream. */
- public void writeUInt64(final int fieldNumber, final long value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeUInt64NoTag(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeUInt64(int fieldNumber, long value) throws IOException;
/** Write an {@code sint64} field, including tag, to the stream. */
- public void writeSInt64(final int fieldNumber, final long value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeSInt64NoTag(value);
+ public final void writeSInt64(final int fieldNumber, final long value) throws IOException {
+ writeUInt64(fieldNumber, encodeZigZag64(value));
}
/** Write a {@code fixed64} field, including tag, to the stream. */
- public void writeFixed64(final int fieldNumber, final long value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
- writeFixed64NoTag(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeFixed64(int fieldNumber, long value) throws IOException;
/** Write an {@code sfixed64} field, including tag, to the stream. */
- public void writeSFixed64(final int fieldNumber, final long value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
- writeSFixed64NoTag(value);
+ public final void writeSFixed64(final int fieldNumber, final long value) throws IOException {
+ writeFixed64(fieldNumber, value);
}
/** Write a {@code float} field, including tag, to the stream. */
- public void writeFloat(final int fieldNumber, final float value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
- writeFloatNoTag(value);
+ public final void writeFloat(final int fieldNumber, final float value) throws IOException {
+ writeFixed32(fieldNumber, Float.floatToRawIntBits(value));
}
/** Write a {@code double} field, including tag, to the stream. */
- public void writeDouble(final int fieldNumber, final double value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
- writeDoubleNoTag(value);
+ public final void writeDouble(final int fieldNumber, final double value) throws IOException {
+ writeFixed64(fieldNumber, Double.doubleToRawLongBits(value));
}
/** Write a {@code bool} field, including tag, to the stream. */
- public void writeBool(final int fieldNumber, final boolean value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeBoolNoTag(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeBool(int fieldNumber, boolean value) throws IOException;
/**
* Write an enum field, including tag, to the stream. The provided value is the numeric
* value used to represent the enum value on the wire (not the enum ordinal value).
*/
- public void writeEnum(final int fieldNumber, final int value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeEnumNoTag(value);
+ public final void writeEnum(final int fieldNumber, final int value) throws IOException {
+ writeInt32(fieldNumber, value);
}
/** Write a {@code string} field, including tag, to the stream. */
- public void writeString(final int fieldNumber, final String value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- writeStringNoTag(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeString(int fieldNumber, String value) throws IOException;
/** Write a {@code bytes} field, including tag, to the stream. */
- public void writeBytes(final int fieldNumber, final ByteString value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- writeBytesNoTag(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeBytes(int fieldNumber, ByteString value) throws IOException;
/** Write a {@code bytes} field, including tag, to the stream. */
- public void writeByteArray(final int fieldNumber, final byte[] value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- writeByteArrayNoTag(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeByteArray(int fieldNumber, byte[] value) throws IOException;
/** Write a {@code bytes} field, including tag, to the stream. */
- public void writeByteArray(
- final int fieldNumber, final byte[] value, final int offset, final int length)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- writeByteArrayNoTag(value, offset, length);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeByteArray(int fieldNumber, byte[] value, int offset, int length)
+ throws IOException;
/**
* Write a {@code bytes} field, including tag, to the stream.
@@ -302,67 +284,36 @@ public final class CodedOutputStream {
* of a ByteBuffer, you can call
* {@code writeByteBuffer(fieldNumber, byteBuffer.slice())}.
*/
- public void writeByteBuffer(final int fieldNumber, final ByteBuffer value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- writeByteBufferNoTag(value);
- }
-
- /** Write a single byte. */
- public void writeRawByte(final byte value) throws IOException {
- if (position == limit) {
- refreshBuffer();
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeByteBuffer(int fieldNumber, ByteBuffer value) throws IOException;
- buffer[position++] = value;
- ++totalBytesWritten;
+ /**
+ * Write a single byte.
+ */
+ public final void writeRawByte(final byte value) throws IOException {
+ write(value);
}
/** Write a single byte, represented by an integer value. */
- public void writeRawByte(final int value) throws IOException {
- writeRawByte((byte) value);
+ public final void writeRawByte(final int value) throws IOException {
+ write((byte) value);
}
/** Write an array of bytes. */
- public void writeRawBytes(final byte[] value) throws IOException {
- writeRawBytes(value, 0, value.length);
+ public final void writeRawBytes(final byte[] value) throws IOException {
+ write(value, 0, value.length);
}
- /** Write part of an array of bytes. */
- public void writeRawBytes(final byte[] value, int offset, int length) throws IOException {
- if (limit - position >= length) {
- // We have room in the current buffer.
- System.arraycopy(value, offset, buffer, position, length);
- position += length;
- totalBytesWritten += length;
- } else {
- // Write extends past current buffer. Fill the rest of this buffer and
- // flush.
- final int bytesWritten = limit - position;
- System.arraycopy(value, offset, buffer, position, bytesWritten);
- offset += bytesWritten;
- length -= bytesWritten;
- position = limit;
- totalBytesWritten += bytesWritten;
- refreshBuffer();
-
- // Now deal with the rest.
- // Since we have an output stream, this is our buffer
- // and buffer offset == 0
- if (length <= limit) {
- // Fits in new buffer.
- System.arraycopy(value, offset, buffer, 0, length);
- position = length;
- } else {
- // Write is very big. Let's do it all at once.
- output.write(value, offset, length);
- }
- totalBytesWritten += length;
- }
+ /**
+ * Write part of an array of bytes.
+ */
+ public final void writeRawBytes(final byte[] value, int offset, int length) throws IOException {
+ write(value, offset, length);
}
/** Write a byte string. */
- public void writeRawBytes(final ByteString value) throws IOException {
- writeRawBytes(value, 0, value.size());
+ public final void writeRawBytes(final ByteString value) throws IOException {
+ value.writeTo(this);
}
/**
@@ -374,155 +325,138 @@ public final class CodedOutputStream {
* write the remaining bytes of a ByteBuffer, you can call
* {@code writeRawBytes(byteBuffer.slice())}.
*/
- public void writeRawBytes(final ByteBuffer value) throws IOException {
- if (value.hasArray()) {
- writeRawBytes(value.array(), value.arrayOffset(), value.capacity());
- } else {
- ByteBuffer duplicated = value.duplicate();
- duplicated.clear();
- writeRawBytesInternal(duplicated);
- }
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeRawBytes(final ByteBuffer value) throws IOException;
/** Write an embedded message field, including tag, to the stream. */
- public void writeMessage(final int fieldNumber, final MessageLite value) throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- writeMessageNoTag(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeMessage(final int fieldNumber, final MessageLite value)
+ throws IOException;
/**
* Write a MessageSet extension field to the stream. For historical reasons,
* the wire format differs from normal fields.
*/
- public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
- throws IOException {
- writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
- writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
- writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
- writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
+ throws IOException;
/**
* Write an unparsed MessageSet extension field to the stream. For
* historical reasons, the wire format differs from normal fields.
*/
- public void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
- throws IOException {
- writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
- writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
- writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
- writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
+ throws IOException;
// -----------------------------------------------------------------
/** Write an {@code int32} field to the stream. */
- public void writeInt32NoTag(final int value) throws IOException {
- if (value >= 0) {
- writeRawVarint32(value);
- } else {
- // Must sign-extend.
- writeRawVarint64(value);
- }
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeInt32NoTag(final int value) throws IOException;
/** Write a {@code uint32} field to the stream. */
- public void writeUInt32NoTag(final int value) throws IOException {
- writeRawVarint32(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeUInt32NoTag(int value) throws IOException;
/** Write a {@code sint32} field to the stream. */
- public void writeSInt32NoTag(final int value) throws IOException {
- writeRawVarint32(encodeZigZag32(value));
+ public final void writeSInt32NoTag(final int value) throws IOException {
+ writeUInt32NoTag(encodeZigZag32(value));
}
/** Write a {@code fixed32} field to the stream. */
- public void writeFixed32NoTag(final int value) throws IOException {
- writeRawLittleEndian32(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeFixed32NoTag(int value) throws IOException;
/** Write a {@code sfixed32} field to the stream. */
- public void writeSFixed32NoTag(final int value) throws IOException {
- writeRawLittleEndian32(value);
+ public final void writeSFixed32NoTag(final int value) throws IOException {
+ writeFixed32NoTag(value);
}
/** Write an {@code int64} field to the stream. */
- public void writeInt64NoTag(final long value) throws IOException {
- writeRawVarint64(value);
+ public final void writeInt64NoTag(final long value) throws IOException {
+ writeUInt64NoTag(value);
}
/** Write a {@code uint64} field to the stream. */
- public void writeUInt64NoTag(final long value) throws IOException {
- writeRawVarint64(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeUInt64NoTag(long value) throws IOException;
/** Write a {@code sint64} field to the stream. */
- public void writeSInt64NoTag(final long value) throws IOException {
- writeRawVarint64(encodeZigZag64(value));
+ public final void writeSInt64NoTag(final long value) throws IOException {
+ writeUInt64NoTag(encodeZigZag64(value));
}
/** Write a {@code fixed64} field to the stream. */
- public void writeFixed64NoTag(final long value) throws IOException {
- writeRawLittleEndian64(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeFixed64NoTag(long value) throws IOException;
/** Write a {@code sfixed64} field to the stream. */
- public void writeSFixed64NoTag(final long value) throws IOException {
- writeRawLittleEndian64(value);
+ public final void writeSFixed64NoTag(final long value) throws IOException {
+ writeFixed64NoTag(value);
}
/** Write a {@code float} field to the stream. */
- public void writeFloatNoTag(final float value) throws IOException {
- writeRawLittleEndian32(Float.floatToRawIntBits(value));
+ public final void writeFloatNoTag(final float value) throws IOException {
+ writeFixed32NoTag(Float.floatToRawIntBits(value));
}
/** Write a {@code double} field to the stream. */
- public void writeDoubleNoTag(final double value) throws IOException {
- writeRawLittleEndian64(Double.doubleToRawLongBits(value));
+ public final void writeDoubleNoTag(final double value) throws IOException {
+ writeFixed64NoTag(Double.doubleToRawLongBits(value));
}
/** Write a {@code bool} field to the stream. */
- public void writeBoolNoTag(final boolean value) throws IOException {
- writeRawByte(value ? 1 : 0);
+ public final void writeBoolNoTag(final boolean value) throws IOException {
+ write((byte) (value ? 1 : 0));
}
/**
* Write an enum field to the stream. The provided value is the numeric
* value used to represent the enum value on the wire (not the enum ordinal value).
*/
- public void writeEnumNoTag(final int value) throws IOException {
+ public final void writeEnumNoTag(final int value) throws IOException {
writeInt32NoTag(value);
}
/** Write a {@code string} field to the stream. */
// TODO(dweis): Document behavior on ill-formed UTF-16 input.
- public void writeStringNoTag(final String value) throws IOException {
- try {
- efficientWriteStringNoTag(value);
- } catch (UnpairedSurrogateException e) {
- logger.log(Level.WARNING,
- "Converting ill-formed UTF-16. Your Protocol Buffer will not round trip correctly!", e);
- inefficientWriteStringNoTag(value);
- }
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeStringNoTag(String value) throws IOException;
/** Write a {@code bytes} field to the stream. */
- public void writeBytesNoTag(final ByteString value) throws IOException {
- writeRawVarint32(value.size());
- writeRawBytes(value);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeBytesNoTag(final ByteString value) throws IOException;
/** Write a {@code bytes} field to the stream. */
- public void writeByteArrayNoTag(final byte[] value) throws IOException {
- writeRawVarint32(value.length);
- writeRawBytes(value);
+ public final void writeByteArrayNoTag(final byte[] value) throws IOException {
+ writeByteArrayNoTag(value, 0, value.length);
}
/** Write an embedded message field to the stream. */
- public void writeMessageNoTag(final MessageLite value) throws IOException {
- writeRawVarint32(value.getSerializedSize());
- value.writeTo(this);
- }
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeMessageNoTag(final MessageLite value) throws IOException;
+
+ //=================================================================
+
+ @ExperimentalApi
+ @Override
+ public abstract void write(byte value) throws IOException;
+
+ @ExperimentalApi
+ @Override
+ public abstract void write(byte[] value, int offset, int length) throws IOException;
+
+ @ExperimentalApi
+ @Override
+ public abstract void writeLazy(byte[] value, int offset, int length) throws IOException;
+
+ @Override
+ public abstract void write(ByteBuffer value) throws IOException;
+
+ @ExperimentalApi
+ @Override
+ public abstract void writeLazy(ByteBuffer value) throws IOException;
// =================================================================
// =================================================================
@@ -727,7 +661,7 @@ public final class CodedOutputStream {
/** Compute the number of bytes that would be needed to encode a tag. */
public static int computeTagSize(final int fieldNumber) {
- return computeRawVarint32Size(WireFormat.makeTag(fieldNumber, 0));
+ return computeUInt32SizeNoTag(WireFormat.makeTag(fieldNumber, 0));
}
/**
@@ -736,10 +670,10 @@ public final class CodedOutputStream {
*/
public static int computeInt32SizeNoTag(final int value) {
if (value >= 0) {
- return computeRawVarint32Size(value);
+ return computeUInt32SizeNoTag(value);
} else {
// Must sign-extend.
- return 10;
+ return MAX_VARINT_SIZE;
}
}
@@ -748,7 +682,19 @@ public final class CodedOutputStream {
* {@code uint32} field.
*/
public static int computeUInt32SizeNoTag(final int value) {
- return computeRawVarint32Size(value);
+ if ((value & (~0 << 7)) == 0) {
+ return 1;
+ }
+ if ((value & (~0 << 14)) == 0) {
+ return 2;
+ }
+ if ((value & (~0 << 21)) == 0) {
+ return 3;
+ }
+ if ((value & (~0 << 28)) == 0) {
+ return 4;
+ }
+ return 5;
}
/**
@@ -756,7 +702,7 @@ public final class CodedOutputStream {
* {@code sint32} field.
*/
public static int computeSInt32SizeNoTag(final int value) {
- return computeRawVarint32Size(encodeZigZag32(value));
+ return computeUInt32SizeNoTag(encodeZigZag32(value));
}
/**
@@ -764,7 +710,7 @@ public final class CodedOutputStream {
* {@code fixed32} field.
*/
public static int computeFixed32SizeNoTag(@SuppressWarnings("unused") final int unused) {
- return LITTLE_ENDIAN_32_SIZE;
+ return FIXED_32_SIZE;
}
/**
@@ -772,7 +718,7 @@ public final class CodedOutputStream {
* {@code sfixed32} field.
*/
public static int computeSFixed32SizeNoTag(@SuppressWarnings("unused") final int unused) {
- return LITTLE_ENDIAN_32_SIZE;
+ return FIXED_32_SIZE;
}
/**
@@ -780,15 +726,33 @@ public final class CodedOutputStream {
* {@code int64} field, including tag.
*/
public static int computeInt64SizeNoTag(final long value) {
- return computeRawVarint64Size(value);
+ return computeUInt64SizeNoTag(value);
}
/**
* Compute the number of bytes that would be needed to encode a
* {@code uint64} field, including tag.
*/
- public static int computeUInt64SizeNoTag(final long value) {
- return computeRawVarint64Size(value);
+ public static int computeUInt64SizeNoTag(long value) {
+ // handle two popular special cases up front ...
+ if ((value & (~0L << 7)) == 0L) {
+ return 1;
+ }
+ if (value < 0L) {
+ return 10;
+ }
+ // ... leaving us with 8 remaining, which we can divide and conquer
+ int n = 2;
+ if ((value & (~0L << 35)) != 0L) {
+ n += 4; value >>>= 28;
+ }
+ if ((value & (~0L << 21)) != 0L) {
+ n += 2; value >>>= 14;
+ }
+ if ((value & (~0L << 14)) != 0L) {
+ n += 1;
+ }
+ return n;
}
/**
@@ -796,7 +760,7 @@ public final class CodedOutputStream {
* {@code sint64} field.
*/
public static int computeSInt64SizeNoTag(final long value) {
- return computeRawVarint64Size(encodeZigZag64(value));
+ return computeUInt64SizeNoTag(encodeZigZag64(value));
}
/**
@@ -804,7 +768,7 @@ public final class CodedOutputStream {
* {@code fixed64} field.
*/
public static int computeFixed64SizeNoTag(@SuppressWarnings("unused") final long unused) {
- return LITTLE_ENDIAN_64_SIZE;
+ return FIXED_64_SIZE;
}
/**
@@ -812,7 +776,7 @@ public final class CodedOutputStream {
* {@code sfixed64} field.
*/
public static int computeSFixed64SizeNoTag(@SuppressWarnings("unused") final long unused) {
- return LITTLE_ENDIAN_64_SIZE;
+ return FIXED_64_SIZE;
}
/**
@@ -820,7 +784,7 @@ public final class CodedOutputStream {
* {@code float} field, including tag.
*/
public static int computeFloatSizeNoTag(@SuppressWarnings("unused") final float unused) {
- return LITTLE_ENDIAN_32_SIZE;
+ return FIXED_32_SIZE;
}
/**
@@ -828,7 +792,7 @@ public final class CodedOutputStream {
* {@code double} field, including tag.
*/
public static int computeDoubleSizeNoTag(@SuppressWarnings("unused") final double unused) {
- return LITTLE_ENDIAN_64_SIZE;
+ return FIXED_64_SIZE;
}
/**
@@ -862,7 +826,7 @@ public final class CodedOutputStream {
length = bytes.length;
}
- return computeRawVarint32Size(length) + length;
+ return computeLengthDelimitedFieldSize(length);
}
/**
@@ -870,8 +834,7 @@ public final class CodedOutputStream {
* message stored in lazy field.
*/
public static int computeLazyFieldSizeNoTag(final LazyFieldLite value) {
- final int size = value.getSerializedSize();
- return computeRawVarint32Size(size) + size;
+ return computeLengthDelimitedFieldSize(value.getSerializedSize());
}
/**
@@ -879,7 +842,7 @@ public final class CodedOutputStream {
* {@code bytes} field.
*/
public static int computeBytesSizeNoTag(final ByteString value) {
- return computeRawVarint32Size(value.size()) + value.size();
+ return computeLengthDelimitedFieldSize(value.size());
}
/**
@@ -887,7 +850,7 @@ public final class CodedOutputStream {
* {@code bytes} field.
*/
public static int computeByteArraySizeNoTag(final byte[] value) {
- return computeRawVarint32Size(value.length) + value.length;
+ return computeLengthDelimitedFieldSize(value.length);
}
/**
@@ -895,7 +858,7 @@ public final class CodedOutputStream {
* {@code bytes} field.
*/
public static int computeByteBufferSizeNoTag(final ByteBuffer value) {
- return computeRawVarint32Size(value.capacity()) + value.capacity();
+ return computeLengthDelimitedFieldSize(value.capacity());
}
/**
@@ -903,8 +866,11 @@ public final class CodedOutputStream {
* message field.
*/
public static int computeMessageSizeNoTag(final MessageLite value) {
- final int size = value.getSerializedSize();
- return computeRawVarint32Size(size) + size;
+ return computeLengthDelimitedFieldSize(value.getSerializedSize());
+ }
+
+ private static int computeLengthDelimitedFieldSize(int fieldLength) {
+ return computeUInt32SizeNoTag(fieldLength) + fieldLength;
}
/**
@@ -943,25 +909,13 @@ public final class CodedOutputStream {
* Flushes the stream and forces any buffered bytes to be written. This
* does not flush the underlying OutputStream.
*/
- public void flush() throws IOException {
- if (output != null) {
- refreshBuffer();
- }
- }
+ public abstract void flush() throws IOException;
/**
* If writing to a flat array, return the space left in the array.
* Otherwise, throws {@code UnsupportedOperationException}.
*/
- public int spaceLeft() {
- if (output == null) {
- return limit - position;
- } else {
- throw new UnsupportedOperationException(
- "spaceLeft() can only be called on CodedOutputStreams that are "
- + "writing to a flat array.");
- }
- }
+ public abstract int spaceLeft();
/**
* Verifies that {@link #spaceLeft()} returns zero. It's common to create
@@ -970,7 +924,7 @@ public final class CodedOutputStream {
* after writing verifies that the message was actually as big as expected,
* which can help catch bugs.
*/
- public void checkNoSpaceLeft() {
+ public final void checkNoSpaceLeft() {
if (spaceLeft() != 0) {
throw new IllegalStateException("Did not write as much data as expected.");
}
@@ -1001,183 +955,31 @@ public final class CodedOutputStream {
* returned value is not guaranteed to be accurate if exceptions have been
* found in the middle of writing.
*/
- public int getTotalBytesWritten() {
- return totalBytesWritten;
- }
+ public abstract int getTotalBytesWritten();
// =================================================================
- /**
- * Internal helper that writes the current buffer to the output. The
- * buffer position is reset to its initial value when this returns.
- */
- private void refreshBuffer() throws IOException {
- if (output == null) {
- // We're writing to a single buffer.
- throw new OutOfSpaceException();
- }
+ /** Write a {@code bytes} field to the stream. Visible for testing. */
+ abstract void writeByteArrayNoTag(final byte[] value, final int offset, final int length)
+ throws IOException;
- // Since we have an output stream, this is our buffer
- // and buffer offset == 0
- output.write(buffer, 0, position);
- position = 0;
- }
+ final void inefficientWriteStringNoTag(String value, UnpairedSurrogateException cause)
+ throws IOException {
+ logger.log(Level.WARNING,
+ "Converting ill-formed UTF-16. Your Protocol Buffer will not round trip correctly!", cause);
- /** Write a {@code string} field to the stream. */
- private void inefficientWriteStringNoTag(final String value) throws IOException {
// Unfortunately there does not appear to be any way to tell Java to encode
// UTF-8 directly into our buffer, so we have to let it create its own byte
// array and then copy.
// TODO(dweis): Consider using nio Charset methods instead.
final byte[] bytes = value.getBytes(Internal.UTF_8);
- writeRawVarint32(bytes.length);
- writeRawBytes(bytes);
- }
-
- /**
- * Write a {@code string} field to the stream efficiently. If the {@code string} is malformed,
- * this method rolls back its changes and throws an {@link UnpairedSurrogateException} with the
- * intent that the caller will catch and retry with {@link #inefficientWriteStringNoTag(String)}.
- *
- * @param value the string to write to the stream
- *
- * @throws UnpairedSurrogateException when {@code value} is ill-formed UTF-16.
- */
- private void efficientWriteStringNoTag(final String value) throws IOException {
- // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
- // and at most 3 times of it. We take advantage of this in both branches below.
- final int maxLength = value.length() * Utf8.MAX_BYTES_PER_CHAR;
- final int maxLengthVarIntSize = computeRawVarint32Size(maxLength);
-
- // If we are streaming and the potential length is too big to fit in our buffer, we take the
- // slower path. Otherwise, we're good to try the fast path.
- if (output != null && maxLengthVarIntSize + maxLength > limit - position) {
- // Allocate a byte[] that we know can fit the string and encode into it. String.getBytes()
- // does the same internally and then does *another copy* to return a byte[] of exactly the
- // right size. We can skip that copy and just writeRawBytes up to the actualLength of the
- // UTF-8 encoded bytes.
- final byte[] encodedBytes = new byte[maxLength];
- int actualLength = Utf8.encode(value, encodedBytes, 0, maxLength);
- writeRawVarint32(actualLength);
- writeRawBytes(encodedBytes, 0, actualLength);
- } else {
- // Optimize for the case where we know this length results in a constant varint length as this
- // saves a pass for measuring the length of the string.
- final int minLengthVarIntSize = computeRawVarint32Size(value.length());
- int oldPosition = position;
- final int length;
- try {
- if (minLengthVarIntSize == maxLengthVarIntSize) {
- position = oldPosition + minLengthVarIntSize;
- int newPosition = Utf8.encode(value, buffer, position, limit - position);
- // Since this class is stateful and tracks the position, we rewind and store the state,
- // prepend the length, then reset it back to the end of the string.
- position = oldPosition;
- length = newPosition - oldPosition - minLengthVarIntSize;
- writeRawVarint32(length);
- position = newPosition;
- } else {
- length = Utf8.encodedLength(value);
- writeRawVarint32(length);
- position = Utf8.encode(value, buffer, position, limit - position);
- }
- } catch (UnpairedSurrogateException e) {
- // Be extra careful and restore the original position for retrying the write with the less
- // efficient path.
- position = oldPosition;
- throw e;
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new OutOfSpaceException(e);
- }
- totalBytesWritten += length;
- }
- }
-
- /** Write a ByteBuffer that isn't backed by an array. */
- private void writeRawBytesInternal(final ByteBuffer value) throws IOException {
- int length = value.remaining();
- if (limit - position >= length) {
- // We have room in the current buffer.
- value.get(buffer, position, length);
- position += length;
- totalBytesWritten += length;
- } else {
- // Write extends past current buffer. Fill the rest of this buffer and
- // flush.
- final int bytesWritten = limit - position;
- value.get(buffer, position, bytesWritten);
- length -= bytesWritten;
- position = limit;
- totalBytesWritten += bytesWritten;
- refreshBuffer();
-
- // Now deal with the rest.
- // Since we have an output stream, this is our buffer
- // and buffer offset == 0
- while (length > limit) {
- // Copy data into the buffer before writing it to OutputStream.
- // TODO(xiaofeng): Introduce ZeroCopyOutputStream to avoid this copy.
- value.get(buffer, 0, limit);
- output.write(buffer, 0, limit);
- length -= limit;
- totalBytesWritten += limit;
- }
- value.get(buffer, 0, length);
- position = length;
- totalBytesWritten += length;
- }
- }
-
- /** Write a {@code bytes} field to the stream. Visible for testing. */
- void writeByteArrayNoTag(final byte[] value, final int offset, final int length)
- throws IOException {
- writeRawVarint32(length);
- writeRawBytes(value, offset, length);
- }
-
- /**
- * Write a {@code bytes} field to the stream. This method will write all
- * content of the ByteBuffer regardless of the current position and limit
- * (i.e., the number of bytes to be written is value.capacity(), not
- * value.remaining()). Furthermore, this method doesn't alter the state of
- * the passed-in ByteBuffer. Its position, limit, mark, etc. will remain
- * unchanged. If you only want to write the remaining bytes of a ByteBuffer,
- * you can call {@code writeByteBufferNoTag(byteBuffer.slice())}.
- */
- private void writeByteBufferNoTag(final ByteBuffer value) throws IOException {
- writeRawVarint32(value.capacity());
- writeRawBytes(value);
- }
-
- /** Write part of a byte string. */
- private void writeRawBytes(final ByteString value, int offset, int length) throws IOException {
- if (limit - position >= length) {
- // We have room in the current buffer.
- value.copyTo(buffer, offset, position, length);
- position += length;
- totalBytesWritten += length;
- } else {
- // Write extends past current buffer. Fill the rest of this buffer and
- // flush.
- final int bytesWritten = limit - position;
- value.copyTo(buffer, offset, position, bytesWritten);
- offset += bytesWritten;
- length -= bytesWritten;
- position = limit;
- totalBytesWritten += bytesWritten;
- refreshBuffer();
-
- // Now deal with the rest.
- // Since we have an output stream, this is our buffer
- // and buffer offset == 0
- if (length <= limit) {
- // Fits in new buffer.
- value.copyTo(buffer, offset, 0, length);
- position = length;
- } else {
- value.writeTo(output, offset, length);
- }
- totalBytesWritten += length;
+ try {
+ writeUInt32NoTag(bytes.length);
+ writeLazy(bytes, 0, bytes.length);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(e);
+ } catch (OutOfSpaceException e) {
+ throw e;
}
}
@@ -1189,7 +991,7 @@ public final class CodedOutputStream {
* @deprecated groups are deprecated.
*/
@Deprecated
- public void writeGroup(final int fieldNumber, final MessageLite value) throws IOException {
+ public final void writeGroup(final int fieldNumber, final MessageLite value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
writeGroupNoTag(value);
writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
@@ -1201,7 +1003,7 @@ public final class CodedOutputStream {
* @deprecated groups are deprecated.
*/
@Deprecated
- public void writeGroupNoTag(final MessageLite value) throws IOException {
+ public final void writeGroupNoTag(final MessageLite value) throws IOException {
value.writeTo(this);
}
@@ -1232,16 +1034,8 @@ public final class CodedOutputStream {
* @deprecated use {@link #writeUInt32NoTag} instead.
*/
@Deprecated
- public void writeRawVarint32(int value) throws IOException {
- while (true) {
- if ((value & ~0x7F) == 0) {
- writeRawByte(value);
- return;
- } else {
- writeRawByte((value & 0x7F) | 0x80);
- value >>>= 7;
- }
- }
+ public final void writeRawVarint32(int value) throws IOException {
+ writeUInt32NoTag(value);
}
/**
@@ -1250,16 +1044,8 @@ public final class CodedOutputStream {
* @deprecated use {@link #writeUInt64NoTag} instead.
*/
@Deprecated
- public void writeRawVarint64(long value) throws IOException {
- while (true) {
- if ((value & ~0x7FL) == 0) {
- writeRawByte((int) value);
- return;
- } else {
- writeRawByte(((int) value & 0x7F) | 0x80);
- value >>>= 7;
- }
- }
+ public final void writeRawVarint64(long value) throws IOException {
+ writeUInt64NoTag(value);
}
/**
@@ -1271,19 +1057,7 @@ public final class CodedOutputStream {
*/
@Deprecated
public static int computeRawVarint32Size(final int value) {
- if ((value & (~0 << 7)) == 0) {
- return 1;
- }
- if ((value & (~0 << 14)) == 0) {
- return 2;
- }
- if ((value & (~0 << 21)) == 0) {
- return 3;
- }
- if ((value & (~0 << 28)) == 0) {
- return 4;
- }
- return 5;
+ return computeUInt32SizeNoTag(value);
}
/**
@@ -1293,27 +1067,7 @@ public final class CodedOutputStream {
*/
@Deprecated
public static int computeRawVarint64Size(long value) {
- // handle two popular special cases up front ...
- if ((value & (~0L << 7)) == 0L) {
- return 1;
- }
- if (value < 0L) {
- return 10;
- }
- // ... leaving us with 8 remaining, which we can divide and conquer
- int n = 2;
- if ((value & (~0L << 35)) != 0L) {
- n += 4;
- value >>>= 28;
- }
- if ((value & (~0L << 21)) != 0L) {
- n += 2;
- value >>>= 14;
- }
- if ((value & (~0L << 14)) != 0L) {
- n += 1;
- }
- return n;
+ return computeUInt64SizeNoTag(value);
}
/**
@@ -1322,11 +1076,8 @@ public final class CodedOutputStream {
* @deprecated Use {@link #writeFixed32NoTag} instead.
*/
@Deprecated
- public void writeRawLittleEndian32(final int value) throws IOException {
- writeRawByte((value) & 0xFF);
- writeRawByte((value >> 8) & 0xFF);
- writeRawByte((value >> 16) & 0xFF);
- writeRawByte((value >> 24) & 0xFF);
+ public final void writeRawLittleEndian32(final int value) throws IOException {
+ writeFixed32NoTag(value);
}
/**
@@ -1335,14 +1086,1579 @@ public final class CodedOutputStream {
* @deprecated Use {@link #writeFixed64NoTag} instead.
*/
@Deprecated
- public void writeRawLittleEndian64(final long value) throws IOException {
- writeRawByte((int) (value) & 0xFF);
- writeRawByte((int) (value >> 8) & 0xFF);
- writeRawByte((int) (value >> 16) & 0xFF);
- writeRawByte((int) (value >> 24) & 0xFF);
- writeRawByte((int) (value >> 32) & 0xFF);
- writeRawByte((int) (value >> 40) & 0xFF);
- writeRawByte((int) (value >> 48) & 0xFF);
- writeRawByte((int) (value >> 56) & 0xFF);
+ public final void writeRawLittleEndian64(final long value) throws IOException {
+ writeFixed64NoTag(value);
+ }
+
+ // =================================================================
+
+ /**
+ * A {@link CodedOutputStream} that writes directly to a byte array.
+ */
+ private static class ArrayEncoder extends CodedOutputStream {
+ private final byte[] buffer;
+ private final int offset;
+ private final int limit;
+ private int position;
+
+ ArrayEncoder(byte[] buffer, int offset, int length) {
+ if (buffer == null) {
+ throw new NullPointerException("buffer");
+ }
+ if ((offset | length | (buffer.length - (offset + length))) < 0) {
+ throw new IllegalArgumentException(String.format(
+ "Array range is invalid. Buffer.length=%d, offset=%d, length=%d",
+ buffer.length, offset, length));
+ }
+ this.buffer = buffer;
+ this.offset = offset;
+ position = offset;
+ limit = offset + length;
+ }
+
+ @Override
+ public final void writeTag(final int fieldNumber, final int wireType) throws IOException {
+ writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
+ }
+
+ @Override
+ public final void writeInt32(final int fieldNumber, final int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeInt32NoTag(value);
+ }
+
+ @Override
+ public final void writeUInt32(final int fieldNumber, final int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeUInt32NoTag(value);
+ }
+
+ @Override
+ public final void writeFixed32(final int fieldNumber, final int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ writeFixed32NoTag(value);
+ }
+
+ @Override
+ public final void writeUInt64(final int fieldNumber, final long value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeUInt64NoTag(value);
+ }
+
+ @Override
+ public final void writeFixed64(final int fieldNumber, final long value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ writeFixed64NoTag(value);
+ }
+
+ @Override
+ public final void writeBool(final int fieldNumber, final boolean value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ write((byte) (value ? 1 : 0));
+ }
+
+ @Override
+ public final void writeString(final int fieldNumber, final String value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeStringNoTag(value);
+ }
+
+ @Override
+ public final void writeBytes(final int fieldNumber, final ByteString value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeBytesNoTag(value);
+ }
+
+ @Override
+ public final void writeByteArray(final int fieldNumber, final byte[] value) throws IOException {
+ writeByteArray(fieldNumber, value, 0, value.length);
+ }
+
+ @Override
+ public final void writeByteArray(
+ final int fieldNumber, final byte[] value, final int offset, final int length)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeByteArrayNoTag(value, offset, length);
+ }
+
+ @Override
+ public final void writeByteBuffer(final int fieldNumber, final ByteBuffer value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeUInt32NoTag(value.capacity());
+ writeRawBytes(value);
+ }
+
+ @Override
+ public final void writeBytesNoTag(final ByteString value) throws IOException {
+ writeUInt32NoTag(value.size());
+ value.writeTo(this);
+ }
+
+ @Override
+ public final void writeByteArrayNoTag(final byte[] value, int offset, int length)
+ throws IOException {
+ writeUInt32NoTag(length);
+ write(value, offset, length);
+ }
+
+ @Override
+ public final void writeRawBytes(final ByteBuffer value) throws IOException {
+ if (value.hasArray()) {
+ write(value.array(), value.arrayOffset(), value.capacity());
+ } else {
+ ByteBuffer duplicated = value.duplicate();
+ duplicated.clear();
+ write(duplicated);
+ }
+ }
+
+ @Override
+ public final void writeMessage(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeMessageNoTag(value);
+ }
+
+ @Override
+ public final void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public final void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public final void writeMessageNoTag(final MessageLite value) throws IOException {
+ writeUInt32NoTag(value.getSerializedSize());
+ value.writeTo(this);
+ }
+
+ @Override
+ public final void write(byte value) throws IOException {
+ try {
+ buffer[position++] = value;
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(new IndexOutOfBoundsException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, 1)));
+ }
+ }
+
+ @Override
+ public final void writeInt32NoTag(int value) throws IOException {
+ if (value >= 0) {
+ writeUInt32NoTag(value);
+ } else {
+ // Must sign-extend.
+ writeUInt64NoTag(value);
+ }
+ }
+
+ @Override
+ public final void writeUInt32NoTag(int value) throws IOException {
+ if (HAS_UNSAFE_ARRAY_OPERATIONS && spaceLeft() >= MAX_VARINT_SIZE) {
+ long pos = ARRAY_BASE_OFFSET + position;
+ while (true) {
+ if ((value & ~0x7F) == 0) {
+ UNSAFE.putByte(buffer, pos++, (byte) value);
+ position++;
+ return;
+ } else {
+ UNSAFE.putByte(buffer, pos++, (byte) ((value & 0x7F) | 0x80));
+ position++;
+ value >>>= 7;
+ }
+ }
+ } else {
+ try {
+ while (true) {
+ if ((value & ~0x7F) == 0) {
+ buffer[position++] = (byte) value;
+ return;
+ } else {
+ buffer[position++] = (byte) ((value & 0x7F) | 0x80);
+ value >>>= 7;
+ }
+ }
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(
+ new IndexOutOfBoundsException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, 1)));
+ }
+ }
+ }
+
+ @Override
+ public final void writeFixed32NoTag(int value) throws IOException {
+ try {
+ buffer[position++] = (byte) (value & 0xFF);
+ buffer[position++] = (byte) ((value >> 8) & 0xFF);
+ buffer[position++] = (byte) ((value >> 16) & 0xFF);
+ buffer[position++] = (byte) ((value >> 24) & 0xFF);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(
+ new IndexOutOfBoundsException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, 1)));
+ }
+ }
+
+ @Override
+ public final void writeUInt64NoTag(long value) throws IOException {
+ if (HAS_UNSAFE_ARRAY_OPERATIONS && spaceLeft() >= MAX_VARINT_SIZE) {
+ long pos = ARRAY_BASE_OFFSET + position;
+ while (true) {
+ if ((value & ~0x7FL) == 0) {
+ UNSAFE.putByte(buffer, pos++, (byte) value);
+ position++;
+ return;
+ } else {
+ UNSAFE.putByte(buffer, pos++, (byte) (((int) value & 0x7F) | 0x80));
+ position++;
+ value >>>= 7;
+ }
+ }
+ } else {
+ try {
+ while (true) {
+ if ((value & ~0x7FL) == 0) {
+ buffer[position++] = (byte) value;
+ return;
+ } else {
+ buffer[position++] = (byte) (((int) value & 0x7F) | 0x80);
+ value >>>= 7;
+ }
+ }
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(
+ new IndexOutOfBoundsException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, 1)));
+ }
+ }
+ }
+
+ @Override
+ public final void writeFixed64NoTag(long value) throws IOException {
+ try {
+ buffer[position++] = (byte) ((int) (value) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 8) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 16) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 24) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 32) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 40) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 48) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 56) & 0xFF);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(
+ new IndexOutOfBoundsException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, 1)));
+ }
+ }
+
+ @Override
+ public final void write(byte[] value, int offset, int length) throws IOException {
+ try {
+ System.arraycopy(value, offset, buffer, position, length);
+ position += length;
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(
+ new IndexOutOfBoundsException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, length)));
+ }
+ }
+
+ @Override
+ public final void writeLazy(byte[] value, int offset, int length) throws IOException {
+ write(value, offset, length);
+ }
+
+ @Override
+ public final void write(ByteBuffer value) throws IOException {
+ final int length = value.remaining();
+ try {
+ value.get(buffer, position, length);
+ position += length;
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(
+ new IndexOutOfBoundsException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, length)));
+ }
+ }
+
+ @Override
+ public final void writeLazy(ByteBuffer value) throws IOException {
+ write(value);
+ }
+
+ @Override
+ public final void writeStringNoTag(String value) throws IOException {
+ final int oldPosition = position;
+ try {
+ // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
+ // and at most 3 times of it. We take advantage of this in both branches below.
+ final int maxLength = value.length() * Utf8.MAX_BYTES_PER_CHAR;
+ final int maxLengthVarIntSize = computeUInt32SizeNoTag(maxLength);
+ final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
+ if (minLengthVarIntSize == maxLengthVarIntSize) {
+ position = oldPosition + minLengthVarIntSize;
+ int newPosition = Utf8.encode(value, buffer, position, spaceLeft());
+ // Since this class is stateful and tracks the position, we rewind and store the state,
+ // prepend the length, then reset it back to the end of the string.
+ position = oldPosition;
+ int length = newPosition - oldPosition - minLengthVarIntSize;
+ writeUInt32NoTag(length);
+ position = newPosition;
+ } else {
+ int length = Utf8.encodedLength(value);
+ writeUInt32NoTag(length);
+ position = Utf8.encode(value, buffer, position, spaceLeft());
+ }
+ } catch (UnpairedSurrogateException e) {
+ // Roll back the change - we fall back to inefficient path.
+ position = oldPosition;
+
+ // TODO(nathanmittler): We should throw an IOException here instead.
+ inefficientWriteStringNoTag(value, e);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void flush() {
+ // Do nothing.
+ }
+
+ @Override
+ public final int spaceLeft() {
+ return limit - position;
+ }
+
+ @Override
+ public final int getTotalBytesWritten() {
+ return position - offset;
+ }
+ }
+
+ /**
+ * A {@link CodedOutputStream} that writes directly to a heap {@link ByteBuffer}. Writes are
+ * done directly to the underlying array. The buffer position is only updated after a flush.
+ */
+ private static final class NioHeapEncoder extends ArrayEncoder {
+ private final ByteBuffer byteBuffer;
+ private int initialPosition;
+
+ NioHeapEncoder(ByteBuffer byteBuffer) {
+ super(byteBuffer.array(), byteBuffer.arrayOffset() + byteBuffer.position(),
+ byteBuffer.remaining());
+ this.byteBuffer = byteBuffer;
+ this.initialPosition = byteBuffer.position();
+ }
+
+ @Override
+ public void flush() {
+ // Update the position on the buffer.
+ byteBuffer.position(initialPosition + getTotalBytesWritten());
+ }
+ }
+
+ /**
+ * A {@link CodedOutputStream} that writes directly to a {@link ByteBuffer}.
+ */
+ private static final class NioEncoder extends CodedOutputStream {
+ private final ByteBuffer originalBuffer;
+ private final ByteBuffer buffer;
+ private final int initialPosition;
+
+ NioEncoder(ByteBuffer buffer) {
+ this.originalBuffer = buffer;
+ this.buffer = buffer.duplicate().order(ByteOrder.LITTLE_ENDIAN);
+ initialPosition = buffer.position();
+ }
+
+ @Override
+ public void writeTag(final int fieldNumber, final int wireType) throws IOException {
+ writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
+ }
+
+ @Override
+ public void writeInt32(final int fieldNumber, final int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeInt32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt32(final int fieldNumber, final int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeUInt32NoTag(value);
+ }
+
+ @Override
+ public void writeFixed32(final int fieldNumber, final int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ writeFixed32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt64(final int fieldNumber, final long value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeUInt64NoTag(value);
+ }
+
+ @Override
+ public void writeFixed64(final int fieldNumber, final long value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ writeFixed64NoTag(value);
+ }
+
+ @Override
+ public void writeBool(final int fieldNumber, final boolean value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ write((byte) (value ? 1 : 0));
+ }
+
+ @Override
+ public void writeString(final int fieldNumber, final String value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeStringNoTag(value);
+ }
+
+ @Override
+ public void writeBytes(final int fieldNumber, final ByteString value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeBytesNoTag(value);
+ }
+
+ @Override
+ public void writeByteArray(final int fieldNumber, final byte[] value) throws IOException {
+ writeByteArray(fieldNumber, value, 0, value.length);
+ }
+
+ @Override
+ public void writeByteArray(
+ final int fieldNumber, final byte[] value, final int offset, final int length)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeByteArrayNoTag(value, offset, length);
+ }
+
+ @Override
+ public void writeByteBuffer(final int fieldNumber, final ByteBuffer value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeUInt32NoTag(value.capacity());
+ writeRawBytes(value);
+ }
+
+ @Override
+ public void writeMessage(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeMessageNoTag(value);
+ }
+
+ @Override
+ public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public void writeMessageNoTag(final MessageLite value) throws IOException {
+ writeUInt32NoTag(value.getSerializedSize());
+ value.writeTo(this);
+ }
+
+ @Override
+ public void write(byte value) throws IOException {
+ try {
+ buffer.put(value);
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void writeBytesNoTag(final ByteString value) throws IOException {
+ writeUInt32NoTag(value.size());
+ value.writeTo(this);
+ }
+
+ @Override
+ public void writeByteArrayNoTag(final byte[] value, int offset, int length) throws IOException {
+ writeUInt32NoTag(length);
+ write(value, offset, length);
+ }
+
+ @Override
+ public void writeRawBytes(final ByteBuffer value) throws IOException {
+ if (value.hasArray()) {
+ write(value.array(), value.arrayOffset(), value.capacity());
+ } else {
+ ByteBuffer duplicated = value.duplicate();
+ duplicated.clear();
+ write(duplicated);
+ }
+ }
+
+ @Override
+ public void writeInt32NoTag(int value) throws IOException {
+ if (value >= 0) {
+ writeUInt32NoTag(value);
+ } else {
+ // Must sign-extend.
+ writeUInt64NoTag(value);
+ }
+ }
+
+ @Override
+ public void writeUInt32NoTag(int value) throws IOException {
+ try {
+ while (true) {
+ if ((value & ~0x7F) == 0) {
+ buffer.put((byte) value);
+ return;
+ } else {
+ buffer.put((byte) ((value & 0x7F) | 0x80));
+ value >>>= 7;
+ }
+ }
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void writeFixed32NoTag(int value) throws IOException {
+ try {
+ buffer.putInt(value);
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void writeUInt64NoTag(long value) throws IOException {
+ try {
+ while (true) {
+ if ((value & ~0x7FL) == 0) {
+ buffer.put((byte) value);
+ return;
+ } else {
+ buffer.put((byte) (((int) value & 0x7F) | 0x80));
+ value >>>= 7;
+ }
+ }
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void writeFixed64NoTag(long value) throws IOException {
+ try {
+ buffer.putLong(value);
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void write(byte[] value, int offset, int length) throws IOException {
+ try {
+ buffer.put(value, offset, length);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(e);
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void writeLazy(byte[] value, int offset, int length) throws IOException {
+ write(value, offset, length);
+ }
+
+ @Override
+ public void write(ByteBuffer value) throws IOException {
+ try {
+ buffer.put(value);
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void writeLazy(ByteBuffer value) throws IOException {
+ write(value);
+ }
+
+ @Override
+ public void writeStringNoTag(String value) throws IOException {
+ final int startPos = buffer.position();
+ try {
+ // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
+ // and at most 3 times of it. We take advantage of this in both branches below.
+ final int maxEncodedSize = value.length() * Utf8.MAX_BYTES_PER_CHAR;
+ final int maxLengthVarIntSize = computeUInt32SizeNoTag(maxEncodedSize);
+ final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
+ if (minLengthVarIntSize == maxLengthVarIntSize) {
+ // Save the current position and increment past the length field. We'll come back
+ // and write the length field after the encoding is complete.
+ final int startOfBytes = buffer.position() + minLengthVarIntSize;
+ buffer.position(startOfBytes);
+
+ // Encode the string.
+ encode(value);
+
+ // Now go back to the beginning and write the length.
+ int endOfBytes = buffer.position();
+ buffer.position(startPos);
+ writeUInt32NoTag(endOfBytes - startOfBytes);
+
+ // Reposition the buffer past the written data.
+ buffer.position(endOfBytes);
+ } else {
+ final int length = Utf8.encodedLength(value);
+ writeUInt32NoTag(length);
+ encode(value);
+ }
+ } catch (UnpairedSurrogateException e) {
+ // Roll back the change and convert to an IOException.
+ buffer.position(startPos);
+
+ // TODO(nathanmittler): We should throw an IOException here instead.
+ inefficientWriteStringNoTag(value, e);
+ } catch (IllegalArgumentException e) {
+ // Thrown by buffer.position() if out of range.
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void flush() {
+ // Update the position of the original buffer.
+ originalBuffer.position(buffer.position());
+ }
+
+ @Override
+ public int spaceLeft() {
+ return buffer.remaining();
+ }
+
+ @Override
+ public int getTotalBytesWritten() {
+ return buffer.position() - initialPosition;
+ }
+
+ private void encode(String value) throws IOException {
+ try {
+ Utf8.encodeUtf8(value, buffer);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+ }
+
+ /**
+ * Abstract base class for buffered encoders.
+ */
+ private abstract static class AbstractBufferedEncoder extends CodedOutputStream {
+ final byte[] buffer;
+ final int limit;
+ int position;
+ int totalBytesWritten;
+
+ AbstractBufferedEncoder(int bufferSize) {
+ if (bufferSize < 0) {
+ throw new IllegalArgumentException("bufferSize must be >= 0");
+ }
+ // As an optimization, we require that the buffer be able to store at least 2
+ // varints so that we can buffer any integer write (tag + value). This reduces the
+ // number of range checks for a single write to 1 (i.e. if there is not enough space
+ // to buffer the tag+value, flush and then buffer it).
+ this.buffer = new byte[max(bufferSize, MAX_VARINT_SIZE * 2)];
+ this.limit = buffer.length;
+ }
+
+ @Override
+ public final int spaceLeft() {
+ throw new UnsupportedOperationException(
+ "spaceLeft() can only be called on CodedOutputStreams that are "
+ + "writing to a flat array or ByteBuffer.");
+ }
+
+ @Override
+ public final int getTotalBytesWritten() {
+ return totalBytesWritten;
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void buffer(byte value) {
+ buffer[position++] = value;
+ totalBytesWritten++;
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void bufferTag(final int fieldNumber, final int wireType) {
+ bufferUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void bufferInt32NoTag(final int value) {
+ if (value >= 0) {
+ bufferUInt32NoTag(value);
+ } else {
+ // Must sign-extend.
+ bufferUInt64NoTag(value);
+ }
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void bufferUInt32NoTag(int value) {
+ if (HAS_UNSAFE_ARRAY_OPERATIONS) {
+ final long originalPos = ARRAY_BASE_OFFSET + position;
+ long pos = originalPos;
+ while (true) {
+ if ((value & ~0x7F) == 0) {
+ UNSAFE.putByte(buffer, pos++, (byte) value);
+ break;
+ } else {
+ UNSAFE.putByte(buffer, pos++, (byte) ((value & 0x7F) | 0x80));
+ value >>>= 7;
+ }
+ }
+ int delta = (int) (pos - originalPos);
+ position += delta;
+ totalBytesWritten += delta;
+ } else {
+ while (true) {
+ if ((value & ~0x7F) == 0) {
+ buffer[position++] = (byte) value;
+ totalBytesWritten++;
+ return;
+ } else {
+ buffer[position++] = (byte) ((value & 0x7F) | 0x80);
+ totalBytesWritten++;
+ value >>>= 7;
+ }
+ }
+ }
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void bufferUInt64NoTag(long value) {
+ if (HAS_UNSAFE_ARRAY_OPERATIONS) {
+ final long originalPos = ARRAY_BASE_OFFSET + position;
+ long pos = originalPos;
+ while (true) {
+ if ((value & ~0x7FL) == 0) {
+ UNSAFE.putByte(buffer, pos++, (byte) value);
+ break;
+ } else {
+ UNSAFE.putByte(buffer, pos++, (byte) (((int) value & 0x7F) | 0x80));
+ value >>>= 7;
+ }
+ }
+ int delta = (int) (pos - originalPos);
+ position += delta;
+ totalBytesWritten += delta;
+ } else {
+ while (true) {
+ if ((value & ~0x7FL) == 0) {
+ buffer[position++] = (byte) value;
+ totalBytesWritten++;
+ return;
+ } else {
+ buffer[position++] = (byte) (((int) value & 0x7F) | 0x80);
+ totalBytesWritten++;
+ value >>>= 7;
+ }
+ }
+ }
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void bufferFixed32NoTag(int value) {
+ buffer[position++] = (byte) (value & 0xFF);
+ buffer[position++] = (byte) ((value >> 8) & 0xFF);
+ buffer[position++] = (byte) ((value >> 16) & 0xFF);
+ buffer[position++] = (byte) ((value >> 24) & 0xFF);
+ totalBytesWritten += FIXED_32_SIZE;
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void bufferFixed64NoTag(long value) {
+ buffer[position++] = (byte) (value & 0xFF);
+ buffer[position++] = (byte) ((value >> 8) & 0xFF);
+ buffer[position++] = (byte) ((value >> 16) & 0xFF);
+ buffer[position++] = (byte) ((value >> 24) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 32) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 40) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 48) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 56) & 0xFF);
+ totalBytesWritten += FIXED_64_SIZE;
+ }
+ }
+
+ /**
+ * A {@link CodedOutputStream} that decorates a {@link ByteOutput}. It internal buffer only to
+ * support string encoding operations. All other writes are just passed through to the
+ * {@link ByteOutput}.
+ */
+ private static final class ByteOutputEncoder extends AbstractBufferedEncoder {
+ private final ByteOutput out;
+
+ ByteOutputEncoder(ByteOutput out, int bufferSize) {
+ super(bufferSize);
+ if (out == null) {
+ throw new NullPointerException("out");
+ }
+ this.out = out;
+ }
+
+ @Override
+ public void writeTag(final int fieldNumber, final int wireType) throws IOException {
+ writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
+ }
+
+ @Override
+ public void writeInt32(final int fieldNumber, final int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE * 2);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ bufferInt32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt32(final int fieldNumber, final int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE * 2);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ bufferUInt32NoTag(value);
+ }
+
+ @Override
+ public void writeFixed32(final int fieldNumber, final int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_32_SIZE);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ bufferFixed32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt64(final int fieldNumber, final long value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE * 2);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ bufferUInt64NoTag(value);
+ }
+
+ @Override
+ public void writeFixed64(final int fieldNumber, final long value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_64_SIZE);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ bufferFixed64NoTag(value);
+ }
+
+ @Override
+ public void writeBool(final int fieldNumber, final boolean value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE + 1);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ buffer((byte) (value ? 1 : 0));
+ }
+
+ @Override
+ public void writeString(final int fieldNumber, final String value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeStringNoTag(value);
+ }
+
+ @Override
+ public void writeBytes(final int fieldNumber, final ByteString value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeBytesNoTag(value);
+ }
+
+ @Override
+ public void writeByteArray(final int fieldNumber, final byte[] value) throws IOException {
+ writeByteArray(fieldNumber, value, 0, value.length);
+ }
+
+ @Override
+ public void writeByteArray(
+ final int fieldNumber, final byte[] value, final int offset, final int length)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeByteArrayNoTag(value, offset, length);
+ }
+
+ @Override
+ public void writeByteBuffer(final int fieldNumber, final ByteBuffer value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeUInt32NoTag(value.capacity());
+ writeRawBytes(value);
+ }
+
+ @Override
+ public void writeBytesNoTag(final ByteString value) throws IOException {
+ writeUInt32NoTag(value.size());
+ value.writeTo(this);
+ }
+
+ @Override
+ public void writeByteArrayNoTag(final byte[] value, int offset, int length) throws IOException {
+ writeUInt32NoTag(length);
+ write(value, offset, length);
+ }
+
+ @Override
+ public void writeRawBytes(final ByteBuffer value) throws IOException {
+ if (value.hasArray()) {
+ write(value.array(), value.arrayOffset(), value.capacity());
+ } else {
+ ByteBuffer duplicated = value.duplicate();
+ duplicated.clear();
+ write(duplicated);
+ }
+ }
+
+ @Override
+ public void writeMessage(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeMessageNoTag(value);
+ }
+
+ @Override
+ public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public void writeMessageNoTag(final MessageLite value) throws IOException {
+ writeUInt32NoTag(value.getSerializedSize());
+ value.writeTo(this);
+ }
+
+ @Override
+ public void write(byte value) throws IOException {
+ if (position == limit) {
+ doFlush();
+ }
+
+ buffer(value);
+ }
+
+ @Override
+ public void writeInt32NoTag(int value) throws IOException {
+ if (value >= 0) {
+ writeUInt32NoTag(value);
+ } else {
+ // Must sign-extend.
+ writeUInt64NoTag(value);
+ }
+ }
+
+ @Override
+ public void writeUInt32NoTag(int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE);
+ bufferUInt32NoTag(value);
+ }
+
+ @Override
+ public void writeFixed32NoTag(final int value) throws IOException {
+ flushIfNotAvailable(FIXED_32_SIZE);
+ bufferFixed32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt64NoTag(long value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE);
+ bufferUInt64NoTag(value);
+ }
+
+ @Override
+ public void writeFixed64NoTag(final long value) throws IOException {
+ flushIfNotAvailable(FIXED_64_SIZE);
+ bufferFixed64NoTag(value);
+ }
+
+ @Override
+ public void writeStringNoTag(String value) throws IOException {
+ // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
+ // and at most 3 times of it. We take advantage of this in both branches below.
+ final int maxLength = value.length() * Utf8.MAX_BYTES_PER_CHAR;
+ final int maxLengthVarIntSize = computeUInt32SizeNoTag(maxLength);
+
+ // If we are streaming and the potential length is too big to fit in our buffer, we take the
+ // slower path.
+ if (maxLengthVarIntSize + maxLength > limit) {
+ // Allocate a byte[] that we know can fit the string and encode into it. String.getBytes()
+ // does the same internally and then does *another copy* to return a byte[] of exactly the
+ // right size. We can skip that copy and just writeRawBytes up to the actualLength of the
+ // UTF-8 encoded bytes.
+ final byte[] encodedBytes = new byte[maxLength];
+ int actualLength = Utf8.encode(value, encodedBytes, 0, maxLength);
+ writeUInt32NoTag(actualLength);
+ writeLazy(encodedBytes, 0, actualLength);
+ return;
+ }
+
+ // Fast path: we have enough space available in our buffer for the string...
+ if (maxLengthVarIntSize + maxLength > limit - position) {
+ // Flush to free up space.
+ doFlush();
+ }
+
+ final int oldPosition = position;
+ try {
+ // Optimize for the case where we know this length results in a constant varint length as
+ // this saves a pass for measuring the length of the string.
+ final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
+
+ if (minLengthVarIntSize == maxLengthVarIntSize) {
+ position = oldPosition + minLengthVarIntSize;
+ int newPosition = Utf8.encode(value, buffer, position, limit - position);
+ // Since this class is stateful and tracks the position, we rewind and store the state,
+ // prepend the length, then reset it back to the end of the string.
+ position = oldPosition;
+ int length = newPosition - oldPosition - minLengthVarIntSize;
+ bufferUInt32NoTag(length);
+ position = newPosition;
+ totalBytesWritten += length;
+ } else {
+ int length = Utf8.encodedLength(value);
+ bufferUInt32NoTag(length);
+ position = Utf8.encode(value, buffer, position, length);
+ totalBytesWritten += length;
+ }
+ } catch (UnpairedSurrogateException e) {
+ // Roll back the change and convert to an IOException.
+ totalBytesWritten -= position - oldPosition;
+ position = oldPosition;
+
+ // TODO(nathanmittler): We should throw an IOException here instead.
+ inefficientWriteStringNoTag(value, e);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ if (position > 0) {
+ // Flush the buffer.
+ doFlush();
+ }
+ }
+
+ @Override
+ public void write(byte[] value, int offset, int length) throws IOException {
+ flush();
+ out.write(value, offset, length);
+ totalBytesWritten += length;
+ }
+
+ @Override
+ public void writeLazy(byte[] value, int offset, int length) throws IOException {
+ flush();
+ out.writeLazy(value, offset, length);
+ totalBytesWritten += length;
+ }
+
+ @Override
+ public void write(ByteBuffer value) throws IOException {
+ flush();
+ int length = value.remaining();
+ out.write(value);
+ totalBytesWritten += length;
+ }
+
+ @Override
+ public void writeLazy(ByteBuffer value) throws IOException {
+ flush();
+ int length = value.remaining();
+ out.writeLazy(value);
+ totalBytesWritten += length;
+ }
+
+ private void flushIfNotAvailable(int requiredSize) throws IOException {
+ if (limit - position < requiredSize) {
+ doFlush();
+ }
+ }
+
+ private void doFlush() throws IOException {
+ out.write(buffer, 0, position);
+ position = 0;
+ }
+ }
+
+ /**
+ * An {@link CodedOutputStream} that decorates an {@link OutputStream}. It performs internal
+ * buffering to optimize writes to the {@link OutputStream}.
+ */
+ private static final class OutputStreamEncoder extends AbstractBufferedEncoder {
+ private final OutputStream out;
+
+ OutputStreamEncoder(OutputStream out, int bufferSize) {
+ super(bufferSize);
+ if (out == null) {
+ throw new NullPointerException("out");
+ }
+ this.out = out;
+ }
+
+ @Override
+ public void writeTag(final int fieldNumber, final int wireType) throws IOException {
+ writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
+ }
+
+ @Override
+ public void writeInt32(final int fieldNumber, final int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE * 2);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ bufferInt32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt32(final int fieldNumber, final int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE * 2);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ bufferUInt32NoTag(value);
+ }
+
+ @Override
+ public void writeFixed32(final int fieldNumber, final int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_32_SIZE);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ bufferFixed32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt64(final int fieldNumber, final long value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE * 2);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ bufferUInt64NoTag(value);
+ }
+
+ @Override
+ public void writeFixed64(final int fieldNumber, final long value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_64_SIZE);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ bufferFixed64NoTag(value);
+ }
+
+ @Override
+ public void writeBool(final int fieldNumber, final boolean value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE + 1);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ buffer((byte) (value ? 1 : 0));
+ }
+
+ @Override
+ public void writeString(final int fieldNumber, final String value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeStringNoTag(value);
+ }
+
+ @Override
+ public void writeBytes(final int fieldNumber, final ByteString value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeBytesNoTag(value);
+ }
+
+ @Override
+ public void writeByteArray(final int fieldNumber, final byte[] value) throws IOException {
+ writeByteArray(fieldNumber, value, 0, value.length);
+ }
+
+ @Override
+ public void writeByteArray(
+ final int fieldNumber, final byte[] value, final int offset, final int length)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeByteArrayNoTag(value, offset, length);
+ }
+
+ @Override
+ public void writeByteBuffer(final int fieldNumber, final ByteBuffer value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeUInt32NoTag(value.capacity());
+ writeRawBytes(value);
+ }
+
+ @Override
+ public void writeBytesNoTag(final ByteString value) throws IOException {
+ writeUInt32NoTag(value.size());
+ value.writeTo(this);
+ }
+
+ @Override
+ public void writeByteArrayNoTag(final byte[] value, int offset, int length) throws IOException {
+ writeUInt32NoTag(length);
+ write(value, offset, length);
+ }
+
+ @Override
+ public void writeRawBytes(final ByteBuffer value) throws IOException {
+ if (value.hasArray()) {
+ write(value.array(), value.arrayOffset(), value.capacity());
+ } else {
+ ByteBuffer duplicated = value.duplicate();
+ duplicated.clear();
+ write(duplicated);
+ }
+ }
+
+ @Override
+ public void writeMessage(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeMessageNoTag(value);
+ }
+
+ @Override
+ public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public void writeMessageNoTag(final MessageLite value) throws IOException {
+ writeUInt32NoTag(value.getSerializedSize());
+ value.writeTo(this);
+ }
+
+ @Override
+ public void write(byte value) throws IOException {
+ if (position == limit) {
+ doFlush();
+ }
+
+ buffer(value);
+ }
+
+ @Override
+ public void writeInt32NoTag(int value) throws IOException {
+ if (value >= 0) {
+ writeUInt32NoTag(value);
+ } else {
+ // Must sign-extend.
+ writeUInt64NoTag(value);
+ }
+ }
+
+ @Override
+ public void writeUInt32NoTag(int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE);
+ bufferUInt32NoTag(value);
+ }
+
+ @Override
+ public void writeFixed32NoTag(final int value) throws IOException {
+ flushIfNotAvailable(FIXED_32_SIZE);
+ bufferFixed32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt64NoTag(long value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE);
+ bufferUInt64NoTag(value);
+ }
+
+ @Override
+ public void writeFixed64NoTag(final long value) throws IOException {
+ flushIfNotAvailable(FIXED_64_SIZE);
+ bufferFixed64NoTag(value);
+ }
+
+ @Override
+ public void writeStringNoTag(String value) throws IOException {
+ try {
+ // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
+ // and at most 3 times of it. We take advantage of this in both branches below.
+ final int maxLength = value.length() * Utf8.MAX_BYTES_PER_CHAR;
+ final int maxLengthVarIntSize = computeUInt32SizeNoTag(maxLength);
+
+ // If we are streaming and the potential length is too big to fit in our buffer, we take the
+ // slower path.
+ if (maxLengthVarIntSize + maxLength > limit) {
+ // Allocate a byte[] that we know can fit the string and encode into it. String.getBytes()
+ // does the same internally and then does *another copy* to return a byte[] of exactly the
+ // right size. We can skip that copy and just writeRawBytes up to the actualLength of the
+ // UTF-8 encoded bytes.
+ final byte[] encodedBytes = new byte[maxLength];
+ int actualLength = Utf8.encode(value, encodedBytes, 0, maxLength);
+ writeUInt32NoTag(actualLength);
+ writeLazy(encodedBytes, 0, actualLength);
+ return;
+ }
+
+ // Fast path: we have enough space available in our buffer for the string...
+ if (maxLengthVarIntSize + maxLength > limit - position) {
+ // Flush to free up space.
+ doFlush();
+ }
+
+ // Optimize for the case where we know this length results in a constant varint length as
+ // this saves a pass for measuring the length of the string.
+ final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
+ int oldPosition = position;
+ final int length;
+ try {
+ if (minLengthVarIntSize == maxLengthVarIntSize) {
+ position = oldPosition + minLengthVarIntSize;
+ int newPosition = Utf8.encode(value, buffer, position, limit - position);
+ // Since this class is stateful and tracks the position, we rewind and store the
+ // state, prepend the length, then reset it back to the end of the string.
+ position = oldPosition;
+ length = newPosition - oldPosition - minLengthVarIntSize;
+ bufferUInt32NoTag(length);
+ position = newPosition;
+ } else {
+ length = Utf8.encodedLength(value);
+ bufferUInt32NoTag(length);
+ position = Utf8.encode(value, buffer, position, length);
+ }
+ totalBytesWritten += length;
+ } catch (UnpairedSurrogateException e) {
+ // Be extra careful and restore the original position for retrying the write with the
+ // less efficient path.
+ totalBytesWritten -= position - oldPosition;
+ position = oldPosition;
+ throw e;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(e);
+ }
+ } catch (UnpairedSurrogateException e) {
+ inefficientWriteStringNoTag(value, e);
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ if (position > 0) {
+ // Flush the buffer.
+ doFlush();
+ }
+ }
+
+ @Override
+ public void write(byte[] value, int offset, int length)
+ throws IOException {
+ if (limit - position >= length) {
+ // We have room in the current buffer.
+ System.arraycopy(value, offset, buffer, position, length);
+ position += length;
+ totalBytesWritten += length;
+ } else {
+ // Write extends past current buffer. Fill the rest of this buffer and
+ // flush.
+ final int bytesWritten = limit - position;
+ System.arraycopy(value, offset, buffer, position, bytesWritten);
+ offset += bytesWritten;
+ length -= bytesWritten;
+ position = limit;
+ totalBytesWritten += bytesWritten;
+ doFlush();
+
+ // Now deal with the rest.
+ // Since we have an output stream, this is our buffer
+ // and buffer offset == 0
+ if (length <= limit) {
+ // Fits in new buffer.
+ System.arraycopy(value, offset, buffer, 0, length);
+ position = length;
+ } else {
+ // Write is very big. Let's do it all at once.
+ out.write(value, offset, length);
+ }
+ totalBytesWritten += length;
+ }
+ }
+
+ @Override
+ public void writeLazy(byte[] value, int offset, int length) throws IOException {
+ write(value, offset, length);
+ }
+
+ @Override
+ public void write(ByteBuffer value) throws IOException {
+ int length = value.remaining();
+ if (limit - position >= length) {
+ // We have room in the current buffer.
+ value.get(buffer, position, length);
+ position += length;
+ totalBytesWritten += length;
+ } else {
+ // Write extends past current buffer. Fill the rest of this buffer and
+ // flush.
+ final int bytesWritten = limit - position;
+ value.get(buffer, position, bytesWritten);
+ length -= bytesWritten;
+ position = limit;
+ totalBytesWritten += bytesWritten;
+ doFlush();
+
+ // Now deal with the rest.
+ // Since we have an output stream, this is our buffer
+ // and buffer offset == 0
+ while (length > limit) {
+ // Copy data into the buffer before writing it to OutputStream.
+ value.get(buffer, 0, limit);
+ out.write(buffer, 0, limit);
+ length -= limit;
+ totalBytesWritten += limit;
+ }
+ value.get(buffer, 0, length);
+ position = length;
+ totalBytesWritten += length;
+ }
+ }
+
+ @Override
+ public void writeLazy(ByteBuffer value) throws IOException {
+ write(value);
+ }
+
+ private void flushIfNotAvailable(int requiredSize) throws IOException {
+ if (limit - position < requiredSize) {
+ doFlush();
+ }
+ }
+
+ private void doFlush() throws IOException {
+ out.write(buffer, 0, position);
+ position = 0;
+ }
+ }
+
+ /**
+ * Gets the {@code sun.misc.Unsafe} instance, or {@code null} if not available on this
+ * platform.
+ */
+ private static sun.misc.Unsafe getUnsafe() {
+ sun.misc.Unsafe unsafe = null;
+ try {
+ unsafe = AccessController.doPrivileged(new PrivilegedExceptionAction<sun.misc.Unsafe>() {
+ @Override
+ public sun.misc.Unsafe run() throws Exception {
+ Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
+
+ for (Field f : k.getDeclaredFields()) {
+ f.setAccessible(true);
+ Object x = f.get(null);
+ if (k.isInstance(x)) {
+ return k.cast(x);
+ }
+ }
+ // The sun.misc.Unsafe field does not exist.
+ return null;
+ }
+ });
+ } catch (Throwable e) {
+ // Catching Throwable here due to the fact that Google AppEngine raises NoClassDefFoundError
+ // for Unsafe.
+ }
+
+ logger.log(Level.FINEST, "sun.misc.Unsafe: {}",
+ unsafe != null ? "available" : "unavailable");
+ return unsafe;
+ }
+
+ /**
+ * Indicates whether or not unsafe array operations are supported on this platform.
+ */
+ // TODO(nathanmittler): Add support for Android's MemoryBlock.
+ private static boolean supportsUnsafeArrayOperations() {
+ boolean supported = false;
+ if (UNSAFE != null) {
+ try {
+ UNSAFE.getClass().getMethod("arrayBaseOffset", Class.class);
+ UNSAFE.getClass().getMethod("putByte", Object.class, long.class, byte.class);
+ supported = true;
+ } catch (Throwable e) {
+ // Do nothing.
+ }
+ }
+ logger.log(Level.FINEST, "Unsafe array operations: {}",
+ supported ? "available" : "unavailable");
+ return supported;
+ }
+
+ /**
+ * Get the base offset for byte arrays, or {@code -1} if {@code sun.misc.Unsafe} is not
+ * available.
+ */
+ private static <T> int byteArrayBaseOffset() {
+ return HAS_UNSAFE_ARRAY_OPERATIONS ? UNSAFE.arrayBaseOffset(byte[].class) : -1;
}
}
diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java
index e303e138..e00ea342 100644
--- a/java/core/src/main/java/com/google/protobuf/Descriptors.java
+++ b/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 {
/** Convert the descriptor to its protocol message representation. */
- public FileDescriptorProto toProto() { return proto; }
+ @Override
+ public FileDescriptorProto toProto() {
+ return proto;
+ }
/** Get the file name. */
- public String getName() { return proto.getName(); }
+ @Override
+ public String getName() {
+ return proto.getName();
+ }
/** Returns this object. */
- public FileDescriptor getFile() { return this; }
+ @Override
+ public FileDescriptor getFile() {
+ return this;
+ }
/** 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
@@ -582,10 +594,16 @@ public final class Descriptors {
public int getIndex() { return index; }
/** 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. */
- 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
@@ -598,10 +616,16 @@ public final class Descriptors {
* </pre>
* {@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. */
- public FileDescriptor getFile() { return file; }
+ @Override
+ public FileDescriptor getFile() {
+ return file;
+ }
/** If this is a nested type, get the outer descriptor, otherwise null. */
public Descriptor getContainingType() { return containingType; }
@@ -875,19 +899,31 @@ public final class Descriptors {
public int getIndex() { return index; }
/** 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. */
- public String getName() { return proto.getName(); }
+ @Override
+ public String getName() {
+ return proto.getName();
+ }
/** 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.
* @see Descriptors.Descriptor#getFullName()
*/
- public String getFullName() { return fullName; }
+ @Override
+ public String getFullName() {
+ return fullName;
+ }
/** Get the JSON name of this field. */
public String getJsonName() {
@@ -901,17 +937,22 @@ public final class Descriptors {
public JavaType getJavaType() { return type.getJavaType(); }
/** For internal use only. */
+ @Override
public WireFormat.JavaType getLiteJavaType() {
return getLiteType().getJavaType();
}
/** Get the {@code FileDescriptor} containing this descriptor. */
- public FileDescriptor getFile() { return file; }
+ @Override
+ public FileDescriptor getFile() {
+ return file;
+ }
/** Get the field's declared type. */
public Type getType() { return type; }
/** For internal use only. */
+ @Override
public WireFormat.FieldType getLiteType() {
return table[type.ordinal()];
}
@@ -953,6 +994,7 @@ public final class Descriptors {
}
/** Is this field declared repeated? */
+ @Override
public boolean isRepeated() {
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
* packable in proto3 and not explicitly setted to unpacked?
*/
+ @Override
public boolean isPacked() {
if (!isPackable()) {
return false;
@@ -1048,6 +1091,7 @@ public final class Descriptors {
}
/** For enum fields, gets the field's type. */
+ @Override
public EnumDescriptor getEnumType() {
if (getJavaType() != JavaType.ENUM) {
throw new UnsupportedOperationException(
@@ -1066,6 +1110,7 @@ public final class Descriptors {
* @return negative, zero, or positive if {@code this} is less than,
* equal to, or greater than {@code other}, respectively.
*/
+ @Override
public int compareTo(final FieldDescriptor other) {
if (other.containingType != containingType) {
throw new IllegalArgumentException(
@@ -1466,8 +1511,8 @@ public final class Descriptors {
* For internal use only. This is to satisfy the FieldDescriptorLite
* 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
// down-cast and call mergeFrom directly.
return ((Message.Builder) to).mergeFrom((Message) from);
@@ -1487,19 +1532,31 @@ public final class Descriptors {
public int getIndex() { return index; }
/** 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. */
- public String getName() { return proto.getName(); }
+ @Override
+ public String getName() {
+ return proto.getName();
+ }
/**
* Get the type's fully-qualified name.
* @see Descriptors.Descriptor#getFullName()
*/
- public String getFullName() { return fullName; }
+ @Override
+ public String getFullName() {
+ return fullName;
+ }
/** 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. */
public Descriptor getContainingType() { return containingType; }
@@ -1533,6 +1590,7 @@ public final class Descriptors {
* @param number The value's number.
* @return the value's descriptor, or {@code null} if not found.
*/
+ @Override
public EnumValueDescriptor findValueByNumber(final int number) {
return file.pool.enumValuesByNumber.get(
new DescriptorPool.DescriptorIntPair(this, number));
@@ -1659,13 +1717,22 @@ public final class Descriptors {
public int getIndex() { return index; }
/** 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. */
- public String getName() { return proto.getName(); }
+ @Override
+ public String getName() {
+ return proto.getName();
+ }
/** Get the value's number. */
- public int getNumber() { return proto.getNumber(); }
+ @Override
+ public int getNumber() {
+ return proto.getNumber();
+ }
@Override
public String toString() { return proto.getName(); }
@@ -1674,10 +1741,16 @@ public final class Descriptors {
* Get the value's fully-qualified name.
* @see Descriptors.Descriptor#getFullName()
*/
- public String getFullName() { return fullName; }
+ @Override
+ public String getFullName() {
+ return fullName;
+ }
/** Get the {@link FileDescriptor} containing this descriptor. */
- public FileDescriptor getFile() { return file; }
+ @Override
+ public FileDescriptor getFile() {
+ return file;
+ }
/** Get the value's enum type. */
public EnumDescriptor getType() { return type; }
@@ -1745,19 +1818,31 @@ public final class Descriptors {
public int getIndex() { return index; }
/** 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. */
- public String getName() { return proto.getName(); }
+ @Override
+ public String getName() {
+ return proto.getName();
+ }
/**
* Get the type's fully-qualified name.
* @see Descriptors.Descriptor#getFullName()
*/
- public String getFullName() { return fullName; }
+ @Override
+ public String getFullName() {
+ return fullName;
+ }
/** 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}. */
public ServiceOptions getOptions() { return proto.getOptions(); }
@@ -1835,19 +1920,31 @@ public final class Descriptors {
public int getIndex() { return index; }
/** 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. */
- public String getName() { return proto.getName(); }
+ @Override
+ public String getName() {
+ return proto.getName();
+ }
/**
* Get the method's fully-qualified name.
* @see Descriptors.Descriptor#getFullName()
*/
- public String getFullName() { return fullName; }
+ @Override
+ public String getFullName() {
+ return fullName;
+ }
/** Get the {@link FileDescriptor} containing this descriptor. */
- public FileDescriptor getFile() { return file; }
+ @Override
+ public FileDescriptor getFile() {
+ return file;
+ }
/** Get the method's service type. */
public ServiceDescriptor getService() { return service; }
@@ -2248,10 +2345,22 @@ public final class Descriptors {
* that has the same name as an existing package.
*/
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,
final FileDescriptor file) {
diff --git a/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java b/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java
index bcc9d6ee..a9543b83 100644
--- a/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java
+++ b/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.Collection;
-import java.util.List;
import java.util.RandomAccess;
/**
@@ -45,8 +44,6 @@ import java.util.RandomAccess;
final class DoubleArrayList
extends AbstractProtobufList<Double> implements DoubleList, RandomAccess {
- private static final int DEFAULT_CAPACITY = 10;
-
private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList();
static {
EMPTY_LIST.makeImmutable();
@@ -71,32 +68,56 @@ final class DoubleArrayList
* Constructs a new mutable {@code DoubleArrayList} with default capacity.
*/
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}.
*/
- 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
diff --git a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
index 3ea1b688..859a9e8f 100644
--- a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
@@ -156,18 +156,22 @@ public final class DynamicMessage extends AbstractMessage {
// -----------------------------------------------------------------
// Implementation of Message interface.
+ @Override
public Descriptor getDescriptorForType() {
return type;
}
+ @Override
public DynamicMessage getDefaultInstanceForType() {
return getDefaultInstance(type);
}
+ @Override
public Map<FieldDescriptor, Object> getAllFields() {
return fields.getAllFields();
}
+ @Override
public boolean hasOneof(OneofDescriptor oneof) {
verifyOneofContainingType(oneof);
FieldDescriptor field = oneofCases[oneof.getIndex()];
@@ -177,16 +181,19 @@ public final class DynamicMessage extends AbstractMessage {
return true;
}
+ @Override
public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
verifyOneofContainingType(oneof);
return oneofCases[oneof.getIndex()];
}
+ @Override
public boolean hasField(FieldDescriptor field) {
verifyContainingType(field);
return fields.hasField(field);
}
+ @Override
public Object getField(FieldDescriptor field) {
verifyContainingType(field);
Object result = fields.getField(field);
@@ -202,16 +209,19 @@ public final class DynamicMessage extends AbstractMessage {
return result;
}
+ @Override
public int getRepeatedFieldCount(FieldDescriptor field) {
verifyContainingType(field);
return fields.getRepeatedFieldCount(field);
}
+ @Override
public Object getRepeatedField(FieldDescriptor field, int index) {
verifyContainingType(field);
return fields.getRepeatedField(field, index);
}
+ @Override
public UnknownFieldSet getUnknownFields() {
return unknownFields;
}
@@ -264,19 +274,22 @@ public final class DynamicMessage extends AbstractMessage {
return size;
}
+ @Override
public Builder newBuilderForType() {
return new Builder(type);
}
+ @Override
public Builder toBuilder() {
return newBuilderForType().mergeFrom(this);
}
+ @Override
public Parser<DynamicMessage> getParserForType() {
return new AbstractParser<DynamicMessage>() {
+ @Override
public DynamicMessage parsePartialFrom(
- CodedInputStream input,
- ExtensionRegistryLite extensionRegistry)
+ CodedInputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
Builder builder = newBuilder(type);
try {
@@ -370,6 +383,7 @@ public final class DynamicMessage extends AbstractMessage {
}
}
+ @Override
public DynamicMessage build() {
if (!isInitialized()) {
throw newUninitializedMessageException(
@@ -394,6 +408,7 @@ public final class DynamicMessage extends AbstractMessage {
return buildPartial();
}
+ @Override
public DynamicMessage buildPartial() {
fields.makeImmutable();
DynamicMessage result =
@@ -411,22 +426,27 @@ public final class DynamicMessage extends AbstractMessage {
return result;
}
+ @Override
public boolean isInitialized() {
return DynamicMessage.isInitialized(type, fields);
}
+ @Override
public Descriptor getDescriptorForType() {
return type;
}
+ @Override
public DynamicMessage getDefaultInstanceForType() {
return getDefaultInstance(type);
}
+ @Override
public Map<FieldDescriptor, Object> getAllFields() {
return fields.getAllFields();
}
+ @Override
public Builder newBuilderForField(FieldDescriptor field) {
verifyContainingType(field);
@@ -438,6 +458,7 @@ public final class DynamicMessage extends AbstractMessage {
return new Builder(field.getMessageType());
}
+ @Override
public boolean hasOneof(OneofDescriptor oneof) {
verifyOneofContainingType(oneof);
FieldDescriptor field = oneofCases[oneof.getIndex()];
@@ -447,11 +468,13 @@ public final class DynamicMessage extends AbstractMessage {
return true;
}
+ @Override
public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
verifyOneofContainingType(oneof);
return oneofCases[oneof.getIndex()];
}
+ @Override
public Builder clearOneof(OneofDescriptor oneof) {
verifyOneofContainingType(oneof);
FieldDescriptor field = oneofCases[oneof.getIndex()];
@@ -461,11 +484,13 @@ public final class DynamicMessage extends AbstractMessage {
return this;
}
+ @Override
public boolean hasField(FieldDescriptor field) {
verifyContainingType(field);
return fields.hasField(field);
}
+ @Override
public Object getField(FieldDescriptor field) {
verifyContainingType(field);
Object result = fields.getField(field);
@@ -481,6 +506,7 @@ public final class DynamicMessage extends AbstractMessage {
return result;
}
+ @Override
public Builder setField(FieldDescriptor field, Object value) {
verifyContainingType(field);
ensureIsMutable();
@@ -505,6 +531,7 @@ public final class DynamicMessage extends AbstractMessage {
return this;
}
+ @Override
public Builder clearField(FieldDescriptor field) {
verifyContainingType(field);
ensureIsMutable();
@@ -519,24 +546,27 @@ public final class DynamicMessage extends AbstractMessage {
return this;
}
+ @Override
public int getRepeatedFieldCount(FieldDescriptor field) {
verifyContainingType(field);
return fields.getRepeatedFieldCount(field);
}
+ @Override
public Object getRepeatedField(FieldDescriptor field, int index) {
verifyContainingType(field);
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);
ensureIsMutable();
fields.setRepeatedField(field, index, value);
return this;
}
+ @Override
public Builder addRepeatedField(FieldDescriptor field, Object value) {
verifyContainingType(field);
ensureIsMutable();
@@ -544,10 +574,12 @@ public final class DynamicMessage extends AbstractMessage {
return this;
}
+ @Override
public UnknownFieldSet getUnknownFields() {
return unknownFields;
}
+ @Override
public Builder setUnknownFields(UnknownFieldSet unknownFields) {
if (getDescriptorForType().getFile().getSyntax()
== Descriptors.FileDescriptor.Syntax.PROTO3) {
diff --git a/java/core/src/main/java/com/google/protobuf/Extension.java b/java/core/src/main/java/com/google/protobuf/Extension.java
index 68d29f33..08ec5b45 100644
--- a/java/core/src/main/java/com/google/protobuf/Extension.java
+++ b/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();
/** Returns whether or not this extension is a Lite Extension. */
+ @Override
final boolean isLite() {
return false;
}
diff --git a/java/core/src/main/java/com/google/protobuf/FieldSet.java b/java/core/src/main/java/com/google/protobuf/FieldSet.java
index 47924b65..4e89709f 100644
--- a/java/core/src/main/java/com/google/protobuf/FieldSet.java
+++ b/java/core/src/main/java/com/google/protobuf/FieldSet.java
@@ -120,6 +120,25 @@ final class FieldSet<FieldDescriptorType extends
public boolean 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
diff --git a/java/core/src/main/java/com/google/protobuf/FloatArrayList.java b/java/core/src/main/java/com/google/protobuf/FloatArrayList.java
index 033b5eed..63cb6d77 100644
--- a/java/core/src/main/java/com/google/protobuf/FloatArrayList.java
+++ b/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.Collection;
-import java.util.List;
import java.util.RandomAccess;
/**
@@ -44,8 +43,6 @@ import java.util.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();
static {
EMPTY_LIST.makeImmutable();
@@ -70,32 +67,55 @@ final class FloatArrayList extends AbstractProtobufList<Float> implements FloatL
* Constructs a new mutable {@code FloatArrayList} with default capacity.
*/
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}.
*/
- 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
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
index a50afe55..57e732a0 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
@@ -80,6 +80,7 @@ public abstract class GeneratedMessage extends AbstractMessage
unknownFields = builder.getUnknownFields();
}
+ @Override
public Parser<? extends GeneratedMessage> getParserForType() {
throw new UnsupportedOperationException(
"This is supposed to be overridden by subclasses.");
@@ -102,7 +103,7 @@ public abstract class GeneratedMessage extends AbstractMessage
*/
protected abstract FieldAccessorTable internalGetFieldAccessorTable();
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Descriptor getDescriptorForType() {
return internalGetFieldAccessorTable().descriptor;
}
@@ -191,7 +192,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return true;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Map<FieldDescriptor, Object> getAllFields() {
return Collections.unmodifiableMap(
getAllFieldsMutable(/* getBytesForString = */ false));
@@ -212,22 +213,22 @@ public abstract class GeneratedMessage extends AbstractMessage
getAllFieldsMutable(/* getBytesForString = */ true));
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasOneof(final OneofDescriptor oneof) {
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) {
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) {
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) {
return internalGetFieldAccessorTable().getField(field).get(this);
}
@@ -244,19 +245,19 @@ public abstract class GeneratedMessage extends AbstractMessage
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) {
return internalGetFieldAccessorTable().getField(field)
.getRepeatedCount(this);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Object getRepeatedField(final FieldDescriptor field, final int index) {
return internalGetFieldAccessorTable().getField(field)
.getRepeated(this, index);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public UnknownFieldSet getUnknownFields() {
throw new UnsupportedOperationException(
"This is supposed to be overridden by subclasses.");
@@ -380,7 +381,7 @@ public abstract class GeneratedMessage extends AbstractMessage
}
@SuppressWarnings("unchecked")
- public abstract static class Builder <BuilderType extends Builder>
+ public abstract static class Builder <BuilderType extends Builder<BuilderType>>
extends AbstractMessage.Builder<BuilderType> {
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
* reset any of their builtin fields back to the initial values.
*/
+ @Override
public BuilderType clear() {
unknownFields = UnknownFieldSet.getDefaultInstance();
onChanged();
@@ -457,12 +459,12 @@ public abstract class GeneratedMessage extends AbstractMessage
*/
protected abstract FieldAccessorTable internalGetFieldAccessorTable();
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Descriptor getDescriptorForType() {
return internalGetFieldAccessorTable().descriptor;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Map<FieldDescriptor, Object> getAllFields() {
return Collections.unmodifiableMap(getAllFieldsMutable());
}
@@ -510,39 +512,38 @@ public abstract class GeneratedMessage extends AbstractMessage
return result;
}
- public Message.Builder newBuilderForField(
- final FieldDescriptor field) {
+ @Override
+ public Message.Builder newBuilderForField(final FieldDescriptor field) {
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) {
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(
this, index);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasOneof(final OneofDescriptor oneof) {
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) {
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) {
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) {
Object object = internalGetFieldAccessorTable().getField(field).get(this);
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);
return (BuilderType) this;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public BuilderType clearField(final FieldDescriptor field) {
internalGetFieldAccessorTable().getField(field).clear(this);
return (BuilderType) this;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public BuilderType clearOneof(final OneofDescriptor oneof) {
internalGetFieldAccessorTable().getOneof(oneof).clear(this);
return (BuilderType) this;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public int getRepeatedFieldCount(final FieldDescriptor field) {
return internalGetFieldAccessorTable().getField(field)
.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)
.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)
.setRepeated(this, index, value);
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);
return (BuilderType) this;
}
- public BuilderType setUnknownFields(
- final UnknownFieldSet unknownFields) {
+ @Override
+ public BuilderType setUnknownFields(final UnknownFieldSet unknownFields) {
this.unknownFields = unknownFields;
onChanged();
return (BuilderType) this;
@@ -616,7 +617,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return (BuilderType) this;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean isInitialized() {
for (final FieldDescriptor field : getDescriptorForType().getFields()) {
// Check that all required fields are present.
@@ -646,7 +647,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return true;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final UnknownFieldSet getUnknownFields() {
return unknownFields;
}
@@ -670,7 +671,7 @@ public abstract class GeneratedMessage extends AbstractMessage
*/
private class BuilderParentImpl implements BuilderParent {
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void markDirty() {
onChanged();
}
@@ -735,6 +736,7 @@ public abstract class GeneratedMessage extends AbstractMessage
public interface ExtendableMessageOrBuilder<
MessageType extends ExtendableMessage> extends MessageOrBuilder {
// Re-define for return type covariance.
+ @Override
Message getDefaultInstanceForType();
/** Check if a singular extension is present. */
@@ -821,9 +823,8 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** 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);
verifyExtensionContainingType(extension);
@@ -831,7 +832,7 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** 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(
final ExtensionLite<MessageType, List<Type>> extensionLite) {
Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
@@ -842,10 +843,9 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** Get the value of an extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
@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);
verifyExtensionContainingType(extension);
@@ -867,11 +867,10 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** Get one element of a repeated extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
@SuppressWarnings("unchecked")
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);
verifyExtensionContainingType(extension);
@@ -1105,7 +1104,7 @@ public abstract class GeneratedMessage extends AbstractMessage
@SuppressWarnings("unchecked")
public abstract static class ExtendableBuilder<
MessageType extends ExtendableMessage,
- BuilderType extends ExtendableBuilder>
+ BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
extends Builder<BuilderType>
implements ExtendableMessageOrBuilder<MessageType> {
@@ -1157,9 +1156,8 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** 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);
verifyExtensionContainingType(extension);
@@ -1167,7 +1165,7 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** 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(
final ExtensionLite<MessageType, List<Type>> extensionLite) {
Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
@@ -1178,9 +1176,8 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** 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);
verifyExtensionContainingType(extension);
@@ -1202,10 +1199,9 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** 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(
- 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);
verifyExtensionContainingType(extension);
@@ -1458,10 +1454,9 @@ public abstract class GeneratedMessage extends AbstractMessage
// obtained.
return new GeneratedExtension<ContainingType, Type>(
new CachedDescriptorRetriever() {
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public FieldDescriptor loadDescriptor() {
- return scope.getDescriptorForType().getExtensions()
- .get(descriptorIndex);
+ return scope.getDescriptorForType().getExtensions().get(descriptorIndex);
}
},
singularType,
@@ -1489,6 +1484,7 @@ public abstract class GeneratedMessage extends AbstractMessage
private volatile FieldDescriptor descriptor;
protected abstract FieldDescriptor loadDescriptor();
+ @Override
public FieldDescriptor getDescriptor() {
if (descriptor == null) {
synchronized (this) {
@@ -1518,6 +1514,7 @@ public abstract class GeneratedMessage extends AbstractMessage
// obtained.
return new GeneratedExtension<ContainingType, Type>(
new CachedDescriptorRetriever() {
+ @Override
protected FieldDescriptor loadDescriptor() {
return scope.getDescriptorForType().findFieldByName(name);
}
@@ -1544,17 +1541,18 @@ public abstract class GeneratedMessage extends AbstractMessage
// used to obtain the extension's FieldDescriptor.
return new GeneratedExtension<ContainingType, Type>(
new CachedDescriptorRetriever() {
+ @Override
protected FieldDescriptor loadDescriptor() {
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);
} catch (Exception e) {
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) {
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;
@@ -1651,6 +1650,7 @@ public abstract class GeneratedMessage extends AbstractMessage
private final Method enumGetValueDescriptor;
private final ExtensionType extensionType;
+ @Override
public FieldDescriptor getDescriptor() {
if (descriptorRetriever == null) {
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
* instance of the message.
*/
+ @Override
public Message getMessageDefaultInstance() {
return messageDefaultInstance;
}
+ @Override
protected ExtensionType getExtensionType() {
return extensionType;
}
@@ -1677,7 +1679,7 @@ public abstract class GeneratedMessage extends AbstractMessage
* EnumValueDescriptors but the native accessors use the generated enum
* type.
*/
- // @Override
+ @Override
@SuppressWarnings("unchecked")
protected Object fromReflectionType(final Object value) {
FieldDescriptor descriptor = getDescriptor();
@@ -1702,7 +1704,7 @@ public abstract class GeneratedMessage extends AbstractMessage
* Like {@link #fromReflectionType(Object)}, but if the type is a repeated
* type, this converts a single element.
*/
- // @Override
+ @Override
protected Object singularFromReflectionType(final Object value) {
FieldDescriptor descriptor = getDescriptor();
switch (descriptor.getJavaType()) {
@@ -1726,7 +1728,7 @@ public abstract class GeneratedMessage extends AbstractMessage
* EnumValueDescriptors but the native accessors use the generated enum
* type.
*/
- // @Override
+ @Override
@SuppressWarnings("unchecked")
protected Object toReflectionType(final Object value) {
FieldDescriptor descriptor = getDescriptor();
@@ -1750,7 +1752,7 @@ public abstract class GeneratedMessage extends AbstractMessage
* Like {@link #toReflectionType(Object)}, but if the type is a repeated
* type, this converts a single element.
*/
- // @Override
+ @Override
protected Object singularToReflectionType(final Object value) {
FieldDescriptor descriptor = getDescriptor();
switch (descriptor.getJavaType()) {
@@ -1761,22 +1763,22 @@ public abstract class GeneratedMessage extends AbstractMessage
}
}
- // @Override
+ @Override
public int getNumber() {
return getDescriptor().getNumber();
}
- // @Override
+ @Override
public WireFormat.FieldType getLiteType() {
return getDescriptor().getLiteType();
}
- // @Override
+ @Override
public boolean isRepeated() {
return getDescriptor().isRepeated();
}
- // @Override
+ @Override
@SuppressWarnings("unchecked")
public Type getDefaultValue() {
if (isRepeated()) {
@@ -2126,49 +2128,57 @@ public abstract class GeneratedMessage extends AbstractMessage
return ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber();
}
+ @Override
public Object get(final GeneratedMessage message) {
return invokeOrDie(getMethod, message);
}
+ @Override
public Object get(GeneratedMessage.Builder builder) {
return invokeOrDie(getMethodBuilder, builder);
}
+ @Override
public Object getRaw(final GeneratedMessage message) {
return get(message);
}
+ @Override
public Object getRaw(GeneratedMessage.Builder builder) {
return get(builder);
}
+ @Override
public void set(final Builder builder, final Object 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(
"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(
"getRepeatedFieldRaw() called on a singular field.");
}
+ @Override
public Object getRepeated(GeneratedMessage.Builder builder, int index) {
throw new UnsupportedOperationException(
"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(
"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(
"setRepeatedField() called on a singular field.");
}
+ @Override
public void addRepeated(final Builder builder, final Object value) {
throw new UnsupportedOperationException(
"addRepeatedField() called on a singular field.");
}
+ @Override
public boolean has(final GeneratedMessage message) {
if (!hasHasMethod) {
if (isOneofField) {
@@ -2178,6 +2188,7 @@ public abstract class GeneratedMessage extends AbstractMessage
}
return (Boolean) invokeOrDie(hasMethod, message);
}
+ @Override
public boolean has(GeneratedMessage.Builder builder) {
if (!hasHasMethod) {
if (isOneofField) {
@@ -2187,27 +2198,32 @@ public abstract class GeneratedMessage extends AbstractMessage
}
return (Boolean) invokeOrDie(hasMethodBuilder, builder);
}
+ @Override
public int getRepeatedCount(final GeneratedMessage message) {
throw new UnsupportedOperationException(
"getRepeatedFieldSize() called on a singular field.");
}
+ @Override
public int getRepeatedCount(GeneratedMessage.Builder builder) {
throw new UnsupportedOperationException(
"getRepeatedFieldSize() called on a singular field.");
}
+ @Override
public void clear(final Builder builder) {
invokeOrDie(clearMethod, builder);
}
+ @Override
public Message.Builder newBuilder() {
throw new UnsupportedOperationException(
"newBuilderForField() called on a non-Message type.");
}
+ @Override
public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
throw new UnsupportedOperationException(
"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(
"getRepeatedFieldBuilder() called on a non-Message type.");
}
@@ -2251,18 +2267,23 @@ public abstract class GeneratedMessage extends AbstractMessage
clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
}
+ @Override
public Object get(final GeneratedMessage message) {
return invokeOrDie(getMethod, message);
}
+ @Override
public Object get(GeneratedMessage.Builder builder) {
return invokeOrDie(getMethodBuilder, builder);
}
+ @Override
public Object getRaw(final GeneratedMessage message) {
return get(message);
}
+ @Override
public Object getRaw(GeneratedMessage.Builder builder) {
return get(builder);
}
+ @Override
public void set(final Builder builder, final Object value) {
// Add all the elements individually. This serves two purposes:
// 1) Verifies that each element has the correct type.
@@ -2273,54 +2294,64 @@ public abstract class GeneratedMessage extends AbstractMessage
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);
}
+ @Override
public Object getRepeated(GeneratedMessage.Builder builder, int index) {
return invokeOrDie(getRepeatedMethodBuilder, builder, index);
}
+ @Override
public Object getRepeatedRaw(GeneratedMessage message, int 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);
}
- 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);
}
+ @Override
public void addRepeated(final Builder builder, final Object value) {
invokeOrDie(addRepeatedMethod, builder, value);
}
+ @Override
public boolean has(final GeneratedMessage message) {
throw new UnsupportedOperationException(
"hasField() called on a repeated field.");
}
+ @Override
public boolean has(GeneratedMessage.Builder builder) {
throw new UnsupportedOperationException(
"hasField() called on a repeated field.");
}
+ @Override
public int getRepeatedCount(final GeneratedMessage message) {
return (Integer) invokeOrDie(getCountMethod, message);
}
+ @Override
public int getRepeatedCount(GeneratedMessage.Builder builder) {
return (Integer) invokeOrDie(getCountMethodBuilder, builder);
}
+ @Override
public void clear(final Builder builder) {
invokeOrDie(clearMethod, builder);
}
+ @Override
public Message.Builder newBuilder() {
throw new UnsupportedOperationException(
"newBuilderForField() called on a non-Message type.");
}
+ @Override
public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
throw new UnsupportedOperationException(
"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(
"getRepeatedFieldBuilder() called on a non-Message type.");
}
@@ -2357,6 +2388,7 @@ public abstract class GeneratedMessage extends AbstractMessage
field.getNumber());
}
+ @Override
public Object get(GeneratedMessage message) {
List result = new ArrayList();
for (int i = 0; i < getRepeatedCount(message); i++) {
@@ -2365,6 +2397,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return Collections.unmodifiableList(result);
}
+ @Override
public Object get(Builder builder) {
List result = new ArrayList();
for (int i = 0; i < getRepeatedCount(builder); i++) {
@@ -2373,14 +2406,17 @@ public abstract class GeneratedMessage extends AbstractMessage
return Collections.unmodifiableList(result);
}
+ @Override
public Object getRaw(GeneratedMessage message) {
return get(message);
}
+ @Override
public Object getRaw(GeneratedMessage.Builder builder) {
return get(builder);
}
+ @Override
public void set(Builder builder, Object value) {
clear(builder);
for (Object entry : (List) value) {
@@ -2388,63 +2424,76 @@ public abstract class GeneratedMessage extends AbstractMessage
}
}
+ @Override
public Object getRepeated(GeneratedMessage message, int index) {
return getMapField(message).getList().get(index);
}
+ @Override
public Object getRepeated(Builder builder, int index) {
return getMapField(builder).getList().get(index);
}
+ @Override
public Object getRepeatedRaw(GeneratedMessage message, int index) {
return getRepeated(message, index);
}
+ @Override
public Object getRepeatedRaw(Builder builder, int index) {
return getRepeated(builder, index);
}
+ @Override
public void setRepeated(Builder builder, int index, Object value) {
getMutableMapField(builder).getMutableList().set(index, (Message) value);
}
+ @Override
public void addRepeated(Builder builder, Object value) {
getMutableMapField(builder).getMutableList().add((Message) value);
}
+ @Override
public boolean has(GeneratedMessage message) {
throw new UnsupportedOperationException(
"hasField() is not supported for repeated fields.");
}
+ @Override
public boolean has(Builder builder) {
throw new UnsupportedOperationException(
"hasField() is not supported for repeated fields.");
}
+ @Override
public int getRepeatedCount(GeneratedMessage message) {
return getMapField(message).getList().size();
}
+ @Override
public int getRepeatedCount(Builder builder) {
return getMapField(builder).getList().size();
}
+ @Override
public void clear(Builder builder) {
getMutableMapField(builder).getMutableList().clear();
}
+ @Override
public com.google.protobuf.Message.Builder newBuilder() {
return mapEntryMessageDefaultInstance.newBuilderForType();
}
+ @Override
public com.google.protobuf.Message.Builder getBuilder(Builder builder) {
throw new UnsupportedOperationException(
"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(
"Nested builder not supported for map fields.");
}
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
index 12a1472d..c5adc5ad 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -31,6 +31,7 @@
package com.google.protobuf;
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.DoubleList;
import com.google.protobuf.Internal.FloatList;
@@ -59,24 +60,27 @@ import java.util.Map;
public abstract class GeneratedMessageLite<
MessageType extends GeneratedMessageLite<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. */
- protected UnknownFieldSetLite unknownFields = null;
+ protected UnknownFieldSetLite unknownFields = UnknownFieldSetLite.getDefaultInstance();
/** For use by generated code only. */
protected int memoizedSerializedSize = -1;
+ @Override
@SuppressWarnings("unchecked") // Guaranteed by runtime.
public final Parser<MessageType> getParserForType() {
return (Parser<MessageType>) dynamicMethod(MethodToInvoke.GET_PARSER);
}
+ @Override
@SuppressWarnings("unchecked") // Guaranteed by runtime.
public final MessageType getDefaultInstanceForType() {
return (MessageType) dynamicMethod(MethodToInvoke.GET_DEFAULT_INSTANCE);
}
+ @Override
@SuppressWarnings("unchecked") // Guaranteed by runtime.
public final BuilderType newBuilderForType() {
return (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER);
@@ -99,7 +103,65 @@ public abstract class GeneratedMessageLite<
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
// mutable during the parsing constructor and immutable after. This allows us to avoid
// any unnecessary intermediary allocations while reducing the generated code size.
@@ -108,7 +170,7 @@ public abstract class GeneratedMessageLite<
* Lazily initializes unknown fields.
*/
private final void ensureUnknownFieldsInitialized() {
- if (unknownFields == null) {
+ if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
unknownFields = UnknownFieldSetLite.newInstance();
}
}
@@ -147,18 +209,18 @@ public abstract class GeneratedMessageLite<
/**
* 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() {
return dynamicMethod(MethodToInvoke.IS_INITIALIZED, Boolean.TRUE) != null;
}
+ @Override
public final BuilderType toBuilder() {
BuilderType builder = (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER);
builder.mergeFrom((MessageType) this);
@@ -172,11 +234,14 @@ public abstract class GeneratedMessageLite<
* For use by generated code only.
*/
public static enum MethodToInvoke {
+ // Rely on/modify instance state
IS_INITIALIZED,
- PARSE_PARTIAL_FROM,
- MERGE_FROM,
+ VISIT,
+ MERGE_FROM_STREAM,
MAKE_IMMUTABLE,
- NEW_INSTANCE,
+
+ // Rely on static state
+ NEW_MUTABLE_INSTANCE,
NEW_BUILDER,
GET_DEFAULT_INSTANCE,
GET_PARSER;
@@ -188,17 +253,18 @@ public abstract class GeneratedMessageLite<
* builders in the runtime. This method bundles those operations to reduce the generated methods
* count.
* <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
* 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
* 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.
* <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.
* </ul>
* 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);
}
+ 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
* message.
@@ -236,7 +307,7 @@ public abstract class GeneratedMessageLite<
public abstract static class Builder<
MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
BuilderType extends Builder<MessageType, BuilderType>>
- extends AbstractMessageLite.Builder<BuilderType> {
+ extends AbstractMessageLite.Builder<MessageType, BuilderType> {
private final MessageType defaultInstance;
protected MessageType instance;
@@ -244,7 +315,8 @@ public abstract class GeneratedMessageLite<
protected Builder(MessageType defaultInstance) {
this.defaultInstance = defaultInstance;
- this.instance = (MessageType) defaultInstance.dynamicMethod(MethodToInvoke.NEW_INSTANCE);
+ this.instance =
+ (MessageType) defaultInstance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
isBuilt = false;
}
@@ -254,26 +326,27 @@ public abstract class GeneratedMessageLite<
*/
protected void copyOnWrite() {
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;
isBuilt = false;
}
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final boolean isInitialized() {
return GeneratedMessageLite.isInitialized(instance, false /* shouldMemoize */);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final BuilderType clear() {
// 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;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public BuilderType clone() {
BuilderType builder =
(BuilderType) getDefaultInstanceForType().newBuilderForType();
@@ -281,20 +354,19 @@ public abstract class GeneratedMessageLite<
return builder;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public MessageType buildPartial() {
if (isBuilt) {
return instance;
}
- instance.dynamicMethod(MethodToInvoke.MAKE_IMMUTABLE);
- instance.unknownFields.makeImmutable();
+ instance.makeImmutable();
isBuilt = true;
return instance;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final MessageType build() {
MessageType result = buildPartial();
if (!result.isInitialized()) {
@@ -303,32 +375,36 @@ public abstract class GeneratedMessageLite<
return result;
}
+ @Override
+ protected BuilderType internalMergeFrom(MessageType message) {
+ return mergeFrom(message);
+ }
+
/** All subclasses implement this. */
public BuilderType mergeFrom(MessageType message) {
copyOnWrite();
- instance.dynamicMethod(MethodToInvoke.MERGE_FROM, message);
+ instance.visit(MergeFromVisitor.INSTANCE, message);
return (BuilderType) this;
}
+ @Override
public MessageType getDefaultInstanceForType() {
return defaultInstance;
}
+ @Override
public BuilderType mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws java.io.IOException {
- MessageType parsedMessage = null;
+ throws IOException {
+ copyOnWrite();
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;
}
@@ -384,6 +460,12 @@ public abstract class GeneratedMessageLite<
}
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.
@@ -521,9 +603,8 @@ public abstract class GeneratedMessageLite<
}
/** 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 =
checkIsLite(extension);
@@ -532,7 +613,7 @@ public abstract class GeneratedMessageLite<
}
/** 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(
final ExtensionLite<MessageType, List<Type>> extension) {
GeneratedExtension<MessageType, List<Type>> extensionLite =
@@ -543,10 +624,9 @@ public abstract class GeneratedMessageLite<
}
/** Get the value of an extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
@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 =
checkIsLite(extension);
@@ -560,11 +640,10 @@ public abstract class GeneratedMessageLite<
}
/** Get one element of a repeated extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
@SuppressWarnings("unchecked")
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 =
checkIsLite(extension);
@@ -579,8 +658,8 @@ public abstract class GeneratedMessageLite<
}
@Override
- protected final void doneParsing() {
- super.doneParsing();
+ protected final void makeImmutable() {
+ super.makeImmutable();
extensions.makeImmutable();
}
@@ -669,7 +748,7 @@ public abstract class GeneratedMessageLite<
instance.extensions = extensions;
}
- // @Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
protected void copyOnWrite() {
if (!isBuilt) {
return;
@@ -679,7 +758,7 @@ public abstract class GeneratedMessageLite<
instance.extensions = instance.extensions.clone();
}
- // @Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final MessageType buildPartial() {
if (isBuilt) {
return instance;
@@ -701,33 +780,30 @@ public abstract class GeneratedMessageLite<
}
/** 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);
}
/** 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(
final ExtensionLite<MessageType, List<Type>> extension) {
return instance.getExtensionCount(extension);
}
/** Get the value of an extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
@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);
}
/** Get one element of a repeated extension. */
+ @Override
@SuppressWarnings("unchecked")
- //@Override (Java 1.6 override semantics, but we must support 1.5)
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);
}
@@ -859,37 +935,44 @@ public abstract class GeneratedMessageLite<
final boolean isRepeated;
final boolean isPacked;
+ @Override
public int getNumber() {
return number;
}
+ @Override
public WireFormat.FieldType getLiteType() {
return type;
}
+ @Override
public WireFormat.JavaType getLiteJavaType() {
return type.getJavaType();
}
+ @Override
public boolean isRepeated() {
return isRepeated;
}
+ @Override
public boolean isPacked() {
return isPacked;
}
+ @Override
public Internal.EnumLiteMap<?> getEnumType() {
return enumTypeMap;
}
+ @Override
@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);
}
+ @Override
public int compareTo(ExtensionDescriptor other) {
return number - other.number;
}
@@ -984,6 +1067,7 @@ public abstract class GeneratedMessageLite<
}
/** Get the field number. */
+ @Override
public int getNumber() {
return descriptor.getNumber();
}
@@ -993,6 +1077,7 @@ public abstract class GeneratedMessageLite<
* If the extension is an embedded message or group, returns the default
* instance of the message.
*/
+ @Override
public MessageLite getMessageDefaultInstance() {
return messageDefaultInstance;
}
@@ -1047,14 +1132,17 @@ public abstract class GeneratedMessageLite<
}
}
+ @Override
public FieldType getLiteType() {
return descriptor.getLiteType();
}
+ @Override
public boolean isRepeated() {
return descriptor.isRepeated;
}
+ @Override
public Type getDefaultValue() {
return defaultValue;
}
@@ -1139,112 +1227,72 @@ public abstract class GeneratedMessageLite<
protected static final <T extends GeneratedMessageLite<T, ?>> boolean isInitialized(
T message, boolean shouldMemoize) {
return message.dynamicMethod(MethodToInvoke.IS_INITIALIZED, shouldMemoize) != null;
- }
+ }
protected static final <T extends GeneratedMessageLite<T, ?>> void makeImmutable(T message) {
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() {
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() {
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() {
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() {
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() {
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() {
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.
* <p>
@@ -1274,10 +1322,11 @@ public abstract class GeneratedMessageLite<
static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
T instance, CodedInputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
- T result;
+ @SuppressWarnings("unchecked") // Guaranteed by protoc
+ T result = (T) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
try {
- result = (T) instance.dynamicMethod(
- MethodToInvoke.PARSE_PARTIAL_FROM, input, extensionRegistry);
+ result.dynamicMethod(MethodToInvoke.MERGE_FROM_STREAM, input, extensionRegistry);
+ result.makeImmutable();
} catch (RuntimeException e) {
if (e.getCause() instanceof InvalidProtocolBufferException) {
throw (InvalidProtocolBufferException) e.getCause();
@@ -1454,4 +1503,740 @@ public abstract class GeneratedMessageLite<
}
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;
+ }
+ }
}
diff --git a/java/core/src/main/java/com/google/protobuf/IntArrayList.java b/java/core/src/main/java/com/google/protobuf/IntArrayList.java
index f4e68ed8..6d6ece5a 100644
--- a/java/core/src/main/java/com/google/protobuf/IntArrayList.java
+++ b/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.Collection;
-import java.util.List;
import java.util.RandomAccess;
/**
@@ -44,8 +43,6 @@ import java.util.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();
static {
EMPTY_LIST.makeImmutable();
@@ -70,32 +67,55 @@ final class IntArrayList extends AbstractProtobufList<Integer> implements IntLis
* Constructs a new mutable {@code IntArrayList} with default capacity.
*/
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}.
*/
- 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
diff --git a/java/core/src/main/java/com/google/protobuf/Internal.java b/java/core/src/main/java/com/google/protobuf/Internal.java
index abf7ddd6..d1de375e 100644
--- a/java/core/src/main/java/com/google/protobuf/Internal.java
+++ b/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.List;
import java.util.Map;
+import java.util.RandomAccess;
import java.util.Set;
/**
@@ -457,10 +458,13 @@ public final class Internal {
public static <T extends EnumLite> Converter<Integer, T> newEnumConverter(
final EnumLiteMap<T> enumMap, final T unrecognizedValue) {
return new Converter<Integer, T>() {
+ @Override
public T doForward(Integer value) {
T result = enumMap.findValueByNumber(value);
return result == null ? unrecognizedValue : result;
}
+
+ @Override
public Integer doBackward(T value) {
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
* 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
@@ -586,6 +592,11 @@ public final class Internal {
* Returns whether this list can be modified via the publicly accessible {@link List} methods.
*/
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);
/**
- * 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);
/**
- * 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);
+
+ /**
+ * 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);
/**
- * 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);
/**
- * 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);
+
+ /**
+ * 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);
/**
- * 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);
/**
- * 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);
+
+ /**
+ * 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);
/**
- * 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);
/**
- * 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);
+
+ /**
+ * 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);
/**
- * 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);
/**
- * 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);
+
+ /**
+ * Returns a mutable clone of this list with the specified capacity.
+ */
+ @Override
+ FloatList mutableCopyWithCapacity(int capacity);
}
}
diff --git a/java/core/src/main/java/com/google/protobuf/LazyField.java b/java/core/src/main/java/com/google/protobuf/LazyField.java
index 3da8b900..98e13ca1 100644
--- a/java/core/src/main/java/com/google/protobuf/LazyField.java
+++ b/java/core/src/main/java/com/google/protobuf/LazyField.java
@@ -95,12 +95,12 @@ public class LazyField extends LazyFieldLite {
this.entry = entry;
}
- // @Override
+ @Override
public K getKey() {
return entry.getKey();
}
- // @Override
+ @Override
public Object getValue() {
LazyField field = entry.getValue();
if (field == null) {
@@ -113,7 +113,7 @@ public class LazyField extends LazyFieldLite {
return entry.getValue();
}
- // @Override
+ @Override
public Object setValue(Object value) {
if (!(value instanceof MessageLite)) {
throw new IllegalArgumentException(
@@ -131,13 +131,13 @@ public class LazyField extends LazyFieldLite {
this.iterator = iterator;
}
- // @Override
+ @Override
public boolean hasNext() {
return iterator.hasNext();
}
+ @Override
@SuppressWarnings("unchecked")
- // @Override
public Entry<K, Object> next() {
Entry<K, ?> entry = iterator.next();
if (entry.getValue() instanceof LazyField) {
@@ -146,7 +146,7 @@ public class LazyField extends LazyFieldLite {
return (Entry<K, Object>) entry;
}
- // @Override
+ @Override
public void remove() {
iterator.remove();
}
diff --git a/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java b/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java
index 016ec20d..2febaace 100644
--- a/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java
+++ b/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java
@@ -135,6 +135,43 @@ public class LazyFieldLite {
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.
*/
@@ -340,6 +377,8 @@ public class LazyFieldLite {
* parsed. Be careful when using this method.
*/
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) {
return memoizedBytes.size();
} else if (delayedBytes != null) {
@@ -358,6 +397,8 @@ public class LazyFieldLite {
if (memoizedBytes != null) {
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) {
return delayedBytes;
}
diff --git a/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java b/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java
index 68c430cf..d474c51e 100644
--- a/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java
@@ -64,7 +64,7 @@ import java.util.RandomAccess;
*/
public class LazyStringArrayList extends AbstractProtobufList<String>
implements LazyStringList, RandomAccess {
-
+
private static final LazyStringArrayList EMPTY_LIST = new LazyStringArrayList();
static {
EMPTY_LIST.makeImmutable();
@@ -80,11 +80,11 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
private final List<Object> list;
public LazyStringArrayList() {
- list = new ArrayList<Object>();
+ this(DEFAULT_CAPACITY);
}
public LazyStringArrayList(int intialCapacity) {
- list = new ArrayList<Object>(intialCapacity);
+ this(new ArrayList<Object>(intialCapacity));
}
public LazyStringArrayList(LazyStringList from) {
@@ -93,7 +93,21 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
}
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
@@ -170,7 +184,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
return ret;
}
- // @Override
+ @Override
public boolean addAllByteString(Collection<? extends ByteString> values) {
ensureIsMutable();
boolean ret = list.addAll(values);
@@ -178,7 +192,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
return ret;
}
- // @Override
+ @Override
public boolean addAllByteArray(Collection<byte[]> c) {
ensureIsMutable();
boolean ret = list.addAll(c);
@@ -201,14 +215,14 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
modCount++;
}
- // @Override
+ @Override
public void add(ByteString element) {
ensureIsMutable();
list.add(element);
modCount++;
}
- // @Override
+ @Override
public void add(byte[] element) {
ensureIsMutable();
list.add(element);
@@ -220,7 +234,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
return list.get(index);
}
- // @Override
+ @Override
public ByteString getByteString(int index) {
Object o = list.get(index);
ByteString b = asByteString(o);
@@ -230,7 +244,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
return b;
}
- // @Override
+ @Override
public byte[] getByteArray(int index) {
Object o = list.get(index);
byte[] b = asByteArray(o);
@@ -240,7 +254,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
return b;
}
- // @Override
+ @Override
public void set(int index, ByteString s) {
setAndReturn(index, s);
}
@@ -250,7 +264,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
return list.set(index, s);
}
- // @Override
+ @Override
public void set(int index, byte[] s) {
setAndReturn(index, s);
}
@@ -290,12 +304,12 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
}
}
- // @Override
+ @Override
public List<?> getUnderlyingElements() {
return Collections.unmodifiableList(list);
}
- // @Override
+ @Override
public void mergeFrom(LazyStringList other) {
ensureIsMutable();
for (Object o : other.getUnderlyingElements()) {
@@ -349,7 +363,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
}
}
- // @Override
+ @Override
public List<byte[]> asByteArrayList() {
return new ByteArrayListView(this);
}
@@ -393,12 +407,12 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
}
}
- // @Override
+ @Override
public List<ByteString> asByteStringList() {
return new ByteStringListView(this);
}
- // @Override
+ @Override
public LazyStringList getUnmodifiableView() {
if (isModifiable()) {
return new UnmodifiableLazyStringList(this);
diff --git a/java/core/src/main/java/com/google/protobuf/LongArrayList.java b/java/core/src/main/java/com/google/protobuf/LongArrayList.java
index ebe62029..bc4475d1 100644
--- a/java/core/src/main/java/com/google/protobuf/LongArrayList.java
+++ b/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.Collection;
-import java.util.List;
import java.util.RandomAccess;
/**
@@ -44,8 +43,6 @@ import java.util.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();
static {
EMPTY_LIST.makeImmutable();
@@ -70,32 +67,55 @@ final class LongArrayList extends AbstractProtobufList<Long> implements LongList
* Constructs a new mutable {@code LongArrayList} with default capacity.
*/
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}.
*/
- 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
diff --git a/java/core/src/main/java/com/google/protobuf/MapEntryLite.java b/java/core/src/main/java/com/google/protobuf/MapEntryLite.java
index bcffa946..12c64abb 100644
--- a/java/core/src/main/java/com/google/protobuf/MapEntryLite.java
+++ b/java/core/src/main/java/com/google/protobuf/MapEntryLite.java
@@ -41,7 +41,8 @@ import java.io.IOException;
*
* 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> {
public final MapEntryLite<K, V> defaultInstance;
public final WireFormat.FieldType keyType;
@@ -233,7 +234,7 @@ public class MapEntryLite<K, V> extends AbstractMessageLite {
* Builder used to create {@link MapEntryLite} messages.
*/
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 K key;
private V value;
@@ -327,5 +328,10 @@ public class MapEntryLite<K, V> extends AbstractMessageLite {
this.value = entry.value;
return this;
}
+
+ @Override
+ protected Builder<K, V> internalMergeFrom(MapEntryLite<K, V> message) {
+ throw new UnsupportedOperationException();
+ }
}
}
diff --git a/java/core/src/main/java/com/google/protobuf/MapField.java b/java/core/src/main/java/com/google/protobuf/MapField.java
index b290993c..907f0f71 100644
--- a/java/core/src/main/java/com/google/protobuf/MapField.java
+++ b/java/core/src/main/java/com/google/protobuf/MapField.java
@@ -93,15 +93,18 @@ public class MapField<K, V> implements MutabilityOracle {
this.defaultEntry = defaultEntry;
}
+ @Override
public Message convertKeyAndValueToMessage(K key, V value) {
return defaultEntry.newBuilderForType().setKey(key).setValue(value).buildPartial();
}
+ @Override
public void convertMessageToKeyAndValue(Message message, Map<K, V> map) {
MapEntry<K, V> entry = (MapEntry<K, V>) message;
map.put(entry.getKey(), entry.getValue());
}
+ @Override
public Message getMessageDefaultInstance() {
return defaultEntry;
}
diff --git a/java/core/src/main/java/com/google/protobuf/Message.java b/java/core/src/main/java/com/google/protobuf/Message.java
index 9516d71f..94590fb9 100644
--- a/java/core/src/main/java/com/google/protobuf/Message.java
+++ b/java/core/src/main/java/com/google/protobuf/Message.java
@@ -51,6 +51,7 @@ import java.util.Map;
public interface Message extends MessageLite, MessageOrBuilder {
// (From MessageLite, re-declared here only for return type covariance.)
+ @Override
Parser<? extends Message> getParserForType();
@@ -97,7 +98,10 @@ public interface Message extends MessageLite, MessageOrBuilder {
// Builders
// (From MessageLite, re-declared here only for return type covariance.)
+ @Override
Builder newBuilderForType();
+
+ @Override
Builder toBuilder();
/**
@@ -106,6 +110,7 @@ public interface Message extends MessageLite, MessageOrBuilder {
interface Builder extends MessageLite.Builder, MessageOrBuilder {
// (From MessageLite.Builder, re-declared here only for return type
// covariance.)
+ @Override
Builder clear();
/**
@@ -131,18 +136,27 @@ public interface Message extends MessageLite, MessageOrBuilder {
// (From MessageLite.Builder, re-declared here only for return type
// covariance.)
+ @Override
Message build();
+
+ @Override
Message buildPartial();
+
+ @Override
Builder clone();
+
+ @Override
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.
* See {@link Message#getDescriptorForType()}.
*/
+ @Override
Descriptors.Descriptor getDescriptorForType();
/**
@@ -240,27 +254,39 @@ public interface Message extends MessageLite, MessageOrBuilder {
// (From MessageLite.Builder, re-declared here only for return type
// covariance.)
+ @Override
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, 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,
- 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;
}
}
diff --git a/java/core/src/main/java/com/google/protobuf/MessageLite.java b/java/core/src/main/java/com/google/protobuf/MessageLite.java
index 798b7943..88f531df 100644
--- a/java/core/src/main/java/com/google/protobuf/MessageLite.java
+++ b/java/core/src/main/java/com/google/protobuf/MessageLite.java
@@ -295,6 +295,27 @@ public interface MessageLite extends MessageLiteOrBuilder {
Builder mergeFrom(InputStream input,
ExtensionRegistryLite extensionRegistry)
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.
diff --git a/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java b/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java
index 2a6e0e30..43847651 100644
--- a/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java
+++ b/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java
@@ -30,23 +30,24 @@
package com.google.protobuf;
-import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
/**
* Helps generate {@link String} representations of {@link MessageLite} protos.
*/
+// TODO(dweis): Fix map fields.
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
* 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
// getFooList() which might be useful for building an object's string representation.
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()) {
+ nameToMethod.put(method.getName(), method);
if (method.getParameterTypes().length == 0) {
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
// 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(
buffer,
indent,
- upperUnderscore.toLowerCase(),
- GeneratedMessageLite.invokeOrDie(getMethod, messageLite));
+ camelCaseToSnakeCase(camelCase),
+ value);
}
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) {
@@ -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.
@@ -166,7 +214,7 @@ final class MessageLiteToString {
buffer.append(": \"").append(TextFormatEscaper.escapeBytes((ByteString) object)).append('"');
} else if (object instanceof GeneratedMessageLite) {
buffer.append(" {");
- reflectivePrintWithIndent((GeneratedMessageLite) object, buffer, indent + 2);
+ reflectivePrintWithIndent((GeneratedMessageLite<?, ?>) object, buffer, indent + 2);
buffer.append("\n");
for (int i = 0; i < indent; i++) {
buffer.append(' ');
@@ -176,25 +224,16 @@ final class MessageLiteToString {
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();
}
}
diff --git a/java/core/src/main/java/com/google/protobuf/MessageOrBuilder.java b/java/core/src/main/java/com/google/protobuf/MessageOrBuilder.java
index f0fc4859..5e7d7821 100644
--- a/java/core/src/main/java/com/google/protobuf/MessageOrBuilder.java
+++ b/java/core/src/main/java/com/google/protobuf/MessageOrBuilder.java
@@ -42,7 +42,7 @@ import java.util.Map;
public interface MessageOrBuilder extends MessageLiteOrBuilder {
// (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();
/**
diff --git a/java/core/src/main/java/com/google/protobuf/MessageReflection.java b/java/core/src/main/java/com/google/protobuf/MessageReflection.java
index de4bfd3e..7b791d9e 100644
--- a/java/core/src/main/java/com/google/protobuf/MessageReflection.java
+++ b/java/core/src/main/java/com/google/protobuf/MessageReflection.java
@@ -364,12 +364,14 @@ class MessageReflection {
* Finishes the merge and returns the underlying object.
*/
Object finish();
+
}
static class BuilderAdapter implements MergeTarget {
private final Message.Builder builder;
+ @Override
public Descriptors.Descriptor getDescriptorForType() {
return builder.getDescriptorForType();
}
@@ -378,6 +380,7 @@ class MessageReflection {
this.builder = builder;
}
+ @Override
public Object getField(Descriptors.FieldDescriptor field) {
return builder.getField(field);
}
@@ -387,25 +390,27 @@ class MessageReflection {
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);
return this;
}
+ @Override
public MergeTarget clearField(Descriptors.FieldDescriptor field) {
builder.clearField(field);
return this;
}
+ @Override
public MergeTarget setRepeatedField(
Descriptors.FieldDescriptor field, int index, Object value) {
builder.setRepeatedField(field, index, value);
return this;
}
- public MergeTarget addRepeatedField(
- Descriptors.FieldDescriptor field, Object value) {
+ @Override
+ public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
builder.addRepeatedField(field, value);
return this;
}
@@ -426,25 +431,30 @@ class MessageReflection {
return builder.getOneofFieldDescriptor(oneof);
}
+ @Override
public ContainerType getContainerType() {
return ContainerType.MESSAGE;
}
+ @Override
public ExtensionRegistry.ExtensionInfo findExtensionByName(
ExtensionRegistry registry, String name) {
return registry.findImmutableExtensionByName(name);
}
+ @Override
public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
- ExtensionRegistry registry, Descriptors.Descriptor containingType,
- int fieldNumber) {
+ ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
return registry.findImmutableExtensionByNumber(containingType,
fieldNumber);
}
- public Object parseGroup(CodedInputStream input,
+ @Override
+ public Object parseGroup(
+ CodedInputStream input,
ExtensionRegistryLite extensionRegistry,
- Descriptors.FieldDescriptor field, Message defaultInstance)
+ Descriptors.FieldDescriptor field,
+ Message defaultInstance)
throws IOException {
Message.Builder subBuilder;
// When default instance is not null. The field is an extension field.
@@ -463,9 +473,12 @@ class MessageReflection {
return subBuilder.buildPartial();
}
- public Object parseMessage(CodedInputStream input,
+ @Override
+ public Object parseMessage(
+ CodedInputStream input,
ExtensionRegistryLite extensionRegistry,
- Descriptors.FieldDescriptor field, Message defaultInstance)
+ Descriptors.FieldDescriptor field,
+ Message defaultInstance)
throws IOException {
Message.Builder subBuilder;
// When default instance is not null. The field is an extension field.
@@ -484,9 +497,12 @@ class MessageReflection {
return subBuilder.buildPartial();
}
- public Object parseMessageFromBytes(ByteString bytes,
+ @Override
+ public Object parseMessageFromBytes(
+ ByteString bytes,
ExtensionRegistryLite extensionRegistry,
- Descriptors.FieldDescriptor field, Message defaultInstance)
+ Descriptors.FieldDescriptor field,
+ Message defaultInstance)
throws IOException {
Message.Builder subBuilder;
// When default instance is not null. The field is an extension field.
@@ -505,8 +521,9 @@ class MessageReflection {
return subBuilder.buildPartial();
}
- public MergeTarget newMergeTargetForField(Descriptors.FieldDescriptor field,
- Message defaultInstance) {
+ @Override
+ public MergeTarget newMergeTargetForField(
+ Descriptors.FieldDescriptor field, Message defaultInstance) {
if (defaultInstance != null) {
return new BuilderAdapter(
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()) {
return WireFormat.Utf8Validation.STRICT;
}
@@ -528,9 +545,11 @@ class MessageReflection {
return WireFormat.Utf8Validation.LOOSE;
}
+ @Override
public Object finish() {
return builder.buildPartial();
}
+
}
@@ -542,38 +561,43 @@ class MessageReflection {
this.extensions = extensions;
}
+ @Override
public Descriptors.Descriptor getDescriptorForType() {
throw new UnsupportedOperationException(
"getDescriptorForType() called on FieldSet object");
}
+ @Override
public Object getField(Descriptors.FieldDescriptor field) {
return extensions.getField(field);
}
+ @Override
public boolean hasField(Descriptors.FieldDescriptor field) {
return extensions.hasField(field);
}
- public MergeTarget setField(Descriptors.FieldDescriptor field,
- Object value) {
+ @Override
+ public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
extensions.setField(field, value);
return this;
}
+ @Override
public MergeTarget clearField(Descriptors.FieldDescriptor field) {
extensions.clearField(field);
return this;
}
+ @Override
public MergeTarget setRepeatedField(
Descriptors.FieldDescriptor field, int index, Object value) {
extensions.setRepeatedField(field, index, value);
return this;
}
- public MergeTarget addRepeatedField(
- Descriptors.FieldDescriptor field, Object value) {
+ @Override
+ public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
extensions.addRepeatedField(field, value);
return this;
}
@@ -594,25 +618,31 @@ class MessageReflection {
return null;
}
+ @Override
public ContainerType getContainerType() {
return ContainerType.EXTENSION_SET;
}
+ @Override
public ExtensionRegistry.ExtensionInfo findExtensionByName(
ExtensionRegistry registry, String name) {
return registry.findImmutableExtensionByName(name);
}
+ @Override
public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
- ExtensionRegistry registry, Descriptors.Descriptor containingType,
- int fieldNumber) {
+ ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
return registry.findImmutableExtensionByNumber(containingType,
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 =
defaultInstance.newBuilderForType();
if (!field.isRepeated()) {
@@ -625,9 +655,13 @@ class MessageReflection {
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 =
defaultInstance.newBuilderForType();
if (!field.isRepeated()) {
@@ -640,9 +674,13 @@ class MessageReflection {
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();
if (!field.isRepeated()) {
Message originalMessage = (Message) getField(field);
@@ -654,14 +692,15 @@ class MessageReflection {
return subBuilder.buildPartial();
}
+ @Override
public MergeTarget newMergeTargetForField(
Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
throw new UnsupportedOperationException(
"newMergeTargetForField() called on FieldSet object");
}
- public WireFormat.Utf8Validation
- getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
+ @Override
+ public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
if (descriptor.needsUtf8Check()) {
return WireFormat.Utf8Validation.STRICT;
}
@@ -669,10 +708,12 @@ class MessageReflection {
return WireFormat.Utf8Validation.LOOSE;
}
+ @Override
public Object finish() {
throw new UnsupportedOperationException(
"finish() called on FieldSet object");
}
+
}
/**
diff --git a/java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java b/java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java
index d2f82ac5..81255ec2 100644
--- a/java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java
+++ b/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.
*/
-class ProtobufArrayList<E> extends AbstractProtobufList<E> {
+final class ProtobufArrayList<E> extends AbstractProtobufList<E> {
private static final ProtobufArrayList<Object> EMPTY_LIST = new ProtobufArrayList<Object>();
static {
@@ -51,17 +51,23 @@ class ProtobufArrayList<E> extends AbstractProtobufList<E> {
}
private final List<E> list;
-
+
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
diff --git a/java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java b/java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java
index 0c8df989..a596d301 100644
--- a/java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java
+++ b/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.
*/
+ @Override
int getNumber();
/**
diff --git a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
index f91cdbce..29f567dc 100644
--- a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
+++ b/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() {
onChanged();
}
@@ -621,10 +621,12 @@ public class RepeatedFieldBuilder
this.builder = builder;
}
+ @Override
public int size() {
return this.builder.getCount();
}
+ @Override
public MType get(int index) {
return builder.getMessage(index);
}
@@ -654,10 +656,12 @@ public class RepeatedFieldBuilder
this.builder = builder;
}
+ @Override
public int size() {
return this.builder.getCount();
}
+ @Override
public BType get(int index) {
return builder.getBuilder(index);
}
@@ -687,10 +691,12 @@ public class RepeatedFieldBuilder
this.builder = builder;
}
+ @Override
public int size() {
return this.builder.getCount();
}
+ @Override
public IType get(int index) {
return builder.getMessageOrBuilder(index);
}
diff --git a/java/core/src/main/java/com/google/protobuf/RpcUtil.java b/java/core/src/main/java/com/google/protobuf/RpcUtil.java
index 694b8d13..f7d555ae 100644
--- a/java/core/src/main/java/com/google/protobuf/RpcUtil.java
+++ b/java/core/src/main/java/com/google/protobuf/RpcUtil.java
@@ -71,6 +71,7 @@ public final class RpcUtil {
final Class<Type> originalClass,
final Type defaultInstance) {
return new RpcCallback<Message>() {
+ @Override
public void run(final Message parameter) {
Type typedParameter;
try {
@@ -107,8 +108,9 @@ public final class RpcUtil {
return new RpcCallback<ParameterType>() {
private boolean alreadyCalled = false;
+ @Override
public void run(final ParameterType parameter) {
- synchronized(this) {
+ synchronized (this) {
if (alreadyCalled) {
throw new AlreadyCalledException();
}
diff --git a/java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java b/java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java
index aba65e32..941b5def 100644
--- a/java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java
+++ b/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() {
onChanged();
}
diff --git a/java/core/src/main/java/com/google/protobuf/SmallSortedMap.java b/java/core/src/main/java/com/google/protobuf/SmallSortedMap.java
index dff19328..409fec10 100644
--- a/java/core/src/main/java/com/google/protobuf/SmallSortedMap.java
+++ b/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;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public K getKey() {
return key;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public V getValue() {
return value;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public int compareTo(Entry other) {
return getKey().compareTo(other.getKey());
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public V setValue(V newValue) {
checkMutable();
final V oldValue = this.value;
@@ -535,13 +535,13 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
private boolean nextCalledBeforeRemove;
private Iterator<Map.Entry<K, V>> lazyOverflowIterator;
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasNext() {
return (pos + 1) < entryList.size() ||
getOverflowIterator().hasNext();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Map.Entry<K, V> next() {
nextCalledBeforeRemove = true;
// 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();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void remove() {
if (!nextCalledBeforeRemove) {
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 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")
static <T> 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;
+ }
}
diff --git a/java/core/src/main/java/com/google/protobuf/TextFormat.java b/java/core/src/main/java/com/google/protobuf/TextFormat.java
index edf114fa..c1c328fc 100644
--- a/java/core/src/main/java/com/google/protobuf/TextFormat.java
+++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java
@@ -965,11 +965,13 @@ public final class TextFormat {
*/
public boolean consumeBoolean() throws ParseException {
if (currentToken.equals("true")
+ || currentToken.equals("True")
|| currentToken.equals("t")
|| currentToken.equals("1")) {
nextToken();
return true;
} else if (currentToken.equals("false")
+ || currentToken.equals("False")
|| currentToken.equals("f")
|| currentToken.equals("0")) {
nextToken();
diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
index 7cd2250e..c906420d 100644
--- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
+++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
@@ -76,6 +76,7 @@ public final class UnknownFieldSet implements MessageLite {
public static UnknownFieldSet getDefaultInstance() {
return defaultInstance;
}
+ @Override
public UnknownFieldSet getDefaultInstanceForType() {
return defaultInstance;
}
@@ -126,6 +127,7 @@ public final class UnknownFieldSet implements MessageLite {
}
/** Serializes the set and writes it to {@code output}. */
+ @Override
public void writeTo(final CodedOutputStream output) throws IOException {
for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
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
* just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
*/
+ @Override
public ByteString toByteString() {
try {
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
* just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
*/
+ @Override
public byte[] toByteArray() {
try {
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
* trivial wrapper around {@link #writeTo(CodedOutputStream)}.
*/
+ @Override
public void writeTo(final OutputStream output) throws IOException {
final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
writeTo(codedOutput);
codedOutput.flush();
}
+ @Override
public void writeDelimitedTo(OutputStream output) throws IOException {
final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
codedOutput.writeRawVarint32(getSerializedSize());
@@ -195,6 +201,7 @@ public final class UnknownFieldSet implements MessageLite {
}
/** Get the number of bytes required to encode this set. */
+ @Override
public int getSerializedSize() {
int result = 0;
for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
@@ -228,6 +235,7 @@ public final class UnknownFieldSet implements MessageLite {
return result;
}
+ @Override
public boolean isInitialized() {
// UnknownFieldSets do not have required fields, so they are always
// initialized.
@@ -258,10 +266,12 @@ public final class UnknownFieldSet implements MessageLite {
return newBuilder().mergeFrom(input).build();
}
+ @Override
public Builder newBuilderForType() {
return newBuilder();
}
+ @Override
public Builder toBuilder() {
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
* thrown.
*/
+ @Override
public UnknownFieldSet build() {
getFieldBuilder(0); // Force lastField to be built.
final UnknownFieldSet result;
@@ -341,6 +352,7 @@ public final class UnknownFieldSet implements MessageLite {
return result;
}
+ @Override
public UnknownFieldSet buildPartial() {
// No required fields, so this is the same as build().
return build();
@@ -353,6 +365,7 @@ public final class UnknownFieldSet implements MessageLite {
new UnknownFieldSet(fields));
}
+ @Override
public UnknownFieldSet getDefaultInstanceForType() {
return UnknownFieldSet.getDefaultInstance();
}
@@ -364,6 +377,7 @@ public final class UnknownFieldSet implements MessageLite {
}
/** Reset the builder to an empty set. */
+ @Override
public Builder clear() {
reinitialize();
return this;
@@ -487,6 +501,7 @@ public final class UnknownFieldSet implements MessageLite {
* Parse an entire message from {@code input} and merge its fields into
* this set.
*/
+ @Override
public Builder mergeFrom(final CodedInputStream input) throws IOException {
while (true) {
final int tag = input.readTag();
@@ -536,8 +551,8 @@ public final class UnknownFieldSet implements MessageLite {
* set being built. This is just a small wrapper around
* {@link #mergeFrom(CodedInputStream)}.
*/
- public Builder mergeFrom(final ByteString data)
- throws InvalidProtocolBufferException {
+ @Override
+ public Builder mergeFrom(final ByteString data) throws InvalidProtocolBufferException {
try {
final CodedInputStream input = data.newCodedInput();
mergeFrom(input);
@@ -557,8 +572,8 @@ public final class UnknownFieldSet implements MessageLite {
* set being built. This is just a small wrapper around
* {@link #mergeFrom(CodedInputStream)}.
*/
- public Builder mergeFrom(final byte[] data)
- throws InvalidProtocolBufferException {
+ @Override
+ public Builder mergeFrom(final byte[] data) throws InvalidProtocolBufferException {
try {
final CodedInputStream input = CodedInputStream.newInstance(data);
mergeFrom(input);
@@ -578,6 +593,7 @@ public final class UnknownFieldSet implements MessageLite {
* set being built. This is just a small wrapper around
* {@link #mergeFrom(CodedInputStream)}.
*/
+ @Override
public Builder mergeFrom(final InputStream input) throws IOException {
final CodedInputStream codedInput = CodedInputStream.newInstance(input);
mergeFrom(codedInput);
@@ -585,8 +601,8 @@ public final class UnknownFieldSet implements MessageLite {
return this;
}
- public boolean mergeDelimitedFrom(InputStream input)
- throws IOException {
+ @Override
+ public boolean mergeDelimitedFrom(InputStream input) throws IOException {
final int firstByte = input.read();
if (firstByte == -1) {
return false;
@@ -597,30 +613,29 @@ public final class UnknownFieldSet implements MessageLite {
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.
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.
return mergeFrom(input);
}
- public Builder mergeFrom(
- ByteString data,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
// UnknownFieldSet has no extensions.
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 {
final CodedInputStream input =
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 {
// UnknownFieldSet has no extensions.
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 {
// UnknownFieldSet has no extensions.
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.
return mergeFrom(input);
}
+ @Override
+ public Builder mergeFrom(MessageLite m) {
+ if (m instanceof UnknownFieldSet) {
+ return mergeFrom((UnknownFieldSet) m);
+ }
+ throw new IllegalArgumentException(
+ "mergeFrom(MessageLite) can only merge messages of the same type.");
+ }
+
+ @Override
public boolean isInitialized() {
// UnknownFieldSets do not have required fields, so they are always
// initialized.
@@ -987,6 +1010,7 @@ public final class UnknownFieldSet implements MessageLite {
* Parser to implement MessageLite interface.
*/
public static final class Parser extends AbstractParser<UnknownFieldSet> {
+ @Override
public UnknownFieldSet parsePartialFrom(
CodedInputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
@@ -1004,6 +1028,7 @@ public final class UnknownFieldSet implements MessageLite {
}
private static final Parser PARSER = new Parser();
+ @Override
public final Parser getParserForType() {
return PARSER;
}
diff --git a/java/core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java b/java/core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java
index 5257c5a2..30e87911 100644
--- a/java/core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java
+++ b/java/core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java
@@ -68,42 +68,42 @@ public class UnmodifiableLazyStringList extends AbstractList<String>
return list.size();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public ByteString getByteString(int index) {
return list.getByteString(index);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void add(ByteString element) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void set(int index, ByteString element) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean addAllByteString(Collection<? extends ByteString> element) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public byte[] getByteArray(int index) {
return list.getByteArray(index);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void add(byte[] element) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void set(int index, byte[] element) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean addAllByteArray(Collection<byte[]> element) {
throw new UnsupportedOperationException();
}
@@ -113,47 +113,47 @@ public class UnmodifiableLazyStringList extends AbstractList<String>
return new ListIterator<String>() {
ListIterator<String> iter = list.listIterator(index);
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasNext() {
return iter.hasNext();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public String next() {
return iter.next();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasPrevious() {
return iter.hasPrevious();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public String previous() {
return iter.previous();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public int nextIndex() {
return iter.nextIndex();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public int previousIndex() {
return iter.previousIndex();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void remove() {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void set(String o) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void add(String o) {
throw new UnsupportedOperationException();
}
@@ -165,45 +165,45 @@ public class UnmodifiableLazyStringList extends AbstractList<String>
return new Iterator<String>() {
Iterator<String> iter = list.iterator();
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasNext() {
return iter.hasNext();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public String next() {
return iter.next();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public List<?> getUnderlyingElements() {
// The returned value is already unmodifiable.
return list.getUnderlyingElements();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void mergeFrom(LazyStringList other) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public List<byte[]> asByteArrayList() {
return Collections.unmodifiableList(list.asByteArrayList());
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public List<ByteString> asByteStringList() {
return Collections.unmodifiableList(list.asByteStringList());
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public LazyStringList getUnmodifiableView() {
return this;
}
diff --git a/java/core/src/main/java/com/google/protobuf/WireFormat.java b/java/core/src/main/java/com/google/protobuf/WireFormat.java
index 8dbe1ae3..6a58b081 100644
--- a/java/core/src/main/java/com/google/protobuf/WireFormat.java
+++ b/java/core/src/main/java/com/google/protobuf/WireFormat.java
@@ -116,16 +116,24 @@ public final class WireFormat {
FIXED32 (JavaType.INT , WIRETYPE_FIXED32 ),
BOOL (JavaType.BOOLEAN , WIRETYPE_VARINT ),
STRING (JavaType.STRING , WIRETYPE_LENGTH_DELIMITED) {
- public boolean isPackable() { return false; }
+ @Override
+ public boolean isPackable() {
+ return false; }
},
GROUP (JavaType.MESSAGE , WIRETYPE_START_GROUP ) {
- public boolean isPackable() { return false; }
+ @Override
+ public boolean isPackable() {
+ return false; }
},
MESSAGE (JavaType.MESSAGE , WIRETYPE_LENGTH_DELIMITED) {
- public boolean isPackable() { return false; }
+ @Override
+ public boolean isPackable() {
+ return false; }
},
BYTES (JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED) {
- public boolean isPackable() { return false; }
+ @Override
+ public boolean isPackable() {
+ return false; }
},
UINT32 (JavaType.INT , WIRETYPE_VARINT ),
ENUM (JavaType.ENUM , WIRETYPE_VARINT ),
@@ -170,18 +178,21 @@ public final class WireFormat {
enum Utf8Validation {
/** Eagerly parses to String; silently accepts invalid UTF8 bytes. */
LOOSE {
+ @Override
Object readString(CodedInputStream input) throws IOException {
return input.readString();
}
},
/** Eagerly parses to String; throws an IOException on invalid bytes. */
STRICT {
+ @Override
Object readString(CodedInputStream input) throws IOException {
return input.readStringRequireUtf8();
}
},
/** Keep data as ByteString; validation/conversion to String is lazy. */
LAZY {
+ @Override
Object readString(CodedInputStream input) throws IOException {
return input.readBytes();
}
diff --git a/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java b/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java
index 1e57b647..7dc9fc15 100644
--- a/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java
+++ b/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java
@@ -64,35 +64,44 @@ public class AbstractMessageTest extends TestCase {
this.wrappedMessage = wrappedMessage;
}
+ @Override
public Descriptors.Descriptor getDescriptorForType() {
return wrappedMessage.getDescriptorForType();
}
+ @Override
public AbstractMessageWrapper getDefaultInstanceForType() {
return new AbstractMessageWrapper(
wrappedMessage.getDefaultInstanceForType());
}
+ @Override
public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
return wrappedMessage.getAllFields();
}
+ @Override
public boolean hasField(Descriptors.FieldDescriptor field) {
return wrappedMessage.hasField(field);
}
+ @Override
public Object getField(Descriptors.FieldDescriptor field) {
return wrappedMessage.getField(field);
}
+ @Override
public int getRepeatedFieldCount(Descriptors.FieldDescriptor 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);
}
+ @Override
public UnknownFieldSet getUnknownFields() {
return wrappedMessage.getUnknownFields();
}
+ @Override
public Builder newBuilderForType() {
return new Builder(wrappedMessage.newBuilderForType());
}
+ @Override
public Builder toBuilder() {
return new Builder(wrappedMessage.toBuilder());
}
@@ -104,65 +113,80 @@ public class AbstractMessageTest extends TestCase {
this.wrappedBuilder = wrappedBuilder;
}
+ @Override
public AbstractMessageWrapper build() {
return new AbstractMessageWrapper(wrappedBuilder.build());
}
+ @Override
public AbstractMessageWrapper buildPartial() {
return new AbstractMessageWrapper(wrappedBuilder.buildPartial());
}
+ @Override
public Builder clone() {
return new Builder(wrappedBuilder.clone());
}
+ @Override
public boolean isInitialized() {
return clone().buildPartial().isInitialized();
}
+ @Override
public Descriptors.Descriptor getDescriptorForType() {
return wrappedBuilder.getDescriptorForType();
}
+ @Override
public AbstractMessageWrapper getDefaultInstanceForType() {
return new AbstractMessageWrapper(
wrappedBuilder.getDefaultInstanceForType());
}
+ @Override
public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
return wrappedBuilder.getAllFields();
}
+ @Override
public Builder newBuilderForField(Descriptors.FieldDescriptor field) {
return new Builder(wrappedBuilder.newBuilderForField(field));
}
+ @Override
public boolean hasField(Descriptors.FieldDescriptor field) {
return wrappedBuilder.hasField(field);
}
+ @Override
public Object getField(Descriptors.FieldDescriptor field) {
return wrappedBuilder.getField(field);
}
+ @Override
public Builder setField(Descriptors.FieldDescriptor field, Object value) {
wrappedBuilder.setField(field, value);
return this;
}
+ @Override
public Builder clearField(Descriptors.FieldDescriptor field) {
wrappedBuilder.clearField(field);
return this;
}
+ @Override
public int getRepeatedFieldCount(Descriptors.FieldDescriptor 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);
}
- 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);
return this;
}
- public Builder addRepeatedField(
- Descriptors.FieldDescriptor field, Object value) {
+ @Override
+ public Builder addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
wrappedBuilder.addRepeatedField(field, value);
return this;
}
+ @Override
public UnknownFieldSet getUnknownFields() {
return wrappedBuilder.getUnknownFields();
}
+ @Override
public Builder setUnknownFields(UnknownFieldSet unknownFields) {
wrappedBuilder.setUnknownFields(unknownFields);
return this;
@@ -172,6 +196,7 @@ public class AbstractMessageTest extends TestCase {
return wrappedBuilder.getFieldBuilder(field);
}
}
+ @Override
public Parser<? extends Message> getParserForType() {
return wrappedMessage.getParserForType();
}
diff --git a/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java b/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java
index b8ad1fe4..24b96c60 100644
--- a/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java
@@ -73,20 +73,6 @@ public class BooleanArrayListTest extends TestCase {
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() {
list.addAll(asList(true, false, false, true));
Iterator<Boolean> iterator = list.iterator();
diff --git a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
index a1d6f1be..ca940ced 100644
--- a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
+++ b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
@@ -81,10 +81,12 @@ public class CodedInputStreamTest extends TestCase {
this.blockSize = blockSize;
}
+ @Override
public int read(byte[] b) throws IOException {
return super.read(b, 0, Math.min(b.length, blockSize));
}
+ @Override
public int read(byte[] b, int off, int len) throws IOException {
return super.read(b, off, Math.min(len, blockSize));
}
diff --git a/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java b/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
index 6018ea55..33aa4357 100644
--- a/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
+++ b/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
@@ -30,6 +30,7 @@
package com.google.protobuf;
+import com.google.protobuf.CodedOutputStream.OutOfSpaceException;
import protobuf_unittest.UnittestProto.SparseEnumMessage;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestPackedTypes;
@@ -50,118 +51,180 @@ import java.util.List;
* @author kenton@google.com Kenton Varda
*/
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. */
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
assertWriteVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
// 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
// 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
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
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(). */
@@ -245,141 +263,138 @@ public class CodedOutputStreamTest extends TestCase {
assertWriteLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
assertWriteLittleEndian64(
- bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
- 0x123456789abcdef0L);
+ bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12), 0x123456789abcdef0L);
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(). */
public void testEncodeZigZag() throws Exception {
- assertEquals(0, CodedOutputStream.encodeZigZag32( 0));
+ assertEquals(0, CodedOutputStream.encodeZigZag32(0));
assertEquals(1, CodedOutputStream.encodeZigZag32(-1));
- assertEquals(2, CodedOutputStream.encodeZigZag32( 1));
+ assertEquals(2, CodedOutputStream.encodeZigZag32(1));
assertEquals(3, CodedOutputStream.encodeZigZag32(-2));
assertEquals(0x7FFFFFFE, CodedOutputStream.encodeZigZag32(0x3FFFFFFF));
assertEquals(0x7FFFFFFF, CodedOutputStream.encodeZigZag32(0xC0000000));
assertEquals(0xFFFFFFFE, CodedOutputStream.encodeZigZag32(0x7FFFFFFF));
assertEquals(0xFFFFFFFF, CodedOutputStream.encodeZigZag32(0x80000000));
- assertEquals(0, CodedOutputStream.encodeZigZag64( 0));
+ assertEquals(0, CodedOutputStream.encodeZigZag64(0));
assertEquals(1, CodedOutputStream.encodeZigZag64(-1));
- assertEquals(2, CodedOutputStream.encodeZigZag64( 1));
+ assertEquals(2, CodedOutputStream.encodeZigZag64(1));
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)
// 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. */
public void testWriteWholeMessage() throws Exception {
+ final byte[] expectedBytes = TestUtil.getGoldenMessage().toByteArray();
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.
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 {
+ byte[] expectedBytes = TestUtil.getGoldenPackedFieldsMessage().toByteArray();
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.
*/
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);
- 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() */
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);
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 =
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
// 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);
-
- // 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
- 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
// this case.
public void testWriteStringNoTag_fastpath() throws Exception {
@@ -390,14 +405,16 @@ public class CodedOutputStreamTest extends TestCase {
string += threeBytesPer;
}
// These checks ensure we will tickle the slower fast path.
- assertEquals(1, CodedOutputStream.computeRawVarint32Size(string.length()));
+ assertEquals(1, CodedOutputStream.computeUInt32SizeNoTag(string.length()));
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);
-
- 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 {
@@ -464,83 +481,296 @@ public class CodedOutputStreamTest extends TestCase {
byte[] destination = new byte[4];
CodedOutputStream codedStream = CodedOutputStream.newInstance(destination);
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());
}
-
+
+ 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 {
- 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),
- 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 outputWithArray = CodedOutputStream.newInstance(new byte[10000]);
+ CodedOutputStream outputWithByteBuffer =
+ CodedOutputStream.newInstance(ByteBuffer.allocate(10000));
for (String s : invalidStrings) {
// TODO(dweis): These should all fail; instead they are corrupting data.
CodedOutputStream.computeStringSizeNoTag(s);
outputWithStream.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 */
public void testCorrectExceptionThrowWhenEncodingStringsWithoutEnoughSpace() throws Exception {
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));
// 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.
- 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 {
// Test string serialization roundtrip using strings of the following lengths,
// with ASCII and Unicode characters requiring different UTF-8 byte counts per
// char, hence causing the length delimiter varint to sometimes require more
// bytes for the Unicode strings than the ASCII string of the same length.
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);
- 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(
- 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];
Arrays.fill(result, c);
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());
+ }
+ }
}
diff --git a/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java b/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java
index d3deaa07..85b418c4 100644
--- a/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java
@@ -73,20 +73,6 @@ public class DoubleArrayListTest extends TestCase {
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() {
list.addAll(asList(1D, 2D, 3D, 4D));
Iterator<Double> iterator = list.iterator();
diff --git a/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java b/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java
index a5e65424..88a75743 100644
--- a/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java
@@ -73,20 +73,6 @@ public class FloatArrayListTest extends TestCase {
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() {
list.addAll(asList(1F, 2F, 3F, 4F));
Iterator<Float> iterator = list.iterator();
diff --git a/java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java b/java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java
index a92ba374..b7eaebf5 100644
--- a/java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java
+++ b/java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java
@@ -41,7 +41,7 @@ package com.google.protobuf;
*/
public class ForceFieldBuildersPreRun implements Runnable {
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void run() {
GeneratedMessage.enableAlwaysUseFieldBuildersForTesting();
}
diff --git a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
index 8cd1f38d..a9b8b638 100644
--- a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
+++ b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -723,7 +723,7 @@ public class GeneratedMessageTest extends TestCase {
public void testLiteExtensionMessageOrBuilder() throws Exception {
TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
- TestUtil.setAllExtensions(builder);
+ TestUtilLite.setAllExtensions(builder);
TestUtil.assertAllExtensionsSet(builder);
TestAllExtensionsLite message = builder.build();
@@ -732,8 +732,8 @@ public class GeneratedMessageTest extends TestCase {
public void testLiteExtensionRepeatedSetters() throws Exception {
TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
- TestUtil.setAllExtensions(builder);
- TestUtil.modifyRepeatedExtensions(builder);
+ TestUtilLite.setAllExtensions(builder);
+ TestUtilLite.modifyRepeatedExtensions(builder);
TestUtil.assertRepeatedExtensionsModified(builder);
TestAllExtensionsLite message = builder.build();
@@ -760,7 +760,7 @@ public class GeneratedMessageTest extends TestCase {
}
public void testLiteExtensionCopy() throws Exception {
- TestAllExtensionsLite original = TestUtil.getAllLiteExtensionsSet();
+ TestAllExtensionsLite original = TestUtilLite.getAllLiteExtensionsSet();
TestAllExtensionsLite copy =
TestAllExtensionsLite.newBuilder(original).build();
TestUtil.assertAllExtensionsSet(copy);
diff --git a/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java b/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java
index 3733eb30..efb8f3e2 100644
--- a/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java
@@ -72,20 +72,6 @@ public class IntArrayListTest extends TestCase {
list.makeImmutable();
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() {
list.addAll(asList(1, 2, 3, 4));
diff --git a/java/core/src/test/java/com/google/protobuf/LiteTest.java b/java/core/src/test/java/com/google/protobuf/LiteTest.java
index 9e503cc3..88c3e0b2 100644
--- a/java/core/src/test/java/com/google/protobuf/LiteTest.java
+++ b/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.singletonList;
+import com.google.protobuf.UnittestImportLite.ImportEnumLite;
+import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
import com.google.protobuf.UnittestLite;
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.TestAllTypesLite.NestedEnum;
import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage;
import com.google.protobuf.UnittestLite.TestAllTypesLite.OneofFieldCase;
import com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup;
import com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup;
import com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder;
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;
@@ -59,6 +67,7 @@ import java.io.ObjectOutputStream;
* @author kenton@google.com Kenton Varda
*/
public class LiteTest extends TestCase {
+ @Override
public void setUp() throws Exception {
// Test that nested extensions are initialized correctly even if the outer
// class has not been accessed directly. This was once a bug with lite
@@ -302,11 +311,9 @@ public class LiteTest extends TestCase {
assertEquals(
ForeignMessageLite.getDefaultInstance(),
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();
- assertEquals(3, messageAfterBuild.getOptionalForeignMessage().getC());
+ assertEquals(foreignMessageBuilder.build(), messageAfterBuild.getOptionalForeignMessage());
assertEquals(
ForeignMessageLite.getDefaultInstance(),
message.getOptionalForeignMessage());
@@ -314,7 +321,7 @@ public class LiteTest extends TestCase {
assertEquals(
ForeignMessageLite.getDefaultInstance(),
builder.getOptionalForeignMessage());
- assertEquals(3, messageAfterBuild.getOptionalForeignMessage().getC());
+ assertEquals(foreignMessageBuilder.build(), messageAfterBuild.getOptionalForeignMessage());
message = builder.build();
OptionalGroup optionalGroup = OptionalGroup.newBuilder()
@@ -339,17 +346,15 @@ public class LiteTest extends TestCase {
builder.setOptionalGroup(optionalGroupBuilder);
assertEquals(
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();
- assertEquals(3, messageAfterBuild.getOptionalGroup().getA());
+ assertEquals(optionalGroupBuilder.build(), messageAfterBuild.getOptionalGroup());
assertEquals(
OptionalGroup.getDefaultInstance(), message.getOptionalGroup());
builder.clearOptionalGroup();
assertEquals(
OptionalGroup.getDefaultInstance(), builder.getOptionalGroup());
- assertEquals(3, messageAfterBuild.getOptionalGroup().getA());
+ assertEquals(optionalGroupBuilder.build(), messageAfterBuild.getOptionalGroup());
message = builder.build();
builder.setOptionalInt32(1);
@@ -400,17 +405,16 @@ public class LiteTest extends TestCase {
assertEquals(
NestedMessage.getDefaultInstance(),
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();
- assertEquals(3, messageAfterBuild.getOptionalLazyMessage().getBb());
+ assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getOptionalLazyMessage());
assertEquals(
NestedMessage.getDefaultInstance(),
message.getOptionalLazyMessage());
builder.clearOptionalLazyMessage();
assertEquals(
NestedMessage.getDefaultInstance(), builder.getOptionalLazyMessage());
- assertEquals(3, messageAfterBuild.getOptionalLazyMessage().getBb());
+ assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getOptionalLazyMessage());
message = builder.build();
builder.setOptionalSfixed32(1);
@@ -1100,8 +1104,7 @@ public class LiteTest extends TestCase {
assertEquals(0, message.getRepeatedForeignMessageCount());
builder.setRepeatedForeignMessage(
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(
ForeignMessageLite.getDefaultInstance(),
builder.getRepeatedForeignMessage(0));
@@ -1114,8 +1117,7 @@ public class LiteTest extends TestCase {
builder.setRepeatedForeignMessage(0, foreignMessageBuilder);
assertEquals(
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();
message = builder.build();
@@ -1148,9 +1150,7 @@ public class LiteTest extends TestCase {
messageAfterBuild = builder.build();
assertEquals(0, message.getRepeatedGroupCount());
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(
RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0));
builder.clearRepeatedGroup();
@@ -1160,9 +1160,7 @@ public class LiteTest extends TestCase {
messageAfterBuild = builder.build();
assertEquals(0, message.getRepeatedGroupCount());
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(
RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0));
builder.clearRepeatedGroup();
@@ -1210,9 +1208,7 @@ public class LiteTest extends TestCase {
messageAfterBuild = builder.build();
assertEquals(0, message.getRepeatedLazyMessageCount());
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(
NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0));
builder.clearRepeatedLazyMessage();
@@ -1222,9 +1218,7 @@ public class LiteTest extends TestCase {
messageAfterBuild = builder.build();
assertEquals(0, message.getRepeatedLazyMessageCount());
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(
NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0));
builder.clearRepeatedLazyMessage();
@@ -1456,7 +1450,7 @@ public class LiteTest extends TestCase {
.setOptionalFloat(2.72f)
.setOptionalDouble(3.14)
.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 {
@@ -1511,7 +1505,7 @@ public class LiteTest extends TestCase {
.setC(3))
.build();
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);
}
@@ -1546,6 +1540,27 @@ public class LiteTest extends TestCase {
"1: 123\n18: \"\\b\\a\"\n21: 3\n44: \"spam\"\n44: \"eggs\"",
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
// 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(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();
+ }
}
diff --git a/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java b/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java
index 1bd094f7..0a8f9ed2 100644
--- a/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java
@@ -73,20 +73,6 @@ public class LongArrayListTest extends TestCase {
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() {
list.addAll(asList(1L, 2L, 3L, 4L));
Iterator<Long> iterator = list.iterator();
diff --git a/java/core/src/test/java/com/google/protobuf/ParserTest.java b/java/core/src/test/java/com/google/protobuf/ParserTest.java
index 9d4b6b94..30842d2c 100644
--- a/java/core/src/test/java/com/google/protobuf/ParserTest.java
+++ b/java/core/src/test/java/com/google/protobuf/ParserTest.java
@@ -179,16 +179,16 @@ public class ParserTest extends TestCase {
public void testParseExtensions() throws Exception {
assertRoundTripEquals(TestUtil.getAllExtensionsSet(),
TestUtil.getExtensionRegistry());
- assertRoundTripEquals(TestUtil.getAllLiteExtensionsSet(),
- TestUtil.getExtensionRegistryLite());
+ assertRoundTripEquals(
+ TestUtilLite.getAllLiteExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
}
public void testParsePacked() throws Exception {
assertRoundTripEquals(TestUtil.getPackedSet());
assertRoundTripEquals(TestUtil.getPackedExtensionsSet(),
TestUtil.getExtensionRegistry());
- assertRoundTripEquals(TestUtil.getLitePackedExtensionsSet(),
- TestUtil.getExtensionRegistryLite());
+ assertRoundTripEquals(
+ TestUtilLite.getLitePackedExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
}
public void testParseDelimitedTo() throws Exception {
@@ -198,8 +198,7 @@ public class ParserTest extends TestCase {
normalMessage.writeDelimitedTo(output);
// Write MessageLite with packed extension fields.
- TestPackedExtensionsLite packedMessage =
- TestUtil.getLitePackedExtensionsSet();
+ TestPackedExtensionsLite packedMessage = TestUtilLite.getLitePackedExtensionsSet();
packedMessage.writeDelimitedTo(output);
InputStream input = new ByteArrayInputStream(output.toByteArray());
@@ -208,8 +207,9 @@ public class ParserTest extends TestCase {
normalMessage.getParserForType().parseDelimitedFrom(input));
assertMessageEquals(
packedMessage,
- packedMessage.getParserForType().parseDelimitedFrom(
- input, TestUtil.getExtensionRegistryLite()));
+ packedMessage
+ .getParserForType()
+ .parseDelimitedFrom(input, TestUtilLite.getExtensionRegistryLite()));
}
public void testParseUnknownFields() throws Exception {
diff --git a/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java b/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java
index 245c3dee..3f45e226 100644
--- a/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java
@@ -63,20 +63,6 @@ public class ProtobufArrayListTest extends TestCase {
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() {
list.addAll(asList(1, 2, 3, 4));
Iterator<Integer> iterator = list.iterator();
diff --git a/java/core/src/test/java/com/google/protobuf/ServiceTest.java b/java/core/src/test/java/com/google/protobuf/ServiceTest.java
index 7f3439d0..b902737d 100644
--- a/java/core/src/test/java/com/google/protobuf/ServiceTest.java
+++ b/java/core/src/test/java/com/google/protobuf/ServiceTest.java
@@ -175,12 +175,14 @@ public class ServiceTest extends TestCase {
MethodDescriptor fooMethod =
ServiceWithNoOuter.getDescriptor().findMethodByName("Foo");
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 =
RpcUtil.specializeCallback(callback);
@@ -290,7 +292,9 @@ public class ServiceTest extends TestCase {
public boolean isCalled() { return called; }
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. */
@@ -301,6 +305,7 @@ public class ServiceTest extends TestCase {
this.callback = callback;
}
+ @Override
@SuppressWarnings("unchecked")
public boolean matches(Object actual) {
if (!(actual instanceof RpcCallback)) {
@@ -313,6 +318,7 @@ public class ServiceTest extends TestCase {
return callback.isCalled();
}
+ @Override
public void appendTo(StringBuffer buffer) {
buffer.append("wrapsCallback(mockCallback)");
}
diff --git a/java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java b/java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java
index 366086d3..e96ecd65 100644
--- a/java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java
+++ b/java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java
@@ -56,14 +56,17 @@ public class SmallSortedMapTest extends TestCase {
this.value = value;
}
+ @Override
public K getKey() {
return key;
}
+ @Override
public V getValue() {
return value;
}
+ @Override
public V setValue(V value) {
V oldValue = this.value;
this.value = value;
diff --git a/java/core/src/test/java/com/google/protobuf/TestUtil.java b/java/core/src/test/java/com/google/protobuf/TestUtil.java
index 53d65428..08b2a76d 100644
--- a/java/core/src/test/java/com/google/protobuf/TestUtil.java
+++ b/java/core/src/test/java/com/google/protobuf/TestUtil.java
@@ -30,8 +30,6 @@
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;
@@ -216,12 +214,7 @@ import static protobuf_unittest.UnittestProto.repeatedUint32Extension;
import static protobuf_unittest.UnittestProto.repeatedUint64Extension;
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.ForeignMessageLite;
-import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
import com.google.protobuf.UnittestLite.TestAllExtensionsLiteOrBuilder;
import com.google.protobuf.UnittestLite.TestAllTypesLite;
import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
@@ -287,16 +280,6 @@ public final class TestUtil {
}
/**
- * 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
* {@link #setAllExtensions(TestAllExtensions.Builder)}.
*/
@@ -306,12 +289,6 @@ public final class TestUtil {
return builder.build();
}
- public static TestAllExtensionsLite getAllLiteExtensionsSet() {
- TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
- setAllExtensions(builder);
- return builder.build();
- }
-
public static TestPackedTypes getPackedSet() {
TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
setPackedFields(builder);
@@ -330,157 +307,6 @@ public final class TestUtil {
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
* {@code assertAllFieldsSet()}.
@@ -1370,23 +1196,13 @@ public final class TestUtil {
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
* given {@link ExtensionRegistry}.
*/
public static void registerAllExtensions(ExtensionRegistry registry) {
UnittestProto.registerAllExtensions(registry);
- registerAllExtensionsLite(registry);
- }
-
- public static void registerAllExtensionsLite(ExtensionRegistryLite registry) {
- UnittestLite.registerAllExtensions(registry);
+ TestUtilLite.registerAllExtensionsLite(registry);
}
/**
@@ -2180,195 +1996,6 @@ public final class TestUtil {
// 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
* {@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));
}
- 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) {
Assert.assertEquals(2, message.getExtensionCount(packedInt32ExtensionLite ));
Assert.assertEquals(2, message.getExtensionCount(packedInt64ExtensionLite ));
@@ -4250,7 +3845,7 @@ public final class TestUtil {
private int invalidations;
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void markDirty() {
invalidations++;
}
diff --git a/java/core/src/test/java/com/google/protobuf/TestUtilLite.java b/java/core/src/test/java/com/google/protobuf/TestUtilLite.java
new file mode 100644
index 00000000..8f33fa14
--- /dev/null
+++ b/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);
+ }
+}
diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
index 3f47d924..63c17cd0 100644
--- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
+++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
@@ -775,11 +775,14 @@ public class TextFormatTest extends TestCase {
public void testParseBoolean() throws Exception {
String goodText =
"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 =
"repeated_bool: true\n" +
"repeated_bool: false\n" +
"repeated_bool: false\n" +
+ "repeated_bool: true\n" +
+ "repeated_bool: false\n" +
"repeated_bool: true\n";
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
TextFormat.merge(goodText, builder);
diff --git a/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
index 8c9dcafe..32380f70 100644
--- a/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
+++ b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
@@ -50,6 +50,7 @@ import java.util.Map;
* @author kenton@google.com (Kenton Varda)
*/
public class UnknownFieldSetTest extends TestCase {
+ @Override
public void setUp() throws Exception {
descriptor = TestAllTypes.getDescriptor();
allFields = TestUtil.getAllSet();
diff --git a/java/core/src/test/java/com/google/protobuf/WireFormatTest.java b/java/core/src/test/java/com/google/protobuf/WireFormatTest.java
index b3aabb8f..e66b371c 100644
--- a/java/core/src/test/java/com/google/protobuf/WireFormatTest.java
+++ b/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
// it should work.
- TestAllExtensionsLite message = TestUtil.getAllLiteExtensionsSet();
+ TestAllExtensionsLite message = TestUtilLite.getAllLiteExtensionsSet();
ByteString rawBytes = message.toByteString();
assertEquals(rawBytes.size(), message.getSerializedSize());
@@ -144,7 +144,7 @@ public class WireFormatTest extends TestCase {
public void testSerializePackedExtensionsLite() throws Exception {
// TestPackedTypes and TestPackedExtensions should have compatible wire
// formats; check that they serialize to the same string.
- TestPackedExtensionsLite message = TestUtil.getLitePackedExtensionsSet();
+ TestPackedExtensionsLite message = TestUtilLite.getLitePackedExtensionsSet();
ByteString rawBytes = message.toByteString();
TestPackedTypes message2 = TestUtil.getPackedSet();
@@ -190,7 +190,7 @@ public class WireFormatTest extends TestCase {
TestAllTypes message = TestUtil.getAllSet();
ByteString rawBytes = message.toByteString();
- ExtensionRegistryLite registry_lite = TestUtil.getExtensionRegistryLite();
+ ExtensionRegistryLite registry_lite = TestUtilLite.getExtensionRegistryLite();
TestAllExtensionsLite message2 =
TestAllExtensionsLite.parseFrom(rawBytes, registry_lite);
@@ -208,10 +208,10 @@ public class WireFormatTest extends TestCase {
public void testParsePackedExtensionsLite() throws Exception {
// Ensure that packed extensions can be properly parsed.
- TestPackedExtensionsLite message = TestUtil.getLitePackedExtensionsSet();
+ TestPackedExtensionsLite message = TestUtilLite.getLitePackedExtensionsSet();
ByteString rawBytes = message.toByteString();
- ExtensionRegistryLite registry = TestUtil.getExtensionRegistryLite();
+ ExtensionRegistryLite registry = TestUtilLite.getExtensionRegistryLite();
TestPackedExtensionsLite message2 =
TestPackedExtensionsLite.parseFrom(rawBytes, registry);
diff --git a/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto b/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto
index f75484de..6eef42c5 100644
--- a/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto
+++ b/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;
-// 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;
message TestOneofEquals {