diff options
Diffstat (limited to 'java')
38 files changed, 770 insertions, 5795 deletions
diff --git a/java/README.txt b/java/README.txt index 1656e59..3ed06a1 100644 --- a/java/README.txt +++ b/java/README.txt @@ -82,184 +82,11 @@ running unit tests. $ protoc --java_out=src/main/java -I../src \ ../src/google/protobuf/descriptor.proto + 3) Compile the code in src/main/java using whatever means you prefer. 4) Install the classes wherever you prefer. -Micro version -============================ - -The runtime and generated code for MICRO_RUNTIME is smaller -because it does not include support for the descriptor, -reflection or extensions. Also, not currently supported -are packed repeated elements nor testing of java_multiple_files. - -To create a jar file for the runtime and run tests invoke -"mvn package -P micro" from the <protobuf-root>/java -directory. The generated jar file is -<protobuf-root>java/target/protobuf-java-2.2.0-micro.jar. - -If you wish to compile the MICRO_RUTIME your self, place -the 7 files below, in <root>/com/google/protobuf and -create a jar file for use with your code and the generated -code: - -ByteStringMicro.java -CodedInputStreamMicro.java -CodedOutputStreamMicro.java -InvalidProtocolBufferException.java -MessageMicro.java -StringUtf8Micro.java -WireFormatMicro.java - -If you wish to change on the code generator it is located -in /src/google/protobuf/compiler/javamicro. - -To generate code for the MICRO_RUNTIME invoke protoc with ---javamicro_out command line parameter. javamciro_out takes -a series of optional sub-parameters separated by comma's -and a final parameter, with a colon separator, which defines -the source directory. Sub-paraemeters begin with a name -followed by an equal and if that sub-parameter has multiple -parameters they are seperated by "|". The command line options -are: - -opt -> speed or space -java_use_vector -> true or false -java_package -> <file-name>|<package-name> -java_outer_classname -> <file-name>|<package-name> - -opt: - This change the code generation to optimize for speed, - opt=speed, or space, opt=space. When opt=speed this - changes the code generation for strings to use - StringUtf8Micro which eliminates multiple conversions - of the string to utf8. The default value is opt=space. - -java_use_vector: - Is a boolean flag either java_use_vector=true or - java_use_vector=false. When java_use_vector=true the - code generated for repeated elements uses - java.util.Vector and when java_use_vector=false the - java.util.ArrayList<> is used. When java.util.Vector - is used the code must be compiled with Java 1.3 and - when ArrayList is used Java 1.5 or above must be used. - The using javac the source parameter maybe used to - control the version of the srouce: "javac -source 1.3". - You can also change the <source> xml element for the - maven-compiler-plugin. Below is for 1.5 sources: - - <plugin> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <source>1.5</source> - <target>1.5</target> - </configuration> - </plugin> - - When compiling for 1.5 java_use_vector=false or not - present where the default value is false. - - And below would be for 1.3 sources note when changing - to 1.3 you must also set java_use_vector=true: - - <plugin> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <source>1.3</source> - <target>1.5</target> - </configuration> - </plugin> - -java_package: - The allows setting/overriding the java_package option - and associates allows a package name for a file to - be specified on the command line. Overriding any - "option java_package xxxx" in the file. The default - if not present is to use the value from the package - statment or "option java_package xxxx" in the file. - -java_outer_classname: - This allows the setting/overriding of the outer - class name option and associates a class name - to a file. An outer class name is required and - must be specified if there are multiple messages - in a single proto file either in the proto source - file or on the command line. If not present the - no outer class name will be used. - -Below are a series of examples for clarification of the -various javamicro_out parameters using -src/test/proto/simple-data.proto: - -package testprotobuf; - -message SimpleData { - optional fixed64 id = 1; - optional string description = 2; - optional bool ok = 3 [default = false]; -}; - - -Assuming you've only compiled and not installed protoc and -your current working directory java/, then a simple -command line to compile simple-data would be: - -../src/protoc --javamicro_out=. src/test/proto/simple-data.proto - -This will create testprotobuf/SimpleData.java - -The directory testprotobuf is created because on line 1 -of simple-data.proto is "package testprotobuf;". If you -wanted a different package name you could use the -java_package option command line sub-parameter: - -../src/protoc '--javamicro_out=java_package=src/test/proto/simple-data.proto|my_package:.' src/test/proto/simple-data.proto - -Here you see the new java_package sub-parameter which -itself needs two parameters the file name and the -package name, these are separated by "|". Now you'll -find my_package/SimpleData.java. - -If you wanted to also change the optimization for -speed you'd add opt=speed with the comma seperator -as follows: - -../src/protoc '--javamicro_out=opt=speed,java_package=src/test/proto/simple-data.proto|my_package:.' src/test/proto/simple-data.proto - -Finally if you also wanted an outer class name you'd -do the following: - -../src/protoc '--javamicro_out=opt=speed,java_package=src/test/proto/simple-data.proto|my_package,java_outer_classname=src/test/proto/simple-data.proto|OuterName:.' src/test/proto/simple-data.proto - -Now you'll find my_packate/OuterName.java. - -As mentioned java_package and java_outer_classname -may also be specified in the file. In the example -below we must define java_outer_classname because -there are multiple messages in -src/test/proto/two-messages.proto - -package testmicroruntime; - -option java_package = "com.example"; -option java_outer_classname = "TestMessages"; - -message TestMessage1 { - required int32 id = 1; -} - -message TestMessage2 { - required int32 id = 1; -} - -This could be compiled using: - -../src/protoc --javamicro_out=. src/test/proto/two-message.proto - -With the result will be com/example/TestMessages.java - - Usage ===== diff --git a/java/pom.xml b/java/pom.xml index 5f7dd17..b07f29b 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -10,7 +10,7 @@ </parent> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> - <version>2.2.0</version> + <version>2.3.0</version> <packaging>jar</packaging> <name>Protocol Buffer Java API</name> <description> @@ -96,8 +96,6 @@ <configuration> <tasks> <mkdir dir="target/generated-test-sources" /> - <!--mkdir dir="target/generated-test-sources/opt-space" /--> - <!--mkdir dir="target/generated-test-sources/opt-speed" /--> <exec executable="../src/protoc"> <arg value="--java_out=target/generated-test-sources" /> <arg value="--proto_path=../src" /> @@ -115,21 +113,10 @@ <arg value="../src/google/protobuf/unittest_import_lite.proto" /> <arg value="../src/google/protobuf/unittest_lite_imports_nonlite.proto" /> <arg value="../src/google/protobuf/unittest_enormous_descriptor.proto" /> - </exec> - <exec executable="../src/protoc"> - <arg value="--javamicro_out=opt=speed,java_use_vector=false,java_package=google/protobuf/unittest_import_micro.proto|com.google.protobuf.micro,java_outer_classname=google/protobuf/unittest_import_micro.proto|UnittestImportMicro:target/generated-test-sources" /> - <arg value="--proto_path=../src" /> - <arg value="--proto_path=src/test/java" /> - <arg value="../src/google/protobuf/unittest_micro.proto" /> - <arg value="../src/google/protobuf/unittest_simple_micro.proto" /> - <arg value="../src/google/protobuf/unittest_stringutf8_micro.proto" /> - <arg value="../src/google/protobuf/unittest_recursive_micro.proto" /> - <arg value="../src/google/protobuf/unittest_import_micro.proto" /> + <arg value="../src/google/protobuf/unittest_no_generic_services.proto" /> </exec> </tasks> <testSourceRoot>target/generated-test-sources</testSourceRoot> - <!--testSourceRoot>target/generated-test-sources/opt-space</testSourceRoot--> - <!--testSourceRoot>target/generated-test-sources/opt-speed</testSourceRoot--> </configuration> <goals> <goal>run</goal> @@ -184,48 +171,5 @@ </plugins> </build> </profile> - <profile> - <id>micro</id> - <build> - <plugins> - <plugin> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <includes> - <include>**/MessageMicro.java</include> - <include>**/ByteStringMicro.java</include> - <include>**/CodedInputStreamMicro.java</include> - <include>**/CodedOutputStreamMicro.java</include> - <include>**/InvalidProtocolBufferMicroException.java</include> - <include>**/StringUtf8Micro.java</include> - <include>**/WireFormatMicro.java</include> - </includes> - <testIncludes> - <testInclude>**/MicroTest.java</testInclude> - <testInclude>**/MicroOuterClass.java</testInclude> - <testInclude>**/SimpleMessageMicro.java</testInclude> - <testInclude>**/StringUtf8.java</testInclude> - <testInclude>**/RecursiveMessageMicro.java</testInclude> - <testInclude>**/UnittestImportMicro.java</testInclude> - </testIncludes> - </configuration> - </plugin> - <plugin> - <artifactId>maven-surefire-plugin</artifactId> - <configuration> - <includes> - <include>**/MicroTest.java</include> - </includes> - </configuration> - </plugin> - <plugin> - <artifactId>maven-jar-plugin</artifactId> - <configuration> - <classifier>micro</classifier> - </configuration> - </plugin> - </plugins> - </build> - </profile> </profiles> </project> diff --git a/java/src/main/java/com/google/protobuf/AbstractMessage.java b/java/src/main/java/com/google/protobuf/AbstractMessage.java index e5bdefe..b059bc9 100644 --- a/java/src/main/java/com/google/protobuf/AbstractMessage.java +++ b/java/src/main/java/com/google/protobuf/AbstractMessage.java @@ -311,6 +311,12 @@ public abstract class AbstractMessage extends AbstractMessageLite } else { field = extension.descriptor; defaultInstance = extension.defaultInstance; + if (defaultInstance == null && + field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + throw new IllegalStateException( + "Message-typed extension lacked default instance: " + + field.getFullName()); + } } } else { field = null; @@ -319,15 +325,28 @@ public abstract class AbstractMessage extends AbstractMessageLite field = type.findFieldByNumber(fieldNumber); } - if (field == null || wireType != - FieldSet.getWireFormatForFieldType( - field.getLiteType(), - field.getOptions().getPacked())) { - // Unknown field or wrong wire type. Skip. + boolean unknown = false; + boolean packed = false; + if (field == null) { + unknown = true; // Unknown field. + } else if (wireType == FieldSet.getWireFormatForFieldType( + field.getLiteType(), + false /* isPacked */)) { + packed = false; + } else if (field.isPackable() && + wireType == FieldSet.getWireFormatForFieldType( + field.getLiteType(), + true /* isPacked */)) { + packed = true; + } else { + unknown = true; // Unknown wire type. + } + + if (unknown) { // Unknown field or wrong wire type. Skip. return unknownFields.mergeFieldFrom(tag, input); } - if (field.getOptions().getPacked()) { + if (packed) { final int length = input.readRawVarint32(); final int limit = input.pushLimit(length); if (field.getLiteType() == WireFormat.FieldType.ENUM) { @@ -673,13 +692,13 @@ public abstract class AbstractMessage extends AbstractMessageLite } @Override - public BuilderType mergeDelimitedFrom(final InputStream input) + public boolean mergeDelimitedFrom(final InputStream input) throws IOException { return super.mergeDelimitedFrom(input); } @Override - public BuilderType mergeDelimitedFrom( + public boolean mergeDelimitedFrom( final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException { diff --git a/java/src/main/java/com/google/protobuf/AbstractMessageLite.java b/java/src/main/java/com/google/protobuf/AbstractMessageLite.java index 489577d..9210d85 100644 --- a/java/src/main/java/com/google/protobuf/AbstractMessageLite.java +++ b/java/src/main/java/com/google/protobuf/AbstractMessageLite.java @@ -72,14 +72,21 @@ public abstract class AbstractMessageLite implements MessageLite { } public void writeTo(final OutputStream output) throws IOException { - final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); + final int bufferSize = + CodedOutputStream.computePreferredBufferSize(getSerializedSize()); + final CodedOutputStream codedOutput = + CodedOutputStream.newInstance(output, bufferSize); writeTo(codedOutput); codedOutput.flush(); } public void writeDelimitedTo(final OutputStream output) throws IOException { - final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); - codedOutput.writeRawVarint32(getSerializedSize()); + final int serialized = getSerializedSize(); + final int bufferSize = CodedOutputStream.computePreferredBufferSize( + CodedOutputStream.computeRawVarint32Size(serialized) + serialized); + final CodedOutputStream codedOutput = + CodedOutputStream.newInstance(output, bufferSize); + codedOutput.writeRawVarint32(serialized); writeTo(codedOutput); codedOutput.flush(); } @@ -98,13 +105,7 @@ public abstract class AbstractMessageLite implements MessageLite { public BuilderType mergeFrom(final CodedInputStream input) throws IOException { - // TODO(kenton): Don't use null here. Currently we have to because - // using ExtensionRegistry.getEmptyRegistry() would imply a dependency - // on ExtensionRegistry. However, AbstractMessage overrides this with - // a correct implementation, and lite messages don't yet support - // extensions, so it ends up not mattering for now. It will matter - // once lite messages support extensions. - return mergeFrom(input, null); + return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry()); } // Re-defined here for return type covariance. @@ -268,20 +269,24 @@ public abstract class AbstractMessageLite implements MessageLite { } } - public BuilderType mergeDelimitedFrom( + public boolean mergeDelimitedFrom( final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException { - final int size = CodedInputStream.readRawVarint32(input); + final int firstByte = input.read(); + if (firstByte == -1) { + return false; + } + final int size = CodedInputStream.readRawVarint32(firstByte, input); final InputStream limitedInput = new LimitedInputStream(input, size); - return mergeFrom(limitedInput, extensionRegistry); + mergeFrom(limitedInput, extensionRegistry); + return true; } - public BuilderType mergeDelimitedFrom(final InputStream input) + public boolean mergeDelimitedFrom(final InputStream input) throws IOException { - final int size = CodedInputStream.readRawVarint32(input); - final InputStream limitedInput = new LimitedInputStream(input, size); - return mergeFrom(limitedInput); + return mergeDelimitedFrom(input, + ExtensionRegistryLite.getEmptyRegistry()); } /** diff --git a/java/src/main/java/com/google/protobuf/ByteString.java b/java/src/main/java/com/google/protobuf/ByteString.java index c83c335..5fade03 100644 --- a/java/src/main/java/com/google/protobuf/ByteString.java +++ b/java/src/main/java/com/google/protobuf/ByteString.java @@ -36,6 +36,7 @@ import java.io.ByteArrayOutputStream; import java.io.FilterOutputStream; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; +import java.util.List; /** * Immutable array of bytes. @@ -99,6 +100,24 @@ public final class ByteString { } /** + * Copies {@code size} bytes from a {@code java.nio.ByteBuffer} into + * a {@code ByteString}. + */ + public static ByteString copyFrom(final ByteBuffer bytes, final int size) { + final byte[] copy = new byte[size]; + bytes.get(copy); + return new ByteString(copy); + } + + /** + * Copies the remaining bytes from a {@code java.nio.ByteBuffer} into + * a {@code ByteString}. + */ + public static ByteString copyFrom(final ByteBuffer bytes) { + return copyFrom(bytes, bytes.remaining()); + } + + /** * Encodes {@code text} into a sequence of bytes using the named charset * and returns the result as a {@code ByteString}. */ @@ -119,6 +138,34 @@ public final class ByteString { } } + /** + * Concatenates all byte strings in the list and returns the result. + * + * <p>The returned {@code ByteString} is not necessarily a unique object. + * If the list is empty, the returned object is the singleton empty + * {@code ByteString}. If the list has only one element, that + * {@code ByteString} will be returned without copying. + */ + public static ByteString copyFrom(List<ByteString> list) { + if (list.size() == 0) { + return EMPTY; + } else if (list.size() == 1) { + return list.get(0); + } + + int size = 0; + for (ByteString str : list) { + size += str.size(); + } + byte[] bytes = new byte[size]; + int pos = 0; + for (ByteString str : list) { + System.arraycopy(str.bytes, 0, bytes, pos, str.size()); + pos += str.size(); + } + return new ByteString(bytes); + } + // ================================================================= // ByteString -> byte[] diff --git a/java/src/main/java/com/google/protobuf/CodedInputStream.java b/java/src/main/java/com/google/protobuf/CodedInputStream.java index 9125957..ad43f96 100644 --- a/java/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/src/main/java/com/google/protobuf/CodedInputStream.java @@ -84,8 +84,9 @@ public final class CodedInputStream { } lastTag = readRawVarint32(); - if (lastTag == 0) { - // If we actually read zero, that's not a valid tag. + if (WireFormat.getTagFieldNumber(lastTag) == 0) { + // If we actually read zero (or any tag number corresponding to field + // number zero), that's not a valid tag. throw InvalidProtocolBufferException.invalidTag(); } return lastTag; @@ -355,8 +356,26 @@ public final class CodedInputStream { * CodedInputStream buffers its input. */ static int readRawVarint32(final InputStream input) throws IOException { - int result = 0; - int offset = 0; + final int firstByte = input.read(); + if (firstByte == -1) { + throw InvalidProtocolBufferException.truncatedMessage(); + } + return readRawVarint32(firstByte, input); + } + + /** + * Like {@link #readRawVarint32(InputStream)}, but expects that the caller + * has already read one byte. This allows the caller to determine if EOF + * has been reached before attempting to read. + */ + static int readRawVarint32(final int firstByte, + final InputStream input) throws IOException { + if ((firstByte & 0x80) == 0) { + return firstByte; + } + + int result = firstByte & 0x7f; + int offset = 7; for (; offset < 32; offset += 7) { final int b = input.read(); if (b == -1) { @@ -467,7 +486,9 @@ public final class CodedInputStream { /** * The total number of bytes read before the current buffer. The total * bytes read up to the current position can be computed as - * {@code totalBytesRetired + bufferPos}. + * {@code totalBytesRetired + bufferPos}. This value may be negative if + * reading started in the middle of the current buffer (e.g. if the + * constructor that takes a byte array and an offset was used). */ private int totalBytesRetired; @@ -489,6 +510,7 @@ public final class CodedInputStream { this.buffer = buffer; bufferSize = off + len; bufferPos = off; + totalBytesRetired = -off; input = null; } @@ -496,6 +518,7 @@ public final class CodedInputStream { buffer = new byte[BUFFER_SIZE]; bufferSize = 0; bufferPos = 0; + totalBytesRetired = 0; this.input = input; } @@ -546,13 +569,21 @@ public final class CodedInputStream { * Resets the current size counter to zero (see {@link #setSizeLimit(int)}). */ public void resetSizeCounter() { - totalBytesRetired = 0; + totalBytesRetired = -bufferPos; } /** * Sets {@code currentLimit} to (current position) + {@code byteLimit}. This * is called when descending into a length-delimited embedded message. * + * <p>Note that {@code pushLimit()} does NOT affect how many bytes the + * {@code CodedInputStream} reads from an underlying {@code InputStream} when + * refreshing its buffer. If you need to prevent reading past a certain + * point in the underlying {@code InputStream} (e.g. because you expect it to + * contain more data after the end of the message which you need to handle + * differently) then you must place a wrapper around you {@code InputStream} + * which limits the amount of data that can be read from it. + * * @return the old limit. */ public int pushLimit(int byteLimit) throws InvalidProtocolBufferException { @@ -616,6 +647,14 @@ public final class CodedInputStream { } /** + * The total bytes read up to the current position. Calling + * {@link #resetSizeCounter()} resets this value to zero. + */ + public int getTotalBytesRead() { + return totalBytesRetired + bufferPos; + } + + /** * 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 d3907a7..58dd150 100644 --- a/java/src/main/java/com/google/protobuf/CodedOutputStream.java +++ b/java/src/main/java/com/google/protobuf/CodedOutputStream.java @@ -60,6 +60,18 @@ public final class CodedOutputStream { */ public static final int DEFAULT_BUFFER_SIZE = 4096; + /** + * Returns the buffer size to efficiently write dataLength bytes to this + * CodedOutputStream. Used by AbstractMessageLite. + * + * @return the buffer size to efficiently write dataLength bytes to this + * CodedOutputStream. + */ + static int computePreferredBufferSize(int dataLength) { + if (dataLength > DEFAULT_BUFFER_SIZE) return DEFAULT_BUFFER_SIZE; + return dataLength; + } + private CodedOutputStream(final byte[] buffer, final int offset, final int length) { output = null; diff --git a/java/src/main/java/com/google/protobuf/Descriptors.java b/java/src/main/java/com/google/protobuf/Descriptors.java index 0c162d5..c5e9a04 100644 --- a/java/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/src/main/java/com/google/protobuf/Descriptors.java @@ -48,7 +48,7 @@ import java.io.UnsupportedEncodingException; * (given a message object of the type) {@code message.getDescriptorForType()}. * * Descriptors are built from DescriptorProtos, as defined in - * {@code net/proto2/proto/descriptor.proto}. + * {@code google/protobuf/descriptor.proto}. * * @author kenton@google.com Kenton Varda */ @@ -699,6 +699,11 @@ public final class Descriptors { return getOptions().getPacked(); } + /** Can this field be packed? i.e. is it a repeated primitive field? */ + public boolean isPackable() { + return isRepeated() && getLiteType().isPackable(); + } + /** Returns true if the field had an explicitly-defined default value. */ public boolean hasDefaultValue() { return proto.hasDefaultValue(); } @@ -810,39 +815,34 @@ public final class Descriptors { private Object defaultValue; public enum Type { - DOUBLE (FieldDescriptorProto.Type.TYPE_DOUBLE , JavaType.DOUBLE ), - FLOAT (FieldDescriptorProto.Type.TYPE_FLOAT , JavaType.FLOAT ), - INT64 (FieldDescriptorProto.Type.TYPE_INT64 , JavaType.LONG ), - UINT64 (FieldDescriptorProto.Type.TYPE_UINT64 , JavaType.LONG ), - INT32 (FieldDescriptorProto.Type.TYPE_INT32 , JavaType.INT ), - FIXED64 (FieldDescriptorProto.Type.TYPE_FIXED64 , JavaType.LONG ), - FIXED32 (FieldDescriptorProto.Type.TYPE_FIXED32 , JavaType.INT ), - BOOL (FieldDescriptorProto.Type.TYPE_BOOL , JavaType.BOOLEAN ), - STRING (FieldDescriptorProto.Type.TYPE_STRING , JavaType.STRING ), - GROUP (FieldDescriptorProto.Type.TYPE_GROUP , JavaType.MESSAGE ), - MESSAGE (FieldDescriptorProto.Type.TYPE_MESSAGE , JavaType.MESSAGE ), - BYTES (FieldDescriptorProto.Type.TYPE_BYTES , JavaType.BYTE_STRING), - UINT32 (FieldDescriptorProto.Type.TYPE_UINT32 , JavaType.INT ), - ENUM (FieldDescriptorProto.Type.TYPE_ENUM , JavaType.ENUM ), - SFIXED32(FieldDescriptorProto.Type.TYPE_SFIXED32, JavaType.INT ), - SFIXED64(FieldDescriptorProto.Type.TYPE_SFIXED64, JavaType.LONG ), - SINT32 (FieldDescriptorProto.Type.TYPE_SINT32 , JavaType.INT ), - SINT64 (FieldDescriptorProto.Type.TYPE_SINT64 , JavaType.LONG ); - - Type(final FieldDescriptorProto.Type proto, final JavaType javaType) { - this.proto = proto; + DOUBLE (JavaType.DOUBLE ), + FLOAT (JavaType.FLOAT ), + INT64 (JavaType.LONG ), + UINT64 (JavaType.LONG ), + INT32 (JavaType.INT ), + FIXED64 (JavaType.LONG ), + FIXED32 (JavaType.INT ), + BOOL (JavaType.BOOLEAN ), + STRING (JavaType.STRING ), + GROUP (JavaType.MESSAGE ), + MESSAGE (JavaType.MESSAGE ), + BYTES (JavaType.BYTE_STRING), + UINT32 (JavaType.INT ), + ENUM (JavaType.ENUM ), + SFIXED32(JavaType.INT ), + SFIXED64(JavaType.LONG ), + SINT32 (JavaType.INT ), + SINT64 (JavaType.LONG ); + + Type(final JavaType javaType) { this.javaType = javaType; - - if (ordinal() != proto.getNumber() - 1) { - throw new RuntimeException( - "descriptor.proto changed but Desrciptors.java wasn't updated."); - } } - private FieldDescriptorProto.Type proto; private JavaType javaType; - public FieldDescriptorProto.Type toProto() { return proto; } + public FieldDescriptorProto.Type toProto() { + return FieldDescriptorProto.Type.valueOf(ordinal() + 1); + } public JavaType getJavaType() { return javaType; } public static Type valueOf(final FieldDescriptorProto.Type type) { @@ -902,16 +902,10 @@ public final class Descriptors { } // 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 (proto.getOptions().getPacked() && !isPackable()) { + throw new DescriptorValidationException(this, + "[packed = true] can only be specified for repeated primitive " + + "fields."); } if (isExtension) { @@ -1030,10 +1024,26 @@ public final class Descriptors { defaultValue = TextFormat.parseUInt64(proto.getDefaultValue()); break; case FLOAT: - defaultValue = Float.valueOf(proto.getDefaultValue()); + if (proto.getDefaultValue().equals("inf")) { + defaultValue = Float.POSITIVE_INFINITY; + } else if (proto.getDefaultValue().equals("-inf")) { + defaultValue = Float.NEGATIVE_INFINITY; + } else if (proto.getDefaultValue().equals("nan")) { + defaultValue = Float.NaN; + } else { + defaultValue = Float.valueOf(proto.getDefaultValue()); + } break; case DOUBLE: - defaultValue = Double.valueOf(proto.getDefaultValue()); + if (proto.getDefaultValue().equals("inf")) { + defaultValue = Double.POSITIVE_INFINITY; + } else if (proto.getDefaultValue().equals("-inf")) { + defaultValue = Double.NEGATIVE_INFINITY; + } else if (proto.getDefaultValue().equals("nan")) { + defaultValue = Double.NaN; + } else { + defaultValue = Double.valueOf(proto.getDefaultValue()); + } break; case BOOL: defaultValue = Boolean.valueOf(proto.getDefaultValue()); @@ -1064,12 +1074,9 @@ public final class Descriptors { "Message type had default value."); } } catch (NumberFormatException e) { - final DescriptorValidationException validationException = - new DescriptorValidationException(this, - "Could not parse default value: \"" + - proto.getDefaultValue() + '\"'); - validationException.initCause(e); - throw validationException; + throw new DescriptorValidationException(this, + "Could not parse default value: \"" + + proto.getDefaultValue() + '\"', e); } } else { // Determine the default default for this field. @@ -1536,14 +1543,7 @@ public final class Descriptors { private DescriptorValidationException( final GenericDescriptor problemDescriptor, final String description) { - this(problemDescriptor, description, null); - } - - private DescriptorValidationException( - final GenericDescriptor problemDescriptor, - final String description, - final Throwable cause) { - super(problemDescriptor.getFullName() + ": " + description, cause); + super(problemDescriptor.getFullName() + ": " + description); // Note that problemDescriptor may be partially uninitialized, so we // don't want to expose it directly to the user. So, we only provide @@ -1554,6 +1554,14 @@ public final class Descriptors { } private DescriptorValidationException( + final GenericDescriptor problemDescriptor, + final String description, + final Throwable cause) { + this(problemDescriptor, description); + initCause(cause); + } + + private DescriptorValidationException( final FileDescriptor problemDescriptor, final String description) { super(problemDescriptor.getName() + ": " + description); diff --git a/java/src/main/java/com/google/protobuf/ExtensionRegistry.java b/java/src/main/java/com/google/protobuf/ExtensionRegistry.java index 87bbd6e..d4f6ba9 100644 --- a/java/src/main/java/com/google/protobuf/ExtensionRegistry.java +++ b/java/src/main/java/com/google/protobuf/ExtensionRegistry.java @@ -157,6 +157,11 @@ public final class ExtensionRegistry extends ExtensionRegistryLite { public void add(final GeneratedMessage.GeneratedExtension<?, ?> extension) { if (extension.getDescriptor().getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + if (extension.getMessageDefaultInstance() == null) { + throw new IllegalStateException( + "Registered message-type extension had null default instance: " + + extension.getDescriptor().getFullName()); + } add(new ExtensionInfo(extension.getDescriptor(), extension.getMessageDefaultInstance())); } else { diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/src/main/java/com/google/protobuf/GeneratedMessage.java index 4994faa..dba0ec8 100644 --- a/java/src/main/java/com/google/protobuf/GeneratedMessage.java +++ b/java/src/main/java/com/google/protobuf/GeneratedMessage.java @@ -352,7 +352,10 @@ public abstract class GeneratedMessage extends AbstractMessage { FieldDescriptor descriptor = extension.getDescriptor(); final Object value = extensions.getField(descriptor); if (value == null) { - if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + if (descriptor.isRepeated()) { + return (Type) Collections.emptyList(); + } else if (descriptor.getJavaType() == + FieldDescriptor.JavaType.MESSAGE) { return (Type) extension.getMessageDefaultInstance(); } else { return (Type) extension.fromReflectionType( @@ -721,25 +724,8 @@ public abstract class GeneratedMessage extends AbstractMessage { /** For use by generated code only. */ public static <ContainingType extends Message, Type> GeneratedExtension<ContainingType, Type> - newGeneratedExtension(final FieldDescriptor descriptor, - final Class<Type> type) { - if (descriptor.isRepeated()) { - throw new IllegalArgumentException( - "Must call newRepeatedGeneratedExtension() for repeated types."); - } - return new GeneratedExtension<ContainingType, Type>(descriptor, type); - } - - /** For use by generated code only. */ - public static <ContainingType extends Message, Type> - GeneratedExtension<ContainingType, List<Type>> - newRepeatedGeneratedExtension( - final FieldDescriptor descriptor, final Class<Type> type) { - if (!descriptor.isRepeated()) { - throw new IllegalArgumentException( - "Must call newGeneratedExtension() for non-repeated types."); - } - return new GeneratedExtension<ContainingType, List<Type>>(descriptor, type); + newGeneratedExtension() { + return new GeneratedExtension<ContainingType, Type>(); } /** @@ -772,8 +758,23 @@ public abstract class GeneratedMessage extends AbstractMessage { // TODO(kenton): Find ways to avoid using Java reflection within this // class. Also try to avoid suppressing unchecked warnings. - private GeneratedExtension(final FieldDescriptor descriptor, - final Class type) { + // We can't always initialize a GeneratedExtension when we first construct + // it due to initialization order difficulties (namely, the descriptor may + // not have been constructed yet, since it is often constructed by the + // initializer of a separate module). So, we construct an uninitialized + // GeneratedExtension once, then call internalInit() on it later. Generated + // code will always call internalInit() on all extensions as part of the + // static initialization code, and internalInit() throws an exception if + // called more than once, so this method is useless to users. + private GeneratedExtension() {} + + /** For use by generated code only. */ + public void internalInit(final FieldDescriptor descriptor, + final Class type) { + if (this.descriptor != null) { + throw new IllegalStateException("Already initialized."); + } + if (!descriptor.isExtension()) { throw new IllegalArgumentException( "GeneratedExtension given a regular (non-extension) field."); @@ -789,6 +790,10 @@ public abstract class GeneratedMessage extends AbstractMessage { messageDefaultInstance = (Message) invokeOrDie(getMethodOrDie(type, "getDefaultInstance"), null); + if (messageDefaultInstance == null) { + throw new IllegalStateException( + type.getName() + ".getDefaultInstance() returned null."); + } break; case ENUM: enumValueOf = getMethodOrDie(type, "valueOf", @@ -804,11 +809,11 @@ public abstract class GeneratedMessage extends AbstractMessage { } } - private final FieldDescriptor descriptor; - private final Class type; - private final Method enumValueOf; - private final Method enumGetValueDescriptor; - private final Message messageDefaultInstance; + private FieldDescriptor descriptor; + private Class type; + private Method enumValueOf; + private Method enumGetValueDescriptor; + private Message messageDefaultInstance; public FieldDescriptor getDescriptor() { return descriptor; } diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java index c68414b..9cdd4e9 100644 --- a/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -303,7 +303,7 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite { final ExtensionRegistryLite extensionRegistry, final int tag) throws IOException { final FieldSet<ExtensionDescriptor> extensions = - internalGetResult().extensions; + ((ExtendableMessage) internalGetResult()).extensions; final int wireType = WireFormat.getTagWireType(tag); final int fieldNumber = WireFormat.getTagFieldNumber(tag); @@ -312,15 +312,29 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite { extensionRegistry.findLiteExtensionByNumber( getDefaultInstanceForType(), fieldNumber); - if (extension == null || wireType != - FieldSet.getWireFormatForFieldType( - extension.descriptor.getLiteType(), - extension.descriptor.isPacked())) { - // Unknown field or wrong wire type. Skip. + boolean unknown = false; + boolean packed = false; + if (extension == null) { + unknown = true; // Unknown field. + } else if (wireType == FieldSet.getWireFormatForFieldType( + extension.descriptor.getLiteType(), + false /* isPacked */)) { + packed = false; // Normal, unpacked value. + } else if (extension.descriptor.isRepeated && + extension.descriptor.type.isPackable() && + wireType == FieldSet.getWireFormatForFieldType( + extension.descriptor.getLiteType(), + true /* isPacked */)) { + packed = true; // Packed value. + } else { + unknown = true; // Wrong wire type. + } + + if (unknown) { // Unknown field or wrong wire type. Skip. return input.skipField(tag); } - if (extension.descriptor.isPacked()) { + if (packed) { final int length = input.readRawVarint32(); final int limit = input.pushLimit(length); if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) { @@ -396,7 +410,8 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite { } protected final void mergeExtensionFields(final MessageType other) { - internalGetResult().extensions.mergeFrom(other.extensions); + ((ExtendableMessage) internalGetResult()).extensions.mergeFrom( + ((ExtendableMessage) other).extensions); } } @@ -405,34 +420,8 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite { /** For use by generated code only. */ public static <ContainingType extends MessageLite, Type> GeneratedExtension<ContainingType, Type> - newGeneratedExtension( - final ContainingType containingTypeDefaultInstance, - final Type defaultValue, - final MessageLite messageDefaultInstance, - final Internal.EnumLiteMap<?> enumTypeMap, - final int number, - final WireFormat.FieldType type) { - return new GeneratedExtension<ContainingType, Type>( - containingTypeDefaultInstance, defaultValue, messageDefaultInstance, - new ExtensionDescriptor(enumTypeMap, number, type, - false /* isRepeated */, false /* isPacked */)); - } - - /** For use by generated code only. */ - public static <ContainingType extends MessageLite, Type> - GeneratedExtension<ContainingType, List<Type>> - newRepeatedGeneratedExtension( - final ContainingType containingTypeDefaultInstance, - final MessageLite messageDefaultInstance, - final Internal.EnumLiteMap<?> enumTypeMap, - final int number, - final WireFormat.FieldType type, - final boolean isPacked) { - return new GeneratedExtension<ContainingType, List<Type>>( - containingTypeDefaultInstance, Collections.<Type>emptyList(), - messageDefaultInstance, - new ExtensionDescriptor( - enumTypeMap, number, type, true /* isRepeated */, isPacked)); + newGeneratedExtension() { + return new GeneratedExtension<ContainingType, Type>(); } private static final class ExtensionDescriptor @@ -500,7 +489,16 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite { */ public static final class GeneratedExtension< ContainingType extends MessageLite, Type> { - private GeneratedExtension( + // We can't always initialize a GeneratedExtension when we first construct + // it due to initialization order difficulties (namely, the default + // instances may not have been constructed yet). So, we construct an + // uninitialized GeneratedExtension once, then call internalInit() on it + // later. Generated code will always call internalInit() on all extensions + // as part of the static initialization code, and internalInit() throws an + // exception if called more than once, so this method is useless to users. + private GeneratedExtension() {} + + private void internalInit( final ContainingType containingTypeDefaultInstance, final Type defaultValue, final MessageLite messageDefaultInstance, @@ -511,10 +509,39 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite { this.descriptor = descriptor; } - private final ContainingType containingTypeDefaultInstance; - private final Type defaultValue; - private final MessageLite messageDefaultInstance; - private final ExtensionDescriptor descriptor; + /** For use by generated code only. */ + public void internalInitSingular( + final ContainingType containingTypeDefaultInstance, + final Type defaultValue, + final MessageLite messageDefaultInstance, + final Internal.EnumLiteMap<?> enumTypeMap, + final int number, + final WireFormat.FieldType type) { + internalInit( + containingTypeDefaultInstance, defaultValue, messageDefaultInstance, + new ExtensionDescriptor(enumTypeMap, number, type, + false /* isRepeated */, false /* isPacked */)); + } + + /** For use by generated code only. */ + public void internalInitRepeated( + final ContainingType containingTypeDefaultInstance, + final MessageLite messageDefaultInstance, + final Internal.EnumLiteMap<?> enumTypeMap, + final int number, + final WireFormat.FieldType type, + final boolean isPacked) { + internalInit( + containingTypeDefaultInstance, (Type) Collections.emptyList(), + messageDefaultInstance, + new ExtensionDescriptor( + enumTypeMap, number, type, true /* isRepeated */, isPacked)); + } + + private ContainingType containingTypeDefaultInstance; + private Type defaultValue; + private MessageLite messageDefaultInstance; + private ExtensionDescriptor descriptor; /** * Default instance of the type being extended, used to identify that type. diff --git a/java/src/main/java/com/google/protobuf/Message.java b/java/src/main/java/com/google/protobuf/Message.java index c11abdc..8c29e21 100644 --- a/java/src/main/java/com/google/protobuf/Message.java +++ b/java/src/main/java/com/google/protobuf/Message.java @@ -296,9 +296,9 @@ public interface Message extends MessageLite { Builder mergeFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException; - Builder mergeDelimitedFrom(InputStream input) + boolean mergeDelimitedFrom(InputStream input) throws IOException; - Builder mergeDelimitedFrom(InputStream input, + boolean mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException; } diff --git a/java/src/main/java/com/google/protobuf/MessageLite.java b/java/src/main/java/com/google/protobuf/MessageLite.java index 3ebe9bb..cf7f39e 100644 --- a/java/src/main/java/com/google/protobuf/MessageLite.java +++ b/java/src/main/java/com/google/protobuf/MessageLite.java @@ -317,14 +317,18 @@ public interface MessageLite { * then the message data. Use * {@link MessageLite#writeDelimitedTo(OutputStream)} to write messages in * this format. + * + * @returns True if successful, or false if the stream is at EOF when the + * method starts. Any other error (including reaching EOF during + * parsing) will cause an exception to be thrown. */ - Builder mergeDelimitedFrom(InputStream input) + boolean mergeDelimitedFrom(InputStream input) throws IOException; /** * Like {@link #mergeDelimitedFrom(InputStream)} but supporting extensions. */ - Builder mergeDelimitedFrom(InputStream input, + boolean mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException; } diff --git a/java/src/main/java/com/google/protobuf/RpcCallback.java b/java/src/main/java/com/google/protobuf/RpcCallback.java index 841c88a..1fd35ed 100644 --- a/java/src/main/java/com/google/protobuf/RpcCallback.java +++ b/java/src/main/java/com/google/protobuf/RpcCallback.java @@ -34,6 +34,12 @@ package com.google.protobuf; * Interface for an RPC callback, normally called when an RPC completes. * {@code ParameterType} is normally the method's response message type. * + * <p>Starting with version 2.3.0, RPC implementations should not try to build + * on this, but should instead provide code generator plugins which generate + * code specific to the particular RPC implementation. This way the generated + * code can be more appropriate for the implementation in use and can avoid + * unnecessary layers of indirection. + * * @author kenton@google.com Kenton Varda */ public interface RpcCallback<ParameterType> { diff --git a/java/src/main/java/com/google/protobuf/RpcChannel.java b/java/src/main/java/com/google/protobuf/RpcChannel.java index 204ff18..c6ec54f 100644 --- a/java/src/main/java/com/google/protobuf/RpcChannel.java +++ b/java/src/main/java/com/google/protobuf/RpcChannel.java @@ -44,6 +44,12 @@ package com.google.protobuf; * service.myMethod(controller, request, callback); * </pre> * + * <p>Starting with version 2.3.0, RPC implementations should not try to build + * on this, but should instead provide code generator plugins which generate + * code specific to the particular RPC implementation. This way the generated + * code can be more appropriate for the implementation in use and can avoid + * unnecessary layers of indirection. + * * @author kenton@google.com Kenton Varda */ public interface RpcChannel { diff --git a/java/src/main/java/com/google/protobuf/RpcController.java b/java/src/main/java/com/google/protobuf/RpcController.java index a017422..aaa5446 100644 --- a/java/src/main/java/com/google/protobuf/RpcController.java +++ b/java/src/main/java/com/google/protobuf/RpcController.java @@ -35,6 +35,12 @@ package com.google.protobuf; * purpose of the controller is to provide a way to manipulate settings * specific to the RPC implementation and to find out about RPC-level errors. * + * <p>Starting with version 2.3.0, RPC implementations should not try to build + * on this, but should instead provide code generator plugins which generate + * code specific to the particular RPC implementation. This way the generated + * code can be more appropriate for the implementation in use and can avoid + * unnecessary layers of indirection. + * * <p>The methods provided by the {@code RpcController} interface are intended * to be a "least common denominator" set of features which we expect all * implementations to support. Specific implementations may provide more diff --git a/java/src/main/java/com/google/protobuf/Service.java b/java/src/main/java/com/google/protobuf/Service.java index 33bcfd3..541585f 100644 --- a/java/src/main/java/com/google/protobuf/Service.java +++ b/java/src/main/java/com/google/protobuf/Service.java @@ -37,6 +37,12 @@ package com.google.protobuf; * interface can be used to call the methods of the service without knowing * its exact type at compile time (analogous to the Message interface). * + * <p>Starting with version 2.3.0, RPC implementations should not try to build + * on this, but should instead provide code generator plugins which generate + * code specific to the particular RPC implementation. This way the generated + * code can be more appropriate for the implementation in use and can avoid + * unnecessary layers of indirection. + * * @author kenton@google.com Kenton Varda */ public interface Service { diff --git a/java/src/main/java/com/google/protobuf/TextFormat.java b/java/src/main/java/com/google/protobuf/TextFormat.java index a855720..cb23f0c 100644 --- a/java/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/src/main/java/com/google/protobuf/TextFormat.java @@ -38,6 +38,7 @@ import com.google.protobuf.Descriptors.EnumValueDescriptor; import java.io.IOException; import java.nio.CharBuffer; import java.math.BigInteger; +import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -115,7 +116,7 @@ public final class TextFormat { } printUnknownFields(message.getUnknownFields(), generator); } - + public static void printField(final FieldDescriptor field, final Object value, final Appendable output) @@ -133,10 +134,10 @@ public final class TextFormat { } catch (IOException e) { throw new RuntimeException( "Writing to a StringBuilder threw an IOException (should never " + - "happen).", e); + "happen).", e); } } - + private static void printField(final FieldDescriptor field, final Object value, final TextGenerator generator) @@ -426,9 +427,9 @@ public final class TextFormat { Pattern.compile("(\\s|(#.*$))++", Pattern.MULTILINE); private static final Pattern TOKEN = Pattern.compile( "[a-zA-Z_][0-9a-zA-Z_+-]*+|" + // an identifier - "[0-9+-][0-9a-zA-Z_.+-]*+|" + // a number + "[.]?[0-9+-][0-9a-zA-Z_.+-]*+|" + // a number "\"([^\"\n\\\\]|\\\\.)*+(\"|\\\\?$)|" + // a double-quoted string - "\'([^\"\n\\\\]|\\\\.)*+(\'|\\\\?$)", // a single-quoted string + "\'([^\'\n\\\\]|\\\\.)*+(\'|\\\\?$)", // a single-quoted string Pattern.MULTILINE); private static final Pattern DOUBLE_INFINITY = Pattern.compile( @@ -695,6 +696,21 @@ public final class TextFormat { * {@link ParseException}. */ public ByteString consumeByteString() throws ParseException { + List<ByteString> list = new ArrayList<ByteString>(); + consumeByteString(list); + while (currentToken.startsWith("'") || currentToken.startsWith("\"")) { + consumeByteString(list); + } + return ByteString.copyFrom(list); + } + + /** + * Like {@link #consumeByteString()} but adds each token of the string to + * the given list. String literals (whether bytes or text) may come in + * multiple adjacent tokens which are automatically concatenated, like in + * C or Python. + */ + private void consumeByteString(List<ByteString> list) throws ParseException { final char quote = currentToken.length() > 0 ? currentToken.charAt(0) : '\0'; if (quote != '\"' && quote != '\'') { @@ -711,7 +727,7 @@ public final class TextFormat { currentToken.substring(1, currentToken.length() - 1); final ByteString result = unescapeBytes(escaped); nextToken(); - return result; + list.add(result); } catch (InvalidEscapeSequenceException e) { throw parseException(e.getMessage()); } diff --git a/java/src/main/java/com/google/protobuf/UnknownFieldSet.java b/java/src/main/java/com/google/protobuf/UnknownFieldSet.java index 7f7e493..26a15d0 100644 --- a/java/src/main/java/com/google/protobuf/UnknownFieldSet.java +++ b/java/src/main/java/com/google/protobuf/UnknownFieldSet.java @@ -30,6 +30,8 @@ package com.google.protobuf; +import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -551,19 +553,23 @@ public final class UnknownFieldSet implements MessageLite { return this; } - public Builder mergeDelimitedFrom(InputStream input) + public boolean mergeDelimitedFrom(InputStream input) throws IOException { - final int size = CodedInputStream.readRawVarint32(input); - final InputStream limitedInput = - new AbstractMessage.Builder.LimitedInputStream(input, size); - return mergeFrom(limitedInput, null); + final int firstByte = input.read(); + if (firstByte == -1) { + return false; + } + final int size = CodedInputStream.readRawVarint32(firstByte, input); + final InputStream limitedInput = new LimitedInputStream(input, size); + mergeFrom(limitedInput); + return true; } - public Builder mergeDelimitedFrom( + public boolean mergeDelimitedFrom( InputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { // UnknownFieldSet has no extensions. - return mergeFrom(input); + return mergeDelimitedFrom(input); } public Builder mergeFrom( diff --git a/java/src/main/java/com/google/protobuf/WireFormat.java b/java/src/main/java/com/google/protobuf/WireFormat.java index 3b0bdcd..c46f7b0 100644 --- a/java/src/main/java/com/google/protobuf/WireFormat.java +++ b/java/src/main/java/com/google/protobuf/WireFormat.java @@ -113,10 +113,18 @@ public final class WireFormat { FIXED64 (JavaType.LONG , WIRETYPE_FIXED64 ), FIXED32 (JavaType.INT , WIRETYPE_FIXED32 ), BOOL (JavaType.BOOLEAN , WIRETYPE_VARINT ), - STRING (JavaType.STRING , WIRETYPE_LENGTH_DELIMITED), - GROUP (JavaType.MESSAGE , WIRETYPE_START_GROUP ), - MESSAGE (JavaType.MESSAGE , WIRETYPE_LENGTH_DELIMITED), - BYTES (JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED), + STRING (JavaType.STRING , WIRETYPE_LENGTH_DELIMITED) { + public boolean isPackable() { return false; } + }, + GROUP (JavaType.MESSAGE , WIRETYPE_START_GROUP ) { + public boolean isPackable() { return false; } + }, + MESSAGE (JavaType.MESSAGE , WIRETYPE_LENGTH_DELIMITED) { + public boolean isPackable() { return false; } + }, + BYTES (JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED) { + public boolean isPackable() { return false; } + }, UINT32 (JavaType.INT , WIRETYPE_VARINT ), ENUM (JavaType.ENUM , WIRETYPE_VARINT ), SFIXED32(JavaType.INT , WIRETYPE_FIXED32 ), @@ -134,6 +142,8 @@ public final class WireFormat { public JavaType getJavaType() { return javaType; } public int getWireType() { return wireType; } + + public boolean isPackable() { return true; } } // Field numbers for feilds in MessageSet wire format. diff --git a/java/src/main/java/com/google/protobuf/micro/ByteStringMicro.java b/java/src/main/java/com/google/protobuf/micro/ByteStringMicro.java deleted file mode 100644 index 6e87dc9..0000000 --- a/java/src/main/java/com/google/protobuf/micro/ByteStringMicro.java +++ /dev/null @@ -1,227 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf.micro; - -import java.io.UnsupportedEncodingException; - -/** - * Immutable array of bytes. - * - * @author crazybob@google.com Bob Lee - * @author kenton@google.com Kenton Varda - */ -public final class ByteStringMicro { - private final byte[] bytes; - - private ByteStringMicro(final byte[] bytes) { - this.bytes = bytes; - } - - /** - * Gets the byte at the given index. - * - * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size - */ - public byte byteAt(final int index) { - return bytes[index]; - } - - /** - * Gets the number of bytes. - */ - public int size() { - return bytes.length; - } - - /** - * Returns {@code true} if the size is {@code 0}, {@code false} otherwise. - */ - public boolean isEmpty() { - return bytes.length == 0; - } - - // ================================================================= - // byte[] -> ByteStringMicro - - /** - * Empty ByteStringMicro. - */ - public static final ByteStringMicro EMPTY = new ByteStringMicro(new byte[0]); - - /** - * Copies the given bytes into a {@code ByteStringMicro}. - */ - public static ByteStringMicro copyFrom(final byte[] bytes, final int offset, - final int size) { - final byte[] copy = new byte[size]; - System.arraycopy(bytes, offset, copy, 0, size); - return new ByteStringMicro(copy); - } - - /** - * Copies the given bytes into a {@code ByteStringMicro}. - */ - public static ByteStringMicro copyFrom(final byte[] bytes) { - return copyFrom(bytes, 0, bytes.length); - } - - /** - * Encodes {@code text} into a sequence of bytes using the named charset - * and returns the result as a {@code ByteStringMicro}. - */ - public static ByteStringMicro copyFrom(final String text, final String charsetName) - throws UnsupportedEncodingException { - return new ByteStringMicro(text.getBytes(charsetName)); - } - - /** - * Encodes {@code text} into a sequence of UTF-8 bytes and returns the - * result as a {@code ByteStringMicro}. - */ - public static ByteStringMicro copyFromUtf8(final String text) { - try { - return new ByteStringMicro(text.getBytes("UTF-8")); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("UTF-8 not supported?"); - } - } - - // ================================================================= - // ByteStringMicro -> byte[] - - /** - * Copies bytes into a buffer at the given offset. - * - * @param target buffer to copy into - * @param offset in the target buffer - */ - public void copyTo(final byte[] target, final int offset) { - System.arraycopy(bytes, 0, target, offset, bytes.length); - } - - /** - * Copies bytes into a buffer. - * - * @param target buffer to copy into - * @param sourceOffset offset within these bytes - * @param targetOffset offset within the target buffer - * @param size number of bytes to copy - */ - public void copyTo(final byte[] target, final int sourceOffset, - final int targetOffset, - final int size) { - System.arraycopy(bytes, sourceOffset, target, targetOffset, size); - } - - /** - * Copies bytes to a {@code byte[]}. - */ - public byte[] toByteArray() { - final int size = bytes.length; - final byte[] copy = new byte[size]; - System.arraycopy(bytes, 0, copy, 0, size); - return copy; - } - - /** - * Constructs a new {@code String} by decoding the bytes using the - * specified charset. - */ - public String toString(final String charsetName) - throws UnsupportedEncodingException { - return new String(bytes, charsetName); - } - - /** - * Constructs a new {@code String} by decoding the bytes as UTF-8. - */ - public String toStringUtf8() { - try { - return new String(bytes, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("UTF-8 not supported?"); - } - } - - // ================================================================= - // equals() and hashCode() - - //@Override for compatibility with Java 1.3 code we can't use annotations - public boolean equals(final Object o) { - if (o == this) { - return true; - } - - if (!(o instanceof ByteStringMicro)) { - return false; - } - - final ByteStringMicro other = (ByteStringMicro) o; - final int size = bytes.length; - if (size != other.bytes.length) { - return false; - } - - final byte[] thisBytes = bytes; - final byte[] otherBytes = other.bytes; - for (int i = 0; i < size; i++) { - if (thisBytes[i] != otherBytes[i]) { - return false; - } - } - - return true; - } - - private volatile int hash = 0; - - //@Override for compatibility with Java 1.3 code we can't use annotations - public int hashCode() { - int h = hash; - - if (h == 0) { - final byte[] thisBytes = bytes; - final int size = bytes.length; - - h = size; - for (int i = 0; i < size; i++) { - h = h * 31 + thisBytes[i]; - } - if (h == 0) { - h = 1; - } - - hash = h; - } - - return h; - } -} diff --git a/java/src/main/java/com/google/protobuf/micro/CodedInputStreamMicro.java b/java/src/main/java/com/google/protobuf/micro/CodedInputStreamMicro.java deleted file mode 100644 index 0791b8f..0000000 --- a/java/src/main/java/com/google/protobuf/micro/CodedInputStreamMicro.java +++ /dev/null @@ -1,804 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf.micro; - -import java.io.IOException; -import java.io.InputStream; - -/** - * Reads and decodes protocol message fields. - * - * This class contains two kinds of methods: methods that read specific - * protocol message constructs and field types (e.g. {@link #readTag()} and - * {@link #readInt32()}) and methods that read low-level values (e.g. - * {@link #readRawVarint32()} and {@link #readRawBytes}). If you are reading - * encoded protocol messages, you should use the former methods, but if you are - * reading some other format of your own design, use the latter. - * - * @author kenton@google.com Kenton Varda - */ -public final class CodedInputStreamMicro { - /** - * Create a new CodedInputStream wrapping the given InputStream. - */ - public static CodedInputStreamMicro newInstance(final InputStream input) { - return new CodedInputStreamMicro(input); - } - - /** - * Create a new CodedInputStream wrapping the given byte array. - */ - public static CodedInputStreamMicro newInstance(final byte[] buf) { - return newInstance(buf, 0, buf.length); - } - - /** - * Create a new CodedInputStream wrapping the given byte array slice. - */ - public static CodedInputStreamMicro newInstance(final byte[] buf, final int off, - final int len) { - return new CodedInputStreamMicro(buf, off, len); - } - - // ----------------------------------------------------------------- - - /** - * Attempt to read a field tag, returning zero if we have reached EOF. - * Protocol message parsers use this to read tags, since a protocol message - * may legally end wherever a tag occurs, and zero is not a valid tag number. - */ - public int readTag() throws IOException { - if (isAtEnd()) { - lastTag = 0; - return 0; - } - - lastTag = readRawVarint32(); - if (lastTag == 0) { - // If we actually read zero, that's not a valid tag. - throw InvalidProtocolBufferMicroException.invalidTag(); - } - return lastTag; - } - - /** - * Verifies that the last call to readTag() returned the given tag value. - * This is used to verify that a nested group ended with the correct - * end tag. - * - * @throws InvalidProtocolBufferMicroException {@code value} does not match the - * last tag. - */ - public void checkLastTagWas(final int value) - throws InvalidProtocolBufferMicroException { - if (lastTag != value) { - throw InvalidProtocolBufferMicroException.invalidEndTag(); - } - } - - /** - * Reads and discards a single field, given its tag value. - * - * @return {@code false} if the tag is an endgroup tag, in which case - * nothing is skipped. Otherwise, returns {@code true}. - */ - public boolean skipField(final int tag) throws IOException { - switch (WireFormatMicro.getTagWireType(tag)) { - case WireFormatMicro.WIRETYPE_VARINT: - readInt32(); - return true; - case WireFormatMicro.WIRETYPE_FIXED64: - readRawLittleEndian64(); - return true; - case WireFormatMicro.WIRETYPE_LENGTH_DELIMITED: - skipRawBytes(readRawVarint32()); - return true; - case WireFormatMicro.WIRETYPE_START_GROUP: - skipMessage(); - checkLastTagWas( - WireFormatMicro.makeTag(WireFormatMicro.getTagFieldNumber(tag), - WireFormatMicro.WIRETYPE_END_GROUP)); - return true; - case WireFormatMicro.WIRETYPE_END_GROUP: - return false; - case WireFormatMicro.WIRETYPE_FIXED32: - readRawLittleEndian32(); - return true; - default: - throw InvalidProtocolBufferMicroException.invalidWireType(); - } - } - - /** - * Reads and discards an entire message. This will read either until EOF - * or until an endgroup tag, whichever comes first. - */ - public void skipMessage() throws IOException { - while (true) { - final int tag = readTag(); - if (tag == 0 || !skipField(tag)) { - return; - } - } - } - - // ----------------------------------------------------------------- - - /** Read a {@code double} field value from the stream. */ - public double readDouble() throws IOException { - return Double.longBitsToDouble(readRawLittleEndian64()); - } - - /** Read a {@code float} field value from the stream. */ - public float readFloat() throws IOException { - return Float.intBitsToFloat(readRawLittleEndian32()); - } - - /** Read a {@code uint64} field value from the stream. */ - public long readUInt64() throws IOException { - return readRawVarint64(); - } - - /** Read an {@code int64} field value from the stream. */ - public long readInt64() throws IOException { - return readRawVarint64(); - } - - /** Read an {@code int32} field value from the stream. */ - public int readInt32() throws IOException { - return readRawVarint32(); - } - - /** Read a {@code fixed64} field value from the stream. */ - public long readFixed64() throws IOException { - return readRawLittleEndian64(); - } - - /** Read a {@code fixed32} field value from the stream. */ - public int readFixed32() throws IOException { - return readRawLittleEndian32(); - } - - /** Read a {@code bool} field value from the stream. */ - public boolean readBool() throws IOException { - return readRawVarint32() != 0; - } - - /** Read a {@code string} field value from the stream. */ - public String readString() throws IOException { - final int size = readRawVarint32(); - if (size <= (bufferSize - bufferPos) && size > 0) { - // Fast path: We already have the bytes in a contiguous buffer, so - // just copy directly from it. - final String result = new String(buffer, bufferPos, size, "UTF-8"); - bufferPos += size; - return result; - } else { - // Slow path: Build a byte array first then copy it. - return new String(readRawBytes(size), "UTF-8"); - } - } - - /** Read a {@code group} field value from the stream. */ - public void readGroup(final MessageMicro msg, final int fieldNumber) - throws IOException { - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferMicroException.recursionLimitExceeded(); - } - ++recursionDepth; - msg.mergeFrom(this); - checkLastTagWas( - WireFormatMicro.makeTag(fieldNumber, WireFormatMicro.WIRETYPE_END_GROUP)); - --recursionDepth; - } - - public void readMessage(final MessageMicro msg) - throws IOException { - final int length = readRawVarint32(); - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferMicroException.recursionLimitExceeded(); - } - final int oldLimit = pushLimit(length); - ++recursionDepth; - msg.mergeFrom(this); - checkLastTagWas(0); - --recursionDepth; - popLimit(oldLimit); - } - - /** Read a {@code bytes} field value from the stream. */ - public ByteStringMicro readBytes() throws IOException { - final int size = readRawVarint32(); - if (size <= (bufferSize - bufferPos) && size > 0) { - // Fast path: We already have the bytes in a contiguous buffer, so - // just copy directly from it. - final ByteStringMicro result = ByteStringMicro.copyFrom(buffer, bufferPos, size); - bufferPos += size; - return result; - } else { - // Slow path: Build a byte array first then copy it. - return ByteStringMicro.copyFrom(readRawBytes(size)); - } - } - - /** Read a {@code uint32} field value from the stream. */ - public int readUInt32() throws IOException { - return readRawVarint32(); - } - - /** - * Read an enum field value from the stream. Caller is responsible - * for converting the numeric value to an actual enum. - */ - public int readEnum() throws IOException { - return readRawVarint32(); - } - - /** Read an {@code sfixed32} field value from the stream. */ - public int readSFixed32() throws IOException { - return readRawLittleEndian32(); - } - - /** Read an {@code sfixed64} field value from the stream. */ - public long readSFixed64() throws IOException { - return readRawLittleEndian64(); - } - - /** Read an {@code sint32} field value from the stream. */ - public int readSInt32() throws IOException { - return decodeZigZag32(readRawVarint32()); - } - - /** Read an {@code sint64} field value from the stream. */ - public long readSInt64() throws IOException { - return decodeZigZag64(readRawVarint64()); - } - - // ================================================================= - - /** - * Read a raw Varint from the stream. If larger than 32 bits, discard the - * upper bits. - */ - public int readRawVarint32() throws IOException { - byte tmp = readRawByte(); - if (tmp >= 0) { - return tmp; - } - int result = tmp & 0x7f; - if ((tmp = readRawByte()) >= 0) { - result |= tmp << 7; - } else { - result |= (tmp & 0x7f) << 7; - if ((tmp = readRawByte()) >= 0) { - result |= tmp << 14; - } else { - result |= (tmp & 0x7f) << 14; - if ((tmp = readRawByte()) >= 0) { - result |= tmp << 21; - } else { - result |= (tmp & 0x7f) << 21; - result |= (tmp = readRawByte()) << 28; - if (tmp < 0) { - // Discard upper 32 bits. - for (int i = 0; i < 5; i++) { - if (readRawByte() >= 0) { - return result; - } - } - throw InvalidProtocolBufferMicroException.malformedVarint(); - } - } - } - } - return result; - } - - /** - * Reads a varint from the input one byte at a time, so that it does not - * read any bytes after the end of the varint. If you simply wrapped the - * stream in a CodedInputStream and used {@link #readRawVarint32(InputStream)} - * then you would probably end up reading past the end of the varint since - * CodedInputStream buffers its input. - */ - static int readRawVarint32(final InputStream input) throws IOException { - int result = 0; - int offset = 0; - for (; offset < 32; offset += 7) { - final int b = input.read(); - if (b == -1) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - result |= (b & 0x7f) << offset; - if ((b & 0x80) == 0) { - return result; - } - } - // Keep reading up to 64 bits. - for (; offset < 64; offset += 7) { - final int b = input.read(); - if (b == -1) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - if ((b & 0x80) == 0) { - return result; - } - } - throw InvalidProtocolBufferMicroException.malformedVarint(); - } - - /** Read a raw Varint from the stream. */ - public long readRawVarint64() throws IOException { - int shift = 0; - long result = 0; - while (shift < 64) { - final byte b = readRawByte(); - result |= (long)(b & 0x7F) << shift; - if ((b & 0x80) == 0) { - return result; - } - shift += 7; - } - throw InvalidProtocolBufferMicroException.malformedVarint(); - } - - /** Read a 32-bit little-endian integer from the stream. */ - public int readRawLittleEndian32() throws IOException { - final byte b1 = readRawByte(); - final byte b2 = readRawByte(); - final byte b3 = readRawByte(); - final byte b4 = readRawByte(); - return ((b1 & 0xff) ) | - ((b2 & 0xff) << 8) | - ((b3 & 0xff) << 16) | - ((b4 & 0xff) << 24); - } - - /** Read a 64-bit little-endian integer from the stream. */ - public long readRawLittleEndian64() throws IOException { - final byte b1 = readRawByte(); - final byte b2 = readRawByte(); - final byte b3 = readRawByte(); - final byte b4 = readRawByte(); - final byte b5 = readRawByte(); - final byte b6 = readRawByte(); - final byte b7 = readRawByte(); - final byte b8 = readRawByte(); - return (((long)b1 & 0xff) ) | - (((long)b2 & 0xff) << 8) | - (((long)b3 & 0xff) << 16) | - (((long)b4 & 0xff) << 24) | - (((long)b5 & 0xff) << 32) | - (((long)b6 & 0xff) << 40) | - (((long)b7 & 0xff) << 48) | - (((long)b8 & 0xff) << 56); - } - - /** - * Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers - * into values that can be efficiently encoded with varint. (Otherwise, - * negative values must be sign-extended to 64 bits to be varint encoded, - * thus always taking 10 bytes on the wire.) - * - * @param n An unsigned 32-bit integer, stored in a signed int because - * Java has no explicit unsigned support. - * @return A signed 32-bit integer. - */ - public static int decodeZigZag32(final int n) { - return (n >>> 1) ^ -(n & 1); - } - - /** - * Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers - * into values that can be efficiently encoded with varint. (Otherwise, - * negative values must be sign-extended to 64 bits to be varint encoded, - * thus always taking 10 bytes on the wire.) - * - * @param n An unsigned 64-bit integer, stored in a signed int because - * Java has no explicit unsigned support. - * @return A signed 64-bit integer. - */ - public static long decodeZigZag64(final long n) { - return (n >>> 1) ^ -(n & 1); - } - - // ----------------------------------------------------------------- - - private final byte[] buffer; - private int bufferSize; - private int bufferSizeAfterLimit; - private int bufferPos; - private final InputStream input; - private int lastTag; - - /** - * The total number of bytes read before the current buffer. The total - * bytes read up to the current position can be computed as - * {@code totalBytesRetired + bufferPos}. - */ - private int totalBytesRetired; - - /** The absolute position of the end of the current message. */ - private int currentLimit = Integer.MAX_VALUE; - - /** See setRecursionLimit() */ - private int recursionDepth; - private int recursionLimit = DEFAULT_RECURSION_LIMIT; - - /** See setSizeLimit() */ - private int sizeLimit = DEFAULT_SIZE_LIMIT; - - private static final int DEFAULT_RECURSION_LIMIT = 64; - private static final int DEFAULT_SIZE_LIMIT = 64 << 20; // 64MB - private static final int BUFFER_SIZE = 4096; - - private CodedInputStreamMicro(final byte[] buffer, final int off, final int len) { - this.buffer = buffer; - bufferSize = off + len; - bufferPos = off; - input = null; - } - - private CodedInputStreamMicro(final InputStream input) { - buffer = new byte[BUFFER_SIZE]; - bufferSize = 0; - bufferPos = 0; - this.input = input; - } - - /** - * Set the maximum message recursion depth. In order to prevent malicious - * messages from causing stack overflows, {@code CodedInputStream} limits - * how deeply messages may be nested. The default limit is 64. - * - * @return the old limit. - */ - public int setRecursionLimit(final int limit) { - if (limit < 0) { - throw new IllegalArgumentException( - "Recursion limit cannot be negative: " + limit); - } - final int oldLimit = recursionLimit; - recursionLimit = limit; - return oldLimit; - } - - /** - * Set the maximum message size. In order to prevent malicious - * messages from exhausting memory or causing integer overflows, - * {@code CodedInputStream} limits how large a message may be. - * The default limit is 64MB. You should set this limit as small - * as you can without harming your app's functionality. Note that - * size limits only apply when reading from an {@code InputStream}, not - * when constructed around a raw byte array (nor with - * {@link ByteStringMicro#newCodedInput}). - * <p> - * If you want to read several messages from a single CodedInputStream, you - * could call {@link #resetSizeCounter()} after each one to avoid hitting the - * size limit. - * - * @return the old limit. - */ - public int setSizeLimit(final int limit) { - if (limit < 0) { - throw new IllegalArgumentException( - "Size limit cannot be negative: " + limit); - } - final int oldLimit = sizeLimit; - sizeLimit = limit; - return oldLimit; - } - - /** - * Resets the current size counter to zero (see {@link #setSizeLimit(int)}). - */ - public void resetSizeCounter() { - totalBytesRetired = 0; - } - - /** - * Sets {@code currentLimit} to (current position) + {@code byteLimit}. This - * is called when descending into a length-delimited embedded message. - * - * @return the old limit. - */ - public int pushLimit(int byteLimit) throws InvalidProtocolBufferMicroException { - if (byteLimit < 0) { - throw InvalidProtocolBufferMicroException.negativeSize(); - } - byteLimit += totalBytesRetired + bufferPos; - final int oldLimit = currentLimit; - if (byteLimit > oldLimit) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - currentLimit = byteLimit; - - recomputeBufferSizeAfterLimit(); - - return oldLimit; - } - - private void recomputeBufferSizeAfterLimit() { - bufferSize += bufferSizeAfterLimit; - final int bufferEnd = totalBytesRetired + bufferSize; - if (bufferEnd > currentLimit) { - // Limit is in current buffer. - bufferSizeAfterLimit = bufferEnd - currentLimit; - bufferSize -= bufferSizeAfterLimit; - } else { - bufferSizeAfterLimit = 0; - } - } - - /** - * Discards the current limit, returning to the previous limit. - * - * @param oldLimit The old limit, as returned by {@code pushLimit}. - */ - public void popLimit(final int oldLimit) { - currentLimit = oldLimit; - recomputeBufferSizeAfterLimit(); - } - - /** - * 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; - } - - final int currentAbsolutePosition = totalBytesRetired + bufferPos; - return currentLimit - currentAbsolutePosition; - } - - /** - * Returns true if the stream has reached the end of the input. This is the - * case if either the end of the underlying input source has been reached or - * if the stream has reached a limit created using {@link #pushLimit(int)}. - */ - public boolean isAtEnd() throws IOException { - return bufferPos == bufferSize && !refillBuffer(false); - } - - /** - * 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 - * or it will throw an exception. If {@code mustSucceed} is false, - * refillBuffer() returns false if no more bytes were available. - */ - private boolean refillBuffer(final boolean mustSucceed) throws IOException { - if (bufferPos < bufferSize) { - throw new IllegalStateException( - "refillBuffer() called when buffer wasn't empty."); - } - - if (totalBytesRetired + bufferSize == currentLimit) { - // Oops, we hit a limit. - if (mustSucceed) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } else { - return false; - } - } - - totalBytesRetired += bufferSize; - - bufferPos = 0; - bufferSize = (input == null) ? -1 : input.read(buffer); - if (bufferSize == 0 || bufferSize < -1) { - throw new IllegalStateException( - "InputStream#read(byte[]) returned invalid result: " + bufferSize + - "\nThe InputStream implementation is buggy."); - } - if (bufferSize == -1) { - bufferSize = 0; - if (mustSucceed) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } else { - return false; - } - } else { - recomputeBufferSizeAfterLimit(); - final int totalBytesRead = - totalBytesRetired + bufferSize + bufferSizeAfterLimit; - if (totalBytesRead > sizeLimit || totalBytesRead < 0) { - throw InvalidProtocolBufferMicroException.sizeLimitExceeded(); - } - return true; - } - } - - /** - * Read one byte from the input. - * - * @throws InvalidProtocolBufferMicroException The end of the stream or the current - * limit was reached. - */ - public byte readRawByte() throws IOException { - if (bufferPos == bufferSize) { - refillBuffer(true); - } - return buffer[bufferPos++]; - } - - /** - * Read a fixed size of bytes from the input. - * - * @throws InvalidProtocolBufferMicroException The end of the stream or the current - * limit was reached. - */ - public byte[] readRawBytes(final int size) throws IOException { - if (size < 0) { - throw InvalidProtocolBufferMicroException.negativeSize(); - } - - if (totalBytesRetired + bufferPos + size > currentLimit) { - // Read to the end of the stream anyway. - skipRawBytes(currentLimit - totalBytesRetired - bufferPos); - // Then fail. - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - - if (size <= bufferSize - bufferPos) { - // We have all the bytes we need already. - final byte[] bytes = new byte[size]; - System.arraycopy(buffer, bufferPos, bytes, 0, size); - bufferPos += size; - return bytes; - } else if (size < BUFFER_SIZE) { - // Reading more bytes than are in the buffer, but not an excessive number - // of bytes. We can safely allocate the resulting array ahead of time. - - // First copy what we have. - final byte[] bytes = new byte[size]; - int pos = bufferSize - bufferPos; - System.arraycopy(buffer, bufferPos, bytes, 0, pos); - bufferPos = bufferSize; - - // We want to use refillBuffer() and then copy from the buffer into our - // byte array rather than reading directly into our byte array because - // the input may be unbuffered. - refillBuffer(true); - - while (size - pos > bufferSize) { - System.arraycopy(buffer, 0, bytes, pos, bufferSize); - pos += bufferSize; - bufferPos = bufferSize; - refillBuffer(true); - } - - System.arraycopy(buffer, 0, bytes, pos, size - pos); - bufferPos = size - pos; - - return bytes; - } else { - // The size is very large. For security reasons, we can't allocate the - // entire byte array yet. The size comes directly from the input, so a - // maliciously-crafted message could provide a bogus very large size in - // order to trick the app into allocating a lot of memory. We avoid this - // by allocating and reading only a small chunk at a time, so that the - // malicious message must actually *be* extremely large to cause - // problems. Meanwhile, we limit the allowed size of a message elsewhere. - - // Remember the buffer markers since we'll have to copy the bytes out of - // it later. - final int originalBufferPos = bufferPos; - final int originalBufferSize = bufferSize; - - // Mark the current buffer consumed. - totalBytesRetired += bufferSize; - bufferPos = 0; - bufferSize = 0; - - // Read all the rest of the bytes we need. - int sizeLeft = size - (originalBufferSize - originalBufferPos); - - // For compatibility with Java 1.3 use Vector - final java.util.Vector chunks = new java.util.Vector(); - - while (sizeLeft > 0) { - final byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)]; - int pos = 0; - while (pos < chunk.length) { - final int n = (input == null) ? -1 : - input.read(chunk, pos, chunk.length - pos); - if (n == -1) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - totalBytesRetired += n; - pos += n; - } - sizeLeft -= chunk.length; - chunks.addElement(chunk); - } - - // OK, got everything. Now concatenate it all into one buffer. - final byte[] bytes = new byte[size]; - - // Start by copying the leftover bytes from this.buffer. - int pos = originalBufferSize - originalBufferPos; - System.arraycopy(buffer, originalBufferPos, bytes, 0, pos); - - // And now all the chunks. - for (int i = 0; i < chunks.size(); i++) { - byte [] chunk = (byte [])chunks.elementAt(i); - System.arraycopy(chunk, 0, bytes, pos, chunk.length); - pos += chunk.length; - } - - // Done. - return bytes; - } - } - - /** - * Reads and discards {@code size} bytes. - * - * @throws InvalidProtocolBufferMicroException The end of the stream or the current - * limit was reached. - */ - public void skipRawBytes(final int size) throws IOException { - if (size < 0) { - throw InvalidProtocolBufferMicroException.negativeSize(); - } - - if (totalBytesRetired + bufferPos + size > currentLimit) { - // Read to the end of the stream anyway. - skipRawBytes(currentLimit - totalBytesRetired - bufferPos); - // Then fail. - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - - if (size <= bufferSize - bufferPos) { - // We have all the bytes we need already. - bufferPos += size; - } else { - // Skipping more bytes than are in the buffer. First skip what we have. - int pos = bufferSize - bufferPos; - totalBytesRetired += pos; - bufferPos = 0; - bufferSize = 0; - - // Then skip directly from the InputStream for the rest. - while (pos < size) { - final int n = (input == null) ? -1 : (int) input.skip(size - pos); - if (n <= 0) { - throw InvalidProtocolBufferMicroException.truncatedMessage(); - } - pos += n; - totalBytesRetired += n; - } - } - } -} diff --git a/java/src/main/java/com/google/protobuf/micro/CodedOutputStreamMicro.java b/java/src/main/java/com/google/protobuf/micro/CodedOutputStreamMicro.java deleted file mode 100644 index 68b6e97..0000000 --- a/java/src/main/java/com/google/protobuf/micro/CodedOutputStreamMicro.java +++ /dev/null @@ -1,996 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf.micro; - -import java.io.OutputStream; -import java.io.IOException; -import java.io.UnsupportedEncodingException; - -/** - * Encodes and writes protocol message fields. - * - * <p>This class contains two kinds of methods: methods that write specific - * protocol message constructs and field types (e.g. {@link #writeTag} and - * {@link #writeInt32}) and methods that write low-level values (e.g. - * {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are - * writing encoded protocol messages, you should use the former methods, but if - * you are writing some other format of your own design, use the latter. - * - * <p>This class is totally unsynchronized. - * - * @author kneton@google.com Kenton Varda - */ -public final class CodedOutputStreamMicro { - private final byte[] buffer; - private final int limit; - private int position; - - private final OutputStream output; - - /** - * The buffer size used in {@link #newInstance(OutputStream)}. - */ - public static final int DEFAULT_BUFFER_SIZE = 4096; - - private CodedOutputStreamMicro(final byte[] buffer, final int offset, - final int length) { - output = null; - this.buffer = buffer; - position = offset; - limit = offset + length; - } - - private CodedOutputStreamMicro(final OutputStream output, final byte[] buffer) { - this.output = output; - this.buffer = buffer; - position = 0; - limit = buffer.length; - } - - /** - * Create a new {@code CodedOutputStream} wrapping the given - * {@code OutputStream}. - */ - public static CodedOutputStreamMicro newInstance(final OutputStream output) { - return newInstance(output, DEFAULT_BUFFER_SIZE); - } - - /** - * Create a new {@code CodedOutputStream} wrapping the given - * {@code OutputStream} with a given buffer size. - */ - public static CodedOutputStreamMicro newInstance(final OutputStream output, - final int bufferSize) { - return new CodedOutputStreamMicro(output, new byte[bufferSize]); - } - - /** - * Create a new {@code CodedOutputStream} that writes directly to the given - * byte array. If more bytes are written than fit in the array, - * {@link OutOfSpaceException} will be thrown. Writing directly to a flat - * array is faster than writing to an {@code OutputStream}. - */ - public static CodedOutputStreamMicro newInstance(final byte[] flatArray) { - return newInstance(flatArray, 0, flatArray.length); - } - - /** - * Create a new {@code CodedOutputStream} that writes directly to the given - * byte array slice. If more bytes are written than fit in the slice, - * {@link OutOfSpaceException} will be thrown. Writing directly to a flat - * array is faster than writing to an {@code OutputStream}. - */ - public static CodedOutputStreamMicro newInstance(final byte[] flatArray, - final int offset, - final int length) { - return new CodedOutputStreamMicro(flatArray, offset, length); - } - - // ----------------------------------------------------------------- - - /** Write a {@code double} field, including tag, to the stream. */ - public void writeDouble(final int fieldNumber, final double value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED64); - writeDoubleNoTag(value); - } - - /** Write a {@code float} field, including tag, to the stream. */ - public void writeFloat(final int fieldNumber, final float value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED32); - writeFloatNoTag(value); - } - - /** Write a {@code uint64} field, including tag, to the stream. */ - public void writeUInt64(final int fieldNumber, final long value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeUInt64NoTag(value); - } - - /** Write an {@code int64} field, including tag, to the stream. */ - public void writeInt64(final int fieldNumber, final long value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeInt64NoTag(value); - } - - /** Write an {@code int32} field, including tag, to the stream. */ - public void writeInt32(final int fieldNumber, final int value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeInt32NoTag(value); - } - - /** Write a {@code fixed64} field, including tag, to the stream. */ - public void writeFixed64(final int fieldNumber, final long value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED64); - writeFixed64NoTag(value); - } - - /** Write a {@code fixed32} field, including tag, to the stream. */ - public void writeFixed32(final int fieldNumber, final int value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED32); - writeFixed32NoTag(value); - } - - /** Write a {@code bool} field, including tag, to the stream. */ - public void writeBool(final int fieldNumber, final boolean value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeBoolNoTag(value); - } - - /** Write a {@code string} field, including tag, to the stream. */ - public void writeString(final int fieldNumber, final String value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED); - writeStringNoTag(value); - } - - /** Write a {@code StringUtf8Micro} field, including tag, to the stream. */ - public void writeStringUtf8(final int fieldNumber, final StringUtf8Micro value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED); - writeStringUtf8NoTag(value); - } - - /** Write a {@code group} field, including tag, to the stream. */ - public void writeGroup(final int fieldNumber, final MessageMicro value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_START_GROUP); - writeGroupNoTag(value); - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_END_GROUP); - } - - /** Write an embedded message field, including tag, to the stream. */ - public void writeMessage(final int fieldNumber, final MessageMicro value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED); - writeMessageNoTag(value); - } - - /** Write a {@code bytes} field, including tag, to the stream. */ - public void writeBytes(final int fieldNumber, final ByteStringMicro value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED); - writeBytesNoTag(value); - } - - /** Write a {@code uint32} field, including tag, to the stream. */ - public void writeUInt32(final int fieldNumber, final int value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeUInt32NoTag(value); - } - - /** - * Write an enum field, including tag, to the stream. Caller is responsible - * for converting the enum value to its numeric value. - */ - public void writeEnum(final int fieldNumber, final int value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeEnumNoTag(value); - } - - /** Write an {@code sfixed32} field, including tag, to the stream. */ - public void writeSFixed32(final int fieldNumber, final int value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED32); - writeSFixed32NoTag(value); - } - - /** Write an {@code sfixed64} field, including tag, to the stream. */ - public void writeSFixed64(final int fieldNumber, final long value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED64); - writeSFixed64NoTag(value); - } - - /** Write an {@code sint32} field, including tag, to the stream. */ - public void writeSInt32(final int fieldNumber, final int value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeSInt32NoTag(value); - } - - /** Write an {@code sint64} field, including tag, to the stream. */ - public void writeSInt64(final int fieldNumber, final long value) - throws IOException { - writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); - writeSInt64NoTag(value); - } - - /** - * Write a MessageSet extension field to the stream. For historical reasons, - * the wire format differs from normal fields. - */ -// public void writeMessageSetExtension(final int fieldNumber, -// final MessageMicro value) -// throws IOException { -// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP); -// writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber); -// writeMessage(WireFormatMicro.MESSAGE_SET_MESSAGE, value); -// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP); -// } - - /** - * Write an unparsed MessageSet extension field to the stream. For - * historical reasons, the wire format differs from normal fields. - */ -// public void writeRawMessageSetExtension(final int fieldNumber, -// final ByteStringMicro value) -// throws IOException { -// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP); -// writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber); -// writeBytes(WireFormatMicro.MESSAGE_SET_MESSAGE, value); -// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP); -// } - - // ----------------------------------------------------------------- - - /** Write a {@code double} field to the stream. */ - public void writeDoubleNoTag(final double value) throws IOException { - writeRawLittleEndian64(Double.doubleToLongBits(value)); - } - - /** Write a {@code float} field to the stream. */ - public void writeFloatNoTag(final float value) throws IOException { - writeRawLittleEndian32(Float.floatToIntBits(value)); - } - - /** Write a {@code uint64} field to the stream. */ - public void writeUInt64NoTag(final long value) throws IOException { - writeRawVarint64(value); - } - - /** Write an {@code int64} field to the stream. */ - public void writeInt64NoTag(final long value) throws IOException { - writeRawVarint64(value); - } - - /** Write an {@code int32} field to the stream. */ - public void writeInt32NoTag(final int value) throws IOException { - if (value >= 0) { - writeRawVarint32(value); - } else { - // Must sign-extend. - writeRawVarint64(value); - } - } - - /** Write a {@code fixed64} field to the stream. */ - public void writeFixed64NoTag(final long value) throws IOException { - writeRawLittleEndian64(value); - } - - /** Write a {@code fixed32} field to the stream. */ - public void writeFixed32NoTag(final int value) throws IOException { - writeRawLittleEndian32(value); - } - - /** Write a {@code bool} field to the stream. */ - public void writeBoolNoTag(final boolean value) throws IOException { - writeRawByte(value ? 1 : 0); - } - - /** Write a {@code string} field to the stream. */ - public void writeStringNoTag(final String value) throws IOException { - // Unfortunately there does not appear to be any way to tell Java to encode - // UTF-8 directly into our buffer, so we have to let it create its own byte - // array and then copy. - final byte[] bytes = value.getBytes("UTF-8"); - writeRawVarint32(bytes.length); - writeRawBytes(bytes); - } - - /** Write a {@code StringUtf8Micro} field to the stream. */ - public void writeStringUtf8NoTag(final StringUtf8Micro value) throws IOException { - final byte[] bytes = value.getBytes(); - writeRawVarint32(bytes.length); - writeRawBytes(bytes); - } - - /** Write a {@code group} field to the stream. */ - public void writeGroupNoTag(final MessageMicro value) throws IOException { - value.writeTo(this); - } - - /** Write an embedded message field to the stream. */ - public void writeMessageNoTag(final MessageMicro value) throws IOException { - writeRawVarint32(value.getCachedSize()); - value.writeTo(this); - } - - /** Write a {@code bytes} field to the stream. */ - public void writeBytesNoTag(final ByteStringMicro value) throws IOException { - final byte[] bytes = value.toByteArray(); - writeRawVarint32(bytes.length); - writeRawBytes(bytes); - } - - /** Write a {@code uint32} field to the stream. */ - public void writeUInt32NoTag(final 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(final int value) throws IOException { - writeRawVarint32(value); - } - - /** Write an {@code sfixed32} field to the stream. */ - public void writeSFixed32NoTag(final int value) throws IOException { - writeRawLittleEndian32(value); - } - - /** Write an {@code sfixed64} field to the stream. */ - public void writeSFixed64NoTag(final long value) throws IOException { - writeRawLittleEndian64(value); - } - - /** Write an {@code sint32} field to the stream. */ - public void writeSInt32NoTag(final int value) throws IOException { - writeRawVarint32(encodeZigZag32(value)); - } - - /** Write an {@code sint64} field to the stream. */ - public void writeSInt64NoTag(final long value) throws IOException { - writeRawVarint64(encodeZigZag64(value)); - } - - // ================================================================= - - /** - * Compute the number of bytes that would be needed to encode a - * {@code double} field, including tag. - */ - public static int computeDoubleSize(final int fieldNumber, - final double value) { - return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code float} field, including tag. - */ - public static int computeFloatSize(final int fieldNumber, final float value) { - return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code uint64} field, including tag. - */ - public static int computeUInt64Size(final int fieldNumber, final long value) { - return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code int64} field, including tag. - */ - public static int computeInt64Size(final int fieldNumber, final long value) { - return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code int32} field, including tag. - */ - public static int computeInt32Size(final int fieldNumber, final int value) { - return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code fixed64} field, including tag. - */ - public static int computeFixed64Size(final int fieldNumber, - final long value) { - return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code fixed32} field, including tag. - */ - public static int computeFixed32Size(final int fieldNumber, - final int value) { - return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code bool} field, including tag. - */ - public static int computeBoolSize(final int fieldNumber, - final boolean value) { - return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code string} field, including tag. - */ - public static int computeStringSize(final int fieldNumber, - final String value) { - return computeTagSize(fieldNumber) + computeStringSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code StringUtf8Micro} field, including tag. - */ - public static int computeStringUtf8Size(final int fieldNumber, - final StringUtf8Micro value) { - return computeTagSize(fieldNumber) + computeStringUtf8SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code group} field, including tag. - */ - public static int computeGroupSize(final int fieldNumber, - final MessageMicro value) { - return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * embedded message field, including tag. - */ - public static int computeMessageSize(final int fieldNumber, - final MessageMicro value) { - return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code bytes} field, including tag. - */ - public static int computeBytesSize(final int fieldNumber, - final ByteStringMicro value) { - return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code uint32} field, including tag. - */ - public static int computeUInt32Size(final int fieldNumber, final int value) { - return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * enum field, including tag. Caller is responsible for converting the - * enum value to its numeric value. - */ - public static int computeEnumSize(final int fieldNumber, final int value) { - return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code sfixed32} field, including tag. - */ - public static int computeSFixed32Size(final int fieldNumber, - final int value) { - return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code sfixed64} field, including tag. - */ - public static int computeSFixed64Size(final int fieldNumber, - final long value) { - return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code sint32} field, including tag. - */ - public static int computeSInt32Size(final int fieldNumber, final int value) { - return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code sint64} field, including tag. - */ - public static int computeSInt64Size(final int fieldNumber, final long value) { - return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value); - } - - /** - * Compute the number of bytes that would be needed to encode a - * MessageSet extension to the stream. For historical reasons, - * the wire format differs from normal fields. - */ -// public static int computeMessageSetExtensionSize( -// final int fieldNumber, final MessageMicro value) { -// return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 + -// computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) + -// computeMessageSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value); -// } - - /** - * Compute the number of bytes that would be needed to encode an - * unparsed MessageSet extension field to the stream. For - * historical reasons, the wire format differs from normal fields. - */ -// public static int computeRawMessageSetExtensionSize( -// final int fieldNumber, final ByteStringMicro value) { -// return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 + -// computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) + -// computeBytesSize(WireFormatMicro.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(final 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(final 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(final 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(final 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(final 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(final 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(final 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(final boolean value) { - return 1; - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code string} field. - */ - public static int computeStringSizeNoTag(final String value) { - try { - final byte[] bytes = value.getBytes("UTF-8"); - return computeRawVarint32Size(bytes.length) + - bytes.length; - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("UTF-8 not supported."); - } - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code StringUtf8Micro} field. - */ - public static int computeStringUtf8SizeNoTag(final StringUtf8Micro value) { - final byte[] bytes = value.getBytes(); - return computeRawVarint32Size(bytes.length) + - bytes.length; - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code group} field. - */ - public static int computeGroupSizeNoTag(final MessageMicro value) { - return value.getCachedSize(); - } - - /** - * Compute the number of bytes that would be needed to encode an embedded - * message field. - */ - public static int computeMessageSizeNoTag(final MessageMicro value) { - final int size = value.getCachedSize(); - return computeRawVarint32Size(size) + size; - } - - /** - * Compute the number of bytes that would be needed to encode a - * {@code bytes} field. - */ - public static int computeBytesSizeNoTag(final ByteStringMicro 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(final 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(final int value) { - return computeRawVarint32Size(value); - } - - /** - * Compute the number of bytes that would be needed to encode an - * {@code sfixed32} field. - */ - public static int computeSFixed32SizeNoTag(final 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(final 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(final 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(final long value) { - return computeRawVarint64Size(encodeZigZag64(value)); - } - - // ================================================================= - - /** - * Internal helper that writes the current buffer to the output. The - * buffer position is reset to its initial value when this returns. - */ - private void refreshBuffer() throws IOException { - if (output == null) { - // We're writing to a single buffer. - throw new OutOfSpaceException(); - } - - // Since we have an output stream, this is our buffer - // and buffer offset == 0 - output.write(buffer, 0, position); - position = 0; - } - - /** - * Flushes the stream and forces any buffered bytes to be written. This - * does not flush the underlying OutputStream. - */ - public void flush() throws IOException { - if (output != null) { - refreshBuffer(); - } - } - - /** - * If writing to a flat array, return the space left in the array. - * Otherwise, throws {@code UnsupportedOperationException}. - */ - public int spaceLeft() { - if (output == null) { - return limit - position; - } else { - throw new UnsupportedOperationException( - "spaceLeft() can only be called on CodedOutputStreams that are " + - "writing to a flat array."); - } - } - - /** - * Verifies that {@link #spaceLeft()} returns zero. It's common to create - * a byte array that is exactly big enough to hold a message, then write to - * it with a {@code CodedOutputStream}. Calling {@code checkNoSpaceLeft()} - * after writing verifies that the message was actually as big as expected, - * which can help catch bugs. - */ - public void checkNoSpaceLeft() { - if (spaceLeft() != 0) { - throw new IllegalStateException( - "Did not write as much data as expected."); - } - } - - /** - * If you create a CodedOutputStream around a simple flat array, you must - * not attempt to write more bytes than the array has space. Otherwise, - * this exception will be thrown. - */ - public static class OutOfSpaceException extends IOException { - private static final long serialVersionUID = -6947486886997889499L; - - OutOfSpaceException() { - super("CodedOutputStream was writing to a flat byte array and ran " + - "out of space."); - } - } - - /** Write a single byte. */ - public void writeRawByte(final byte value) throws IOException { - if (position == limit) { - refreshBuffer(); - } - - buffer[position++] = value; - } - - /** Write a single byte, represented by an integer value. */ - public void writeRawByte(final int value) throws IOException { - writeRawByte((byte) value); - } - - /** Write an array of bytes. */ - public void writeRawBytes(final byte[] value) throws IOException { - writeRawBytes(value, 0, value.length); - } - - /** Write part of an array of bytes. */ - public void writeRawBytes(final byte[] value, int offset, int length) - throws IOException { - if (limit - position >= length) { - // We have room in the current buffer. - System.arraycopy(value, offset, buffer, position, length); - position += length; - } else { - // Write extends past current buffer. Fill the rest of this buffer and - // flush. - final int bytesWritten = limit - position; - System.arraycopy(value, offset, buffer, position, bytesWritten); - offset += bytesWritten; - length -= bytesWritten; - position = limit; - refreshBuffer(); - - // Now deal with the rest. - // Since we have an output stream, this is our buffer - // and buffer offset == 0 - if (length <= limit) { - // Fits in new buffer. - System.arraycopy(value, offset, buffer, 0, length); - position = length; - } else { - // Write is very big. Let's do it all at once. - output.write(value, offset, length); - } - } - } - - /** Encode and write a tag. */ - public void writeTag(final int fieldNumber, final int wireType) - throws IOException { - writeRawVarint32(WireFormatMicro.makeTag(fieldNumber, wireType)); - } - - /** Compute the number of bytes that would be needed to encode a tag. */ - public static int computeTagSize(final int fieldNumber) { - return computeRawVarint32Size(WireFormatMicro.makeTag(fieldNumber, 0)); - } - - /** - * Encode and write a varint. {@code value} is treated as - * unsigned, so it won't be sign-extended if negative. - */ - public void writeRawVarint32(int value) throws IOException { - while (true) { - if ((value & ~0x7F) == 0) { - writeRawByte(value); - return; - } else { - writeRawByte((value & 0x7F) | 0x80); - value >>>= 7; - } - } - } - - /** - * Compute the number of bytes that would be needed to encode a varint. - * {@code value} is treated as unsigned, so it won't be sign-extended if - * negative. - */ - public static int computeRawVarint32Size(final int value) { - if ((value & (0xffffffff << 7)) == 0) return 1; - if ((value & (0xffffffff << 14)) == 0) return 2; - if ((value & (0xffffffff << 21)) == 0) return 3; - if ((value & (0xffffffff << 28)) == 0) return 4; - return 5; - } - - /** Encode and write a varint. */ - public void writeRawVarint64(long value) throws IOException { - while (true) { - if ((value & ~0x7FL) == 0) { - writeRawByte((int)value); - return; - } else { - writeRawByte(((int)value & 0x7F) | 0x80); - value >>>= 7; - } - } - } - - /** Compute the number of bytes that would be needed to encode a varint. */ - public static int computeRawVarint64Size(final long value) { - if ((value & (0xffffffffffffffffL << 7)) == 0) return 1; - if ((value & (0xffffffffffffffffL << 14)) == 0) return 2; - if ((value & (0xffffffffffffffffL << 21)) == 0) return 3; - if ((value & (0xffffffffffffffffL << 28)) == 0) return 4; - if ((value & (0xffffffffffffffffL << 35)) == 0) return 5; - if ((value & (0xffffffffffffffffL << 42)) == 0) return 6; - if ((value & (0xffffffffffffffffL << 49)) == 0) return 7; - if ((value & (0xffffffffffffffffL << 56)) == 0) return 8; - if ((value & (0xffffffffffffffffL << 63)) == 0) return 9; - return 10; - } - - /** Write a little-endian 32-bit integer. */ - public void writeRawLittleEndian32(final int value) throws IOException { - writeRawByte((value ) & 0xFF); - writeRawByte((value >> 8) & 0xFF); - writeRawByte((value >> 16) & 0xFF); - writeRawByte((value >> 24) & 0xFF); - } - - public static final int LITTLE_ENDIAN_32_SIZE = 4; - - /** Write a little-endian 64-bit integer. */ - public void writeRawLittleEndian64(final long value) throws IOException { - writeRawByte((int)(value ) & 0xFF); - writeRawByte((int)(value >> 8) & 0xFF); - writeRawByte((int)(value >> 16) & 0xFF); - writeRawByte((int)(value >> 24) & 0xFF); - writeRawByte((int)(value >> 32) & 0xFF); - writeRawByte((int)(value >> 40) & 0xFF); - writeRawByte((int)(value >> 48) & 0xFF); - writeRawByte((int)(value >> 56) & 0xFF); - } - - public static final int LITTLE_ENDIAN_64_SIZE = 8; - - /** - * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers - * into values that can be efficiently encoded with varint. (Otherwise, - * negative values must be sign-extended to 64 bits to be varint encoded, - * thus always taking 10 bytes on the wire.) - * - * @param n A signed 32-bit integer. - * @return An unsigned 32-bit integer, stored in a signed int because - * Java has no explicit unsigned support. - */ - public static int encodeZigZag32(final int n) { - // Note: the right-shift must be arithmetic - return (n << 1) ^ (n >> 31); - } - - /** - * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers - * into values that can be efficiently encoded with varint. (Otherwise, - * negative values must be sign-extended to 64 bits to be varint encoded, - * thus always taking 10 bytes on the wire.) - * - * @param n A signed 64-bit integer. - * @return An unsigned 64-bit integer, stored in a signed int because - * Java has no explicit unsigned support. - */ - public static long encodeZigZag64(final long n) { - // Note: the right-shift must be arithmetic - return (n << 1) ^ (n >> 63); - } -} diff --git a/java/src/main/java/com/google/protobuf/micro/InvalidProtocolBufferMicroException.java b/java/src/main/java/com/google/protobuf/micro/InvalidProtocolBufferMicroException.java deleted file mode 100644 index 050f99b..0000000 --- a/java/src/main/java/com/google/protobuf/micro/InvalidProtocolBufferMicroException.java +++ /dev/null @@ -1,93 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf.micro; - -import java.io.IOException; - -/** - * Thrown when a protocol message being parsed is invalid in some way, - * e.g. it contains a malformed varint or a negative byte length. - * - * @author kenton@google.com Kenton Varda - */ -public class InvalidProtocolBufferMicroException extends IOException { - private static final long serialVersionUID = -1616151763072450476L; - - public InvalidProtocolBufferMicroException(final String description) { - super(description); - } - - static InvalidProtocolBufferMicroException truncatedMessage() { - return new InvalidProtocolBufferMicroException( - "While parsing a protocol message, the input ended unexpectedly " + - "in the middle of a field. This could mean either than the " + - "input has been truncated or that an embedded message " + - "misreported its own length."); - } - - static InvalidProtocolBufferMicroException negativeSize() { - return new InvalidProtocolBufferMicroException( - "CodedInputStream encountered an embedded string or message " + - "which claimed to have negative size."); - } - - static InvalidProtocolBufferMicroException malformedVarint() { - return new InvalidProtocolBufferMicroException( - "CodedInputStream encountered a malformed varint."); - } - - static InvalidProtocolBufferMicroException invalidTag() { - return new InvalidProtocolBufferMicroException( - "Protocol message contained an invalid tag (zero)."); - } - - static InvalidProtocolBufferMicroException invalidEndTag() { - return new InvalidProtocolBufferMicroException( - "Protocol message end-group tag did not match expected tag."); - } - - static InvalidProtocolBufferMicroException invalidWireType() { - return new InvalidProtocolBufferMicroException( - "Protocol message tag had invalid wire type."); - } - - static InvalidProtocolBufferMicroException recursionLimitExceeded() { - return new InvalidProtocolBufferMicroException( - "Protocol message had too many levels of nesting. May be malicious. " + - "Use CodedInputStream.setRecursionLimit() to increase the depth limit."); - } - - static InvalidProtocolBufferMicroException sizeLimitExceeded() { - return new InvalidProtocolBufferMicroException( - "Protocol message was too large. May be malicious. " + - "Use CodedInputStream.setSizeLimit() to increase the size limit."); - } -} diff --git a/java/src/main/java/com/google/protobuf/micro/MessageMicro.java b/java/src/main/java/com/google/protobuf/micro/MessageMicro.java deleted file mode 100644 index 0c02793..0000000 --- a/java/src/main/java/com/google/protobuf/micro/MessageMicro.java +++ /dev/null @@ -1,136 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf.micro; - -import com.google.protobuf.micro.CodedOutputStreamMicro; -import java.io.IOException; - -/** - * Abstract interface implemented by Protocol Message objects. - * - * @author wink@google.com Wink Saville - */ -public abstract class MessageMicro { - /** - * Get the number of bytes required to encode this message. - * Returns the cached size or calls getSerializedSize which - * sets the cached size. This is used internally when serializing - * so the size is only computed once. If a member is modified - * then this could be stale call getSerializedSize if in doubt. - */ - abstract public int getCachedSize(); - - /** - * Computes the number of bytes required to encode this message. - * The size is cached and the cached result can be retrieved - * using getCachedSize(). - */ - abstract public int getSerializedSize(); - - /** - * Serializes the message and writes it to {@code output}. This does not - * flush or close the stream. - */ - abstract public void writeTo(CodedOutputStreamMicro output) throws java.io.IOException; - - /** - * Parse {@code input} as a message of this type and merge it with the - * message being built. - */ - abstract public MessageMicro mergeFrom(final CodedInputStreamMicro input) throws IOException; - - /** - * Serialize to a byte array. - * @return byte array with the serialized data. - */ - public byte[] toByteArray() { - final byte[] result = new byte[getSerializedSize()]; - toByteArray(result, 0, result.length); - return result; - } - - /** - * Serialize to a byte array starting at offset through length. The - * method getSerializedSize must have been called prior to calling - * this method so the proper length is know. If an attempt to - * write more than length bytes OutOfSpaceException will be thrown - * and if length bytes are not written then IllegalStateException - * is thrown. - * @return byte array with the serialized data. - */ - public void toByteArray(byte [] data, int offset, int length) { - try { - final CodedOutputStreamMicro output = CodedOutputStreamMicro.newInstance(data, offset, length); - writeTo(output); - output.checkNoSpaceLeft(); - } catch (IOException e) { - throw new RuntimeException("Serializing to a byte array threw an IOException " - + "(should never happen)."); - } - } - - /** - * Parse {@code data} as a message of this type and merge it with the - * message being built. - */ - public MessageMicro mergeFrom(final byte[] data) throws InvalidProtocolBufferMicroException { - return mergeFrom(data, 0, data.length); - } - - /** - * Parse {@code data} as a message of this type and merge it with the - * message being built. - */ - public MessageMicro mergeFrom(final byte[] data, final int off, final int len) - throws InvalidProtocolBufferMicroException { - try { - final CodedInputStreamMicro input = CodedInputStreamMicro.newInstance(data, off, len); - mergeFrom(input); - input.checkLastTagWas(0); - return this; - } catch (InvalidProtocolBufferMicroException e) { - throw e; - } catch (IOException e) { - throw new RuntimeException("Reading from a byte array threw an IOException (should " - + "never happen)."); - } - } - - /** - * Called by subclasses to parse an unknown field. - * @return {@code true} unless the tag is an end-group tag. - */ - protected boolean parseUnknownField( - final CodedInputStreamMicro input, - final int tag) throws IOException { - return input.skipField(tag); - } -} diff --git a/java/src/main/java/com/google/protobuf/micro/StringUtf8Micro.java b/java/src/main/java/com/google/protobuf/micro/StringUtf8Micro.java deleted file mode 100644 index 0c43e54..0000000 --- a/java/src/main/java/com/google/protobuf/micro/StringUtf8Micro.java +++ /dev/null @@ -1,67 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf.micro; - -/** - * A surogate for a String with a UTF8 representation. - * - * @author wink@google.com Wink Saville - */ -public final class StringUtf8Micro { - private String string; - private byte[] bytes; - - public StringUtf8Micro(String string) { - setString(string); - } - - public static final StringUtf8Micro EMPTY = new StringUtf8Micro(""); - - public String getString() { - return string; - } - - public void setString(String string) { - this.string = string; - bytes = null; - } - - public byte [] getBytes() { - if (bytes == null) { - try { - bytes = string.getBytes("UTF-8"); - } catch (java.io.UnsupportedEncodingException e) { - throw new RuntimeException("UTF-8 not supported."); - } - } - return bytes; - } -} diff --git a/java/src/main/java/com/google/protobuf/micro/WireFormatMicro.java b/java/src/main/java/com/google/protobuf/micro/WireFormatMicro.java deleted file mode 100644 index d8a88bd..0000000 --- a/java/src/main/java/com/google/protobuf/micro/WireFormatMicro.java +++ /dev/null @@ -1,87 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf.micro; - -/** - * This class is used internally by the Protocol Buffer library and generated - * message implementations. It is public only because those generated messages - * do not reside in the {@code protobuf} package. Others should not use this - * class directly. - * - * This class contains constants and helper functions useful for dealing with - * the Protocol Buffer wire format. - * - * @author kenton@google.com Kenton Varda - */ -public final class WireFormatMicro { - // Do not allow instantiation. - private WireFormatMicro() {} - - static final int WIRETYPE_VARINT = 0; - static final int WIRETYPE_FIXED64 = 1; - static final int WIRETYPE_LENGTH_DELIMITED = 2; - static final int WIRETYPE_START_GROUP = 3; - static final int WIRETYPE_END_GROUP = 4; - static final int WIRETYPE_FIXED32 = 5; - - static final int TAG_TYPE_BITS = 3; - static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1; - - /** Given a tag value, determines the wire type (the lower 3 bits). */ - static int getTagWireType(final int tag) { - return tag & TAG_TYPE_MASK; - } - - /** Given a tag value, determines the field number (the upper 29 bits). */ - public static int getTagFieldNumber(final int tag) { - return tag >>> TAG_TYPE_BITS; - } - - /** Makes a tag value given a field number and wire type. */ - static int makeTag(final int fieldNumber, final int wireType) { - return (fieldNumber << TAG_TYPE_BITS) | wireType; - } - - // Field numbers for feilds in MessageSet wire format. - static final int MESSAGE_SET_ITEM = 1; - static final int MESSAGE_SET_TYPE_ID = 2; - static final int MESSAGE_SET_MESSAGE = 3; - - // Tag numbers. - static final int MESSAGE_SET_ITEM_TAG = - makeTag(MESSAGE_SET_ITEM, WIRETYPE_START_GROUP); - static final int MESSAGE_SET_ITEM_END_TAG = - makeTag(MESSAGE_SET_ITEM, WIRETYPE_END_GROUP); - static final int MESSAGE_SET_TYPE_ID_TAG = - makeTag(MESSAGE_SET_TYPE_ID, WIRETYPE_VARINT); - static final int MESSAGE_SET_MESSAGE_TAG = - makeTag(MESSAGE_SET_MESSAGE, WIRETYPE_LENGTH_DELIMITED); -} diff --git a/java/src/test/java/com/google/protobuf/AbstractMessageTest.java b/java/src/test/java/com/google/protobuf/AbstractMessageTest.java index 2c59fd0..c44d660 100644 --- a/java/src/test/java/com/google/protobuf/AbstractMessageTest.java +++ b/java/src/test/java/com/google/protobuf/AbstractMessageTest.java @@ -38,6 +38,7 @@ import protobuf_unittest.UnittestProto.TestAllTypes; import protobuf_unittest.UnittestProto.TestPackedTypes; import protobuf_unittest.UnittestProto.TestRequired; import protobuf_unittest.UnittestProto.TestRequiredForeign; +import protobuf_unittest.UnittestProto.TestUnpackedTypes; import junit.framework.TestCase; @@ -238,6 +239,43 @@ public class AbstractMessageTest extends TestCase { TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage); } + public void testUnpackedSerialization() throws Exception { + Message abstractMessage = + new AbstractMessageWrapper(TestUtil.getUnpackedSet()); + + TestUtil.assertUnpackedFieldsSet( + TestUnpackedTypes.parseFrom(abstractMessage.toByteString())); + + assertEquals(TestUtil.getUnpackedSet().toByteString(), + abstractMessage.toByteString()); + } + + public void testParsePackedToUnpacked() throws Exception { + AbstractMessageWrapper.Builder builder = + new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder()); + AbstractMessageWrapper message = + builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build(); + TestUtil.assertUnpackedFieldsSet( + (TestUnpackedTypes) message.wrappedMessage); + } + + public void testParseUnpackedToPacked() throws Exception { + AbstractMessageWrapper.Builder builder = + new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder()); + AbstractMessageWrapper message = + builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); + TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage); + } + + public void testUnpackedParsing() throws Exception { + AbstractMessageWrapper.Builder builder = + new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder()); + AbstractMessageWrapper message = + builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); + TestUtil.assertUnpackedFieldsSet( + (TestUnpackedTypes) 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/CodedInputStreamTest.java b/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java index 850b8aa..6acd322 100644 --- a/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java +++ b/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java @@ -434,6 +434,7 @@ public class CodedInputStreamTest extends TestCase { new SmallBlockInputStream(new byte[256], 8)); input.setSizeLimit(16); input.readRawBytes(16); + assertEquals(16, input.getTotalBytesRead()); try { input.readRawByte(); @@ -443,7 +444,10 @@ public class CodedInputStreamTest extends TestCase { } input.resetSizeCounter(); + assertEquals(0, input.getTotalBytesRead()); input.readRawByte(); // No exception thrown. + input.resetSizeCounter(); + assertEquals(0, input.getTotalBytesRead()); try { input.readRawBytes(16); // Hits limit again. @@ -477,10 +481,27 @@ public class CodedInputStreamTest extends TestCase { public void testReadFromSlice() throws Exception { byte[] bytes = bytes(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); CodedInputStream in = CodedInputStream.newInstance(bytes, 3, 5); + assertEquals(0, in.getTotalBytesRead()); for (int i = 3; i < 8; i++) { assertEquals(i, in.readRawByte()); + assertEquals(i-2, in.getTotalBytesRead()); } // eof assertEquals(0, in.readTag()); + assertEquals(5, in.getTotalBytesRead()); + } + + public void testInvalidTag() throws Exception { + // Any tag number which corresponds to field number zero is invalid and + // should throw InvalidProtocolBufferException. + for (int i = 0; i < 8; i++) { + try { + CodedInputStream.newInstance(bytes(i)).readTag(); + fail("Should have thrown an exception."); + } catch (InvalidProtocolBufferException e) { + assertEquals(InvalidProtocolBufferException.invalidTag().getMessage(), + e.getMessage()); + } + } } } diff --git a/java/src/test/java/com/google/protobuf/DescriptorsTest.java b/java/src/test/java/com/google/protobuf/DescriptorsTest.java index c5c38b2..f41d070 100644 --- a/java/src/test/java/com/google/protobuf/DescriptorsTest.java +++ b/java/src/test/java/com/google/protobuf/DescriptorsTest.java @@ -30,6 +30,10 @@ package com.google.protobuf; +import com.google.protobuf.DescriptorProtos.DescriptorProto; +import com.google.protobuf.DescriptorProtos.FieldDescriptorProto; +import com.google.protobuf.DescriptorProtos.FileDescriptorProto; +import com.google.protobuf.Descriptors.DescriptorValidationException; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FieldDescriptor; @@ -63,6 +67,22 @@ import java.util.Collections; * @author kenton@google.com Kenton Varda */ public class DescriptorsTest extends TestCase { + + // Regression test for bug where referencing a FieldDescriptor.Type value + // before a FieldDescriptorProto.Type value would yield a + // ExceptionInInitializerError. + private static final Object STATIC_INIT_TEST = FieldDescriptor.Type.BOOL; + + public void testFieldTypeEnumMapping() throws Exception { + assertEquals(FieldDescriptor.Type.values().length, + FieldDescriptorProto.Type.values().length); + for (FieldDescriptor.Type type : FieldDescriptor.Type.values()) { + FieldDescriptorProto.Type protoType = type.toProto(); + assertEquals("TYPE_" + type.name(), protoType.name()); + assertEquals(type, FieldDescriptor.Type.valueOf(protoType)); + } + } + public void testFileDescriptor() throws Exception { FileDescriptor file = UnittestProto.getDescriptor(); @@ -405,4 +425,35 @@ public class DescriptorsTest extends TestCase { UnittestEnormousDescriptor.getDescriptor() .toProto().getSerializedSize() > 65536); } + + /** + * Tests that the DescriptorValidationException works as intended. + */ + public void testDescriptorValidatorException() throws Exception { + FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder() + .setName("foo.proto") + .addMessageType(DescriptorProto.newBuilder() + .setName("Foo") + .addField(FieldDescriptorProto.newBuilder() + .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) + .setType(FieldDescriptorProto.Type.TYPE_INT32) + .setName("foo") + .setNumber(1) + .setDefaultValue("invalid") + .build()) + .build()) + .build(); + try { + Descriptors.FileDescriptor.buildFrom(fileDescriptorProto, + new FileDescriptor[0]); + fail("DescriptorValidationException expected"); + } catch (DescriptorValidationException e) { + // Expected; check that the error message contains some useful hints + assertTrue(e.getMessage().indexOf("foo") != -1); + assertTrue(e.getMessage().indexOf("Foo") != -1); + assertTrue(e.getMessage().indexOf("invalid") != -1); + assertTrue(e.getCause() instanceof NumberFormatException); + assertTrue(e.getCause().getMessage().indexOf("invalid") != -1); + } + } } diff --git a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java index cdf60c5..73c71f3 100644 --- a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java +++ b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java @@ -39,6 +39,8 @@ import protobuf_unittest.UnittestProto.ForeignEnum; import protobuf_unittest.UnittestProto.TestAllTypes; import protobuf_unittest.UnittestProto.TestAllExtensions; import protobuf_unittest.UnittestProto.TestExtremeDefaultValues; +import protobuf_unittest.UnittestProto.TestPackedTypes; +import protobuf_unittest.UnittestProto.TestUnpackedTypes; import protobuf_unittest.MultipleFilesTestProto; import protobuf_unittest.MessageWithNoOuter; import protobuf_unittest.EnumWithNoOuter; @@ -303,8 +305,15 @@ public class GeneratedMessageTest extends TestCase { TestUtil.assertClear(TestAllTypes.getDefaultInstance()); TestUtil.assertClear(TestAllTypes.newBuilder().build()); - assertEquals("\u1234", - TestExtremeDefaultValues.getDefaultInstance().getUtf8String()); + TestExtremeDefaultValues message = + TestExtremeDefaultValues.getDefaultInstance(); + assertEquals("\u1234", message.getUtf8String()); + assertEquals(Double.POSITIVE_INFINITY, message.getInfDouble()); + assertEquals(Double.NEGATIVE_INFINITY, message.getNegInfDouble()); + assertTrue(Double.isNaN(message.getNanDouble())); + assertEquals(Float.POSITIVE_INFINITY, message.getInfFloat()); + assertEquals(Float.NEGATIVE_INFINITY, message.getNegInfFloat()); + assertTrue(Float.isNaN(message.getNanFloat())); } public void testReflectionGetters() throws Exception { @@ -361,6 +370,20 @@ public class GeneratedMessageTest extends TestCase { assertTrue(map.findValueByNumber(12345) == null); } + public void testParsePackedToUnpacked() throws Exception { + TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder(); + TestUnpackedTypes message = + builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build(); + TestUtil.assertUnpackedFieldsSet(message); + } + + public void testParseUnpackedToPacked() throws Exception { + TestPackedTypes.Builder builder = TestPackedTypes.newBuilder(); + TestPackedTypes message = + builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build(); + TestUtil.assertPackedFieldsSet(message); + } + // ================================================================= // Extensions. @@ -615,4 +638,12 @@ public class GeneratedMessageTest extends TestCase { UnittestProto.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 48); assertEquals(UnittestProto.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 51); } + + public void testRecursiveMessageDefaultInstance() throws Exception { + UnittestProto.TestRecursiveMessage message = + UnittestProto.TestRecursiveMessage.getDefaultInstance(); + assertTrue(message != null); + assertTrue(message.getA() != null); + assertTrue(message.getA() == message); + } } diff --git a/java/src/test/java/com/google/protobuf/LiteTest.java b/java/src/test/java/com/google/protobuf/LiteTest.java index 9dd730c..728bad9 100644 --- a/java/src/test/java/com/google/protobuf/LiteTest.java +++ b/java/src/test/java/com/google/protobuf/LiteTest.java @@ -83,7 +83,7 @@ public class LiteTest extends TestCase { public void testLiteExtensions() throws Exception { // TODO(kenton): Unlike other features of the lite library, extensions are // implemented completely differently from the regular library. We - // need to test them more thoroughly, once they are fully-implemented. + // should probably test them more thoroughly. TestAllExtensionsLite message = TestAllExtensionsLite.newBuilder() @@ -104,6 +104,8 @@ public class LiteTest extends TestCase { UnittestLite.optionalInt32ExtensionLite)); assertEquals(1, message2.getExtensionCount( UnittestLite.repeatedStringExtensionLite)); + assertEquals(1, message2.getExtension( + UnittestLite.repeatedStringExtensionLite).size()); assertEquals("hello", message2.getExtension( UnittestLite.repeatedStringExtensionLite, 0)); assertEquals(TestAllTypesLite.NestedEnum.BAZ, message2.getExtension( diff --git a/java/src/test/java/com/google/protobuf/MicroTest.java b/java/src/test/java/com/google/protobuf/MicroTest.java deleted file mode 100644 index ebfccc2..0000000 --- a/java/src/test/java/com/google/protobuf/MicroTest.java +++ /dev/null @@ -1,2138 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.protobuf; - -import com.google.protobuf.micro.MicroOuterClass; -import com.google.protobuf.micro.MicroOuterClass.TestAllTypesMicro; -import com.google.protobuf.micro.RecursiveMessageMicro; -import com.google.protobuf.micro.SimpleMessageMicro; -import com.google.protobuf.micro.StringUtf8; -import com.google.protobuf.micro.StringUtf8Micro; -import com.google.protobuf.micro.UnittestImportMicro; -import com.google.protobuf.micro.ByteStringMicro; - -import junit.framework.TestCase; - -/** - * Test micro runtime. - * - * @author wink@google.com Wink Saville - */ -public class MicroTest extends TestCase { - public void setUp() throws Exception { - } - - public void testSimpleMessageMicro() throws Exception { - SimpleMessageMicro msg = new SimpleMessageMicro(); - assertFalse(msg.hasD()); - assertEquals(123, msg.getD()); - assertFalse(msg.hasNestedMsg()); - assertEquals(null, msg.getNestedMsg()); - assertFalse(msg.hasDefaultNestedEnum()); - assertEquals(SimpleMessageMicro.BAZ, msg.getDefaultNestedEnum()); - - msg.setD(456); - assertTrue(msg.hasD()); - assertEquals(456, msg.getD()); - msg.clearD() - .setD(456); - assertTrue(msg.hasD()); - - SimpleMessageMicro.NestedMessage nestedMsg = new SimpleMessageMicro.NestedMessage() - .setBb(2); - assertTrue(nestedMsg.hasBb()); - assertEquals(2, nestedMsg.getBb()); - msg.setNestedMsg(nestedMsg); - assertTrue(msg.hasNestedMsg()); - assertEquals(2, msg.getNestedMsg().getBb()); - - msg.setDefaultNestedEnum(SimpleMessageMicro.BAR); - assertTrue(msg.hasDefaultNestedEnum()); - assertEquals(SimpleMessageMicro.BAR, msg.getDefaultNestedEnum()); - - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 9); - assertEquals(result.length, msgSerializedSize); - - SimpleMessageMicro newMsg = SimpleMessageMicro.parseFrom(result); - assertTrue(newMsg.hasD()); - assertTrue(newMsg.hasNestedMsg()); - assertTrue(newMsg.hasDefaultNestedEnum()); - assertEquals(456, newMsg.getD()); - assertEquals(2, msg.getNestedMsg().getBb()); - assertEquals(SimpleMessageMicro.BAR, msg.getDefaultNestedEnum()); - } - - public void testRecursiveMessageMicro() throws Exception { - RecursiveMessageMicro msg = new RecursiveMessageMicro(); - assertFalse(msg.hasId()); - assertFalse(msg.hasNestedMessage()); - assertFalse(msg.hasOptionalRecursiveMessageMicro()); - assertEquals(0, msg.getRepeatedRecursiveMessageMicroCount()); - - RecursiveMessageMicro msg1 = new RecursiveMessageMicro(); - msg1.setId(1); - assertEquals(1, msg1.getId()); - RecursiveMessageMicro msg2 = new RecursiveMessageMicro(); - msg2.setId(2); - RecursiveMessageMicro msg3 = new RecursiveMessageMicro(); - msg3.setId(3); - - RecursiveMessageMicro.NestedMessage nestedMsg = new RecursiveMessageMicro.NestedMessage(); - nestedMsg.setA(msg1); - assertEquals(1, nestedMsg.getA().getId()); - - msg.setId(0); - msg.setNestedMessage(nestedMsg); - msg.setOptionalRecursiveMessageMicro(msg2); - msg.addRepeatedRecursiveMessageMicro(msg3); - - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 16); - assertEquals(result.length, msgSerializedSize); - - RecursiveMessageMicro newMsg = RecursiveMessageMicro.parseFrom(result); - assertTrue(newMsg.hasId()); - assertTrue(newMsg.hasNestedMessage()); - assertTrue(newMsg.hasOptionalRecursiveMessageMicro()); - assertEquals(1, newMsg.getRepeatedRecursiveMessageMicroCount()); - - assertEquals(0, newMsg.getId()); - assertEquals(1, newMsg.getNestedMessage().getA().getId()); - assertEquals(2, newMsg.getOptionalRecursiveMessageMicro().getId()); - assertEquals(3, newMsg.getRepeatedRecursiveMessageMicro(0).getId()); - } - - public void testMicroRequiredInt32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasId()); - assertFalse(msg.isInitialized()); - msg.setId(123); - assertTrue(msg.hasId()); - assertTrue(msg.isInitialized()); - assertEquals(123, msg.getId()); - msg.clearId(); - assertFalse(msg.hasId()); - assertFalse(msg.isInitialized()); - msg.clearId() - .setId(456); - assertTrue(msg.hasId()); - msg.clear(); - assertFalse(msg.hasId()); - assertFalse(msg.isInitialized()); - - msg.setId(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasId()); - assertTrue(newMsg.isInitialized()); - assertEquals(123, newMsg.getId()); - } - - public void testMicroOptionalInt32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalInt32()); - msg.setOptionalInt32(123); - assertTrue(msg.hasOptionalInt32()); - assertEquals(123, msg.getOptionalInt32()); - msg.clearOptionalInt32(); - assertFalse(msg.hasOptionalInt32()); - msg.clearOptionalInt32() - .setOptionalInt32(456); - assertTrue(msg.hasOptionalInt32()); - msg.clear(); - assertFalse(msg.hasOptionalInt32()); - - msg.setOptionalInt32(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 2); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalInt32()); - assertEquals(123, newMsg.getOptionalInt32()); - } - - public void testMicroOptionalInt64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalInt64()); - msg.setOptionalInt64(123); - assertTrue(msg.hasOptionalInt64()); - assertEquals(123, msg.getOptionalInt64()); - msg.clearOptionalInt64(); - assertFalse(msg.hasOptionalInt64()); - msg.clearOptionalInt64() - .setOptionalInt64(456); - assertTrue(msg.hasOptionalInt64()); - msg.clear(); - assertFalse(msg.hasOptionalInt64()); - - msg.setOptionalInt64(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 2); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalInt64()); - assertEquals(123, newMsg.getOptionalInt64()); - } - - public void testMicroOptionalUint32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalUint32()); - msg.setOptionalUint32(123); - assertTrue(msg.hasOptionalUint32()); - assertEquals(123, msg.getOptionalUint32()); - msg.clearOptionalUint32(); - assertFalse(msg.hasOptionalUint32()); - msg.clearOptionalUint32() - .setOptionalUint32(456); - assertTrue(msg.hasOptionalUint32()); - msg.clear(); - assertFalse(msg.hasOptionalUint32()); - - msg.setOptionalUint32(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 2); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalUint32()); - assertEquals(123, newMsg.getOptionalUint32()); - } - - public void testMicroOptionalUint64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalUint64()); - msg.setOptionalUint64(123); - assertTrue(msg.hasOptionalUint64()); - assertEquals(123, msg.getOptionalUint64()); - msg.clearOptionalUint64(); - assertFalse(msg.hasOptionalUint64()); - msg.clearOptionalUint64() - .setOptionalUint64(456); - assertTrue(msg.hasOptionalUint64()); - msg.clear(); - assertFalse(msg.hasOptionalUint64()); - - msg.setOptionalUint64(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 2); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalUint64()); - assertEquals(123, newMsg.getOptionalUint64()); - } - - public void testMicroOptionalSint32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalSint32()); - msg.setOptionalSint32(123); - assertTrue(msg.hasOptionalSint32()); - assertEquals(123, msg.getOptionalSint32()); - msg.clearOptionalSint32(); - assertFalse(msg.hasOptionalSint32()); - msg.clearOptionalSint32() - .setOptionalSint32(456); - assertTrue(msg.hasOptionalSint32()); - msg.clear(); - assertFalse(msg.hasOptionalSint32()); - - msg.setOptionalSint32(-123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalSint32()); - assertEquals(-123, newMsg.getOptionalSint32()); - } - - public void testMicroOptionalSint64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalSint64()); - msg.setOptionalSint64(123); - assertTrue(msg.hasOptionalSint64()); - assertEquals(123, msg.getOptionalSint64()); - msg.clearOptionalSint64(); - assertFalse(msg.hasOptionalSint64()); - msg.clearOptionalSint64() - .setOptionalSint64(456); - assertTrue(msg.hasOptionalSint64()); - msg.clear(); - assertFalse(msg.hasOptionalSint64()); - - msg.setOptionalSint64(-123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalSint64()); - assertEquals(-123, newMsg.getOptionalSint64()); - } - - public void testMicroOptionalFixed32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalFixed32()); - msg.setOptionalFixed32(123); - assertTrue(msg.hasOptionalFixed32()); - assertEquals(123, msg.getOptionalFixed32()); - msg.clearOptionalFixed32(); - assertFalse(msg.hasOptionalFixed32()); - msg.clearOptionalFixed32() - .setOptionalFixed32(456); - assertTrue(msg.hasOptionalFixed32()); - msg.clear(); - assertFalse(msg.hasOptionalFixed32()); - - msg.setOptionalFixed32(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalFixed32()); - assertEquals(123, newMsg.getOptionalFixed32()); - } - - public void testMicroOptionalFixed64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalFixed64()); - msg.setOptionalFixed64(123); - assertTrue(msg.hasOptionalFixed64()); - assertEquals(123, msg.getOptionalFixed64()); - msg.clearOptionalFixed64(); - assertFalse(msg.hasOptionalFixed64()); - msg.clearOptionalFixed64() - .setOptionalFixed64(456); - assertTrue(msg.hasOptionalFixed64()); - msg.clear(); - assertFalse(msg.hasOptionalFixed64()); - - msg.setOptionalFixed64(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 9); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalFixed64()); - assertEquals(123, newMsg.getOptionalFixed64()); - } - public void testMicroOptionalSfixed32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalSfixed32()); - msg.setOptionalSfixed32(123); - assertTrue(msg.hasOptionalSfixed32()); - assertEquals(123, msg.getOptionalSfixed32()); - msg.clearOptionalSfixed32(); - assertFalse(msg.hasOptionalSfixed32()); - msg.clearOptionalSfixed32() - .setOptionalSfixed32(456); - assertTrue(msg.hasOptionalSfixed32()); - msg.clear(); - assertFalse(msg.hasOptionalSfixed32()); - - msg.setOptionalSfixed32(123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalSfixed32()); - assertEquals(123, newMsg.getOptionalSfixed32()); - } - - public void testMicroOptionalSfixed64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalSfixed64()); - msg.setOptionalSfixed64(123); - assertTrue(msg.hasOptionalSfixed64()); - assertEquals(123, msg.getOptionalSfixed64()); - msg.clearOptionalSfixed64(); - assertFalse(msg.hasOptionalSfixed64()); - msg.clearOptionalSfixed64() - .setOptionalSfixed64(456); - assertTrue(msg.hasOptionalSfixed64()); - msg.clear(); - assertFalse(msg.hasOptionalSfixed64()); - - msg.setOptionalSfixed64(-123); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 9); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalSfixed64()); - assertEquals(-123, newMsg.getOptionalSfixed64()); - } - - public void testMicroOptionalFloat() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalFloat()); - msg.setOptionalFloat(123f); - assertTrue(msg.hasOptionalFloat()); - assertTrue(123.0f == msg.getOptionalFloat()); - msg.clearOptionalFloat(); - assertFalse(msg.hasOptionalFloat()); - msg.clearOptionalFloat() - .setOptionalFloat(456.0f); - assertTrue(msg.hasOptionalFloat()); - msg.clear(); - assertFalse(msg.hasOptionalFloat()); - - msg.setOptionalFloat(-123.456f); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalFloat()); - assertTrue(-123.456f == newMsg.getOptionalFloat()); - } - - public void testMicroOptionalDouble() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalDouble()); - msg.setOptionalDouble(123); - assertTrue(msg.hasOptionalDouble()); - assertTrue(123.0 == msg.getOptionalDouble()); - msg.clearOptionalDouble(); - assertFalse(msg.hasOptionalDouble()); - msg.clearOptionalDouble() - .setOptionalDouble(456.0); - assertTrue(msg.hasOptionalDouble()); - msg.clear(); - assertFalse(msg.hasOptionalDouble()); - - msg.setOptionalDouble(-123.456); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 9); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalDouble()); - assertTrue(-123.456 == newMsg.getOptionalDouble()); - } - - public void testMicroOptionalBool() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalBool()); - msg.setOptionalBool(true); - assertTrue(msg.hasOptionalBool()); - assertEquals(true, msg.getOptionalBool()); - msg.clearOptionalBool(); - assertFalse(msg.hasOptionalBool()); - msg.clearOptionalBool() - .setOptionalBool(true); - assertTrue(msg.hasOptionalBool()); - msg.clear(); - assertFalse(msg.hasOptionalBool()); - - msg.setOptionalBool(false); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 2); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalBool()); - assertEquals(false, newMsg.getOptionalBool()); - } - - public void testMicroOptionalString() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalString()); - msg.setOptionalString("hello"); - assertTrue(msg.hasOptionalString()); - assertEquals("hello", msg.getOptionalString()); - msg.clearOptionalString(); - assertFalse(msg.hasOptionalString()); - msg.clearOptionalString() - .setOptionalString("hello"); - assertTrue(msg.hasOptionalString()); - msg.clear(); - assertFalse(msg.hasOptionalString()); - - msg.setOptionalString("bye"); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalString()); - assertEquals("bye", newMsg.getOptionalString()); - } - - public void testMicroOptionalBytes() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalBytes()); - msg.setOptionalBytes(ByteStringMicro.copyFromUtf8("hello")); - assertTrue(msg.hasOptionalBytes()); - assertEquals("hello", msg.getOptionalBytes().toStringUtf8()); - msg.clearOptionalBytes(); - assertFalse(msg.hasOptionalBytes()); - msg.clearOptionalBytes() - .setOptionalBytes(ByteStringMicro.copyFromUtf8("hello")); - assertTrue(msg.hasOptionalBytes()); - msg.clear(); - assertFalse(msg.hasOptionalBytes()); - - msg.setOptionalBytes(ByteStringMicro.copyFromUtf8("bye")); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalBytes()); - assertEquals("bye", newMsg.getOptionalBytes().toStringUtf8()); - } - - public void testMicroOptionalGroup() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - TestAllTypesMicro.OptionalGroup grp = new TestAllTypesMicro.OptionalGroup(); - grp.setA(1); - assertFalse(msg.hasOptionalGroup()); - msg.setOptionalGroup(grp); - assertTrue(msg.hasOptionalGroup()); - assertEquals(1, msg.getOptionalGroup().getA()); - msg.clearOptionalGroup(); - assertFalse(msg.hasOptionalGroup()); - msg.clearOptionalGroup() - .setOptionalGroup(new TestAllTypesMicro.OptionalGroup().setA(2)); - assertTrue(msg.hasOptionalGroup()); - msg.clear(); - assertFalse(msg.hasOptionalGroup()); - - msg.setOptionalGroup(grp); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 7); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalGroup()); - assertEquals(1, newMsg.getOptionalGroup().getA()); - } - - public void testMicroOptionalNestedMessage() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - TestAllTypesMicro.NestedMessage nestedMsg = new TestAllTypesMicro.NestedMessage(); - nestedMsg.setBb(1); - assertFalse(msg.hasOptionalNestedMessage()); - msg.setOptionalNestedMessage(nestedMsg); - assertTrue(msg.hasOptionalNestedMessage()); - assertEquals(1, msg.getOptionalNestedMessage().getBb()); - msg.clearOptionalNestedMessage(); - assertFalse(msg.hasOptionalNestedMessage()); - msg.clearOptionalNestedMessage() - .setOptionalNestedMessage(new TestAllTypesMicro.NestedMessage().setBb(2)); - assertTrue(msg.hasOptionalNestedMessage()); - msg.clear(); - assertFalse(msg.hasOptionalNestedMessage()); - - msg.setOptionalNestedMessage(nestedMsg); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalNestedMessage()); - assertEquals(1, newMsg.getOptionalNestedMessage().getBb()); - } - - public void testMicroOptionalForeignMessage() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - MicroOuterClass.ForeignMessageMicro foreignMsg = - new MicroOuterClass.ForeignMessageMicro(); - assertFalse(foreignMsg.hasC()); - foreignMsg.setC(1); - assertTrue(foreignMsg.hasC()); - assertFalse(msg.hasOptionalForeignMessage()); - msg.setOptionalForeignMessage(foreignMsg); - assertTrue(msg.hasOptionalForeignMessage()); - assertEquals(1, msg.getOptionalForeignMessage().getC()); - msg.clearOptionalForeignMessage(); - assertFalse(msg.hasOptionalForeignMessage()); - msg.clearOptionalForeignMessage() - .setOptionalForeignMessage(new MicroOuterClass.ForeignMessageMicro().setC(2)); - assertTrue(msg.hasOptionalForeignMessage()); - msg.clear(); - assertFalse(msg.hasOptionalForeignMessage()); - - msg.setOptionalForeignMessage(foreignMsg); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalForeignMessage()); - assertEquals(1, newMsg.getOptionalForeignMessage().getC()); - } - - public void testMicroOptionalImportMessage() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - UnittestImportMicro.ImportMessageMicro importMsg = - new UnittestImportMicro.ImportMessageMicro(); - assertFalse(importMsg.hasD()); - importMsg.setD(1); - assertTrue(importMsg.hasD()); - assertFalse(msg.hasOptionalImportMessage()); - msg.setOptionalImportMessage(importMsg); - assertTrue(msg.hasOptionalImportMessage()); - assertEquals(1, msg.getOptionalImportMessage().getD()); - msg.clearOptionalImportMessage(); - assertFalse(msg.hasOptionalImportMessage()); - msg.clearOptionalImportMessage() - .setOptionalImportMessage(new UnittestImportMicro.ImportMessageMicro().setD(2)); - assertTrue(msg.hasOptionalImportMessage()); - msg.clear(); - assertFalse(msg.hasOptionalImportMessage()); - - msg.setOptionalImportMessage(importMsg); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalImportMessage()); - assertEquals(1, newMsg.getOptionalImportMessage().getD()); - } - - public void testMicroOptionalNestedEnum() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - msg.setOptionalNestedEnum(TestAllTypesMicro.BAR); - assertTrue(msg.hasOptionalNestedEnum()); - assertEquals(TestAllTypesMicro.BAR, msg.getOptionalNestedEnum()); - msg.clearOptionalNestedEnum(); - assertFalse(msg.hasOptionalNestedEnum()); - msg.clearOptionalNestedEnum() - .setOptionalNestedEnum(TestAllTypesMicro.BAZ); - assertTrue(msg.hasOptionalNestedEnum()); - msg.clear(); - assertFalse(msg.hasOptionalNestedEnum()); - - msg.setOptionalNestedEnum(TestAllTypesMicro.BAR); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalNestedEnum()); - assertEquals(TestAllTypesMicro.BAR, newMsg.getOptionalNestedEnum()); - } - - public void testMicroOptionalForeignEnum() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - msg.setOptionalForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR); - assertTrue(msg.hasOptionalForeignEnum()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, - msg.getOptionalForeignEnum()); - msg.clearOptionalForeignEnum(); - assertFalse(msg.hasOptionalForeignEnum()); - msg.clearOptionalForeignEnum() - .setOptionalForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAZ); - assertTrue(msg.hasOptionalForeignEnum()); - msg.clear(); - assertFalse(msg.hasOptionalForeignEnum()); - - msg.setOptionalForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalForeignEnum()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, - newMsg.getOptionalForeignEnum()); - } - - public void testMicroOptionalImportEnum() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - msg.setOptionalImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR); - assertTrue(msg.hasOptionalImportEnum()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, - msg.getOptionalImportEnum()); - msg.clearOptionalImportEnum(); - assertFalse(msg.hasOptionalImportEnum()); - msg.clearOptionalImportEnum() - .setOptionalImportEnum(UnittestImportMicro.IMPORT_MICRO_BAZ); - assertTrue(msg.hasOptionalImportEnum()); - msg.clear(); - assertFalse(msg.hasOptionalImportEnum()); - - msg.setOptionalImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalImportEnum()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, - newMsg.getOptionalImportEnum()); - } - - public void testMicroOptionalStringPiece() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalStringPiece()); - msg.setOptionalStringPiece("hello"); - assertTrue(msg.hasOptionalStringPiece()); - assertEquals("hello", msg.getOptionalStringPiece()); - msg.clearOptionalStringPiece(); - assertFalse(msg.hasOptionalStringPiece()); - msg.clearOptionalStringPiece() - .setOptionalStringPiece("hello"); - assertTrue(msg.hasOptionalStringPiece()); - msg.clear(); - assertFalse(msg.hasOptionalStringPiece()); - - msg.setOptionalStringPiece("bye"); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalStringPiece()); - assertEquals("bye", newMsg.getOptionalStringPiece()); - } - - public void testMicroOptionalCord() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasOptionalCord()); - msg.setOptionalCord("hello"); - assertTrue(msg.hasOptionalCord()); - assertEquals("hello", msg.getOptionalCord()); - msg.clearOptionalCord(); - assertFalse(msg.hasOptionalCord()); - msg.clearOptionalCord() - .setOptionalCord("hello"); - assertTrue(msg.hasOptionalCord()); - msg.clear(); - assertFalse(msg.hasOptionalCord()); - - msg.setOptionalCord("bye"); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertTrue(newMsg.hasOptionalCord()); - assertEquals("bye", newMsg.getOptionalCord()); - } - - public void testMicroRepeatedInt32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedInt32Count()); - msg.addRepeatedInt32(123); - assertEquals(1, msg.getRepeatedInt32Count()); - assertEquals(123, msg.getRepeatedInt32(0)); - msg.addRepeatedInt32(456); - assertEquals(2, msg.getRepeatedInt32Count()); - assertEquals(123, msg.getRepeatedInt32(0)); - assertEquals(456, msg.getRepeatedInt32(1)); - msg.setRepeatedInt32(0, 789); - assertEquals(2, msg.getRepeatedInt32Count()); - assertEquals(789, msg.getRepeatedInt32(0)); - assertEquals(456, msg.getRepeatedInt32(1)); - msg.clearRepeatedInt32(); - assertEquals(0, msg.getRepeatedInt32Count()); - msg.clearRepeatedInt32() - .addRepeatedInt32(456); - assertEquals(1, msg.getRepeatedInt32Count()); - assertEquals(456, msg.getRepeatedInt32(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedInt32Count()); - - // Test 1 entry - msg.clear() - .addRepeatedInt32(123); - assertEquals(1, msg.getRepeatedInt32Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedInt32Count()); - assertEquals(123, newMsg.getRepeatedInt32(0)); - - // Test 2 entries - msg.clear() - .addRepeatedInt32(123) - .addRepeatedInt32(456); - assertEquals(2, msg.getRepeatedInt32Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 7); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedInt32Count()); - assertEquals(123, newMsg.getRepeatedInt32(0)); - assertEquals(456, newMsg.getRepeatedInt32(1)); - } - - public void testMicroRepeatedInt64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedInt64Count()); - msg.addRepeatedInt64(123); - assertEquals(1, msg.getRepeatedInt64Count()); - assertEquals(123, msg.getRepeatedInt64(0)); - msg.addRepeatedInt64(456); - assertEquals(2, msg.getRepeatedInt64Count()); - assertEquals(123, msg.getRepeatedInt64(0)); - assertEquals(456, msg.getRepeatedInt64(1)); - msg.setRepeatedInt64(0, 789); - assertEquals(2, msg.getRepeatedInt64Count()); - assertEquals(789, msg.getRepeatedInt64(0)); - assertEquals(456, msg.getRepeatedInt64(1)); - msg.clearRepeatedInt64(); - assertEquals(0, msg.getRepeatedInt64Count()); - msg.clearRepeatedInt64() - .addRepeatedInt64(456); - assertEquals(1, msg.getRepeatedInt64Count()); - assertEquals(456, msg.getRepeatedInt64(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedInt64Count()); - - // Test 1 entry - msg.clear() - .addRepeatedInt64(123); - assertEquals(1, msg.getRepeatedInt64Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedInt64Count()); - assertEquals(123, newMsg.getRepeatedInt64(0)); - - // Test 2 entries - msg.clear() - .addRepeatedInt64(123) - .addRepeatedInt64(456); - assertEquals(2, msg.getRepeatedInt64Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 7); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedInt64Count()); - assertEquals(123, newMsg.getRepeatedInt64(0)); - assertEquals(456, newMsg.getRepeatedInt64(1)); - } - - public void testMicroRepeatedUint32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedUint32Count()); - msg.addRepeatedUint32(123); - assertEquals(1, msg.getRepeatedUint32Count()); - assertEquals(123, msg.getRepeatedUint32(0)); - msg.addRepeatedUint32(456); - assertEquals(2, msg.getRepeatedUint32Count()); - assertEquals(123, msg.getRepeatedUint32(0)); - assertEquals(456, msg.getRepeatedUint32(1)); - msg.setRepeatedUint32(0, 789); - assertEquals(2, msg.getRepeatedUint32Count()); - assertEquals(789, msg.getRepeatedUint32(0)); - assertEquals(456, msg.getRepeatedUint32(1)); - msg.clearRepeatedUint32(); - assertEquals(0, msg.getRepeatedUint32Count()); - msg.clearRepeatedUint32() - .addRepeatedUint32(456); - assertEquals(1, msg.getRepeatedUint32Count()); - assertEquals(456, msg.getRepeatedUint32(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedUint32Count()); - - // Test 1 entry - msg.clear() - .addRepeatedUint32(123); - assertEquals(1, msg.getRepeatedUint32Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedUint32Count()); - assertEquals(123, newMsg.getRepeatedUint32(0)); - - // Test 2 entries - msg.clear() - .addRepeatedUint32(123) - .addRepeatedUint32(456); - assertEquals(2, msg.getRepeatedUint32Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 7); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedUint32Count()); - assertEquals(123, newMsg.getRepeatedUint32(0)); - assertEquals(456, newMsg.getRepeatedUint32(1)); - } - - public void testMicroRepeatedUint64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedUint64Count()); - msg.addRepeatedUint64(123); - assertEquals(1, msg.getRepeatedUint64Count()); - assertEquals(123, msg.getRepeatedUint64(0)); - msg.addRepeatedUint64(456); - assertEquals(2, msg.getRepeatedUint64Count()); - assertEquals(123, msg.getRepeatedUint64(0)); - assertEquals(456, msg.getRepeatedUint64(1)); - msg.setRepeatedUint64(0, 789); - assertEquals(2, msg.getRepeatedUint64Count()); - assertEquals(789, msg.getRepeatedUint64(0)); - assertEquals(456, msg.getRepeatedUint64(1)); - msg.clearRepeatedUint64(); - assertEquals(0, msg.getRepeatedUint64Count()); - msg.clearRepeatedUint64() - .addRepeatedUint64(456); - assertEquals(1, msg.getRepeatedUint64Count()); - assertEquals(456, msg.getRepeatedUint64(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedUint64Count()); - - // Test 1 entry - msg.clear() - .addRepeatedUint64(123); - assertEquals(1, msg.getRepeatedUint64Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedUint64Count()); - assertEquals(123, newMsg.getRepeatedUint64(0)); - - // Test 2 entries - msg.clear() - .addRepeatedUint64(123) - .addRepeatedUint64(456); - assertEquals(2, msg.getRepeatedUint64Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 7); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedUint64Count()); - assertEquals(123, newMsg.getRepeatedUint64(0)); - assertEquals(456, newMsg.getRepeatedUint64(1)); - } - - public void testMicroRepeatedSint32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedSint32Count()); - msg.addRepeatedSint32(123); - assertEquals(1, msg.getRepeatedSint32Count()); - assertEquals(123, msg.getRepeatedSint32(0)); - msg.addRepeatedSint32(456); - assertEquals(2, msg.getRepeatedSint32Count()); - assertEquals(123, msg.getRepeatedSint32(0)); - assertEquals(456, msg.getRepeatedSint32(1)); - msg.setRepeatedSint32(0, 789); - assertEquals(2, msg.getRepeatedSint32Count()); - assertEquals(789, msg.getRepeatedSint32(0)); - assertEquals(456, msg.getRepeatedSint32(1)); - msg.clearRepeatedSint32(); - assertEquals(0, msg.getRepeatedSint32Count()); - msg.clearRepeatedSint32() - .addRepeatedSint32(456); - assertEquals(1, msg.getRepeatedSint32Count()); - assertEquals(456, msg.getRepeatedSint32(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedSint32Count()); - - // Test 1 entry - msg.clear() - .addRepeatedSint32(123); - assertEquals(1, msg.getRepeatedSint32Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 4); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedSint32Count()); - assertEquals(123, newMsg.getRepeatedSint32(0)); - - // Test 2 entries - msg.clear() - .addRepeatedSint32(123) - .addRepeatedSint32(456); - assertEquals(2, msg.getRepeatedSint32Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 8); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedSint32Count()); - assertEquals(123, newMsg.getRepeatedSint32(0)); - assertEquals(456, newMsg.getRepeatedSint32(1)); - } - - public void testMicroRepeatedSint64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedSint64Count()); - msg.addRepeatedSint64(123); - assertEquals(1, msg.getRepeatedSint64Count()); - assertEquals(123, msg.getRepeatedSint64(0)); - msg.addRepeatedSint64(456); - assertEquals(2, msg.getRepeatedSint64Count()); - assertEquals(123, msg.getRepeatedSint64(0)); - assertEquals(456, msg.getRepeatedSint64(1)); - msg.setRepeatedSint64(0, 789); - assertEquals(2, msg.getRepeatedSint64Count()); - assertEquals(789, msg.getRepeatedSint64(0)); - assertEquals(456, msg.getRepeatedSint64(1)); - msg.clearRepeatedSint64(); - assertEquals(0, msg.getRepeatedSint64Count()); - msg.clearRepeatedSint64() - .addRepeatedSint64(456); - assertEquals(1, msg.getRepeatedSint64Count()); - assertEquals(456, msg.getRepeatedSint64(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedSint64Count()); - - // Test 1 entry - msg.clear() - .addRepeatedSint64(123); - assertEquals(1, msg.getRepeatedSint64Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 4); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedSint64Count()); - assertEquals(123, newMsg.getRepeatedSint64(0)); - - // Test 2 entries - msg.clear() - .addRepeatedSint64(123) - .addRepeatedSint64(456); - assertEquals(2, msg.getRepeatedSint64Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 8); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedSint64Count()); - assertEquals(123, newMsg.getRepeatedSint64(0)); - assertEquals(456, newMsg.getRepeatedSint64(1)); - } - - public void testMicroRepeatedFixed32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedFixed32Count()); - msg.addRepeatedFixed32(123); - assertEquals(1, msg.getRepeatedFixed32Count()); - assertEquals(123, msg.getRepeatedFixed32(0)); - msg.addRepeatedFixed32(456); - assertEquals(2, msg.getRepeatedFixed32Count()); - assertEquals(123, msg.getRepeatedFixed32(0)); - assertEquals(456, msg.getRepeatedFixed32(1)); - msg.setRepeatedFixed32(0, 789); - assertEquals(2, msg.getRepeatedFixed32Count()); - assertEquals(789, msg.getRepeatedFixed32(0)); - assertEquals(456, msg.getRepeatedFixed32(1)); - msg.clearRepeatedFixed32(); - assertEquals(0, msg.getRepeatedFixed32Count()); - msg.clearRepeatedFixed32() - .addRepeatedFixed32(456); - assertEquals(1, msg.getRepeatedFixed32Count()); - assertEquals(456, msg.getRepeatedFixed32(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedFixed32Count()); - - // Test 1 entry - msg.clear() - .addRepeatedFixed32(123); - assertEquals(1, msg.getRepeatedFixed32Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedFixed32Count()); - assertEquals(123, newMsg.getRepeatedFixed32(0)); - - // Test 2 entries - msg.clear() - .addRepeatedFixed32(123) - .addRepeatedFixed32(456); - assertEquals(2, msg.getRepeatedFixed32Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 12); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedFixed32Count()); - assertEquals(123, newMsg.getRepeatedFixed32(0)); - assertEquals(456, newMsg.getRepeatedFixed32(1)); - } - - public void testMicroRepeatedFixed64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedFixed64Count()); - msg.addRepeatedFixed64(123); - assertEquals(1, msg.getRepeatedFixed64Count()); - assertEquals(123, msg.getRepeatedFixed64(0)); - msg.addRepeatedFixed64(456); - assertEquals(2, msg.getRepeatedFixed64Count()); - assertEquals(123, msg.getRepeatedFixed64(0)); - assertEquals(456, msg.getRepeatedFixed64(1)); - msg.setRepeatedFixed64(0, 789); - assertEquals(2, msg.getRepeatedFixed64Count()); - assertEquals(789, msg.getRepeatedFixed64(0)); - assertEquals(456, msg.getRepeatedFixed64(1)); - msg.clearRepeatedFixed64(); - assertEquals(0, msg.getRepeatedFixed64Count()); - msg.clearRepeatedFixed64() - .addRepeatedFixed64(456); - assertEquals(1, msg.getRepeatedFixed64Count()); - assertEquals(456, msg.getRepeatedFixed64(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedFixed64Count()); - - // Test 1 entry - msg.clear() - .addRepeatedFixed64(123); - assertEquals(1, msg.getRepeatedFixed64Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 10); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedFixed64Count()); - assertEquals(123, newMsg.getRepeatedFixed64(0)); - - // Test 2 entries - msg.clear() - .addRepeatedFixed64(123) - .addRepeatedFixed64(456); - assertEquals(2, msg.getRepeatedFixed64Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 20); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedFixed64Count()); - assertEquals(123, newMsg.getRepeatedFixed64(0)); - assertEquals(456, newMsg.getRepeatedFixed64(1)); - } - - public void testMicroRepeatedSfixed32() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedSfixed32Count()); - msg.addRepeatedSfixed32(123); - assertEquals(1, msg.getRepeatedSfixed32Count()); - assertEquals(123, msg.getRepeatedSfixed32(0)); - msg.addRepeatedSfixed32(456); - assertEquals(2, msg.getRepeatedSfixed32Count()); - assertEquals(123, msg.getRepeatedSfixed32(0)); - assertEquals(456, msg.getRepeatedSfixed32(1)); - msg.setRepeatedSfixed32(0, 789); - assertEquals(2, msg.getRepeatedSfixed32Count()); - assertEquals(789, msg.getRepeatedSfixed32(0)); - assertEquals(456, msg.getRepeatedSfixed32(1)); - msg.clearRepeatedSfixed32(); - assertEquals(0, msg.getRepeatedSfixed32Count()); - msg.clearRepeatedSfixed32() - .addRepeatedSfixed32(456); - assertEquals(1, msg.getRepeatedSfixed32Count()); - assertEquals(456, msg.getRepeatedSfixed32(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedSfixed32Count()); - - // Test 1 entry - msg.clear() - .addRepeatedSfixed32(123); - assertEquals(1, msg.getRepeatedSfixed32Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedSfixed32Count()); - assertEquals(123, newMsg.getRepeatedSfixed32(0)); - - // Test 2 entries - msg.clear() - .addRepeatedSfixed32(123) - .addRepeatedSfixed32(456); - assertEquals(2, msg.getRepeatedSfixed32Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 12); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedSfixed32Count()); - assertEquals(123, newMsg.getRepeatedSfixed32(0)); - assertEquals(456, newMsg.getRepeatedSfixed32(1)); - } - - public void testMicroRepeatedSfixed64() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedSfixed64Count()); - msg.addRepeatedSfixed64(123); - assertEquals(1, msg.getRepeatedSfixed64Count()); - assertEquals(123, msg.getRepeatedSfixed64(0)); - msg.addRepeatedSfixed64(456); - assertEquals(2, msg.getRepeatedSfixed64Count()); - assertEquals(123, msg.getRepeatedSfixed64(0)); - assertEquals(456, msg.getRepeatedSfixed64(1)); - msg.setRepeatedSfixed64(0, 789); - assertEquals(2, msg.getRepeatedSfixed64Count()); - assertEquals(789, msg.getRepeatedSfixed64(0)); - assertEquals(456, msg.getRepeatedSfixed64(1)); - msg.clearRepeatedSfixed64(); - assertEquals(0, msg.getRepeatedSfixed64Count()); - msg.clearRepeatedSfixed64() - .addRepeatedSfixed64(456); - assertEquals(1, msg.getRepeatedSfixed64Count()); - assertEquals(456, msg.getRepeatedSfixed64(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedSfixed64Count()); - - // Test 1 entry - msg.clear() - .addRepeatedSfixed64(123); - assertEquals(1, msg.getRepeatedSfixed64Count()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 10); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedSfixed64Count()); - assertEquals(123, newMsg.getRepeatedSfixed64(0)); - - // Test 2 entries - msg.clear() - .addRepeatedSfixed64(123) - .addRepeatedSfixed64(456); - assertEquals(2, msg.getRepeatedSfixed64Count()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 20); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedSfixed64Count()); - assertEquals(123, newMsg.getRepeatedSfixed64(0)); - assertEquals(456, newMsg.getRepeatedSfixed64(1)); - } - - public void testMicroRepeatedFloat() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedFloatCount()); - msg.addRepeatedFloat(123f); - assertEquals(1, msg.getRepeatedFloatCount()); - assertTrue(123f == msg.getRepeatedFloat(0)); - msg.addRepeatedFloat(456f); - assertEquals(2, msg.getRepeatedFloatCount()); - assertTrue(123f == msg.getRepeatedFloat(0)); - assertTrue(456f == msg.getRepeatedFloat(1)); - msg.setRepeatedFloat(0, 789f); - assertEquals(2, msg.getRepeatedFloatCount()); - assertTrue(789f == msg.getRepeatedFloat(0)); - assertTrue(456f == msg.getRepeatedFloat(1)); - msg.clearRepeatedFloat(); - assertEquals(0, msg.getRepeatedFloatCount()); - msg.clearRepeatedFloat() - .addRepeatedFloat(456f); - assertEquals(1, msg.getRepeatedFloatCount()); - assertTrue(456f == msg.getRepeatedFloat(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedFloatCount()); - - // Test 1 entry - msg.clear() - .addRepeatedFloat(123f); - assertEquals(1, msg.getRepeatedFloatCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedFloatCount()); - assertTrue(123f == newMsg.getRepeatedFloat(0)); - - // Test 2 entries - msg.clear() - .addRepeatedFloat(123f) - .addRepeatedFloat(456f); - assertEquals(2, msg.getRepeatedFloatCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 12); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedFloatCount()); - assertTrue(123f == newMsg.getRepeatedFloat(0)); - assertTrue(456f == newMsg.getRepeatedFloat(1)); - } - - public void testMicroRepeatedDouble() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedDoubleCount()); - msg.addRepeatedDouble(123.0); - assertEquals(1, msg.getRepeatedDoubleCount()); - assertTrue(123.0 == msg.getRepeatedDouble(0)); - msg.addRepeatedDouble(456.0); - assertEquals(2, msg.getRepeatedDoubleCount()); - assertTrue(123.0 == msg.getRepeatedDouble(0)); - assertTrue(456.0 == msg.getRepeatedDouble(1)); - msg.setRepeatedDouble(0, 789.0); - assertEquals(2, msg.getRepeatedDoubleCount()); - assertTrue(789.0 == msg.getRepeatedDouble(0)); - assertTrue(456.0 == msg.getRepeatedDouble(1)); - msg.clearRepeatedDouble(); - assertEquals(0, msg.getRepeatedDoubleCount()); - msg.clearRepeatedDouble() - .addRepeatedDouble(456.0); - assertEquals(1, msg.getRepeatedDoubleCount()); - assertTrue(456.0 == msg.getRepeatedDouble(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedDoubleCount()); - - // Test 1 entry - msg.clear() - .addRepeatedDouble(123.0); - assertEquals(1, msg.getRepeatedDoubleCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 10); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedDoubleCount()); - assertTrue(123.0 == newMsg.getRepeatedDouble(0)); - - // Test 2 entries - msg.clear() - .addRepeatedDouble(123.0) - .addRepeatedDouble(456.0); - assertEquals(2, msg.getRepeatedDoubleCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 20); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedDoubleCount()); - assertTrue(123.0 == newMsg.getRepeatedDouble(0)); - assertTrue(456.0 == newMsg.getRepeatedDouble(1)); - } - - public void testMicroRepeatedBool() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedBoolCount()); - msg.addRepeatedBool(true); - assertEquals(1, msg.getRepeatedBoolCount()); - assertEquals(true, msg.getRepeatedBool(0)); - msg.addRepeatedBool(false); - assertEquals(2, msg.getRepeatedBoolCount()); - assertEquals(true, msg.getRepeatedBool(0)); - assertEquals(false, msg.getRepeatedBool(1)); - msg.setRepeatedBool(0, false); - assertEquals(2, msg.getRepeatedBoolCount()); - assertEquals(false, msg.getRepeatedBool(0)); - assertEquals(false, msg.getRepeatedBool(1)); - msg.clearRepeatedBool(); - assertEquals(0, msg.getRepeatedBoolCount()); - msg.clearRepeatedBool() - .addRepeatedBool(true); - assertEquals(1, msg.getRepeatedBoolCount()); - assertEquals(true, msg.getRepeatedBool(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedBoolCount()); - - // Test 1 entry - msg.clear() - .addRepeatedBool(false); - assertEquals(1, msg.getRepeatedBoolCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedBoolCount()); - assertEquals(false, newMsg.getRepeatedBool(0)); - - // Test 2 entries - msg.clear() - .addRepeatedBool(true) - .addRepeatedBool(false); - assertEquals(2, msg.getRepeatedBoolCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedBoolCount()); - assertEquals(true, newMsg.getRepeatedBool(0)); - assertEquals(false, newMsg.getRepeatedBool(1)); - } - - public void testMicroRepeatedString() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedStringCount()); - msg.addRepeatedString("hello"); - assertEquals(1, msg.getRepeatedStringCount()); - assertEquals("hello", msg.getRepeatedString(0)); - msg.addRepeatedString("bye"); - assertEquals(2, msg.getRepeatedStringCount()); - assertEquals("hello", msg.getRepeatedString(0)); - assertEquals("bye", msg.getRepeatedString(1)); - msg.setRepeatedString(0, "boo"); - assertEquals(2, msg.getRepeatedStringCount()); - assertEquals("boo", msg.getRepeatedString(0)); - assertEquals("bye", msg.getRepeatedString(1)); - msg.clearRepeatedString(); - assertEquals(0, msg.getRepeatedStringCount()); - msg.clearRepeatedString() - .addRepeatedString("hello"); - assertEquals(1, msg.getRepeatedStringCount()); - assertEquals("hello", msg.getRepeatedString(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedStringCount()); - - // Test 1 entry and an empty string - msg.clear() - .addRepeatedString(""); - assertEquals(1, msg.getRepeatedStringCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedStringCount()); - assertEquals("", newMsg.getRepeatedString(0)); - - // Test 2 entries - msg.clear() - .addRepeatedString("hello") - .addRepeatedString("world"); - assertEquals(2, msg.getRepeatedStringCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 16); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedStringCount()); - assertEquals("hello", newMsg.getRepeatedString(0)); - assertEquals("world", newMsg.getRepeatedString(1)); - } - - public void testMicroRepeatedBytes() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedBytesCount()); - msg.addRepeatedBytes(ByteStringMicro.copyFromUtf8("hello")); - assertEquals(1, msg.getRepeatedBytesCount()); - assertEquals("hello", msg.getRepeatedBytes(0).toStringUtf8()); - msg.addRepeatedBytes(ByteStringMicro.copyFromUtf8("bye")); - assertEquals(2, msg.getRepeatedBytesCount()); - assertEquals("hello", msg.getRepeatedBytes(0).toStringUtf8()); - assertEquals("bye", msg.getRepeatedBytes(1).toStringUtf8()); - msg.setRepeatedBytes(0, ByteStringMicro.copyFromUtf8("boo")); - assertEquals(2, msg.getRepeatedBytesCount()); - assertEquals("boo", msg.getRepeatedBytes(0).toStringUtf8()); - assertEquals("bye", msg.getRepeatedBytes(1).toStringUtf8()); - msg.clearRepeatedBytes(); - assertEquals(0, msg.getRepeatedBytesCount()); - msg.clearRepeatedBytes() - .addRepeatedBytes(ByteStringMicro.copyFromUtf8("hello")); - assertEquals(1, msg.getRepeatedBytesCount()); - assertEquals("hello", msg.getRepeatedBytes(0).toStringUtf8()); - msg.clear(); - assertEquals(0, msg.getRepeatedBytesCount()); - - // Test 1 entry and an empty byte array can be serialized - msg.clear() - .addRepeatedBytes(ByteStringMicro.copyFromUtf8("")); - assertEquals(1, msg.getRepeatedBytesCount()); - assertEquals("", msg.getRepeatedBytes(0).toStringUtf8()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedBytesCount()); - assertEquals("", newMsg.getRepeatedBytes(0).toStringUtf8()); - - // Test 2 entries - msg.clear() - .addRepeatedBytes(ByteStringMicro.copyFromUtf8("hello")) - .addRepeatedBytes(ByteStringMicro.copyFromUtf8("world")); - assertEquals(2, msg.getRepeatedBytesCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 16); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedBytesCount()); - assertEquals("hello", newMsg.getRepeatedBytes(0).toStringUtf8()); - assertEquals("world", newMsg.getRepeatedBytes(1).toStringUtf8()); - } - - public void testMicroRepeatedGroup() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - TestAllTypesMicro.RepeatedGroup group0 = - new TestAllTypesMicro.RepeatedGroup().setA(0); - TestAllTypesMicro.RepeatedGroup group1 = - new TestAllTypesMicro.RepeatedGroup().setA(1); - TestAllTypesMicro.RepeatedGroup group2 = - new TestAllTypesMicro.RepeatedGroup().setA(2); - - msg.addRepeatedGroup(group0); - assertEquals(1, msg.getRepeatedGroupCount()); - assertEquals(0, msg.getRepeatedGroup(0).getA()); - msg.addRepeatedGroup(group1); - assertEquals(2, msg.getRepeatedGroupCount()); - assertEquals(0, msg.getRepeatedGroup(0).getA()); - assertEquals(1, msg.getRepeatedGroup(1).getA()); - msg.setRepeatedGroup(0, group2); - assertEquals(2, msg.getRepeatedGroupCount()); - assertEquals(2, msg.getRepeatedGroup(0).getA()); - assertEquals(1, msg.getRepeatedGroup(1).getA()); - msg.clearRepeatedGroup(); - assertEquals(0, msg.getRepeatedGroupCount()); - msg.clearRepeatedGroup() - .addRepeatedGroup(group1); - assertEquals(1, msg.getRepeatedGroupCount()); - assertEquals(1, msg.getRepeatedGroup(0).getA()); - msg.clear(); - assertEquals(0, msg.getRepeatedGroupCount()); - - // Test 1 entry - msg.clear() - .addRepeatedGroup(group0); - assertEquals(1, msg.getRepeatedGroupCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 7); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedGroupCount()); - assertEquals(0, newMsg.getRepeatedGroup(0).getA()); - - // Test 2 entries - msg.clear() - .addRepeatedGroup(group0) - .addRepeatedGroup(group1); - assertEquals(2, msg.getRepeatedGroupCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 14); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedGroupCount()); - assertEquals(0, newMsg.getRepeatedGroup(0).getA()); - assertEquals(1, newMsg.getRepeatedGroup(1).getA()); - } - - - public void testMicroRepeatedNestedMessage() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - TestAllTypesMicro.NestedMessage nestedMsg0 = - new TestAllTypesMicro.NestedMessage().setBb(0); - TestAllTypesMicro.NestedMessage nestedMsg1 = - new TestAllTypesMicro.NestedMessage().setBb(1); - TestAllTypesMicro.NestedMessage nestedMsg2 = - new TestAllTypesMicro.NestedMessage().setBb(2); - - msg.addRepeatedNestedMessage(nestedMsg0); - assertEquals(1, msg.getRepeatedNestedMessageCount()); - assertEquals(0, msg.getRepeatedNestedMessage(0).getBb()); - msg.addRepeatedNestedMessage(nestedMsg1); - assertEquals(2, msg.getRepeatedNestedMessageCount()); - assertEquals(0, msg.getRepeatedNestedMessage(0).getBb()); - assertEquals(1, msg.getRepeatedNestedMessage(1).getBb()); - msg.setRepeatedNestedMessage(0, nestedMsg2); - assertEquals(2, msg.getRepeatedNestedMessageCount()); - assertEquals(2, msg.getRepeatedNestedMessage(0).getBb()); - assertEquals(1, msg.getRepeatedNestedMessage(1).getBb()); - msg.clearRepeatedNestedMessage(); - assertEquals(0, msg.getRepeatedNestedMessageCount()); - msg.clearRepeatedNestedMessage() - .addRepeatedNestedMessage(nestedMsg1); - assertEquals(1, msg.getRepeatedNestedMessageCount()); - assertEquals(1, msg.getRepeatedNestedMessage(0).getBb()); - msg.clear(); - assertEquals(0, msg.getRepeatedNestedMessageCount()); - - // Test 1 entry - msg.clear() - .addRepeatedNestedMessage(nestedMsg0); - assertEquals(1, msg.getRepeatedNestedMessageCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedNestedMessageCount()); - assertEquals(0, newMsg.getRepeatedNestedMessage(0).getBb()); - - // Test 2 entries - msg.clear() - .addRepeatedNestedMessage(nestedMsg0) - .addRepeatedNestedMessage(nestedMsg1); - assertEquals(2, msg.getRepeatedNestedMessageCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 10); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedNestedMessageCount()); - assertEquals(0, newMsg.getRepeatedNestedMessage(0).getBb()); - assertEquals(1, newMsg.getRepeatedNestedMessage(1).getBb()); - } - - public void testMicroRepeatedForeignMessage() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - MicroOuterClass.ForeignMessageMicro foreignMsg0 = - new MicroOuterClass.ForeignMessageMicro().setC(0); - MicroOuterClass.ForeignMessageMicro foreignMsg1 = - new MicroOuterClass.ForeignMessageMicro().setC(1); - MicroOuterClass.ForeignMessageMicro foreignMsg2 = - new MicroOuterClass.ForeignMessageMicro().setC(2); - - msg.addRepeatedForeignMessage(foreignMsg0); - assertEquals(1, msg.getRepeatedForeignMessageCount()); - assertEquals(0, msg.getRepeatedForeignMessage(0).getC()); - msg.addRepeatedForeignMessage(foreignMsg1); - assertEquals(2, msg.getRepeatedForeignMessageCount()); - assertEquals(0, msg.getRepeatedForeignMessage(0).getC()); - assertEquals(1, msg.getRepeatedForeignMessage(1).getC()); - msg.setRepeatedForeignMessage(0, foreignMsg2); - assertEquals(2, msg.getRepeatedForeignMessageCount()); - assertEquals(2, msg.getRepeatedForeignMessage(0).getC()); - assertEquals(1, msg.getRepeatedForeignMessage(1).getC()); - msg.clearRepeatedForeignMessage(); - assertEquals(0, msg.getRepeatedForeignMessageCount()); - msg.clearRepeatedForeignMessage() - .addRepeatedForeignMessage(foreignMsg1); - assertEquals(1, msg.getRepeatedForeignMessageCount()); - assertEquals(1, msg.getRepeatedForeignMessage(0).getC()); - msg.clear(); - assertEquals(0, msg.getRepeatedForeignMessageCount()); - - // Test 1 entry - msg.clear() - .addRepeatedForeignMessage(foreignMsg0); - assertEquals(1, msg.getRepeatedForeignMessageCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedForeignMessageCount()); - assertEquals(0, newMsg.getRepeatedForeignMessage(0).getC()); - - // Test 2 entries - msg.clear() - .addRepeatedForeignMessage(foreignMsg0) - .addRepeatedForeignMessage(foreignMsg1); - assertEquals(2, msg.getRepeatedForeignMessageCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 10); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedForeignMessageCount()); - assertEquals(0, newMsg.getRepeatedForeignMessage(0).getC()); - assertEquals(1, newMsg.getRepeatedForeignMessage(1).getC()); - } - - public void testMicroRepeatedImportMessage() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - UnittestImportMicro.ImportMessageMicro importMsg0 = - new UnittestImportMicro.ImportMessageMicro().setD(0); - UnittestImportMicro.ImportMessageMicro importMsg1 = - new UnittestImportMicro.ImportMessageMicro().setD(1); - UnittestImportMicro.ImportMessageMicro importMsg2 = - new UnittestImportMicro.ImportMessageMicro().setD(2); - - msg.addRepeatedImportMessage(importMsg0); - assertEquals(1, msg.getRepeatedImportMessageCount()); - assertEquals(0, msg.getRepeatedImportMessage(0).getD()); - msg.addRepeatedImportMessage(importMsg1); - assertEquals(2, msg.getRepeatedImportMessageCount()); - assertEquals(0, msg.getRepeatedImportMessage(0).getD()); - assertEquals(1, msg.getRepeatedImportMessage(1).getD()); - msg.setRepeatedImportMessage(0, importMsg2); - assertEquals(2, msg.getRepeatedImportMessageCount()); - assertEquals(2, msg.getRepeatedImportMessage(0).getD()); - assertEquals(1, msg.getRepeatedImportMessage(1).getD()); - msg.clearRepeatedImportMessage(); - assertEquals(0, msg.getRepeatedImportMessageCount()); - msg.clearRepeatedImportMessage() - .addRepeatedImportMessage(importMsg1); - assertEquals(1, msg.getRepeatedImportMessageCount()); - assertEquals(1, msg.getRepeatedImportMessage(0).getD()); - msg.clear(); - assertEquals(0, msg.getRepeatedImportMessageCount()); - - // Test 1 entry - msg.clear() - .addRepeatedImportMessage(importMsg0); - assertEquals(1, msg.getRepeatedImportMessageCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 5); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedImportMessageCount()); - assertEquals(0, newMsg.getRepeatedImportMessage(0).getD()); - - // Test 2 entries - msg.clear() - .addRepeatedImportMessage(importMsg0) - .addRepeatedImportMessage(importMsg1); - assertEquals(2, msg.getRepeatedImportMessageCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 10); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedImportMessageCount()); - assertEquals(0, newMsg.getRepeatedImportMessage(0).getD()); - assertEquals(1, newMsg.getRepeatedImportMessage(1).getD()); - } - - public void testMicroRepeatedNestedEnum() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - msg.addRepeatedNestedEnum(TestAllTypesMicro.FOO); - assertEquals(1, msg.getRepeatedNestedEnumCount()); - assertEquals(TestAllTypesMicro.FOO, msg.getRepeatedNestedEnum(0)); - msg.addRepeatedNestedEnum(TestAllTypesMicro.BAR); - assertEquals(2, msg.getRepeatedNestedEnumCount()); - assertEquals(TestAllTypesMicro.FOO, msg.getRepeatedNestedEnum(0)); - assertEquals(TestAllTypesMicro.BAR, msg.getRepeatedNestedEnum(1)); - msg.setRepeatedNestedEnum(0, TestAllTypesMicro.BAZ); - assertEquals(2, msg.getRepeatedNestedEnumCount()); - assertEquals(TestAllTypesMicro.BAZ, msg.getRepeatedNestedEnum(0)); - assertEquals(TestAllTypesMicro.BAR, msg.getRepeatedNestedEnum(1)); - msg.clearRepeatedNestedEnum(); - assertEquals(0, msg.getRepeatedNestedEnumCount()); - msg.clearRepeatedNestedEnum() - .addRepeatedNestedEnum(TestAllTypesMicro.BAR); - assertEquals(1, msg.getRepeatedNestedEnumCount()); - assertEquals(TestAllTypesMicro.BAR, msg.getRepeatedNestedEnum(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedNestedEnumCount()); - - // Test 1 entry - msg.clear() - .addRepeatedNestedEnum(TestAllTypesMicro.FOO); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedNestedEnumCount()); - assertEquals(TestAllTypesMicro.FOO, msg.getRepeatedNestedEnum(0)); - - // Test 2 entries - msg.clear() - .addRepeatedNestedEnum(TestAllTypesMicro.FOO) - .addRepeatedNestedEnum(TestAllTypesMicro.BAR); - assertEquals(2, msg.getRepeatedNestedEnumCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedNestedEnumCount()); - assertEquals(TestAllTypesMicro.FOO, msg.getRepeatedNestedEnum(0)); - assertEquals(TestAllTypesMicro.BAR, msg.getRepeatedNestedEnum(1)); - } - - public void testMicroRepeatedForeignEnum() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - msg.addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_FOO); - assertEquals(1, msg.getRepeatedForeignEnumCount()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_FOO, msg.getRepeatedForeignEnum(0)); - msg.addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR); - assertEquals(2, msg.getRepeatedForeignEnumCount()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_FOO, msg.getRepeatedForeignEnum(0)); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getRepeatedForeignEnum(1)); - msg.setRepeatedForeignEnum(0, MicroOuterClass.FOREIGN_MICRO_BAZ); - assertEquals(2, msg.getRepeatedForeignEnumCount()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAZ, msg.getRepeatedForeignEnum(0)); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getRepeatedForeignEnum(1)); - msg.clearRepeatedForeignEnum(); - assertEquals(0, msg.getRepeatedForeignEnumCount()); - msg.clearRepeatedForeignEnum() - .addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR); - assertEquals(1, msg.getRepeatedForeignEnumCount()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getRepeatedForeignEnum(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedForeignEnumCount()); - - // Test 1 entry - msg.clear() - .addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_FOO); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedForeignEnumCount()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_FOO, msg.getRepeatedForeignEnum(0)); - - // Test 2 entries - msg.clear() - .addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_FOO) - .addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR); - assertEquals(2, msg.getRepeatedForeignEnumCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedForeignEnumCount()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_FOO, msg.getRepeatedForeignEnum(0)); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getRepeatedForeignEnum(1)); - } - - public void testMicroRepeatedImportEnum() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - msg.addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_FOO); - assertEquals(1, msg.getRepeatedImportEnumCount()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_FOO, msg.getRepeatedImportEnum(0)); - msg.addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR); - assertEquals(2, msg.getRepeatedImportEnumCount()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_FOO, msg.getRepeatedImportEnum(0)); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getRepeatedImportEnum(1)); - msg.setRepeatedImportEnum(0, UnittestImportMicro.IMPORT_MICRO_BAZ); - assertEquals(2, msg.getRepeatedImportEnumCount()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAZ, msg.getRepeatedImportEnum(0)); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getRepeatedImportEnum(1)); - msg.clearRepeatedImportEnum(); - assertEquals(0, msg.getRepeatedImportEnumCount()); - msg.clearRepeatedImportEnum() - .addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR); - assertEquals(1, msg.getRepeatedImportEnumCount()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getRepeatedImportEnum(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedImportEnumCount()); - - // Test 1 entry - msg.clear() - .addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_FOO); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedImportEnumCount()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_FOO, msg.getRepeatedImportEnum(0)); - - // Test 2 entries - msg.clear() - .addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_FOO) - .addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR); - assertEquals(2, msg.getRepeatedImportEnumCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 6); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedImportEnumCount()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_FOO, msg.getRepeatedImportEnum(0)); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getRepeatedImportEnum(1)); - } - - public void testMicroRepeatedStringPiece() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedStringPieceCount()); - msg.addRepeatedStringPiece("hello"); - assertEquals(1, msg.getRepeatedStringPieceCount()); - assertEquals("hello", msg.getRepeatedStringPiece(0)); - msg.addRepeatedStringPiece("bye"); - assertEquals(2, msg.getRepeatedStringPieceCount()); - assertEquals("hello", msg.getRepeatedStringPiece(0)); - assertEquals("bye", msg.getRepeatedStringPiece(1)); - msg.setRepeatedStringPiece(0, "boo"); - assertEquals(2, msg.getRepeatedStringPieceCount()); - assertEquals("boo", msg.getRepeatedStringPiece(0)); - assertEquals("bye", msg.getRepeatedStringPiece(1)); - msg.clearRepeatedStringPiece(); - assertEquals(0, msg.getRepeatedStringPieceCount()); - msg.clearRepeatedStringPiece() - .addRepeatedStringPiece("hello"); - assertEquals(1, msg.getRepeatedStringPieceCount()); - assertEquals("hello", msg.getRepeatedStringPiece(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedStringPieceCount()); - - // Test 1 entry and an empty string - msg.clear() - .addRepeatedStringPiece(""); - assertEquals(1, msg.getRepeatedStringPieceCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedStringPieceCount()); - assertEquals("", newMsg.getRepeatedStringPiece(0)); - - // Test 2 entries - msg.clear() - .addRepeatedStringPiece("hello") - .addRepeatedStringPiece("world"); - assertEquals(2, msg.getRepeatedStringPieceCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 16); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedStringPieceCount()); - assertEquals("hello", newMsg.getRepeatedStringPiece(0)); - assertEquals("world", newMsg.getRepeatedStringPiece(1)); - } - - public void testMicroRepeatedCord() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertEquals(0, msg.getRepeatedCordCount()); - msg.addRepeatedCord("hello"); - assertEquals(1, msg.getRepeatedCordCount()); - assertEquals("hello", msg.getRepeatedCord(0)); - msg.addRepeatedCord("bye"); - assertEquals(2, msg.getRepeatedCordCount()); - assertEquals("hello", msg.getRepeatedCord(0)); - assertEquals("bye", msg.getRepeatedCord(1)); - msg.setRepeatedCord(0, "boo"); - assertEquals(2, msg.getRepeatedCordCount()); - assertEquals("boo", msg.getRepeatedCord(0)); - assertEquals("bye", msg.getRepeatedCord(1)); - msg.clearRepeatedCord(); - assertEquals(0, msg.getRepeatedCordCount()); - msg.clearRepeatedCord() - .addRepeatedCord("hello"); - assertEquals(1, msg.getRepeatedCordCount()); - assertEquals("hello", msg.getRepeatedCord(0)); - msg.clear(); - assertEquals(0, msg.getRepeatedCordCount()); - - // Test 1 entry and an empty string - msg.clear() - .addRepeatedCord(""); - assertEquals(1, msg.getRepeatedCordCount()); - byte [] result = msg.toByteArray(); - int msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 3); - assertEquals(result.length, msgSerializedSize); - TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(1, newMsg.getRepeatedCordCount()); - assertEquals("", newMsg.getRepeatedCord(0)); - - // Test 2 entries - msg.clear() - .addRepeatedCord("hello") - .addRepeatedCord("world"); - assertEquals(2, msg.getRepeatedCordCount()); - result = msg.toByteArray(); - msgSerializedSize = msg.getSerializedSize(); - //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); - assertTrue(msgSerializedSize == 16); - assertEquals(result.length, msgSerializedSize); - - newMsg = TestAllTypesMicro.parseFrom(result); - assertEquals(2, newMsg.getRepeatedCordCount()); - assertEquals("hello", newMsg.getRepeatedCord(0)); - assertEquals("world", newMsg.getRepeatedCord(1)); - } - - public void testMicroDefaults() throws Exception { - TestAllTypesMicro msg = new TestAllTypesMicro(); - assertFalse(msg.hasDefaultInt32()); - assertEquals(41, msg.getDefaultInt32()); - assertFalse(msg.hasDefaultInt64()); - assertEquals(42, msg.getDefaultInt64()); - assertFalse(msg.hasDefaultUint32()); - assertEquals(43, msg.getDefaultUint32()); - assertFalse(msg.hasDefaultUint64()); - assertEquals(44, msg.getDefaultUint64()); - assertFalse(msg.hasDefaultSint32()); - assertEquals(-45, msg.getDefaultSint32()); - assertFalse(msg.hasDefaultSint64()); - assertEquals(46, msg.getDefaultSint64()); - assertFalse(msg.hasDefaultFixed32()); - assertEquals(47, msg.getDefaultFixed32()); - assertFalse(msg.hasDefaultFixed64()); - assertEquals(48, msg.getDefaultFixed64()); - assertFalse(msg.hasDefaultSfixed32()); - assertEquals(49, msg.getDefaultSfixed32()); - assertFalse(msg.hasDefaultSfixed64()); - assertEquals(-50, msg.getDefaultSfixed64()); - assertFalse(msg.hasDefaultFloat()); - assertTrue(51.5f == msg.getDefaultFloat()); - assertFalse(msg.hasDefaultDouble()); - assertTrue(52.0e3 == msg.getDefaultDouble()); - assertFalse(msg.hasDefaultBool()); - assertEquals(true, msg.getDefaultBool()); - assertFalse(msg.hasDefaultString()); - assertEquals("hello", msg.getDefaultString()); - assertFalse(msg.hasDefaultBytes()); - assertEquals("world", msg.getDefaultBytes().toStringUtf8()); - assertFalse(msg.hasDefaultNestedEnum()); - assertEquals(TestAllTypesMicro.BAR, msg.getDefaultNestedEnum()); - assertFalse(msg.hasDefaultForeignEnum()); - assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getDefaultForeignEnum()); - assertFalse(msg.hasDefaultImportEnum()); - assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getDefaultImportEnum()); - } -} diff --git a/java/src/test/java/com/google/protobuf/PerfTimer.java b/java/src/test/java/com/google/protobuf/PerfTimer.java deleted file mode 100644 index d6df4ff..0000000 --- a/java/src/test/java/com/google/protobuf/PerfTimer.java +++ /dev/null @@ -1,832 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.protobuf; - -import java.util.Arrays; - -/** - * A Performance Timing class that can be used to estimate the amount of time a - * sequence of code takes. The typical code sequence would be as follows:</p> - * <code> - PerfTimer pt = new PerfTimer(); - pt.calibrate(); - pt.timeEachAutomatically(new Runnable() = { - public void run() { - // Add code to time - } - }); - System.out.printf("time per loop=" + pt); - - * The calibrate method determines the overhead of timing the run() method and - * the number of times to call the run() method to have approximately 1% precision - * for timing. The method pt.stats() method will return a string containing some - * statistics tpl, il, ol, min, max, mean, median, stddev and total. - * - * tpl ::= Timer per loop - * min ::= minimum time one call to run() took - * stddev ::= Standard deviation of the collected times - * mean ::= the average time to call run() - * median ::= 1/2 the times were > than this time and 1/2 were less. - * total ::= Sum of the times collected. - * il ::= innerLoops; the number of times run() between each call to start/stop - * ol ::= outerLoops, the number of times start/stop was called - * - * You can also use start/stop/restart to do simple timing: - * - * pt.start(); - * a += 1; - * pt.stop(); - * pt.log("time=" + pt); - * pt.restart(); - * doSomething(); - * pt.stop(); - * System.out.printf("time=" + pt); - * </code> - * - * @author wink@google.com (Wink Saville) - */ -public class PerfTimer { - /** No debug */ - public static final int DEBUG_LEVEL_NONE = 0; - - /** Some debug */ - public static final int DEBUG_LEVEL_SOME = 1; - - /** All debug */ - public static final int DEBUG_LEVEL_ALL = 2; - - /** Timer ticks per microsecond */ - private static final double TICKS_PER_MICROSECOND = 1000.0; - - /** Random number generator */ - java.util.Random rng = new java.util.Random(); - - /** get ticks */ - private static long getTicks() { - return System.nanoTime(); - } - - /** Debug logging */ - private static void log(String s) { - System.out.printf(String.format("[PerfTimer] %s\n", s)); - } - - /** Outer loops for timeEachAutomatically */ - private static final int OUTER_LOOPS = 100; - - /** Thrown if an error occurs while timing */ - public static class PerfTimerException extends RuntimeException { - } - - /** - * Calibration record - */ - public static class CalibrationRec { - /** Runnable overhead */ - public double mRunnableOverheadInMicros = 0.0; - - /** Minimum Threshold value for timeEachAutomaticaly */ - public double mMinThresholdInMicros = 3000.0; - - /** Maximum Threshold value for timeEachAutomaticaly */ - public double mMaxThresholdInMicros = 6000.0; - - /** Desired precision in decimal digits */ - public double mPrecisionInDecimalDigits = 2.0; - - /** - * Default number of retries if the standard deviation ratio is too - * large - */ - public final int mStdDevRetrys = 5; - - /** Default maximum standard deviation radio */ - public final double mMaxStdDevRatio = 0.15; - - /** Number of votes looking for smallest time per loop */ - public final int mVotes = 3; - - /** Convert to string */ - @Override - public String toString() { - return String - .format( - "oh=%.6fus minT=%.6fus maxT=%.6fus prc=%,.3f stdDevRetrys=%d maxStdDevRatio=%.2f votes=%d", - mRunnableOverheadInMicros, mMinThresholdInMicros, - mMaxThresholdInMicros, mPrecisionInDecimalDigits, mStdDevRetrys, - mMaxStdDevRatio, mVotes); - } - } - - /** - * Calibration record - */ - private CalibrationRec mCr; - - /** - * Statistics calculated on the timing data. - */ - public static class Stats { - /** Number of outer loops */ - private int mOuterLoops; - - /** Number of inner loops */ - private int mInnerLoops; - - /** Minimum time in times array */ - private long mMin; - - /** Maximum time in times array */ - private long mMax; - - /** Median value in times array */ - private double mMedian; - - /** The mean (average) of the values in times array */ - private double mMean; - - /** The standard deviation of the values in times array */ - private double mStdDev; - - private int mStdDevTooLargeCount; - - /** Sum of the times in the times array */ - private double mTotal; - - /** Initialize */ - public void init() { - mInnerLoops = 1; - mOuterLoops = 1; - mMin = 0; - mMax = 0; - mMedian = 0; - mMean = 0; - mStdDev = 0; - mStdDevTooLargeCount = 0; - mTotal = 0; - } - - /** Constructor */ - public Stats() { - init(); - } - - /** Set number of inner loops */ - public void setInnerLoops(int loops) { - mInnerLoops = loops; - } - - /** Get number of inner loops */ - public int getInnerLoops() { - return mInnerLoops; - } - - /** Set number of inner loops */ - public void setOuterLoops(int loops) { - mOuterLoops = loops; - } - - /** Get number of inner loops */ - public int getOuterLoops() { - return mOuterLoops; - } - - /** - * Minimum value of collected data in microseconds, valid after analyze. - */ - public double getMinInMicros() { - return mMin / TICKS_PER_MICROSECOND; - } - - /** - * Maximum value of collected data in microseconds, valid after analyze. - */ - public double getMaxInMicros() { - return mMax / TICKS_PER_MICROSECOND; - } - - /** - * Sum of the values of collected data in microseconds, valid after - * analyze. - */ - public double getTotalInMicros() { - return mTotal / TICKS_PER_MICROSECOND; - } - - /** Sum of the values of collected data in seconds, valid after analyze. */ - public double getTotalInSecs() { - return mTotal / (TICKS_PER_MICROSECOND * 1000000.0); - } - - /** Sum of the values of collected data in seconds, valid after analyze. */ - public double getMeanInMicros() { - return mMean / TICKS_PER_MICROSECOND; - } - - /** Median value of collected data in microseconds, valid after analyze. */ - public double getMedianInMicros() { - return mMedian / TICKS_PER_MICROSECOND; - } - - /** - * Standard deviation of collected data in microseconds, valid after - * analyze. - */ - public double getStdDevInMicros() { - return mStdDev / TICKS_PER_MICROSECOND; - } - - public double getStdDevRatio() { - return mStdDev / mMin; - } - - /** Return true if (mStdDev / mMin) <= maxStdDevRation */ - public boolean stdDevOk(double maxStdDevRatio) { - return getStdDevRatio() <= maxStdDevRatio; - } - - /** Increment StdDevTooLargeCount */ - public void incStdDevTooLargeCount() { - mStdDevTooLargeCount += 1; - } - - /** Return number of times stdDev was not ok */ - public int getStdDevTooLargeCount() { - return mStdDevTooLargeCount; - } - - /** Return time per loop */ - public double getTimePerLoop() { - return mMin / TICKS_PER_MICROSECOND / mInnerLoops; - } - - /** - * Calculate the stats for the data. Note the data in the range will be - * sorted. - * - * @param data - * @param count - */ - public Stats calculate(long data[], int count) { - if (count == 1) { - mMin = mMax = data[0]; - mTotal = mMedian = mMean = data[0]; - mStdDev = 0; - } else if (count > 1) { - Arrays.sort(data, 0, count); - mMin = data[0]; - mMax = data[count - 1]; - if ((count & 1) == 1) { - mMedian = data[((count + 1) / 2) - 1]; - } else { - mMedian = (data[count / 2] + data[(count / 2) - 1]) / 2; - } - mTotal = 0; - double sumSquares = 0; - for (int i = 0; i < count; i++) { - long t = data[i]; - mTotal += t; - sumSquares += t * t; - } - mMean = mTotal / count; - double variance = (sumSquares / count) - (mMean * mMean); - mStdDev = Math.pow(variance, 0.5); - } else { - init(); - } - return this; - } - - /** Convert to string */ - @Override - public String toString() { - double timePerLoop = getTimePerLoop(); - double stdDevPerLoop = mStdDev / TICKS_PER_MICROSECOND / mInnerLoops; - return String.format( - "tpl=%,.6fus stdDev=%,.6fus tpl/stdDev=%.2fpercent min=%,.6fus median=%,.6fus mean=%,.6fus max=%,.6fus total=%,.6fs il=%d, ol=%d tlc=%d", - timePerLoop, stdDevPerLoop, (stdDevPerLoop / timePerLoop) * 100, mMin - / TICKS_PER_MICROSECOND, mMedian / TICKS_PER_MICROSECOND, mMean - / TICKS_PER_MICROSECOND, mMax / TICKS_PER_MICROSECOND, mTotal - / (TICKS_PER_MICROSECOND * 1000000.0), mInnerLoops, mOuterLoops, mStdDevTooLargeCount); - } - } - - /** Statistics */ - private Stats mStats = new Stats(); - - /** Statistics of the clock precision */ - private Stats mClockStats; - - /** Number of items in times array */ - private int mCount; - - /** Array of stop - start times */ - private long mTimes[]; - - /** Time of last started */ - private long mStart; - - /** Sleep a little so we don't look like a hog */ - private void sleep() { - try { - Thread.sleep(0); - } catch (InterruptedException e) { - // Ignore exception - } - } - - /** Empty Runnable used for determining overhead */ - private Runnable mEmptyRunnable = new Runnable() { - public void run() { - } - }; - - /** Initialize */ - private void init(int maxCount, CalibrationRec cr) { - mTimes = new long[maxCount]; - mCr = cr; - reset(); - } - - /** Construct the stop watch */ - public PerfTimer() { - init(10, new CalibrationRec()); - } - - /** Construct setting size of times array */ - public PerfTimer(int maxCount) { - init(maxCount, new CalibrationRec()); - } - - /** Construct the stop watch */ - public PerfTimer(CalibrationRec cr) { - init(10, cr); - } - - /** Construct the stop watch */ - public PerfTimer(int maxCount, CalibrationRec cr) { - init(maxCount, cr); - } - - /** Reset the contents of the times array */ - public PerfTimer reset() { - mCount = 0; - mStats.init(); - return this; - } - - /** Reset and then start the timer */ - public PerfTimer restart() { - reset(); - mStart = getTicks(); - return this; - } - - /** Start timing */ - public PerfTimer start() { - mStart = getTicks(); - return this; - } - - /** - * Record the difference between start and now in the times array - * incrementing count. The time will be stored in the times array if the - * array is not full. - */ - public PerfTimer stop() { - long stop = getTicks(); - if (mCount < mTimes.length) { - mTimes[mCount++] = stop - mStart; - } - return this; - } - - /** - * Time how long it takes to execute runnable.run() innerLoop number of - * times outerLoops number of times. - * - * @param outerLoops - * @param innerLoops - * @param runnable - * @return PerfTimer - */ - public PerfTimer timeEach(Stats stats, int outerLoops, int innerLoops, Runnable runnable) { - reset(); - resize(outerLoops); - stats.setOuterLoops(outerLoops); - stats.setInnerLoops(innerLoops); - for (int i = 0; i < outerLoops; i++) { - start(); - for (int j = 0; j < innerLoops; j++) { - runnable.run(); - } - stop(); - sleep(); - } - return this; - } - - /** - * Time how long it takes to execute runnable.run(). Runs runnable votes - * times and returns the Stats of the fastest run. The actual number times - * that runnable.run() is executes is enough times so that it runs at least - * minThreadholeInMicros but not greater than maxThreadholdInMicro. This - * minimizes the chance that long context switches influence the result. - * - * @param votes is the number of runnable will be executed to determine - * fastest run - * @param outerLoops is the number of of times the inner loop is run - * @param initialInnerLoops is the initial inner loop - * @param maxStdDevRetrys if the maxStdDevRatio is exceeded this number of - * time the PerfTimerException is thrown. - * @param maxStdDevRatio the ratio of the standard deviation of the run and - * the time to run. - * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL - * @param runnable is the code to test. - * @return Stats of the fastest run. - */ - public Stats timeEachAutomatically(int votes, int outerLoops, int initialInnerLoops, - double minThresholdInMicros, double maxThresholdInMicros, int maxStdDevRetrys, - double maxStdDevRatio, int debugLevel, Runnable runnable) throws PerfTimerException { - Stats minStats = null; - - for (int v = 0; v < votes; v++) { - boolean successful = false; - Stats stats = new Stats(); - int innerLoops = initialInnerLoops; - - /* Warm up cache */ - timeEach(stats, outerLoops, initialInnerLoops, runnable); - - for (int stdDevRetrys = 0; stdDevRetrys < maxStdDevRetrys; stdDevRetrys++) { - /** - * First time may be long enough - */ - timeEach(stats, outerLoops, innerLoops, runnable); - analyze(stats, mTimes, outerLoops, debugLevel); - double innerLoopTime = stats.getMinInMicros(); - if ((innerLoopTime >= minThresholdInMicros - - ((maxThresholdInMicros - minThresholdInMicros) / 2))) { - if (stats.stdDevOk(maxStdDevRatio)) { - successful = true; - break; - } else { - stats.incStdDevTooLargeCount(); - if (debugLevel >= DEBUG_LEVEL_SOME) { - log(String.format( - "tea: tlc=%d StdDevRatio=%.2f > maxStdDevRatio=%.2f", - stats.getStdDevTooLargeCount(), stats.getStdDevRatio(), - maxStdDevRatio)); - } - } - } else { - /** - * The initial number of loops is too short find the number - * of loops that exceeds maxThresholdInMicros. Then use a - * binary search to find the approriate innerLoop value that - * is between min/maxThreshold. - */ - innerLoops *= 10; - int maxInnerLoops = innerLoops; - int minInnerLoops = 1; - boolean binarySearch = false; - for (int i = 0; i < 10; i++) { - timeEach(stats, outerLoops, innerLoops, runnable); - analyze(stats, mTimes, outerLoops, debugLevel); - innerLoopTime = stats.getMedianInMicros(); - if ((innerLoopTime >= minThresholdInMicros) - && (innerLoopTime <= maxThresholdInMicros)) { - if (stats.stdDevOk(maxStdDevRatio)) { - successful = true; - break; - } else { - stats.incStdDevTooLargeCount(); - if (debugLevel >= DEBUG_LEVEL_SOME) { - log(String.format( - "tea: tlc=%d StdDevRatio=%.2f > maxStdDevRatio=%.2f", - stats.getStdDevTooLargeCount(), stats.getStdDevRatio(), - maxStdDevRatio)); - } - } - } else if (binarySearch) { - if ((innerLoopTime < minThresholdInMicros)) { - minInnerLoops = innerLoops; - } else { - maxInnerLoops = innerLoops; - } - innerLoops = (maxInnerLoops + minInnerLoops) / 2; - } else if (innerLoopTime >= maxThresholdInMicros) { - /* Found a too large value, change to binary search */ - binarySearch = true; - maxInnerLoops = innerLoops; - innerLoops = (maxInnerLoops + minInnerLoops) / 2; - } else { - innerLoops *= 10; - } - } - if (successful) { - break; - } - } - } - if (!successful) { - /* Couldn't find the number of loops to execute */ - throw new PerfTimerException(); - } - - /** Looking for minimum */ - if ((minStats == null) || (minStats.getTimePerLoop() > stats.getTimePerLoop())) { - minStats = stats; - } - if (debugLevel >= DEBUG_LEVEL_SOME) { - log(String.format("minStats.getTimePerLoop=%f minStats: %s", minStats.getTimePerLoop(), minStats)); - } - } - - return minStats; - } - - /** - * Time how long it takes to execute runnable.run() with a threshold of 1 to - * 10ms. - * - * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL - * @param runnable - * @throws PerfTimerException - */ - public Stats timeEachAutomatically(int debugLevel, Runnable runnable) - throws PerfTimerException { - mStats = timeEachAutomatically(mCr.mVotes, OUTER_LOOPS, 1, mCr.mMinThresholdInMicros, - mCr.mMaxThresholdInMicros, mCr.mStdDevRetrys, mCr.mMaxStdDevRatio, debugLevel, - runnable); - return mStats; - } - - /** - * Time how long it takes to execute runnable.run() with a threshold of 1 to - * 10ms. - * - * @param runnable - * @throws PerfTimerException - */ - public Stats timeEachAutomatically(Runnable runnable) throws PerfTimerException { - mStats = timeEachAutomatically(mCr.mVotes, OUTER_LOOPS, 1, mCr.mMinThresholdInMicros, - mCr.mMaxThresholdInMicros, mCr.mStdDevRetrys, mCr.mMaxStdDevRatio, - DEBUG_LEVEL_NONE, runnable); - return mStats; - } - - /** Resize the times array */ - public void resize(int maxCount) { - if (maxCount > mTimes.length) { - mTimes = new long[maxCount]; - } - } - - /** - * Analyze the data calculating the min, max, total, median, mean and - * stdDev. The standard deviation is calculated as sqrt(((sum of the squares - * of each time) / count) - mean^2) - * {@link "http://www.sciencebuddies.org/mentoring/project_data_analysis_variance_std_deviation.shtml"} - * - * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL - * @return StopWatch - */ - public Stats analyze(Stats stats, long data[], int count, int debugLevel) { - if (count > 0) { - if (debugLevel >= DEBUG_LEVEL_ALL) { - for (int j = 0; j < count; j++) { - log(String.format("data[%d]=%,dns", j, data[j])); - } - } - stats.calculate(data, count); - } else { - stats.init(); - } - if (debugLevel >= DEBUG_LEVEL_SOME) { - log("stats: " + stats); - } - return stats; - } - - /** - * Calibrate the system and set it for this PerfTimer instance - * - * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL - * @param precisionInDecimalDigits the precision in number of decimal digits - */ - public CalibrationRec calibrate(int debugLevel, double precisionInDecimalDigits) - throws PerfTimerException { - int nonZeroCount = 0; - Stats stats = new Stats(); - CalibrationRec cr = new CalibrationRec(); - - /* initialize the precision */ - cr.mPrecisionInDecimalDigits = precisionInDecimalDigits; - - /* Warm up the cache */ - timeEach(stats, OUTER_LOOPS, 10, mEmptyRunnable); - - /* - * Determine the clock stats with at least 20% non-zero unique values. - */ - for (int clockStatsTries = 1; clockStatsTries < 100; clockStatsTries++) { - int j; - int i; - long cur; - long prev; - long min; - - int innerLoops = clockStatsTries * 10; - timeEach(stats, OUTER_LOOPS, innerLoops, mEmptyRunnable); - long nonZeroValues[] = new long[mCount]; - prev = 0; - for (nonZeroCount = 0, i = 0; i < mCount; i++) { - cur = mTimes[i]; - if (cur > 0) { - nonZeroValues[nonZeroCount++] = cur; - } - } - if (nonZeroCount > (mCount * 0.20)) { - // Calculate thresholds - analyze(stats, nonZeroValues, nonZeroCount, debugLevel); - stats.calculate(nonZeroValues, nonZeroCount); - cr.mMinThresholdInMicros = stats.getMeanInMicros() - * Math.pow(10, cr.mPrecisionInDecimalDigits); - cr.mMaxThresholdInMicros = cr.mMinThresholdInMicros * 2; - - // Set overhead to 0 and time the empty loop then set overhead. - cr.mRunnableOverheadInMicros = 0; - mClockStats = timeEachAutomatically(mCr.mVotes, OUTER_LOOPS, innerLoops, - cr.mMinThresholdInMicros, cr.mMaxThresholdInMicros, mCr.mStdDevRetrys, - mCr.mMaxStdDevRatio, debugLevel, mEmptyRunnable); - cr.mRunnableOverheadInMicros = mClockStats.getMinInMicros() - / mClockStats.getInnerLoops(); - break; - } - nonZeroCount = 0; - } - if (nonZeroCount == 0) { - throw new PerfTimerException(); - } - if (debugLevel >= DEBUG_LEVEL_SOME) { - log(String.format("calibrate X oh=%.6fus minT=%,.6fus maxT=%,.6fus stats: %s", - cr.mRunnableOverheadInMicros, cr.mMinThresholdInMicros, - cr.mMaxThresholdInMicros, stats)); - } - mCr = cr; - return mCr; - } - - /** Calibrate the system and set it for this PerfTimer instance */ - public CalibrationRec calibrate(double precisionInDecimalDigits) throws PerfTimerException { - return calibrate(DEBUG_LEVEL_NONE, precisionInDecimalDigits); - } - - /** Calibrate the system and set it for this PerfTimer instance */ - public CalibrationRec calibrate() throws PerfTimerException { - return calibrate(DEBUG_LEVEL_NONE, mCr.mPrecisionInDecimalDigits); - } - - /* - * Accessors for the private data - */ - - /** Set calibration record */ - public void setCalibrationRec(CalibrationRec cr) { - mCr = cr; - } - - /** Get calibration record */ - public CalibrationRec getCalibrationRec() { - return mCr; - } - - /** Number of samples in times array. */ - public int getCount() { - return mCount; - } - - /** Minimum value of collected data in microseconds, valid after analyze. */ - public double getMinInMicros() { - return mStats.getMinInMicros(); - } - - /** Maximum value of collected data in microseconds, valid after analyze. */ - public double getMaxInMicros() { - return mStats.getMaxInMicros(); - } - - /** - * Sum of the values of collected data in microseconds, valid after analyze. - */ - public double getTotalInMicros() { - return mStats.getTotalInMicros(); - } - - /** Sum of the values of collected data in seconds, valid after analyze. */ - public double getTotalInSecs() { - return mStats.getTotalInSecs(); - } - - /** Sum of the values of collected data in seconds, valid after analyze. */ - public double getMeanInMicros() { - return mStats.getMeanInMicros(); - } - - /** Median value of collected data in microseconds, valid after analyze. */ - public double getMedianInMicros() { - return mStats.getMedianInMicros(); - } - - /** - * Standard deviation of collected data in microseconds, valid after - * analyze. - */ - public double getStdDevInMicros() { - return mStats.getStdDevInMicros(); - } - - /** The mTimes[index] value */ - public long getTime(int index) { - return mTimes[index]; - } - - /** The mTimes */ - public long[] getTimes() { - return mTimes; - } - - /** @return the clock stats as measured in calibrate */ - public Stats getClockStats() { - return mClockStats; - } - - /** @return the stats */ - public Stats getStats() { - return mStats; - } - - /** - * Convert stats to string - * - * @param debugLevel DEBUG_LEVEL_NONE, DEBUG_LEVEL_SOME, DEBUG_LEVEL_ALL - */ - public String stats(int debugLevel) { - int innerLoops = mStats.getInnerLoops(); - if (mCount == 0) { - return String.format("%,.3fus", (getTicks() - mStart) / TICKS_PER_MICROSECOND); - } else { - if (mCount == 1) { - return String.format("%,.3fus", getTime()); - } else { - analyze(mStats, mTimes, mCount, debugLevel); - return mStats.toString(); - } - } - } - - /** - * Convert string - */ - public String stats() { - return stats(0); - } - - /** - * Get time - */ - public double getTime() { - int innerLoops = mStats.getInnerLoops(); - if (mCount == 0) { - return (getTicks() - mStart) / TICKS_PER_MICROSECOND; - } else { - if (mCount == 1) { - return mStats.getTotalInMicros(); - } else { - analyze(mStats, mTimes, mCount, DEBUG_LEVEL_NONE); - return (mStats.getMinInMicros() / innerLoops) - mCr.mRunnableOverheadInMicros; - } - } - } - - /** Convert to string */ - @Override - public String toString() { - return String.format("%,.3fus", getTime()); - } -} diff --git a/java/src/test/java/com/google/protobuf/ServiceTest.java b/java/src/test/java/com/google/protobuf/ServiceTest.java index d8523ea..e10322d 100644 --- a/java/src/test/java/com/google/protobuf/ServiceTest.java +++ b/java/src/test/java/com/google/protobuf/ServiceTest.java @@ -30,7 +30,9 @@ package com.google.protobuf; +import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.MethodDescriptor; +import google.protobuf.no_generic_services_test.UnittestNoGenericServices; import protobuf_unittest.MessageWithNoOuter; import protobuf_unittest.ServiceWithNoOuter; import protobuf_unittest.UnittestProto.TestAllTypes; @@ -44,6 +46,9 @@ import org.easymock.classextension.EasyMock; import org.easymock.classextension.IMocksControl; import org.easymock.IArgumentMatcher; +import java.util.HashSet; +import java.util.Set; + import junit.framework.TestCase; /** @@ -220,6 +225,48 @@ public class ServiceTest extends TestCase { control.verify(); } + public void testNoGenericServices() throws Exception { + // Non-services should be usable. + UnittestNoGenericServices.TestMessage message = + UnittestNoGenericServices.TestMessage.newBuilder() + .setA(123) + .setExtension(UnittestNoGenericServices.testExtension, 456) + .build(); + assertEquals(123, message.getA()); + assertEquals(1, UnittestNoGenericServices.TestEnum.FOO.getNumber()); + + // Build a list of the class names nested in UnittestNoGenericServices. + String outerName = "google.protobuf.no_generic_services_test." + + "UnittestNoGenericServices"; + Class<?> outerClass = Class.forName(outerName); + + Set<String> innerClassNames = new HashSet<String>(); + for (Class<?> innerClass : outerClass.getClasses()) { + String fullName = innerClass.getName(); + // Figure out the unqualified name of the inner class. + // Note: Surprisingly, the full name of an inner class will be separated + // from the outer class name by a '$' rather than a '.'. This is not + // mentioned in the documentation for java.lang.Class. I don't want to + // make assumptions, so I'm just going to accept any character as the + // separator. + assertTrue(fullName.startsWith(outerName)); + innerClassNames.add(fullName.substring(outerName.length() + 1)); + } + + // No service class should have been generated. + assertTrue(innerClassNames.contains("TestMessage")); + assertTrue(innerClassNames.contains("TestEnum")); + assertFalse(innerClassNames.contains("TestService")); + + // But descriptors are there. + FileDescriptor file = UnittestNoGenericServices.getDescriptor(); + assertEquals(1, file.getServices().size()); + assertEquals("TestService", file.getServices().get(0).getName()); + assertEquals(1, file.getServices().get(0).getMethods().size()); + assertEquals("Foo", + file.getServices().get(0).getMethods().get(0).getName()); + } + // ================================================================= /** diff --git a/java/src/test/java/com/google/protobuf/TestUtil.java b/java/src/test/java/com/google/protobuf/TestUtil.java index 805c42a..2b8b2af 100644 --- a/java/src/test/java/com/google/protobuf/TestUtil.java +++ b/java/src/test/java/com/google/protobuf/TestUtil.java @@ -217,6 +217,7 @@ import protobuf_unittest.UnittestProto.TestAllExtensions; import protobuf_unittest.UnittestProto.TestAllTypes; import protobuf_unittest.UnittestProto.TestPackedExtensions; import protobuf_unittest.UnittestProto.TestPackedTypes; +import protobuf_unittest.UnittestProto.TestUnpackedTypes; import protobuf_unittest.UnittestProto.ForeignMessage; import protobuf_unittest.UnittestProto.ForeignEnum; import com.google.protobuf.test.UnittestImport.ImportMessage; @@ -289,6 +290,12 @@ class TestUtil { return builder.build(); } + public static TestUnpackedTypes getUnpackedSet() { + TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder(); + setUnpackedFields(builder); + return builder.build(); + } + public static TestPackedExtensions getPackedExtensionsSet() { TestPackedExtensions.Builder builder = TestPackedExtensions.newBuilder(); setPackedExtensions(builder); @@ -956,6 +963,42 @@ class TestUtil { } /** + * Set every field of {@code message} to a unique value. Must correspond with + * the values applied by {@code setPackedFields}. + */ + public static void setUnpackedFields(TestUnpackedTypes.Builder message) { + message.addUnpackedInt32 (601); + message.addUnpackedInt64 (602); + message.addUnpackedUint32 (603); + message.addUnpackedUint64 (604); + message.addUnpackedSint32 (605); + message.addUnpackedSint64 (606); + message.addUnpackedFixed32 (607); + message.addUnpackedFixed64 (608); + message.addUnpackedSfixed32(609); + message.addUnpackedSfixed64(610); + message.addUnpackedFloat (611); + message.addUnpackedDouble (612); + message.addUnpackedBool (true); + message.addUnpackedEnum (ForeignEnum.FOREIGN_BAR); + // Add a second one of each field. + message.addUnpackedInt32 (701); + message.addUnpackedInt64 (702); + message.addUnpackedUint32 (703); + message.addUnpackedUint64 (704); + message.addUnpackedSint32 (705); + message.addUnpackedSint64 (706); + message.addUnpackedFixed32 (707); + message.addUnpackedFixed64 (708); + message.addUnpackedSfixed32(709); + message.addUnpackedSfixed64(710); + message.addUnpackedFloat (711); + message.addUnpackedDouble (712); + message.addUnpackedBool (false); + message.addUnpackedEnum (ForeignEnum.FOREIGN_BAZ); + } + + /** * Assert (using {@code junit.framework.Assert}} that all fields of * {@code message} are set to the values assigned by {@code setPackedFields}. */ @@ -1004,6 +1047,55 @@ class TestUtil { Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getPackedEnum(1)); } + /** + * Assert (using {@code junit.framework.Assert}} that all fields of + * {@code message} are set to the values assigned by {@code setUnpackedFields}. + */ + public static void assertUnpackedFieldsSet(TestUnpackedTypes message) { + Assert.assertEquals(2, message.getUnpackedInt32Count ()); + Assert.assertEquals(2, message.getUnpackedInt64Count ()); + Assert.assertEquals(2, message.getUnpackedUint32Count ()); + Assert.assertEquals(2, message.getUnpackedUint64Count ()); + Assert.assertEquals(2, message.getUnpackedSint32Count ()); + Assert.assertEquals(2, message.getUnpackedSint64Count ()); + Assert.assertEquals(2, message.getUnpackedFixed32Count ()); + Assert.assertEquals(2, message.getUnpackedFixed64Count ()); + Assert.assertEquals(2, message.getUnpackedSfixed32Count()); + Assert.assertEquals(2, message.getUnpackedSfixed64Count()); + Assert.assertEquals(2, message.getUnpackedFloatCount ()); + Assert.assertEquals(2, message.getUnpackedDoubleCount ()); + Assert.assertEquals(2, message.getUnpackedBoolCount ()); + Assert.assertEquals(2, message.getUnpackedEnumCount ()); + Assert.assertEquals(601 , message.getUnpackedInt32 (0)); + Assert.assertEquals(602 , message.getUnpackedInt64 (0)); + Assert.assertEquals(603 , message.getUnpackedUint32 (0)); + Assert.assertEquals(604 , message.getUnpackedUint64 (0)); + Assert.assertEquals(605 , message.getUnpackedSint32 (0)); + Assert.assertEquals(606 , message.getUnpackedSint64 (0)); + Assert.assertEquals(607 , message.getUnpackedFixed32 (0)); + Assert.assertEquals(608 , message.getUnpackedFixed64 (0)); + Assert.assertEquals(609 , message.getUnpackedSfixed32(0)); + Assert.assertEquals(610 , message.getUnpackedSfixed64(0)); + Assert.assertEquals(611 , message.getUnpackedFloat (0), 0.0); + Assert.assertEquals(612 , message.getUnpackedDouble (0), 0.0); + Assert.assertEquals(true , message.getUnpackedBool (0)); + Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getUnpackedEnum(0)); + Assert.assertEquals(701 , message.getUnpackedInt32 (1)); + Assert.assertEquals(702 , message.getUnpackedInt64 (1)); + Assert.assertEquals(703 , message.getUnpackedUint32 (1)); + Assert.assertEquals(704 , message.getUnpackedUint64 (1)); + Assert.assertEquals(705 , message.getUnpackedSint32 (1)); + Assert.assertEquals(706 , message.getUnpackedSint64 (1)); + Assert.assertEquals(707 , message.getUnpackedFixed32 (1)); + Assert.assertEquals(708 , message.getUnpackedFixed64 (1)); + Assert.assertEquals(709 , message.getUnpackedSfixed32(1)); + Assert.assertEquals(710 , message.getUnpackedSfixed64(1)); + Assert.assertEquals(711 , message.getUnpackedFloat (1), 0.0); + Assert.assertEquals(712 , message.getUnpackedDouble (1), 0.0); + Assert.assertEquals(false, message.getUnpackedBool (1)); + Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getUnpackedEnum(1)); + } + // =================================================================== // Like above, but for extensions @@ -1572,6 +1664,34 @@ class TestUtil { Assert.assertEquals(0, message.getExtensionCount(repeatedStringPieceExtension)); Assert.assertEquals(0, message.getExtensionCount(repeatedCordExtension)); + // Repeated fields are empty via getExtension().size(). + Assert.assertEquals(0, message.getExtension(repeatedInt32Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedInt64Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedUint32Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedUint64Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedSint32Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedSint64Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedFixed32Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedFixed64Extension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedSfixed32Extension).size()); + Assert.assertEquals(0, message.getExtension(repeatedSfixed64Extension).size()); + Assert.assertEquals(0, message.getExtension(repeatedFloatExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedDoubleExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedBoolExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedStringExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedBytesExtension ).size()); + + Assert.assertEquals(0, message.getExtension(repeatedGroupExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedNestedMessageExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedForeignMessageExtension).size()); + Assert.assertEquals(0, message.getExtension(repeatedImportMessageExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedNestedEnumExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedForeignEnumExtension ).size()); + Assert.assertEquals(0, message.getExtension(repeatedImportEnumExtension ).size()); + + Assert.assertEquals(0, message.getExtension(repeatedStringPieceExtension).size()); + Assert.assertEquals(0, message.getExtension(repeatedCordExtension).size()); + // hasBlah() should also be false for all default fields. Assert.assertFalse(message.hasExtension(defaultInt32Extension )); Assert.assertFalse(message.hasExtension(defaultInt64Extension )); diff --git a/java/src/test/java/com/google/protobuf/TextFormatTest.java b/java/src/test/java/com/google/protobuf/TextFormatTest.java index 1d73165..60bd800 100644 --- a/java/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/src/test/java/com/google/protobuf/TextFormatTest.java @@ -68,7 +68,7 @@ public class TextFormatTest extends TestCase { private static String allExtensionsSetText = TestUtil.readTextFromFile( "text_format_unittest_extensions_data.txt"); - private String exoticText = + private static String exoticText = "repeated_int32: -1\n" + "repeated_int32: -2147483648\n" + "repeated_int64: -1\n" + @@ -80,7 +80,13 @@ public class TextFormatTest extends TestCase { "repeated_double: 123.0\n" + "repeated_double: 123.5\n" + "repeated_double: 0.125\n" + + "repeated_double: .125\n" + + "repeated_double: -.125\n" + "repeated_double: 1.23E17\n" + + "repeated_double: 1.23E+17\n" + + "repeated_double: -1.23e-17\n" + + "repeated_double: .23e+17\n" + + "repeated_double: -.23E17\n" + "repeated_double: 1.235E22\n" + "repeated_double: 1.235E-18\n" + "repeated_double: 123.456789\n" + @@ -91,6 +97,10 @@ public class TextFormatTest extends TestCase { "\\341\\210\\264\"\n" + "repeated_bytes: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\376\"\n"; + private static String canonicalExoticText = + exoticText.replace(": .", ": 0.").replace(": -.", ": -0.") // short-form double + .replace("23e", "23E").replace("E+", "E").replace("0.23E17", "2.3E16"); + private String messageSetText = "[protobuf_unittest.TestMessageSetExtension1] {\n" + " i: 123\n" + @@ -186,12 +196,12 @@ public class TextFormatTest extends TestCase { final FieldDescriptor optionalField = TestAllTypes.getDescriptor().findFieldByName("optional_nested_message"); final Object value = NestedMessage.newBuilder().setBb(42).build(); - + assertEquals( "optional_nested_message {\n bb: 42\n}\n", TextFormat.printFieldToString(optionalField, value)); } - + /** * Helper to construct a ByteString from a String containing only 8-bit * characters. The characters are converted directly to bytes, *not* @@ -231,7 +241,13 @@ public class TextFormatTest extends TestCase { .addRepeatedDouble(123) .addRepeatedDouble(123.5) .addRepeatedDouble(0.125) + .addRepeatedDouble(.125) + .addRepeatedDouble(-.125) + .addRepeatedDouble(123e15) .addRepeatedDouble(123e15) + .addRepeatedDouble(-1.23e-17) + .addRepeatedDouble(.23e17) + .addRepeatedDouble(-23e15) .addRepeatedDouble(123.5e20) .addRepeatedDouble(123.5e-20) .addRepeatedDouble(123.456789) @@ -244,7 +260,7 @@ public class TextFormatTest extends TestCase { .addRepeatedBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\"\u00fe")) .build(); - assertEquals(exoticText, message.toString()); + assertEquals(canonicalExoticText, message.toString()); } public void testPrintMessageSet() throws Exception { @@ -319,7 +335,7 @@ public class TextFormatTest extends TestCase { // Too lazy to check things individually. Don't try to debug this // if testPrintExotic() is failing. - assertEquals(exoticText, builder.build().toString()); + assertEquals(canonicalExoticText, builder.build().toString()); } public void testParseMessageSet() throws Exception { @@ -633,4 +649,10 @@ public class TextFormatTest extends TestCase { TextFormat.merge("optional_string: \"" + longText + "\"", builder); assertEquals(longText, builder.getOptionalString()); } + + public void testParseAdjacentStringLiterals() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + TextFormat.merge("optional_string: \"foo\" 'corge' \"grault\"", builder); + assertEquals("foocorgegrault", 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 bd1c6db..5ea1dd6 100644 --- a/java/src/test/java/com/google/protobuf/WireFormatTest.java +++ b/java/src/test/java/com/google/protobuf/WireFormatTest.java @@ -102,6 +102,28 @@ public class WireFormatTest extends TestCase { assertEquals(rawBytes, rawBytes2); } + public void testSerializationPackedWithoutGetSerializedSize() + throws Exception { + // Write directly to an OutputStream, without invoking getSerializedSize() + // This used to be a bug where the size of a packed field was incorrect, + // since getSerializedSize() was never invoked. + TestPackedTypes message = TestUtil.getPackedSet(); + + // Directly construct a CodedOutputStream around the actual OutputStream, + // in case writeTo(OutputStream output) invokes getSerializedSize(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + CodedOutputStream codedOutput = CodedOutputStream.newInstance(outputStream); + + message.writeTo(codedOutput); + + codedOutput.flush(); + + TestPackedTypes message2 = TestPackedTypes.parseFrom( + outputStream.toByteArray()); + + TestUtil.assertPackedFieldsSet(message2); + } + public void testSerializeExtensionsLite() throws Exception { // TestAllTypes and TestAllExtensions should have compatible wire formats, // so if we serialize a TestAllExtensions then parse it as TestAllTypes @@ -213,6 +235,9 @@ public class WireFormatTest extends TestCase { TestUtil.assertPackedFieldsSet(TestPackedTypes.parseDelimitedFrom(input)); assertEquals(34, input.read()); assertEquals(-1, input.read()); + + // We're at EOF, so parsing again should return null. + assertTrue(TestAllTypes.parseDelimitedFrom(input) == null); } private void assertFieldsInOrder(ByteString data) throws Exception { |