aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt35
-rw-r--r--Makefile.am1
-rw-r--r--java/src/main/java/com/google/protobuf/AbstractMessage.java43
-rw-r--r--java/src/main/java/com/google/protobuf/CodedInputStream.java15
-rw-r--r--java/src/main/java/com/google/protobuf/CodedOutputStream.java507
-rw-r--r--java/src/main/java/com/google/protobuf/Descriptors.java13
-rw-r--r--java/src/main/java/com/google/protobuf/DynamicMessage.java5
-rw-r--r--java/src/main/java/com/google/protobuf/FieldSet.java154
-rw-r--r--java/src/main/java/com/google/protobuf/GeneratedMessage.java102
-rw-r--r--java/src/main/java/com/google/protobuf/Message.java6
-rw-r--r--java/src/main/java/com/google/protobuf/TextFormat.java12
-rw-r--r--java/src/main/java/com/google/protobuf/WireFormat.java10
-rw-r--r--java/src/test/java/com/google/protobuf/AbstractMessageTest.java23
-rw-r--r--java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java11
-rw-r--r--java/src/test/java/com/google/protobuf/DynamicMessageTest.java68
-rw-r--r--java/src/test/java/com/google/protobuf/GeneratedMessageTest.java198
-rw-r--r--java/src/test/java/com/google/protobuf/TestUtil.java1518
-rw-r--r--java/src/test/java/com/google/protobuf/TextFormatTest.java28
-rw-r--r--java/src/test/java/com/google/protobuf/WireFormatTest.java49
-rwxr-xr-xpython/google/protobuf/internal/containers.py13
-rwxr-xr-xpython/google/protobuf/internal/decoder_test.py2
-rwxr-xr-xpython/google/protobuf/internal/encoder.py140
-rwxr-xr-xpython/google/protobuf/internal/encoder_test.py70
-rwxr-xr-xpython/google/protobuf/internal/reflection_test.py120
-rwxr-xr-xpython/google/protobuf/internal/service_reflection_test.py6
-rwxr-xr-xpython/google/protobuf/internal/test_util.py48
-rwxr-xr-xpython/google/protobuf/internal/type_checkers.py17
-rwxr-xr-xpython/google/protobuf/internal/wire_format.py35
-rwxr-xr-xpython/google/protobuf/reflection.py99
-rwxr-xr-xpython/google/protobuf/service.py17
-rwxr-xr-xpython/google/protobuf/service_reflection.py23
-rw-r--r--src/Makefile.am1
-rw-r--r--src/google/protobuf/compiler/command_line_interface.cc3
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum_field.cc91
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.cc25
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message_field.cc10
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_primitive_field.cc82
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.cc10
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto8
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc8
-rw-r--r--src/google/protobuf/compiler/java/java_enum.cc3
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field.cc86
-rw-r--r--src/google/protobuf/compiler/java/java_message.cc12
-rw-r--r--src/google/protobuf/compiler/java/java_message_field.cc9
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field.cc155
-rw-r--r--src/google/protobuf/compiler/python/python_generator.cc1
-rw-r--r--src/google/protobuf/descriptor.cc344
-rw-r--r--src/google/protobuf/descriptor.h50
-rw-r--r--src/google/protobuf/descriptor.pb.cc211
-rw-r--r--src/google/protobuf/descriptor.pb.h37
-rw-r--r--src/google/protobuf/descriptor.proto6
-rw-r--r--src/google/protobuf/descriptor_unittest.cc245
-rw-r--r--src/google/protobuf/dynamic_message_unittest.cc16
-rw-r--r--src/google/protobuf/extension_set_unittest.cc25
-rw-r--r--src/google/protobuf/io/coded_stream.cc28
-rw-r--r--src/google/protobuf/io/coded_stream.h28
-rw-r--r--src/google/protobuf/io/coded_stream_unittest.cc70
-rw-r--r--src/google/protobuf/message.cc26
-rw-r--r--src/google/protobuf/message.h8
-rw-r--r--src/google/protobuf/message_unittest.cc32
-rw-r--r--src/google/protobuf/test_util.cc479
-rw-r--r--src/google/protobuf/test_util.h25
-rw-r--r--src/google/protobuf/unittest.proto40
-rw-r--r--src/google/protobuf/unknown_field_set.cc40
-rw-r--r--src/google/protobuf/unknown_field_set.h152
-rw-r--r--src/google/protobuf/unknown_field_set_unittest.cc86
-rw-r--r--src/google/protobuf/wire_format.cc316
-rw-r--r--src/google/protobuf/wire_format.h42
-rw-r--r--src/google/protobuf/wire_format_inl.h100
-rw-r--r--src/google/protobuf/wire_format_unittest.cc55
70 files changed, 5088 insertions, 1265 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 7cc10e12..2a86a63c 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,8 +1,41 @@
-version 2.0.4:
+????-??-?? version 2.0.4:
+
+ General
+ * Repeated fields of primitive types (types other that string, group, and
+ nested messages) may now use the option [packed = true] to get a more
+ efficient encoding. In the new encoding, the entire list is written
+ as a single byte blob using the "length-delimited" wire type. Within
+ this blob, the individual values are encoded the same way they would
+ be normally except without a tag before each value (thus, they are
+ tightly "packed").
+
+ C++
+ * UnknownFieldSet now supports STL-like iteration.
+ * Message interface has method ParseFromBoundedZeroCopyStream() which parses
+ a limited number of bytes from an input stream rather than parsing until
+ EOF.
+
+ Java
+ * Fixed bug where Message.mergeFrom(Message) failed to merge extensions.
+ * Message interface has new method toBuilder() which is equivalent to
+ newBuilderForType().mergeFrom(this).
+ * All enums now implement the ProtocolMessageEnum interface.
+ * Setting a field to null now throws NullPointerException.
+ * Fixed tendency for TextFormat's parsing to overflow the stack when
+ parsing large string values. The underlying problem is with Java's
+ regex implementation (which unfortunately uses recursive backtracking
+ rather than building an NFA). Worked around by making use of possesive
+ quantifiers.
Python
* Added slicing support for repeated scalar fields. Added slice retrieval and
removal of repeated composite fields.
+ * Updated RPC interfaces to allow for blocking operation. A client may
+ now pass None for a callback when making an RPC, in which case the
+ call will block until the response is received, and the response
+ object will be returned directly to the caller. This interface change
+ cannot be used in practice until RPC implementations are updated to
+ implement it.
2008-11-25 version 2.0.3:
diff --git a/Makefile.am b/Makefile.am
index c3d40b1f..b4ceacd4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -45,6 +45,7 @@ EXTRA_DIST = \
java/src/main/java/com/google/protobuf/GeneratedMessage.java \
java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \
java/src/main/java/com/google/protobuf/Message.java \
+ java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java \
java/src/main/java/com/google/protobuf/RpcCallback.java \
java/src/main/java/com/google/protobuf/RpcChannel.java \
java/src/main/java/com/google/protobuf/RpcController.java \
diff --git a/java/src/main/java/com/google/protobuf/AbstractMessage.java b/java/src/main/java/com/google/protobuf/AbstractMessage.java
index 2f61859d..24c32a47 100644
--- a/java/src/main/java/com/google/protobuf/AbstractMessage.java
+++ b/java/src/main/java/com/google/protobuf/AbstractMessage.java
@@ -86,8 +86,25 @@ public abstract class AbstractMessage implements Message {
for (Map.Entry<FieldDescriptor, Object> entry : getAllFields().entrySet()) {
FieldDescriptor field = entry.getKey();
if (field.isRepeated()) {
- for (Object element : (List) entry.getValue()) {
- output.writeField(field.getType(), field.getNumber(), element);
+ List valueList = (List) entry.getValue();
+ if (field.getOptions().getPacked()) {
+
+ output.writeTag(field.getNumber(),
+ WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ int dataSize = 0;
+ for (Object element : valueList) {
+ dataSize += CodedOutputStream.computeFieldSizeNoTag(
+ field.getType(), element);
+ }
+ output.writeRawVarint32(dataSize);
+
+ for (Object element : valueList) {
+ output.writeFieldNoTag(field.getType(), element);
+ }
+ } else {
+ for (Object element : valueList) {
+ output.writeField(field.getType(), field.getNumber(), element);
+ }
}
} else {
output.writeField(field.getType(), field.getNumber(), entry.getValue());
@@ -145,9 +162,21 @@ public abstract class AbstractMessage implements Message {
for (Map.Entry<FieldDescriptor, Object> entry : getAllFields().entrySet()) {
FieldDescriptor field = entry.getKey();
if (field.isRepeated()) {
- for (Object element : (List) entry.getValue()) {
- size += CodedOutputStream.computeFieldSize(
- field.getType(), field.getNumber(), element);
+ List valueList = (List) entry.getValue();
+ if (field.getOptions().getPacked()) {
+ int dataSize = 0;
+ for (Object element : valueList) {
+ dataSize += CodedOutputStream.computeFieldSizeNoTag(
+ field.getType(), element);
+ }
+ size += dataSize;
+ size += CodedOutputStream.computeTagSize(field.getNumber());
+ size += CodedOutputStream.computeRawVarint32Size(dataSize);
+ } else {
+ for (Object element : valueList) {
+ size += CodedOutputStream.computeFieldSize(
+ field.getType(), field.getNumber(), element);
+ }
}
} else {
size += CodedOutputStream.computeFieldSize(
@@ -165,7 +194,7 @@ public abstract class AbstractMessage implements Message {
memoizedSize = size;
return size;
}
-
+
@Override
public boolean equals(Object other) {
if (other == this) {
@@ -180,7 +209,7 @@ public abstract class AbstractMessage implements Message {
}
return getAllFields().equals(otherMessage.getAllFields());
}
-
+
@Override
public int hashCode() {
int hash = 41;
diff --git a/java/src/main/java/com/google/protobuf/CodedInputStream.java b/java/src/main/java/com/google/protobuf/CodedInputStream.java
index caef068b..8f277a9f 100644
--- a/java/src/main/java/com/google/protobuf/CodedInputStream.java
+++ b/java/src/main/java/com/google/protobuf/CodedInputStream.java
@@ -193,7 +193,7 @@ public final class CodedInputStream {
/** Read a {@code string} field value from the stream. */
public String readString() throws IOException {
int size = readRawVarint32();
- if (size < bufferSize - bufferPos && size > 0) {
+ if (size <= (bufferSize - bufferPos) && size > 0) {
// Fast path: We already have the bytes in a contiguous buffer, so
// just copy directly from it.
String result = new String(buffer, bufferPos, size, "UTF-8");
@@ -584,6 +584,19 @@ public final class CodedInputStream {
}
/**
+ * Returns the number of bytes to be read before the current limit.
+ * If no limit is set, returns -1.
+ */
+ public int getBytesUntilLimit() {
+ if (currentLimit == Integer.MAX_VALUE) {
+ return -1;
+ }
+
+ int currentAbsolutePosition = totalBytesRetired + bufferPos;
+ return currentLimit - currentAbsolutePosition;
+ }
+
+ /**
* Called with {@code this.buffer} is empty to read more bytes from the
* input. If {@code mustSucceed} is true, refillBuffer() gurantees that
* either there will be at least one byte in the buffer when it returns
diff --git a/java/src/main/java/com/google/protobuf/CodedOutputStream.java b/java/src/main/java/com/google/protobuf/CodedOutputStream.java
index d232841a..e8be8611 100644
--- a/java/src/main/java/com/google/protobuf/CodedOutputStream.java
+++ b/java/src/main/java/com/google/protobuf/CodedOutputStream.java
@@ -118,71 +118,61 @@ public final class CodedOutputStream {
/** Write a {@code double} field, including tag, to the stream. */
public void writeDouble(int fieldNumber, double value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
- writeRawLittleEndian64(Double.doubleToRawLongBits(value));
+ writeDoubleNoTag(value);
}
/** Write a {@code float} field, including tag, to the stream. */
public void writeFloat(int fieldNumber, float value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
- writeRawLittleEndian32(Float.floatToRawIntBits(value));
+ writeFloatNoTag(value);
}
/** Write a {@code uint64} field, including tag, to the stream. */
public void writeUInt64(int fieldNumber, long value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeRawVarint64(value);
+ writeUInt64NoTag(value);
}
/** Write an {@code int64} field, including tag, to the stream. */
public void writeInt64(int fieldNumber, long value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeRawVarint64(value);
+ writeInt64NoTag(value);
}
/** Write an {@code int32} field, including tag, to the stream. */
public void writeInt32(int fieldNumber, int value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- if (value >= 0) {
- writeRawVarint32(value);
- } else {
- // Must sign-extend.
- writeRawVarint64(value);
- }
+ writeInt32NoTag(value);
}
/** Write a {@code fixed64} field, including tag, to the stream. */
public void writeFixed64(int fieldNumber, long value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
- writeRawLittleEndian64(value);
+ writeFixed64NoTag(value);
}
/** Write a {@code fixed32} field, including tag, to the stream. */
public void writeFixed32(int fieldNumber, int value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
- writeRawLittleEndian32(value);
+ writeFixed32NoTag(value);
}
/** Write a {@code bool} field, including tag, to the stream. */
public void writeBool(int fieldNumber, boolean value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeRawByte(value ? 1 : 0);
+ writeBoolNoTag(value);
}
/** Write a {@code string} field, including tag, to the stream. */
public void writeString(int fieldNumber, String value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- // 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.
- byte[] bytes = value.getBytes("UTF-8");
- writeRawVarint32(bytes.length);
- writeRawBytes(bytes);
+ writeStringNoTag(value);
}
/** Write a {@code group} field, including tag, to the stream. */
public void writeGroup(int fieldNumber, Message value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
- value.writeTo(this);
+ writeGroupNoTag(value);
writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
}
@@ -190,29 +180,26 @@ public final class CodedOutputStream {
public void writeUnknownGroup(int fieldNumber, UnknownFieldSet value)
throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
- value.writeTo(this);
+ writeUnknownGroupNoTag(value);
writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
}
/** Write an embedded message field, including tag, to the stream. */
public void writeMessage(int fieldNumber, Message value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- writeRawVarint32(value.getSerializedSize());
- value.writeTo(this);
+ writeMessageNoTag(value);
}
/** Write a {@code bytes} field, including tag, to the stream. */
public void writeBytes(int fieldNumber, ByteString value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- byte[] bytes = value.toByteArray();
- writeRawVarint32(bytes.length);
- writeRawBytes(bytes);
+ writeBytesNoTag(value);
}
/** Write a {@code uint32} field, including tag, to the stream. */
public void writeUInt32(int fieldNumber, int value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeRawVarint32(value);
+ writeUInt32NoTag(value);
}
/**
@@ -221,31 +208,31 @@ public final class CodedOutputStream {
*/
public void writeEnum(int fieldNumber, int value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeRawVarint32(value);
+ writeEnumNoTag(value);
}
/** Write an {@code sfixed32} field, including tag, to the stream. */
public void writeSFixed32(int fieldNumber, int value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
- writeRawLittleEndian32(value);
+ writeSFixed32NoTag(value);
}
/** Write an {@code sfixed64} field, including tag, to the stream. */
public void writeSFixed64(int fieldNumber, long value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
- writeRawLittleEndian64(value);
+ writeSFixed64NoTag(value);
}
/** Write an {@code sint32} field, including tag, to the stream. */
public void writeSInt32(int fieldNumber, int value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeRawVarint32(encodeZigZag32(value));
+ writeSInt32NoTag(value);
}
/** Write an {@code sint64} field, including tag, to the stream. */
public void writeSInt64(int fieldNumber, long value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeRawVarint64(encodeZigZag64(value));
+ writeSInt64NoTag(value);
}
/**
@@ -283,32 +270,168 @@ public final class CodedOutputStream {
* this field.
*/
public void writeField(Descriptors.FieldDescriptor.Type type,
- int number, Object value) throws IOException {
+ int number,
+ Object value) throws IOException {
+ // Special case for groups, which need a start and end tag; other fields
+ // can just use writeTag() and writeFieldNoTag().
+ if (type == Descriptors.FieldDescriptor.Type.GROUP) {
+ writeGroup(number, (Message) value);
+ } else {
+ writeTag(number, WireFormat.getWireFormatForFieldType(type));
+ writeFieldNoTag(type, value);
+ }
+ }
+
+ /**
+ * Write a field of arbitrary type, without its tag, to the stream.
+ *
+ * @param type The field's type.
+ * @param value Object representing the field's value. Must be of the exact
+ * type which would be returned by
+ * {@link Message#getField(Descriptors.FieldDescriptor)} for
+ * this field.
+ */
+ public void writeFieldNoTag(Descriptors.FieldDescriptor.Type type,
+ Object value) throws IOException {
switch (type) {
- case DOUBLE : writeDouble (number, (Double )value); break;
- case FLOAT : writeFloat (number, (Float )value); break;
- case INT64 : writeInt64 (number, (Long )value); break;
- case UINT64 : writeUInt64 (number, (Long )value); break;
- case INT32 : writeInt32 (number, (Integer )value); break;
- case FIXED64 : writeFixed64 (number, (Long )value); break;
- case FIXED32 : writeFixed32 (number, (Integer )value); break;
- case BOOL : writeBool (number, (Boolean )value); break;
- case STRING : writeString (number, (String )value); break;
- case GROUP : writeGroup (number, (Message )value); break;
- case MESSAGE : writeMessage (number, (Message )value); break;
- case BYTES : writeBytes (number, (ByteString)value); break;
- case UINT32 : writeUInt32 (number, (Integer )value); break;
- case SFIXED32: writeSFixed32(number, (Integer )value); break;
- case SFIXED64: writeSFixed64(number, (Long )value); break;
- case SINT32 : writeSInt32 (number, (Integer )value); break;
- case SINT64 : writeSInt64 (number, (Long )value); break;
+ case DOUBLE : writeDoubleNoTag ((Double ) value); break;
+ case FLOAT : writeFloatNoTag ((Float ) value); break;
+ case INT64 : writeInt64NoTag ((Long ) value); break;
+ case UINT64 : writeUInt64NoTag ((Long ) value); break;
+ case INT32 : writeInt32NoTag ((Integer ) value); break;
+ case FIXED64 : writeFixed64NoTag ((Long ) value); break;
+ case FIXED32 : writeFixed32NoTag ((Integer ) value); break;
+ case BOOL : writeBoolNoTag ((Boolean ) value); break;
+ case STRING : writeStringNoTag ((String ) value); break;
+ case GROUP : writeGroupNoTag ((Message ) value); break;
+ case MESSAGE : writeMessageNoTag ((Message ) value); break;
+ case BYTES : writeBytesNoTag ((ByteString) value); break;
+ case UINT32 : writeUInt32NoTag ((Integer ) value); break;
+ case SFIXED32: writeSFixed32NoTag((Integer ) value); break;
+ case SFIXED64: writeSFixed64NoTag((Long ) value); break;
+ case SINT32 : writeSInt32NoTag ((Integer ) value); break;
+ case SINT64 : writeSInt64NoTag ((Long ) value); break;
case ENUM:
- writeEnum(number, ((Descriptors.EnumValueDescriptor)value).getNumber());
+ writeEnumNoTag(((Descriptors.EnumValueDescriptor) value).getNumber());
break;
}
}
+ // -----------------------------------------------------------------
+
+ /** Write a {@code double} field to the stream. */
+ public void writeDoubleNoTag(double value) throws IOException {
+ writeRawLittleEndian64(Double.doubleToRawLongBits(value));
+ }
+
+ /** Write a {@code float} field to the stream. */
+ public void writeFloatNoTag(float value) throws IOException {
+ writeRawLittleEndian32(Float.floatToRawIntBits(value));
+ }
+
+ /** Write a {@code uint64} field to the stream. */
+ public void writeUInt64NoTag(long value) throws IOException {
+ writeRawVarint64(value);
+ }
+
+ /** Write an {@code int64} field to the stream. */
+ public void writeInt64NoTag(long value) throws IOException {
+ writeRawVarint64(value);
+ }
+
+ /** Write an {@code int32} field to the stream. */
+ public void writeInt32NoTag(int value) throws IOException {
+ if (value >= 0) {
+ writeRawVarint32(value);
+ } else {
+ // Must sign-extend.
+ writeRawVarint64(value);
+ }
+ }
+
+ /** Write a {@code fixed64} field to the stream. */
+ public void writeFixed64NoTag(long value) throws IOException {
+ writeRawLittleEndian64(value);
+ }
+
+ /** Write a {@code fixed32} field to the stream. */
+ public void writeFixed32NoTag(int value) throws IOException {
+ writeRawLittleEndian32(value);
+ }
+
+ /** Write a {@code bool} field to the stream. */
+ public void writeBoolNoTag(boolean value) throws IOException {
+ writeRawByte(value ? 1 : 0);
+ }
+
+ /** Write a {@code string} field to the stream. */
+ public void writeStringNoTag(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.
+ byte[] bytes = value.getBytes("UTF-8");
+ writeRawVarint32(bytes.length);
+ writeRawBytes(bytes);
+ }
+
+ /** Write a {@code group} field to the stream. */
+ public void writeGroupNoTag(Message value) throws IOException {
+ value.writeTo(this);
+ }
+
+ /** Write a group represented by an {@link UnknownFieldSet}. */
+ public void writeUnknownGroupNoTag(UnknownFieldSet value)
+ throws IOException {
+ value.writeTo(this);
+ }
+
+ /** Write an embedded message field to the stream. */
+ public void writeMessageNoTag(Message value) throws IOException {
+ writeRawVarint32(value.getSerializedSize());
+ value.writeTo(this);
+ }
+
+ /** Write a {@code bytes} field to the stream. */
+ public void writeBytesNoTag(ByteString value) throws IOException {
+ byte[] bytes = value.toByteArray();
+ writeRawVarint32(bytes.length);
+ writeRawBytes(bytes);
+ }
+
+ /** Write a {@code uint32} field to the stream. */
+ public void writeUInt32NoTag(int value) throws IOException {
+ writeRawVarint32(value);
+ }
+
+ /**
+ * Write an enum field to the stream. Caller is responsible
+ * for converting the enum value to its numeric value.
+ */
+ public void writeEnumNoTag(int value) throws IOException {
+ writeRawVarint32(value);
+ }
+
+ /** Write an {@code sfixed32} field to the stream. */
+ public void writeSFixed32NoTag(int value) throws IOException {
+ writeRawLittleEndian32(value);
+ }
+
+ /** Write an {@code sfixed64} field to the stream. */
+ public void writeSFixed64NoTag(long value) throws IOException {
+ writeRawLittleEndian64(value);
+ }
+
+ /** Write an {@code sint32} field to the stream. */
+ public void writeSInt32NoTag(int value) throws IOException {
+ writeRawVarint32(encodeZigZag32(value));
+ }
+
+ /** Write an {@code sint64} field to the stream. */
+ public void writeSInt64NoTag(long value) throws IOException {
+ writeRawVarint64(encodeZigZag64(value));
+ }
+
// =================================================================
/**
@@ -316,7 +439,7 @@ public final class CodedOutputStream {
* {@code double} field, including tag.
*/
public static int computeDoubleSize(int fieldNumber, double value) {
- return computeTagSize(fieldNumber) + LITTLE_ENDIAN_64_SIZE;
+ return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
}
/**
@@ -324,7 +447,7 @@ public final class CodedOutputStream {
* {@code float} field, including tag.
*/
public static int computeFloatSize(int fieldNumber, float value) {
- return computeTagSize(fieldNumber) + LITTLE_ENDIAN_32_SIZE;
+ return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
}
/**
@@ -332,7 +455,7 @@ public final class CodedOutputStream {
* {@code uint64} field, including tag.
*/
public static int computeUInt64Size(int fieldNumber, long value) {
- return computeTagSize(fieldNumber) + computeRawVarint64Size(value);
+ return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
}
/**
@@ -340,7 +463,7 @@ public final class CodedOutputStream {
* {@code int64} field, including tag.
*/
public static int computeInt64Size(int fieldNumber, long value) {
- return computeTagSize(fieldNumber) + computeRawVarint64Size(value);
+ return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
}
/**
@@ -348,12 +471,7 @@ public final class CodedOutputStream {
* {@code int32} field, including tag.
*/
public static int computeInt32Size(int fieldNumber, int value) {
- if (value >= 0) {
- return computeTagSize(fieldNumber) + computeRawVarint32Size(value);
- } else {
- // Must sign-extend.
- return computeTagSize(fieldNumber) + 10;
- }
+ return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
}
/**
@@ -361,7 +479,7 @@ public final class CodedOutputStream {
* {@code fixed64} field, including tag.
*/
public static int computeFixed64Size(int fieldNumber, long value) {
- return computeTagSize(fieldNumber) + LITTLE_ENDIAN_64_SIZE;
+ return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
}
/**
@@ -369,7 +487,7 @@ public final class CodedOutputStream {
* {@code fixed32} field, including tag.
*/
public static int computeFixed32Size(int fieldNumber, int value) {
- return computeTagSize(fieldNumber) + LITTLE_ENDIAN_32_SIZE;
+ return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
}
/**
@@ -377,7 +495,7 @@ public final class CodedOutputStream {
* {@code bool} field, including tag.
*/
public static int computeBoolSize(int fieldNumber, boolean value) {
- return computeTagSize(fieldNumber) + 1;
+ return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
}
/**
@@ -385,14 +503,7 @@ public final class CodedOutputStream {
* {@code string} field, including tag.
*/
public static int computeStringSize(int fieldNumber, String value) {
- try {
- byte[] bytes = value.getBytes("UTF-8");
- return computeTagSize(fieldNumber) +
- computeRawVarint32Size(bytes.length) +
- bytes.length;
- } catch (java.io.UnsupportedEncodingException e) {
- throw new RuntimeException("UTF-8 not supported.", e);
- }
+ return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
}
/**
@@ -400,7 +511,7 @@ public final class CodedOutputStream {
* {@code group} field, including tag.
*/
public static int computeGroupSize(int fieldNumber, Message value) {
- return computeTagSize(fieldNumber) * 2 + value.getSerializedSize();
+ return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
}
/**
@@ -410,7 +521,8 @@ public final class CodedOutputStream {
*/
public static int computeUnknownGroupSize(int fieldNumber,
UnknownFieldSet value) {
- return computeTagSize(fieldNumber) * 2 + value.getSerializedSize();
+ return computeTagSize(fieldNumber) * 2 +
+ computeUnknownGroupSizeNoTag(value);
}
/**
@@ -418,8 +530,7 @@ public final class CodedOutputStream {
* embedded message field, including tag.
*/
public static int computeMessageSize(int fieldNumber, Message value) {
- int size = value.getSerializedSize();
- return computeTagSize(fieldNumber) + computeRawVarint32Size(size) + size;
+ return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
}
/**
@@ -427,9 +538,7 @@ public final class CodedOutputStream {
* {@code bytes} field, including tag.
*/
public static int computeBytesSize(int fieldNumber, ByteString value) {
- return computeTagSize(fieldNumber) +
- computeRawVarint32Size(value.size()) +
- value.size();
+ return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
}
/**
@@ -437,7 +546,7 @@ public final class CodedOutputStream {
* {@code uint32} field, including tag.
*/
public static int computeUInt32Size(int fieldNumber, int value) {
- return computeTagSize(fieldNumber) + computeRawVarint32Size(value);
+ return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
}
/**
@@ -446,7 +555,7 @@ public final class CodedOutputStream {
* enum value to its numeric value.
*/
public static int computeEnumSize(int fieldNumber, int value) {
- return computeTagSize(fieldNumber) + computeRawVarint32Size(value);
+ return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
}
/**
@@ -454,7 +563,7 @@ public final class CodedOutputStream {
* {@code sfixed32} field, including tag.
*/
public static int computeSFixed32Size(int fieldNumber, int value) {
- return computeTagSize(fieldNumber) + LITTLE_ENDIAN_32_SIZE;
+ return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
}
/**
@@ -462,7 +571,7 @@ public final class CodedOutputStream {
* {@code sfixed64} field, including tag.
*/
public static int computeSFixed64Size(int fieldNumber, long value) {
- return computeTagSize(fieldNumber) + LITTLE_ENDIAN_64_SIZE;
+ return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
}
/**
@@ -470,8 +579,7 @@ public final class CodedOutputStream {
* {@code sint32} field, including tag.
*/
public static int computeSInt32Size(int fieldNumber, int value) {
- return computeTagSize(fieldNumber) +
- computeRawVarint32Size(encodeZigZag32(value));
+ return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
}
/**
@@ -479,8 +587,7 @@ public final class CodedOutputStream {
* {@code sint64} field, including tag.
*/
public static int computeSInt64Size(int fieldNumber, long value) {
- return computeTagSize(fieldNumber) +
- computeRawVarint64Size(encodeZigZag64(value));
+ return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
}
/**
@@ -507,6 +614,174 @@ public final class CodedOutputStream {
computeBytesSize(WireFormat.MESSAGE_SET_MESSAGE, value);
}
+ // -----------------------------------------------------------------
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code double} field, including tag.
+ */
+ public static int computeDoubleSizeNoTag(double value) {
+ return LITTLE_ENDIAN_64_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code float} field, including tag.
+ */
+ public static int computeFloatSizeNoTag(float value) {
+ return LITTLE_ENDIAN_32_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code uint64} field, including tag.
+ */
+ public static int computeUInt64SizeNoTag(long value) {
+ return computeRawVarint64Size(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code int64} field, including tag.
+ */
+ public static int computeInt64SizeNoTag(long value) {
+ return computeRawVarint64Size(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code int32} field, including tag.
+ */
+ public static int computeInt32SizeNoTag(int value) {
+ if (value >= 0) {
+ return computeRawVarint32Size(value);
+ } else {
+ // Must sign-extend.
+ return 10;
+ }
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code fixed64} field.
+ */
+ public static int computeFixed64SizeNoTag(long value) {
+ return LITTLE_ENDIAN_64_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code fixed32} field.
+ */
+ public static int computeFixed32SizeNoTag(int value) {
+ return LITTLE_ENDIAN_32_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bool} field.
+ */
+ public static int computeBoolSizeNoTag(boolean value) {
+ return 1;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code string} field.
+ */
+ public static int computeStringSizeNoTag(String value) {
+ try {
+ byte[] bytes = value.getBytes("UTF-8");
+ return computeRawVarint32Size(bytes.length) +
+ bytes.length;
+ } catch (java.io.UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not supported.", e);
+ }
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code group} field.
+ */
+ public static int computeGroupSizeNoTag(Message value) {
+ return value.getSerializedSize();
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code group} field represented by an {@code UnknownFieldSet}, including
+ * tag.
+ */
+ public static int computeUnknownGroupSizeNoTag(UnknownFieldSet value) {
+ return value.getSerializedSize();
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an embedded
+ * message field.
+ */
+ public static int computeMessageSizeNoTag(Message value) {
+ int size = value.getSerializedSize();
+ return computeRawVarint32Size(size) + size;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bytes} field.
+ */
+ public static int computeBytesSizeNoTag(ByteString value) {
+ return computeRawVarint32Size(value.size()) +
+ value.size();
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code uint32} field.
+ */
+ public static int computeUInt32SizeNoTag(int value) {
+ return computeRawVarint32Size(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an enum field.
+ * Caller is responsible for converting the enum value to its numeric value.
+ */
+ public static int computeEnumSizeNoTag(int value) {
+ return computeRawVarint32Size(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sfixed32} field.
+ */
+ public static int computeSFixed32SizeNoTag(int value) {
+ return LITTLE_ENDIAN_32_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sfixed64} field.
+ */
+ public static int computeSFixed64SizeNoTag(long value) {
+ return LITTLE_ENDIAN_64_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sint32} field.
+ */
+ public static int computeSInt32SizeNoTag(int value) {
+ return computeRawVarint32Size(encodeZigZag32(value));
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sint64} field.
+ */
+ public static int computeSInt64SizeNoTag(long value) {
+ return computeRawVarint64Size(encodeZigZag64(value));
+ }
+
/**
* Compute the number of bytes that would be needed to encode a
* field of arbitrary type, including tag, to the stream.
@@ -521,28 +796,48 @@ public final class CodedOutputStream {
public static int computeFieldSize(
Descriptors.FieldDescriptor.Type type,
int number, Object value) {
+ int tagSize = computeTagSize(number);
+ if (type == Descriptors.FieldDescriptor.Type.GROUP) {
+ tagSize *= 2;
+ }
+ return tagSize + computeFieldSizeNoTag(type, value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * field of arbitrary type, excluding tag, to the stream.
+ *
+ * @param type The field's type.
+ * @param number The field's number.
+ * @param value Object representing the field's value. Must be of the exact
+ * type which would be returned by
+ * {@link Message#getField(Descriptors.FieldDescriptor)} for
+ * this field.
+ */
+ public static int computeFieldSizeNoTag(
+ Descriptors.FieldDescriptor.Type type, Object value) {
switch (type) {
- case DOUBLE : return computeDoubleSize (number, (Double )value);
- case FLOAT : return computeFloatSize (number, (Float )value);
- case INT64 : return computeInt64Size (number, (Long )value);
- case UINT64 : return computeUInt64Size (number, (Long )value);
- case INT32 : return computeInt32Size (number, (Integer )value);
- case FIXED64 : return computeFixed64Size (number, (Long )value);
- case FIXED32 : return computeFixed32Size (number, (Integer )value);
- case BOOL : return computeBoolSize (number, (Boolean )value);
- case STRING : return computeStringSize (number, (String )value);
- case GROUP : return computeGroupSize (number, (Message )value);
- case MESSAGE : return computeMessageSize (number, (Message )value);
- case BYTES : return computeBytesSize (number, (ByteString)value);
- case UINT32 : return computeUInt32Size (number, (Integer )value);
- case SFIXED32: return computeSFixed32Size(number, (Integer )value);
- case SFIXED64: return computeSFixed64Size(number, (Long )value);
- case SINT32 : return computeSInt32Size (number, (Integer )value);
- case SINT64 : return computeSInt64Size (number, (Long )value);
+ case DOUBLE : return computeDoubleSizeNoTag ((Double )value);
+ case FLOAT : return computeFloatSizeNoTag ((Float )value);
+ case INT64 : return computeInt64SizeNoTag ((Long )value);
+ case UINT64 : return computeUInt64SizeNoTag ((Long )value);
+ case INT32 : return computeInt32SizeNoTag ((Integer )value);
+ case FIXED64 : return computeFixed64SizeNoTag ((Long )value);
+ case FIXED32 : return computeFixed32SizeNoTag ((Integer )value);
+ case BOOL : return computeBoolSizeNoTag ((Boolean )value);
+ case STRING : return computeStringSizeNoTag ((String )value);
+ case GROUP : return computeGroupSizeNoTag ((Message )value);
+ case MESSAGE : return computeMessageSizeNoTag ((Message )value);
+ case BYTES : return computeBytesSizeNoTag ((ByteString)value);
+ case UINT32 : return computeUInt32SizeNoTag ((Integer )value);
+ case SFIXED32: return computeSFixed32SizeNoTag((Integer )value);
+ case SFIXED64: return computeSFixed64SizeNoTag((Long )value);
+ case SINT32 : return computeSInt32SizeNoTag ((Integer )value);
+ case SINT64 : return computeSInt64SizeNoTag ((Long )value);
case ENUM:
- return computeEnumSize(number,
- ((Descriptors.EnumValueDescriptor)value).getNumber());
+ return computeEnumSizeNoTag(
+ ((Descriptors.EnumValueDescriptor)value).getNumber());
}
throw new RuntimeException(
diff --git a/java/src/main/java/com/google/protobuf/Descriptors.java b/java/src/main/java/com/google/protobuf/Descriptors.java
index ee4d4e3a..80266a59 100644
--- a/java/src/main/java/com/google/protobuf/Descriptors.java
+++ b/java/src/main/java/com/google/protobuf/Descriptors.java
@@ -857,6 +857,19 @@ public final class Descriptors {
"Field numbers must be positive integers.");
}
+ // Only repeated primitive fields may be packed.
+ if (proto.getOptions().getPacked()) {
+ if (proto.getLabel() != FieldDescriptorProto.Label.LABEL_REPEATED ||
+ proto.getType() == FieldDescriptorProto.Type.TYPE_STRING ||
+ proto.getType() == FieldDescriptorProto.Type.TYPE_GROUP ||
+ proto.getType() == FieldDescriptorProto.Type.TYPE_MESSAGE ||
+ proto.getType() == FieldDescriptorProto.Type.TYPE_BYTES) {
+ throw new DescriptorValidationException(this,
+ "[packed = true] can only be specified for repeated primitive " +
+ "fields.");
+ }
+ }
+
if (isExtension) {
if (!proto.hasExtendee()) {
throw new DescriptorValidationException(this,
diff --git a/java/src/main/java/com/google/protobuf/DynamicMessage.java b/java/src/main/java/com/google/protobuf/DynamicMessage.java
index fefa23ec..99ae253c 100644
--- a/java/src/main/java/com/google/protobuf/DynamicMessage.java
+++ b/java/src/main/java/com/google/protobuf/DynamicMessage.java
@@ -211,6 +211,10 @@ public final class DynamicMessage extends AbstractMessage {
return new Builder(type);
}
+ public Builder toBuilder() {
+ return newBuilderForType().mergeFrom(this);
+ }
+
/** Verifies that the field is a field of this message. */
private void verifyContainingType(FieldDescriptor field) {
if (field.getContainingType() != type) {
@@ -251,6 +255,7 @@ public final class DynamicMessage extends AbstractMessage {
}
fields.mergeFrom(other);
+ mergeUnknownFields(other.getUnknownFields());
return this;
}
diff --git a/java/src/main/java/com/google/protobuf/FieldSet.java b/java/src/main/java/com/google/protobuf/FieldSet.java
index 98a1c328..01da3faf 100644
--- a/java/src/main/java/com/google/protobuf/FieldSet.java
+++ b/java/src/main/java/com/google/protobuf/FieldSet.java
@@ -351,8 +351,7 @@ final class FieldSet {
setField(field, entry.getValue());
} else {
setField(field,
- existingValue.newBuilderForType()
- .mergeFrom(existingValue)
+ existingValue.toBuilder()
.mergeFrom((Message)entry.getValue())
.build());
}
@@ -384,8 +383,7 @@ final class FieldSet {
setField(field, value);
} else {
setField(field,
- existingValue.newBuilderForType()
- .mergeFrom(existingValue)
+ existingValue.toBuilder()
.mergeFrom((Message)value)
.build());
}
@@ -463,60 +461,83 @@ final class FieldSet {
}
if (field == null ||
- wireType != WireFormat.getWireFormatForFieldType(field.getType())) {
+ wireType != WireFormat.getWireFormatForField(field)) {
// Unknown field or wrong wire type. Skip.
return unknownFields.mergeFieldFrom(tag, input);
} else {
- Object value;
- switch (field.getType()) {
- case GROUP: {
- Message.Builder subBuilder;
- if (defaultInstance != null) {
- subBuilder = defaultInstance.newBuilderForType();
- } else {
- subBuilder = builder.newBuilderForField(field);
+ if (field.getOptions().getPacked()) {
+ int length = input.readRawVarint32();
+ int limit = input.pushLimit(length);
+ if (field.getType() == FieldDescriptor.Type.ENUM) {
+ while (input.getBytesUntilLimit() > 0) {
+ int rawValue = input.readEnum();
+ Object value = field.getEnumType().findValueByNumber(rawValue);
+ if (value == null) {
+ // If the number isn't recognized as a valid value for this
+ // enum, drop it (don't even add it to unknownFields).
+ return true;
+ }
+ builder.addRepeatedField(field, value);
}
- if (!field.isRepeated()) {
- subBuilder.mergeFrom((Message) builder.getField(field));
+ } else {
+ while (input.getBytesUntilLimit() > 0) {
+ Object value = input.readPrimitiveField(field.getType());
+ builder.addRepeatedField(field, value);
}
- input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
- value = subBuilder.build();
- break;
}
- case MESSAGE: {
- Message.Builder subBuilder;
- if (defaultInstance != null) {
- subBuilder = defaultInstance.newBuilderForType();
- } else {
- subBuilder = builder.newBuilderForField(field);
+ input.popLimit(limit);
+ } else {
+ Object value;
+ switch (field.getType()) {
+ case GROUP: {
+ Message.Builder subBuilder;
+ if (defaultInstance != null) {
+ subBuilder = defaultInstance.newBuilderForType();
+ } else {
+ subBuilder = builder.newBuilderForField(field);
+ }
+ if (!field.isRepeated()) {
+ subBuilder.mergeFrom((Message) builder.getField(field));
+ }
+ input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
+ value = subBuilder.build();
+ break;
}
- if (!field.isRepeated()) {
- subBuilder.mergeFrom((Message) builder.getField(field));
+ case MESSAGE: {
+ Message.Builder subBuilder;
+ if (defaultInstance != null) {
+ subBuilder = defaultInstance.newBuilderForType();
+ } else {
+ subBuilder = builder.newBuilderForField(field);
+ }
+ if (!field.isRepeated()) {
+ subBuilder.mergeFrom((Message) builder.getField(field));
+ }
+ input.readMessage(subBuilder, extensionRegistry);
+ value = subBuilder.build();
+ break;
}
- input.readMessage(subBuilder, extensionRegistry);
- value = subBuilder.build();
- break;
- }
- case ENUM: {
- int rawValue = input.readEnum();
- value = field.getEnumType().findValueByNumber(rawValue);
- // If the number isn't recognized as a valid value for this enum,
- // drop it.
- if (value == null) {
- unknownFields.mergeVarintField(fieldNumber, rawValue);
- return true;
+ case ENUM: {
+ int rawValue = input.readEnum();
+ value = field.getEnumType().findValueByNumber(rawValue);
+ // If the number isn't recognized as a valid value for this enum,
+ // drop it.
+ if (value == null) {
+ unknownFields.mergeVarintField(fieldNumber, rawValue);
+ return true;
+ }
+ break;
}
- break;
+ default:
+ value = input.readPrimitiveField(field.getType());
+ break;
}
- default:
- value = input.readPrimitiveField(field.getType());
- break;
- }
- if (field.isRepeated()) {
- builder.addRepeatedField(field, value);
- } else {
- builder.setField(field, value);
+ if (field.isRepeated()) {
+ builder.addRepeatedField(field, value);
+ } else {
+ builder.setField(field, value);
+ }
}
}
@@ -636,8 +657,24 @@ final class FieldSet {
output.writeMessageSetExtension(field.getNumber(), (Message)value);
} else {
if (field.isRepeated()) {
- for (Object element : (List)value) {
- output.writeField(field.getType(), field.getNumber(), element);
+ List valueList = (List)value;
+ if (field.getOptions().getPacked()) {
+ output.writeTag(field.getNumber(),
+ WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ // Compute the total data size so the length can be written.
+ int dataSize = 0;
+ for (Object element : valueList) {
+ dataSize += output.computeFieldSizeNoTag(field.getType(), element);
+ }
+ output.writeRawVarint32(dataSize);
+ // Write the data itself, without any tags.
+ for (Object element : valueList) {
+ output.writeFieldNoTag(field.getType(), element);
+ }
+ } else {
+ for (Object element : valueList) {
+ output.writeField(field.getType(), field.getNumber(), element);
+ }
}
} else {
output.writeField(field.getType(), field.getNumber(), value);
@@ -658,12 +695,23 @@ final class FieldSet {
if (field.isExtension() &&
field.getContainingType().getOptions().getMessageSetWireFormat()) {
size += CodedOutputStream.computeMessageSetExtensionSize(
- field.getNumber(), (Message)value);
+ field.getNumber(), (Message) value);
} else {
if (field.isRepeated()) {
- for (Object element : (List)value) {
- size += CodedOutputStream.computeFieldSize(
- field.getType(), field.getNumber(), element);
+ if (field.getOptions().getPacked()) {
+ int dataSize = 0;
+ for (Object element : (List)value) {
+ dataSize += CodedOutputStream.computeFieldSizeNoTag(
+ field.getType(), element);
+ }
+ size += dataSize +
+ CodedOutputStream.computeTagSize(field.getNumber()) +
+ CodedOutputStream.computeRawVarint32Size(dataSize);
+ } else {
+ for (Object element : (List)value) {
+ size += CodedOutputStream.computeFieldSize(
+ field.getType(), field.getNumber(), element);
+ }
}
} else {
size += CodedOutputStream.computeFieldSize(
diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/src/main/java/com/google/protobuf/GeneratedMessage.java
index b1be8b14..77c88c30 100644
--- a/java/src/main/java/com/google/protobuf/GeneratedMessage.java
+++ b/java/src/main/java/com/google/protobuf/GeneratedMessage.java
@@ -31,8 +31,8 @@
package com.google.protobuf;
import com.google.protobuf.Descriptors.Descriptor;
-import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
import java.io.IOException;
import java.lang.reflect.Method;
@@ -75,7 +75,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
for (FieldDescriptor field : descriptor.getFields()) {
if (field.isRepeated()) {
- List value = (List)getField(field);
+ List value = (List) getField(field);
if (!value.isEmpty()) {
result.put(field, value);
}
@@ -87,7 +87,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
}
return result;
}
-
+
public boolean isInitialized() {
for (FieldDescriptor field : getDescriptorForType().getFields()) {
// Check that all required fields are present.
@@ -99,7 +99,9 @@ public abstract class GeneratedMessage extends AbstractMessage {
// Check that embedded messages are initialized.
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
if (field.isRepeated()) {
- for (Message element : (List<Message>) getField(field)) {
+ @SuppressWarnings("unchecked")
+ List<Message> messageList = (List<Message>) getField(field);
+ for (Message element : messageList) {
if (!element.isInitialized()) {
return false;
}
@@ -189,7 +191,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
setField(field, entry.getValue());
}
}
- return (BuilderType)this;
+ return (BuilderType) this;
}
public Descriptor getDescriptorForType() {
@@ -214,7 +216,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
// The underlying list object is still modifiable at this point.
// Make sure not to expose the modifiable list to the caller.
return Collections.unmodifiableList(
- (List)internalGetResult().getField(field));
+ (List) internalGetResult().getField(field));
} else {
return internalGetResult().getField(field);
}
@@ -223,12 +225,12 @@ public abstract class GeneratedMessage extends AbstractMessage {
public BuilderType setField(Descriptors.FieldDescriptor field,
Object value) {
internalGetFieldAccessorTable().getField(field).set(this, value);
- return (BuilderType)this;
+ return (BuilderType) this;
}
public BuilderType clearField(Descriptors.FieldDescriptor field) {
internalGetFieldAccessorTable().getField(field).clear(this);
- return (BuilderType)this;
+ return (BuilderType) this;
}
public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
@@ -244,13 +246,13 @@ public abstract class GeneratedMessage extends AbstractMessage {
int index, Object value) {
internalGetFieldAccessorTable().getField(field)
.setRepeated(this, index, value);
- return (BuilderType)this;
+ return (BuilderType) this;
}
public BuilderType addRepeatedField(Descriptors.FieldDescriptor field,
Object value) {
internalGetFieldAccessorTable().getField(field).addRepeated(this, value);
- return (BuilderType)this;
+ return (BuilderType) this;
}
public final UnknownFieldSet getUnknownFields() {
@@ -259,7 +261,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
public final BuilderType setUnknownFields(UnknownFieldSet unknownFields) {
internalGetResult().unknownFields = unknownFields;
- return (BuilderType)this;
+ return (BuilderType) this;
}
public final BuilderType mergeUnknownFields(UnknownFieldSet unknownFields) {
@@ -268,7 +270,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
UnknownFieldSet.newBuilder(result.unknownFields)
.mergeFrom(unknownFields)
.build();
- return (BuilderType)this;
+ return (BuilderType) this;
}
public boolean isInitialized() {
@@ -287,7 +289,18 @@ public abstract class GeneratedMessage extends AbstractMessage {
return unknownFields.mergeFieldFrom(tag, input);
}
+ /**
+ * Adds the {@code values} to the {@code list}.
+ *
+ * @throws NullPointerException if any of the elements of {@code values} is
+ * null.
+ */
protected <T> void addAll(Iterable<T> values, Collection<? super T> list) {
+ for (T value : values) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ }
if (values instanceof Collection) {
@SuppressWarnings("unsafe")
Collection<T> collection = (Collection<T>) values;
@@ -378,9 +391,9 @@ public abstract class GeneratedMessage extends AbstractMessage {
verifyExtensionContainingType(extension);
Object value = extensions.getField(extension.getDescriptor());
if (value == null) {
- return (Type)extension.getMessageDefaultInstance();
+ return (Type) extension.getMessageDefaultInstance();
} else {
- return (Type)extension.fromReflectionType(value);
+ return (Type) extension.fromReflectionType(value);
}
}
@@ -389,7 +402,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
public final <Type> Type getExtension(
GeneratedExtension<MessageType, List<Type>> extension, int index) {
verifyExtensionContainingType(extension);
- return (Type)extension.singularFromReflectionType(
+ return (Type) extension.singularFromReflectionType(
extensions.getRepeatedField(extension.getDescriptor(), index));
}
@@ -397,7 +410,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
protected boolean extensionsAreInitialized() {
return extensions.isInitialized();
}
-
+
public boolean isInitialized() {
return super.isInitialized() && extensionsAreInitialized();
}
@@ -580,7 +593,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
message.verifyExtensionContainingType(extension);
message.extensions.setField(extension.getDescriptor(),
extension.toReflectionType(value));
- return (BuilderType)this;
+ return (BuilderType) this;
}
/** Set the value of one element of a repeated extension. */
@@ -592,7 +605,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
message.extensions.setRepeatedField(
extension.getDescriptor(), index,
extension.singularToReflectionType(value));
- return (BuilderType)this;
+ return (BuilderType) this;
}
/** Append a value to a repeated extension. */
@@ -602,7 +615,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
message.verifyExtensionContainingType(extension);
message.extensions.addRepeatedField(
extension.getDescriptor(), extension.singularToReflectionType(value));
- return (BuilderType)this;
+ return (BuilderType) this;
}
/** Clear an extension. */
@@ -611,7 +624,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
ExtendableMessage<MessageType> message = internalGetResult();
message.verifyExtensionContainingType(extension);
message.extensions.clearField(extension.getDescriptor());
- return (BuilderType)this;
+ return (BuilderType) this;
}
/**
@@ -639,7 +652,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
ExtendableMessage<MessageType> message = internalGetResult();
message.verifyContainingType(field);
message.extensions.setField(field, value);
- return (BuilderType)this;
+ return (BuilderType) this;
} else {
return super.setField(field, value);
}
@@ -650,7 +663,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
ExtendableMessage<MessageType> message = internalGetResult();
message.verifyContainingType(field);
message.extensions.clearField(field);
- return (BuilderType)this;
+ return (BuilderType) this;
} else {
return super.clearField(field);
}
@@ -662,7 +675,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
ExtendableMessage<MessageType> message = internalGetResult();
message.verifyContainingType(field);
message.extensions.setRepeatedField(field, index, value);
- return (BuilderType)this;
+ return (BuilderType) this;
} else {
return super.setRepeatedField(field, index, value);
}
@@ -674,11 +687,15 @@ public abstract class GeneratedMessage extends AbstractMessage {
ExtendableMessage<MessageType> message = internalGetResult();
message.verifyContainingType(field);
message.extensions.addRepeatedField(field, value);
- return (BuilderType)this;
+ return (BuilderType) this;
} else {
return super.addRepeatedField(field, value);
}
}
+
+ protected final void mergeExtensionFields(ExtendableMessage other) {
+ internalGetResult().extensions.mergeFrom(other.extensions);
+ }
}
// -----------------------------------------------------------------
@@ -750,8 +767,8 @@ public abstract class GeneratedMessage extends AbstractMessage {
enumValueOf = null;
enumGetValueDescriptor = null;
messageDefaultInstance =
- (Message)invokeOrDie(getMethodOrDie(type, "getDefaultInstance"),
- null);
+ (Message) invokeOrDie(getMethodOrDie(type, "getDefaultInstance"),
+ null);
break;
case ENUM:
enumValueOf = getMethodOrDie(type, "valueOf",
@@ -797,7 +814,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) {
// Must convert the whole list.
List result = new ArrayList();
- for (Object element : (List)value) {
+ for (Object element : (List) value) {
result.add(singularFromReflectionType(element));
}
return result;
@@ -826,10 +843,10 @@ public abstract class GeneratedMessage extends AbstractMessage {
// This should not happen in normal use. But, to be nice, we'll
// copy the message to whatever type the caller was expecting.
return messageDefaultInstance.newBuilderForType()
- .mergeFrom((Message)value).build();
+ .mergeFrom((Message) value).build();
}
case ENUM:
- return invokeOrDie(enumValueOf, null, (EnumValueDescriptor)value);
+ return invokeOrDie(enumValueOf, null, (EnumValueDescriptor) value);
default:
return value;
}
@@ -847,7 +864,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
if (descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) {
// Must convert the whole list.
List result = new ArrayList();
- for (Object element : (List)value) {
+ for (Object element : (List) value) {
result.add(singularToReflectionType(element));
}
return result;
@@ -900,9 +917,9 @@ public abstract class GeneratedMessage extends AbstractMessage {
} catch (java.lang.reflect.InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof RuntimeException) {
- throw (RuntimeException)cause;
+ throw (RuntimeException) cause;
} else if (cause instanceof Error) {
- throw (Error)cause;
+ throw (Error) cause;
} else {
throw new RuntimeException(
"Unexpected exception thrown by generated accessor method.", cause);
@@ -915,6 +932,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
* with access to the fields of a message object using Java reflection.
*/
public static final class FieldAccessorTable {
+
/**
* Construct a FieldAccessorTable for a particular message class. Only
* one FieldAccessorTable should ever be constructed per class.
@@ -1039,7 +1057,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
"addRepeatedField() called on a singular field.");
}
public boolean has(GeneratedMessage message) {
- return (Boolean)invokeOrDie(hasMethod, message);
+ return (Boolean) invokeOrDie(hasMethod, message);
}
public int getRepeatedCount(GeneratedMessage message) {
throw new UnsupportedOperationException(
@@ -1092,7 +1110,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
// 2) Insures that the caller cannot modify the list later on and
// have the modifications be reflected in the message.
clear(builder);
- for (Object element : (List)value) {
+ for (Object element : (List) value) {
addRepeated(builder, element);
}
}
@@ -1111,7 +1129,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
"hasField() called on a singular field.");
}
public int getRepeatedCount(GeneratedMessage message) {
- return (Integer)invokeOrDie(getCountMethod, message);
+ return (Integer) invokeOrDie(getCountMethod, message);
}
public void clear(GeneratedMessage.Builder builder) {
invokeOrDie(clearMethod, builder);
@@ -1169,7 +1187,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
@SuppressWarnings("unchecked")
public Object get(GeneratedMessage message) {
List newList = new ArrayList();
- for (Object element : (List)super.get(message)) {
+ for (Object element : (List) super.get(message)) {
newList.add(invokeOrDie(getValueDescriptorMethod, element));
}
return Collections.unmodifiableList(newList);
@@ -1210,8 +1228,8 @@ public abstract class GeneratedMessage extends AbstractMessage {
// is an alternative implementation of the same type -- e.g. a
// DynamicMessage -- we should accept it. In this case we can make
// a copy of the message.
- return ((Message.Builder)invokeOrDie(newBuilderMethod, null))
- .mergeFrom((Message)value).build();
+ return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
+ .mergeFrom((Message) value).build();
}
}
@@ -1219,7 +1237,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
super.set(builder, coerceType(value));
}
public Message.Builder newBuilder() {
- return (Message.Builder)invokeOrDie(newBuilderMethod, null);
+ return (Message.Builder) invokeOrDie(newBuilderMethod, null);
}
}
@@ -1244,8 +1262,8 @@ public abstract class GeneratedMessage extends AbstractMessage {
// is an alternative implementation of the same type -- e.g. a
// DynamicMessage -- we should accept it. In this case we can make
// a copy of the message.
- return ((Message.Builder)invokeOrDie(newBuilderMethod, null))
- .mergeFrom((Message)value).build();
+ return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
+ .mergeFrom((Message) value).build();
}
}
@@ -1257,7 +1275,7 @@ public abstract class GeneratedMessage extends AbstractMessage {
super.addRepeated(builder, coerceType(value));
}
public Message.Builder newBuilder() {
- return (Message.Builder)invokeOrDie(newBuilderMethod, null);
+ return (Message.Builder) invokeOrDie(newBuilderMethod, null);
}
}
}
diff --git a/java/src/main/java/com/google/protobuf/Message.java b/java/src/main/java/com/google/protobuf/Message.java
index 9635387a..2f8700db 100644
--- a/java/src/main/java/com/google/protobuf/Message.java
+++ b/java/src/main/java/com/google/protobuf/Message.java
@@ -195,6 +195,12 @@ public interface Message {
Builder newBuilderForType();
/**
+ * Constructs a builder initialized with the current message. Use this to
+ * derive a new message from the current one.
+ */
+ Builder toBuilder();
+
+ /**
* Abstract interface implemented by Protocol Message builders.
*/
public static interface Builder extends Cloneable {
diff --git a/java/src/main/java/com/google/protobuf/TextFormat.java b/java/src/main/java/com/google/protobuf/TextFormat.java
index 3a1b1d4e..3dcf68c8 100644
--- a/java/src/main/java/com/google/protobuf/TextFormat.java
+++ b/java/src/main/java/com/google/protobuf/TextFormat.java
@@ -397,13 +397,15 @@ public final class TextFormat {
private int previousLine = 0;
private int previousColumn = 0;
+ // We use possesive quantifiers (*+ and ++) because otherwise the Java
+ // regex matcher has stack overflows on large inputs.
private static Pattern WHITESPACE =
- Pattern.compile("(\\s|(#.*$))+", Pattern.MULTILINE);
+ Pattern.compile("(\\s|(#.*$))++", Pattern.MULTILINE);
private static Pattern TOKEN = Pattern.compile(
- "[a-zA-Z_][0-9a-zA-Z_+-]*|" + // an identifier
- "[0-9+-][0-9a-zA-Z_.+-]*|" + // a number
- "\"([^\"\n\\\\]|\\\\.)*(\"|\\\\?$)|" + // a double-quoted string
- "\'([^\"\n\\\\]|\\\\.)*(\'|\\\\?$)", // a single-quoted string
+ "[a-zA-Z_][0-9a-zA-Z_+-]*+|" + // an identifier
+ "[0-9+-][0-9a-zA-Z_.+-]*+|" + // a number
+ "\"([^\"\n\\\\]|\\\\.)*+(\"|\\\\?$)|" + // a double-quoted string
+ "\'([^\"\n\\\\]|\\\\.)*+(\'|\\\\?$)", // a single-quoted string
Pattern.MULTILINE);
private static Pattern DOUBLE_INFINITY = Pattern.compile(
diff --git a/java/src/main/java/com/google/protobuf/WireFormat.java b/java/src/main/java/com/google/protobuf/WireFormat.java
index ff042c05..2faf2448 100644
--- a/java/src/main/java/com/google/protobuf/WireFormat.java
+++ b/java/src/main/java/com/google/protobuf/WireFormat.java
@@ -96,6 +96,16 @@ public final class WireFormat {
"There is no way to get here, but the compiler thinks otherwise.");
}
+ /** Given a field descriptor, returns the wire type. This differs from
+ * getWireFormatForFieldType for packed repeated fields. */
+ static int getWireFormatForField(Descriptors.FieldDescriptor descriptor) {
+ if (descriptor.getOptions().getPacked()) {
+ return WIRETYPE_LENGTH_DELIMITED;
+ } else {
+ return getWireFormatForFieldType(descriptor.getType());
+ }
+ }
+
// Field numbers for feilds in MessageSet wire format.
static final int MESSAGE_SET_ITEM = 1;
static final int MESSAGE_SET_TYPE_ID = 2;
diff --git a/java/src/test/java/com/google/protobuf/AbstractMessageTest.java b/java/src/test/java/com/google/protobuf/AbstractMessageTest.java
index 10ab7e75..da073561 100644
--- a/java/src/test/java/com/google/protobuf/AbstractMessageTest.java
+++ b/java/src/test/java/com/google/protobuf/AbstractMessageTest.java
@@ -34,6 +34,7 @@ import protobuf_unittest.UnittestProto;
import protobuf_unittest.UnittestProto.ForeignMessage;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestProto.TestRequired;
import protobuf_unittest.UnittestProto.TestRequiredForeign;
import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
@@ -91,6 +92,9 @@ public class AbstractMessageTest extends TestCase {
public Builder newBuilderForType() {
return new Builder(wrappedMessage.newBuilderForType());
}
+ public Builder toBuilder() {
+ return new Builder(wrappedMessage.toBuilder());
+ }
static class Builder extends AbstractMessage.Builder<Builder> {
private final Message.Builder wrappedBuilder;
@@ -215,6 +219,25 @@ public class AbstractMessageTest extends TestCase {
TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage);
}
+ public void testPackedSerialization() throws Exception {
+ Message abstractMessage =
+ new AbstractMessageWrapper(TestUtil.getPackedSet());
+
+ TestUtil.assertPackedFieldsSet(
+ TestPackedTypes.parseFrom(abstractMessage.toByteString()));
+
+ assertEquals(TestUtil.getPackedSet().toByteString(),
+ abstractMessage.toByteString());
+ }
+
+ public void testPackedParsing() throws Exception {
+ AbstractMessageWrapper.Builder builder =
+ new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder());
+ AbstractMessageWrapper message =
+ builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
+ TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage);
+ }
+
public void testOptimizedForSize() throws Exception {
// We're mostly only checking that this class was compiled successfully.
TestOptimizedForSize message =
diff --git a/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java b/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
index 5a96e3e6..c42b485c 100644
--- a/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
+++ b/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
@@ -31,6 +31,7 @@
package com.google.protobuf;
import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
import junit.framework.TestCase;
@@ -290,4 +291,14 @@ public class CodedOutputStreamTest extends TestCase {
assertEqualBytes(rawBytes, rawOutput.toByteArray());
}
}
+
+ /** 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 {
+ TestPackedTypes message = TestUtil.getPackedSet();
+
+ byte[] rawBytes = message.toByteArray();
+ assertEqualBytes(TestUtil.getGoldenPackedFieldsMessage().toByteArray(),
+ rawBytes);
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/DynamicMessageTest.java b/java/src/test/java/com/google/protobuf/DynamicMessageTest.java
index e2c15c64..fc53c531 100644
--- a/java/src/test/java/com/google/protobuf/DynamicMessageTest.java
+++ b/java/src/test/java/com/google/protobuf/DynamicMessageTest.java
@@ -32,8 +32,10 @@ package com.google.protobuf;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
import junit.framework.TestCase;
+import java.util.Arrays;
/**
* Unit test for {@link DynamicMessage}. See also {@link MessageTest}, which
@@ -48,6 +50,8 @@ public class DynamicMessageTest extends TestCase {
TestUtil.ReflectionTester extensionsReflectionTester =
new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
TestUtil.getExtensionRegistry());
+ TestUtil.ReflectionTester packedReflectionTester =
+ new TestUtil.ReflectionTester(TestPackedTypes.getDescriptor(), null);
public void testDynamicMessageAccessors() throws Exception {
Message.Builder builder =
@@ -57,6 +61,12 @@ public class DynamicMessageTest extends TestCase {
reflectionTester.assertAllFieldsSetViaReflection(message);
}
+ public void testDynamicMessageSettersRejectNull() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.assertReflectionSettersRejectNull(builder);
+ }
+
public void testDynamicMessageExtensionAccessors() throws Exception {
// We don't need to extensively test DynamicMessage's handling of
// extensions because, frankly, it doesn't do anything special with them.
@@ -68,6 +78,12 @@ public class DynamicMessageTest extends TestCase {
extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
}
+ public void testDynamicMessageExtensionSettersRejectNull() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllExtensions.getDescriptor());
+ extensionsReflectionTester.assertReflectionSettersRejectNull(builder);
+ }
+
public void testDynamicMessageRepeatedSetters() throws Exception {
Message.Builder builder =
DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
@@ -77,6 +93,12 @@ public class DynamicMessageTest extends TestCase {
reflectionTester.assertRepeatedFieldsModifiedViaReflection(message);
}
+ public void testDynamicMessageRepeatedSettersRejectNull() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.assertReflectionRepeatedSettersRejectNull(builder);
+ }
+
public void testDynamicMessageDefaults() throws Exception {
reflectionTester.assertClearViaReflection(
DynamicMessage.getDefaultInstance(TestAllTypes.getDescriptor()));
@@ -123,6 +145,33 @@ public class DynamicMessageTest extends TestCase {
reflectionTester.assertAllFieldsSetViaReflection(message2);
}
+ public void testDynamicMessagePackedSerialization() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestPackedTypes.getDescriptor());
+ packedReflectionTester.setPackedFieldsViaReflection(builder);
+ Message message = builder.build();
+
+ ByteString rawBytes = message.toByteString();
+ TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
+
+ TestUtil.assertPackedFieldsSet(message2);
+
+ // In fact, the serialized forms should be exactly the same, byte-for-byte.
+ assertEquals(TestUtil.getPackedSet().toByteString(), rawBytes);
+ }
+
+ public void testDynamicMessagePackedParsing() throws Exception {
+ TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
+ TestUtil.setPackedFields(builder);
+ TestPackedTypes message = builder.build();
+
+ ByteString rawBytes = message.toByteString();
+
+ Message message2 =
+ DynamicMessage.parseFrom(TestPackedTypes.getDescriptor(), rawBytes);
+ packedReflectionTester.assertPackedFieldsSetViaReflection(message2);
+ }
+
public void testDynamicMessageCopy() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
TestUtil.setAllFields(builder);
@@ -131,4 +180,23 @@ public class DynamicMessageTest extends TestCase {
DynamicMessage copy = DynamicMessage.newBuilder(message).build();
reflectionTester.assertAllFieldsSetViaReflection(copy);
}
+
+ public void testToBuilder() throws Exception {
+ DynamicMessage.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.setAllFieldsViaReflection(builder);
+ int unknownFieldNum = 9;
+ long unknownFieldVal = 90;
+ builder.setUnknownFields(UnknownFieldSet.newBuilder()
+ .addField(unknownFieldNum,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(unknownFieldVal).build())
+ .build());
+ DynamicMessage message = builder.build();
+
+ DynamicMessage derived = message.toBuilder().build();
+ reflectionTester.assertAllFieldsSetViaReflection(derived);
+ assertEquals(Arrays.asList(unknownFieldVal),
+ derived.getUnknownFields().getField(unknownFieldNum).getVarintList());
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
index 95c269a2..0ecdc6ae 100644
--- a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
+++ b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -71,6 +71,72 @@ public class GeneratedMessageTest extends TestCase {
TestUtil.assertAllFieldsSet(message);
}
+ public void testSettersRejectNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ try {
+ builder.setOptionalString(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setOptionalBytes(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setOptionalNestedMessage((TestAllTypes.NestedMessage) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setOptionalNestedMessage(
+ (TestAllTypes.NestedMessage.Builder) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setOptionalNestedEnum(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedString(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedBytes(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedNestedMessage(
+ (TestAllTypes.NestedMessage.Builder) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedNestedEnum(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+
public void testRepeatedSetters() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
TestUtil.setAllFields(builder);
@@ -79,6 +145,55 @@ public class GeneratedMessageTest extends TestCase {
TestUtil.assertRepeatedFieldsModified(message);
}
+ public void testRepeatedSettersRejectNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+ builder.addRepeatedString("one");
+ builder.addRepeatedString("two");
+ try {
+ builder.setRepeatedString(1, null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedBytes(TestUtil.toBytes("one"));
+ builder.addRepeatedBytes(TestUtil.toBytes("two"));
+ try {
+ builder.setRepeatedBytes(1, null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedNestedMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+ builder.addRepeatedNestedMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(456).build());
+ try {
+ builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setRepeatedNestedMessage(
+ 1, (TestAllTypes.NestedMessage.Builder) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.FOO);
+ builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR);
+ try {
+ builder.setRepeatedNestedEnum(1, null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+
public void testRepeatedAppend() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
@@ -97,6 +212,42 @@ public class GeneratedMessageTest extends TestCase {
assertEquals(12, message.getRepeatedForeignMessage(0).getC());
}
+ public void testRepeatedAppendRejectsNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+ ForeignMessage foreignMessage =
+ ForeignMessage.newBuilder().setC(12).build();
+ try {
+ builder.addAllRepeatedForeignMessage(
+ Arrays.asList(foreignMessage, (ForeignMessage) null));
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ try {
+ builder.addAllRepeatedForeignEnum(
+ Arrays.asList(ForeignEnum.FOREIGN_BAZ, null));
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ try {
+ builder.addAllRepeatedString(Arrays.asList("one", null));
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ try {
+ builder.addAllRepeatedBytes(Arrays.asList(TestUtil.toBytes("one"), null));
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+
public void testSettingForeignMessageUsingBuilder() throws Exception {
TestAllTypes message = TestAllTypes.newBuilder()
// Pass builder for foreign message instance.
@@ -146,6 +297,11 @@ public class GeneratedMessageTest extends TestCase {
TestUtil.assertAllFieldsSet(message);
}
+ public void testReflectionSettersRejectNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ reflectionTester.assertReflectionSettersRejectNull(builder);
+ }
+
public void testReflectionRepeatedSetters() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
reflectionTester.setAllFieldsViaReflection(builder);
@@ -154,6 +310,11 @@ public class GeneratedMessageTest extends TestCase {
TestUtil.assertRepeatedFieldsModified(message);
}
+ public void testReflectionRepeatedSettersRejectNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ reflectionTester.assertReflectionRepeatedSettersRejectNull(builder);
+ }
+
public void testReflectionDefaults() throws Exception {
reflectionTester.assertClearViaReflection(
TestAllTypes.getDefaultInstance());
@@ -161,6 +322,11 @@ public class GeneratedMessageTest extends TestCase {
TestAllTypes.newBuilder().build());
}
+ public void testEnumInterface() throws Exception {
+ assertTrue(TestAllTypes.getDefaultInstance().getDefaultNestedEnum()
+ instanceof ProtocolMessageEnum);
+ }
+
// =================================================================
// Extensions.
@@ -202,6 +368,11 @@ public class GeneratedMessageTest extends TestCase {
TestUtil.assertAllExtensionsSet(message);
}
+ public void testExtensionReflectionSettersRejectNull() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ extensionsReflectionTester.assertReflectionSettersRejectNull(builder);
+ }
+
public void testExtensionReflectionRepeatedSetters() throws Exception {
TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
extensionsReflectionTester.setAllFieldsViaReflection(builder);
@@ -210,6 +381,13 @@ public class GeneratedMessageTest extends TestCase {
TestUtil.assertRepeatedExtensionsModified(message);
}
+ public void testExtensionReflectionRepeatedSettersRejectNull()
+ throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ extensionsReflectionTester.assertReflectionRepeatedSettersRejectNull(
+ builder);
+ }
+
public void testExtensionReflectionDefaults() throws Exception {
extensionsReflectionTester.assertClearViaReflection(
TestAllExtensions.getDefaultInstance());
@@ -231,6 +409,17 @@ public class GeneratedMessageTest extends TestCase {
.getExtensionCount(UnittestProto.repeatedInt32Extension));
}
+ public void testExtensionMergeFrom() throws Exception {
+ TestAllExtensions original =
+ TestAllExtensions.newBuilder()
+ .setExtension(UnittestProto.optionalInt32Extension, 1).build();
+ TestAllExtensions merged =
+ TestAllExtensions.newBuilder().mergeFrom(original).build();
+ assertTrue(merged.hasExtension(UnittestProto.optionalInt32Extension));
+ assertEquals(
+ 1, (int) merged.getExtension(UnittestProto.optionalInt32Extension));
+ }
+
// =================================================================
// multiple_files_test
@@ -266,7 +455,7 @@ public class GeneratedMessageTest extends TestCase {
TestOptionalOptimizedForSize message =
TestOptionalOptimizedForSize.getDefaultInstance();
assertTrue(message.isInitialized());
-
+
message = TestOptionalOptimizedForSize.newBuilder().setO(
TestRequiredOptimizedForSize.newBuilder().buildPartial()
).buildPartial();
@@ -292,4 +481,11 @@ public class GeneratedMessageTest extends TestCase {
assertTrue(builder.isInitialized());
assertTrue(builder.buildPartial().isInitialized());
}
+
+ public void testToBuilder() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestAllTypes message = builder.build();
+ TestUtil.assertAllFieldsSet(message.toBuilder().build());
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/TestUtil.java b/java/src/test/java/com/google/protobuf/TestUtil.java
index d99ab85e..2f47b714 100644
--- a/java/src/test/java/com/google/protobuf/TestUtil.java
+++ b/java/src/test/java/com/google/protobuf/TestUtil.java
@@ -28,17 +28,105 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Note: This file contains many lines over 80 characters. It even contains
-// many lines over 100 characters, which fails a presubmit test. However,
-// given the extremely repetitive nature of the file, I (kenton) feel that
-// having similar components of each statement line up is more important than
-// avoiding horizontal scrolling. So, I am bypassing the presubmit check.
-
package com.google.protobuf;
import protobuf_unittest.UnittestProto;
-import protobuf_unittest.UnittestProto.TestAllTypes;
+
+// The static imports are to avoid 100+ char lines. The following is roughly equivalent to
+// import static protobuf_unittest.UnittestProto.*;
+import static protobuf_unittest.UnittestProto.defaultInt32Extension;
+import static protobuf_unittest.UnittestProto.defaultInt64Extension;
+import static protobuf_unittest.UnittestProto.defaultUint32Extension;
+import static protobuf_unittest.UnittestProto.defaultUint64Extension;
+import static protobuf_unittest.UnittestProto.defaultSint32Extension;
+import static protobuf_unittest.UnittestProto.defaultSint64Extension;
+import static protobuf_unittest.UnittestProto.defaultFixed32Extension;
+import static protobuf_unittest.UnittestProto.defaultFixed64Extension;
+import static protobuf_unittest.UnittestProto.defaultSfixed32Extension;
+import static protobuf_unittest.UnittestProto.defaultSfixed64Extension;
+import static protobuf_unittest.UnittestProto.defaultFloatExtension;
+import static protobuf_unittest.UnittestProto.defaultDoubleExtension;
+import static protobuf_unittest.UnittestProto.defaultBoolExtension;
+import static protobuf_unittest.UnittestProto.defaultStringExtension;
+import static protobuf_unittest.UnittestProto.defaultBytesExtension;
+import static protobuf_unittest.UnittestProto.defaultNestedEnumExtension;
+import static protobuf_unittest.UnittestProto.defaultForeignEnumExtension;
+import static protobuf_unittest.UnittestProto.defaultImportEnumExtension;
+import static protobuf_unittest.UnittestProto.defaultStringPieceExtension;
+import static protobuf_unittest.UnittestProto.defaultCordExtension;
+
+import static protobuf_unittest.UnittestProto.optionalInt32Extension;
+import static protobuf_unittest.UnittestProto.optionalInt64Extension;
+import static protobuf_unittest.UnittestProto.optionalUint32Extension;
+import static protobuf_unittest.UnittestProto.optionalUint64Extension;
+import static protobuf_unittest.UnittestProto.optionalSint32Extension;
+import static protobuf_unittest.UnittestProto.optionalSint64Extension;
+import static protobuf_unittest.UnittestProto.optionalFixed32Extension;
+import static protobuf_unittest.UnittestProto.optionalFixed64Extension;
+import static protobuf_unittest.UnittestProto.optionalSfixed32Extension;
+import static protobuf_unittest.UnittestProto.optionalSfixed64Extension;
+import static protobuf_unittest.UnittestProto.optionalFloatExtension;
+import static protobuf_unittest.UnittestProto.optionalDoubleExtension;
+import static protobuf_unittest.UnittestProto.optionalBoolExtension;
+import static protobuf_unittest.UnittestProto.optionalStringExtension;
+import static protobuf_unittest.UnittestProto.optionalBytesExtension;
+import static protobuf_unittest.UnittestProto.optionalGroupExtension;
+import static protobuf_unittest.UnittestProto.optionalNestedMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalForeignMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalImportMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalNestedEnumExtension;
+import static protobuf_unittest.UnittestProto.optionalForeignEnumExtension;
+import static protobuf_unittest.UnittestProto.optionalImportEnumExtension;
+import static protobuf_unittest.UnittestProto.optionalStringPieceExtension;
+import static protobuf_unittest.UnittestProto.optionalCordExtension;
+
+import static protobuf_unittest.UnittestProto.repeatedInt32Extension;
+import static protobuf_unittest.UnittestProto.repeatedInt64Extension;
+import static protobuf_unittest.UnittestProto.repeatedUint32Extension;
+import static protobuf_unittest.UnittestProto.repeatedUint64Extension;
+import static protobuf_unittest.UnittestProto.repeatedSint32Extension;
+import static protobuf_unittest.UnittestProto.repeatedSint64Extension;
+import static protobuf_unittest.UnittestProto.repeatedFixed32Extension;
+import static protobuf_unittest.UnittestProto.repeatedFixed64Extension;
+import static protobuf_unittest.UnittestProto.repeatedSfixed32Extension;
+import static protobuf_unittest.UnittestProto.repeatedSfixed64Extension;
+import static protobuf_unittest.UnittestProto.repeatedFloatExtension;
+import static protobuf_unittest.UnittestProto.repeatedDoubleExtension;
+import static protobuf_unittest.UnittestProto.repeatedBoolExtension;
+import static protobuf_unittest.UnittestProto.repeatedStringExtension;
+import static protobuf_unittest.UnittestProto.repeatedBytesExtension;
+import static protobuf_unittest.UnittestProto.repeatedGroupExtension;
+import static protobuf_unittest.UnittestProto.repeatedNestedMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedForeignMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedImportMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedNestedEnumExtension;
+import static protobuf_unittest.UnittestProto.repeatedForeignEnumExtension;
+import static protobuf_unittest.UnittestProto.repeatedImportEnumExtension;
+import static protobuf_unittest.UnittestProto.repeatedStringPieceExtension;
+import static protobuf_unittest.UnittestProto.repeatedCordExtension;
+
+import static protobuf_unittest.UnittestProto.OptionalGroup_extension;
+import static protobuf_unittest.UnittestProto.RepeatedGroup_extension;
+
+import static protobuf_unittest.UnittestProto.packedInt32Extension;
+import static protobuf_unittest.UnittestProto.packedInt64Extension;
+import static protobuf_unittest.UnittestProto.packedUint32Extension;
+import static protobuf_unittest.UnittestProto.packedUint64Extension;
+import static protobuf_unittest.UnittestProto.packedSint32Extension;
+import static protobuf_unittest.UnittestProto.packedSint64Extension;
+import static protobuf_unittest.UnittestProto.packedFixed32Extension;
+import static protobuf_unittest.UnittestProto.packedFixed64Extension;
+import static protobuf_unittest.UnittestProto.packedSfixed32Extension;
+import static protobuf_unittest.UnittestProto.packedSfixed64Extension;
+import static protobuf_unittest.UnittestProto.packedFloatExtension;
+import static protobuf_unittest.UnittestProto.packedDoubleExtension;
+import static protobuf_unittest.UnittestProto.packedBoolExtension;
+import static protobuf_unittest.UnittestProto.packedEnumExtension;
+
import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestPackedExtensions;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestProto.ForeignMessage;
import protobuf_unittest.UnittestProto.ForeignEnum;
import com.google.protobuf.test.UnittestImport.ImportMessage;
@@ -63,7 +151,7 @@ class TestUtil {
private TestUtil() {}
/** Helper to convert a String to ByteString. */
- private static ByteString toBytes(String str) {
+ static ByteString toBytes(String str) {
try {
return ByteString.copyFrom(str.getBytes("UTF-8"));
} catch(java.io.UnsupportedEncodingException e) {
@@ -91,6 +179,18 @@ class TestUtil {
return builder.build();
}
+ public static TestPackedTypes getPackedSet() {
+ TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
+ setPackedFields(builder);
+ return builder.build();
+ }
+
+ public static TestPackedExtensions getPackedExtensionsSet() {
+ TestPackedExtensions.Builder builder = TestPackedExtensions.newBuilder();
+ setPackedExtensions(builder);
+ return builder.build();
+ }
+
/**
* Set every field of {@code message} to the values expected by
* {@code assertAllFieldsSet()}.
@@ -770,141 +870,129 @@ class TestUtil {
* {@code assertAllExtensionsSet()}.
*/
public static void setAllExtensions(TestAllExtensions.Builder message) {
- message.setExtension(UnittestProto.optionalInt32Extension , 101);
- message.setExtension(UnittestProto.optionalInt64Extension , 102L);
- message.setExtension(UnittestProto.optionalUint32Extension , 103);
- message.setExtension(UnittestProto.optionalUint64Extension , 104L);
- message.setExtension(UnittestProto.optionalSint32Extension , 105);
- message.setExtension(UnittestProto.optionalSint64Extension , 106L);
- message.setExtension(UnittestProto.optionalFixed32Extension , 107);
- message.setExtension(UnittestProto.optionalFixed64Extension , 108L);
- message.setExtension(UnittestProto.optionalSfixed32Extension, 109);
- message.setExtension(UnittestProto.optionalSfixed64Extension, 110L);
- message.setExtension(UnittestProto.optionalFloatExtension , 111F);
- message.setExtension(UnittestProto.optionalDoubleExtension , 112D);
- message.setExtension(UnittestProto.optionalBoolExtension , true);
- message.setExtension(UnittestProto.optionalStringExtension , "115");
- message.setExtension(UnittestProto.optionalBytesExtension , toBytes("116"));
-
- message.setExtension(UnittestProto.optionalGroupExtension,
- UnittestProto.OptionalGroup_extension.newBuilder().setA(117).build());
- message.setExtension(UnittestProto.optionalNestedMessageExtension,
+ message.setExtension(optionalInt32Extension , 101);
+ message.setExtension(optionalInt64Extension , 102L);
+ message.setExtension(optionalUint32Extension , 103);
+ message.setExtension(optionalUint64Extension , 104L);
+ message.setExtension(optionalSint32Extension , 105);
+ message.setExtension(optionalSint64Extension , 106L);
+ message.setExtension(optionalFixed32Extension , 107);
+ message.setExtension(optionalFixed64Extension , 108L);
+ message.setExtension(optionalSfixed32Extension, 109);
+ message.setExtension(optionalSfixed64Extension, 110L);
+ message.setExtension(optionalFloatExtension , 111F);
+ message.setExtension(optionalDoubleExtension , 112D);
+ message.setExtension(optionalBoolExtension , true);
+ message.setExtension(optionalStringExtension , "115");
+ message.setExtension(optionalBytesExtension , toBytes("116"));
+
+ message.setExtension(optionalGroupExtension,
+ OptionalGroup_extension.newBuilder().setA(117).build());
+ message.setExtension(optionalNestedMessageExtension,
TestAllTypes.NestedMessage.newBuilder().setBb(118).build());
- message.setExtension(UnittestProto.optionalForeignMessageExtension,
+ message.setExtension(optionalForeignMessageExtension,
ForeignMessage.newBuilder().setC(119).build());
- message.setExtension(UnittestProto.optionalImportMessageExtension,
+ message.setExtension(optionalImportMessageExtension,
ImportMessage.newBuilder().setD(120).build());
- message.setExtension(UnittestProto.optionalNestedEnumExtension,
- TestAllTypes.NestedEnum.BAZ);
- message.setExtension(UnittestProto.optionalForeignEnumExtension,
- ForeignEnum.FOREIGN_BAZ);
- message.setExtension(UnittestProto.optionalImportEnumExtension,
- ImportEnum.IMPORT_BAZ);
+ message.setExtension(optionalNestedEnumExtension, TestAllTypes.NestedEnum.BAZ);
+ message.setExtension(optionalForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
+ message.setExtension(optionalImportEnumExtension, ImportEnum.IMPORT_BAZ);
- message.setExtension(UnittestProto.optionalStringPieceExtension, "124");
- message.setExtension(UnittestProto.optionalCordExtension, "125");
+ message.setExtension(optionalStringPieceExtension, "124");
+ message.setExtension(optionalCordExtension, "125");
// -----------------------------------------------------------------
- message.addExtension(UnittestProto.repeatedInt32Extension , 201);
- message.addExtension(UnittestProto.repeatedInt64Extension , 202L);
- message.addExtension(UnittestProto.repeatedUint32Extension , 203);
- message.addExtension(UnittestProto.repeatedUint64Extension , 204L);
- message.addExtension(UnittestProto.repeatedSint32Extension , 205);
- message.addExtension(UnittestProto.repeatedSint64Extension , 206L);
- message.addExtension(UnittestProto.repeatedFixed32Extension , 207);
- message.addExtension(UnittestProto.repeatedFixed64Extension , 208L);
- message.addExtension(UnittestProto.repeatedSfixed32Extension, 209);
- message.addExtension(UnittestProto.repeatedSfixed64Extension, 210L);
- message.addExtension(UnittestProto.repeatedFloatExtension , 211F);
- message.addExtension(UnittestProto.repeatedDoubleExtension , 212D);
- message.addExtension(UnittestProto.repeatedBoolExtension , true);
- message.addExtension(UnittestProto.repeatedStringExtension , "215");
- message.addExtension(UnittestProto.repeatedBytesExtension , toBytes("216"));
-
- message.addExtension(UnittestProto.repeatedGroupExtension,
- UnittestProto.RepeatedGroup_extension.newBuilder().setA(217).build());
- message.addExtension(UnittestProto.repeatedNestedMessageExtension,
+ message.addExtension(repeatedInt32Extension , 201);
+ message.addExtension(repeatedInt64Extension , 202L);
+ message.addExtension(repeatedUint32Extension , 203);
+ message.addExtension(repeatedUint64Extension , 204L);
+ message.addExtension(repeatedSint32Extension , 205);
+ message.addExtension(repeatedSint64Extension , 206L);
+ message.addExtension(repeatedFixed32Extension , 207);
+ message.addExtension(repeatedFixed64Extension , 208L);
+ message.addExtension(repeatedSfixed32Extension, 209);
+ message.addExtension(repeatedSfixed64Extension, 210L);
+ message.addExtension(repeatedFloatExtension , 211F);
+ message.addExtension(repeatedDoubleExtension , 212D);
+ message.addExtension(repeatedBoolExtension , true);
+ message.addExtension(repeatedStringExtension , "215");
+ message.addExtension(repeatedBytesExtension , toBytes("216"));
+
+ message.addExtension(repeatedGroupExtension,
+ RepeatedGroup_extension.newBuilder().setA(217).build());
+ message.addExtension(repeatedNestedMessageExtension,
TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
- message.addExtension(UnittestProto.repeatedForeignMessageExtension,
+ message.addExtension(repeatedForeignMessageExtension,
ForeignMessage.newBuilder().setC(219).build());
- message.addExtension(UnittestProto.repeatedImportMessageExtension,
+ message.addExtension(repeatedImportMessageExtension,
ImportMessage.newBuilder().setD(220).build());
- message.addExtension(UnittestProto.repeatedNestedEnumExtension,
- TestAllTypes.NestedEnum.BAR);
- message.addExtension(UnittestProto.repeatedForeignEnumExtension,
- ForeignEnum.FOREIGN_BAR);
- message.addExtension(UnittestProto.repeatedImportEnumExtension,
- ImportEnum.IMPORT_BAR);
+ message.addExtension(repeatedNestedEnumExtension, TestAllTypes.NestedEnum.BAR);
+ message.addExtension(repeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAR);
+ message.addExtension(repeatedImportEnumExtension, ImportEnum.IMPORT_BAR);
- message.addExtension(UnittestProto.repeatedStringPieceExtension, "224");
- message.addExtension(UnittestProto.repeatedCordExtension, "225");
+ message.addExtension(repeatedStringPieceExtension, "224");
+ message.addExtension(repeatedCordExtension, "225");
// Add a second one of each field.
- message.addExtension(UnittestProto.repeatedInt32Extension , 301);
- message.addExtension(UnittestProto.repeatedInt64Extension , 302L);
- message.addExtension(UnittestProto.repeatedUint32Extension , 303);
- message.addExtension(UnittestProto.repeatedUint64Extension , 304L);
- message.addExtension(UnittestProto.repeatedSint32Extension , 305);
- message.addExtension(UnittestProto.repeatedSint64Extension , 306L);
- message.addExtension(UnittestProto.repeatedFixed32Extension , 307);
- message.addExtension(UnittestProto.repeatedFixed64Extension , 308L);
- message.addExtension(UnittestProto.repeatedSfixed32Extension, 309);
- message.addExtension(UnittestProto.repeatedSfixed64Extension, 310L);
- message.addExtension(UnittestProto.repeatedFloatExtension , 311F);
- message.addExtension(UnittestProto.repeatedDoubleExtension , 312D);
- message.addExtension(UnittestProto.repeatedBoolExtension , false);
- message.addExtension(UnittestProto.repeatedStringExtension , "315");
- message.addExtension(UnittestProto.repeatedBytesExtension , toBytes("316"));
-
- message.addExtension(UnittestProto.repeatedGroupExtension,
- UnittestProto.RepeatedGroup_extension.newBuilder().setA(317).build());
- message.addExtension(UnittestProto.repeatedNestedMessageExtension,
+ message.addExtension(repeatedInt32Extension , 301);
+ message.addExtension(repeatedInt64Extension , 302L);
+ message.addExtension(repeatedUint32Extension , 303);
+ message.addExtension(repeatedUint64Extension , 304L);
+ message.addExtension(repeatedSint32Extension , 305);
+ message.addExtension(repeatedSint64Extension , 306L);
+ message.addExtension(repeatedFixed32Extension , 307);
+ message.addExtension(repeatedFixed64Extension , 308L);
+ message.addExtension(repeatedSfixed32Extension, 309);
+ message.addExtension(repeatedSfixed64Extension, 310L);
+ message.addExtension(repeatedFloatExtension , 311F);
+ message.addExtension(repeatedDoubleExtension , 312D);
+ message.addExtension(repeatedBoolExtension , false);
+ message.addExtension(repeatedStringExtension , "315");
+ message.addExtension(repeatedBytesExtension , toBytes("316"));
+
+ message.addExtension(repeatedGroupExtension,
+ RepeatedGroup_extension.newBuilder().setA(317).build());
+ message.addExtension(repeatedNestedMessageExtension,
TestAllTypes.NestedMessage.newBuilder().setBb(318).build());
- message.addExtension(UnittestProto.repeatedForeignMessageExtension,
+ message.addExtension(repeatedForeignMessageExtension,
ForeignMessage.newBuilder().setC(319).build());
- message.addExtension(UnittestProto.repeatedImportMessageExtension,
+ message.addExtension(repeatedImportMessageExtension,
ImportMessage.newBuilder().setD(320).build());
- message.addExtension(UnittestProto.repeatedNestedEnumExtension,
- TestAllTypes.NestedEnum.BAZ);
- message.addExtension(UnittestProto.repeatedForeignEnumExtension,
- ForeignEnum.FOREIGN_BAZ);
- message.addExtension(UnittestProto.repeatedImportEnumExtension,
- ImportEnum.IMPORT_BAZ);
+ message.addExtension(repeatedNestedEnumExtension, TestAllTypes.NestedEnum.BAZ);
+ message.addExtension(repeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
+ message.addExtension(repeatedImportEnumExtension, ImportEnum.IMPORT_BAZ);
- message.addExtension(UnittestProto.repeatedStringPieceExtension, "324");
- message.addExtension(UnittestProto.repeatedCordExtension, "325");
+ message.addExtension(repeatedStringPieceExtension, "324");
+ message.addExtension(repeatedCordExtension, "325");
// -----------------------------------------------------------------
- message.setExtension(UnittestProto.defaultInt32Extension , 401);
- message.setExtension(UnittestProto.defaultInt64Extension , 402L);
- message.setExtension(UnittestProto.defaultUint32Extension , 403);
- message.setExtension(UnittestProto.defaultUint64Extension , 404L);
- message.setExtension(UnittestProto.defaultSint32Extension , 405);
- message.setExtension(UnittestProto.defaultSint64Extension , 406L);
- message.setExtension(UnittestProto.defaultFixed32Extension , 407);
- message.setExtension(UnittestProto.defaultFixed64Extension , 408L);
- message.setExtension(UnittestProto.defaultSfixed32Extension, 409);
- message.setExtension(UnittestProto.defaultSfixed64Extension, 410L);
- message.setExtension(UnittestProto.defaultFloatExtension , 411F);
- message.setExtension(UnittestProto.defaultDoubleExtension , 412D);
- message.setExtension(UnittestProto.defaultBoolExtension , false);
- message.setExtension(UnittestProto.defaultStringExtension , "415");
- message.setExtension(UnittestProto.defaultBytesExtension , toBytes("416"));
-
- message.setExtension(UnittestProto.defaultNestedEnumExtension,
- TestAllTypes.NestedEnum.FOO);
- message.setExtension(UnittestProto.defaultForeignEnumExtension,
- ForeignEnum.FOREIGN_FOO);
- message.setExtension(UnittestProto.defaultImportEnumExtension,
- ImportEnum.IMPORT_FOO);
-
- message.setExtension(UnittestProto.defaultStringPieceExtension, "424");
- message.setExtension(UnittestProto.defaultCordExtension, "425");
+ message.setExtension(defaultInt32Extension , 401);
+ message.setExtension(defaultInt64Extension , 402L);
+ message.setExtension(defaultUint32Extension , 403);
+ message.setExtension(defaultUint64Extension , 404L);
+ message.setExtension(defaultSint32Extension , 405);
+ message.setExtension(defaultSint64Extension , 406L);
+ message.setExtension(defaultFixed32Extension , 407);
+ message.setExtension(defaultFixed64Extension , 408L);
+ message.setExtension(defaultSfixed32Extension, 409);
+ message.setExtension(defaultSfixed64Extension, 410L);
+ message.setExtension(defaultFloatExtension , 411F);
+ message.setExtension(defaultDoubleExtension , 412D);
+ message.setExtension(defaultBoolExtension , false);
+ message.setExtension(defaultStringExtension , "415");
+ message.setExtension(defaultBytesExtension , toBytes("416"));
+
+ message.setExtension(defaultNestedEnumExtension, TestAllTypes.NestedEnum.FOO);
+ message.setExtension(defaultForeignEnumExtension, ForeignEnum.FOREIGN_FOO);
+ message.setExtension(defaultImportEnumExtension, ImportEnum.IMPORT_FOO);
+
+ message.setExtension(defaultStringPieceExtension, "424");
+ message.setExtension(defaultCordExtension, "425");
}
// -------------------------------------------------------------------
@@ -915,40 +1003,37 @@ class TestUtil {
*/
public static void modifyRepeatedExtensions(
TestAllExtensions.Builder message) {
- message.setExtension(UnittestProto.repeatedInt32Extension , 1, 501);
- message.setExtension(UnittestProto.repeatedInt64Extension , 1, 502L);
- message.setExtension(UnittestProto.repeatedUint32Extension , 1, 503);
- message.setExtension(UnittestProto.repeatedUint64Extension , 1, 504L);
- message.setExtension(UnittestProto.repeatedSint32Extension , 1, 505);
- message.setExtension(UnittestProto.repeatedSint64Extension , 1, 506L);
- message.setExtension(UnittestProto.repeatedFixed32Extension , 1, 507);
- message.setExtension(UnittestProto.repeatedFixed64Extension , 1, 508L);
- message.setExtension(UnittestProto.repeatedSfixed32Extension, 1, 509);
- message.setExtension(UnittestProto.repeatedSfixed64Extension, 1, 510L);
- message.setExtension(UnittestProto.repeatedFloatExtension , 1, 511F);
- message.setExtension(UnittestProto.repeatedDoubleExtension , 1, 512D);
- message.setExtension(UnittestProto.repeatedBoolExtension , 1, true);
- message.setExtension(UnittestProto.repeatedStringExtension , 1, "515");
- message.setExtension(UnittestProto.repeatedBytesExtension , 1, toBytes("516"));
-
- message.setExtension(UnittestProto.repeatedGroupExtension, 1,
- UnittestProto.RepeatedGroup_extension.newBuilder().setA(517).build());
- message.setExtension(UnittestProto.repeatedNestedMessageExtension, 1,
+ message.setExtension(repeatedInt32Extension , 1, 501);
+ message.setExtension(repeatedInt64Extension , 1, 502L);
+ message.setExtension(repeatedUint32Extension , 1, 503);
+ message.setExtension(repeatedUint64Extension , 1, 504L);
+ message.setExtension(repeatedSint32Extension , 1, 505);
+ message.setExtension(repeatedSint64Extension , 1, 506L);
+ message.setExtension(repeatedFixed32Extension , 1, 507);
+ message.setExtension(repeatedFixed64Extension , 1, 508L);
+ message.setExtension(repeatedSfixed32Extension, 1, 509);
+ message.setExtension(repeatedSfixed64Extension, 1, 510L);
+ message.setExtension(repeatedFloatExtension , 1, 511F);
+ message.setExtension(repeatedDoubleExtension , 1, 512D);
+ message.setExtension(repeatedBoolExtension , 1, true);
+ message.setExtension(repeatedStringExtension , 1, "515");
+ message.setExtension(repeatedBytesExtension , 1, toBytes("516"));
+
+ message.setExtension(repeatedGroupExtension, 1,
+ RepeatedGroup_extension.newBuilder().setA(517).build());
+ message.setExtension(repeatedNestedMessageExtension, 1,
TestAllTypes.NestedMessage.newBuilder().setBb(518).build());
- message.setExtension(UnittestProto.repeatedForeignMessageExtension, 1,
+ message.setExtension(repeatedForeignMessageExtension, 1,
ForeignMessage.newBuilder().setC(519).build());
- message.setExtension(UnittestProto.repeatedImportMessageExtension, 1,
+ message.setExtension(repeatedImportMessageExtension, 1,
ImportMessage.newBuilder().setD(520).build());
- message.setExtension(UnittestProto.repeatedNestedEnumExtension , 1,
- TestAllTypes.NestedEnum.FOO);
- message.setExtension(UnittestProto.repeatedForeignEnumExtension, 1,
- ForeignEnum.FOREIGN_FOO);
- message.setExtension(UnittestProto.repeatedImportEnumExtension , 1,
- ImportEnum.IMPORT_FOO);
+ message.setExtension(repeatedNestedEnumExtension , 1, TestAllTypes.NestedEnum.FOO);
+ message.setExtension(repeatedForeignEnumExtension, 1, ForeignEnum.FOREIGN_FOO);
+ message.setExtension(repeatedImportEnumExtension , 1, ImportEnum.IMPORT_FOO);
- message.setExtension(UnittestProto.repeatedStringPieceExtension, 1, "524");
- message.setExtension(UnittestProto.repeatedCordExtension, 1, "525");
+ message.setExtension(repeatedStringPieceExtension, 1, "524");
+ message.setExtension(repeatedCordExtension, 1, "525");
}
// -------------------------------------------------------------------
@@ -958,211 +1043,211 @@ class TestUtil {
* {@code message} are set to the values assigned by {@code setAllExtensions}.
*/
public static void assertAllExtensionsSet(TestAllExtensions message) {
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalInt32Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalInt64Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalUint32Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalUint64Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalSint32Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalSint64Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalFixed32Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalFixed64Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalSfixed32Extension));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalSfixed64Extension));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalFloatExtension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalDoubleExtension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalBoolExtension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalStringExtension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalBytesExtension ));
-
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalGroupExtension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalNestedMessageExtension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalForeignMessageExtension));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalImportMessageExtension ));
-
- Assert.assertTrue(message.getExtension(UnittestProto.optionalGroupExtension ).hasA());
- Assert.assertTrue(message.getExtension(UnittestProto.optionalNestedMessageExtension ).hasBb());
- Assert.assertTrue(message.getExtension(UnittestProto.optionalForeignMessageExtension).hasC());
- Assert.assertTrue(message.getExtension(UnittestProto.optionalImportMessageExtension ).hasD());
-
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalNestedEnumExtension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalForeignEnumExtension));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalImportEnumExtension ));
-
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalStringPieceExtension));
- Assert.assertTrue(message.hasExtension(UnittestProto.optionalCordExtension));
-
- assertEqualsExactType(101 , message.getExtension(UnittestProto.optionalInt32Extension ));
- assertEqualsExactType(102L , message.getExtension(UnittestProto.optionalInt64Extension ));
- assertEqualsExactType(103 , message.getExtension(UnittestProto.optionalUint32Extension ));
- assertEqualsExactType(104L , message.getExtension(UnittestProto.optionalUint64Extension ));
- assertEqualsExactType(105 , message.getExtension(UnittestProto.optionalSint32Extension ));
- assertEqualsExactType(106L , message.getExtension(UnittestProto.optionalSint64Extension ));
- assertEqualsExactType(107 , message.getExtension(UnittestProto.optionalFixed32Extension ));
- assertEqualsExactType(108L , message.getExtension(UnittestProto.optionalFixed64Extension ));
- assertEqualsExactType(109 , message.getExtension(UnittestProto.optionalSfixed32Extension));
- assertEqualsExactType(110L , message.getExtension(UnittestProto.optionalSfixed64Extension));
- assertEqualsExactType(111F , message.getExtension(UnittestProto.optionalFloatExtension ));
- assertEqualsExactType(112D , message.getExtension(UnittestProto.optionalDoubleExtension ));
- assertEqualsExactType(true , message.getExtension(UnittestProto.optionalBoolExtension ));
- assertEqualsExactType("115", message.getExtension(UnittestProto.optionalStringExtension ));
- assertEqualsExactType(toBytes("116"), message.getExtension(UnittestProto.optionalBytesExtension));
-
- assertEqualsExactType(117, message.getExtension(UnittestProto.optionalGroupExtension ).getA());
- assertEqualsExactType(118, message.getExtension(UnittestProto.optionalNestedMessageExtension ).getBb());
- assertEqualsExactType(119, message.getExtension(UnittestProto.optionalForeignMessageExtension).getC());
- assertEqualsExactType(120, message.getExtension(UnittestProto.optionalImportMessageExtension ).getD());
+ Assert.assertTrue(message.hasExtension(optionalInt32Extension ));
+ Assert.assertTrue(message.hasExtension(optionalInt64Extension ));
+ Assert.assertTrue(message.hasExtension(optionalUint32Extension ));
+ Assert.assertTrue(message.hasExtension(optionalUint64Extension ));
+ Assert.assertTrue(message.hasExtension(optionalSint32Extension ));
+ Assert.assertTrue(message.hasExtension(optionalSint64Extension ));
+ Assert.assertTrue(message.hasExtension(optionalFixed32Extension ));
+ Assert.assertTrue(message.hasExtension(optionalFixed64Extension ));
+ Assert.assertTrue(message.hasExtension(optionalSfixed32Extension));
+ Assert.assertTrue(message.hasExtension(optionalSfixed64Extension));
+ Assert.assertTrue(message.hasExtension(optionalFloatExtension ));
+ Assert.assertTrue(message.hasExtension(optionalDoubleExtension ));
+ Assert.assertTrue(message.hasExtension(optionalBoolExtension ));
+ Assert.assertTrue(message.hasExtension(optionalStringExtension ));
+ Assert.assertTrue(message.hasExtension(optionalBytesExtension ));
+
+ Assert.assertTrue(message.hasExtension(optionalGroupExtension ));
+ Assert.assertTrue(message.hasExtension(optionalNestedMessageExtension ));
+ Assert.assertTrue(message.hasExtension(optionalForeignMessageExtension));
+ Assert.assertTrue(message.hasExtension(optionalImportMessageExtension ));
+
+ Assert.assertTrue(message.getExtension(optionalGroupExtension ).hasA());
+ Assert.assertTrue(message.getExtension(optionalNestedMessageExtension ).hasBb());
+ Assert.assertTrue(message.getExtension(optionalForeignMessageExtension).hasC());
+ Assert.assertTrue(message.getExtension(optionalImportMessageExtension ).hasD());
+
+ Assert.assertTrue(message.hasExtension(optionalNestedEnumExtension ));
+ Assert.assertTrue(message.hasExtension(optionalForeignEnumExtension));
+ Assert.assertTrue(message.hasExtension(optionalImportEnumExtension ));
+
+ Assert.assertTrue(message.hasExtension(optionalStringPieceExtension));
+ Assert.assertTrue(message.hasExtension(optionalCordExtension));
+
+ assertEqualsExactType(101 , message.getExtension(optionalInt32Extension ));
+ assertEqualsExactType(102L , message.getExtension(optionalInt64Extension ));
+ assertEqualsExactType(103 , message.getExtension(optionalUint32Extension ));
+ assertEqualsExactType(104L , message.getExtension(optionalUint64Extension ));
+ assertEqualsExactType(105 , message.getExtension(optionalSint32Extension ));
+ assertEqualsExactType(106L , message.getExtension(optionalSint64Extension ));
+ assertEqualsExactType(107 , message.getExtension(optionalFixed32Extension ));
+ assertEqualsExactType(108L , message.getExtension(optionalFixed64Extension ));
+ assertEqualsExactType(109 , message.getExtension(optionalSfixed32Extension));
+ assertEqualsExactType(110L , message.getExtension(optionalSfixed64Extension));
+ assertEqualsExactType(111F , message.getExtension(optionalFloatExtension ));
+ assertEqualsExactType(112D , message.getExtension(optionalDoubleExtension ));
+ assertEqualsExactType(true , message.getExtension(optionalBoolExtension ));
+ assertEqualsExactType("115", message.getExtension(optionalStringExtension ));
+ assertEqualsExactType(toBytes("116"), message.getExtension(optionalBytesExtension));
+
+ assertEqualsExactType(117, message.getExtension(optionalGroupExtension ).getA());
+ assertEqualsExactType(118, message.getExtension(optionalNestedMessageExtension ).getBb());
+ assertEqualsExactType(119, message.getExtension(optionalForeignMessageExtension).getC());
+ assertEqualsExactType(120, message.getExtension(optionalImportMessageExtension ).getD());
assertEqualsExactType(TestAllTypes.NestedEnum.BAZ,
- message.getExtension(UnittestProto.optionalNestedEnumExtension));
+ message.getExtension(optionalNestedEnumExtension));
assertEqualsExactType(ForeignEnum.FOREIGN_BAZ,
- message.getExtension(UnittestProto.optionalForeignEnumExtension));
+ message.getExtension(optionalForeignEnumExtension));
assertEqualsExactType(ImportEnum.IMPORT_BAZ,
- message.getExtension(UnittestProto.optionalImportEnumExtension));
+ message.getExtension(optionalImportEnumExtension));
- assertEqualsExactType("124", message.getExtension(UnittestProto.optionalStringPieceExtension));
- assertEqualsExactType("125", message.getExtension(UnittestProto.optionalCordExtension));
+ assertEqualsExactType("124", message.getExtension(optionalStringPieceExtension));
+ assertEqualsExactType("125", message.getExtension(optionalCordExtension));
// -----------------------------------------------------------------
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedInt32Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedInt64Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedUint32Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedUint64Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedSint32Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedSint64Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedFixed32Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedFixed64Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedSfixed32Extension));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedSfixed64Extension));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedFloatExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedDoubleExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedBoolExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedStringExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedBytesExtension ));
-
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedGroupExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedNestedMessageExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedForeignMessageExtension));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedImportMessageExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedNestedEnumExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedForeignEnumExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedImportEnumExtension ));
-
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedStringPieceExtension));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedCordExtension));
-
- assertEqualsExactType(201 , message.getExtension(UnittestProto.repeatedInt32Extension , 0));
- assertEqualsExactType(202L , message.getExtension(UnittestProto.repeatedInt64Extension , 0));
- assertEqualsExactType(203 , message.getExtension(UnittestProto.repeatedUint32Extension , 0));
- assertEqualsExactType(204L , message.getExtension(UnittestProto.repeatedUint64Extension , 0));
- assertEqualsExactType(205 , message.getExtension(UnittestProto.repeatedSint32Extension , 0));
- assertEqualsExactType(206L , message.getExtension(UnittestProto.repeatedSint64Extension , 0));
- assertEqualsExactType(207 , message.getExtension(UnittestProto.repeatedFixed32Extension , 0));
- assertEqualsExactType(208L , message.getExtension(UnittestProto.repeatedFixed64Extension , 0));
- assertEqualsExactType(209 , message.getExtension(UnittestProto.repeatedSfixed32Extension, 0));
- assertEqualsExactType(210L , message.getExtension(UnittestProto.repeatedSfixed64Extension, 0));
- assertEqualsExactType(211F , message.getExtension(UnittestProto.repeatedFloatExtension , 0));
- assertEqualsExactType(212D , message.getExtension(UnittestProto.repeatedDoubleExtension , 0));
- assertEqualsExactType(true , message.getExtension(UnittestProto.repeatedBoolExtension , 0));
- assertEqualsExactType("215", message.getExtension(UnittestProto.repeatedStringExtension , 0));
- assertEqualsExactType(toBytes("216"), message.getExtension(UnittestProto.repeatedBytesExtension, 0));
-
- assertEqualsExactType(217, message.getExtension(UnittestProto.repeatedGroupExtension , 0).getA());
- assertEqualsExactType(218, message.getExtension(UnittestProto.repeatedNestedMessageExtension , 0).getBb());
- assertEqualsExactType(219, message.getExtension(UnittestProto.repeatedForeignMessageExtension, 0).getC());
- assertEqualsExactType(220, message.getExtension(UnittestProto.repeatedImportMessageExtension , 0).getD());
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32Extension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64Extension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtension ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtension ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtension));
+
+ assertEqualsExactType(201 , message.getExtension(repeatedInt32Extension , 0));
+ assertEqualsExactType(202L , message.getExtension(repeatedInt64Extension , 0));
+ assertEqualsExactType(203 , message.getExtension(repeatedUint32Extension , 0));
+ assertEqualsExactType(204L , message.getExtension(repeatedUint64Extension , 0));
+ assertEqualsExactType(205 , message.getExtension(repeatedSint32Extension , 0));
+ assertEqualsExactType(206L , message.getExtension(repeatedSint64Extension , 0));
+ assertEqualsExactType(207 , message.getExtension(repeatedFixed32Extension , 0));
+ assertEqualsExactType(208L , message.getExtension(repeatedFixed64Extension , 0));
+ assertEqualsExactType(209 , message.getExtension(repeatedSfixed32Extension, 0));
+ assertEqualsExactType(210L , message.getExtension(repeatedSfixed64Extension, 0));
+ assertEqualsExactType(211F , message.getExtension(repeatedFloatExtension , 0));
+ assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtension , 0));
+ assertEqualsExactType(true , message.getExtension(repeatedBoolExtension , 0));
+ assertEqualsExactType("215", message.getExtension(repeatedStringExtension , 0));
+ assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtension, 0));
+
+ assertEqualsExactType(217, message.getExtension(repeatedGroupExtension , 0).getA());
+ assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtension , 0).getBb());
+ assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtension, 0).getC());
+ assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtension , 0).getD());
assertEqualsExactType(TestAllTypes.NestedEnum.BAR,
- message.getExtension(UnittestProto.repeatedNestedEnumExtension, 0));
+ message.getExtension(repeatedNestedEnumExtension, 0));
assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
- message.getExtension(UnittestProto.repeatedForeignEnumExtension, 0));
+ message.getExtension(repeatedForeignEnumExtension, 0));
assertEqualsExactType(ImportEnum.IMPORT_BAR,
- message.getExtension(UnittestProto.repeatedImportEnumExtension, 0));
-
- assertEqualsExactType("224", message.getExtension(UnittestProto.repeatedStringPieceExtension, 0));
- assertEqualsExactType("225", message.getExtension(UnittestProto.repeatedCordExtension, 0));
-
- assertEqualsExactType(301 , message.getExtension(UnittestProto.repeatedInt32Extension , 1));
- assertEqualsExactType(302L , message.getExtension(UnittestProto.repeatedInt64Extension , 1));
- assertEqualsExactType(303 , message.getExtension(UnittestProto.repeatedUint32Extension , 1));
- assertEqualsExactType(304L , message.getExtension(UnittestProto.repeatedUint64Extension , 1));
- assertEqualsExactType(305 , message.getExtension(UnittestProto.repeatedSint32Extension , 1));
- assertEqualsExactType(306L , message.getExtension(UnittestProto.repeatedSint64Extension , 1));
- assertEqualsExactType(307 , message.getExtension(UnittestProto.repeatedFixed32Extension , 1));
- assertEqualsExactType(308L , message.getExtension(UnittestProto.repeatedFixed64Extension , 1));
- assertEqualsExactType(309 , message.getExtension(UnittestProto.repeatedSfixed32Extension, 1));
- assertEqualsExactType(310L , message.getExtension(UnittestProto.repeatedSfixed64Extension, 1));
- assertEqualsExactType(311F , message.getExtension(UnittestProto.repeatedFloatExtension , 1));
- assertEqualsExactType(312D , message.getExtension(UnittestProto.repeatedDoubleExtension , 1));
- assertEqualsExactType(false, message.getExtension(UnittestProto.repeatedBoolExtension , 1));
- assertEqualsExactType("315", message.getExtension(UnittestProto.repeatedStringExtension , 1));
- assertEqualsExactType(toBytes("316"), message.getExtension(UnittestProto.repeatedBytesExtension, 1));
-
- assertEqualsExactType(317, message.getExtension(UnittestProto.repeatedGroupExtension , 1).getA());
- assertEqualsExactType(318, message.getExtension(UnittestProto.repeatedNestedMessageExtension , 1).getBb());
- assertEqualsExactType(319, message.getExtension(UnittestProto.repeatedForeignMessageExtension, 1).getC());
- assertEqualsExactType(320, message.getExtension(UnittestProto.repeatedImportMessageExtension , 1).getD());
+ message.getExtension(repeatedImportEnumExtension, 0));
+
+ assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtension, 0));
+ assertEqualsExactType("225", message.getExtension(repeatedCordExtension, 0));
+
+ assertEqualsExactType(301 , message.getExtension(repeatedInt32Extension , 1));
+ assertEqualsExactType(302L , message.getExtension(repeatedInt64Extension , 1));
+ assertEqualsExactType(303 , message.getExtension(repeatedUint32Extension , 1));
+ assertEqualsExactType(304L , message.getExtension(repeatedUint64Extension , 1));
+ assertEqualsExactType(305 , message.getExtension(repeatedSint32Extension , 1));
+ assertEqualsExactType(306L , message.getExtension(repeatedSint64Extension , 1));
+ assertEqualsExactType(307 , message.getExtension(repeatedFixed32Extension , 1));
+ assertEqualsExactType(308L , message.getExtension(repeatedFixed64Extension , 1));
+ assertEqualsExactType(309 , message.getExtension(repeatedSfixed32Extension, 1));
+ assertEqualsExactType(310L , message.getExtension(repeatedSfixed64Extension, 1));
+ assertEqualsExactType(311F , message.getExtension(repeatedFloatExtension , 1));
+ assertEqualsExactType(312D , message.getExtension(repeatedDoubleExtension , 1));
+ assertEqualsExactType(false, message.getExtension(repeatedBoolExtension , 1));
+ assertEqualsExactType("315", message.getExtension(repeatedStringExtension , 1));
+ assertEqualsExactType(toBytes("316"), message.getExtension(repeatedBytesExtension, 1));
+
+ assertEqualsExactType(317, message.getExtension(repeatedGroupExtension , 1).getA());
+ assertEqualsExactType(318, message.getExtension(repeatedNestedMessageExtension , 1).getBb());
+ assertEqualsExactType(319, message.getExtension(repeatedForeignMessageExtension, 1).getC());
+ assertEqualsExactType(320, message.getExtension(repeatedImportMessageExtension , 1).getD());
assertEqualsExactType(TestAllTypes.NestedEnum.BAZ,
- message.getExtension(UnittestProto.repeatedNestedEnumExtension, 1));
+ message.getExtension(repeatedNestedEnumExtension, 1));
assertEqualsExactType(ForeignEnum.FOREIGN_BAZ,
- message.getExtension(UnittestProto.repeatedForeignEnumExtension, 1));
+ message.getExtension(repeatedForeignEnumExtension, 1));
assertEqualsExactType(ImportEnum.IMPORT_BAZ,
- message.getExtension(UnittestProto.repeatedImportEnumExtension, 1));
+ message.getExtension(repeatedImportEnumExtension, 1));
- assertEqualsExactType("324", message.getExtension(UnittestProto.repeatedStringPieceExtension, 1));
- assertEqualsExactType("325", message.getExtension(UnittestProto.repeatedCordExtension, 1));
+ assertEqualsExactType("324", message.getExtension(repeatedStringPieceExtension, 1));
+ assertEqualsExactType("325", message.getExtension(repeatedCordExtension, 1));
// -----------------------------------------------------------------
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultInt32Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultInt64Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultUint32Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultUint64Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultSint32Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultSint64Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultFixed32Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultFixed64Extension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultSfixed32Extension));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultSfixed64Extension));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultFloatExtension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultDoubleExtension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultBoolExtension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultStringExtension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultBytesExtension ));
-
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultNestedEnumExtension ));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultForeignEnumExtension));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultImportEnumExtension ));
-
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultStringPieceExtension));
- Assert.assertTrue(message.hasExtension(UnittestProto.defaultCordExtension));
-
- assertEqualsExactType(401 , message.getExtension(UnittestProto.defaultInt32Extension ));
- assertEqualsExactType(402L , message.getExtension(UnittestProto.defaultInt64Extension ));
- assertEqualsExactType(403 , message.getExtension(UnittestProto.defaultUint32Extension ));
- assertEqualsExactType(404L , message.getExtension(UnittestProto.defaultUint64Extension ));
- assertEqualsExactType(405 , message.getExtension(UnittestProto.defaultSint32Extension ));
- assertEqualsExactType(406L , message.getExtension(UnittestProto.defaultSint64Extension ));
- assertEqualsExactType(407 , message.getExtension(UnittestProto.defaultFixed32Extension ));
- assertEqualsExactType(408L , message.getExtension(UnittestProto.defaultFixed64Extension ));
- assertEqualsExactType(409 , message.getExtension(UnittestProto.defaultSfixed32Extension));
- assertEqualsExactType(410L , message.getExtension(UnittestProto.defaultSfixed64Extension));
- assertEqualsExactType(411F , message.getExtension(UnittestProto.defaultFloatExtension ));
- assertEqualsExactType(412D , message.getExtension(UnittestProto.defaultDoubleExtension ));
- assertEqualsExactType(false, message.getExtension(UnittestProto.defaultBoolExtension ));
- assertEqualsExactType("415", message.getExtension(UnittestProto.defaultStringExtension ));
- assertEqualsExactType(toBytes("416"), message.getExtension(UnittestProto.defaultBytesExtension));
+ Assert.assertTrue(message.hasExtension(defaultInt32Extension ));
+ Assert.assertTrue(message.hasExtension(defaultInt64Extension ));
+ Assert.assertTrue(message.hasExtension(defaultUint32Extension ));
+ Assert.assertTrue(message.hasExtension(defaultUint64Extension ));
+ Assert.assertTrue(message.hasExtension(defaultSint32Extension ));
+ Assert.assertTrue(message.hasExtension(defaultSint64Extension ));
+ Assert.assertTrue(message.hasExtension(defaultFixed32Extension ));
+ Assert.assertTrue(message.hasExtension(defaultFixed64Extension ));
+ Assert.assertTrue(message.hasExtension(defaultSfixed32Extension));
+ Assert.assertTrue(message.hasExtension(defaultSfixed64Extension));
+ Assert.assertTrue(message.hasExtension(defaultFloatExtension ));
+ Assert.assertTrue(message.hasExtension(defaultDoubleExtension ));
+ Assert.assertTrue(message.hasExtension(defaultBoolExtension ));
+ Assert.assertTrue(message.hasExtension(defaultStringExtension ));
+ Assert.assertTrue(message.hasExtension(defaultBytesExtension ));
+
+ Assert.assertTrue(message.hasExtension(defaultNestedEnumExtension ));
+ Assert.assertTrue(message.hasExtension(defaultForeignEnumExtension));
+ Assert.assertTrue(message.hasExtension(defaultImportEnumExtension ));
+
+ Assert.assertTrue(message.hasExtension(defaultStringPieceExtension));
+ Assert.assertTrue(message.hasExtension(defaultCordExtension));
+
+ assertEqualsExactType(401 , message.getExtension(defaultInt32Extension ));
+ assertEqualsExactType(402L , message.getExtension(defaultInt64Extension ));
+ assertEqualsExactType(403 , message.getExtension(defaultUint32Extension ));
+ assertEqualsExactType(404L , message.getExtension(defaultUint64Extension ));
+ assertEqualsExactType(405 , message.getExtension(defaultSint32Extension ));
+ assertEqualsExactType(406L , message.getExtension(defaultSint64Extension ));
+ assertEqualsExactType(407 , message.getExtension(defaultFixed32Extension ));
+ assertEqualsExactType(408L , message.getExtension(defaultFixed64Extension ));
+ assertEqualsExactType(409 , message.getExtension(defaultSfixed32Extension));
+ assertEqualsExactType(410L , message.getExtension(defaultSfixed64Extension));
+ assertEqualsExactType(411F , message.getExtension(defaultFloatExtension ));
+ assertEqualsExactType(412D , message.getExtension(defaultDoubleExtension ));
+ assertEqualsExactType(false, message.getExtension(defaultBoolExtension ));
+ assertEqualsExactType("415", message.getExtension(defaultStringExtension ));
+ assertEqualsExactType(toBytes("416"), message.getExtension(defaultBytesExtension));
assertEqualsExactType(TestAllTypes.NestedEnum.FOO,
- message.getExtension(UnittestProto.defaultNestedEnumExtension ));
+ message.getExtension(defaultNestedEnumExtension ));
assertEqualsExactType(ForeignEnum.FOREIGN_FOO,
- message.getExtension(UnittestProto.defaultForeignEnumExtension));
+ message.getExtension(defaultForeignEnumExtension));
assertEqualsExactType(ImportEnum.IMPORT_FOO,
- message.getExtension(UnittestProto.defaultImportEnumExtension));
+ message.getExtension(defaultImportEnumExtension));
- assertEqualsExactType("424", message.getExtension(UnittestProto.defaultStringPieceExtension));
- assertEqualsExactType("425", message.getExtension(UnittestProto.defaultCordExtension));
+ assertEqualsExactType("424", message.getExtension(defaultStringPieceExtension));
+ assertEqualsExactType("425", message.getExtension(defaultCordExtension));
}
// -------------------------------------------------------------------
@@ -1174,151 +1259,151 @@ class TestUtil {
*/
public static void assertExtensionsClear(TestAllExtensions message) {
// hasBlah() should initially be false for all optional fields.
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalInt32Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalInt64Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalUint32Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalUint64Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalSint32Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalSint64Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalFixed32Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalFixed64Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalSfixed32Extension));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalSfixed64Extension));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalFloatExtension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalDoubleExtension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalBoolExtension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalStringExtension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalBytesExtension ));
-
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalGroupExtension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalNestedMessageExtension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalForeignMessageExtension));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalImportMessageExtension ));
-
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalNestedEnumExtension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalForeignEnumExtension));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalImportEnumExtension ));
-
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalStringPieceExtension));
- Assert.assertFalse(message.hasExtension(UnittestProto.optionalCordExtension));
+ Assert.assertFalse(message.hasExtension(optionalInt32Extension ));
+ Assert.assertFalse(message.hasExtension(optionalInt64Extension ));
+ Assert.assertFalse(message.hasExtension(optionalUint32Extension ));
+ Assert.assertFalse(message.hasExtension(optionalUint64Extension ));
+ Assert.assertFalse(message.hasExtension(optionalSint32Extension ));
+ Assert.assertFalse(message.hasExtension(optionalSint64Extension ));
+ Assert.assertFalse(message.hasExtension(optionalFixed32Extension ));
+ Assert.assertFalse(message.hasExtension(optionalFixed64Extension ));
+ Assert.assertFalse(message.hasExtension(optionalSfixed32Extension));
+ Assert.assertFalse(message.hasExtension(optionalSfixed64Extension));
+ Assert.assertFalse(message.hasExtension(optionalFloatExtension ));
+ Assert.assertFalse(message.hasExtension(optionalDoubleExtension ));
+ Assert.assertFalse(message.hasExtension(optionalBoolExtension ));
+ Assert.assertFalse(message.hasExtension(optionalStringExtension ));
+ Assert.assertFalse(message.hasExtension(optionalBytesExtension ));
+
+ Assert.assertFalse(message.hasExtension(optionalGroupExtension ));
+ Assert.assertFalse(message.hasExtension(optionalNestedMessageExtension ));
+ Assert.assertFalse(message.hasExtension(optionalForeignMessageExtension));
+ Assert.assertFalse(message.hasExtension(optionalImportMessageExtension ));
+
+ Assert.assertFalse(message.hasExtension(optionalNestedEnumExtension ));
+ Assert.assertFalse(message.hasExtension(optionalForeignEnumExtension));
+ Assert.assertFalse(message.hasExtension(optionalImportEnumExtension ));
+
+ Assert.assertFalse(message.hasExtension(optionalStringPieceExtension));
+ Assert.assertFalse(message.hasExtension(optionalCordExtension));
// Optional fields without defaults are set to zero or something like it.
- assertEqualsExactType(0 , message.getExtension(UnittestProto.optionalInt32Extension ));
- assertEqualsExactType(0L , message.getExtension(UnittestProto.optionalInt64Extension ));
- assertEqualsExactType(0 , message.getExtension(UnittestProto.optionalUint32Extension ));
- assertEqualsExactType(0L , message.getExtension(UnittestProto.optionalUint64Extension ));
- assertEqualsExactType(0 , message.getExtension(UnittestProto.optionalSint32Extension ));
- assertEqualsExactType(0L , message.getExtension(UnittestProto.optionalSint64Extension ));
- assertEqualsExactType(0 , message.getExtension(UnittestProto.optionalFixed32Extension ));
- assertEqualsExactType(0L , message.getExtension(UnittestProto.optionalFixed64Extension ));
- assertEqualsExactType(0 , message.getExtension(UnittestProto.optionalSfixed32Extension));
- assertEqualsExactType(0L , message.getExtension(UnittestProto.optionalSfixed64Extension));
- assertEqualsExactType(0F , message.getExtension(UnittestProto.optionalFloatExtension ));
- assertEqualsExactType(0D , message.getExtension(UnittestProto.optionalDoubleExtension ));
- assertEqualsExactType(false, message.getExtension(UnittestProto.optionalBoolExtension ));
- assertEqualsExactType("" , message.getExtension(UnittestProto.optionalStringExtension ));
- assertEqualsExactType(ByteString.EMPTY, message.getExtension(UnittestProto.optionalBytesExtension));
+ assertEqualsExactType(0 , message.getExtension(optionalInt32Extension ));
+ assertEqualsExactType(0L , message.getExtension(optionalInt64Extension ));
+ assertEqualsExactType(0 , message.getExtension(optionalUint32Extension ));
+ assertEqualsExactType(0L , message.getExtension(optionalUint64Extension ));
+ assertEqualsExactType(0 , message.getExtension(optionalSint32Extension ));
+ assertEqualsExactType(0L , message.getExtension(optionalSint64Extension ));
+ assertEqualsExactType(0 , message.getExtension(optionalFixed32Extension ));
+ assertEqualsExactType(0L , message.getExtension(optionalFixed64Extension ));
+ assertEqualsExactType(0 , message.getExtension(optionalSfixed32Extension));
+ assertEqualsExactType(0L , message.getExtension(optionalSfixed64Extension));
+ assertEqualsExactType(0F , message.getExtension(optionalFloatExtension ));
+ assertEqualsExactType(0D , message.getExtension(optionalDoubleExtension ));
+ assertEqualsExactType(false, message.getExtension(optionalBoolExtension ));
+ assertEqualsExactType("" , message.getExtension(optionalStringExtension ));
+ assertEqualsExactType(ByteString.EMPTY, message.getExtension(optionalBytesExtension));
// Embedded messages should also be clear.
- Assert.assertFalse(message.getExtension(UnittestProto.optionalGroupExtension ).hasA());
- Assert.assertFalse(message.getExtension(UnittestProto.optionalNestedMessageExtension ).hasBb());
- Assert.assertFalse(message.getExtension(UnittestProto.optionalForeignMessageExtension).hasC());
- Assert.assertFalse(message.getExtension(UnittestProto.optionalImportMessageExtension ).hasD());
+ Assert.assertFalse(message.getExtension(optionalGroupExtension ).hasA());
+ Assert.assertFalse(message.getExtension(optionalNestedMessageExtension ).hasBb());
+ Assert.assertFalse(message.getExtension(optionalForeignMessageExtension).hasC());
+ Assert.assertFalse(message.getExtension(optionalImportMessageExtension ).hasD());
- assertEqualsExactType(0, message.getExtension(UnittestProto.optionalGroupExtension ).getA());
- assertEqualsExactType(0, message.getExtension(UnittestProto.optionalNestedMessageExtension ).getBb());
- assertEqualsExactType(0, message.getExtension(UnittestProto.optionalForeignMessageExtension).getC());
- assertEqualsExactType(0, message.getExtension(UnittestProto.optionalImportMessageExtension ).getD());
+ assertEqualsExactType(0, message.getExtension(optionalGroupExtension ).getA());
+ assertEqualsExactType(0, message.getExtension(optionalNestedMessageExtension ).getBb());
+ assertEqualsExactType(0, message.getExtension(optionalForeignMessageExtension).getC());
+ assertEqualsExactType(0, message.getExtension(optionalImportMessageExtension ).getD());
// Enums without defaults are set to the first value in the enum.
assertEqualsExactType(TestAllTypes.NestedEnum.FOO,
- message.getExtension(UnittestProto.optionalNestedEnumExtension ));
+ message.getExtension(optionalNestedEnumExtension ));
assertEqualsExactType(ForeignEnum.FOREIGN_FOO,
- message.getExtension(UnittestProto.optionalForeignEnumExtension));
+ message.getExtension(optionalForeignEnumExtension));
assertEqualsExactType(ImportEnum.IMPORT_FOO,
- message.getExtension(UnittestProto.optionalImportEnumExtension));
+ message.getExtension(optionalImportEnumExtension));
- assertEqualsExactType("", message.getExtension(UnittestProto.optionalStringPieceExtension));
- assertEqualsExactType("", message.getExtension(UnittestProto.optionalCordExtension));
+ assertEqualsExactType("", message.getExtension(optionalStringPieceExtension));
+ assertEqualsExactType("", message.getExtension(optionalCordExtension));
// Repeated fields are empty.
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedInt32Extension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedInt64Extension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedUint32Extension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedUint64Extension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedSint32Extension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedSint64Extension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedFixed32Extension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedFixed64Extension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedSfixed32Extension));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedSfixed64Extension));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedFloatExtension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedDoubleExtension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedBoolExtension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedStringExtension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedBytesExtension ));
-
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedGroupExtension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedNestedMessageExtension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedForeignMessageExtension));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedImportMessageExtension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedNestedEnumExtension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedForeignEnumExtension ));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedImportEnumExtension ));
-
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedStringPieceExtension));
- Assert.assertEquals(0, message.getExtensionCount(UnittestProto.repeatedCordExtension));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedInt32Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedInt64Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedUint32Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedUint64Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSint32Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSint64Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedFixed32Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedFixed64Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed32Extension));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed64Extension));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedFloatExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedDoubleExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedBoolExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedStringExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedBytesExtension ));
+
+ Assert.assertEquals(0, message.getExtensionCount(repeatedGroupExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedNestedMessageExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedForeignMessageExtension));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedImportMessageExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedNestedEnumExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedForeignEnumExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedImportEnumExtension ));
+
+ Assert.assertEquals(0, message.getExtensionCount(repeatedStringPieceExtension));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedCordExtension));
// hasBlah() should also be false for all default fields.
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultInt32Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultInt64Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultUint32Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultUint64Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultSint32Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultSint64Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultFixed32Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultFixed64Extension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultSfixed32Extension));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultSfixed64Extension));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultFloatExtension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultDoubleExtension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultBoolExtension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultStringExtension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultBytesExtension ));
-
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultNestedEnumExtension ));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultForeignEnumExtension));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultImportEnumExtension ));
-
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultStringPieceExtension));
- Assert.assertFalse(message.hasExtension(UnittestProto.defaultCordExtension));
+ Assert.assertFalse(message.hasExtension(defaultInt32Extension ));
+ Assert.assertFalse(message.hasExtension(defaultInt64Extension ));
+ Assert.assertFalse(message.hasExtension(defaultUint32Extension ));
+ Assert.assertFalse(message.hasExtension(defaultUint64Extension ));
+ Assert.assertFalse(message.hasExtension(defaultSint32Extension ));
+ Assert.assertFalse(message.hasExtension(defaultSint64Extension ));
+ Assert.assertFalse(message.hasExtension(defaultFixed32Extension ));
+ Assert.assertFalse(message.hasExtension(defaultFixed64Extension ));
+ Assert.assertFalse(message.hasExtension(defaultSfixed32Extension));
+ Assert.assertFalse(message.hasExtension(defaultSfixed64Extension));
+ Assert.assertFalse(message.hasExtension(defaultFloatExtension ));
+ Assert.assertFalse(message.hasExtension(defaultDoubleExtension ));
+ Assert.assertFalse(message.hasExtension(defaultBoolExtension ));
+ Assert.assertFalse(message.hasExtension(defaultStringExtension ));
+ Assert.assertFalse(message.hasExtension(defaultBytesExtension ));
+
+ Assert.assertFalse(message.hasExtension(defaultNestedEnumExtension ));
+ Assert.assertFalse(message.hasExtension(defaultForeignEnumExtension));
+ Assert.assertFalse(message.hasExtension(defaultImportEnumExtension ));
+
+ Assert.assertFalse(message.hasExtension(defaultStringPieceExtension));
+ Assert.assertFalse(message.hasExtension(defaultCordExtension));
// Fields with defaults have their default values (duh).
- assertEqualsExactType( 41 , message.getExtension(UnittestProto.defaultInt32Extension ));
- assertEqualsExactType( 42L , message.getExtension(UnittestProto.defaultInt64Extension ));
- assertEqualsExactType( 43 , message.getExtension(UnittestProto.defaultUint32Extension ));
- assertEqualsExactType( 44L , message.getExtension(UnittestProto.defaultUint64Extension ));
- assertEqualsExactType(-45 , message.getExtension(UnittestProto.defaultSint32Extension ));
- assertEqualsExactType( 46L , message.getExtension(UnittestProto.defaultSint64Extension ));
- assertEqualsExactType( 47 , message.getExtension(UnittestProto.defaultFixed32Extension ));
- assertEqualsExactType( 48L , message.getExtension(UnittestProto.defaultFixed64Extension ));
- assertEqualsExactType( 49 , message.getExtension(UnittestProto.defaultSfixed32Extension));
- assertEqualsExactType(-50L , message.getExtension(UnittestProto.defaultSfixed64Extension));
- assertEqualsExactType( 51.5F , message.getExtension(UnittestProto.defaultFloatExtension ));
- assertEqualsExactType( 52e3D , message.getExtension(UnittestProto.defaultDoubleExtension ));
- assertEqualsExactType(true , message.getExtension(UnittestProto.defaultBoolExtension ));
- assertEqualsExactType("hello", message.getExtension(UnittestProto.defaultStringExtension ));
- assertEqualsExactType(toBytes("world"), message.getExtension(UnittestProto.defaultBytesExtension));
+ assertEqualsExactType( 41 , message.getExtension(defaultInt32Extension ));
+ assertEqualsExactType( 42L , message.getExtension(defaultInt64Extension ));
+ assertEqualsExactType( 43 , message.getExtension(defaultUint32Extension ));
+ assertEqualsExactType( 44L , message.getExtension(defaultUint64Extension ));
+ assertEqualsExactType(-45 , message.getExtension(defaultSint32Extension ));
+ assertEqualsExactType( 46L , message.getExtension(defaultSint64Extension ));
+ assertEqualsExactType( 47 , message.getExtension(defaultFixed32Extension ));
+ assertEqualsExactType( 48L , message.getExtension(defaultFixed64Extension ));
+ assertEqualsExactType( 49 , message.getExtension(defaultSfixed32Extension));
+ assertEqualsExactType(-50L , message.getExtension(defaultSfixed64Extension));
+ assertEqualsExactType( 51.5F , message.getExtension(defaultFloatExtension ));
+ assertEqualsExactType( 52e3D , message.getExtension(defaultDoubleExtension ));
+ assertEqualsExactType(true , message.getExtension(defaultBoolExtension ));
+ assertEqualsExactType("hello", message.getExtension(defaultStringExtension ));
+ assertEqualsExactType(toBytes("world"), message.getExtension(defaultBytesExtension));
assertEqualsExactType(TestAllTypes.NestedEnum.BAR,
- message.getExtension(UnittestProto.defaultNestedEnumExtension ));
+ message.getExtension(defaultNestedEnumExtension ));
assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
- message.getExtension(UnittestProto.defaultForeignEnumExtension));
+ message.getExtension(defaultForeignEnumExtension));
assertEqualsExactType(ImportEnum.IMPORT_BAR,
- message.getExtension(UnittestProto.defaultImportEnumExtension));
+ message.getExtension(defaultImportEnumExtension));
- assertEqualsExactType("abc", message.getExtension(UnittestProto.defaultStringPieceExtension));
- assertEqualsExactType("123", message.getExtension(UnittestProto.defaultCordExtension));
+ assertEqualsExactType("abc", message.getExtension(defaultStringPieceExtension));
+ assertEqualsExactType("123", message.getExtension(defaultCordExtension));
}
// -------------------------------------------------------------------
@@ -1333,97 +1418,261 @@ class TestUtil {
// ModifyRepeatedFields only sets the second repeated element of each
// field. In addition to verifying this, we also verify that the first
// element and size were *not* modified.
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedInt32Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedInt64Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedUint32Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedUint64Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedSint32Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedSint64Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedFixed32Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedFixed64Extension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedSfixed32Extension));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedSfixed64Extension));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedFloatExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedDoubleExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedBoolExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedStringExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedBytesExtension ));
-
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedGroupExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedNestedMessageExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedForeignMessageExtension));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedImportMessageExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedNestedEnumExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedForeignEnumExtension ));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedImportEnumExtension ));
-
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedStringPieceExtension));
- Assert.assertEquals(2, message.getExtensionCount(UnittestProto.repeatedCordExtension));
-
- assertEqualsExactType(201 , message.getExtension(UnittestProto.repeatedInt32Extension , 0));
- assertEqualsExactType(202L , message.getExtension(UnittestProto.repeatedInt64Extension , 0));
- assertEqualsExactType(203 , message.getExtension(UnittestProto.repeatedUint32Extension , 0));
- assertEqualsExactType(204L , message.getExtension(UnittestProto.repeatedUint64Extension , 0));
- assertEqualsExactType(205 , message.getExtension(UnittestProto.repeatedSint32Extension , 0));
- assertEqualsExactType(206L , message.getExtension(UnittestProto.repeatedSint64Extension , 0));
- assertEqualsExactType(207 , message.getExtension(UnittestProto.repeatedFixed32Extension , 0));
- assertEqualsExactType(208L , message.getExtension(UnittestProto.repeatedFixed64Extension , 0));
- assertEqualsExactType(209 , message.getExtension(UnittestProto.repeatedSfixed32Extension, 0));
- assertEqualsExactType(210L , message.getExtension(UnittestProto.repeatedSfixed64Extension, 0));
- assertEqualsExactType(211F , message.getExtension(UnittestProto.repeatedFloatExtension , 0));
- assertEqualsExactType(212D , message.getExtension(UnittestProto.repeatedDoubleExtension , 0));
- assertEqualsExactType(true , message.getExtension(UnittestProto.repeatedBoolExtension , 0));
- assertEqualsExactType("215", message.getExtension(UnittestProto.repeatedStringExtension , 0));
- assertEqualsExactType(toBytes("216"), message.getExtension(UnittestProto.repeatedBytesExtension, 0));
-
- assertEqualsExactType(217, message.getExtension(UnittestProto.repeatedGroupExtension , 0).getA());
- assertEqualsExactType(218, message.getExtension(UnittestProto.repeatedNestedMessageExtension , 0).getBb());
- assertEqualsExactType(219, message.getExtension(UnittestProto.repeatedForeignMessageExtension, 0).getC());
- assertEqualsExactType(220, message.getExtension(UnittestProto.repeatedImportMessageExtension , 0).getD());
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32Extension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64Extension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtension ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtension ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtension));
+
+ assertEqualsExactType(201 , message.getExtension(repeatedInt32Extension , 0));
+ assertEqualsExactType(202L , message.getExtension(repeatedInt64Extension , 0));
+ assertEqualsExactType(203 , message.getExtension(repeatedUint32Extension , 0));
+ assertEqualsExactType(204L , message.getExtension(repeatedUint64Extension , 0));
+ assertEqualsExactType(205 , message.getExtension(repeatedSint32Extension , 0));
+ assertEqualsExactType(206L , message.getExtension(repeatedSint64Extension , 0));
+ assertEqualsExactType(207 , message.getExtension(repeatedFixed32Extension , 0));
+ assertEqualsExactType(208L , message.getExtension(repeatedFixed64Extension , 0));
+ assertEqualsExactType(209 , message.getExtension(repeatedSfixed32Extension, 0));
+ assertEqualsExactType(210L , message.getExtension(repeatedSfixed64Extension, 0));
+ assertEqualsExactType(211F , message.getExtension(repeatedFloatExtension , 0));
+ assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtension , 0));
+ assertEqualsExactType(true , message.getExtension(repeatedBoolExtension , 0));
+ assertEqualsExactType("215", message.getExtension(repeatedStringExtension , 0));
+ assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtension, 0));
+
+ assertEqualsExactType(217, message.getExtension(repeatedGroupExtension , 0).getA());
+ assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtension , 0).getBb());
+ assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtension, 0).getC());
+ assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtension , 0).getD());
assertEqualsExactType(TestAllTypes.NestedEnum.BAR,
- message.getExtension(UnittestProto.repeatedNestedEnumExtension, 0));
+ message.getExtension(repeatedNestedEnumExtension, 0));
assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
- message.getExtension(UnittestProto.repeatedForeignEnumExtension, 0));
+ message.getExtension(repeatedForeignEnumExtension, 0));
assertEqualsExactType(ImportEnum.IMPORT_BAR,
- message.getExtension(UnittestProto.repeatedImportEnumExtension, 0));
+ message.getExtension(repeatedImportEnumExtension, 0));
- assertEqualsExactType("224", message.getExtension(UnittestProto.repeatedStringPieceExtension, 0));
- assertEqualsExactType("225", message.getExtension(UnittestProto.repeatedCordExtension, 0));
+ assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtension, 0));
+ assertEqualsExactType("225", message.getExtension(repeatedCordExtension, 0));
// Actually verify the second (modified) elements now.
- assertEqualsExactType(501 , message.getExtension(UnittestProto.repeatedInt32Extension , 1));
- assertEqualsExactType(502L , message.getExtension(UnittestProto.repeatedInt64Extension , 1));
- assertEqualsExactType(503 , message.getExtension(UnittestProto.repeatedUint32Extension , 1));
- assertEqualsExactType(504L , message.getExtension(UnittestProto.repeatedUint64Extension , 1));
- assertEqualsExactType(505 , message.getExtension(UnittestProto.repeatedSint32Extension , 1));
- assertEqualsExactType(506L , message.getExtension(UnittestProto.repeatedSint64Extension , 1));
- assertEqualsExactType(507 , message.getExtension(UnittestProto.repeatedFixed32Extension , 1));
- assertEqualsExactType(508L , message.getExtension(UnittestProto.repeatedFixed64Extension , 1));
- assertEqualsExactType(509 , message.getExtension(UnittestProto.repeatedSfixed32Extension, 1));
- assertEqualsExactType(510L , message.getExtension(UnittestProto.repeatedSfixed64Extension, 1));
- assertEqualsExactType(511F , message.getExtension(UnittestProto.repeatedFloatExtension , 1));
- assertEqualsExactType(512D , message.getExtension(UnittestProto.repeatedDoubleExtension , 1));
- assertEqualsExactType(true , message.getExtension(UnittestProto.repeatedBoolExtension , 1));
- assertEqualsExactType("515", message.getExtension(UnittestProto.repeatedStringExtension , 1));
- assertEqualsExactType(toBytes("516"), message.getExtension(UnittestProto.repeatedBytesExtension, 1));
-
- assertEqualsExactType(517, message.getExtension(UnittestProto.repeatedGroupExtension , 1).getA());
- assertEqualsExactType(518, message.getExtension(UnittestProto.repeatedNestedMessageExtension , 1).getBb());
- assertEqualsExactType(519, message.getExtension(UnittestProto.repeatedForeignMessageExtension, 1).getC());
- assertEqualsExactType(520, message.getExtension(UnittestProto.repeatedImportMessageExtension , 1).getD());
+ assertEqualsExactType(501 , message.getExtension(repeatedInt32Extension , 1));
+ assertEqualsExactType(502L , message.getExtension(repeatedInt64Extension , 1));
+ assertEqualsExactType(503 , message.getExtension(repeatedUint32Extension , 1));
+ assertEqualsExactType(504L , message.getExtension(repeatedUint64Extension , 1));
+ assertEqualsExactType(505 , message.getExtension(repeatedSint32Extension , 1));
+ assertEqualsExactType(506L , message.getExtension(repeatedSint64Extension , 1));
+ assertEqualsExactType(507 , message.getExtension(repeatedFixed32Extension , 1));
+ assertEqualsExactType(508L , message.getExtension(repeatedFixed64Extension , 1));
+ assertEqualsExactType(509 , message.getExtension(repeatedSfixed32Extension, 1));
+ assertEqualsExactType(510L , message.getExtension(repeatedSfixed64Extension, 1));
+ assertEqualsExactType(511F , message.getExtension(repeatedFloatExtension , 1));
+ assertEqualsExactType(512D , message.getExtension(repeatedDoubleExtension , 1));
+ assertEqualsExactType(true , message.getExtension(repeatedBoolExtension , 1));
+ assertEqualsExactType("515", message.getExtension(repeatedStringExtension , 1));
+ assertEqualsExactType(toBytes("516"), message.getExtension(repeatedBytesExtension, 1));
+
+ assertEqualsExactType(517, message.getExtension(repeatedGroupExtension , 1).getA());
+ assertEqualsExactType(518, message.getExtension(repeatedNestedMessageExtension , 1).getBb());
+ assertEqualsExactType(519, message.getExtension(repeatedForeignMessageExtension, 1).getC());
+ assertEqualsExactType(520, message.getExtension(repeatedImportMessageExtension , 1).getD());
assertEqualsExactType(TestAllTypes.NestedEnum.FOO,
- message.getExtension(UnittestProto.repeatedNestedEnumExtension, 1));
+ message.getExtension(repeatedNestedEnumExtension, 1));
assertEqualsExactType(ForeignEnum.FOREIGN_FOO,
- message.getExtension(UnittestProto.repeatedForeignEnumExtension, 1));
+ message.getExtension(repeatedForeignEnumExtension, 1));
assertEqualsExactType(ImportEnum.IMPORT_FOO,
- message.getExtension(UnittestProto.repeatedImportEnumExtension, 1));
+ message.getExtension(repeatedImportEnumExtension, 1));
+
+ assertEqualsExactType("524", message.getExtension(repeatedStringPieceExtension, 1));
+ assertEqualsExactType("525", message.getExtension(repeatedCordExtension, 1));
+ }
- assertEqualsExactType("524", message.getExtension(UnittestProto.repeatedStringPieceExtension, 1));
- assertEqualsExactType("525", message.getExtension(UnittestProto.repeatedCordExtension, 1));
+ /**
+ * Set every field of {@code message} to a unique value.
+ */
+ public static void setPackedFields(TestPackedTypes.Builder message) {
+ message.addPackedInt32 (601);
+ message.addPackedInt64 (602);
+ message.addPackedUint32 (603);
+ message.addPackedUint64 (604);
+ message.addPackedSint32 (605);
+ message.addPackedSint64 (606);
+ message.addPackedFixed32 (607);
+ message.addPackedFixed64 (608);
+ message.addPackedSfixed32(609);
+ message.addPackedSfixed64(610);
+ message.addPackedFloat (611);
+ message.addPackedDouble (612);
+ message.addPackedBool (true);
+ message.addPackedEnum (ForeignEnum.FOREIGN_BAR);
+ // Add a second one of each field.
+ message.addPackedInt32 (701);
+ message.addPackedInt64 (702);
+ message.addPackedUint32 (703);
+ message.addPackedUint64 (704);
+ message.addPackedSint32 (705);
+ message.addPackedSint64 (706);
+ message.addPackedFixed32 (707);
+ message.addPackedFixed64 (708);
+ message.addPackedSfixed32(709);
+ message.addPackedSfixed64(710);
+ message.addPackedFloat (711);
+ message.addPackedDouble (712);
+ message.addPackedBool (false);
+ message.addPackedEnum (ForeignEnum.FOREIGN_BAZ);
}
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are set to the values assigned by {@code setPackedFields}.
+ */
+ public static void assertPackedFieldsSet(TestPackedTypes message) {
+ Assert.assertEquals(2, message.getPackedInt32Count ());
+ Assert.assertEquals(2, message.getPackedInt64Count ());
+ Assert.assertEquals(2, message.getPackedUint32Count ());
+ Assert.assertEquals(2, message.getPackedUint64Count ());
+ Assert.assertEquals(2, message.getPackedSint32Count ());
+ Assert.assertEquals(2, message.getPackedSint64Count ());
+ Assert.assertEquals(2, message.getPackedFixed32Count ());
+ Assert.assertEquals(2, message.getPackedFixed64Count ());
+ Assert.assertEquals(2, message.getPackedSfixed32Count());
+ Assert.assertEquals(2, message.getPackedSfixed64Count());
+ Assert.assertEquals(2, message.getPackedFloatCount ());
+ Assert.assertEquals(2, message.getPackedDoubleCount ());
+ Assert.assertEquals(2, message.getPackedBoolCount ());
+ Assert.assertEquals(2, message.getPackedEnumCount ());
+ Assert.assertEquals(601 , message.getPackedInt32 (0));
+ Assert.assertEquals(602 , message.getPackedInt64 (0));
+ Assert.assertEquals(603 , message.getPackedUint32 (0));
+ Assert.assertEquals(604 , message.getPackedUint64 (0));
+ Assert.assertEquals(605 , message.getPackedSint32 (0));
+ Assert.assertEquals(606 , message.getPackedSint64 (0));
+ Assert.assertEquals(607 , message.getPackedFixed32 (0));
+ Assert.assertEquals(608 , message.getPackedFixed64 (0));
+ Assert.assertEquals(609 , message.getPackedSfixed32(0));
+ Assert.assertEquals(610 , message.getPackedSfixed64(0));
+ Assert.assertEquals(611 , message.getPackedFloat (0), 0.0);
+ Assert.assertEquals(612 , message.getPackedDouble (0), 0.0);
+ Assert.assertEquals(true , message.getPackedBool (0));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getPackedEnum(0));
+ Assert.assertEquals(701 , message.getPackedInt32 (1));
+ Assert.assertEquals(702 , message.getPackedInt64 (1));
+ Assert.assertEquals(703 , message.getPackedUint32 (1));
+ Assert.assertEquals(704 , message.getPackedUint64 (1));
+ Assert.assertEquals(705 , message.getPackedSint32 (1));
+ Assert.assertEquals(706 , message.getPackedSint64 (1));
+ Assert.assertEquals(707 , message.getPackedFixed32 (1));
+ Assert.assertEquals(708 , message.getPackedFixed64 (1));
+ Assert.assertEquals(709 , message.getPackedSfixed32(1));
+ Assert.assertEquals(710 , message.getPackedSfixed64(1));
+ Assert.assertEquals(711 , message.getPackedFloat (1), 0.0);
+ Assert.assertEquals(712 , message.getPackedDouble (1), 0.0);
+ Assert.assertEquals(false, message.getPackedBool (1));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getPackedEnum(1));
+ }
+
+ public static void setPackedExtensions(TestPackedExtensions.Builder message) {
+ message.addExtension(packedInt32Extension , 601);
+ message.addExtension(packedInt64Extension , 602L);
+ message.addExtension(packedUint32Extension , 603);
+ message.addExtension(packedUint64Extension , 604L);
+ message.addExtension(packedSint32Extension , 605);
+ message.addExtension(packedSint64Extension , 606L);
+ message.addExtension(packedFixed32Extension , 607);
+ message.addExtension(packedFixed64Extension , 608L);
+ message.addExtension(packedSfixed32Extension, 609);
+ message.addExtension(packedSfixed64Extension, 610L);
+ message.addExtension(packedFloatExtension , 611F);
+ message.addExtension(packedDoubleExtension , 612D);
+ message.addExtension(packedBoolExtension , true);
+ message.addExtension(packedEnumExtension, ForeignEnum.FOREIGN_BAR);
+ // Add a second one of each field.
+ message.addExtension(packedInt32Extension , 701);
+ message.addExtension(packedInt64Extension , 702L);
+ message.addExtension(packedUint32Extension , 703);
+ message.addExtension(packedUint64Extension , 704L);
+ message.addExtension(packedSint32Extension , 705);
+ message.addExtension(packedSint64Extension , 706L);
+ message.addExtension(packedFixed32Extension , 707);
+ message.addExtension(packedFixed64Extension , 708L);
+ message.addExtension(packedSfixed32Extension, 709);
+ message.addExtension(packedSfixed64Extension, 710L);
+ message.addExtension(packedFloatExtension , 711F);
+ message.addExtension(packedDoubleExtension , 712D);
+ message.addExtension(packedBoolExtension , false);
+ message.addExtension(packedEnumExtension, ForeignEnum.FOREIGN_BAZ);
+ }
+
+ public static void assertPackedExtensionsSet(TestPackedExtensions message) {
+ Assert.assertEquals(2, message.getExtensionCount(packedInt32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedInt64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedUint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedUint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedSint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedSint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedFixed32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedFixed64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedSfixed32Extension));
+ Assert.assertEquals(2, message.getExtensionCount(packedSfixed64Extension));
+ Assert.assertEquals(2, message.getExtensionCount(packedFloatExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedDoubleExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedBoolExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedEnumExtension));
+ assertEqualsExactType(601 , message.getExtension(packedInt32Extension , 0));
+ assertEqualsExactType(602L , message.getExtension(packedInt64Extension , 0));
+ assertEqualsExactType(603 , message.getExtension(packedUint32Extension , 0));
+ assertEqualsExactType(604L , message.getExtension(packedUint64Extension , 0));
+ assertEqualsExactType(605 , message.getExtension(packedSint32Extension , 0));
+ assertEqualsExactType(606L , message.getExtension(packedSint64Extension , 0));
+ assertEqualsExactType(607 , message.getExtension(packedFixed32Extension , 0));
+ assertEqualsExactType(608L , message.getExtension(packedFixed64Extension , 0));
+ assertEqualsExactType(609 , message.getExtension(packedSfixed32Extension, 0));
+ assertEqualsExactType(610L , message.getExtension(packedSfixed64Extension, 0));
+ assertEqualsExactType(611F , message.getExtension(packedFloatExtension , 0));
+ assertEqualsExactType(612D , message.getExtension(packedDoubleExtension , 0));
+ assertEqualsExactType(true , message.getExtension(packedBoolExtension , 0));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
+ message.getExtension(packedEnumExtension, 0));
+ assertEqualsExactType(701 , message.getExtension(packedInt32Extension , 1));
+ assertEqualsExactType(702L , message.getExtension(packedInt64Extension , 1));
+ assertEqualsExactType(703 , message.getExtension(packedUint32Extension , 1));
+ assertEqualsExactType(704L , message.getExtension(packedUint64Extension , 1));
+ assertEqualsExactType(705 , message.getExtension(packedSint32Extension , 1));
+ assertEqualsExactType(706L , message.getExtension(packedSint64Extension , 1));
+ assertEqualsExactType(707 , message.getExtension(packedFixed32Extension , 1));
+ assertEqualsExactType(708L , message.getExtension(packedFixed64Extension , 1));
+ assertEqualsExactType(709 , message.getExtension(packedSfixed32Extension, 1));
+ assertEqualsExactType(710L , message.getExtension(packedSfixed64Extension, 1));
+ assertEqualsExactType(711F , message.getExtension(packedFloatExtension , 1));
+ assertEqualsExactType(712D , message.getExtension(packedDoubleExtension , 1));
+ assertEqualsExactType(false, message.getExtension(packedBoolExtension , 1));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAZ,
+ message.getExtension(packedEnumExtension, 1));
+ }
+
+
// ===================================================================
/**
@@ -1487,7 +1736,7 @@ class TestUtil {
this.importFile = file.getDependencies().get(0);
Descriptors.Descriptor testAllTypes;
- if (extensionRegistry == null) {
+ if (baseDescriptor.getName() == "TestAllTypes") {
testAllTypes = baseDescriptor;
} else {
testAllTypes = file.findMessageTypeByName("TestAllTypes");
@@ -1495,10 +1744,13 @@ class TestUtil {
}
if (extensionRegistry == null) {
+ // Use testAllTypes, rather than baseDescriptor, to allow
+ // initialization using TestPackedTypes descriptors. These objects
+ // won't be used by the methods for packed fields.
this.optionalGroup =
- baseDescriptor.findNestedTypeByName("OptionalGroup");
+ testAllTypes.findNestedTypeByName("OptionalGroup");
this.repeatedGroup =
- baseDescriptor.findNestedTypeByName("RepeatedGroup");
+ testAllTypes.findNestedTypeByName("RepeatedGroup");
} else {
this.optionalGroup =
file.findMessageTypeByName("OptionalGroup_extension");
@@ -2279,6 +2531,191 @@ class TestUtil {
Assert.assertEquals("524", message.getRepeatedField(f("repeated_string_piece"), 1));
Assert.assertEquals("525", message.getRepeatedField(f("repeated_cord"), 1));
}
+
+ public void setPackedFieldsViaReflection(Message.Builder message) {
+ message.addRepeatedField(f("packed_int32" ), 601 );
+ message.addRepeatedField(f("packed_int64" ), 602L);
+ message.addRepeatedField(f("packed_uint32" ), 603 );
+ message.addRepeatedField(f("packed_uint64" ), 604L);
+ message.addRepeatedField(f("packed_sint32" ), 605 );
+ message.addRepeatedField(f("packed_sint64" ), 606L);
+ message.addRepeatedField(f("packed_fixed32" ), 607 );
+ message.addRepeatedField(f("packed_fixed64" ), 608L);
+ message.addRepeatedField(f("packed_sfixed32"), 609 );
+ message.addRepeatedField(f("packed_sfixed64"), 610L);
+ message.addRepeatedField(f("packed_float" ), 611F);
+ message.addRepeatedField(f("packed_double" ), 612D);
+ message.addRepeatedField(f("packed_bool" ), true);
+ message.addRepeatedField(f("packed_enum" ), foreignBar);
+ // Add a second one of each field.
+ message.addRepeatedField(f("packed_int32" ), 701 );
+ message.addRepeatedField(f("packed_int64" ), 702L);
+ message.addRepeatedField(f("packed_uint32" ), 703 );
+ message.addRepeatedField(f("packed_uint64" ), 704L);
+ message.addRepeatedField(f("packed_sint32" ), 705 );
+ message.addRepeatedField(f("packed_sint64" ), 706L);
+ message.addRepeatedField(f("packed_fixed32" ), 707 );
+ message.addRepeatedField(f("packed_fixed64" ), 708L);
+ message.addRepeatedField(f("packed_sfixed32"), 709 );
+ message.addRepeatedField(f("packed_sfixed64"), 710L);
+ message.addRepeatedField(f("packed_float" ), 711F);
+ message.addRepeatedField(f("packed_double" ), 712D);
+ message.addRepeatedField(f("packed_bool" ), false);
+ message.addRepeatedField(f("packed_enum" ), foreignBaz);
+ }
+
+ public void assertPackedFieldsSetViaReflection(Message message) {
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_int32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_int64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_uint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_uint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_fixed32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_fixed64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sfixed32")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sfixed64")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_float" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_double" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_bool" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_enum" )));
+ Assert.assertEquals(601 , message.getRepeatedField(f("packed_int32" ), 0));
+ Assert.assertEquals(602L , message.getRepeatedField(f("packed_int64" ), 0));
+ Assert.assertEquals(603 , message.getRepeatedField(f("packed_uint32" ), 0));
+ Assert.assertEquals(604L , message.getRepeatedField(f("packed_uint64" ), 0));
+ Assert.assertEquals(605 , message.getRepeatedField(f("packed_sint32" ), 0));
+ Assert.assertEquals(606L , message.getRepeatedField(f("packed_sint64" ), 0));
+ Assert.assertEquals(607 , message.getRepeatedField(f("packed_fixed32" ), 0));
+ Assert.assertEquals(608L , message.getRepeatedField(f("packed_fixed64" ), 0));
+ Assert.assertEquals(609 , message.getRepeatedField(f("packed_sfixed32"), 0));
+ Assert.assertEquals(610L , message.getRepeatedField(f("packed_sfixed64"), 0));
+ Assert.assertEquals(611F , message.getRepeatedField(f("packed_float" ), 0));
+ Assert.assertEquals(612D , message.getRepeatedField(f("packed_double" ), 0));
+ Assert.assertEquals(true , message.getRepeatedField(f("packed_bool" ), 0));
+ Assert.assertEquals(foreignBar, message.getRepeatedField(f("packed_enum" ),0));
+ Assert.assertEquals(701 , message.getRepeatedField(f("packed_int32" ), 1));
+ Assert.assertEquals(702L , message.getRepeatedField(f("packed_int64" ), 1));
+ Assert.assertEquals(703 , message.getRepeatedField(f("packed_uint32" ), 1));
+ Assert.assertEquals(704L , message.getRepeatedField(f("packed_uint64" ), 1));
+ Assert.assertEquals(705 , message.getRepeatedField(f("packed_sint32" ), 1));
+ Assert.assertEquals(706L , message.getRepeatedField(f("packed_sint64" ), 1));
+ Assert.assertEquals(707 , message.getRepeatedField(f("packed_fixed32" ), 1));
+ Assert.assertEquals(708L , message.getRepeatedField(f("packed_fixed64" ), 1));
+ Assert.assertEquals(709 , message.getRepeatedField(f("packed_sfixed32"), 1));
+ Assert.assertEquals(710L , message.getRepeatedField(f("packed_sfixed64"), 1));
+ Assert.assertEquals(711F , message.getRepeatedField(f("packed_float" ), 1));
+ Assert.assertEquals(712D , message.getRepeatedField(f("packed_double" ), 1));
+ Assert.assertEquals(false, message.getRepeatedField(f("packed_bool" ), 1));
+ Assert.assertEquals(foreignBaz, message.getRepeatedField(f("packed_enum" ),1));
+ }
+
+ /**
+ * Verifies that the reflection setters for the given.Builder object throw a
+ * NullPointerException if they are passed a null value. Uses Assert to throw an
+ * appropriate assertion failure, if the condition is not verified.
+ */
+ public void assertReflectionSettersRejectNull(Message.Builder builder)
+ throws Exception {
+ try {
+ builder.setField(f("optional_string"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setField(f("optional_bytes"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setField(f("optional_nested_enum"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setField(f("optional_nested_message"),
+ (TestAllTypes.NestedMessage) null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setField(f("optional_nested_message"),
+ (TestAllTypes.NestedMessage.Builder) null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ try {
+ builder.addRepeatedField(f("repeated_string"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedField(f("repeated_bytes"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedField(f("repeated_nested_enum"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedField(f("repeated_nested_message"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+
+ /**
+ * Verifies that the reflection repeated setters for the given Builder object throw a
+ * NullPointerException if they are passed a null value. Uses Assert to throw an appropriate
+ * assertion failure, if the condition is not verified.
+ */
+ public void assertReflectionRepeatedSettersRejectNull(Message.Builder builder)
+ throws Exception {
+ builder.addRepeatedField(f("repeated_string"), "one");
+ try {
+ builder.setRepeatedField(f("repeated_string"), 0, null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedField(f("repeated_bytes"), toBytes("one"));
+ try {
+ builder.setRepeatedField(f("repeated_bytes"), 0, null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedField(f("repeated_nested_enum"), nestedBaz);
+ try {
+ builder.setRepeatedField(f("repeated_nested_enum"), 0, null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedField(
+ f("repeated_nested_message"),
+ TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+ try {
+ builder.setRepeatedField(f("repeated_nested_message"), 0, null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
}
/**
@@ -2344,4 +2781,21 @@ class TestUtil {
return goldenMessage;
}
private static ByteString goldenMessage = null;
+
+ /**
+ * Get the bytes of the "golden packed fields message". This is a serialized
+ * TestPackedTypes with all fields set as they would be by
+ * {@link setPackedFields(TestPackedTypes.Builder)}, but it is loaded from a
+ * file on disk rather than generated dynamically. The file is actually
+ * generated by C++ code, so testing against it verifies compatibility with
+ * C++.
+ */
+ public static ByteString getGoldenPackedFieldsMessage() {
+ if (goldenPackedFieldsMessage == null) {
+ goldenPackedFieldsMessage =
+ readBytesFromFile("golden_packed_fields_message");
+ }
+ return goldenPackedFieldsMessage;
+ }
+ private static ByteString goldenPackedFieldsMessage = null;
}
diff --git a/java/src/test/java/com/google/protobuf/TextFormatTest.java b/java/src/test/java/com/google/protobuf/TextFormatTest.java
index 9557bdf6..ec4910a3 100644
--- a/java/src/test/java/com/google/protobuf/TextFormatTest.java
+++ b/java/src/test/java/com/google/protobuf/TextFormatTest.java
@@ -586,4 +586,32 @@ public class TextFormatTest extends TestCase {
// success
}
}
+
+ public void testParseLongString() throws Exception {
+ String longText =
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890";
+
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge("optional_string: \"" + longText + "\"", builder);
+ assertEquals(longText, builder.getOptionalString());
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/WireFormatTest.java b/java/src/test/java/com/google/protobuf/WireFormatTest.java
index 3fb54fcf..48453faf 100644
--- a/java/src/test/java/com/google/protobuf/WireFormatTest.java
+++ b/java/src/test/java/com/google/protobuf/WireFormatTest.java
@@ -32,9 +32,11 @@ package com.google.protobuf;
import junit.framework.TestCase;
import protobuf_unittest.UnittestProto;
-import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestFieldOrderings;
+import protobuf_unittest.UnittestProto.TestPackedExtensions;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestMset.TestMessageSet;
import protobuf_unittest.UnittestMset.RawMessageSet;
import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
@@ -57,9 +59,20 @@ public class WireFormatTest extends TestCase {
TestUtil.assertAllFieldsSet(message2);
}
+ public void testSerializationPacked() throws Exception {
+ TestPackedTypes message = TestUtil.getPackedSet();
+
+ ByteString rawBytes = message.toByteString();
+ assertEquals(rawBytes.size(), message.getSerializedSize());
+
+ TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
+
+ TestUtil.assertPackedFieldsSet(message2);
+ }
+
public void testSerializeExtensions() throws Exception {
// TestAllTypes and TestAllExtensions should have compatible wire formats,
- // so if we serealize a TestAllExtensions then parse it as TestAllTypes
+ // so if we serialize a TestAllExtensions then parse it as TestAllTypes
// it should work.
TestAllExtensions message = TestUtil.getAllExtensionsSet();
@@ -71,17 +84,27 @@ public class WireFormatTest extends TestCase {
TestUtil.assertAllFieldsSet(message2);
}
+ public void testSerializePackedExtensions() throws Exception {
+ // TestPackedTypes and TestPackedExtensions should have compatible wire
+ // formats; check that they serialize to the same string.
+ TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
+ ByteString rawBytes = message.toByteString();
+
+ TestPackedTypes message2 = TestUtil.getPackedSet();
+ ByteString rawBytes2 = message2.toByteString();
+
+ assertEquals(rawBytes, rawBytes2);
+ }
+
public void testParseExtensions() throws Exception {
// TestAllTypes and TestAllExtensions should have compatible wire formats,
- // so if we serealize a TestAllTypes then parse it as TestAllExtensions
+ // so if we serialize a TestAllTypes then parse it as TestAllExtensions
// it should work.
TestAllTypes message = TestUtil.getAllSet();
ByteString rawBytes = message.toByteString();
- ExtensionRegistry registry = ExtensionRegistry.newInstance();
- TestUtil.registerAllExtensions(registry);
- registry = registry.getUnmodifiable();
+ ExtensionRegistry registry = TestUtil.getExtensionRegistry();
TestAllExtensions message2 =
TestAllExtensions.parseFrom(rawBytes, registry);
@@ -89,6 +112,19 @@ public class WireFormatTest extends TestCase {
TestUtil.assertAllExtensionsSet(message2);
}
+ public void testParsePackedExtensions() throws Exception {
+ // Ensure that packed extensions can be properly parsed.
+ TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
+ ByteString rawBytes = message.toByteString();
+
+ ExtensionRegistry registry = TestUtil.getExtensionRegistry();
+
+ TestPackedExtensions message2 =
+ TestPackedExtensions.parseFrom(rawBytes, registry);
+
+ TestUtil.assertPackedExtensionsSet(message2);
+ }
+
public void testExtensionsSerializedSize() throws Exception {
assertEquals(TestUtil.getAllSet().getSerializedSize(),
TestUtil.getAllExtensionsSet().getSerializedSize());
@@ -279,4 +315,3 @@ public class WireFormatTest extends TestCase {
assertEquals("bar", field.getLengthDelimitedList().get(0).toStringUtf8());
}
}
-
diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py
index 14fe863e..fa1e3402 100755
--- a/python/google/protobuf/internal/containers.py
+++ b/python/google/protobuf/internal/containers.py
@@ -106,6 +106,19 @@ class RepeatedScalarFieldContainer(BaseContainer):
if len(self._values) == 1:
self._message_listener.TransitionToNonempty()
+ def extend(self, elem_seq):
+ """Extends by appending the given sequence. Similar to list.extend()."""
+ if not elem_seq:
+ return
+
+ orig_empty = len(self._values) == 0
+ for elem in elem_seq:
+ self._type_checker.CheckValue(elem)
+ self._values.extend(elem_seq)
+ self._message_listener.ByteSizeDirty()
+ if orig_empty:
+ self._message_listener.TransitionToNonempty()
+
def remove(self, elem):
"""Removes an item from the list. Similar to list.remove()."""
self._values.remove(elem)
diff --git a/python/google/protobuf/internal/decoder_test.py b/python/google/protobuf/internal/decoder_test.py
index abcc07fc..e186e14d 100755
--- a/python/google/protobuf/internal/decoder_test.py
+++ b/python/google/protobuf/internal/decoder_test.py
@@ -57,7 +57,7 @@ class DecoderTest(unittest.TestCase):
for expected_field_number in (1, 15, 16, 2047, 2048):
for expected_wire_type in range(6): # Highest-numbered wiretype is 5.
e = encoder.Encoder()
- e._AppendTag(expected_field_number, expected_wire_type)
+ e.AppendTag(expected_field_number, expected_wire_type)
s = e.ToString()
d = decoder.Decoder(s)
field_number, wire_type = d.ReadFieldNumberAndWireType()
diff --git a/python/google/protobuf/internal/encoder.py b/python/google/protobuf/internal/encoder.py
index 7071241c..eed8c8bd 100755
--- a/python/google/protobuf/internal/encoder.py
+++ b/python/google/protobuf/internal/encoder.py
@@ -58,89 +58,161 @@ class Encoder(object):
"""Returns all values encoded in this object as a string."""
return self._stream.ToString()
- # All the Append*() methods below first append a tag+type pair to the buffer
- # before appending the specified value.
-
- def AppendInt32(self, field_number, value):
+ # Append*NoTag methods. These are necessary for serializing packed
+ # repeated fields. The Append*() methods call these methods to do
+ # the actual serialization.
+ def AppendInt32NoTag(self, value):
"""Appends a 32-bit integer to our buffer, varint-encoded."""
- self._AppendTag(field_number, wire_format.WIRETYPE_VARINT)
self._stream.AppendVarint32(value)
- def AppendInt64(self, field_number, value):
+ def AppendInt64NoTag(self, value):
"""Appends a 64-bit integer to our buffer, varint-encoded."""
- self._AppendTag(field_number, wire_format.WIRETYPE_VARINT)
self._stream.AppendVarint64(value)
- def AppendUInt32(self, field_number, unsigned_value):
+ def AppendUInt32NoTag(self, unsigned_value):
"""Appends an unsigned 32-bit integer to our buffer, varint-encoded."""
- self._AppendTag(field_number, wire_format.WIRETYPE_VARINT)
self._stream.AppendVarUInt32(unsigned_value)
- def AppendUInt64(self, field_number, unsigned_value):
+ def AppendUInt64NoTag(self, unsigned_value):
"""Appends an unsigned 64-bit integer to our buffer, varint-encoded."""
- self._AppendTag(field_number, wire_format.WIRETYPE_VARINT)
self._stream.AppendVarUInt64(unsigned_value)
- def AppendSInt32(self, field_number, value):
+ def AppendSInt32NoTag(self, value):
"""Appends a 32-bit integer to our buffer, zigzag-encoded and then
varint-encoded.
"""
- self._AppendTag(field_number, wire_format.WIRETYPE_VARINT)
zigzag_value = wire_format.ZigZagEncode(value)
self._stream.AppendVarUInt32(zigzag_value)
- def AppendSInt64(self, field_number, value):
+ def AppendSInt64NoTag(self, value):
"""Appends a 64-bit integer to our buffer, zigzag-encoded and then
varint-encoded.
"""
- self._AppendTag(field_number, wire_format.WIRETYPE_VARINT)
zigzag_value = wire_format.ZigZagEncode(value)
self._stream.AppendVarUInt64(zigzag_value)
- def AppendFixed32(self, field_number, unsigned_value):
+ def AppendFixed32NoTag(self, unsigned_value):
"""Appends an unsigned 32-bit integer to our buffer, in little-endian
byte-order.
"""
- self._AppendTag(field_number, wire_format.WIRETYPE_FIXED32)
self._stream.AppendLittleEndian32(unsigned_value)
- def AppendFixed64(self, field_number, unsigned_value):
+ def AppendFixed64NoTag(self, unsigned_value):
"""Appends an unsigned 64-bit integer to our buffer, in little-endian
byte-order.
"""
- self._AppendTag(field_number, wire_format.WIRETYPE_FIXED64)
self._stream.AppendLittleEndian64(unsigned_value)
- def AppendSFixed32(self, field_number, value):
+ def AppendSFixed32NoTag(self, value):
"""Appends a signed 32-bit integer to our buffer, in little-endian
byte-order.
"""
sign = (value & 0x80000000) and -1 or 0
if value >> 32 != sign:
raise message.EncodeError('SFixed32 out of range: %d' % value)
- self._AppendTag(field_number, wire_format.WIRETYPE_FIXED32)
self._stream.AppendLittleEndian32(value & 0xffffffff)
- def AppendSFixed64(self, field_number, value):
+ def AppendSFixed64NoTag(self, value):
"""Appends a signed 64-bit integer to our buffer, in little-endian
byte-order.
"""
sign = (value & 0x8000000000000000) and -1 or 0
if value >> 64 != sign:
raise message.EncodeError('SFixed64 out of range: %d' % value)
- self._AppendTag(field_number, wire_format.WIRETYPE_FIXED64)
self._stream.AppendLittleEndian64(value & 0xffffffffffffffff)
- def AppendFloat(self, field_number, value):
+ def AppendFloatNoTag(self, value):
"""Appends a floating-point number to our buffer."""
- self._AppendTag(field_number, wire_format.WIRETYPE_FIXED32)
self._stream.AppendRawBytes(struct.pack('f', value))
- def AppendDouble(self, field_number, value):
+ def AppendDoubleNoTag(self, value):
"""Appends a double-precision floating-point number to our buffer."""
- self._AppendTag(field_number, wire_format.WIRETYPE_FIXED64)
self._stream.AppendRawBytes(struct.pack('d', value))
+ def AppendBoolNoTag(self, value):
+ """Appends a boolean to our buffer."""
+ self.AppendInt32NoTag(value)
+
+ def AppendEnumNoTag(self, value):
+ """Appends an enum value to our buffer."""
+ self.AppendInt32NoTag(value)
+
+
+ # All the Append*() methods below first append a tag+type pair to the buffer
+ # before appending the specified value.
+
+ def AppendInt32(self, field_number, value):
+ """Appends a 32-bit integer to our buffer, varint-encoded."""
+ self.AppendTag(field_number, wire_format.WIRETYPE_VARINT)
+ self.AppendInt32NoTag(value)
+
+ def AppendInt64(self, field_number, value):
+ """Appends a 64-bit integer to our buffer, varint-encoded."""
+ self.AppendTag(field_number, wire_format.WIRETYPE_VARINT)
+ self.AppendInt64NoTag(value)
+
+ def AppendUInt32(self, field_number, unsigned_value):
+ """Appends an unsigned 32-bit integer to our buffer, varint-encoded."""
+ self.AppendTag(field_number, wire_format.WIRETYPE_VARINT)
+ self.AppendUInt32NoTag(unsigned_value)
+
+ def AppendUInt64(self, field_number, unsigned_value):
+ """Appends an unsigned 64-bit integer to our buffer, varint-encoded."""
+ self.AppendTag(field_number, wire_format.WIRETYPE_VARINT)
+ self.AppendUInt64NoTag(unsigned_value)
+
+ def AppendSInt32(self, field_number, value):
+ """Appends a 32-bit integer to our buffer, zigzag-encoded and then
+ varint-encoded.
+ """
+ self.AppendTag(field_number, wire_format.WIRETYPE_VARINT)
+ self.AppendSInt32NoTag(value)
+
+ def AppendSInt64(self, field_number, value):
+ """Appends a 64-bit integer to our buffer, zigzag-encoded and then
+ varint-encoded.
+ """
+ self.AppendTag(field_number, wire_format.WIRETYPE_VARINT)
+ self.AppendSInt64NoTag(value)
+
+ def AppendFixed32(self, field_number, unsigned_value):
+ """Appends an unsigned 32-bit integer to our buffer, in little-endian
+ byte-order.
+ """
+ self.AppendTag(field_number, wire_format.WIRETYPE_FIXED32)
+ self.AppendFixed32NoTag(unsigned_value)
+
+ def AppendFixed64(self, field_number, unsigned_value):
+ """Appends an unsigned 64-bit integer to our buffer, in little-endian
+ byte-order.
+ """
+ self.AppendTag(field_number, wire_format.WIRETYPE_FIXED64)
+ self.AppendFixed64NoTag(unsigned_value)
+
+ def AppendSFixed32(self, field_number, value):
+ """Appends a signed 32-bit integer to our buffer, in little-endian
+ byte-order.
+ """
+ self.AppendTag(field_number, wire_format.WIRETYPE_FIXED32)
+ self.AppendSFixed32NoTag(value)
+
+ def AppendSFixed64(self, field_number, value):
+ """Appends a signed 64-bit integer to our buffer, in little-endian
+ byte-order.
+ """
+ self.AppendTag(field_number, wire_format.WIRETYPE_FIXED64)
+ self.AppendSFixed64NoTag(value)
+
+ def AppendFloat(self, field_number, value):
+ """Appends a floating-point number to our buffer."""
+ self.AppendTag(field_number, wire_format.WIRETYPE_FIXED32)
+ self.AppendFloatNoTag(value)
+
+ def AppendDouble(self, field_number, value):
+ """Appends a double-precision floating-point number to our buffer."""
+ self.AppendTag(field_number, wire_format.WIRETYPE_FIXED64)
+ self.AppendDoubleNoTag(value)
+
def AppendBool(self, field_number, value):
"""Appends a boolean to our buffer."""
self.AppendInt32(field_number, value)
@@ -159,7 +231,7 @@ class Encoder(object):
"""Appends a length-prefixed sequence of bytes to our buffer, with the
length varint-encoded.
"""
- self._AppendTag(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ self.AppendTag(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
self._stream.AppendVarUInt32(len(value))
self._stream.AppendRawBytes(value)
@@ -174,14 +246,14 @@ class Encoder(object):
def AppendGroup(self, field_number, group):
"""Appends a group to our buffer.
"""
- self._AppendTag(field_number, wire_format.WIRETYPE_START_GROUP)
+ self.AppendTag(field_number, wire_format.WIRETYPE_START_GROUP)
self._stream.AppendRawBytes(group.SerializeToString())
- self._AppendTag(field_number, wire_format.WIRETYPE_END_GROUP)
+ self.AppendTag(field_number, wire_format.WIRETYPE_END_GROUP)
def AppendMessage(self, field_number, msg):
"""Appends a nested message to our buffer.
"""
- self._AppendTag(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ self.AppendTag(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
self._stream.AppendVarUInt32(msg.ByteSize())
self._stream.AppendRawBytes(msg.SerializeToString())
@@ -196,11 +268,11 @@ class Encoder(object):
}
}
"""
- self._AppendTag(1, wire_format.WIRETYPE_START_GROUP)
+ self.AppendTag(1, wire_format.WIRETYPE_START_GROUP)
self.AppendInt32(2, field_number)
self.AppendMessage(3, msg)
- self._AppendTag(1, wire_format.WIRETYPE_END_GROUP)
+ self.AppendTag(1, wire_format.WIRETYPE_END_GROUP)
- def _AppendTag(self, field_number, wire_type):
+ def AppendTag(self, field_number, wire_type):
"""Appends a tag containing field number and wire type information."""
self._stream.AppendVarUInt32(wire_format.PackTag(field_number, wire_type))
diff --git a/python/google/protobuf/internal/encoder_test.py b/python/google/protobuf/internal/encoder_test.py
index 61668223..83a21c39 100755
--- a/python/google/protobuf/internal/encoder_test.py
+++ b/python/google/protobuf/internal/encoder_test.py
@@ -59,7 +59,8 @@ class EncoderTest(unittest.TestCase):
def AppendScalarTestHelper(self, test_name, encoder_method,
expected_stream_method_name,
wire_type, field_value,
- expected_value=None, expected_length=None):
+ expected_value=None, expected_length=None,
+ is_tag_test=True):
"""Helper for testAppendScalars.
Calls one of the Encoder methods, and ensures that the Encoder
@@ -67,9 +68,10 @@ class EncoderTest(unittest.TestCase):
Args:
test_name: Name of this test, used only for logging.
- encoder_method: Callable on self.encoder, which should
- accept |field_value| as an argument. This is the Encoder
- method we're testing.
+ encoder_method: Callable on self.encoder. This is the Encoder
+ method we're testing. If is_tag_test=True, the encoder method
+ accepts a field_number and field_value. if is_tag_test=False,
+ the encoder method accepts a field_value.
expected_stream_method_name: (string) Name of the OutputStream
method we expect Encoder to call to actually put the value
on the wire.
@@ -83,6 +85,9 @@ class EncoderTest(unittest.TestCase):
expected_length: The length we expect Encoder to pass to the
AppendVarUInt32 method. If None we expect the length of the
field_value.
+ is_tag_test: A Boolean. If True (the default), we append the
+ the packed field number and wire_type to the stream before
+ the field value.
"""
if expected_value is None:
expected_value = field_value
@@ -93,14 +98,16 @@ class EncoderTest(unittest.TestCase):
test_name, encoder_method, field_value,
expected_stream_method_name, expected_value))
- field_number = 10
- # Should first append the field number and type information.
- self.mock_stream.AppendVarUInt32(self.PackTag(field_number, wire_type))
- # If we're length-delimited, we should then append the length.
- if wire_type == wire_format.WIRETYPE_LENGTH_DELIMITED:
- if expected_length is None:
- expected_length = len(field_value)
- self.mock_stream.AppendVarUInt32(expected_length)
+ if is_tag_test:
+ field_number = 10
+ # Should first append the field number and type information.
+ self.mock_stream.AppendVarUInt32(self.PackTag(field_number, wire_type))
+ # If we're length-delimited, we should then append the length.
+ if wire_type == wire_format.WIRETYPE_LENGTH_DELIMITED:
+ if expected_length is None:
+ expected_length = len(field_value)
+ self.mock_stream.AppendVarUInt32(expected_length)
+
# Should then append the value itself.
# We have to use names instead of methods to work around some
# mox weirdness. (ResetAll() is overzealous).
@@ -109,7 +116,10 @@ class EncoderTest(unittest.TestCase):
expected_stream_method(expected_value)
self.mox.ReplayAll()
- encoder_method(field_number, field_value)
+ if is_tag_test:
+ encoder_method(field_number, field_value)
+ else:
+ encoder_method(field_value)
self.mox.VerifyAll()
self.mox.ResetAll()
@@ -160,6 +170,40 @@ class EncoderTest(unittest.TestCase):
for args in scalar_tests:
self.AppendScalarTestHelper(*args)
+ def testAppendScalarsWithoutTags(self):
+ scalar_no_tag_tests = [
+ ['int32', self.encoder.AppendInt32NoTag, 'AppendVarint32', None, 0],
+ ['int64', self.encoder.AppendInt64NoTag, 'AppendVarint64', None, 0],
+ ['uint32', self.encoder.AppendUInt32NoTag, 'AppendVarUInt32', None, 0],
+ ['uint64', self.encoder.AppendUInt64NoTag, 'AppendVarUInt64', None, 0],
+ ['fixed32', self.encoder.AppendFixed32NoTag,
+ 'AppendLittleEndian32', None, 0],
+ ['fixed64', self.encoder.AppendFixed64NoTag,
+ 'AppendLittleEndian64', None, 0],
+ ['sfixed32', self.encoder.AppendSFixed32NoTag,
+ 'AppendLittleEndian32', None, 0],
+ ['sfixed64', self.encoder.AppendSFixed64NoTag,
+ 'AppendLittleEndian64', None, 0],
+ ['float', self.encoder.AppendFloatNoTag,
+ 'AppendRawBytes', None, 0.0, struct.pack('f', 0.0)],
+ ['double', self.encoder.AppendDoubleNoTag,
+ 'AppendRawBytes', None, 0.0, struct.pack('d', 0.0)],
+ ['bool', self.encoder.AppendBoolNoTag, 'AppendVarint32', None, 0],
+ ['enum', self.encoder.AppendEnumNoTag, 'AppendVarint32', None, 0],
+ ['sint32', self.encoder.AppendSInt32NoTag,
+ 'AppendVarUInt32', None, -1, 1],
+ ['sint64', self.encoder.AppendSInt64NoTag,
+ 'AppendVarUInt64', None, -1, 1],
+ ]
+
+ self.assertEqual(len(scalar_no_tag_tests),
+ len(set(t[0] for t in scalar_no_tag_tests)))
+ self.assert_(len(scalar_no_tag_tests) >=
+ len(set(t[1] for t in scalar_no_tag_tests)))
+ for args in scalar_no_tag_tests:
+ # For no tag tests, the wire_type is not used, so we put in None.
+ self.AppendScalarTestHelper(is_tag_test=False, *args)
+
def testAppendGroup(self):
field_number = 23
# Should first append the start-group marker.
diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py
index 14062762..e405f60b 100755
--- a/python/google/protobuf/internal/reflection_test.py
+++ b/python/google/protobuf/internal/reflection_test.py
@@ -229,8 +229,8 @@ class ReflectionTest(unittest.TestCase):
proto.repeated_fixed32.append(1)
proto.repeated_int32.append(5)
proto.repeated_int32.append(11)
- proto.repeated_string.append('foo')
- proto.repeated_string.append('bar')
+ proto.repeated_string.extend(['foo', 'bar'])
+ proto.repeated_string.extend([])
proto.repeated_string.append('baz')
proto.optional_int32 = 21
self.assertEqual(
@@ -757,6 +757,16 @@ class ReflectionTest(unittest.TestCase):
self.assertRaises(KeyError, extendee_proto.HasExtension,
unittest_pb2.repeated_string_extension)
+ def testStaticParseFrom(self):
+ proto1 = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(proto1)
+
+ string1 = proto1.SerializeToString()
+ proto2 = unittest_pb2.TestAllTypes.FromString(string1)
+
+ # Messages should be equal.
+ self.assertEqual(proto2, proto1)
+
def testMergeFromSingularField(self):
# Test merge with just a singular field.
proto1 = unittest_pb2.TestAllTypes()
@@ -1209,6 +1219,8 @@ class ByteSizeTest(unittest.TestCase):
def setUp(self):
self.proto = unittest_pb2.TestAllTypes()
self.extended_proto = more_extensions_pb2.ExtendedMessage()
+ self.packed_proto = unittest_pb2.TestPackedTypes()
+ self.packed_extended_proto = unittest_pb2.TestPackedExtensions()
def Size(self):
return self.proto.ByteSize()
@@ -1291,6 +1303,11 @@ class ByteSizeTest(unittest.TestCase):
# Also need 2 bytes for each entry for tag.
self.assertEqual(1 + 2 + 2*2, self.Size())
+ def testRepeatedScalarsExtend(self):
+ self.proto.repeated_int32.extend([10, 128]) # 3 bytes.
+ # Also need 2 bytes for each entry for tag.
+ self.assertEqual(1 + 2 + 2*2, self.Size())
+
def testRepeatedScalarsRemove(self):
self.proto.repeated_int32.append(10) # 1 byte.
self.proto.repeated_int32.append(128) # 2 bytes.
@@ -1443,6 +1460,33 @@ class ByteSizeTest(unittest.TestCase):
self.extended_proto.ClearExtension(extension)
self.assertEqual(0, self.extended_proto.ByteSize())
+ def testPackedRepeatedScalars(self):
+ self.assertEqual(0, self.packed_proto.ByteSize())
+
+ self.packed_proto.packed_int32.append(10) # 1 byte.
+ self.packed_proto.packed_int32.append(128) # 2 bytes.
+ # The tag is 2 bytes (the field number is 90), and the varint
+ # storing the length is 1 byte.
+ int_size = 1 + 2 + 3
+ self.assertEqual(int_size, self.packed_proto.ByteSize())
+
+ self.packed_proto.packed_double.append(4.2) # 8 bytes
+ self.packed_proto.packed_double.append(3.25) # 8 bytes
+ # 2 more tag bytes, 1 more length byte.
+ double_size = 8 + 8 + 3
+ self.assertEqual(int_size+double_size, self.packed_proto.ByteSize())
+
+ self.packed_proto.ClearField('packed_int32')
+ self.assertEqual(double_size, self.packed_proto.ByteSize())
+
+ def testPackedExtensions(self):
+ self.assertEqual(0, self.packed_extended_proto.ByteSize())
+ extension = self.packed_extended_proto.Extensions[
+ unittest_pb2.packed_fixed32_extension]
+ extension.extend([1, 2, 3, 4]) # 16 bytes
+ # Tag is 3 bytes.
+ self.assertEqual(19, self.packed_extended_proto.ByteSize())
+
# TODO(robinson): We need cross-language serialization consistency tests.
# Issues to be sure to cover include:
@@ -1686,6 +1730,63 @@ class SerializationTest(unittest.TestCase):
self.assertEqual(2, proto2.b)
self.assertEqual(3, proto2.c)
+ def testSerializedAllPackedFields(self):
+ first_proto = unittest_pb2.TestPackedTypes()
+ second_proto = unittest_pb2.TestPackedTypes()
+ test_util.SetAllPackedFields(first_proto)
+ serialized = first_proto.SerializeToString()
+ self.assertEqual(first_proto.ByteSize(), len(serialized))
+ second_proto.MergeFromString(serialized)
+ self.assertEqual(first_proto, second_proto)
+
+ def testSerializeAllPackedExtensions(self):
+ first_proto = unittest_pb2.TestPackedExtensions()
+ second_proto = unittest_pb2.TestPackedExtensions()
+ test_util.SetAllPackedExtensions(first_proto)
+ serialized = first_proto.SerializeToString()
+ second_proto.MergeFromString(serialized)
+ self.assertEqual(first_proto, second_proto)
+
+ def testMergePackedFromStringWhenSomeFieldsAlreadySet(self):
+ first_proto = unittest_pb2.TestPackedTypes()
+ first_proto.packed_int32.extend([1, 2])
+ first_proto.packed_double.append(3.0)
+ serialized = first_proto.SerializeToString()
+
+ second_proto = unittest_pb2.TestPackedTypes()
+ second_proto.packed_int32.append(3)
+ second_proto.packed_double.extend([1.0, 2.0])
+ second_proto.packed_sint32.append(4)
+
+ second_proto.MergeFromString(serialized)
+ self.assertEqual([3, 1, 2], second_proto.packed_int32)
+ self.assertEqual([1.0, 2.0, 3.0], second_proto.packed_double)
+ self.assertEqual([4], second_proto.packed_sint32)
+
+ def testPackedFieldsWireFormat(self):
+ proto = unittest_pb2.TestPackedTypes()
+ proto.packed_int32.extend([1, 2, 150, 3]) # 1 + 1 + 2 + 1 bytes
+ proto.packed_double.extend([1.0, 1000.0]) # 8 + 8 bytes
+ proto.packed_float.append(2.0) # 4 bytes, will be before double
+ serialized = proto.SerializeToString()
+ self.assertEqual(proto.ByteSize(), len(serialized))
+ d = decoder.Decoder(serialized)
+ ReadTag = d.ReadFieldNumberAndWireType
+ self.assertEqual((90, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
+ self.assertEqual(1+1+1+2, d.ReadInt32())
+ self.assertEqual(1, d.ReadInt32())
+ self.assertEqual(2, d.ReadInt32())
+ self.assertEqual(150, d.ReadInt32())
+ self.assertEqual(3, d.ReadInt32())
+ self.assertEqual((100, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
+ self.assertEqual(4, d.ReadInt32())
+ self.assertEqual(2.0, d.ReadFloat())
+ self.assertEqual((101, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
+ self.assertEqual(8+8, d.ReadInt32())
+ self.assertEqual(1.0, d.ReadDouble())
+ self.assertEqual(1000.0, d.ReadDouble())
+ self.assertTrue(d.EndOfStream())
+
class OptionsTest(unittest.TestCase):
@@ -1697,6 +1798,21 @@ class OptionsTest(unittest.TestCase):
self.assertEqual(False,
proto.DESCRIPTOR.GetOptions().message_set_wire_format)
+ def testPackedOptions(self):
+ proto = unittest_pb2.TestAllTypes()
+ proto.optional_int32 = 1
+ proto.optional_double = 3.0
+ for field_descriptor, _ in proto.ListFields():
+ self.assertEqual(False, field_descriptor.GetOptions().packed)
+
+ proto = unittest_pb2.TestPackedTypes()
+ proto.packed_int32.append(1)
+ proto.packed_double.append(3.0)
+ for field_descriptor, _ in proto.ListFields():
+ self.assertEqual(True, field_descriptor.GetOptions().packed)
+ self.assertEqual(reflection._FieldDescriptor.LABEL_REPEATED,
+ field_descriptor.label)
+
class UtilityTest(unittest.TestCase):
diff --git a/python/google/protobuf/internal/service_reflection_test.py b/python/google/protobuf/internal/service_reflection_test.py
index 29492e16..e04f8252 100755
--- a/python/google/protobuf/internal/service_reflection_test.py
+++ b/python/google/protobuf/internal/service_reflection_test.py
@@ -74,7 +74,7 @@ class FooUnitTest(unittest.TestCase):
rpc_controller.failure_message = None
- service_descriptor = unittest_pb2.TestService.DESCRIPTOR
+ service_descriptor = unittest_pb2.TestService.GetDescriptor()
srvc.CallMethod(service_descriptor.methods[1], rpc_controller,
unittest_pb2.BarRequest(), MyCallback)
self.assertEqual('Method Bar not implemented.',
@@ -118,6 +118,10 @@ class FooUnitTest(unittest.TestCase):
rpc_controller = 'controller'
request = 'request'
+ # GetDescriptor now static, still works as instance method for compatability
+ self.assertEqual(unittest_pb2.TestService_Stub.GetDescriptor(),
+ stub.GetDescriptor())
+
# Invoke method.
stub.Foo(rpc_controller, request, MyCallback)
diff --git a/python/google/protobuf/internal/test_util.py b/python/google/protobuf/internal/test_util.py
index 14dfbc51..2d50bc4a 100755
--- a/python/google/protobuf/internal/test_util.py
+++ b/python/google/protobuf/internal/test_util.py
@@ -366,3 +366,51 @@ def GoldenFile(filename):
'Could not find golden files. This test must be run from within the '
'protobuf source package so that it can read test data files from the '
'C++ source tree.')
+
+
+def SetAllPackedFields(message):
+ """Sets every field in the message to a unique value.
+
+ Args:
+ message: A unittest_pb2.TestPackedTypes instance.
+ """
+ message.packed_int32.extend([101, 102])
+ message.packed_int64.extend([103, 104])
+ message.packed_uint32.extend([105, 106])
+ message.packed_uint64.extend([107, 108])
+ message.packed_sint32.extend([109, 110])
+ message.packed_sint64.extend([111, 112])
+ message.packed_fixed32.extend([113, 114])
+ message.packed_fixed64.extend([115, 116])
+ message.packed_sfixed32.extend([117, 118])
+ message.packed_sfixed64.extend([119, 120])
+ message.packed_float.extend([121.0, 122.0])
+ message.packed_double.extend([122.0, 123.0])
+ message.packed_bool.extend([True, False])
+ message.packed_enum.extend([unittest_pb2.FOREIGN_FOO,
+ unittest_pb2.FOREIGN_BAR])
+
+
+def SetAllPackedExtensions(message):
+ """Sets every extension in the message to a unique value.
+
+ Args:
+ message: A unittest_pb2.TestPackedExtensions instance.
+ """
+ extensions = message.Extensions
+ pb2 = unittest_pb2
+
+ extensions[pb2.packed_int32_extension].append(101)
+ extensions[pb2.packed_int64_extension].append(102)
+ extensions[pb2.packed_uint32_extension].append(103)
+ extensions[pb2.packed_uint64_extension].append(104)
+ extensions[pb2.packed_sint32_extension].append(105)
+ extensions[pb2.packed_sint64_extension].append(106)
+ extensions[pb2.packed_fixed32_extension].append(107)
+ extensions[pb2.packed_fixed64_extension].append(108)
+ extensions[pb2.packed_sfixed32_extension].append(109)
+ extensions[pb2.packed_sfixed64_extension].append(110)
+ extensions[pb2.packed_float_extension].append(111.0)
+ extensions[pb2.packed_double_extension].append(112.0)
+ extensions[pb2.packed_bool_extension].append(True)
+ extensions[pb2.packed_enum_extension].append(pb2.FOREIGN_BAZ)
diff --git a/python/google/protobuf/internal/type_checkers.py b/python/google/protobuf/internal/type_checkers.py
index ba470cf2..c009627f 100755
--- a/python/google/protobuf/internal/type_checkers.py
+++ b/python/google/protobuf/internal/type_checkers.py
@@ -216,6 +216,23 @@ TYPE_TO_SERIALIZE_METHOD = {
}
+TYPE_TO_NOTAG_SERIALIZE_METHOD = {
+ _FieldDescriptor.TYPE_DOUBLE: _Encoder.AppendDoubleNoTag,
+ _FieldDescriptor.TYPE_FLOAT: _Encoder.AppendFloatNoTag,
+ _FieldDescriptor.TYPE_INT64: _Encoder.AppendInt64NoTag,
+ _FieldDescriptor.TYPE_UINT64: _Encoder.AppendUInt64NoTag,
+ _FieldDescriptor.TYPE_INT32: _Encoder.AppendInt32NoTag,
+ _FieldDescriptor.TYPE_FIXED64: _Encoder.AppendFixed64NoTag,
+ _FieldDescriptor.TYPE_FIXED32: _Encoder.AppendFixed32NoTag,
+ _FieldDescriptor.TYPE_BOOL: _Encoder.AppendBoolNoTag,
+ _FieldDescriptor.TYPE_UINT32: _Encoder.AppendUInt32NoTag,
+ _FieldDescriptor.TYPE_ENUM: _Encoder.AppendEnumNoTag,
+ _FieldDescriptor.TYPE_SFIXED32: _Encoder.AppendSFixed32NoTag,
+ _FieldDescriptor.TYPE_SFIXED64: _Encoder.AppendSFixed64NoTag,
+ _FieldDescriptor.TYPE_SINT32: _Encoder.AppendSInt32NoTag,
+ _FieldDescriptor.TYPE_SINT64: _Encoder.AppendSInt64NoTag,
+ }
+
# Maps from field type to expected wiretype.
FIELD_TYPE_TO_WIRE_TYPE = {
_FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64,
diff --git a/python/google/protobuf/internal/wire_format.py b/python/google/protobuf/internal/wire_format.py
index 5f0af11e..531c9b85 100755
--- a/python/google/protobuf/internal/wire_format.py
+++ b/python/google/protobuf/internal/wire_format.py
@@ -120,6 +120,10 @@ def Int32ByteSize(field_number, int32):
return Int64ByteSize(field_number, int32)
+def Int32ByteSizeNoTag(int32):
+ return _VarUInt64ByteSizeNoTag(0xffffffffffffffff & int32)
+
+
def Int64ByteSize(field_number, int64):
# Have to convert to uint before calling UInt64ByteSize().
return UInt64ByteSize(field_number, 0xffffffffffffffff & int64)
@@ -130,7 +134,7 @@ def UInt32ByteSize(field_number, uint32):
def UInt64ByteSize(field_number, uint64):
- return _TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64)
+ return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64)
def SInt32ByteSize(field_number, int32):
@@ -142,31 +146,31 @@ def SInt64ByteSize(field_number, int64):
def Fixed32ByteSize(field_number, fixed32):
- return _TagByteSize(field_number) + 4
+ return TagByteSize(field_number) + 4
def Fixed64ByteSize(field_number, fixed64):
- return _TagByteSize(field_number) + 8
+ return TagByteSize(field_number) + 8
def SFixed32ByteSize(field_number, sfixed32):
- return _TagByteSize(field_number) + 4
+ return TagByteSize(field_number) + 4
def SFixed64ByteSize(field_number, sfixed64):
- return _TagByteSize(field_number) + 8
+ return TagByteSize(field_number) + 8
def FloatByteSize(field_number, flt):
- return _TagByteSize(field_number) + 4
+ return TagByteSize(field_number) + 4
def DoubleByteSize(field_number, double):
- return _TagByteSize(field_number) + 8
+ return TagByteSize(field_number) + 8
def BoolByteSize(field_number, b):
- return _TagByteSize(field_number) + 1
+ return TagByteSize(field_number) + 1
def EnumByteSize(field_number, enum):
@@ -178,18 +182,18 @@ def StringByteSize(field_number, string):
def BytesByteSize(field_number, b):
- return (_TagByteSize(field_number)
+ return (TagByteSize(field_number)
+ _VarUInt64ByteSizeNoTag(len(b))
+ len(b))
def GroupByteSize(field_number, message):
- return (2 * _TagByteSize(field_number) # START and END group.
+ return (2 * TagByteSize(field_number) # START and END group.
+ message.ByteSize())
def MessageByteSize(field_number, message):
- return (_TagByteSize(field_number)
+ return (TagByteSize(field_number)
+ _VarUInt64ByteSizeNoTag(message.ByteSize())
+ message.ByteSize())
@@ -199,7 +203,7 @@ def MessageSetItemByteSize(field_number, msg):
# There are 2 tags for the beginning and ending of the repeated group, that
# is field number 1, one with field number 2 (type_id) and one with field
# number 3 (message).
- total_size = (2 * _TagByteSize(1) + _TagByteSize(2) + _TagByteSize(3))
+ total_size = (2 * TagByteSize(1) + TagByteSize(2) + TagByteSize(3))
# Add the number of bytes for type_id.
total_size += _VarUInt64ByteSizeNoTag(field_number)
@@ -214,15 +218,14 @@ def MessageSetItemByteSize(field_number, msg):
return total_size
-# Private helper functions for the *ByteSize() functions above.
-
-
-def _TagByteSize(field_number):
+def TagByteSize(field_number):
"""Returns the bytes required to serialize a tag with this field number."""
# Just pass in type 0, since the type won't affect the tag+type size.
return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0))
+# Private helper function for the *ByteSize() functions above.
+
def _VarUInt64ByteSizeNoTag(uint64):
"""Returns the bytes required to serialize a single varint.
uint64 must be unsigned.
diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py
index 9ba752e4..0d5191be 100755
--- a/python/google/protobuf/reflection.py
+++ b/python/google/protobuf/reflection.py
@@ -462,6 +462,12 @@ def _AddStaticMethods(cls):
cls._known_extensions.append(extension_handle)
cls.RegisterExtension = staticmethod(RegisterExtension)
+ def FromString(s):
+ message = cls()
+ message.MergeFromString(s)
+ return message
+ cls.FromString = staticmethod(FromString)
+
def _AddListFieldsMethod(message_descriptor, cls):
"""Helper for _AddMessageMethods()."""
@@ -665,9 +671,36 @@ def _AddByteSizeMethod(message_descriptor, cls):
else:
elements = [value]
- size = sum(_BytesForNonRepeatedElement(element, field_number, field_type)
- for element in elements)
- return size
+ if field.GetOptions().packed:
+ content_size = _ContentBytesForPackedField(message, field, elements)
+ if content_size:
+ tag_size = wire_format.TagByteSize(field_number)
+ length_size = wire_format.Int32ByteSizeNoTag(content_size)
+ return tag_size + length_size + content_size
+ else:
+ return 0
+ else:
+ return sum(_BytesForNonRepeatedElement(element, field_number, field_type)
+ for element in elements)
+
+ def _ContentBytesForPackedField(self, field, value):
+ """Returns the number of bytes required to serialize the actual
+ content of a packed field (not including the tag or the encoding
+ of the length.
+
+ Args:
+ self: The Message instance containing a field of the given type.
+ field: A FieldDescriptor describing the field of interest.
+ value: The value whose byte size we're interested in.
+
+ Returns: The number of bytes required to serialize the current value
+ of the packed "field" in "message", excluding space for tags and the
+ length encoding.
+ """
+ size = sum(_BytesForNonRepeatedElement(element, field.number, field.type)
+ for element in value)
+ # In the packed case, there are no per element tags.
+ return size - wire_format.TagByteSize(field.number) * len(value)
fields = message_descriptor.fields
has_field_names = (_HasFieldName(f.name) for f in fields)
@@ -691,6 +724,8 @@ def _AddByteSizeMethod(message_descriptor, cls):
self._cached_byte_size = size
self._cached_byte_size_dirty = False
return size
+
+ cls._ContentBytesForPackedField = _ContentBytesForPackedField
cls.ByteSize = ByteSize
@@ -788,10 +823,29 @@ def _AddSerializePartialToStringMethod(message_descriptor, cls):
repeated_value = field_value
else:
repeated_value = [field_value]
- for element in repeated_value:
- _SerializeValueToEncoder(element, field_descriptor.number,
- field_descriptor, encoder)
+ if field_descriptor.GetOptions().packed:
+ # First, write the field number and WIRETYPE_LENGTH_DELIMITED.
+ field_number = field_descriptor.number
+ encoder.AppendTag(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ # Next, write the number of bytes.
+ content_bytes = self._ContentBytesForPackedField(
+ field_descriptor, field_value)
+ encoder.AppendInt32NoTag(content_bytes)
+ # Finally, write the actual values.
+ try:
+ method = type_checkers.TYPE_TO_NOTAG_SERIALIZE_METHOD[
+ field_descriptor.type]
+ for value in repeated_value:
+ method(encoder, value)
+ except KeyError:
+ raise message_mod.EncodeError('Unrecognized field type: %d' %
+ field_descriptor.type)
+ else:
+ for element in repeated_value:
+ _SerializeValueToEncoder(element, field_descriptor.number,
+ field_descriptor, encoder)
return encoder.ToString()
+
cls.SerializePartialToString = SerializePartialToString
@@ -803,6 +857,14 @@ def _WireTypeForFieldType(field_type):
raise message_mod.DecodeError('Unknown field type: %d' % field_type)
+def _WireTypeForField(field_descriptor):
+ """Given a field descriptor, returns the expected wire type."""
+ if field_descriptor.GetOptions().packed:
+ return wire_format.WIRETYPE_LENGTH_DELIMITED
+ else:
+ return _WireTypeForFieldType(field_descriptor.type)
+
+
def _RecursivelyMerge(field_number, field_type, decoder, message):
"""Decodes a message from decoder into message.
message is either a group or a nested message within some containing
@@ -918,9 +980,11 @@ def _DeserializeMessageSetItem(message, decoder):
def _DeserializeOneEntity(message_descriptor, message, decoder):
"""Deserializes the next wire entity from decoder into message.
- The next wire entity is either a scalar or a nested message,
- and may also be an element in a repeated field (the wire encoding
- is the same).
+
+ The next wire entity is either a scalar or a nested message, an
+ element in a repeated field (the wire encoding in this case is the
+ same), or a packed repeated field (in this case, the entire repeated
+ field is read by a single call to _DeserializeOneEntity).
Args:
message_descriptor: A Descriptor instance describing all fields
@@ -973,14 +1037,14 @@ def _DeserializeOneEntity(message_descriptor, message, decoder):
# if this field is a nonrepeated scalar.
field_number = field_descriptor.number
- field_type = field_descriptor.type
- expected_wire_type = _WireTypeForFieldType(field_type)
+ expected_wire_type = _WireTypeForField(field_descriptor)
if wire_type != expected_wire_type:
# Need to fill in uninterpreted_bytes. Work for the next CL.
raise RuntimeError('TODO(robinson): Wiretype mismatches not handled.')
property_name = _PropertyName(field_descriptor.name)
label = field_descriptor.label
+ field_type = field_descriptor.type
cpp_type = field_descriptor.cpp_type
# Nonrepeated scalar. Just set the field directly.
@@ -1000,8 +1064,17 @@ def _DeserializeOneEntity(message_descriptor, message, decoder):
if cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE:
# Repeated scalar.
- element_list.append(_DeserializeScalarFromDecoder(field_type, decoder))
- return decoder.Position() - initial_position
+ if not field_descriptor.GetOptions().packed:
+ element_list.append(_DeserializeScalarFromDecoder(field_type, decoder))
+ return decoder.Position() - initial_position
+ else:
+ # Packed repeated field.
+ length = _DeserializeScalarFromDecoder(
+ _FieldDescriptor.TYPE_INT32, decoder)
+ content_start = decoder.Position()
+ while decoder.Position() - content_start < length:
+ element_list.append(_DeserializeScalarFromDecoder(field_type, decoder))
+ return decoder.Position() - content_start
else:
# Repeated composite.
composite = element_list.add()
diff --git a/python/google/protobuf/service.py b/python/google/protobuf/service.py
index 3989216a..9ec42fe3 100755
--- a/python/google/protobuf/service.py
+++ b/python/google/protobuf/service.py
@@ -31,7 +31,7 @@
"""Declares the RPC service interfaces.
This module declares the abstract interfaces underlying proto2 RPC
-services. These are intented to be independent of any particular RPC
+services. These are intended to be independent of any particular RPC
implementation, so that proto2 services can be used on top of a variety
of implementations.
"""
@@ -39,6 +39,11 @@ of implementations.
__author__ = 'petar@google.com (Petar Petrov)'
+class RpcException(Exception):
+ """Exception raised on failed blocking RPC method call."""
+ pass
+
+
class Service(object):
"""Abstract base interface for protocol-buffer-based RPC services.
@@ -49,7 +54,7 @@ class Service(object):
its exact type at compile time (analogous to the Message interface).
"""
- def GetDescriptor(self):
+ def GetDescriptor():
"""Retrieves this service's descriptor."""
raise NotImplementedError
@@ -57,6 +62,14 @@ class Service(object):
request, done):
"""Calls a method of the service specified by method_descriptor.
+ If "done" is None then the call is blocking and the response
+ message will be returned directly. Otherwise the call is asynchronous
+ and "done" will later be called with the response value.
+
+ In the blocking case, RpcException will be raised on error.
+ Asynchronous calls must check status via the Failed method of the
+ RpcController.
+
Preconditions:
* method_descriptor.service == GetDescriptor
* request is of the exact same classes as returned by
diff --git a/python/google/protobuf/service_reflection.py b/python/google/protobuf/service_reflection.py
index bdd6bad5..851e83e7 100755
--- a/python/google/protobuf/service_reflection.py
+++ b/python/google/protobuf/service_reflection.py
@@ -142,24 +142,17 @@ class _ServiceBuilder(object):
# instance to the method that does the real CallMethod work.
def _WrapCallMethod(srvc, method_descriptor,
rpc_controller, request, callback):
- self._CallMethod(srvc, method_descriptor,
+ return self._CallMethod(srvc, method_descriptor,
rpc_controller, request, callback)
self.cls = cls
cls.CallMethod = _WrapCallMethod
- cls.GetDescriptor = self._GetDescriptor
+ cls.GetDescriptor = staticmethod(lambda: self.descriptor)
+ cls.GetDescriptor.__doc__ = "Returns the service descriptor."
cls.GetRequestClass = self._GetRequestClass
cls.GetResponseClass = self._GetResponseClass
for method in self.descriptor.methods:
setattr(cls, method.name, self._GenerateNonImplementedMethod(method))
- def _GetDescriptor(self):
- """Retrieves the service descriptor.
-
- Returns:
- The descriptor of the service (of type ServiceDescriptor).
- """
- return self.descriptor
-
def _CallMethod(self, srvc, method_descriptor,
rpc_controller, request, callback):
"""Calls the method described by a given method descriptor.
@@ -175,7 +168,7 @@ class _ServiceBuilder(object):
raise RuntimeError(
'CallMethod() given method descriptor for wrong service type.')
method = getattr(srvc, method_descriptor.name)
- method(rpc_controller, request, callback)
+ return method(rpc_controller, request, callback)
def _GetRequestClass(self, method_descriptor):
"""Returns the class of the request protocol message.
@@ -270,8 +263,8 @@ class _ServiceStubBuilder(object):
setattr(cls, method.name, self._GenerateStubMethod(method))
def _GenerateStubMethod(self, method):
- return lambda inst, rpc_controller, request, callback: self._StubMethod(
- inst, method, rpc_controller, request, callback)
+ return (lambda inst, rpc_controller, request, callback=None:
+ self._StubMethod(inst, method, rpc_controller, request, callback))
def _StubMethod(self, stub, method_descriptor,
rpc_controller, request, callback):
@@ -283,7 +276,9 @@ class _ServiceStubBuilder(object):
rpc_controller: Rpc controller to execute the method.
request: Request protocol message.
callback: A callback to execute when the method finishes.
+ Returns:
+ Response message (in case of blocking call).
"""
- stub.rpc_channel.CallMethod(
+ return stub.rpc_channel.CallMethod(
method_descriptor, rpc_controller, request,
method_descriptor.output_type._concrete_class, callback)
diff --git a/src/Makefile.am b/src/Makefile.am
index c13a723e..18167482 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -160,6 +160,7 @@ EXTRA_DIST = \
$(protoc_inputs) \
solaris/libstdc++.la \
google/protobuf/testdata/golden_message \
+ google/protobuf/testdata/golden_packed_fields_message \
google/protobuf/testdata/text_format_unittest_data.txt \
google/protobuf/testdata/text_format_unittest_extensions_data.txt \
google/protobuf/package_info.h \
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index 089844f4..09473ec7 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -751,7 +751,8 @@ bool CommandLineInterface::GenerateOutput(
if (!output_directive.generator->Generate(
parsed_file, output_directive.parameter, &output_directory, &error)) {
// Generator returned an error.
- cerr << output_directive.name << ": " << error << endl;
+ cerr << parsed_file->name() << ": " << output_directive.name << ": "
+ << error << endl;
return false;
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index c998f20b..19779a8a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -158,7 +158,13 @@ RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
void RepeatedEnumFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
- printer->Print(variables_, "::google::protobuf::RepeatedField<int> $name$_;\n");
+ printer->Print(variables_,
+ "::google::protobuf::RepeatedField<int> $name$_;\n");
+ if (descriptor_->options().packed() &&
+ descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+ printer->Print(variables_,
+ "mutable int _$name$_cached_byte_size_;\n");
+ }
}
void RepeatedEnumFieldGenerator::
@@ -217,31 +223,84 @@ GenerateInitializer(io::Printer* printer) const {
void RepeatedEnumFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
- printer->Print(variables_,
- "int value;\n"
- "DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));\n"
- "if ($type$_IsValid(value)) {\n"
- " add_$name$(static_cast< $type$ >(value));\n"
- "} else {\n"
- " mutable_unknown_fields()->AddField($number$)->add_varint(value);\n"
- "}\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "::google::protobuf::uint32 length;\n"
+ "DO_(input->ReadVarint32(&length));\n"
+ "::google::protobuf::io::CodedInputStream::Limit limit = "
+ "input->PushLimit(length);\n"
+ "while (input->BytesUntilLimit() > 0) {\n"
+ " int value;\n"
+ " DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));\n"
+ " if ($type$_IsValid(value)) {\n"
+ " add_$name$(static_cast< $type$ >(value));\n"
+ " }\n"
+ "}\n"
+ "input->PopLimit(limit);\n");
+ } else {
+ printer->Print(variables_,
+ "int value;\n"
+ "DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));\n"
+ "if ($type$_IsValid(value)) {\n"
+ " add_$name$(static_cast< $type$ >(value));\n"
+ "} else {\n"
+ " mutable_unknown_fields()->AddField($number$)->add_varint(value);\n"
+ "}\n");
+ }
}
void RepeatedEnumFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ // Write the tag and the size.
+ printer->Print(variables_,
+ "if (this->$name$_size() > 0) {\n"
+ " DO_(::google::protobuf::internal::WireFormat::WriteTag("
+ "$number$, ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED,"
+ "output));\n"
+ " DO_(output->WriteVarint32(_$name$_cached_byte_size_));\n"
+ "}\n");
+ }
printer->Print(variables_,
- "DO_(::google::protobuf::internal::WireFormat::WriteEnum("
- "$number$, this->$name$(i), output));\n");
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ " DO_(::google::protobuf::internal::WireFormat::WriteEnumNoTag("
+ "this->$name$(i), output));\n");
+ } else {
+ printer->Print(variables_,
+ " DO_(::google::protobuf::internal::WireFormat::WriteEnum("
+ "$number$, this->$name$(i), output));\n");
+ }
+ printer->Print("}\n");
}
void RepeatedEnumFieldGenerator::
GenerateByteSize(io::Printer* printer) const {
printer->Print(variables_,
- "total_size += $tag_size$ * $name$_size();\n"
- "for (int i = 0; i < $name$_size(); i++) {\n"
- " total_size += ::google::protobuf::internal::WireFormat::EnumSize(\n"
- " this->$name$(i));\n"
- "}\n");
+ "{\n"
+ " int data_size = 0;\n");
+ printer->Indent();
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " data_size += ::google::protobuf::internal::WireFormat::EnumSize(\n"
+ " this->$name$(i));\n"
+ "}\n");
+
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (data_size > 0) {\n"
+ " total_size += $tag_size$ + "
+ "::google::protobuf::internal::WireFormat::Int32Size(data_size);\n"
+ "}\n"
+ "_$name$_cached_byte_size_ = data_size;\n"
+ "total_size += data_size;\n");
+ } else {
+ printer->Print(variables_,
+ "total_size += $tag_size$ * this->$name$_size() + data_size;\n");
+ }
+ printer->Outdent();
+ printer->Print("}\n");
}
} // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index eacceeaf..c6843e93 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -41,7 +41,7 @@
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/wire_format.h>
+#include <google/protobuf/wire_format_inl.h>
#include <google/protobuf/descriptor.pb.h>
namespace google {
@@ -1169,10 +1169,9 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
" goto handle_uninterpreted;\n"
" }\n",
"number", SimpleItoa(field->number()),
- "wiretype", kWireTypeNames[
- WireFormat::WireTypeForFieldType(field->type())]);
+ "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]);
- if (i > 0 || field->is_repeated()) {
+ if (i > 0 || (field->is_repeated() && !field->options().packed())) {
printer->Print(
" parse_$name$:\n",
"name", field->name());
@@ -1184,7 +1183,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
// switch() is slow since it can't be predicted well. Insert some if()s
// here that attempt to predict the next tag.
- if (field->is_repeated()) {
+ if (field->is_repeated() && !field->options().packed()) {
// Expect repeats of this field.
printer->Print(
"if (input->ExpectTag($tag$)) goto parse_$name$;\n",
@@ -1283,22 +1282,20 @@ void MessageGenerator::GenerateSerializeOneField(
io::Printer* printer, const FieldDescriptor* field) {
PrintFieldComment(printer, field);
- if (field->is_repeated()) {
- printer->Print(
- "for (int i = 0; i < $name$_.size(); i++) {\n",
- "name", FieldName(field));
- } else {
+ if (!field->is_repeated()) {
printer->Print(
"if (_has_bit($index$)) {\n",
"index", SimpleItoa(field->index()));
+ printer->Indent();
}
- printer->Indent();
-
field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
- printer->Outdent();
- printer->Print("}\n\n");
+ if (!field->is_repeated()) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ printer->Print("\n");
}
void MessageGenerator::GenerateSerializeOneExtensionRange(
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index d1c31067..7d57a6df 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -232,15 +232,17 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
void RepeatedMessageFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
printer->Print(variables_,
- "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$NoVirtual("
- "$number$, this->$name$(i), output));\n");
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " DO_(::google::protobuf::internal::WireFormat::Write$declared_type$NoVirtual("
+ "$number$, this->$name$(i), output));\n"
+ "}\n");
}
void RepeatedMessageFieldGenerator::
GenerateByteSize(io::Printer* printer) const {
printer->Print(variables_,
- "total_size += $tag_size$ * $name$_size();\n"
- "for (int i = 0; i < $name$_size(); i++) {\n"
+ "total_size += $tag_size$ * this->$name$_size();\n"
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
" total_size +=\n"
" ::google::protobuf::internal::WireFormat::$declared_type$SizeNoVirtual(\n"
" this->$name$(i));\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
index ef4072f0..768d30cc 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -227,6 +227,11 @@ void RepeatedPrimitiveFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
printer->Print(variables_,
"::google::protobuf::RepeatedField< $type$ > $name$_;\n");
+ if (descriptor_->options().packed() &&
+ descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+ printer->Print(variables_,
+ "mutable int _$name$_cached_byte_size_;\n");
+ }
}
void RepeatedPrimitiveFieldGenerator::
@@ -283,33 +288,90 @@ GenerateInitializer(io::Printer* printer) const {
void RepeatedPrimitiveFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
- printer->Print(variables_,
- "$type$ value;\n"
- "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$(input, &value));\n"
- "add_$name$(value);\n");
+ if (descriptor_->options().packed()) {
+ printer->Print("{\n");
+ printer->Indent();
+ printer->Print(variables_,
+ "::google::protobuf::uint32 length;\n"
+ "DO_(input->ReadVarint32(&length));\n"
+ "::google::protobuf::io::CodedInputStream::Limit limit = "
+ "input->PushLimit(length);\n"
+ "while (input->BytesUntilLimit() > 0) {\n"
+ " $type$ value;\n"
+ " DO_(::google::protobuf::internal::WireFormat::Read$declared_type$("
+ "input, &value));\n"
+ " add_$name$(value);\n"
+ "}\n"
+ "input->PopLimit(limit);\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ } else {
+ printer->Print(variables_,
+ "$type$ value;\n"
+ "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$("
+ "input, &value));\n"
+ "add_$name$(value);\n");
+ }
}
void RepeatedPrimitiveFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ // Write the tag and the size.
+ printer->Print(variables_,
+ "if (this->$name$_size() > 0) {\n"
+ " DO_(::google::protobuf::internal::WireFormat::WriteTag("
+ "$number$, ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED,"
+ "output));\n"
+ " DO_(output->WriteVarint32(_$name$_cached_byte_size_));\n"
+ "}\n");
+ }
printer->Print(variables_,
- "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$("
- "$number$, this->$name$(i), output));\n");
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ " DO_(::google::protobuf::internal::WireFormat::Write$declared_type$NoTag("
+ "this->$name$(i), output));\n");
+ } else {
+ printer->Print(variables_,
+ " DO_(::google::protobuf::internal::WireFormat::Write$declared_type$("
+ "$number$, this->$name$(i), output));\n");
+ }
+ printer->Print("}\n");
}
void RepeatedPrimitiveFieldGenerator::
GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "{\n"
+ " int data_size = 0;\n");
+ printer->Indent();
int fixed_size = FixedSize(descriptor_->type());
if (fixed_size == -1) {
printer->Print(variables_,
- "total_size += $tag_size$ * $name$_size();\n"
- "for (int i = 0; i < $name$_size(); i++) {\n"
- " total_size += ::google::protobuf::internal::WireFormat::$declared_type$Size(\n"
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " data_size += ::google::protobuf::internal::WireFormat::$declared_type$Size(\n"
" this->$name$(i));\n"
"}\n");
} else {
printer->Print(variables_,
- "total_size += ($tag_size$ + $fixed_size$) * $name$_size();\n");
+ "data_size = $fixed_size$ * this->$name$_size();\n");
+ }
+
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (data_size > 0) {\n"
+ " total_size += $tag_size$ + "
+ "::google::protobuf::internal::WireFormat::Int32Size(data_size);\n"
+ "}\n"
+ "_$name$_cached_byte_size_ = data_size;\n"
+ "total_size += data_size;\n");
+ } else {
+ printer->Print(variables_,
+ "total_size += $tag_size$ * this->$name$_size() + data_size;\n");
}
+ printer->Outdent();
+ printer->Print("}\n");
}
} // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index 3e694ab7..200e3d68 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -374,15 +374,17 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
void RepeatedStringFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
printer->Print(variables_,
- "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$("
- "$number$, this->$name$(i), output));\n");
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " DO_(::google::protobuf::internal::WireFormat::Write$declared_type$("
+ "$number$, this->$name$(i), output));\n"
+ "}\n");
}
void RepeatedStringFieldGenerator::
GenerateByteSize(io::Printer* printer) const {
printer->Print(variables_,
- "total_size += $tag_size$ * $name$_size();\n"
- "for (int i = 0; i < $name$_size(); i++) {\n"
+ "total_size += $tag_size$ * this->$name$_size();\n"
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
" total_size += ::google::protobuf::internal::WireFormat::$declared_type$Size(\n"
" this->$name$(i));\n"
"}\n");
diff --git a/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
index a4d96ac5..79971a95 100644
--- a/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
+++ b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
@@ -54,6 +54,14 @@ message TestConflictingSymbolNames {
optional int32 total_size = 6;
optional int32 tag = 7;
+ enum TestEnum { FOO = 1; }
+ message Data1 { repeated int32 data = 1; }
+ message Data2 { repeated TestEnum data = 1; }
+ message Data3 { repeated string data = 1; }
+ message Data4 { repeated Data4 data = 1; }
+ message Data5 { repeated string data = 1 [ctype=STRING_PIECE]; }
+ message Data6 { repeated string data = 1 [ctype=CORD]; }
+
optional int32 source = 8;
optional int32 value = 9;
optional int32 file = 10;
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index 393c923b..c7e4ee3d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -225,7 +225,6 @@ TEST(GeneratedMessageTest, ClearOneField) {
TEST(GeneratedMessageTest, CopyFrom) {
unittest::TestAllTypes message1, message2;
- string data;
TestUtil::SetAllFields(&message1);
message2.CopyFrom(message1);
@@ -413,6 +412,13 @@ TEST(GeneratedMessageTest, Serialization) {
EXPECT_TRUE(message2.ParseFromString(data));
TestUtil::ExpectAllFieldsSet(message2);
+
+ unittest::TestPackedTypes packed_message1, packed_message2;
+ string packed_data;
+ TestUtil::SetPackedFields(&packed_message1);
+ packed_message1.SerializeToString(&packed_data);
+ EXPECT_TRUE(packed_message2.ParseFromString(packed_data));
+ TestUtil::ExpectPackedFieldsSet(packed_message2);
}
diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc
index b1484763..4aac6493 100644
--- a/src/google/protobuf/compiler/java/java_enum.cc
+++ b/src/google/protobuf/compiler/java/java_enum.cc
@@ -71,7 +71,8 @@ void EnumGenerator::Generate(io::Printer* printer) {
descriptor_->containing_type() == NULL &&
descriptor_->file()->options().java_multiple_files();
printer->Print(
- "public $static$ enum $classname$ {\n",
+ "public $static$ enum $classname$\n"
+ " implements com.google.protobuf.ProtocolMessageEnum {\n",
"static", is_own_file ? "" : "static",
"classname", descriptor_->name());
printer->Indent();
diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc
index e95fdab4..2153042d 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field.cc
@@ -39,6 +39,7 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format_inl.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
@@ -64,6 +65,9 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
(*variables)["number"] = SimpleItoa(descriptor->number());
(*variables)["type"] = type;
(*variables)["default"] = type + "." + default_value->name();
+ (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
+ (*variables)["tag_size"] = SimpleItoa(
+ internal::WireFormat::TagSize(descriptor->number(), descriptor->type()));
}
} // namespace
@@ -97,6 +101,9 @@ GenerateBuilderMembers(io::Printer* printer) const {
" return result.get$capitalized_name$();\n"
"}\n"
"public Builder set$capitalized_name$($type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
" result.has$capitalized_name$ = true;\n"
" result.$name$_ = value;\n"
" return this;\n"
@@ -176,6 +183,12 @@ GenerateMembers(io::Printer* printer) const {
"public $type$ get$capitalized_name$(int index) {\n"
" return $name$_.get(index);\n"
"}\n");
+
+ if (descriptor_->options().packed() &&
+ descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+ printer->Print(variables_,
+ "private int $name$MemoizedSerializedSize;\n");
+ }
}
void RepeatedEnumFieldGenerator::
@@ -195,10 +208,16 @@ GenerateBuilderMembers(io::Printer* printer) const {
" return result.get$capitalized_name$(index);\n"
"}\n"
"public Builder set$capitalized_name$(int index, $type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
" result.$name$_.set(index, value);\n"
" return this;\n"
"}\n"
"public Builder add$capitalized_name$($type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
" if (result.$name$_.isEmpty()) {\n"
" result.$name$_ = new java.util.ArrayList<$type$>();\n"
" }\n"
@@ -241,6 +260,16 @@ GenerateBuildingCode(io::Printer* printer) const {
void RepeatedEnumFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
+ // If packed, set up the while loop
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "int length = input.readRawVarint32();\n"
+ "int oldLimit = input.pushLimit(length);\n"
+ "while(input.getBytesUntilLimit() > 0) {\n");
+ printer->Indent();
+ }
+
+ // Read and store the enum
printer->Print(variables_,
"int rawValue = input.readEnum();\n"
"$type$ value = $type$.valueOf(rawValue);\n"
@@ -249,23 +278,68 @@ GenerateParsingCode(io::Printer* printer) const {
"} else {\n"
" add$capitalized_name$(value);\n"
"}\n");
+
+ if (descriptor_->options().packed()) {
+ printer->Outdent();
+ printer->Print(variables_,
+ "}\n"
+ "input.popLimit(oldLimit);\n");
+ }
}
void RepeatedEnumFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
- printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
- " output.writeEnum($number$, element.getNumber());\n"
- "}\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (get$capitalized_name$List().size() > 0) {\n"
+ " output.writeRawVarint32($tag$);\n"
+ " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+ "}\n"
+ "for ($type$ element : get$capitalized_name$List()) {\n"
+ " output.writeEnumNoTag(element.getNumber());\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "for ($type$ element : get$capitalized_name$List()) {\n"
+ " output.writeEnum($number$, element.getNumber());\n"
+ "}\n");
+ }
}
void RepeatedEnumFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
+ "{\n"
+ " int dataSize = 0;\n");
+ printer->Indent();
+
+ printer->Print(variables_,
"for ($type$ element : get$capitalized_name$List()) {\n"
- " size += com.google.protobuf.CodedOutputStream\n"
- " .computeEnumSize($number$, element.getNumber());\n"
+ " dataSize += com.google.protobuf.CodedOutputStream\n"
+ " .computeEnumSizeNoTag(element.getNumber());\n"
"}\n");
+ printer->Print(
+ "size += dataSize;\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (!get$capitalized_name$List().isEmpty()) {"
+ " size += $tag_size$;\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeRawVarint32Size(dataSize);\n"
+ "}");
+ } else {
+ printer->Print(variables_,
+ "size += $tag_size$ * get$capitalized_name$List().size();\n");
+ }
+
+ // cache the data size for packed fields.
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "$name$MemoizedSerializedSize = dataSize;\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
}
string RepeatedEnumFieldGenerator::GetBoxedType() const {
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index 3fdd1d57..9a4b2f79 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -41,7 +41,7 @@
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/wire_format.h>
+#include <google/protobuf/wire_format_inl.h>
#include <google/protobuf/descriptor.pb.h>
namespace google {
@@ -500,6 +500,7 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) {
"public static Builder newBuilder($classname$ prototype) {\n"
" return new Builder().mergeFrom(prototype);\n"
"}\n"
+ "public Builder toBuilder() { return newBuilder(this); }\n"
"\n",
"classname", ClassName(descriptor_));
@@ -634,6 +635,13 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
}
printer->Outdent();
+
+ // if message type has extensions
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ " this.mergeExtensionFields(other);\n");
+ }
+
printer->Print(
" this.mergeUnknownFields(other.getUnknownFields());\n"
" return this;\n"
@@ -692,7 +700,7 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = sorted_fields[i];
uint32 tag = WireFormat::MakeTag(field->number(),
- WireFormat::WireTypeForFieldType(field->type()));
+ WireFormat::WireTypeForField(field));
printer->Print(
"case $tag$: {\n",
diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc
index c85a1598..bbddddde 100644
--- a/src/google/protobuf/compiler/java/java_message_field.cc
+++ b/src/google/protobuf/compiler/java/java_message_field.cc
@@ -94,6 +94,9 @@ GenerateBuilderMembers(io::Printer* printer) const {
" return result.get$capitalized_name$();\n"
"}\n"
"public Builder set$capitalized_name$($type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
" result.has$capitalized_name$ = true;\n"
" result.$name$_ = value;\n"
" return this;\n"
@@ -216,6 +219,9 @@ GenerateBuilderMembers(io::Printer* printer) const {
" return result.get$capitalized_name$(index);\n"
"}\n"
"public Builder set$capitalized_name$(int index, $type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
" result.$name$_.set(index, value);\n"
" return this;\n"
"}\n"
@@ -225,6 +231,9 @@ GenerateBuilderMembers(io::Printer* printer) const {
" return this;\n"
"}\n"
"public Builder add$capitalized_name$($type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
" if (result.$name$_.isEmpty()) {\n"
" result.$name$_ = new java.util.ArrayList<$type$>();\n"
" }\n"
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc
index fb4e650f..798e8608 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -39,6 +39,7 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format_inl.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
@@ -47,6 +48,8 @@ namespace protobuf {
namespace compiler {
namespace java {
+using internal::WireFormat;
+
namespace {
const char* PrimitiveTypeName(JavaType type) {
@@ -69,6 +72,26 @@ const char* PrimitiveTypeName(JavaType type) {
return NULL;
}
+bool IsReferenceType(JavaType type) {
+ switch (type) {
+ case JAVATYPE_INT : return false;
+ case JAVATYPE_LONG : return false;
+ case JAVATYPE_FLOAT : return false;
+ case JAVATYPE_DOUBLE : return false;
+ case JAVATYPE_BOOLEAN: return false;
+ case JAVATYPE_STRING : return true;
+ case JAVATYPE_BYTES : return true;
+ case JAVATYPE_ENUM : return true;
+ case JAVATYPE_MESSAGE: return true;
+
+ // No default because we want the compiler to complain if any new
+ // JavaTypes are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
const char* GetCapitalizedType(const FieldDescriptor* field) {
switch (field->type()) {
case FieldDescriptor::TYPE_INT32 : return "Int32" ;
@@ -108,6 +131,38 @@ bool AllPrintableAscii(const string& text) {
return true;
}
+// For encodings with fixed sizes, returns that size in bytes. Otherwise
+// returns -1.
+int FixedSize(FieldDescriptor::Type type) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32 : return -1;
+ case FieldDescriptor::TYPE_INT64 : return -1;
+ case FieldDescriptor::TYPE_UINT32 : return -1;
+ case FieldDescriptor::TYPE_UINT64 : return -1;
+ case FieldDescriptor::TYPE_SINT32 : return -1;
+ case FieldDescriptor::TYPE_SINT64 : return -1;
+ case FieldDescriptor::TYPE_FIXED32 : return WireFormat::kFixed32Size;
+ case FieldDescriptor::TYPE_FIXED64 : return WireFormat::kFixed64Size;
+ case FieldDescriptor::TYPE_SFIXED32: return WireFormat::kSFixed32Size;
+ case FieldDescriptor::TYPE_SFIXED64: return WireFormat::kSFixed64Size;
+ case FieldDescriptor::TYPE_FLOAT : return WireFormat::kFloatSize;
+ case FieldDescriptor::TYPE_DOUBLE : return WireFormat::kDoubleSize;
+
+ case FieldDescriptor::TYPE_BOOL : return WireFormat::kBoolSize;
+ case FieldDescriptor::TYPE_ENUM : return -1;
+
+ case FieldDescriptor::TYPE_STRING : return -1;
+ case FieldDescriptor::TYPE_BYTES : return -1;
+ case FieldDescriptor::TYPE_GROUP : return -1;
+ case FieldDescriptor::TYPE_MESSAGE : return -1;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return -1;
+}
+
string DefaultValue(const FieldDescriptor* field) {
// Switch on cpp_type since we need to know which default_value_* method
// of FieldDescriptor to call.
@@ -177,8 +232,22 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
(*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
(*variables)["default"] = DefaultValue(descriptor);
(*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
+ (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
+ (*variables)["tag_size"] = SimpleItoa(
+ WireFormat::TagSize(descriptor->number(), descriptor->type()));
+ if (IsReferenceType(GetJavaType(descriptor))) {
+ (*variables)["null_check"] =
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n";
+ } else {
+ (*variables)["null_check"] = "";
+ }
+ int fixed_size = FixedSize(descriptor->type());
+ if (fixed_size != -1) {
+ (*variables)["fixed_size"] = SimpleItoa(fixed_size);
+ }
}
-
} // namespace
// ===================================================================
@@ -210,6 +279,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
" return result.get$capitalized_name$();\n"
"}\n"
"public Builder set$capitalized_name$($type$ value) {\n"
+ "$null_check$"
" result.has$capitalized_name$ = true;\n"
" result.$name$_ = value;\n"
" return this;\n"
@@ -283,6 +353,12 @@ GenerateMembers(io::Printer* printer) const {
"public $type$ get$capitalized_name$(int index) {\n"
" return $name$_.get(index);\n"
"}\n");
+
+ if (descriptor_->options().packed() &&
+ descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+ printer->Print(variables_,
+ "private int $name$MemoizedSerializedSize;\n");
+ }
}
void RepeatedPrimitiveFieldGenerator::
@@ -302,10 +378,12 @@ GenerateBuilderMembers(io::Printer* printer) const {
" return result.get$capitalized_name$(index);\n"
"}\n"
"public Builder set$capitalized_name$(int index, $type$ value) {\n"
+ "$null_check$"
" result.$name$_.set(index, value);\n"
" return this;\n"
"}\n"
"public Builder add$capitalized_name$($type$ value) {\n"
+ "$null_check$"
" if (result.$name$_.isEmpty()) {\n"
" result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n"
" }\n"
@@ -348,25 +426,80 @@ GenerateBuildingCode(io::Printer* printer) const {
void RepeatedPrimitiveFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
- printer->Print(variables_,
- "add$capitalized_name$(input.read$capitalized_type$());\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "int length = input.readRawVarint32();\n"
+ "int limit = input.pushLimit(length);\n"
+ "while (input.getBytesUntilLimit() > 0) {\n"
+ " add$capitalized_name$(input.read$capitalized_type$());\n"
+ "}\n"
+ "input.popLimit(limit);\n");
+ } else {
+ printer->Print(variables_,
+ "add$capitalized_name$(input.read$capitalized_type$());\n");
+ }
}
void RepeatedPrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
- printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
- " output.write$capitalized_type$($number$, element);\n"
- "}\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (get$capitalized_name$List().size() > 0) {\n"
+ " output.writeRawVarint32($tag$);\n"
+ " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+ "}\n"
+ "for ($type$ element : get$capitalized_name$List()) {\n"
+ " output.write$capitalized_type$NoTag(element);\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "for ($type$ element : get$capitalized_name$List()) {\n"
+ " output.write$capitalized_type$($number$, element);\n"
+ "}\n");
+ }
}
void RepeatedPrimitiveFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
- " size += com.google.protobuf.CodedOutputStream\n"
- " .compute$capitalized_type$Size($number$, element);\n"
- "}\n");
+ "{\n"
+ " int dataSize = 0;\n");
+ printer->Indent();
+
+ if (FixedSize(descriptor_->type()) == -1) {
+ printer->Print(variables_,
+ "for ($type$ element : get$capitalized_name$List()) {\n"
+ " dataSize += com.google.protobuf.CodedOutputStream\n"
+ " .compute$capitalized_type$SizeNoTag(element);\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n");
+ }
+
+ printer->Print(
+ "size += dataSize;\n");
+
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (!get$capitalized_name$List().isEmpty()) {\n"
+ " size += $tag_size$;\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeInt32SizeNoTag(dataSize);\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "size += $tag_size$ * get$capitalized_name$List().size();\n");
+ }
+
+ // cache the data size for packed fields.
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "$name$MemoizedSerializedSize = dataSize;\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
}
string RepeatedPrimitiveFieldGenerator::GetBoxedType() const {
diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc
index 754dcbda..ca69fd4c 100644
--- a/src/google/protobuf/compiler/python/python_generator.cc
+++ b/src/google/protobuf/compiler/python/python_generator.cc
@@ -111,7 +111,6 @@ void PrintTopBoilerplate(
io::Printer* printer, const FileDescriptor* file, bool descriptor_proto) {
// TODO(robinson): Allow parameterization of Python version?
printer->Print(
- "#!/usr/bin/python2.4\n"
"# Generated by the protocol buffer compiler. DO NOT EDIT!\n"
"\n"
"from google.protobuf import descriptor\n"
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index 21c709fb..eb5b5937 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -122,6 +122,35 @@ namespace {
const string kEmptyString;
+string ToCamelCase(const string& input) {
+ bool capitalize_next = false;
+ string result;
+ result.reserve(input.size());
+
+ for (int i = 0; i < input.size(); i++) {
+ if (input[i] == '_') {
+ capitalize_next = true;
+ } else if (capitalize_next) {
+ // Note: I distrust ctype.h due to locales.
+ if ('a' <= input[i] && input[i] <= 'z') {
+ result.push_back(input[i] - 'a' + 'A');
+ } else {
+ result.push_back(input[i]);
+ }
+ capitalize_next = false;
+ } else {
+ result.push_back(input[i]);
+ }
+ }
+
+ // Lower-case the first letter.
+ if (!result.empty() && 'A' <= result[0] && result[0] <= 'Z') {
+ result[0] = result[0] - 'A' + 'a';
+ }
+
+ return result;
+}
+
// A DescriptorPool contains a bunch of hash_maps to implement the
// various Find*By*() methods. Since hashtable lookups are O(1), it's
// most efficient to construct a fixed set of large hash_maps used by
@@ -253,6 +282,9 @@ typedef hash_map<PointerStringPair, Symbol,
typedef hash_map<const char*, const FileDescriptor*,
hash<const char*>, CStringEqual>
FilesByNameMap;
+typedef hash_map<PointerStringPair, const FieldDescriptor*,
+ PointerStringPairHash, PointerStringPairEqual>
+ FieldsByNameMap;
typedef hash_map<DescriptorIntPair, const FieldDescriptor*,
PointerIntegerPairHash<DescriptorIntPair> >
FieldsByNumberMap;
@@ -296,21 +328,29 @@ class DescriptorPool::Tables {
// Finding items.
// Find symbols. These return a null Symbol (symbol.IsNull() is true)
- // if not found. FindSymbolOfType() additionally returns null if the
- // symbol is not of the given type.
+ // if not found.
inline Symbol FindSymbol(const string& key) const;
- inline Symbol FindSymbolOfType(const string& key,
- const Symbol::Type type) const;
inline Symbol FindNestedSymbol(const void* parent,
const string& name) const;
inline Symbol FindNestedSymbolOfType(const void* parent,
const string& name,
const Symbol::Type type) const;
+ // This implements the body of DescriptorPool::Find*ByName(). It should
+ // really be a private method of DescriptorPool, but that would require
+ // declaring Symbol in descriptor.h, which would drag all kinds of other
+ // stuff into the header. Yay C++.
+ Symbol FindByNameHelper(
+ const DescriptorPool* pool, const string& name) const;
+
// These return NULL if not found.
inline const FileDescriptor* FindFile(const string& key) const;
inline const FieldDescriptor* FindFieldByNumber(
const Descriptor* parent, int number) const;
+ inline const FieldDescriptor* FindFieldByLowercaseName(
+ const void* parent, const string& lowercase_name) const;
+ inline const FieldDescriptor* FindFieldByCamelcaseName(
+ const void* parent, const string& camelcase_name) const;
inline const EnumValueDescriptor* FindEnumValueByNumber(
const EnumDescriptor* parent, int number) const;
@@ -330,6 +370,10 @@ class DescriptorPool::Tables {
bool AddFieldByNumber(const FieldDescriptor* field);
bool AddEnumValueByNumber(const EnumValueDescriptor* value);
+ // Adds the field to the lowercase_name and camelcase_name maps. Never
+ // fails because we allow duplicates; the first field by the name wins.
+ void AddFieldByStylizedNames(const FieldDescriptor* field);
+
// Like AddSymbol(), but only adds to symbols_by_parent_, not
// symbols_by_name_. Used for enum values, which need to be registered
// under multiple parents (their type and its parent).
@@ -364,6 +408,8 @@ class DescriptorPool::Tables {
SymbolsByNameMap symbols_by_name_;
SymbolsByParentMap symbols_by_parent_;
FilesByNameMap files_by_name_;
+ FieldsByNameMap fields_by_lowercase_name_;
+ FieldsByNameMap fields_by_camelcase_name_;
FieldsByNumberMap fields_by_number_; // Includes extensions.
EnumValuesByNumberMap enum_values_by_number_;
@@ -373,6 +419,8 @@ class DescriptorPool::Tables {
vector<const char* > symbols_after_checkpoint_;
vector<PointerStringPair> symbols_by_parent_after_checkpoint_;
vector<const char* > files_after_checkpoint_;
+ vector<PointerStringPair> field_lowercase_names_after_checkpoint_;
+ vector<PointerStringPair> field_camelcase_names_after_checkpoint_;
vector<DescriptorIntPair> field_numbers_after_checkpoint_;
vector<EnumIntPair > enum_numbers_after_checkpoint_;
@@ -404,6 +452,8 @@ void DescriptorPool::Tables::Checkpoint() {
symbols_after_checkpoint_.clear();
symbols_by_parent_after_checkpoint_.clear();
files_after_checkpoint_.clear();
+ field_lowercase_names_after_checkpoint_.clear();
+ field_camelcase_names_after_checkpoint_.clear();
field_numbers_after_checkpoint_.clear();
enum_numbers_after_checkpoint_.clear();
}
@@ -418,6 +468,12 @@ void DescriptorPool::Tables::Rollback() {
for (int i = 0; i < files_after_checkpoint_.size(); i++) {
files_by_name_.erase(files_after_checkpoint_[i]);
}
+ for (int i = 0; i < field_lowercase_names_after_checkpoint_.size(); i++) {
+ fields_by_lowercase_name_.erase(field_lowercase_names_after_checkpoint_[i]);
+ }
+ for (int i = 0; i < field_camelcase_names_after_checkpoint_.size(); i++) {
+ fields_by_camelcase_name_.erase(field_camelcase_names_after_checkpoint_[i]);
+ }
for (int i = 0; i < field_numbers_after_checkpoint_.size(); i++) {
fields_by_number_.erase(field_numbers_after_checkpoint_[i]);
}
@@ -428,6 +484,8 @@ void DescriptorPool::Tables::Rollback() {
symbols_after_checkpoint_.clear();
symbols_by_parent_after_checkpoint_.clear();
files_after_checkpoint_.clear();
+ field_lowercase_names_after_checkpoint_.clear();
+ field_camelcase_names_after_checkpoint_.clear();
field_numbers_after_checkpoint_.clear();
enum_numbers_after_checkpoint_.clear();
@@ -455,13 +513,6 @@ inline Symbol DescriptorPool::Tables::FindSymbol(const string& key) const {
}
}
-inline Symbol DescriptorPool::Tables::FindSymbolOfType(
- const string& key, const Symbol::Type type) const {
- Symbol result = FindSymbol(key);
- if (result.type != type) return kNullSymbol;
- return result;
-}
-
inline Symbol DescriptorPool::Tables::FindNestedSymbol(
const void* parent, const string& name) const {
const Symbol* result =
@@ -480,6 +531,27 @@ inline Symbol DescriptorPool::Tables::FindNestedSymbolOfType(
return result;
}
+Symbol DescriptorPool::Tables::FindByNameHelper(
+ const DescriptorPool* pool, const string& name) const {
+ MutexLockMaybe lock(pool->mutex_);
+ Symbol result = FindSymbol(name);
+
+ if (result.IsNull() && pool->underlay_ != NULL) {
+ // Symbol not found; check the underlay.
+ result =
+ pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name);
+ }
+
+ if (result.IsNull()) {
+ // Symbol still not found, so check fallback database.
+ if (pool->TryFindSymbolInFallbackDatabase(name)) {
+ result = FindSymbol(name);
+ }
+ }
+
+ return result;
+}
+
inline const FileDescriptor* DescriptorPool::Tables::FindFile(
const string& key) const {
return FindPtrOrNull(files_by_name_, key.c_str());
@@ -490,6 +562,18 @@ inline const FieldDescriptor* DescriptorPool::Tables::FindFieldByNumber(
return FindPtrOrNull(fields_by_number_, make_pair(parent, number));
}
+inline const FieldDescriptor* DescriptorPool::Tables::FindFieldByLowercaseName(
+ const void* parent, const string& lowercase_name) const {
+ return FindPtrOrNull(fields_by_lowercase_name_,
+ PointerStringPair(parent, lowercase_name.c_str()));
+}
+
+inline const FieldDescriptor* DescriptorPool::Tables::FindFieldByCamelcaseName(
+ const void* parent, const string& camelcase_name) const {
+ return FindPtrOrNull(fields_by_camelcase_name_,
+ PointerStringPair(parent, camelcase_name.c_str()));
+}
+
inline const EnumValueDescriptor* DescriptorPool::Tables::FindEnumValueByNumber(
const EnumDescriptor* parent, int number) const {
return FindPtrOrNull(enum_values_by_number_, make_pair(parent, number));
@@ -537,6 +621,30 @@ bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) {
}
}
+void DescriptorPool::Tables::AddFieldByStylizedNames(
+ const FieldDescriptor* field) {
+ const void* parent;
+ if (field->is_extension()) {
+ if (field->extension_scope() == NULL) {
+ parent = field->file();
+ } else {
+ parent = field->extension_scope();
+ }
+ } else {
+ parent = field->containing_type();
+ }
+
+ PointerStringPair lowercase_key(parent, field->lowercase_name().c_str());
+ if (InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field)) {
+ field_lowercase_names_after_checkpoint_.push_back(lowercase_key);
+ }
+
+ PointerStringPair camelcase_key(parent, field->camelcase_name().c_str());
+ if (InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field)) {
+ field_camelcase_names_after_checkpoint_.push_back(camelcase_key);
+ }
+}
+
bool DescriptorPool::Tables::AddFieldByNumber(const FieldDescriptor* field) {
DescriptorIntPair key(field->containing_type(), field->number());
if (InsertIfNotPresent(&fields_by_number_, key, field)) {
@@ -689,122 +797,55 @@ const FileDescriptor* DescriptorPool::FindFileContainingSymbol(
const Descriptor* DescriptorPool::FindMessageTypeByName(
const string& name) const {
- MutexLockMaybe lock(mutex_);
- Symbol result = tables_->FindSymbolOfType(name, Symbol::MESSAGE);
- if (!result.IsNull()) return result.descriptor;
- if (underlay_ != NULL) {
- const Descriptor* result = underlay_->FindMessageTypeByName(name);
- if (result != NULL) return result;
- }
- if (TryFindSymbolInFallbackDatabase(name)) {
- Symbol result = tables_->FindSymbolOfType(name, Symbol::MESSAGE);
- if (!result.IsNull()) return result.descriptor;
- }
- return NULL;
+ Symbol result = tables_->FindByNameHelper(this, name);
+ return (result.type == Symbol::MESSAGE) ? result.descriptor : NULL;
}
const FieldDescriptor* DescriptorPool::FindFieldByName(
const string& name) const {
- MutexLockMaybe lock(mutex_);
- Symbol result = tables_->FindSymbolOfType(name, Symbol::FIELD);
- if (!result.IsNull() && !result.field_descriptor->is_extension()) {
+ Symbol result = tables_->FindByNameHelper(this, name);
+ if (result.type == Symbol::FIELD &&
+ !result.field_descriptor->is_extension()) {
return result.field_descriptor;
+ } else {
+ return NULL;
}
- if (underlay_ != NULL) {
- const FieldDescriptor* result = underlay_->FindFieldByName(name);
- if (result != NULL) return result;
- }
- if (TryFindSymbolInFallbackDatabase(name)) {
- Symbol result = tables_->FindSymbolOfType(name, Symbol::FIELD);
- if (!result.IsNull() && !result.field_descriptor->is_extension()) {
- return result.field_descriptor;
- }
- }
- return NULL;
}
const FieldDescriptor* DescriptorPool::FindExtensionByName(
const string& name) const {
- MutexLockMaybe lock(mutex_);
- Symbol result = tables_->FindSymbolOfType(name, Symbol::FIELD);
- if (!result.IsNull() && result.field_descriptor->is_extension()) {
+ Symbol result = tables_->FindByNameHelper(this, name);
+ if (result.type == Symbol::FIELD &&
+ result.field_descriptor->is_extension()) {
return result.field_descriptor;
+ } else {
+ return NULL;
}
- if (underlay_ != NULL) {
- const FieldDescriptor* result = underlay_->FindExtensionByName(name);
- if (result != NULL) return result;
- }
- if (TryFindSymbolInFallbackDatabase(name)) {
- Symbol result = tables_->FindSymbolOfType(name, Symbol::FIELD);
- if (!result.IsNull() && result.field_descriptor->is_extension()) {
- return result.field_descriptor;
- }
- }
- return NULL;
}
const EnumDescriptor* DescriptorPool::FindEnumTypeByName(
const string& name) const {
- MutexLockMaybe lock(mutex_);
- Symbol result = tables_->FindSymbolOfType(name, Symbol::ENUM);
- if (!result.IsNull()) return result.enum_descriptor;
- if (underlay_ != NULL) {
- const EnumDescriptor* result = underlay_->FindEnumTypeByName(name);
- if (result != NULL) return result;
- }
- if (TryFindSymbolInFallbackDatabase(name)) {
- Symbol result = tables_->FindSymbolOfType(name, Symbol::ENUM);
- if (!result.IsNull()) return result.enum_descriptor;
- }
- return NULL;
+ Symbol result = tables_->FindByNameHelper(this, name);
+ return (result.type == Symbol::ENUM) ? result.enum_descriptor : NULL;
}
const EnumValueDescriptor* DescriptorPool::FindEnumValueByName(
const string& name) const {
- MutexLockMaybe lock(mutex_);
- Symbol result = tables_->FindSymbolOfType(name, Symbol::ENUM_VALUE);
- if (!result.IsNull()) return result.enum_value_descriptor;
- if (underlay_ != NULL) {
- const EnumValueDescriptor* result = underlay_->FindEnumValueByName(name);
- if (result != NULL) return result;
- }
- if (TryFindSymbolInFallbackDatabase(name)) {
- Symbol result = tables_->FindSymbolOfType(name, Symbol::ENUM_VALUE);
- if (!result.IsNull()) return result.enum_value_descriptor;
- }
- return NULL;
+ Symbol result = tables_->FindByNameHelper(this, name);
+ return (result.type == Symbol::ENUM_VALUE) ?
+ result.enum_value_descriptor : NULL;
}
const ServiceDescriptor* DescriptorPool::FindServiceByName(
const string& name) const {
- MutexLockMaybe lock(mutex_);
- Symbol result = tables_->FindSymbolOfType(name, Symbol::SERVICE);
- if (!result.IsNull()) return result.service_descriptor;
- if (underlay_ != NULL) {
- const ServiceDescriptor* result = underlay_->FindServiceByName(name);
- if (result != NULL) return result;
- }
- if (TryFindSymbolInFallbackDatabase(name)) {
- Symbol result = tables_->FindSymbolOfType(name, Symbol::SERVICE);
- if (!result.IsNull()) return result.service_descriptor;
- }
- return NULL;
+ Symbol result = tables_->FindByNameHelper(this, name);
+ return (result.type == Symbol::SERVICE) ? result.service_descriptor : NULL;
}
const MethodDescriptor* DescriptorPool::FindMethodByName(
const string& name) const {
- MutexLockMaybe lock(mutex_);
- Symbol result = tables_->FindSymbolOfType(name, Symbol::METHOD);
- if (!result.IsNull()) return result.method_descriptor;
- if (underlay_ != NULL) {
- const MethodDescriptor* result = underlay_->FindMethodByName(name);
- if (result != NULL) return result;
- }
- if (TryFindSymbolInFallbackDatabase(name)) {
- Symbol result = tables_->FindSymbolOfType(name, Symbol::METHOD);
- if (!result.IsNull()) return result.method_descriptor;
- }
- return NULL;
+ Symbol result = tables_->FindByNameHelper(this, name);
+ return (result.type == Symbol::METHOD) ? result.method_descriptor : NULL;
}
const FieldDescriptor* DescriptorPool::FindExtensionByNumber(
@@ -844,6 +885,30 @@ Descriptor::FindFieldByNumber(int key) const {
}
const FieldDescriptor*
+Descriptor::FindFieldByLowercaseName(const string& key) const {
+ MutexLockMaybe lock(file()->pool()->mutex_);
+ const FieldDescriptor* result =
+ file()->pool()->tables_->FindFieldByLowercaseName(this, key);
+ if (result == NULL || result->is_extension()) {
+ return NULL;
+ } else {
+ return result;
+ }
+}
+
+const FieldDescriptor*
+Descriptor::FindFieldByCamelcaseName(const string& key) const {
+ MutexLockMaybe lock(file()->pool()->mutex_);
+ const FieldDescriptor* result =
+ file()->pool()->tables_->FindFieldByCamelcaseName(this, key);
+ if (result == NULL || result->is_extension()) {
+ return NULL;
+ } else {
+ return result;
+ }
+}
+
+const FieldDescriptor*
Descriptor::FindFieldByName(const string& key) const {
MutexLockMaybe lock(file()->pool()->mutex_);
Symbol result =
@@ -867,6 +932,30 @@ Descriptor::FindExtensionByName(const string& key) const {
}
}
+const FieldDescriptor*
+Descriptor::FindExtensionByLowercaseName(const string& key) const {
+ MutexLockMaybe lock(file()->pool()->mutex_);
+ const FieldDescriptor* result =
+ file()->pool()->tables_->FindFieldByLowercaseName(this, key);
+ if (result == NULL || !result->is_extension()) {
+ return NULL;
+ } else {
+ return result;
+ }
+}
+
+const FieldDescriptor*
+Descriptor::FindExtensionByCamelcaseName(const string& key) const {
+ MutexLockMaybe lock(file()->pool()->mutex_);
+ const FieldDescriptor* result =
+ file()->pool()->tables_->FindFieldByCamelcaseName(this, key);
+ if (result == NULL || !result->is_extension()) {
+ return NULL;
+ } else {
+ return result;
+ }
+}
+
const Descriptor*
Descriptor::FindNestedTypeByName(const string& key) const {
MutexLockMaybe lock(file()->pool()->mutex_);
@@ -995,6 +1084,30 @@ FileDescriptor::FindExtensionByName(const string& key) const {
}
}
+const FieldDescriptor*
+FileDescriptor::FindExtensionByLowercaseName(const string& key) const {
+ MutexLockMaybe lock(pool()->mutex_);
+ const FieldDescriptor* result =
+ pool()->tables_->FindFieldByLowercaseName(this, key);
+ if (result == NULL || !result->is_extension()) {
+ return NULL;
+ } else {
+ return result;
+ }
+}
+
+const FieldDescriptor*
+FileDescriptor::FindExtensionByCamelcaseName(const string& key) const {
+ MutexLockMaybe lock(pool()->mutex_);
+ const FieldDescriptor* result =
+ pool()->tables_->FindFieldByCamelcaseName(this, key);
+ if (result == NULL || !result->is_extension()) {
+ return NULL;
+ } else {
+ return result;
+ }
+}
+
bool Descriptor::IsExtensionNumber(int number) const {
// Linear search should be fine because we don't expect a message to have
// more than a couple extension ranges.
@@ -2504,6 +2617,22 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
result->number_ = proto.number();
result->is_extension_ = is_extension;
+ // If .proto files follow the style guide then the name should already be
+ // lower-cased. If that's the case we can just reuse the string we already
+ // allocated rather than allocate a new one.
+ string lowercase_name(proto.name());
+ LowerString(&lowercase_name);
+ if (lowercase_name == proto.name()) {
+ result->lowercase_name_ = result->name_;
+ } else {
+ result->lowercase_name_ = tables_->AllocateString(lowercase_name);
+ }
+
+ // Don't bother with the above optimization for camel-case names since
+ // .proto files that follow the guide shouldn't be using names in this
+ // format, so the optimization wouldn't help much.
+ result->camelcase_name_ = tables_->AllocateString(ToCamelCase(proto.name()));
+
// Some compilers do not allow static_cast directly between two enum types,
// so we must cast to int first.
result->type_ = static_cast<FieldDescriptor::Type>(
@@ -3042,6 +3171,9 @@ void DescriptorBuilder::CrossLinkField(
conflicting_field->name()));
}
}
+
+ // Add the field to the lowercase-name and camelcase-name tables.
+ tables_->AddFieldByStylizedNames(field);
}
void DescriptorBuilder::CrossLinkEnum(
@@ -3136,6 +3268,20 @@ void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field,
ValidateMapKey(field, proto);
}
+ // Only repeated primitive fields may be packed.
+ if (field->options().packed()) {
+ if (!field->is_repeated() ||
+ field->type() == FieldDescriptor::TYPE_STRING ||
+ field->type() == FieldDescriptor::TYPE_GROUP ||
+ field->type() == FieldDescriptor::TYPE_MESSAGE ||
+ field->type() == FieldDescriptor::TYPE_BYTES) {
+ AddError(
+ field->full_name(), proto,
+ DescriptorPool::ErrorCollector::TYPE,
+ "[packed = true] can only be specified for repeated primitive fields.");
+ }
+ }
+
// Note: Default instance may not yet be initialized here, so we have to
// avoid reading from it.
if (field->containing_type_ != NULL &&
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h
index 6d496e99..918aafbc 100644
--- a/src/google/protobuf/descriptor.h
+++ b/src/google/protobuf/descriptor.h
@@ -156,6 +156,19 @@ class LIBPROTOBUF_EXPORT Descriptor {
// Looks up a field by name. Returns NULL if no such field exists.
const FieldDescriptor* FindFieldByName(const string& name) const;
+ // Looks up a field by lowercased name (as returned by lowercase_name()).
+ // This lookup may be ambiguous if multiple field names differ only by case,
+ // in which case the field returned is chosen arbitrarily from the matches.
+ const FieldDescriptor* FindFieldByLowercaseName(
+ const string& lowercase_name) const;
+
+ // Looks up a field by camel-case name (as returned by camelcase_name()).
+ // This lookup may be ambiguous if multiple field names differ in a way that
+ // leads them to have identical camel-case names, in which case the field
+ // returned is chosen arbitrarily from the matches.
+ const FieldDescriptor* FindFieldByCamelcaseName(
+ const string& camelcase_name) const;
+
// Nested type stuff -----------------------------------------------
// The number of nested types in this message type.
@@ -213,6 +226,14 @@ class LIBPROTOBUF_EXPORT Descriptor {
// defined within this message type's scope.
const FieldDescriptor* FindExtensionByName(const string& name) const;
+ // Similar to FindFieldByLowercaseName(), but finds extensions defined within
+ // this message type's scope.
+ const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const;
+
+ // Similar to FindFieldByCamelcaseName(), but finds extensions defined within
+ // this message type's scope.
+ const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const;
+
private:
typedef MessageOptions OptionsType;
@@ -336,6 +357,25 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
bool is_extension() const; // Is this an extension field?
int number() const; // Declared tag number.
+ // Same as name() except converted to lower-case. This (and especially the
+ // FindFieldByLowercaseName() method) can be useful when parsing formats
+ // which prefer to use lowercase naming style. (Although, technically
+ // field names should be lowercased anyway according to the protobuf style
+ // guide, so this only makes a difference when dealing with old .proto files
+ // which do not follow the guide.)
+ const string& lowercase_name() const;
+
+ // Same as name() except converted to camel-case. In this conversion, any
+ // time an underscore appears in the name, it is removed and the next
+ // letter is capitalized. Furthermore, the first letter of the name is
+ // lower-cased. Examples:
+ // FooBar -> fooBar
+ // foo_bar -> fooBar
+ // fooBar -> fooBar
+ // This (and especially the FindFieldByCamelcaseName() method) can be useful
+ // when parsing formats which prefer to use camel-case naming style.
+ const string& camelcase_name() const;
+
Type type() const; // Declared type of this field.
CppType cpp_type() const; // C++ type of this field.
Label label() const; // optional/required/repeated
@@ -431,6 +471,8 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
const string* name_;
const string* full_name_;
+ const string* lowercase_name_;
+ const string* camelcase_name_;
const FileDescriptor* file_;
int number_;
Type type_;
@@ -773,6 +815,12 @@ class LIBPROTOBUF_EXPORT FileDescriptor {
const ServiceDescriptor* FindServiceByName(const string& name) const;
// Find a top-level extension definition by name. Returns NULL if not found.
const FieldDescriptor* FindExtensionByName(const string& name) const;
+ // Similar to FindExtensionByName(), but searches by lowercased-name. See
+ // Descriptor::FindFieldByLowercaseName().
+ const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const;
+ // Similar to FindExtensionByName(), but searches by camelcased-name. See
+ // Descriptor::FindFieldByCamelcaseName().
+ const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const;
// See Descriptor::CopyTo().
void CopyTo(FileDescriptorProto* proto) const;
@@ -1084,6 +1132,8 @@ PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions);
PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, full_name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, lowercase_name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, camelcase_name)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int)
PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool)
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index ceb99bf1..0df3f3bd 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -301,8 +301,9 @@ void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto_AssignGlobalDescr
MessageOptions_descriptor_, MessageOptions::default_instance_);
FieldOptions_descriptor_ = file->message_type(10);
FieldOptions::default_instance_ = new FieldOptions();
- static const int FieldOptions_offsets_[3] = {
+ static const int FieldOptions_offsets_[4] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, packed_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, experimental_map_key_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, uninterpreted_option_),
};
@@ -519,30 +520,30 @@ void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto() {
"\n\016MessageOptions\022&\n\027message_set_wire_for"
"mat\030\001 \001(\010:\005false\022C\n\024uninterpreted_option"
"\030\347\007 \003(\0132$.google.protobuf.UninterpretedO"
- "ption*\t\010\350\007\020\200\200\200\200\002\"\325\001\n\014FieldOptions\0222\n\005cty"
+ "ption*\t\010\350\007\020\200\200\200\200\002\"\345\001\n\014FieldOptions\0222\n\005cty"
"pe\030\001 \001(\0162#.google.protobuf.FieldOptions."
- "CType\022\034\n\024experimental_map_key\030\t \001(\t\022C\n\024u"
- "ninterpreted_option\030\347\007 \003(\0132$.google.prot"
- "obuf.UninterpretedOption\"#\n\005CType\022\010\n\004COR"
- "D\020\001\022\020\n\014STRING_PIECE\020\002*\t\010\350\007\020\200\200\200\200\002\"]\n\013Enum"
- "Options\022C\n\024uninterpreted_option\030\347\007 \003(\0132$"
- ".google.protobuf.UninterpretedOption*\t\010\350"
- "\007\020\200\200\200\200\002\"b\n\020EnumValueOptions\022C\n\024uninterpr"
- "eted_option\030\347\007 \003(\0132$.google.protobuf.Uni"
- "nterpretedOption*\t\010\350\007\020\200\200\200\200\002\"`\n\016ServiceOp"
- "tions\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g"
- "oogle.protobuf.UninterpretedOption*\t\010\350\007\020"
- "\200\200\200\200\002\"_\n\rMethodOptions\022C\n\024uninterpreted_"
- "option\030\347\007 \003(\0132$.google.protobuf.Uninterp"
- "retedOption*\t\010\350\007\020\200\200\200\200\002\"\205\002\n\023Uninterpreted"
- "Option\022;\n\004name\030\002 \003(\0132-.google.protobuf.U"
- "ninterpretedOption.NamePart\022\030\n\020identifie"
- "r_value\030\003 \001(\t\022\032\n\022positive_int_value\030\004 \001("
- "\004\022\032\n\022negative_int_value\030\005 \001(\003\022\024\n\014double_"
- "value\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014\0323\n\010Nam"
- "ePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_extension"
- "\030\002 \002(\010B)\n\023com.google.protobufB\020Descripto"
- "rProtosH\001", 3449,
+ "CType\022\016\n\006packed\030\002 \001(\010\022\034\n\024experimental_ma"
+ "p_key\030\t \001(\t\022C\n\024uninterpreted_option\030\347\007 \003"
+ "(\0132$.google.protobuf.UninterpretedOption"
+ "\"#\n\005CType\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020\002*\t\010"
+ "\350\007\020\200\200\200\200\002\"]\n\013EnumOptions\022C\n\024uninterpreted"
+ "_option\030\347\007 \003(\0132$.google.protobuf.Uninter"
+ "pretedOption*\t\010\350\007\020\200\200\200\200\002\"b\n\020EnumValueOpti"
+ "ons\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goo"
+ "gle.protobuf.UninterpretedOption*\t\010\350\007\020\200\200"
+ "\200\200\002\"`\n\016ServiceOptions\022C\n\024uninterpreted_o"
+ "ption\030\347\007 \003(\0132$.google.protobuf.Uninterpr"
+ "etedOption*\t\010\350\007\020\200\200\200\200\002\"_\n\rMethodOptions\022C"
+ "\n\024uninterpreted_option\030\347\007 \003(\0132$.google.p"
+ "rotobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\205"
+ "\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\0132-.g"
+ "oogle.protobuf.UninterpretedOption.NameP"
+ "art\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022positiv"
+ "e_int_value\030\004 \001(\004\022\032\n\022negative_int_value\030"
+ "\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string_va"
+ "lue\030\007 \001(\014\0323\n\010NamePart\022\021\n\tname_part\030\001 \002(\t"
+ "\022\024\n\014is_extension\030\002 \002(\010B)\n\023com.google.pro"
+ "tobufB\020DescriptorProtosH\001", 3465,
&protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto_AssignGlobalDescriptors);
}
@@ -639,7 +640,7 @@ bool FileDescriptorSet::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
// repeated .google.protobuf.FileDescriptorProto file = 1;
- for (int i = 0; i < file_.size(); i++) {
+ for (int i = 0; i < this->file_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(1, this->file(i), output));
}
@@ -655,8 +656,8 @@ int FileDescriptorSet::ByteSize() const {
int total_size = 0;
// repeated .google.protobuf.FileDescriptorProto file = 1;
- total_size += 1 * file_size();
- for (int i = 0; i < file_size(); i++) {
+ total_size += 1 * this->file_size();
+ for (int i = 0; i < this->file_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->file(i));
@@ -954,27 +955,27 @@ bool FileDescriptorProto::SerializeWithCachedSizes(
}
// repeated string dependency = 3;
- for (int i = 0; i < dependency_.size(); i++) {
+ for (int i = 0; i < this->dependency_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteString(3, this->dependency(i), output));
}
// repeated .google.protobuf.DescriptorProto message_type = 4;
- for (int i = 0; i < message_type_.size(); i++) {
+ for (int i = 0; i < this->message_type_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(4, this->message_type(i), output));
}
// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
- for (int i = 0; i < enum_type_.size(); i++) {
+ for (int i = 0; i < this->enum_type_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(5, this->enum_type(i), output));
}
// repeated .google.protobuf.ServiceDescriptorProto service = 6;
- for (int i = 0; i < service_.size(); i++) {
+ for (int i = 0; i < this->service_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(6, this->service(i), output));
}
// repeated .google.protobuf.FieldDescriptorProto extension = 7;
- for (int i = 0; i < extension_.size(); i++) {
+ for (int i = 0; i < this->extension_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(7, this->extension(i), output));
}
@@ -1016,39 +1017,39 @@ int FileDescriptorProto::ByteSize() const {
}
// repeated string dependency = 3;
- total_size += 1 * dependency_size();
- for (int i = 0; i < dependency_size(); i++) {
+ total_size += 1 * this->dependency_size();
+ for (int i = 0; i < this->dependency_size(); i++) {
total_size += ::google::protobuf::internal::WireFormat::StringSize(
this->dependency(i));
}
// repeated .google.protobuf.DescriptorProto message_type = 4;
- total_size += 1 * message_type_size();
- for (int i = 0; i < message_type_size(); i++) {
+ total_size += 1 * this->message_type_size();
+ for (int i = 0; i < this->message_type_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->message_type(i));
}
// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
- total_size += 1 * enum_type_size();
- for (int i = 0; i < enum_type_size(); i++) {
+ total_size += 1 * this->enum_type_size();
+ for (int i = 0; i < this->enum_type_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->enum_type(i));
}
// repeated .google.protobuf.ServiceDescriptorProto service = 6;
- total_size += 1 * service_size();
- for (int i = 0; i < service_size(); i++) {
+ total_size += 1 * this->service_size();
+ for (int i = 0; i < this->service_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->service(i));
}
// repeated .google.protobuf.FieldDescriptorProto extension = 7;
- total_size += 1 * extension_size();
- for (int i = 0; i < extension_size(); i++) {
+ total_size += 1 * this->extension_size();
+ for (int i = 0; i < this->extension_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->extension(i));
@@ -1564,27 +1565,27 @@ bool DescriptorProto::SerializeWithCachedSizes(
}
// repeated .google.protobuf.FieldDescriptorProto field = 2;
- for (int i = 0; i < field_.size(); i++) {
+ for (int i = 0; i < this->field_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->field(i), output));
}
// repeated .google.protobuf.DescriptorProto nested_type = 3;
- for (int i = 0; i < nested_type_.size(); i++) {
+ for (int i = 0; i < this->nested_type_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(3, this->nested_type(i), output));
}
// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
- for (int i = 0; i < enum_type_.size(); i++) {
+ for (int i = 0; i < this->enum_type_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(4, this->enum_type(i), output));
}
// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
- for (int i = 0; i < extension_range_.size(); i++) {
+ for (int i = 0; i < this->extension_range_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(5, this->extension_range(i), output));
}
// repeated .google.protobuf.FieldDescriptorProto extension = 6;
- for (int i = 0; i < extension_.size(); i++) {
+ for (int i = 0; i < this->extension_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(6, this->extension(i), output));
}
@@ -1620,40 +1621,40 @@ int DescriptorProto::ByteSize() const {
}
// repeated .google.protobuf.FieldDescriptorProto field = 2;
- total_size += 1 * field_size();
- for (int i = 0; i < field_size(); i++) {
+ total_size += 1 * this->field_size();
+ for (int i = 0; i < this->field_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->field(i));
}
// repeated .google.protobuf.FieldDescriptorProto extension = 6;
- total_size += 1 * extension_size();
- for (int i = 0; i < extension_size(); i++) {
+ total_size += 1 * this->extension_size();
+ for (int i = 0; i < this->extension_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->extension(i));
}
// repeated .google.protobuf.DescriptorProto nested_type = 3;
- total_size += 1 * nested_type_size();
- for (int i = 0; i < nested_type_size(); i++) {
+ total_size += 1 * this->nested_type_size();
+ for (int i = 0; i < this->nested_type_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->nested_type(i));
}
// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
- total_size += 1 * enum_type_size();
- for (int i = 0; i < enum_type_size(); i++) {
+ total_size += 1 * this->enum_type_size();
+ for (int i = 0; i < this->enum_type_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->enum_type(i));
}
// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
- total_size += 1 * extension_range_size();
- for (int i = 0; i < extension_range_size(); i++) {
+ total_size += 1 * this->extension_range_size();
+ for (int i = 0; i < this->extension_range_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->extension_range(i));
@@ -2407,7 +2408,7 @@ bool EnumDescriptorProto::SerializeWithCachedSizes(
}
// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
- for (int i = 0; i < value_.size(); i++) {
+ for (int i = 0; i < this->value_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->value(i), output));
}
@@ -2443,8 +2444,8 @@ int EnumDescriptorProto::ByteSize() const {
}
// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
- total_size += 1 * value_size();
- for (int i = 0; i < value_size(); i++) {
+ total_size += 1 * this->value_size();
+ for (int i = 0; i < this->value_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->value(i));
@@ -2919,7 +2920,7 @@ bool ServiceDescriptorProto::SerializeWithCachedSizes(
}
// repeated .google.protobuf.MethodDescriptorProto method = 2;
- for (int i = 0; i < method_.size(); i++) {
+ for (int i = 0; i < this->method_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->method(i), output));
}
@@ -2955,8 +2956,8 @@ int ServiceDescriptorProto::ByteSize() const {
}
// repeated .google.protobuf.MethodDescriptorProto method = 2;
- total_size += 1 * method_size();
- for (int i = 0; i < method_size(); i++) {
+ total_size += 1 * this->method_size();
+ for (int i = 0; i < this->method_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->method(i));
@@ -3561,7 +3562,7 @@ bool FileOptions::SerializeWithCachedSizes(
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- for (int i = 0; i < uninterpreted_option_.size(); i++) {
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output));
}
@@ -3606,8 +3607,8 @@ int FileOptions::ByteSize() const {
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- total_size += 2 * uninterpreted_option_size();
- for (int i = 0; i < uninterpreted_option_size(); i++) {
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->uninterpreted_option(i));
@@ -3821,7 +3822,7 @@ bool MessageOptions::SerializeWithCachedSizes(
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- for (int i = 0; i < uninterpreted_option_.size(); i++) {
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output));
}
@@ -3848,8 +3849,8 @@ int MessageOptions::ByteSize() const {
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- total_size += 2 * uninterpreted_option_size();
- for (int i = 0; i < uninterpreted_option_size(); i++) {
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->uninterpreted_option(i));
@@ -3954,6 +3955,7 @@ const FieldOptions_CType FieldOptions::CType_MIN;
const FieldOptions_CType FieldOptions::CType_MAX;
#endif // _MSC_VER
+
const ::std::string FieldOptions::_default_experimental_map_key_;
FieldOptions::FieldOptions()
@@ -3963,6 +3965,7 @@ FieldOptions::FieldOptions()
::google::protobuf::MessageFactory::generated_factory()),
_cached_size_(0),
ctype_(1),
+ packed_(false),
experimental_map_key_(const_cast< ::std::string*>(&_default_experimental_map_key_)) {
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -3976,6 +3979,7 @@ FieldOptions::FieldOptions(const FieldOptions& from)
::google::protobuf::MessageFactory::generated_factory()),
_cached_size_(0),
ctype_(1),
+ packed_(false),
experimental_map_key_(const_cast< ::std::string*>(&_default_experimental_map_key_)) {
::memset(_has_bits_, 0, sizeof(_has_bits_));
MergeFrom(from);
@@ -4009,7 +4013,8 @@ void FieldOptions::Clear() {
_extensions_.Clear();
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
ctype_ = 1;
- if (_has_bit(1)) {
+ packed_ = false;
+ if (_has_bit(2)) {
if (experimental_map_key_ != &_default_experimental_map_key_) {
experimental_map_key_->clear();
}
@@ -4039,6 +4044,20 @@ bool FieldOptions::MergePartialFromCodedStream(
} else {
mutable_unknown_fields()->AddField(1)->add_varint(value);
}
+ if (input->ExpectTag(16)) goto parse_packed;
+ break;
+ }
+
+ // optional bool packed = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+ ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) {
+ goto handle_uninterpreted;
+ }
+ parse_packed:
+ DO_(::google::protobuf::internal::WireFormat::ReadBool(
+ input, &packed_));
+ _set_bit(1);
if (input->ExpectTag(74)) goto parse_experimental_map_key;
break;
}
@@ -4097,13 +4116,18 @@ bool FieldOptions::SerializeWithCachedSizes(
DO_(::google::protobuf::internal::WireFormat::WriteEnum(1, this->ctype(), output));
}
- // optional string experimental_map_key = 9;
+ // optional bool packed = 2;
if (_has_bit(1)) {
+ DO_(::google::protobuf::internal::WireFormat::WriteBool(2, this->packed(), output));
+ }
+
+ // optional string experimental_map_key = 9;
+ if (_has_bit(2)) {
DO_(::google::protobuf::internal::WireFormat::WriteString(9, this->experimental_map_key(), output));
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- for (int i = 0; i < uninterpreted_option_.size(); i++) {
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output));
}
@@ -4129,6 +4153,11 @@ int FieldOptions::ByteSize() const {
::google::protobuf::internal::WireFormat::EnumSize(this->ctype());
}
+ // optional bool packed = 2;
+ if (has_packed()) {
+ total_size += 1 + 1;
+ }
+
// optional string experimental_map_key = 9;
if (has_experimental_map_key()) {
total_size += 1 +
@@ -4137,8 +4166,8 @@ int FieldOptions::ByteSize() const {
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- total_size += 2 * uninterpreted_option_size();
- for (int i = 0; i < uninterpreted_option_size(); i++) {
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->uninterpreted_option(i));
@@ -4175,6 +4204,9 @@ void FieldOptions::MergeFrom(const FieldOptions& from) {
set_ctype(from.ctype());
}
if (from._has_bit(1)) {
+ set_packed(from.packed());
+ }
+ if (from._has_bit(2)) {
set_experimental_map_key(from.experimental_map_key());
}
}
@@ -4197,6 +4229,7 @@ void FieldOptions::CopyFrom(const FieldOptions& from) {
void FieldOptions::Swap(FieldOptions* other) {
if (other != this) {
std::swap(ctype_, other->ctype_);
+ std::swap(packed_, other->packed_);
std::swap(experimental_map_key_, other->experimental_map_key_);
uninterpreted_option_.Swap(&other->uninterpreted_option_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
@@ -4320,7 +4353,7 @@ bool EnumOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- for (int i = 0; i < uninterpreted_option_.size(); i++) {
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output));
}
@@ -4340,8 +4373,8 @@ int EnumOptions::ByteSize() const {
int total_size = 0;
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- total_size += 2 * uninterpreted_option_size();
- for (int i = 0; i < uninterpreted_option_size(); i++) {
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->uninterpreted_option(i));
@@ -4513,7 +4546,7 @@ bool EnumValueOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- for (int i = 0; i < uninterpreted_option_.size(); i++) {
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output));
}
@@ -4533,8 +4566,8 @@ int EnumValueOptions::ByteSize() const {
int total_size = 0;
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- total_size += 2 * uninterpreted_option_size();
- for (int i = 0; i < uninterpreted_option_size(); i++) {
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->uninterpreted_option(i));
@@ -4706,7 +4739,7 @@ bool ServiceOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- for (int i = 0; i < uninterpreted_option_.size(); i++) {
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output));
}
@@ -4726,8 +4759,8 @@ int ServiceOptions::ByteSize() const {
int total_size = 0;
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- total_size += 2 * uninterpreted_option_size();
- for (int i = 0; i < uninterpreted_option_size(); i++) {
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->uninterpreted_option(i));
@@ -4899,7 +4932,7 @@ bool MethodOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- for (int i = 0; i < uninterpreted_option_.size(); i++) {
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(999, this->uninterpreted_option(i), output));
}
@@ -4919,8 +4952,8 @@ int MethodOptions::ByteSize() const {
int total_size = 0;
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
- total_size += 2 * uninterpreted_option_size();
- for (int i = 0; i < uninterpreted_option_size(); i++) {
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->uninterpreted_option(i));
@@ -5398,7 +5431,7 @@ bool UninterpretedOption::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
- for (int i = 0; i < name_.size(); i++) {
+ for (int i = 0; i < this->name_size(); i++) {
DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->name(i), output));
}
@@ -5472,8 +5505,8 @@ int UninterpretedOption::ByteSize() const {
}
// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
- total_size += 1 * name_size();
- for (int i = 0; i < name_size(); i++) {
+ total_size += 1 * this->name_size();
+ for (int i = 0; i < this->name_size(); i++) {
total_size +=
::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
this->name(i));
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 8fa51dd6..e5077aae 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -12,7 +12,7 @@
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
-#if 2000003 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#if 2000004 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
@@ -1645,6 +1645,12 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
inline ::google::protobuf::FieldOptions_CType ctype() const;
inline void set_ctype(::google::protobuf::FieldOptions_CType value);
+ // optional bool packed = 2;
+ inline bool has_packed() const;
+ inline void clear_packed();
+ inline bool packed() const;
+ inline void set_packed(bool value);
+
// optional string experimental_map_key = 9;
inline bool has_experimental_map_key() const;
inline void clear_experimental_map_key();
@@ -1749,12 +1755,13 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
mutable int _cached_size_;
int ctype_;
+ bool packed_;
::std::string* experimental_map_key_;
static const ::std::string _default_experimental_map_key_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto_AssignGlobalDescriptors(
const ::google::protobuf::FileDescriptor* file);
- ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
+ ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
inline bool _has_bit(int index) const {
@@ -3908,35 +3915,51 @@ inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value
ctype_ = value;
}
+// optional bool packed = 2;
+inline bool FieldOptions::has_packed() const {
+ return _has_bit(1);
+}
+inline void FieldOptions::clear_packed() {
+ packed_ = false;
+ _clear_bit(1);
+}
+inline bool FieldOptions::packed() const {
+ return packed_;
+}
+inline void FieldOptions::set_packed(bool value) {
+ _set_bit(1);
+ packed_ = value;
+}
+
// optional string experimental_map_key = 9;
inline bool FieldOptions::has_experimental_map_key() const {
- return _has_bit(1);
+ return _has_bit(2);
}
inline void FieldOptions::clear_experimental_map_key() {
if (experimental_map_key_ != &_default_experimental_map_key_) {
experimental_map_key_->clear();
}
- _clear_bit(1);
+ _clear_bit(2);
}
inline const ::std::string& FieldOptions::experimental_map_key() const {
return *experimental_map_key_;
}
inline void FieldOptions::set_experimental_map_key(const ::std::string& value) {
- _set_bit(1);
+ _set_bit(2);
if (experimental_map_key_ == &_default_experimental_map_key_) {
experimental_map_key_ = new ::std::string;
}
experimental_map_key_->assign(value);
}
inline void FieldOptions::set_experimental_map_key(const char* value) {
- _set_bit(1);
+ _set_bit(2);
if (experimental_map_key_ == &_default_experimental_map_key_) {
experimental_map_key_ = new ::std::string;
}
experimental_map_key_->assign(value);
}
inline ::std::string* FieldOptions::mutable_experimental_map_key() {
- _set_bit(1);
+ _set_bit(2);
if (experimental_map_key_ == &_default_experimental_map_key_) {
experimental_map_key_ = new ::std::string;
}
diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto
index 9cdd61c5..e0e6f7f2 100644
--- a/src/google/protobuf/descriptor.proto
+++ b/src/google/protobuf/descriptor.proto
@@ -253,6 +253,7 @@ message FileOptions {
optional OptimizeMode optimize_for = 9 [default=CODE_SIZE];
+
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@@ -299,6 +300,11 @@ message FieldOptions {
STRING_PIECE = 2;
}
+ // The packed option can be enabled for repeated primitive fields to enable
+ // a more efficient representation on the wire. Rather than repeatedly
+ // writing the tag and type for each element, the entire array is encoded as
+ // a single length-delimited blob.
+ optional bool packed = 2;
// EXPERIMENTAL. DO NOT USE.
// For "map" fields, the name of the field in the enclosed type that
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index f4e60b3a..5ffaea77 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -53,7 +53,8 @@
namespace google {
namespace protobuf {
-namespace GOOGLE_ANONYMOUS_NAMESPACE{
+// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
+namespace descriptor_unittest {
// Some helpers to make assembling descriptors faster.
DescriptorProto* AddMessage(FileDescriptorProto* file, const string& name) {
@@ -631,6 +632,188 @@ TEST_F(DescriptorTest, FieldEnumType) {
// ===================================================================
+class StylizedFieldNamesTest : public testing::Test {
+ protected:
+ void SetUp() {
+ FileDescriptorProto file;
+ file.set_name("foo.proto");
+
+ AddExtensionRange(AddMessage(&file, "ExtendableMessage"), 1, 1000);
+
+ DescriptorProto* message = AddMessage(&file, "TestMessage");
+ AddField(message, "foo_foo", 1,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message, "FooBar", 2,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message, "fooBaz", 3,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message, "fooFoo", 4, // Camel-case conflict with foo_foo.
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message, "foobar", 5, // Lower-case conflict with FooBar.
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ AddNestedExtension(message, "ExtendableMessage", "bar_foo", 1,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddNestedExtension(message, "ExtendableMessage", "BarBar", 2,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddNestedExtension(message, "ExtendableMessage", "BarBaz", 3,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddNestedExtension(message, "ExtendableMessage", "barFoo", 4, // Conflict
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddNestedExtension(message, "ExtendableMessage", "barbar", 5, // Conflict
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ AddExtension(&file, "ExtendableMessage", "baz_foo", 11,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&file, "ExtendableMessage", "BazBar", 12,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&file, "ExtendableMessage", "BazBaz", 13,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&file, "ExtendableMessage", "bazFoo", 14, // Conflict
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&file, "ExtendableMessage", "bazbar", 15, // Conflict
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ file_ = pool_.BuildFile(file);
+ ASSERT_TRUE(file_ != NULL);
+ ASSERT_EQ(2, file_->message_type_count());
+ message_ = file_->message_type(1);
+ ASSERT_EQ("TestMessage", message_->name());
+ ASSERT_EQ(5, message_->field_count());
+ ASSERT_EQ(5, message_->extension_count());
+ ASSERT_EQ(5, file_->extension_count());
+ }
+
+ DescriptorPool pool_;
+ const FileDescriptor* file_;
+ const Descriptor* message_;
+};
+
+TEST_F(StylizedFieldNamesTest, LowercaseName) {
+ EXPECT_EQ("foo_foo", message_->field(0)->lowercase_name());
+ EXPECT_EQ("foobar" , message_->field(1)->lowercase_name());
+ EXPECT_EQ("foobaz" , message_->field(2)->lowercase_name());
+ EXPECT_EQ("foofoo" , message_->field(3)->lowercase_name());
+ EXPECT_EQ("foobar" , message_->field(4)->lowercase_name());
+
+ EXPECT_EQ("bar_foo", message_->extension(0)->lowercase_name());
+ EXPECT_EQ("barbar" , message_->extension(1)->lowercase_name());
+ EXPECT_EQ("barbaz" , message_->extension(2)->lowercase_name());
+ EXPECT_EQ("barfoo" , message_->extension(3)->lowercase_name());
+ EXPECT_EQ("barbar" , message_->extension(4)->lowercase_name());
+
+ EXPECT_EQ("baz_foo", file_->extension(0)->lowercase_name());
+ EXPECT_EQ("bazbar" , file_->extension(1)->lowercase_name());
+ EXPECT_EQ("bazbaz" , file_->extension(2)->lowercase_name());
+ EXPECT_EQ("bazfoo" , file_->extension(3)->lowercase_name());
+ EXPECT_EQ("bazbar" , file_->extension(4)->lowercase_name());
+}
+
+TEST_F(StylizedFieldNamesTest, CamelcaseName) {
+ EXPECT_EQ("fooFoo", message_->field(0)->camelcase_name());
+ EXPECT_EQ("fooBar", message_->field(1)->camelcase_name());
+ EXPECT_EQ("fooBaz", message_->field(2)->camelcase_name());
+ EXPECT_EQ("fooFoo", message_->field(3)->camelcase_name());
+ EXPECT_EQ("foobar", message_->field(4)->camelcase_name());
+
+ EXPECT_EQ("barFoo", message_->extension(0)->camelcase_name());
+ EXPECT_EQ("barBar", message_->extension(1)->camelcase_name());
+ EXPECT_EQ("barBaz", message_->extension(2)->camelcase_name());
+ EXPECT_EQ("barFoo", message_->extension(3)->camelcase_name());
+ EXPECT_EQ("barbar", message_->extension(4)->camelcase_name());
+
+ EXPECT_EQ("bazFoo", file_->extension(0)->camelcase_name());
+ EXPECT_EQ("bazBar", file_->extension(1)->camelcase_name());
+ EXPECT_EQ("bazBaz", file_->extension(2)->camelcase_name());
+ EXPECT_EQ("bazFoo", file_->extension(3)->camelcase_name());
+ EXPECT_EQ("bazbar", file_->extension(4)->camelcase_name());
+}
+
+TEST_F(StylizedFieldNamesTest, FindByLowercaseName) {
+ EXPECT_EQ(message_->field(0),
+ message_->FindFieldByLowercaseName("foo_foo"));
+ EXPECT_EQ(message_->field(1),
+ message_->FindFieldByLowercaseName("foobar"));
+ EXPECT_EQ(message_->field(2),
+ message_->FindFieldByLowercaseName("foobaz"));
+ EXPECT_TRUE(message_->FindFieldByLowercaseName("FooBar") == NULL);
+ EXPECT_TRUE(message_->FindFieldByLowercaseName("fooBaz") == NULL);
+ EXPECT_TRUE(message_->FindFieldByLowercaseName("bar_foo") == NULL);
+ EXPECT_TRUE(message_->FindFieldByLowercaseName("nosuchfield") == NULL);
+
+ EXPECT_EQ(message_->extension(0),
+ message_->FindExtensionByLowercaseName("bar_foo"));
+ EXPECT_EQ(message_->extension(1),
+ message_->FindExtensionByLowercaseName("barbar"));
+ EXPECT_EQ(message_->extension(2),
+ message_->FindExtensionByLowercaseName("barbaz"));
+ EXPECT_TRUE(message_->FindExtensionByLowercaseName("BarBar") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByLowercaseName("barBaz") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByLowercaseName("foo_foo") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByLowercaseName("nosuchfield") == NULL);
+
+ EXPECT_EQ(file_->extension(0),
+ file_->FindExtensionByLowercaseName("baz_foo"));
+ EXPECT_EQ(file_->extension(1),
+ file_->FindExtensionByLowercaseName("bazbar"));
+ EXPECT_EQ(file_->extension(2),
+ file_->FindExtensionByLowercaseName("bazbaz"));
+ EXPECT_TRUE(file_->FindExtensionByLowercaseName("BazBar") == NULL);
+ EXPECT_TRUE(file_->FindExtensionByLowercaseName("bazBaz") == NULL);
+ EXPECT_TRUE(file_->FindExtensionByLowercaseName("nosuchfield") == NULL);
+}
+
+TEST_F(StylizedFieldNamesTest, FindByCamelcaseName) {
+ EXPECT_EQ(message_->field(0),
+ message_->FindFieldByCamelcaseName("fooFoo"));
+ EXPECT_EQ(message_->field(1),
+ message_->FindFieldByCamelcaseName("fooBar"));
+ EXPECT_EQ(message_->field(2),
+ message_->FindFieldByCamelcaseName("fooBaz"));
+ EXPECT_TRUE(message_->FindFieldByCamelcaseName("foo_foo") == NULL);
+ EXPECT_TRUE(message_->FindFieldByCamelcaseName("FooBar") == NULL);
+ EXPECT_TRUE(message_->FindFieldByCamelcaseName("barFoo") == NULL);
+ EXPECT_TRUE(message_->FindFieldByCamelcaseName("nosuchfield") == NULL);
+
+ EXPECT_EQ(message_->extension(0),
+ message_->FindExtensionByCamelcaseName("barFoo"));
+ EXPECT_EQ(message_->extension(1),
+ message_->FindExtensionByCamelcaseName("barBar"));
+ EXPECT_EQ(message_->extension(2),
+ message_->FindExtensionByCamelcaseName("barBaz"));
+ EXPECT_TRUE(message_->FindExtensionByCamelcaseName("bar_foo") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByCamelcaseName("BarBar") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByCamelcaseName("fooFoo") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
+
+ EXPECT_EQ(file_->extension(0),
+ file_->FindExtensionByCamelcaseName("bazFoo"));
+ EXPECT_EQ(file_->extension(1),
+ file_->FindExtensionByCamelcaseName("bazBar"));
+ EXPECT_EQ(file_->extension(2),
+ file_->FindExtensionByCamelcaseName("bazBaz"));
+ EXPECT_TRUE(file_->FindExtensionByCamelcaseName("baz_foo") == NULL);
+ EXPECT_TRUE(file_->FindExtensionByCamelcaseName("BazBar") == NULL);
+ EXPECT_TRUE(file_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
+}
+
+// ===================================================================
+
// Test enum descriptors.
class EnumDescriptorTest : public testing::Test {
protected:
@@ -2457,6 +2640,36 @@ TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
"foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n");
}
+TEST_F(ValidationErrorTest, IllegalPackedField) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {\n"
+ " name: \"Foo\""
+ " field { name:\"packed_string\" number:1 label:LABEL_REPEATED "
+ " type:TYPE_STRING "
+ " options { uninterpreted_option {"
+ " name { name_part: \"packed\" is_extension: false }"
+ " identifier_value: \"true\" }}}\n"
+ " field { name:\"packed_message\" number:3 label:LABEL_REPEATED "
+ " type_name: \"Foo\""
+ " options { uninterpreted_option {"
+ " name { name_part: \"packed\" is_extension: false }"
+ " identifier_value: \"true\" }}}\n"
+ " field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL "
+ " type:TYPE_INT32 "
+ " options { uninterpreted_option {"
+ " name { name_part: \"packed\" is_extension: false }"
+ " identifier_value: \"true\" }}}\n"
+ "}",
+
+ "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be "
+ "specified for repeated primitive fields.\n"
+ "foo.proto: Foo.packed_message: TYPE: [packed = true] can only be "
+ "specified for repeated primitive fields.\n"
+ "foo.proto: Foo.optional_int32: TYPE: [packed = true] can only be "
+ "specified for repeated primitive fields.\n"
+ );
+}
TEST_F(ValidationErrorTest, OptionWrongType) {
BuildFileWithErrors(
@@ -3255,6 +3468,34 @@ TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) {
EXPECT_EQ("", error_collector.text_);
}
-} // anonymous namespace
+TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
+ // If a lookup finds a symbol of the wrong type (e.g. we pass a type name
+ // to FindFieldByName()), we should fail fast, without checking the fallback
+ // database.
+ CallCountingDatabase call_counter(&database_);
+ DescriptorPool pool(&call_counter);
+
+ const FileDescriptor* file = pool.FindFileByName("foo.proto");
+ ASSERT_TRUE(file != NULL);
+ const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+ ASSERT_TRUE(foo != NULL);
+ const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
+ ASSERT_TRUE(test_enum != NULL);
+
+ EXPECT_NE(0, call_counter.call_count_);
+ call_counter.Clear();
+
+ EXPECT_TRUE(pool.FindMessageTypeByName("TestEnum") == NULL);
+ EXPECT_TRUE(pool.FindFieldByName("Foo") == NULL);
+ EXPECT_TRUE(pool.FindExtensionByName("Foo") == NULL);
+ EXPECT_TRUE(pool.FindEnumTypeByName("Foo") == NULL);
+ EXPECT_TRUE(pool.FindEnumValueByName("Foo") == NULL);
+ EXPECT_TRUE(pool.FindServiceByName("Foo") == NULL);
+ EXPECT_TRUE(pool.FindMethodByName("Foo") == NULL);
+
+ EXPECT_EQ(0, call_counter.call_count_);
+}
+
+} // namespace descriptor_unittest
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/dynamic_message_unittest.cc b/src/google/protobuf/dynamic_message_unittest.cc
index 5f7af94e..41b89ab5 100644
--- a/src/google/protobuf/dynamic_message_unittest.cc
+++ b/src/google/protobuf/dynamic_message_unittest.cc
@@ -61,6 +61,8 @@ class DynamicMessageTest : public testing::Test {
const Message* prototype_;
const Descriptor* extensions_descriptor_;
const Message* extensions_prototype_;
+ const Descriptor* packed_descriptor_;
+ const Message* packed_prototype_;
DynamicMessageTest(): factory_(&pool_) {}
@@ -87,6 +89,11 @@ class DynamicMessageTest : public testing::Test {
pool_.FindMessageTypeByName("protobuf_unittest.TestAllExtensions");
ASSERT_TRUE(extensions_descriptor_ != NULL);
extensions_prototype_ = factory_.GetPrototype(extensions_descriptor_);
+
+ packed_descriptor_ =
+ pool_.FindMessageTypeByName("protobuf_unittest.TestPackedTypes");
+ ASSERT_TRUE(packed_descriptor_ != NULL);
+ packed_prototype_ = factory_.GetPrototype(packed_descriptor_);
}
};
@@ -127,6 +134,15 @@ TEST_F(DynamicMessageTest, Extensions) {
reflection_tester.ExpectAllFieldsSetViaReflection(*message);
}
+TEST_F(DynamicMessageTest, PackedFields) {
+ // Check that packed fields work properly.
+ scoped_ptr<Message> message(packed_prototype_->New());
+ TestUtil::ReflectionTester reflection_tester(packed_descriptor_);
+
+ reflection_tester.SetPackedFieldsViaReflection(message.get());
+ reflection_tester.ExpectPackedFieldsSetViaReflection(*message);
+}
+
TEST_F(DynamicMessageTest, SpaceUsed) {
// Test that SpaceUsed() works properly
diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc
index c3ac7ce7..631bbc43 100644
--- a/src/google/protobuf/extension_set_unittest.cc
+++ b/src/google/protobuf/extension_set_unittest.cc
@@ -179,6 +179,19 @@ TEST(ExtensionSetTest, Serialization) {
TestUtil::ExpectAllFieldsSet(destination);
}
+TEST(ExtensionSetTest, PackedSerialization) {
+ // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
+ // wire compatibility of extensions.
+ unittest::TestPackedExtensions source;
+ unittest::TestPackedTypes destination;
+ string data;
+
+ TestUtil::SetPackedExtensions(&source);
+ source.SerializeToString(&data);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectPackedFieldsSet(destination);
+}
+
TEST(ExtensionSetTest, Parsing) {
// Serialize as TestAllTypes and parse as TestAllExtensions.
unittest::TestAllTypes source;
@@ -191,6 +204,18 @@ TEST(ExtensionSetTest, Parsing) {
TestUtil::ExpectAllExtensionsSet(destination);
}
+TEST(ExtensionSetTest, PackedParsing) {
+ // Serialize as TestPackedTypes and parse as TestPackedExtensions.
+ unittest::TestPackedTypes source;
+ unittest::TestPackedExtensions destination;
+ string data;
+
+ TestUtil::SetPackedFields(&source);
+ source.SerializeToString(&data);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectPackedExtensionsSet(destination);
+}
+
TEST(ExtensionSetTest, IsInitialized) {
// Test that IsInitialized() returns false if required fields in nested
// extensions are missing.
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc
index 66f95906..a0f08571 100644
--- a/src/google/protobuf/io/coded_stream.cc
+++ b/src/google/protobuf/io/coded_stream.cc
@@ -207,6 +207,14 @@ bool CodedInputStream::Skip(int count) {
return input_->Skip(count);
}
+bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
+ if (buffer_size_ == 0 && !Refresh()) return false;
+
+ *data = buffer_;
+ *size = buffer_size_;
+ return true;
+}
+
bool CodedInputStream::ReadRaw(void* buffer, int size) {
while (buffer_size_ < size) {
// Reading past end of buffer. Copy what we have, then refresh.
@@ -515,6 +523,26 @@ CodedOutputStream::~CodedOutputStream() {
}
}
+bool CodedOutputStream::Skip(int count) {
+ if (count < 0) return false;
+
+ while (count > buffer_size_) {
+ count -= buffer_size_;
+ if (!Refresh()) return false;
+ }
+
+ Advance(count);
+ return true;
+}
+
+bool CodedOutputStream::GetDirectBufferPointer(void** data, int* size) {
+ if (buffer_size_ == 0 && !Refresh()) return false;
+
+ *data = buffer_;
+ *size = buffer_size_;
+ return true;
+}
+
bool CodedOutputStream::WriteRaw(const void* data, int size) {
while (buffer_size_ < size) {
memcpy(buffer_, data, buffer_size_);
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index a73ac0ba..8ebe4b35 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -149,6 +149,15 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// occurs.
bool Skip(int count);
+ // Sets *data to point directly at the unread part of the CodedInputStream's
+ // underlying buffer, and *size to the size of that buffer, but does not
+ // advance the stream's current position. This will always either produce
+ // a non-empty buffer or return false. If the caller consumes any of
+ // this data, it should then call Skip() to skip over the consumed bytes.
+ // This may be useful for implementing external fast parsing routines for
+ // types of data not covered by the CodedInputStream interface.
+ bool GetDirectBufferPointer(const void** data, int* size);
+
// Read raw bytes, copying them into the given buffer.
bool ReadRaw(void* buffer, int size);
@@ -381,6 +390,21 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
// ZeroCopyOutputStream immediately after the last byte written.
~CodedOutputStream();
+ // Skips a number of bytes, leaving the bytes unmodified in the underlying
+ // buffer. Returns false if an underlying write error occurs. This is
+ // mainly useful with GetDirectBufferPointer().
+ bool Skip(int count);
+
+ // Sets *data to point directly at the unwritten part of the
+ // CodedOutputStream's underlying buffer, and *size to the size of that
+ // buffer, but does not advance the stream's current position. This will
+ // always either produce a non-empty buffer or return false. If the caller
+ // writes any data to this buffer, it should then call Skip() to skip over
+ // the consumed bytes. This may be useful for implementing external fast
+ // serialization routines for types of data not covered by the
+ // CodedOutputStream interface.
+ bool GetDirectBufferPointer(void** data, int* size);
+
// Write raw bytes, copying them from the given buffer.
bool WriteRaw(const void* buffer, int size);
@@ -518,7 +542,7 @@ inline bool CodedInputStream::ExpectAtEnd() {
inline bool CodedOutputStream::WriteVarint32(uint32 value) {
if (value < 0x80 && buffer_size_ > 0) {
- *buffer_ = value;
+ *buffer_ = static_cast<uint8>(value);
Advance(1);
return true;
} else {
@@ -537,7 +561,7 @@ inline bool CodedOutputStream::WriteVarint32SignExtended(int32 value) {
inline bool CodedOutputStream::WriteTag(uint32 value) {
if (value < (1 << 7)) {
if (buffer_size_ != 0) {
- buffer_[0] = value;
+ buffer_[0] = static_cast<uint8>(value);
Advance(1);
return true;
}
diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc
index 459b94a6..6a6eafe9 100644
--- a/src/google/protobuf/io/coded_stream_unittest.cc
+++ b/src/google/protobuf/io/coded_stream_unittest.cc
@@ -77,6 +77,9 @@ namespace {
// which failed will be printed. The case type must be printable using
// ostream::operator<<.
+// TODO(kenton): gTest now supports "parameterized tests" which would be
+// a better way to accomplish this. Rewrite when time permits.
+
#define TEST_1D(FIXTURE, NAME, CASES) \
class FIXTURE##_##NAME##_DD : public FIXTURE { \
protected: \
@@ -614,6 +617,73 @@ TEST_1D(CodedStreamTest, SkipInput, kBlockSizes) {
}
// -------------------------------------------------------------------
+// GetDirectBufferPointer
+
+TEST_F(CodedStreamTest, GetDirectBufferPointerInput) {
+ ArrayInputStream input(buffer_, sizeof(buffer_), 8);
+ CodedInputStream coded_input(&input);
+
+ const void* ptr;
+ int size;
+
+ EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Peeking again should return the same pointer.
+ EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Skip forward in the same buffer then peek again.
+ EXPECT_TRUE(coded_input.Skip(3));
+ EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_ + 3, ptr);
+ EXPECT_EQ(5, size);
+
+ // Skip to end of buffer and peek -- should get next buffer.
+ EXPECT_TRUE(coded_input.Skip(5));
+ EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_ + 8, ptr);
+ EXPECT_EQ(8, size);
+}
+
+TEST_F(CodedStreamTest, GetDirectBufferPointerOutput) {
+ ArrayOutputStream output(buffer_, sizeof(buffer_), 8);
+ CodedOutputStream coded_output(&output);
+
+ void* ptr;
+ int size;
+
+ EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Peeking again should return the same pointer.
+ EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Skip forward in the same buffer then peek again.
+ EXPECT_TRUE(coded_output.Skip(3));
+ EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_ + 3, ptr);
+ EXPECT_EQ(5, size);
+
+ // Skip to end of buffer and peek -- should get next buffer.
+ EXPECT_TRUE(coded_output.Skip(5));
+ EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_ + 8, ptr);
+ EXPECT_EQ(8, size);
+
+ // Skip over multiple buffers.
+ EXPECT_TRUE(coded_output.Skip(22));
+ EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_ + 30, ptr);
+ EXPECT_EQ(2, size);
+}
+
+// -------------------------------------------------------------------
// Limits
TEST_1D(CodedStreamTest, BasicLimit, kBlockSizes) {
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index f6c932ff..097411cb 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -145,24 +145,42 @@ bool Message::ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input) {
decoder.ConsumedEntireMessage();
}
+bool Message::ParseFromBoundedZeroCopyStream(
+ io::ZeroCopyInputStream* input, int size) {
+ io::CodedInputStream decoder(input);
+ decoder.PushLimit(size);
+ return ParseFromCodedStream(&decoder) &&
+ decoder.ConsumedEntireMessage() &&
+ decoder.BytesUntilLimit() == 0;
+}
+
+bool Message::ParsePartialFromBoundedZeroCopyStream(
+ io::ZeroCopyInputStream* input, int size) {
+ io::CodedInputStream decoder(input);
+ decoder.PushLimit(size);
+ return ParsePartialFromCodedStream(&decoder) &&
+ decoder.ConsumedEntireMessage() &&
+ decoder.BytesUntilLimit() == 0;
+}
+
bool Message::ParseFromString(const string& data) {
io::ArrayInputStream input(data.data(), data.size());
- return ParseFromZeroCopyStream(&input);
+ return ParseFromBoundedZeroCopyStream(&input, data.size());
}
bool Message::ParsePartialFromString(const string& data) {
io::ArrayInputStream input(data.data(), data.size());
- return ParsePartialFromZeroCopyStream(&input);
+ return ParsePartialFromBoundedZeroCopyStream(&input, data.size());
}
bool Message::ParseFromArray(const void* data, int size) {
io::ArrayInputStream input(data, size);
- return ParseFromZeroCopyStream(&input);
+ return ParseFromBoundedZeroCopyStream(&input, size);
}
bool Message::ParsePartialFromArray(const void* data, int size) {
io::ArrayInputStream input(data, size);
- return ParsePartialFromZeroCopyStream(&input);
+ return ParsePartialFromBoundedZeroCopyStream(&input, size);
}
bool Message::ParseFromFileDescriptor(int file_descriptor) {
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index d96fcc60..0674a12c 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -232,6 +232,14 @@ class LIBPROTOBUF_EXPORT Message {
// Like ParseFromZeroCopyStream(), but accepts messages that are missing
// required fields.
bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input);
+ // Read a protocol buffer from the given zero-copy input stream, expecting
+ // the message to be exactly "size" bytes long. If successful, exactly
+ // this many bytes will have been consumed from the input.
+ bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size);
+ // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are
+ // missing required fields.
+ bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input,
+ int size);
// Parse a protocol buffer contained in a string.
bool ParseFromString(const string& data);
// Like ParseFromString(), but accepts messages that are missing
diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc
index da99741b..46e68446 100644
--- a/src/google/protobuf/message_unittest.cc
+++ b/src/google/protobuf/message_unittest.cc
@@ -107,6 +107,19 @@ TEST(MessageTest, ParseFromFileDescriptor) {
EXPECT_GE(close(file), 0);
}
+TEST(MessageTest, ParsePackedFromFileDescriptor) {
+ string filename =
+ TestSourceDir() +
+ "/google/protobuf/testdata/golden_packed_fields_message";
+ int file = open(filename.c_str(), O_RDONLY | O_BINARY);
+
+ unittest::TestPackedTypes message;
+ EXPECT_TRUE(message.ParseFromFileDescriptor(file));
+ TestUtil::ExpectPackedFieldsSet(message);
+
+ EXPECT_GE(close(file), 0);
+}
+
TEST(MessageTest, ParseHelpers) {
// TODO(kenton): Test more helpers? They're all two-liners so it seems
// like a waste of time.
@@ -134,6 +147,25 @@ TEST(MessageTest, ParseHelpers) {
EXPECT_TRUE(stream.eof());
TestUtil::ExpectAllFieldsSet(message);
}
+
+ {
+ // Test ParseFromBoundedZeroCopyStream.
+ string data_with_junk(data);
+ data_with_junk.append("some junk on the end");
+ io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size());
+ protobuf_unittest::TestAllTypes message;
+ EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size()));
+ TestUtil::ExpectAllFieldsSet(message);
+ }
+
+ {
+ // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if
+ // EOF is reached before the expected number of bytes.
+ io::ArrayInputStream stream(data.data(), data.size());
+ protobuf_unittest::TestAllTypes message;
+ EXPECT_FALSE(
+ message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1));
+ }
}
TEST(MessageTest, ParseFailsIfNotInitialized) {
diff --git a/src/google/protobuf/test_util.cc b/src/google/protobuf/test_util.cc
index 40120d95..c1e9fa78 100644
--- a/src/google/protobuf/test_util.cc
+++ b/src/google/protobuf/test_util.cc
@@ -636,6 +636,180 @@ void TestUtil::ExpectRepeatedFieldsModified(
}
+// -------------------------------------------------------------------
+
+void TestUtil::SetPackedFields(unittest::TestPackedTypes* message) {
+ message->add_packed_int32 (601);
+ message->add_packed_int64 (602);
+ message->add_packed_uint32 (603);
+ message->add_packed_uint64 (604);
+ message->add_packed_sint32 (605);
+ message->add_packed_sint64 (606);
+ message->add_packed_fixed32 (607);
+ message->add_packed_fixed64 (608);
+ message->add_packed_sfixed32(609);
+ message->add_packed_sfixed64(610);
+ message->add_packed_float (611);
+ message->add_packed_double (612);
+ message->add_packed_bool (true);
+ message->add_packed_enum (unittest::FOREIGN_BAR);
+ // add a second one of each field
+ message->add_packed_int32 (701);
+ message->add_packed_int64 (702);
+ message->add_packed_uint32 (703);
+ message->add_packed_uint64 (704);
+ message->add_packed_sint32 (705);
+ message->add_packed_sint64 (706);
+ message->add_packed_fixed32 (707);
+ message->add_packed_fixed64 (708);
+ message->add_packed_sfixed32(709);
+ message->add_packed_sfixed64(710);
+ message->add_packed_float (711);
+ message->add_packed_double (712);
+ message->add_packed_bool (false);
+ message->add_packed_enum (unittest::FOREIGN_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ModifyPackedFields(unittest::TestPackedTypes* message) {
+ message->set_packed_int32 (1, 801);
+ message->set_packed_int64 (1, 802);
+ message->set_packed_uint32 (1, 803);
+ message->set_packed_uint64 (1, 804);
+ message->set_packed_sint32 (1, 805);
+ message->set_packed_sint64 (1, 806);
+ message->set_packed_fixed32 (1, 807);
+ message->set_packed_fixed64 (1, 808);
+ message->set_packed_sfixed32(1, 809);
+ message->set_packed_sfixed64(1, 810);
+ message->set_packed_float (1, 811);
+ message->set_packed_double (1, 812);
+ message->set_packed_bool (1, true);
+ message->set_packed_enum (1, unittest::FOREIGN_FOO);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedFieldsSet(const unittest::TestPackedTypes& message) {
+ ASSERT_EQ(2, message.packed_int32_size ());
+ ASSERT_EQ(2, message.packed_int64_size ());
+ ASSERT_EQ(2, message.packed_uint32_size ());
+ ASSERT_EQ(2, message.packed_uint64_size ());
+ ASSERT_EQ(2, message.packed_sint32_size ());
+ ASSERT_EQ(2, message.packed_sint64_size ());
+ ASSERT_EQ(2, message.packed_fixed32_size ());
+ ASSERT_EQ(2, message.packed_fixed64_size ());
+ ASSERT_EQ(2, message.packed_sfixed32_size());
+ ASSERT_EQ(2, message.packed_sfixed64_size());
+ ASSERT_EQ(2, message.packed_float_size ());
+ ASSERT_EQ(2, message.packed_double_size ());
+ ASSERT_EQ(2, message.packed_bool_size ());
+ ASSERT_EQ(2, message.packed_enum_size ());
+
+ EXPECT_EQ(601 , message.packed_int32 (0));
+ EXPECT_EQ(602 , message.packed_int64 (0));
+ EXPECT_EQ(603 , message.packed_uint32 (0));
+ EXPECT_EQ(604 , message.packed_uint64 (0));
+ EXPECT_EQ(605 , message.packed_sint32 (0));
+ EXPECT_EQ(606 , message.packed_sint64 (0));
+ EXPECT_EQ(607 , message.packed_fixed32 (0));
+ EXPECT_EQ(608 , message.packed_fixed64 (0));
+ EXPECT_EQ(609 , message.packed_sfixed32(0));
+ EXPECT_EQ(610 , message.packed_sfixed64(0));
+ EXPECT_EQ(611 , message.packed_float (0));
+ EXPECT_EQ(612 , message.packed_double (0));
+ EXPECT_EQ(true , message.packed_bool (0));
+ EXPECT_EQ(unittest::FOREIGN_BAR, message.packed_enum(0));
+
+ EXPECT_EQ(701 , message.packed_int32 (1));
+ EXPECT_EQ(702 , message.packed_int64 (1));
+ EXPECT_EQ(703 , message.packed_uint32 (1));
+ EXPECT_EQ(704 , message.packed_uint64 (1));
+ EXPECT_EQ(705 , message.packed_sint32 (1));
+ EXPECT_EQ(706 , message.packed_sint64 (1));
+ EXPECT_EQ(707 , message.packed_fixed32 (1));
+ EXPECT_EQ(708 , message.packed_fixed64 (1));
+ EXPECT_EQ(709 , message.packed_sfixed32(1));
+ EXPECT_EQ(710 , message.packed_sfixed64(1));
+ EXPECT_EQ(711 , message.packed_float (1));
+ EXPECT_EQ(712 , message.packed_double (1));
+ EXPECT_EQ(false, message.packed_bool (1));
+ EXPECT_EQ(unittest::FOREIGN_BAZ, message.packed_enum(1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedClear(
+ const unittest::TestPackedTypes& message) {
+ // Packed repeated fields are empty.
+ EXPECT_EQ(0, message.packed_int32_size ());
+ EXPECT_EQ(0, message.packed_int64_size ());
+ EXPECT_EQ(0, message.packed_uint32_size ());
+ EXPECT_EQ(0, message.packed_uint64_size ());
+ EXPECT_EQ(0, message.packed_sint32_size ());
+ EXPECT_EQ(0, message.packed_sint64_size ());
+ EXPECT_EQ(0, message.packed_fixed32_size ());
+ EXPECT_EQ(0, message.packed_fixed64_size ());
+ EXPECT_EQ(0, message.packed_sfixed32_size());
+ EXPECT_EQ(0, message.packed_sfixed64_size());
+ EXPECT_EQ(0, message.packed_float_size ());
+ EXPECT_EQ(0, message.packed_double_size ());
+ EXPECT_EQ(0, message.packed_bool_size ());
+ EXPECT_EQ(0, message.packed_enum_size ());
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedFieldsModified(
+ const unittest::TestPackedTypes& message) {
+ // Do the same for packed repeated fields.
+ ASSERT_EQ(2, message.packed_int32_size ());
+ ASSERT_EQ(2, message.packed_int64_size ());
+ ASSERT_EQ(2, message.packed_uint32_size ());
+ ASSERT_EQ(2, message.packed_uint64_size ());
+ ASSERT_EQ(2, message.packed_sint32_size ());
+ ASSERT_EQ(2, message.packed_sint64_size ());
+ ASSERT_EQ(2, message.packed_fixed32_size ());
+ ASSERT_EQ(2, message.packed_fixed64_size ());
+ ASSERT_EQ(2, message.packed_sfixed32_size());
+ ASSERT_EQ(2, message.packed_sfixed64_size());
+ ASSERT_EQ(2, message.packed_float_size ());
+ ASSERT_EQ(2, message.packed_double_size ());
+ ASSERT_EQ(2, message.packed_bool_size ());
+ ASSERT_EQ(2, message.packed_enum_size ());
+
+ EXPECT_EQ(601 , message.packed_int32 (0));
+ EXPECT_EQ(602 , message.packed_int64 (0));
+ EXPECT_EQ(603 , message.packed_uint32 (0));
+ EXPECT_EQ(604 , message.packed_uint64 (0));
+ EXPECT_EQ(605 , message.packed_sint32 (0));
+ EXPECT_EQ(606 , message.packed_sint64 (0));
+ EXPECT_EQ(607 , message.packed_fixed32 (0));
+ EXPECT_EQ(608 , message.packed_fixed64 (0));
+ EXPECT_EQ(609 , message.packed_sfixed32(0));
+ EXPECT_EQ(610 , message.packed_sfixed64(0));
+ EXPECT_EQ(611 , message.packed_float (0));
+ EXPECT_EQ(612 , message.packed_double (0));
+ EXPECT_EQ(true , message.packed_bool (0));
+ EXPECT_EQ(unittest::FOREIGN_BAR, message.packed_enum(0));
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(801 , message.packed_int32 (1));
+ EXPECT_EQ(802 , message.packed_int64 (1));
+ EXPECT_EQ(803 , message.packed_uint32 (1));
+ EXPECT_EQ(804 , message.packed_uint64 (1));
+ EXPECT_EQ(805 , message.packed_sint32 (1));
+ EXPECT_EQ(806 , message.packed_sint64 (1));
+ EXPECT_EQ(807 , message.packed_fixed32 (1));
+ EXPECT_EQ(808 , message.packed_fixed64 (1));
+ EXPECT_EQ(809 , message.packed_sfixed32(1));
+ EXPECT_EQ(810 , message.packed_sfixed64(1));
+ EXPECT_EQ(811 , message.packed_float (1));
+ EXPECT_EQ(812 , message.packed_double (1));
+ EXPECT_EQ(true , message.packed_bool (1));
+ EXPECT_EQ(unittest::FOREIGN_FOO, message.packed_enum(1));
+}
+
// ===================================================================
// Extensions
//
@@ -1246,6 +1420,183 @@ void TestUtil::ExpectRepeatedExtensionsModified(
// -------------------------------------------------------------------
+void TestUtil::SetPackedExtensions(unittest::TestPackedExtensions* message) {
+ message->AddExtension(unittest::packed_int32_extension , 601);
+ message->AddExtension(unittest::packed_int64_extension , 602);
+ message->AddExtension(unittest::packed_uint32_extension , 603);
+ message->AddExtension(unittest::packed_uint64_extension , 604);
+ message->AddExtension(unittest::packed_sint32_extension , 605);
+ message->AddExtension(unittest::packed_sint64_extension , 606);
+ message->AddExtension(unittest::packed_fixed32_extension , 607);
+ message->AddExtension(unittest::packed_fixed64_extension , 608);
+ message->AddExtension(unittest::packed_sfixed32_extension, 609);
+ message->AddExtension(unittest::packed_sfixed64_extension, 610);
+ message->AddExtension(unittest::packed_float_extension , 611);
+ message->AddExtension(unittest::packed_double_extension , 612);
+ message->AddExtension(unittest::packed_bool_extension , true);
+ message->AddExtension(unittest::packed_enum_extension, unittest::FOREIGN_BAR);
+ // add a second one of each field
+ message->AddExtension(unittest::packed_int32_extension , 701);
+ message->AddExtension(unittest::packed_int64_extension , 702);
+ message->AddExtension(unittest::packed_uint32_extension , 703);
+ message->AddExtension(unittest::packed_uint64_extension , 704);
+ message->AddExtension(unittest::packed_sint32_extension , 705);
+ message->AddExtension(unittest::packed_sint64_extension , 706);
+ message->AddExtension(unittest::packed_fixed32_extension , 707);
+ message->AddExtension(unittest::packed_fixed64_extension , 708);
+ message->AddExtension(unittest::packed_sfixed32_extension, 709);
+ message->AddExtension(unittest::packed_sfixed64_extension, 710);
+ message->AddExtension(unittest::packed_float_extension , 711);
+ message->AddExtension(unittest::packed_double_extension , 712);
+ message->AddExtension(unittest::packed_bool_extension , false);
+ message->AddExtension(unittest::packed_enum_extension, unittest::FOREIGN_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ModifyPackedExtensions(unittest::TestPackedExtensions* message) {
+ message->SetExtension(unittest::packed_int32_extension , 1, 801);
+ message->SetExtension(unittest::packed_int64_extension , 1, 802);
+ message->SetExtension(unittest::packed_uint32_extension , 1, 803);
+ message->SetExtension(unittest::packed_uint64_extension , 1, 804);
+ message->SetExtension(unittest::packed_sint32_extension , 1, 805);
+ message->SetExtension(unittest::packed_sint64_extension , 1, 806);
+ message->SetExtension(unittest::packed_fixed32_extension , 1, 807);
+ message->SetExtension(unittest::packed_fixed64_extension , 1, 808);
+ message->SetExtension(unittest::packed_sfixed32_extension, 1, 809);
+ message->SetExtension(unittest::packed_sfixed64_extension, 1, 810);
+ message->SetExtension(unittest::packed_float_extension , 1, 811);
+ message->SetExtension(unittest::packed_double_extension , 1, 812);
+ message->SetExtension(unittest::packed_bool_extension , 1, true);
+ message->SetExtension(unittest::packed_enum_extension , 1,
+ unittest::FOREIGN_FOO);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedExtensionsSet(
+ const unittest::TestPackedExtensions& message) {
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension ));
+
+ EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension , 0));
+ EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension , 0));
+ EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension , 0));
+ EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension , 0));
+ EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension , 0));
+ EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension , 0));
+ EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension , 0));
+ EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension , 0));
+ EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension, 0));
+ EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension, 0));
+ EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension , 0));
+ EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension , 0));
+ EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension , 0));
+ EXPECT_EQ(unittest::FOREIGN_BAR,
+ message.GetExtension(unittest::packed_enum_extension, 0));
+ EXPECT_EQ(701 , message.GetExtension(unittest::packed_int32_extension , 1));
+ EXPECT_EQ(702 , message.GetExtension(unittest::packed_int64_extension , 1));
+ EXPECT_EQ(703 , message.GetExtension(unittest::packed_uint32_extension , 1));
+ EXPECT_EQ(704 , message.GetExtension(unittest::packed_uint64_extension , 1));
+ EXPECT_EQ(705 , message.GetExtension(unittest::packed_sint32_extension , 1));
+ EXPECT_EQ(706 , message.GetExtension(unittest::packed_sint64_extension , 1));
+ EXPECT_EQ(707 , message.GetExtension(unittest::packed_fixed32_extension , 1));
+ EXPECT_EQ(708 , message.GetExtension(unittest::packed_fixed64_extension , 1));
+ EXPECT_EQ(709 , message.GetExtension(unittest::packed_sfixed32_extension, 1));
+ EXPECT_EQ(710 , message.GetExtension(unittest::packed_sfixed64_extension, 1));
+ EXPECT_EQ(711 , message.GetExtension(unittest::packed_float_extension , 1));
+ EXPECT_EQ(712 , message.GetExtension(unittest::packed_double_extension , 1));
+ EXPECT_EQ(false, message.GetExtension(unittest::packed_bool_extension , 1));
+ EXPECT_EQ(unittest::FOREIGN_BAZ,
+ message.GetExtension(unittest::packed_enum_extension, 1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedExtensionsClear(
+ const unittest::TestPackedExtensions& message) {
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int32_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int64_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint32_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint64_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint32_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint64_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed32_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed64_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed32_extension));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed64_extension));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_float_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_double_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_bool_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_enum_extension ));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedExtensionsModified(
+ const unittest::TestPackedExtensions& message) {
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension ));
+ EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension , 0));
+ EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension , 0));
+ EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension , 0));
+ EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension , 0));
+ EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension , 0));
+ EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension , 0));
+ EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension , 0));
+ EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension , 0));
+ EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension, 0));
+ EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension, 0));
+ EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension , 0));
+ EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension , 0));
+ EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension , 0));
+ EXPECT_EQ(unittest::FOREIGN_BAR,
+ message.GetExtension(unittest::packed_enum_extension, 0));
+
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(801 , message.GetExtension(unittest::packed_int32_extension , 1));
+ EXPECT_EQ(802 , message.GetExtension(unittest::packed_int64_extension , 1));
+ EXPECT_EQ(803 , message.GetExtension(unittest::packed_uint32_extension , 1));
+ EXPECT_EQ(804 , message.GetExtension(unittest::packed_uint64_extension , 1));
+ EXPECT_EQ(805 , message.GetExtension(unittest::packed_sint32_extension , 1));
+ EXPECT_EQ(806 , message.GetExtension(unittest::packed_sint64_extension , 1));
+ EXPECT_EQ(807 , message.GetExtension(unittest::packed_fixed32_extension , 1));
+ EXPECT_EQ(808 , message.GetExtension(unittest::packed_fixed64_extension , 1));
+ EXPECT_EQ(809 , message.GetExtension(unittest::packed_sfixed32_extension, 1));
+ EXPECT_EQ(810 , message.GetExtension(unittest::packed_sfixed64_extension, 1));
+ EXPECT_EQ(811 , message.GetExtension(unittest::packed_float_extension , 1));
+ EXPECT_EQ(812 , message.GetExtension(unittest::packed_double_extension , 1));
+ EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension , 1));
+ EXPECT_EQ(unittest::FOREIGN_FOO,
+ message.GetExtension(unittest::packed_enum_extension, 1));
+}
+
+// -------------------------------------------------------------------
+
void TestUtil::ExpectAllFieldsAndExtensionsInOrder(const string& serialized) {
// We set each field individually, serialize separately, and concatenate all
// the strings in canonical order to determine the expected serialization.
@@ -1335,7 +1686,8 @@ TestUtil::ReflectionTester::ReflectionTester(
// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
const FieldDescriptor* TestUtil::ReflectionTester::F(const string& name) {
const FieldDescriptor* result = NULL;
- if (base_descriptor_->name() == "TestAllExtensions") {
+ if (base_descriptor_->name() == "TestAllExtensions" ||
+ base_descriptor_->name() == "TestPackedExtensions") {
result = base_descriptor_->file()->FindExtensionByName(name + "_extension");
} else {
result = base_descriptor_->FindFieldByName(name);
@@ -1475,6 +1827,40 @@ void TestUtil::ReflectionTester::SetAllFieldsViaReflection(Message* message) {
reflection->SetString(message, F("default_cord"), "425");
}
+void TestUtil::ReflectionTester::SetPackedFieldsViaReflection(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ reflection->AddInt32 (message, F("packed_int32" ), 601);
+ reflection->AddInt64 (message, F("packed_int64" ), 602);
+ reflection->AddUInt32(message, F("packed_uint32" ), 603);
+ reflection->AddUInt64(message, F("packed_uint64" ), 604);
+ reflection->AddInt32 (message, F("packed_sint32" ), 605);
+ reflection->AddInt64 (message, F("packed_sint64" ), 606);
+ reflection->AddUInt32(message, F("packed_fixed32" ), 607);
+ reflection->AddUInt64(message, F("packed_fixed64" ), 608);
+ reflection->AddInt32 (message, F("packed_sfixed32"), 609);
+ reflection->AddInt64 (message, F("packed_sfixed64"), 610);
+ reflection->AddFloat (message, F("packed_float" ), 611);
+ reflection->AddDouble(message, F("packed_double" ), 612);
+ reflection->AddBool (message, F("packed_bool" ), true);
+ reflection->AddEnum (message, F("packed_enum" ), foreign_bar_);
+
+ reflection->AddInt32 (message, F("packed_int32" ), 701);
+ reflection->AddInt64 (message, F("packed_int64" ), 702);
+ reflection->AddUInt32(message, F("packed_uint32" ), 703);
+ reflection->AddUInt64(message, F("packed_uint64" ), 704);
+ reflection->AddInt32 (message, F("packed_sint32" ), 705);
+ reflection->AddInt64 (message, F("packed_sint64" ), 706);
+ reflection->AddUInt32(message, F("packed_fixed32" ), 707);
+ reflection->AddUInt64(message, F("packed_fixed64" ), 708);
+ reflection->AddInt32 (message, F("packed_sfixed32"), 709);
+ reflection->AddInt64 (message, F("packed_sfixed64"), 710);
+ reflection->AddFloat (message, F("packed_float" ), 711);
+ reflection->AddDouble(message, F("packed_double" ), 712);
+ reflection->AddBool (message, F("packed_bool" ), false);
+ reflection->AddEnum (message, F("packed_enum" ), foreign_baz_);
+}
+
// -------------------------------------------------------------------
void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection(
@@ -1725,6 +2111,58 @@ void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection(
EXPECT_EQ("425", reflection->GetStringReference(message, F("default_cord"), &scratch));
}
+void TestUtil::ReflectionTester::ExpectPackedFieldsSetViaReflection(
+ const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_int32" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_int64" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_uint32" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_uint64" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sint32" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sint64" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_fixed32" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_fixed64" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sfixed32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sfixed64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_float" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_double" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_bool" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_enum" )));
+
+ EXPECT_EQ(601 , reflection->GetRepeatedInt32 (message, F("packed_int32" ), 0));
+ EXPECT_EQ(602 , reflection->GetRepeatedInt64 (message, F("packed_int64" ), 0));
+ EXPECT_EQ(603 , reflection->GetRepeatedUInt32(message, F("packed_uint32" ), 0));
+ EXPECT_EQ(604 , reflection->GetRepeatedUInt64(message, F("packed_uint64" ), 0));
+ EXPECT_EQ(605 , reflection->GetRepeatedInt32 (message, F("packed_sint32" ), 0));
+ EXPECT_EQ(606 , reflection->GetRepeatedInt64 (message, F("packed_sint64" ), 0));
+ EXPECT_EQ(607 , reflection->GetRepeatedUInt32(message, F("packed_fixed32" ), 0));
+ EXPECT_EQ(608 , reflection->GetRepeatedUInt64(message, F("packed_fixed64" ), 0));
+ EXPECT_EQ(609 , reflection->GetRepeatedInt32 (message, F("packed_sfixed32"), 0));
+ EXPECT_EQ(610 , reflection->GetRepeatedInt64 (message, F("packed_sfixed64"), 0));
+ EXPECT_EQ(611 , reflection->GetRepeatedFloat (message, F("packed_float" ), 0));
+ EXPECT_EQ(612 , reflection->GetRepeatedDouble(message, F("packed_double" ), 0));
+ EXPECT_EQ(true , reflection->GetRepeatedBool (message, F("packed_bool" ), 0));
+ EXPECT_EQ(foreign_bar_,
+ reflection->GetRepeatedEnum(message, F("packed_enum"), 0));
+
+ EXPECT_EQ(701 , reflection->GetRepeatedInt32 (message, F("packed_int32" ), 1));
+ EXPECT_EQ(702 , reflection->GetRepeatedInt64 (message, F("packed_int64" ), 1));
+ EXPECT_EQ(703 , reflection->GetRepeatedUInt32(message, F("packed_uint32" ), 1));
+ EXPECT_EQ(704 , reflection->GetRepeatedUInt64(message, F("packed_uint64" ), 1));
+ EXPECT_EQ(705 , reflection->GetRepeatedInt32 (message, F("packed_sint32" ), 1));
+ EXPECT_EQ(706 , reflection->GetRepeatedInt64 (message, F("packed_sint64" ), 1));
+ EXPECT_EQ(707 , reflection->GetRepeatedUInt32(message, F("packed_fixed32" ), 1));
+ EXPECT_EQ(708 , reflection->GetRepeatedUInt64(message, F("packed_fixed64" ), 1));
+ EXPECT_EQ(709 , reflection->GetRepeatedInt32 (message, F("packed_sfixed32"), 1));
+ EXPECT_EQ(710 , reflection->GetRepeatedInt64 (message, F("packed_sfixed64"), 1));
+ EXPECT_EQ(711 , reflection->GetRepeatedFloat (message, F("packed_float" ), 1));
+ EXPECT_EQ(712 , reflection->GetRepeatedDouble(message, F("packed_double" ), 1));
+ EXPECT_EQ(false, reflection->GetRepeatedBool (message, F("packed_bool" ), 1));
+ EXPECT_EQ(foreign_baz_,
+ reflection->GetRepeatedEnum(message, F("packed_enum"), 1));
+}
+
// -------------------------------------------------------------------
void TestUtil::ReflectionTester::ExpectClearViaReflection(
@@ -1890,6 +2328,26 @@ void TestUtil::ReflectionTester::ExpectClearViaReflection(
EXPECT_EQ("123", reflection->GetStringReference(message, F("default_cord"), &scratch));
}
+void TestUtil::ReflectionTester::ExpectPackedClearViaReflection(
+ const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_int32" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_int64" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_uint32" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_uint64" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sint32" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sint64" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_fixed32" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_fixed64" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sfixed32")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sfixed64")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_float" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_double" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_bool" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_enum" )));
+}
+
// -------------------------------------------------------------------
void TestUtil::ReflectionTester::ModifyRepeatedFieldsViaReflection(
@@ -1930,5 +2388,24 @@ void TestUtil::ReflectionTester::ModifyRepeatedFieldsViaReflection(
reflection->SetRepeatedString(message, F("repeated_cord"), 1, "525");
}
+void TestUtil::ReflectionTester::ModifyPackedFieldsViaReflection(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ reflection->SetRepeatedInt32 (message, F("packed_int32" ), 1, 801);
+ reflection->SetRepeatedInt64 (message, F("packed_int64" ), 1, 802);
+ reflection->SetRepeatedUInt32(message, F("packed_uint32" ), 1, 803);
+ reflection->SetRepeatedUInt64(message, F("packed_uint64" ), 1, 804);
+ reflection->SetRepeatedInt32 (message, F("packed_sint32" ), 1, 805);
+ reflection->SetRepeatedInt64 (message, F("packed_sint64" ), 1, 806);
+ reflection->SetRepeatedUInt32(message, F("packed_fixed32" ), 1, 807);
+ reflection->SetRepeatedUInt64(message, F("packed_fixed64" ), 1, 808);
+ reflection->SetRepeatedInt32 (message, F("packed_sfixed32"), 1, 809);
+ reflection->SetRepeatedInt64 (message, F("packed_sfixed64"), 1, 810);
+ reflection->SetRepeatedFloat (message, F("packed_float" ), 1, 811);
+ reflection->SetRepeatedDouble(message, F("packed_double" ), 1, 812);
+ reflection->SetRepeatedBool (message, F("packed_bool" ), 1, true);
+ reflection->SetRepeatedEnum (message, F("packed_enum" ), 1, foreign_foo_);
+}
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/test_util.h b/src/google/protobuf/test_util.h
index af03afc3..ca840c71 100644
--- a/src/google/protobuf/test_util.h
+++ b/src/google/protobuf/test_util.h
@@ -52,30 +52,44 @@ class TestUtil {
static void SetAllFields(unittest::TestAllTypes* message);
static void SetAllExtensions(unittest::TestAllExtensions* message);
static void SetAllFieldsAndExtensions(unittest::TestFieldOrderings* message);
+ static void SetPackedFields(unittest::TestPackedTypes* message);
+ static void SetPackedExtensions(unittest::TestPackedExtensions* message);
// Use the repeated versions of the set_*() accessors to modify all the
// repeated fields of the messsage (which should already have been
- // initialized with SetAllFields()). SetAllFields() itself only tests
+ // initialized with Set*Fields()). Set*Fields() itself only tests
// the add_*() accessors.
static void ModifyRepeatedFields(unittest::TestAllTypes* message);
static void ModifyRepeatedExtensions(unittest::TestAllExtensions* message);
+ static void ModifyPackedFields(unittest::TestPackedTypes* message);
+ static void ModifyPackedExtensions(unittest::TestPackedExtensions* message);
// Check that all fields have the values that they should have after
- // SetAllFields() is called.
+ // Set*Fields() is called.
static void ExpectAllFieldsSet(const unittest::TestAllTypes& message);
static void ExpectAllExtensionsSet(
const unittest::TestAllExtensions& message);
+ static void ExpectPackedFieldsSet(const unittest::TestPackedTypes& message);
+ static void ExpectPackedExtensionsSet(
+ const unittest::TestPackedExtensions& message);
// Expect that the message is modified as would be expected from
- // ModifyRepeatedFields().
+ // Modify*Fields().
static void ExpectRepeatedFieldsModified(
const unittest::TestAllTypes& message);
static void ExpectRepeatedExtensionsModified(
const unittest::TestAllExtensions& message);
+ static void ExpectPackedFieldsModified(
+ const unittest::TestPackedTypes& message);
+ static void ExpectPackedExtensionsModified(
+ const unittest::TestPackedExtensions& message);
// Check that all fields have their default values.
static void ExpectClear(const unittest::TestAllTypes& message);
static void ExpectExtensionsClear(const unittest::TestAllExtensions& message);
+ static void ExpectPackedClear(const unittest::TestPackedTypes& message);
+ static void ExpectPackedExtensionsClear(
+ const unittest::TestPackedExtensions& message);
// Check that the passed-in serialization is the canonical serialization we
// expect for a TestFieldOrderings message filled in by
@@ -97,6 +111,11 @@ class TestUtil {
void ExpectAllFieldsSetViaReflection(const Message& message);
void ExpectClearViaReflection(const Message& message);
+ void SetPackedFieldsViaReflection(Message* message);
+ void ModifyPackedFieldsViaReflection(Message* message);
+ void ExpectPackedFieldsSetViaReflection(const Message& message);
+ void ExpectPackedClearViaReflection(const Message& message);
+
private:
const FieldDescriptor* F(const string& name);
diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto
index 0aa66b9f..46ce77c3 100644
--- a/src/google/protobuf/unittest.proto
+++ b/src/google/protobuf/unittest.proto
@@ -461,6 +461,46 @@ message OneBytes {
optional bytes data = 1;
}
+// Test messages for packed fields
+
+message TestPackedTypes {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnum packed_enum = 103 [packed = true];
+}
+
+message TestPackedExtensions {
+ extensions 1 to max;
+}
+
+extend TestPackedExtensions {
+ repeated int32 packed_int32_extension = 90 [packed = true];
+ repeated int64 packed_int64_extension = 91 [packed = true];
+ repeated uint32 packed_uint32_extension = 92 [packed = true];
+ repeated uint64 packed_uint64_extension = 93 [packed = true];
+ repeated sint32 packed_sint32_extension = 94 [packed = true];
+ repeated sint64 packed_sint64_extension = 95 [packed = true];
+ repeated fixed32 packed_fixed32_extension = 96 [packed = true];
+ repeated fixed64 packed_fixed64_extension = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32_extension = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64_extension = 99 [packed = true];
+ repeated float packed_float_extension = 100 [packed = true];
+ repeated double packed_double_extension = 101 [packed = true];
+ repeated bool packed_bool_extension = 102 [packed = true];
+ repeated ForeignEnum packed_enum_extension = 103 [packed = true];
+}
+
// Test that RPC services work.
message FooRequest {}
message FooResponse {}
diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc
index 6a9be5a4..f42f9a59 100644
--- a/src/google/protobuf/unknown_field_set.cc
+++ b/src/google/protobuf/unknown_field_set.cc
@@ -154,6 +154,46 @@ int UnknownFieldSet::SpaceUsed() const {
return sizeof(*this) + SpaceUsedExcludingSelf();
}
+UnknownFieldSet::Internal::FieldMap UnknownFieldSet::kEmptyMap;
+const UnknownFieldSet::iterator UnknownFieldSet::kEmptyIterator(
+ kEmptyMap.end(), &kEmptyMap);
+const UnknownFieldSet::const_iterator UnknownFieldSet::kEmptyConstIterator(
+ kEmptyMap.end(), &kEmptyMap);
+
+void UnknownFieldSet::iterator::AdvanceToNonEmpty() {
+ while (inner_iterator_ != inner_map_->end() &&
+ (inner_iterator_->second->index() == -1 ||
+ inner_iterator_->second->empty())) {
+ ++inner_iterator_;
+ }
+}
+
+void UnknownFieldSet::const_iterator::AdvanceToNonEmpty() {
+ while (inner_iterator_ != inner_map_->end() &&
+ (inner_iterator_->second->index() == -1 ||
+ inner_iterator_->second->empty())) {
+ ++inner_iterator_;
+ }
+}
+
+UnknownFieldSet::iterator UnknownFieldSet::begin() {
+ if (internal_ == NULL) return kEmptyIterator;
+
+ UnknownFieldSet::iterator result(internal_->fields_.begin(),
+ &internal_->fields_);
+ result.AdvanceToNonEmpty();
+ return result;
+}
+
+UnknownFieldSet::const_iterator UnknownFieldSet::begin() const {
+ if (internal_ == NULL) return kEmptyIterator;
+
+ UnknownFieldSet::const_iterator result(internal_->fields_.begin(),
+ &internal_->fields_);
+ result.AdvanceToNonEmpty();
+ return result;
+}
+
UnknownField::UnknownField(int number)
: number_(number),
index_(-1) {
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h
index 55eec6e2..f17012df 100644
--- a/src/google/protobuf/unknown_field_set.h
+++ b/src/google/protobuf/unknown_field_set.h
@@ -70,6 +70,13 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet {
void Clear();
// Is this set empty?
+ //
+ // Note that this is equivalent to field_count() == 0 but is NOT necessarily
+ // equivalent to begin() == end(). The iterator class skips fields which are
+ // themselves empty, so if field_count() is non-zero but field(i)->empty() is
+ // true for all i, then begin() will be equal to end() but empty() will return
+ // false. This inconsistency almost never occurs in practice because typical
+ // code does not add empty fields to an UnknownFieldSet.
inline bool empty() const;
// Merge the contents of some other UnknownFieldSet with this one.
@@ -78,6 +85,117 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet {
// Swaps the contents of some other UnknownFieldSet with this one.
inline void Swap(UnknownFieldSet* x);
+ // Find a field by field number. Returns NULL if not found.
+ const UnknownField* FindFieldByNumber(int number) const;
+
+ // Add a field by field number. If the field number already exists, returns
+ // the existing UnknownField.
+ UnknownField* AddField(int number);
+
+ // Computes (an estimate of) the total number of bytes currently used for
+ // storing the unknown fields in memory. Does NOT include
+ // sizeof(*this) in the calculation.
+ int SpaceUsedExcludingSelf() const;
+
+ // Version of SpaceUsed() including sizeof(*this).
+ int SpaceUsed() const;
+
+ // STL-style iteration ---------------------------------------------
+ // These iterate over the non-empty UnknownFields in order by field
+ // number. All iterators are invalidated whenever the UnknownFieldSet
+ // is modified.
+
+ class const_iterator;
+
+ class LIBPROTOBUF_EXPORT iterator {
+ public:
+ iterator() {}
+
+ bool operator==(const iterator& other) {
+ return inner_iterator_ == other.inner_iterator_;
+ }
+ bool operator!=(const iterator& other) {
+ return inner_iterator_ != other.inner_iterator_;
+ }
+
+ UnknownField& operator*() { return *inner_iterator_->second; }
+ UnknownField* operator->() { return inner_iterator_->second; }
+ iterator& operator++() {
+ ++inner_iterator_;
+ AdvanceToNonEmpty();
+ return *this;
+ }
+ iterator operator++(int) {
+ iterator copy(*this);
+ ++*this;
+ return copy;
+ }
+
+ private:
+ friend class UnknownFieldSet;
+ friend class LIBPROTOBUF_EXPORT UnknownFieldSet::const_iterator;
+ iterator(map<int, UnknownField*>::iterator inner_iterator,
+ map<int, UnknownField*>* inner_map)
+ : inner_iterator_(inner_iterator), inner_map_(inner_map) {}
+
+ void AdvanceToNonEmpty();
+
+ map<int, UnknownField*>::iterator inner_iterator_;
+ map<int, UnknownField*>* inner_map_;
+ };
+
+ class LIBPROTOBUF_EXPORT const_iterator {
+ public:
+ const_iterator() {}
+ const_iterator(const iterator& other)
+ : inner_iterator_(other.inner_iterator_), inner_map_(other.inner_map_) {}
+
+ bool operator==(const const_iterator& other) {
+ return inner_iterator_ == other.inner_iterator_;
+ }
+ bool operator!=(const const_iterator& other) {
+ return inner_iterator_ != other.inner_iterator_;
+ }
+
+ UnknownField& operator*() { return *inner_iterator_->second; }
+ UnknownField* operator->() { return inner_iterator_->second; }
+ const_iterator& operator++() {
+ ++inner_iterator_;
+ AdvanceToNonEmpty();
+ return *this;
+ }
+ const_iterator operator++(int) {
+ const_iterator copy(*this);
+ ++*this;
+ return copy;
+ }
+
+ private:
+ friend class UnknownFieldSet;
+ const_iterator(map<int, UnknownField*>::const_iterator inner_iterator,
+ const map<int, UnknownField*>* inner_map)
+ : inner_iterator_(inner_iterator), inner_map_(inner_map) {}
+
+ void AdvanceToNonEmpty();
+
+ map<int, UnknownField*>::const_iterator inner_iterator_;
+ const map<int, UnknownField*>* inner_map_;
+ };
+
+ iterator begin();
+ iterator end() {
+ return internal_ == NULL ? kEmptyIterator :
+ iterator(internal_->fields_.end(), &internal_->fields_);
+ }
+ const_iterator begin() const;
+ const_iterator end() const {
+ return internal_ == NULL ? kEmptyConstIterator :
+ const_iterator(internal_->fields_.end(), &internal_->fields_);
+ }
+
+ // Old-style iteration ---------------------------------------------
+ // New code should use begin() and end() rather than these methods.
+
// Returns the number of fields present in the UnknownFieldSet.
inline int field_count() const;
// Get a field in the set, where 0 <= index < field_count(). The fields
@@ -87,13 +205,6 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet {
// 0 <= index < field_count(). The fields appear in arbitrary order.
inline UnknownField* mutable_field(int index);
- // Find a field by field number. Returns NULL if not found.
- const UnknownField* FindFieldByNumber(int number) const;
-
- // Add a field by field number. If the field number already exists, returns
- // the existing UnknownField.
- UnknownField* AddField(int number);
-
// Parsing helpers -------------------------------------------------
// These work exactly like the similarly-named methods of Message.
@@ -105,13 +216,6 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet {
return ParseFromArray(data.data(), data.size());
}
- // Computes (an estimate of) the total number of bytes currently used for
- // storing the unknown fields in memory. Does NOT include
- // sizeof(*this) in the calculation.
- int SpaceUsedExcludingSelf() const;
- // Version of SpaceUsed() including sizeof(*this).
- int SpaceUsed() const;
-
private:
// "Active" fields are ones which have been added since the last time Clear()
// was called. Inactive fields are objects we are keeping around incase
@@ -139,6 +243,11 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet {
// Don't keep more inactive fields than this.
static const int kMaxInactiveFields = 100;
+ // Used by begin() and end() when internal_ is NULL.
+ static Internal::FieldMap kEmptyMap;
+ static const iterator kEmptyIterator;
+ static const const_iterator kEmptyConstIterator;
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet);
};
@@ -160,6 +269,9 @@ class LIBPROTOBUF_EXPORT UnknownField {
// Clears all fields.
void Clear();
+ // Is this field empty? (I.e. all of the *_size() methods return zero.)
+ inline bool empty() const;
+
// Merge the contents of some other UnknownField with this one. For each
// wire type, the values are simply concatenated.
void MergeFrom(const UnknownField& other);
@@ -256,6 +368,14 @@ inline UnknownField* UnknownFieldSet::mutable_field(int index) {
return internal_->active_fields_[index];
}
+inline bool UnknownField::empty() const {
+ return varint_.size() == 0 &&
+ fixed32_.size() == 0 &&
+ fixed64_.size() == 0 &&
+ length_delimited_.size() == 0 &&
+ group_.size() == 0;
+}
+
inline int UnknownField::number() const { return number_; }
inline int UnknownField::index () const { return index_; }
@@ -322,8 +442,8 @@ inline UnknownFieldSet* UnknownField::add_group() {
}
inline void UnknownField::clear_varint () { varint_.Clear(); }
-inline void UnknownField::clear_fixed32() { varint_.Clear(); }
-inline void UnknownField::clear_fixed64() { varint_.Clear(); }
+inline void UnknownField::clear_fixed32() { fixed32_.Clear(); }
+inline void UnknownField::clear_fixed64() { fixed64_.Clear(); }
inline void UnknownField::clear_length_delimited() {
length_delimited_.Clear();
}
diff --git a/src/google/protobuf/unknown_field_set_unittest.cc b/src/google/protobuf/unknown_field_set_unittest.cc
index c7e78b23..0a75af9f 100644
--- a/src/google/protobuf/unknown_field_set_unittest.cc
+++ b/src/google/protobuf/unknown_field_set_unittest.cc
@@ -516,6 +516,92 @@ TEST_F(UnknownFieldSetTest, SpaceUsed) {
EXPECT_EQ(expected_size, unknown_fields.SpaceUsed());
}
+TEST_F(UnknownFieldSetTest, Empty) {
+ UnknownFieldSet unknown_fields;
+ EXPECT_TRUE(unknown_fields.empty());
+ unknown_fields.AddField(6)->add_varint(123);
+ EXPECT_FALSE(unknown_fields.empty());
+ unknown_fields.Clear();
+ EXPECT_TRUE(unknown_fields.empty());
+}
+
+TEST_F(UnknownFieldSetTest, FieldEmpty) {
+ UnknownFieldSet unknown_fields;
+ UnknownField* field = unknown_fields.AddField(1);
+
+ EXPECT_TRUE(field->empty());
+
+ field->add_varint(1);
+ EXPECT_FALSE(field->empty());
+ field->Clear();
+ EXPECT_TRUE(field->empty());
+
+ field->add_fixed32(1);
+ EXPECT_FALSE(field->empty());
+ field->Clear();
+ EXPECT_TRUE(field->empty());
+
+ field->add_fixed64(1);
+ EXPECT_FALSE(field->empty());
+ field->Clear();
+ EXPECT_TRUE(field->empty());
+
+ field->add_length_delimited("foo");
+ EXPECT_FALSE(field->empty());
+ field->Clear();
+ EXPECT_TRUE(field->empty());
+
+ field->add_group();
+ EXPECT_FALSE(field->empty());
+ field->Clear();
+ EXPECT_TRUE(field->empty());
+}
+
+TEST_F(UnknownFieldSetTest, Iterator) {
+ UnknownFieldSet unknown_fields;
+ EXPECT_TRUE(unknown_fields.begin() == unknown_fields.end());
+
+ // Populate the UnknownFieldSet with some inactive fields by adding some
+ // fields and then clearing.
+ unknown_fields.AddField(6);
+ unknown_fields.AddField(4);
+ unknown_fields.Clear();
+
+ // Add a bunch of "active" fields.
+ UnknownField* a = unknown_fields.AddField(5);
+ unknown_fields.AddField(3);
+ unknown_fields.AddField(9);
+ unknown_fields.AddField(1);
+ UnknownField* b = unknown_fields.AddField(2);
+
+ // Only make some of them non-empty.
+ a->add_varint(1);
+ b->add_length_delimited("foo");
+
+ // Iterate!
+ {
+ UnknownFieldSet::iterator iter = unknown_fields.begin();
+ ASSERT_TRUE(iter != unknown_fields.end());
+ EXPECT_EQ(b, &*iter);
+ ++iter;
+ ASSERT_TRUE(iter != unknown_fields.end());
+ EXPECT_EQ(a, &*iter);
+ ++iter;
+ EXPECT_TRUE(iter == unknown_fields.end());
+ }
+
+ {
+ UnknownFieldSet::const_iterator iter = unknown_fields.begin();
+ ASSERT_TRUE(iter != unknown_fields.end());
+ EXPECT_EQ(b, &*iter);
+ ++iter;
+ ASSERT_TRUE(iter != unknown_fields.end());
+ EXPECT_EQ(a, &*iter);
+ ++iter;
+ EXPECT_TRUE(iter == unknown_fields.end());
+ }
+}
+
} // namespace
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc
index 99ea619b..aeea3ccb 100644
--- a/src/google/protobuf/wire_format.cc
+++ b/src/google/protobuf/wire_format.cc
@@ -369,93 +369,155 @@ bool WireFormat::ParseAndMergeField(
const Reflection* message_reflection = message->GetReflection();
if (field == NULL ||
- GetTagWireType(tag) != WireTypeForFieldType(field->type())) {
+ GetTagWireType(tag) != WireTypeForField(field)) {
// We don't recognize this field. Either the field number is unknown
// or the wire type doesn't match. Put it in our unknown field set.
return SkipField(input, tag,
message_reflection->MutableUnknownFields(message));
}
- switch (field->type()) {
-#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE, CPPTYPE_METHOD) \
- case FieldDescriptor::TYPE_##TYPE: { \
- CPPTYPE value; \
- if (!Read##TYPE_METHOD(input, &value)) return false; \
- if (field->is_repeated()) { \
- message_reflection->Add##CPPTYPE_METHOD(message, field, value); \
- } else { \
- message_reflection->Set##CPPTYPE_METHOD(message, field, value); \
- } \
- break; \
- }
-
- HANDLE_TYPE( INT32, Int32, int32, Int32)
- HANDLE_TYPE( INT64, Int64, int64, Int64)
- HANDLE_TYPE(SINT32, SInt32, int32, Int32)
- HANDLE_TYPE(SINT64, SInt64, int64, Int64)
- HANDLE_TYPE(UINT32, UInt32, uint32, UInt32)
- HANDLE_TYPE(UINT64, UInt64, uint64, UInt64)
-
- HANDLE_TYPE( FIXED32, Fixed32, uint32, UInt32)
- HANDLE_TYPE( FIXED64, Fixed64, uint64, UInt64)
- HANDLE_TYPE(SFIXED32, SFixed32, int32, Int32)
- HANDLE_TYPE(SFIXED64, SFixed64, int64, Int64)
-
- HANDLE_TYPE(FLOAT , Float , float , Float )
- HANDLE_TYPE(DOUBLE, Double, double, Double)
-
- HANDLE_TYPE(BOOL, Bool, bool, Bool)
-
- HANDLE_TYPE(STRING, String, string, String)
- HANDLE_TYPE(BYTES, Bytes, string, String)
+ if (field->options().packed()) {
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ io::CodedInputStream::Limit limit = input->PushLimit(length);
-#undef HANDLE_TYPE
+ switch (field->type()) {
+#define HANDLE_PACKED_TYPE(TYPE, TYPE_METHOD, CPPTYPE, CPPTYPE_METHOD) \
+ case FieldDescriptor::TYPE_##TYPE: { \
+ while (input->BytesUntilLimit() > 0) { \
+ CPPTYPE value; \
+ if (!Read##TYPE_METHOD(input, &value)) return false; \
+ message_reflection->Add##CPPTYPE_METHOD(message, field, value); \
+ } \
+ break; \
+ }
- case FieldDescriptor::TYPE_ENUM: {
- int value;
- if (!ReadEnum(input, &value)) return false;
- const EnumValueDescriptor* enum_value =
- field->enum_type()->FindValueByNumber(value);
- if (enum_value != NULL) {
- if (field->is_repeated()) {
- message_reflection->AddEnum(message, field, enum_value);
- } else {
- message_reflection->SetEnum(message, field, enum_value);
+ HANDLE_PACKED_TYPE( INT32, Int32, int32, Int32)
+ HANDLE_PACKED_TYPE( INT64, Int64, int64, Int64)
+ HANDLE_PACKED_TYPE(SINT32, SInt32, int32, Int32)
+ HANDLE_PACKED_TYPE(SINT64, SInt64, int64, Int64)
+ HANDLE_PACKED_TYPE(UINT32, UInt32, uint32, UInt32)
+ HANDLE_PACKED_TYPE(UINT64, UInt64, uint64, UInt64)
+
+ HANDLE_PACKED_TYPE( FIXED32, Fixed32, uint32, UInt32)
+ HANDLE_PACKED_TYPE( FIXED64, Fixed64, uint64, UInt64)
+ HANDLE_PACKED_TYPE(SFIXED32, SFixed32, int32, Int32)
+ HANDLE_PACKED_TYPE(SFIXED64, SFixed64, int64, Int64)
+
+ HANDLE_PACKED_TYPE(FLOAT , Float , float , Float )
+ HANDLE_PACKED_TYPE(DOUBLE, Double, double, Double)
+
+ HANDLE_PACKED_TYPE(BOOL, Bool, bool, Bool)
+#undef HANDLE_PACKED_TYPE
+
+ case FieldDescriptor::TYPE_ENUM: {
+ while (input->BytesUntilLimit() > 0) {
+ int value;
+ if (!ReadEnum(input, &value)) return false;
+ const EnumValueDescriptor* enum_value =
+ field->enum_type()->FindValueByNumber(value);
+ if (enum_value != NULL) {
+ message_reflection->AddEnum(message, field, enum_value);
+ }
}
- } else {
- // The enum value is not one of the known values. Add it to the
- // UnknownFieldSet.
- int64 sign_extended_value = static_cast<int64>(value);
- message_reflection->MutableUnknownFields(message)
- ->AddField(GetTagFieldNumber(tag))
- ->add_varint(sign_extended_value);
+
+ break;
}
- break;
+
+ case FieldDescriptor::TYPE_STRING:
+ case FieldDescriptor::TYPE_GROUP:
+ case FieldDescriptor::TYPE_MESSAGE:
+ case FieldDescriptor::TYPE_BYTES:
+ // Can't have packed fields of these types: these should be caught by
+ // the protocol compiler.
+ return false;
+ break;
}
+ input->PopLimit(limit);
+ } else {
+ switch (field->type()) {
+#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE, CPPTYPE_METHOD) \
+ case FieldDescriptor::TYPE_##TYPE: { \
+ CPPTYPE value; \
+ if (!Read##TYPE_METHOD(input, &value)) return false; \
+ if (field->is_repeated()) { \
+ message_reflection->Add##CPPTYPE_METHOD(message, field, value); \
+ } else { \
+ message_reflection->Set##CPPTYPE_METHOD(message, field, value); \
+ } \
+ break; \
+ }
+
+ HANDLE_TYPE( INT32, Int32, int32, Int32)
+ HANDLE_TYPE( INT64, Int64, int64, Int64)
+ HANDLE_TYPE(SINT32, SInt32, int32, Int32)
+ HANDLE_TYPE(SINT64, SInt64, int64, Int64)
+ HANDLE_TYPE(UINT32, UInt32, uint32, UInt32)
+ HANDLE_TYPE(UINT64, UInt64, uint64, UInt64)
- case FieldDescriptor::TYPE_GROUP: {
- Message* sub_message;
- if (field->is_repeated()) {
- sub_message = message_reflection->AddMessage(message, field);
- } else {
- sub_message = message_reflection->MutableMessage(message, field);
+ HANDLE_TYPE( FIXED32, Fixed32, uint32, UInt32)
+ HANDLE_TYPE( FIXED64, Fixed64, uint64, UInt64)
+ HANDLE_TYPE(SFIXED32, SFixed32, int32, Int32)
+ HANDLE_TYPE(SFIXED64, SFixed64, int64, Int64)
+
+ HANDLE_TYPE(FLOAT , Float , float , Float )
+ HANDLE_TYPE(DOUBLE, Double, double, Double)
+
+ HANDLE_TYPE(BOOL, Bool, bool, Bool)
+
+ HANDLE_TYPE(STRING, String, string, String)
+ HANDLE_TYPE(BYTES, Bytes, string, String)
+
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::TYPE_ENUM: {
+ int value;
+ if (!ReadEnum(input, &value)) return false;
+ const EnumValueDescriptor* enum_value =
+ field->enum_type()->FindValueByNumber(value);
+ if (enum_value != NULL) {
+ if (field->is_repeated()) {
+ message_reflection->AddEnum(message, field, enum_value);
+ } else {
+ message_reflection->SetEnum(message, field, enum_value);
+ }
+ } else {
+ // The enum value is not one of the known values. Add it to the
+ // UnknownFieldSet.
+ int64 sign_extended_value = static_cast<int64>(value);
+ message_reflection->MutableUnknownFields(message)
+ ->AddField(GetTagFieldNumber(tag))
+ ->add_varint(sign_extended_value);
+ }
+ break;
}
- if (!ReadGroup(GetTagFieldNumber(tag), input, sub_message)) return false;
- break;
- }
- case FieldDescriptor::TYPE_MESSAGE: {
- Message* sub_message;
- if (field->is_repeated()) {
- sub_message = message_reflection->AddMessage(message, field);
- } else {
- sub_message = message_reflection->MutableMessage(message, field);
+ case FieldDescriptor::TYPE_GROUP: {
+ Message* sub_message;
+ if (field->is_repeated()) {
+ sub_message = message_reflection->AddMessage(message, field);
+ } else {
+ sub_message = message_reflection->MutableMessage(message, field);
+ }
+
+ if (!ReadGroup(GetTagFieldNumber(tag), input, sub_message))
+ return false;
+ break;
}
- if (!ReadMessage(input, sub_message)) return false;
- break;
+ case FieldDescriptor::TYPE_MESSAGE: {
+ Message* sub_message;
+ if (field->is_repeated()) {
+ sub_message = message_reflection->AddMessage(message, field);
+ } else {
+ sub_message = message_reflection->MutableMessage(message, field);
+ }
+
+ if (!ReadMessage(input, sub_message)) return false;
+ break;
+ }
}
}
@@ -602,8 +664,53 @@ bool WireFormat::SerializeFieldWithCachedSizes(
count = 1;
}
+ const bool is_packed = field->options().packed();
+ if (is_packed && count > 0) {
+ if (!WriteTag(field->number(), WIRETYPE_LENGTH_DELIMITED, output))
+ return false;
+ const int data_size = FieldDataOnlyByteSize(field, message);
+ if (!output->WriteVarint32(data_size)) return false;
+ }
+
for (int j = 0; j < count; j++) {
switch (field->type()) {
+#define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \
+ case FieldDescriptor::TYPE_##TYPE: { \
+ const CPPTYPE value = field->is_repeated() ? \
+ message_reflection->GetRepeated##CPPTYPE_METHOD( \
+ message, field, j) : \
+ message_reflection->Get##CPPTYPE_METHOD( \
+ message, field); \
+ if (is_packed) { \
+ if (!Write##TYPE_METHOD##NoTag(value, output)) { \
+ return false; \
+ } \
+ } else { \
+ if (!Write##TYPE_METHOD(field->number(), value, output)) { \
+ return false; \
+ } \
+ } \
+ break; \
+ }
+
+ HANDLE_PRIMITIVE_TYPE( INT32, int32, Int32, Int32)
+ HANDLE_PRIMITIVE_TYPE( INT64, int64, Int64, Int64)
+ HANDLE_PRIMITIVE_TYPE(SINT32, int32, SInt32, Int32)
+ HANDLE_PRIMITIVE_TYPE(SINT64, int64, SInt64, Int64)
+ HANDLE_PRIMITIVE_TYPE(UINT32, uint32, UInt32, UInt32)
+ HANDLE_PRIMITIVE_TYPE(UINT64, uint64, UInt64, UInt64)
+
+ HANDLE_PRIMITIVE_TYPE( FIXED32, uint32, Fixed32, UInt32)
+ HANDLE_PRIMITIVE_TYPE( FIXED64, uint64, Fixed64, UInt64)
+ HANDLE_PRIMITIVE_TYPE(SFIXED32, int32, SFixed32, Int32)
+ HANDLE_PRIMITIVE_TYPE(SFIXED64, int64, SFixed64, Int64)
+
+ HANDLE_PRIMITIVE_TYPE(FLOAT , float , Float , Float )
+ HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double)
+
+ HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool)
+#undef HANDLE_PRIMITIVE_TYPE
+
#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \
case FieldDescriptor::TYPE_##TYPE: \
if (!Write##TYPE_METHOD( \
@@ -617,23 +724,6 @@ bool WireFormat::SerializeFieldWithCachedSizes(
} \
break;
- HANDLE_TYPE( INT32, Int32, Int32)
- HANDLE_TYPE( INT64, Int64, Int64)
- HANDLE_TYPE(SINT32, SInt32, Int32)
- HANDLE_TYPE(SINT64, SInt64, Int64)
- HANDLE_TYPE(UINT32, UInt32, UInt32)
- HANDLE_TYPE(UINT64, UInt64, UInt64)
-
- HANDLE_TYPE( FIXED32, Fixed32, UInt32)
- HANDLE_TYPE( FIXED64, Fixed64, UInt64)
- HANDLE_TYPE(SFIXED32, SFixed32, Int32)
- HANDLE_TYPE(SFIXED64, SFixed64, Int64)
-
- HANDLE_TYPE(FLOAT , Float , Float )
- HANDLE_TYPE(DOUBLE, Double, Double)
-
- HANDLE_TYPE(BOOL, Bool, Bool)
-
HANDLE_TYPE(GROUP , Group , Message)
HANDLE_TYPE(MESSAGE, Message, Message)
#undef HANDLE_TYPE
@@ -642,7 +732,12 @@ bool WireFormat::SerializeFieldWithCachedSizes(
const EnumValueDescriptor* value = field->is_repeated() ?
message_reflection->GetRepeatedEnum(message, field, j) :
message_reflection->GetEnum(message, field);
- if (!WriteEnum(field->number(), value->number(), output)) return false;
+ if (is_packed) {
+ if (!WriteEnumNoTag(value->number(), output)) return false;
+ } else {
+ if (!WriteEnum(field->number(), value->number(), output))
+ return false;
+ }
break;
}
@@ -736,36 +831,60 @@ int WireFormat::FieldByteSize(
return MessageSetItemByteSize(field, message);
}
- int our_size = 0;
-
int count = 0;
-
if (field->is_repeated()) {
count = message_reflection->FieldSize(message, field);
} else if (message_reflection->HasField(message, field)) {
count = 1;
}
- our_size += count * TagSize(field->number(), field->type());
+ const int data_size = FieldDataOnlyByteSize(field, message);
+ int our_size = data_size;
+ if (field->options().packed()) {
+ if (data_size > 0) {
+ // Packed fields get serialized like a string, not their native type.
+ // Technically this doesn't really matter; the size only changes if it's
+ // a GROUP
+ our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING);
+ our_size += io::CodedOutputStream::VarintSize32(data_size);
+ }
+ } else {
+ our_size += count * TagSize(field->number(), field->type());
+ }
+ return our_size;
+}
+
+int WireFormat::FieldDataOnlyByteSize(
+ const FieldDescriptor* field,
+ const Message& message) {
+ const Reflection* message_reflection = message.GetReflection();
+
+ int count = 0;
+ if (field->is_repeated()) {
+ count = message_reflection->FieldSize(message, field);
+ } else if (message_reflection->HasField(message, field)) {
+ count = 1;
+ }
+ int data_size = 0;
switch (field->type()) {
#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \
case FieldDescriptor::TYPE_##TYPE: \
if (field->is_repeated()) { \
for (int j = 0; j < count; j++) { \
- our_size += TYPE_METHOD##Size( \
+ data_size += TYPE_METHOD##Size( \
message_reflection->GetRepeated##CPPTYPE_METHOD( \
message, field, j)); \
} \
} else { \
- our_size += TYPE_METHOD##Size( \
+ data_size += TYPE_METHOD##Size( \
message_reflection->Get##CPPTYPE_METHOD(message, field)); \
} \
break;
#define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD) \
case FieldDescriptor::TYPE_##TYPE: \
- our_size += count * k##TYPE_METHOD##Size; \
+ data_size += count * k##TYPE_METHOD##Size; \
break;
HANDLE_TYPE( INT32, Int32, Int32)
@@ -793,11 +912,11 @@ int WireFormat::FieldByteSize(
case FieldDescriptor::TYPE_ENUM: {
if (field->is_repeated()) {
for (int j = 0; j < count; j++) {
- our_size += EnumSize(
+ data_size += EnumSize(
message_reflection->GetRepeatedEnum(message, field, j)->number());
}
} else {
- our_size += EnumSize(
+ data_size += EnumSize(
message_reflection->GetEnum(message, field)->number());
}
break;
@@ -813,13 +932,12 @@ int WireFormat::FieldByteSize(
message_reflection->GetRepeatedStringReference(
message, field, j, &scratch) :
message_reflection->GetStringReference(message, field, &scratch);
- our_size += StringSize(value);
+ data_size += StringSize(value);
}
break;
}
}
-
- return our_size;
+ return data_size;
}
int WireFormat::MessageSetItemByteSize(
diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h
index 06f20d2a..9004caaa 100644
--- a/src/google/protobuf/wire_format.h
+++ b/src/google/protobuf/wire_format.h
@@ -163,13 +163,20 @@ class LIBPROTOBUF_EXPORT WireFormat {
static inline WireType WireTypeForFieldType(FieldDescriptor::Type type) {
return kWireTypeForFieldType[type];
}
+ // This is different from WireTypeForFieldType(field->type()) in the case of
+ // packed repeated fields.
+ static inline WireType WireTypeForField(const FieldDescriptor* field);
// Number of bits in a tag which identify the wire type.
static const int kTagTypeBits = 3;
// Mask for those bits.
static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1;
- // Helper functions for encoding and decoding tags. (Inlined below.)
+ // Helper functions for encoding and decoding tags. (Inlined below and in
+ // _inl.h)
+ //
+ // This is different from MakeTag(field->number(), field->type()) in the case
+ // of packed repeated fields.
static uint32 MakeTag(const FieldDescriptor* field);
static uint32 MakeTag(int field_number, WireType type);
static WireType GetTagWireType(uint32 tag);
@@ -258,10 +265,27 @@ class LIBPROTOBUF_EXPORT WireFormat {
template<typename MessageType>
static inline bool ReadMessageNoVirtual(input, MessageType* value);
- // Write a tag. The Write*() functions automatically include the tag, so
- // normally there's no need to call this.
+ // Write a tag. The Write*() functions typically include the tag, so
+ // normally there's no need to call this unless using the Write*NoTag()
+ // variants.
static inline bool WriteTag(field_number, WireType type, output) INL;
+ // Write fields, without tags.
+ static inline bool WriteInt32NoTag (int32 value, output) INL;
+ static inline bool WriteInt64NoTag (int64 value, output) INL;
+ static inline bool WriteUInt32NoTag (uint32 value, output) INL;
+ static inline bool WriteUInt64NoTag (uint64 value, output) INL;
+ static inline bool WriteSInt32NoTag (int32 value, output) INL;
+ static inline bool WriteSInt64NoTag (int64 value, output) INL;
+ static inline bool WriteFixed32NoTag (uint32 value, output) INL;
+ static inline bool WriteFixed64NoTag (uint64 value, output) INL;
+ static inline bool WriteSFixed32NoTag(int32 value, output) INL;
+ static inline bool WriteSFixed64NoTag(int64 value, output) INL;
+ static inline bool WriteFloatNoTag (float value, output) INL;
+ static inline bool WriteDoubleNoTag (double value, output) INL;
+ static inline bool WriteBoolNoTag (bool value, output) INL;
+ static inline bool WriteEnumNoTag (int value, output) INL;
+
// Write fields, including tags.
static inline bool WriteInt32 (field_number, int32 value, output) INL;
static inline bool WriteInt64 (field_number, int64 value, output) INL;
@@ -355,6 +379,14 @@ class LIBPROTOBUF_EXPORT WireFormat {
const FieldDescriptor* field,
const Message& message);
+ // Computes the byte size of a field, excluding tags. For packed fields, it
+ // only includes the size of the raw data, and not the size of the total
+ // length, but for other length-delimited types, the size of the length is
+ // included.
+ static int FieldDataOnlyByteSize(
+ const FieldDescriptor* field, // Cannot be NULL
+ const Message& message);
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat);
};
@@ -368,10 +400,6 @@ class LIBPROTOBUF_EXPORT WireFormat {
static_cast<uint32>( \
((FIELD_NUMBER) << ::google::protobuf::internal::WireFormat::kTagTypeBits) | (TYPE))
-inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) {
- return MakeTag(field->number(), WireTypeForFieldType(field->type()));
-}
-
inline uint32 WireFormat::MakeTag(int field_number, WireType type) {
return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type);
}
diff --git a/src/google/protobuf/wire_format_inl.h b/src/google/protobuf/wire_format_inl.h
index 539d8c67..451ac11c 100644
--- a/src/google/protobuf/wire_format_inl.h
+++ b/src/google/protobuf/wire_format_inl.h
@@ -38,6 +38,8 @@
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/wire_format.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/coded_stream.h>
@@ -51,6 +53,19 @@ namespace google {
namespace protobuf {
namespace internal {
+inline WireFormat::WireType WireFormat::WireTypeForField(
+ const FieldDescriptor* field) {
+ if (field->options().packed()) {
+ return WIRETYPE_LENGTH_DELIMITED;
+ } else {
+ return WireTypeForFieldType(field->type());
+ }
+}
+
+inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) {
+ return MakeTag(field->number(), WireTypeForField(field));
+}
+
inline bool WireFormat::ReadInt32(io::CodedInputStream* input, int32* value) {
uint32 temp;
if (!input->ReadVarint32(&temp)) return false;
@@ -210,75 +225,132 @@ inline bool WireFormat::WriteTag(int field_number, WireType type,
return output->WriteTag(MakeTag(field_number, type));
}
+inline bool WireFormat::WriteInt32NoTag(int32 value,
+ io::CodedOutputStream* output) {
+ return output->WriteVarint32SignExtended(value);
+}
+inline bool WireFormat::WriteInt64NoTag(int64 value,
+ io::CodedOutputStream* output) {
+ return output->WriteVarint64(static_cast<uint64>(value));
+}
+inline bool WireFormat::WriteUInt32NoTag(uint32 value,
+ io::CodedOutputStream* output) {
+ return output->WriteVarint32(value);
+}
+inline bool WireFormat::WriteUInt64NoTag(uint64 value,
+ io::CodedOutputStream* output) {
+ return output->WriteVarint64(value);
+}
+inline bool WireFormat::WriteSInt32NoTag(int32 value,
+ io::CodedOutputStream* output) {
+ return output->WriteVarint32(ZigZagEncode32(value));
+}
+inline bool WireFormat::WriteSInt64NoTag(int64 value,
+ io::CodedOutputStream* output) {
+ return output->WriteVarint64(ZigZagEncode64(value));
+}
+inline bool WireFormat::WriteFixed32NoTag(uint32 value,
+ io::CodedOutputStream* output) {
+ return output->WriteLittleEndian32(value);
+}
+inline bool WireFormat::WriteFixed64NoTag(uint64 value,
+ io::CodedOutputStream* output) {
+ return output->WriteLittleEndian64(value);
+}
+inline bool WireFormat::WriteSFixed32NoTag(int32 value,
+ io::CodedOutputStream* output) {
+ return output->WriteLittleEndian32(static_cast<uint32>(value));
+}
+inline bool WireFormat::WriteSFixed64NoTag(int64 value,
+ io::CodedOutputStream* output) {
+ return output->WriteLittleEndian64(static_cast<uint64>(value));
+}
+inline bool WireFormat::WriteFloatNoTag(float value,
+ io::CodedOutputStream* output) {
+ return output->WriteLittleEndian32(EncodeFloat(value));
+}
+inline bool WireFormat::WriteDoubleNoTag(double value,
+ io::CodedOutputStream* output) {
+ return output->WriteLittleEndian64(EncodeDouble(value));
+}
+inline bool WireFormat::WriteBoolNoTag(bool value,
+ io::CodedOutputStream* output) {
+ return output->WriteVarint32(value ? 1 : 0);
+}
+inline bool WireFormat::WriteEnumNoTag(int value,
+ io::CodedOutputStream* output) {
+ return output->WriteVarint32SignExtended(value);
+}
+
inline bool WireFormat::WriteInt32(int field_number, int32 value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_VARINT, output) &&
- output->WriteVarint32SignExtended(value);
+ WriteInt32NoTag(value, output);
}
inline bool WireFormat::WriteInt64(int field_number, int64 value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_VARINT, output) &&
- output->WriteVarint64(static_cast<uint64>(value));
+ WriteInt64NoTag(value, output);
}
inline bool WireFormat::WriteUInt32(int field_number, uint32 value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_VARINT, output) &&
- output->WriteVarint32(value);
+ WriteUInt32NoTag(value, output);
}
inline bool WireFormat::WriteUInt64(int field_number, uint64 value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_VARINT, output) &&
- output->WriteVarint64(value);
+ WriteUInt64NoTag(value, output);
}
inline bool WireFormat::WriteSInt32(int field_number, int32 value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_VARINT, output) &&
- output->WriteVarint32(ZigZagEncode32(value));
+ WriteSInt32NoTag(value, output);
}
inline bool WireFormat::WriteSInt64(int field_number, int64 value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_VARINT, output) &&
- output->WriteVarint64(ZigZagEncode64(value));
+ WriteSInt64NoTag(value, output);
}
inline bool WireFormat::WriteFixed32(int field_number, uint32 value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_FIXED32, output) &&
- output->WriteLittleEndian32(value);
+ WriteFixed32NoTag(value, output);
}
inline bool WireFormat::WriteFixed64(int field_number, uint64 value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_FIXED64, output) &&
- output->WriteLittleEndian64(value);
+ WriteFixed64NoTag(value, output);
}
inline bool WireFormat::WriteSFixed32(int field_number, int32 value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_FIXED32, output) &&
- output->WriteLittleEndian32(static_cast<uint32>(value));
+ WriteSFixed32NoTag(value, output);
}
inline bool WireFormat::WriteSFixed64(int field_number, int64 value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_FIXED64, output) &&
- output->WriteLittleEndian64(static_cast<uint64>(value));
+ WriteSFixed64NoTag(value, output);
}
inline bool WireFormat::WriteFloat(int field_number, float value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_FIXED32, output) &&
- output->WriteLittleEndian32(EncodeFloat(value));
+ WriteFloatNoTag(value, output);
}
inline bool WireFormat::WriteDouble(int field_number, double value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_FIXED64, output) &&
- output->WriteLittleEndian64(EncodeDouble(value));
+ WriteDoubleNoTag(value, output);
}
inline bool WireFormat::WriteBool(int field_number, bool value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_VARINT, output) &&
- output->WriteVarint32(value ? 1 : 0);
+ WriteBoolNoTag(value, output);
}
inline bool WireFormat::WriteEnum(int field_number, int value,
io::CodedOutputStream* output) {
return WriteTag(field_number, WIRETYPE_VARINT, output) &&
- output->WriteVarint32SignExtended(value);
+ WriteEnumNoTag(value, output);
}
inline bool WireFormat::WriteString(int field_number, const string& value,
diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc
index 43dccd1a..5a7c6c23 100644
--- a/src/google/protobuf/wire_format_unittest.cc
+++ b/src/google/protobuf/wire_format_unittest.cc
@@ -90,6 +90,40 @@ TEST(WireFormatTest, ParseExtensions) {
TestUtil::ExpectAllExtensionsSet(dest);
}
+TEST(WireFormatTest, ParsePacked) {
+ unittest::TestPackedTypes source, dest;
+ string data;
+
+ // Serialize using the generated code.
+ TestUtil::SetPackedFields(&source);
+ source.SerializeToString(&data);
+
+ // Parse using WireFormat.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectPackedFieldsSet(dest);
+}
+
+TEST(WireFormatTest, ParsePackedExtensions) {
+ unittest::TestPackedExtensions source, dest;
+ string data;
+
+ // Serialize using the generated code.
+ TestUtil::SetPackedExtensions(&source);
+ source.SerializeToString(&data);
+
+ // Parse using WireFormat.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectPackedExtensionsSet(dest);
+}
+
TEST(WireFormatTest, ByteSize) {
unittest::TestAllTypes message;
TestUtil::SetAllFields(&message);
@@ -111,6 +145,27 @@ TEST(WireFormatTest, ByteSizeExtensions) {
EXPECT_EQ(0, WireFormat::ByteSize(message));
}
+TEST(WireFormatTest, ByteSizePacked) {
+ unittest::TestPackedTypes message;
+ TestUtil::SetPackedFields(&message);
+
+ EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message));
+ message.Clear();
+ EXPECT_EQ(0, message.ByteSize());
+ EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, ByteSizePackedExtensions) {
+ unittest::TestPackedExtensions message;
+ TestUtil::SetPackedExtensions(&message);
+
+ EXPECT_EQ(message.ByteSize(),
+ WireFormat::ByteSize(message));
+ message.Clear();
+ EXPECT_EQ(0, message.ByteSize());
+ EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
TEST(WireFormatTest, Serialize) {
unittest::TestAllTypes message;
string generated_data;