diff options
author | Ulas Kirazci <ulas@google.com> | 2013-04-01 11:29:43 -0700 |
---|---|---|
committer | Ulas Kirazci <ulas@google.com> | 2013-07-29 09:35:44 -0700 |
commit | 35d9fd84ff1d9ecdb91156b757cc9fdcc3f25249 (patch) | |
tree | bf47056d6c723ec8939717efb9a5f30cbe7783af /java | |
parent | 021f8f1badf1c4db519e3f35d600dec4b5c52eff (diff) | |
download | external_protobuf-35d9fd84ff1d9ecdb91156b757cc9fdcc3f25249.zip external_protobuf-35d9fd84ff1d9ecdb91156b757cc9fdcc3f25249.tar.gz external_protobuf-35d9fd84ff1d9ecdb91156b757cc9fdcc3f25249.tar.bz2 |
Add an option to inspect "has" state upon parse.
If has is set, also always serialize.
Change-Id: I2c8450f7ab9e837d722123dd1042991c0258ede3
Diffstat (limited to 'java')
-rw-r--r-- | java/README.txt | 16 | ||||
-rw-r--r-- | java/pom.xml | 8 | ||||
-rw-r--r-- | java/src/test/java/com/google/protobuf/NanoTest.java | 88 |
3 files changed, 112 insertions, 0 deletions
diff --git a/java/README.txt b/java/README.txt index dac2e3c..58ccb88 100644 --- a/java/README.txt +++ b/java/README.txt @@ -301,6 +301,22 @@ message's constructor or clear() function is called, the default value penalty. This is not a problem if the field has no default or is an empty default. +Nano Generator options + +java_nano_generate_has: + If true, generates a public boolean variable has<fieldname> + accompanying the optional or required field (not present for + repeated fields, groups or messages). It is set to false initially + and upon clear(). If parseFrom(...) reads the field from the wire, + it is set to true. This is a way for clients to inspect the "has" + value upon parse. If it is set to true, writeTo(...) will ALWAYS + output that field (even if field value is equal to its + default). + + IMPORTANT: This option costs an extra 4 bytes per primitive field in + the message. Think carefully about whether you really need this. In + many cases reading the default works and determining whether the + field was received over the wire is irrelevant. To use nano protobufs: diff --git a/java/pom.xml b/java/pom.xml index 399540f..7970f72 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -117,6 +117,7 @@ <arg value="../src/google/protobuf/unittest_enormous_descriptor.proto" /> <arg value="../src/google/protobuf/unittest_no_generic_services.proto" /> </exec> + <!-- java micro --> <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" /> @@ -128,6 +129,7 @@ <arg value="../src/google/protobuf/unittest_import_micro.proto" /> <arg value="../src/google/protobuf/unittest_multiple_micro.proto" /> </exec> + <!-- java nano --> <exec executable="../src/protoc"> <arg value="--javanano_out=java_package=google/protobuf/unittest_import_nano.proto|com.google.protobuf.nano,java_outer_classname=google/protobuf/unittest_import_nano.proto|UnittestImportNano:target/generated-test-sources" /> <arg value="--proto_path=../src" /> @@ -146,6 +148,12 @@ <arg value="--proto_path=src/test/java" /> <arg value="../src/google/protobuf/unittest_extension_nano.proto" /> </exec> + <exec executable="../src/protoc"> + <arg value="--javanano_out=java_nano_generate_has=true:target/generated-test-sources" /> + <arg value="--proto_path=../src" /> + <arg value="--proto_path=src/test/java" /> + <arg value="../src/google/protobuf/unittest_has_nano.proto" /> + </exec> </tasks> <testSourceRoot>target/generated-test-sources</testSourceRoot> <!--testSourceRoot>target/generated-test-sources/opt-space</testSourceRoot--> diff --git a/java/src/test/java/com/google/protobuf/NanoTest.java b/java/src/test/java/com/google/protobuf/NanoTest.java index 0ea80d4..80f091b 100644 --- a/java/src/test/java/com/google/protobuf/NanoTest.java +++ b/java/src/test/java/com/google/protobuf/NanoTest.java @@ -37,6 +37,7 @@ import com.google.protobuf.nano.InternalNano; import com.google.protobuf.nano.MessageNano; import com.google.protobuf.nano.MultipleImportingNonMultipleNano1; import com.google.protobuf.nano.MultipleImportingNonMultipleNano2; +import com.google.protobuf.nano.NanoHasOuterClass.TestAllTypesNanoHas; import com.google.protobuf.nano.NanoOuterClass; import com.google.protobuf.nano.NanoOuterClass.TestAllTypesNano; import com.google.protobuf.nano.RecursiveMessageNano; @@ -2095,6 +2096,93 @@ public class NanoTest extends TestCase { } } + public void testNanoWithHasParseFrom() throws Exception { + TestAllTypesNanoHas msg = null; + // Test false on creation, after clear and upon empty parse. + for (int i = 0; i < 3; i++) { + if (i == 0) { + msg = new TestAllTypesNanoHas(); + } else if (i == 1) { + msg.clear(); + } else if (i == 2) { + msg = TestAllTypesNanoHas.parseFrom(new byte[0]); + } + assertFalse(msg.hasOptionalInt32); + assertFalse(msg.hasOptionalString); + assertFalse(msg.hasOptionalBytes); + assertFalse(msg.hasOptionalNestedEnum); + assertFalse(msg.hasDefaultInt32); + assertFalse(msg.hasDefaultString); + assertFalse(msg.hasDefaultBytes); + assertFalse(msg.hasDefaultFloatNan); + assertFalse(msg.hasDefaultNestedEnum); + assertFalse(msg.hasId); + msg.optionalInt32 = 123; + msg.optionalNestedMessage = new TestAllTypesNanoHas.NestedMessage(); + msg.optionalNestedMessage.bb = 2; + msg.optionalNestedEnum = TestAllTypesNano.BAZ; + } + + byte [] result = MessageNano.toByteArray(msg); + int msgSerializedSize = msg.getSerializedSize(); + //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length); + assertTrue(msgSerializedSize == 13); + assertEquals(result.length, msgSerializedSize); + + // Has fields true upon parse. + TestAllTypesNanoHas newMsg = TestAllTypesNanoHas.parseFrom(result); + assertEquals(123, newMsg.optionalInt32); + assertTrue(newMsg.hasOptionalInt32); + assertEquals(2, newMsg.optionalNestedMessage.bb); + assertTrue(newMsg.optionalNestedMessage.hasBb); + assertEquals(TestAllTypesNanoHas.BAZ, newMsg.optionalNestedEnum); + assertTrue(newMsg.hasOptionalNestedEnum); + } + + public void testNanoWithHasSerialize() throws Exception { + TestAllTypesNanoHas msg = new TestAllTypesNanoHas(); + msg.hasOptionalInt32 = true; + msg.hasOptionalString = true; + msg.hasOptionalBytes = true; + msg.optionalNestedMessage = new TestAllTypesNanoHas.NestedMessage(); + msg.optionalNestedMessage.hasBb = true; + msg.hasOptionalNestedEnum = true; + msg.hasDefaultInt32 = true; + msg.hasDefaultString = true; + msg.hasDefaultBytes = true; + msg.hasDefaultFloatNan = true; + msg.hasDefaultNestedEnum = true; + + byte [] result = MessageNano.toByteArray(msg); + int msgSerializedSize = msg.getSerializedSize(); + assertEquals(result.length, msgSerializedSize); + + // Now deserialize and find that all fields are set and equal to their defaults. + TestAllTypesNanoHas newMsg = TestAllTypesNanoHas.parseFrom(result); + assertTrue(newMsg.hasOptionalInt32); + assertTrue(newMsg.hasOptionalString); + assertTrue(newMsg.hasOptionalBytes); + assertTrue(newMsg.optionalNestedMessage.hasBb); + assertTrue(newMsg.hasOptionalNestedEnum); + assertTrue(newMsg.hasDefaultInt32); + assertTrue(newMsg.hasDefaultString); + assertTrue(newMsg.hasDefaultBytes); + assertTrue(newMsg.hasDefaultFloatNan); + assertTrue(newMsg.hasDefaultNestedEnum); + assertTrue(newMsg.hasId); + assertEquals(0, newMsg.optionalInt32); + assertEquals(0, newMsg.optionalString.length()); + assertEquals(0, newMsg.optionalBytes.length); + assertEquals(0, newMsg.optionalNestedMessage.bb); + assertEquals(TestAllTypesNanoHas.FOO, newMsg.optionalNestedEnum); + assertEquals(41, newMsg.defaultInt32); + assertEquals("hello", newMsg.defaultString); + assertEquals("world", new String(newMsg.defaultBytes, "UTF-8")); + assertEquals(TestAllTypesNanoHas.BAR, newMsg.defaultNestedEnum); + assertEquals(Float.NaN, newMsg.defaultFloatNan); + assertEquals(0, newMsg.id); + } + /** * Tests that fields with a default value of NaN are not serialized when * set to NaN. This is a special case as NaN != NaN, so normal equality |