aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorUlas Kirazci <ulas@google.com>2013-04-01 11:29:43 -0700
committerUlas Kirazci <ulas@google.com>2013-07-29 09:35:44 -0700
commit35d9fd84ff1d9ecdb91156b757cc9fdcc3f25249 (patch)
treebf47056d6c723ec8939717efb9a5f30cbe7783af /java
parent021f8f1badf1c4db519e3f35d600dec4b5c52eff (diff)
downloadexternal_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.txt16
-rw-r--r--java/pom.xml8
-rw-r--r--java/src/test/java/com/google/protobuf/NanoTest.java88
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