aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brian Duff <bduff@google.com>2015-01-09 13:32:38 -0800
committerGravatar Brian Duff <bduff@google.com>2015-04-28 12:28:05 -0700
commitfb96026b8deb79aa023c9f5c460582e8fea8f331 (patch)
tree45d106b89a44546c57846c0174764c0c367a0ab0
parent9ffaa50d55bf377f4693eae45483e26ca136f878 (diff)
When no clear() is generated, still initialize fields.
https://android-review.googlesource.com/#/c/67890/ removed field initialization from the ctor, making it just call clear() instead. When I added the generate_clear option back (as part of the reftypes compat mode) in https://android-review.googlesource.com/#/c/109530/, I forgot to ensure that what clear() used to do was inlined in the constructor. This change fixes NPEs that are happening for users of reftypes_compat_mode who rely on unset repeated fields being empty arrays rather than null. Change-Id: Idb58746c60f4a4054b7ebb5c3b0e76b16ff88184
-rw-r--r--javanano/pom.xml9
-rw-r--r--javanano/src/test/java/com/google/protobuf/nano/NanoTest.java6
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_message.cc32
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_message.h1
4 files changed, 36 insertions, 12 deletions
diff --git a/javanano/pom.xml b/javanano/pom.xml
index 7a2be9df..64ed4372 100644
--- a/javanano/pom.xml
+++ b/javanano/pom.xml
@@ -139,6 +139,15 @@
<arg value="--proto_path=src/test/java/com" />
<arg value="src/test/java/com/google/protobuf/nano/unittest_reference_types_nano.proto" />
</exec>
+ <exec executable="../src/protoc">
+ <arg value="--javanano_out=
+ optional_field_style=reftypes_compat_mode,
+ generate_equals=true,
+ java_outer_classname=google/protobuf/nano/unittest_reference_types_nano.proto|NanoReferenceTypesCompat
+ :target/generated-test-sources" />
+ <arg value="--proto_path=src/test/java/com" />
+ <arg value="src/test/java/com/google/protobuf/nano/unittest_reference_types_nano.proto" />
+ </exec>
</tasks>
<testSourceRoot>target/generated-test-sources</testSourceRoot>
</configuration>
diff --git a/javanano/src/test/java/com/google/protobuf/nano/NanoTest.java b/javanano/src/test/java/com/google/protobuf/nano/NanoTest.java
index d60e94ff..c81846e5 100644
--- a/javanano/src/test/java/com/google/protobuf/nano/NanoTest.java
+++ b/javanano/src/test/java/com/google/protobuf/nano/NanoTest.java
@@ -36,6 +36,7 @@ import com.google.protobuf.nano.NanoAccessorsOuterClass.TestNanoAccessors;
import com.google.protobuf.nano.NanoHasOuterClass.TestAllTypesNanoHas;
import com.google.protobuf.nano.NanoOuterClass.TestAllTypesNano;
import com.google.protobuf.nano.UnittestRecursiveNano.RecursiveMessageNano;
+import com.google.protobuf.nano.NanoReferenceTypesCompat;
import com.google.protobuf.nano.UnittestSimpleNano.SimpleMessageNano;
import com.google.protobuf.nano.UnittestSingleNano.SingleMessageNano;
import com.google.protobuf.nano.testext.Extensions;
@@ -4381,6 +4382,11 @@ public class NanoTest extends TestCase {
assertMapSet(testMap.sfixed64ToSfixed64Field, int64Values, int64Values);
}
+ public void testRepeatedFieldInitializedInReftypesCompatMode() {
+ NanoReferenceTypesCompat.TestAllTypesNano proto = new NanoReferenceTypesCompat.TestAllTypesNano();
+ assertNotNull(proto.repeatedString);
+ }
+
private void assertRepeatedPackablesEqual(
NanoRepeatedPackables.NonPacked nonPacked, NanoRepeatedPackables.Packed packed) {
// Not using MessageNano.equals() -- that belongs to a separate test.
diff --git a/src/google/protobuf/compiler/javanano/javanano_message.cc b/src/google/protobuf/compiler/javanano/javanano_message.cc
index 707f6b84..d5cbe9ce 100644
--- a/src/google/protobuf/compiler/javanano/javanano_message.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_message.cc
@@ -288,14 +288,18 @@ void MessageGenerator::Generate(io::Printer* printer) {
}
printer->Print("}\n");
} else {
+ printer->Print(
+ "\n"
+ "public $classname$() {\n",
+ "classname", descriptor_->name());
if (params_.generate_clear()) {
- printer->Print(
- "\n"
- "public $classname$() {\n"
- " clear();\n"
- "}\n",
- "classname", descriptor_->name());
+ printer->Print(" clear();\n");
+ } else {
+ printer->Indent();
+ GenerateFieldInitializers(printer);
+ printer->Outdent();
}
+ printer->Print("}\n");
}
// Other methods in this class
@@ -495,6 +499,15 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
"classname", descriptor_->name());
printer->Indent();
+ GenerateFieldInitializers(printer);
+
+ printer->Outdent();
+ printer->Print(
+ " return this;\n"
+ "}\n");
+}
+
+void MessageGenerator::GenerateFieldInitializers(io::Printer* printer) {
// Clear bit fields.
int totalInts = (field_generators_.total_bits() + 31) / 32;
for (int i = 0; i < totalInts; i++) {
@@ -520,12 +533,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
if (params_.store_unknown_fields()) {
printer->Print("unknownFieldData = null;\n");
}
-
- printer->Outdent();
- printer->Print(
- " cachedSize = -1;\n"
- " return this;\n"
- "}\n");
+ printer->Print("cachedSize = -1;\n");
}
void MessageGenerator::GenerateEquals(io::Printer* printer) {
diff --git a/src/google/protobuf/compiler/javanano/javanano_message.h b/src/google/protobuf/compiler/javanano/javanano_message.h
index 6f25a3a0..8504aa83 100644
--- a/src/google/protobuf/compiler/javanano/javanano_message.h
+++ b/src/google/protobuf/compiler/javanano/javanano_message.h
@@ -77,6 +77,7 @@ class MessageGenerator {
const FieldDescriptor* field);
void GenerateClear(io::Printer* printer);
+ void GenerateFieldInitializers(io::Printer* printer);
void GenerateEquals(io::Printer* printer);
void GenerateHashCode(io::Printer* printer);