aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMax Cai <maxtroy@google.com>2013-10-09 13:36:23 +0100
committerMax Cai <maxtroy@google.com>2013-12-10 16:46:22 +0000
commit5cc242074f189837b38e7768b57ccfb0bca258df (patch)
tree186c81cc5282eb6ae8056ad478692e3a24188e33 /src
parentcea499acf68b35921b956785c26c0e6f18c241c1 (diff)
downloadexternal_protobuf-5cc242074f189837b38e7768b57ccfb0bca258df.zip
external_protobuf-5cc242074f189837b38e7768b57ccfb0bca258df.tar.gz
external_protobuf-5cc242074f189837b38e7768b57ccfb0bca258df.tar.bz2
Avoid class initializers to help ProGuard.
Class initializers prevent ProGuard from inlining any methods because it thinks the class initializer may have side effects. This is true for static methods, but instance methods can still be inlined, because to have an instance you will have touched the class and any class initializers would have run. But ProGuard only starts inlining instance methods of classes with class initializers from v4.11b6, and Android uses v4.4 now. This change tries to avoid the class initializers as much as possible, by delaying the initialization of the empty array and some fields' saved defaults until when they're needed. However, if the message hosts any extensions, they must be public static final and therefore introducing the class initializer. In that case we won't bother with lazy initialization. Change-Id: I00d8296f6eb0023112b93ee135cdb28dbd52b0b8
Diffstat (limited to 'src')
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_enum_field.cc6
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_enum_field.h12
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_field.cc39
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_field.h20
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_helpers.cc4
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_message.cc92
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_message_field.cc6
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_message_field.h7
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_primitive_field.cc94
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_primitive_field.h15
10 files changed, 219 insertions, 76 deletions
diff --git a/src/google/protobuf/compiler/javanano/javanano_enum_field.cc b/src/google/protobuf/compiler/javanano/javanano_enum_field.cc
index 17f0e26..5d3511b 100644
--- a/src/google/protobuf/compiler/javanano/javanano_enum_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_enum_field.cc
@@ -87,7 +87,7 @@ EnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
EnumFieldGenerator::~EnumFieldGenerator() {}
void EnumFieldGenerator::
-GenerateMembers(io::Printer* printer) const {
+GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
printer->Print(variables_,
"public $type$ $name$;\n");
@@ -214,7 +214,7 @@ AccessorEnumFieldGenerator(const FieldDescriptor* descriptor,
AccessorEnumFieldGenerator::~AccessorEnumFieldGenerator() {}
void AccessorEnumFieldGenerator::
-GenerateMembers(io::Printer* printer) const {
+GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
printer->Print(variables_,
"private int $name$_;\n"
"public int get$capitalized_name$() {\n"
@@ -291,7 +291,7 @@ RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, const Params& para
RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
void RepeatedEnumFieldGenerator::
-GenerateMembers(io::Printer* printer) const {
+GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
printer->Print(variables_,
"public $type$[] $name$;\n");
}
diff --git a/src/google/protobuf/compiler/javanano/javanano_enum_field.h b/src/google/protobuf/compiler/javanano/javanano_enum_field.h
index 9000d20..c477af2 100644
--- a/src/google/protobuf/compiler/javanano/javanano_enum_field.h
+++ b/src/google/protobuf/compiler/javanano/javanano_enum_field.h
@@ -46,11 +46,12 @@ namespace javanano {
class EnumFieldGenerator : public FieldGenerator {
public:
- explicit EnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params);
+ explicit EnumFieldGenerator(
+ const FieldDescriptor* descriptor, const Params& params);
~EnumFieldGenerator();
// implements FieldGenerator ---------------------------------------
- void GenerateMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer, bool lazy_init) const;
void GenerateClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
@@ -72,7 +73,7 @@ class AccessorEnumFieldGenerator : public FieldGenerator {
~AccessorEnumFieldGenerator();
// implements FieldGenerator ---------------------------------------
- void GenerateMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer, bool lazy_init) const;
void GenerateClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
@@ -89,11 +90,12 @@ class AccessorEnumFieldGenerator : public FieldGenerator {
class RepeatedEnumFieldGenerator : public FieldGenerator {
public:
- explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params);
+ explicit RepeatedEnumFieldGenerator(
+ const FieldDescriptor* descriptor, const Params& params);
~RepeatedEnumFieldGenerator();
// implements FieldGenerator ---------------------------------------
- void GenerateMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer, bool lazy_init) const;
void GenerateClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateMergingCodeFromPacked(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/javanano/javanano_field.cc b/src/google/protobuf/compiler/javanano/javanano_field.cc
index 2581669..e3e4cef 100644
--- a/src/google/protobuf/compiler/javanano/javanano_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_field.cc
@@ -46,6 +46,19 @@ namespace javanano {
FieldGenerator::~FieldGenerator() {}
+bool FieldGenerator::SavedDefaultNeeded() const {
+ // No saved default for this field by default.
+ // Subclasses whose instances may need saved defaults will override this
+ // and return the appropriate value.
+ return false;
+}
+
+void FieldGenerator::GenerateInitSavedDefaultCode(io::Printer* printer) const {
+ // No saved default for this field by default.
+ // Subclasses whose instances may need saved defaults will override this
+ // and generate the appropriate init code to the printer.
+}
+
void FieldGenerator::GenerateMergingCodeFromPacked(io::Printer* printer) const {
// Reaching here indicates a bug. Cases are:
// - This FieldGenerator should support packing, but this method should be
@@ -56,24 +69,26 @@ void FieldGenerator::GenerateMergingCodeFromPacked(io::Printer* printer) const {
<< "called on field generator that does not support packing.";
}
-FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, const Params &params)
+// =============================================
+
+FieldGeneratorMap::FieldGeneratorMap(
+ const Descriptor* descriptor, const Params &params)
: descriptor_(descriptor),
field_generators_(
- new scoped_ptr<FieldGenerator>[descriptor->field_count()]),
- extension_generators_(
- new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) {
+ new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
int next_has_bit_index = 0;
+ bool saved_defaults_needed = false;
// Construct all the FieldGenerators.
for (int i = 0; i < descriptor->field_count(); i++) {
- field_generators_[i].reset(
- MakeGenerator(descriptor->field(i), params, &next_has_bit_index));
- }
- for (int i = 0; i < descriptor->extension_count(); i++) {
- extension_generators_[i].reset(
- MakeGenerator(descriptor->extension(i), params, &next_has_bit_index));
+ FieldGenerator* field_generator = MakeGenerator(
+ descriptor->field(i), params, &next_has_bit_index);
+ saved_defaults_needed = saved_defaults_needed
+ || field_generator->SavedDefaultNeeded();
+ field_generators_[i].reset(field_generator);
}
total_bits_ = next_has_bit_index;
+ saved_defaults_needed_ = saved_defaults_needed;
}
FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
@@ -122,10 +137,6 @@ const FieldGenerator& FieldGeneratorMap::get(
return *field_generators_[field->index()];
}
-const FieldGenerator& FieldGeneratorMap::get_extension(int index) const {
- return *extension_generators_[index];
-}
-
} // namespace javanano
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/javanano/javanano_field.h b/src/google/protobuf/compiler/javanano/javanano_field.h
index 14b6489..61fc621 100644
--- a/src/google/protobuf/compiler/javanano/javanano_field.h
+++ b/src/google/protobuf/compiler/javanano/javanano_field.h
@@ -53,11 +53,23 @@ namespace javanano {
class FieldGenerator {
public:
- //FieldGenerator() {}
FieldGenerator(const Params& params) : params_(params) {}
virtual ~FieldGenerator();
- virtual void GenerateMembers(io::Printer* printer) const = 0;
+ virtual bool SavedDefaultNeeded() const;
+ virtual void GenerateInitSavedDefaultCode(io::Printer* printer) const;
+
+ // Generates code for Java fields and methods supporting this field.
+ // If this field needs a saved default (SavedDefaultNeeded() is true),
+ // then @lazy_init controls how the static field for that default value
+ // and its initialization code should be generated. If @lazy_init is
+ // true, the static field is not declared final and the initialization
+ // code is generated only when GenerateInitSavedDefaultCode is called;
+ // otherwise, the static field is declared final and initialized inline.
+ // GenerateInitSavedDefaultCode will not be called in the latter case.
+ virtual void GenerateMembers(
+ io::Printer* printer, bool lazy_init) const = 0;
+
virtual void GenerateClearCode(io::Printer* printer) const = 0;
virtual void GenerateMergingCode(io::Printer* printer) const = 0;
@@ -84,14 +96,14 @@ class FieldGeneratorMap {
~FieldGeneratorMap();
const FieldGenerator& get(const FieldDescriptor* field) const;
- const FieldGenerator& get_extension(int index) const;
int total_bits() const { return total_bits_; }
+ bool saved_defaults_needed() const { return saved_defaults_needed_; }
private:
const Descriptor* descriptor_;
scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
- scoped_array<scoped_ptr<FieldGenerator> > extension_generators_;
int total_bits_;
+ bool saved_defaults_needed_;
static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
const Params &params, int* next_has_bit_index);
diff --git a/src/google/protobuf/compiler/javanano/javanano_helpers.cc b/src/google/protobuf/compiler/javanano/javanano_helpers.cc
index 95ee670..b3bedcb 100644
--- a/src/google/protobuf/compiler/javanano/javanano_helpers.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_helpers.cc
@@ -261,9 +261,7 @@ string FieldConstantName(const FieldDescriptor *field) {
}
string FieldDefaultConstantName(const FieldDescriptor *field) {
- string name = field->name() + "_DEFAULT";
- UpperString(&name);
- return name;
+ return "_" + RenameJavaKeywords(UnderscoresToCamelCase(field)) + "Default";
}
JavaType GetJavaType(FieldDescriptor::Type field_type) {
diff --git a/src/google/protobuf/compiler/javanano/javanano_message.cc b/src/google/protobuf/compiler/javanano/javanano_message.cc
index f7ab62c..c09670a 100644
--- a/src/google/protobuf/compiler/javanano/javanano_message.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_message.cc
@@ -155,14 +155,6 @@ void MessageGenerator::Generate(io::Printer* printer) {
" com.google.protobuf.nano.MessageNano {\n");
}
printer->Indent();
- printer->Print(
- "\n"
- "public static final $classname$[] EMPTY_ARRAY = {};\n"
- "\n"
- "public $classname$() {\n"
- " clear();\n"
- "}\n",
- "classname", descriptor_->name());
// Nested types and extensions
for (int i = 0; i < descriptor_->extension_count(); i++) {
@@ -177,6 +169,42 @@ void MessageGenerator::Generate(io::Printer* printer) {
MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer);
}
+ // Lazy initialization of otherwise static final fields can help prevent the
+ // class initializer from being generated. We want to prevent it because it
+ // stops ProGuard from inlining any methods in this class into call sites and
+ // therefore reducing the method count. However, extensions are best kept as
+ // public static final fields with initializers, so with their existence we
+ // won't bother with lazy initialization.
+ bool lazy_init = descriptor_->extension_count() == 0;
+
+ // Empty array
+ if (lazy_init) {
+ printer->Print(
+ "\n"
+ "private static volatile $classname$[] _emptyArray;\n"
+ "public static $classname$[] emptyArray() {\n"
+ " // Lazily initializes the empty array\n"
+ " if (_emptyArray == null) {\n"
+ " synchronized (\n"
+ " com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n"
+ " if (_emptyArray == null) {\n"
+ " _emptyArray = new $classname$[0];\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ " return _emptyArray;\n"
+ "}\n",
+ "classname", descriptor_->name());
+ } else {
+ printer->Print(
+ "\n"
+ "private static final $classname$[] EMPTY_ARRAY = {};\n"
+ "public static $classname$[] emptyArray() {\n"
+ " return EMPTY_ARRAY;\n"
+ "}\n",
+ "classname", descriptor_->name());
+ }
+
// Integers for bit fields
int totalInts = (field_generators_.total_bits() + 31) / 32;
if (totalInts > 0) {
@@ -187,13 +215,57 @@ void MessageGenerator::Generate(io::Printer* printer) {
}
}
- // Fields
+ // Fields and maybe their default values
for (int i = 0; i < descriptor_->field_count(); i++) {
printer->Print("\n");
PrintFieldComment(printer, descriptor_->field(i));
- field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
+ field_generators_.get(descriptor_->field(i)).GenerateMembers(
+ printer, lazy_init);
+ }
+
+ // Constructor, with lazy init code if needed
+ if (lazy_init && field_generators_.saved_defaults_needed()) {
+ printer->Print(
+ "\n"
+ "private static volatile boolean _classInitialized;\n"
+ "\n"
+ "public $classname$() {\n"
+ " // Lazily initializes the field defaults\n"
+ " if (!_classInitialized) {\n"
+ " synchronized (\n"
+ " com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n"
+ " if (!_classInitialized) {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+ printer->Indent();
+ printer->Indent();
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateInitSavedDefaultCode(printer);
+ }
+ printer->Outdent();
+ printer->Outdent();
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " _classInitialized = true;\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ " clear();\n"
+ "}\n");
+ } else {
+ printer->Print(
+ "\n"
+ "public $classname$() {\n"
+ " clear();\n"
+ "}\n",
+ "classname", descriptor_->name());
}
+ // Other methods in this class
+
GenerateClear(printer);
if (params_.generate_equals()) {
diff --git a/src/google/protobuf/compiler/javanano/javanano_message_field.cc b/src/google/protobuf/compiler/javanano/javanano_message_field.cc
index 74d3f85..a46081d 100644
--- a/src/google/protobuf/compiler/javanano/javanano_message_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_message_field.cc
@@ -82,7 +82,7 @@ MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
MessageFieldGenerator::~MessageFieldGenerator() {}
void MessageFieldGenerator::
-GenerateMembers(io::Printer* printer) const {
+GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
printer->Print(variables_,
"public $type$ $name$;\n");
}
@@ -158,7 +158,7 @@ RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, const Params& p
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
void RepeatedMessageFieldGenerator::
-GenerateMembers(io::Printer* printer) const {
+GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
printer->Print(variables_,
"public $type$[] $name$;\n");
}
@@ -166,7 +166,7 @@ GenerateMembers(io::Printer* printer) const {
void RepeatedMessageFieldGenerator::
GenerateClearCode(io::Printer* printer) const {
printer->Print(variables_,
- "$name$ = $type$.EMPTY_ARRAY;\n");
+ "$name$ = $type$.emptyArray();\n");
}
void RepeatedMessageFieldGenerator::
diff --git a/src/google/protobuf/compiler/javanano/javanano_message_field.h b/src/google/protobuf/compiler/javanano/javanano_message_field.h
index 55e2610..e94a37b 100644
--- a/src/google/protobuf/compiler/javanano/javanano_message_field.h
+++ b/src/google/protobuf/compiler/javanano/javanano_message_field.h
@@ -46,11 +46,12 @@ namespace javanano {
class MessageFieldGenerator : public FieldGenerator {
public:
- explicit MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params);
+ explicit MessageFieldGenerator(
+ const FieldDescriptor* descriptor, const Params& params);
~MessageFieldGenerator();
// implements FieldGenerator ---------------------------------------
- void GenerateMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer, bool lazy_init) const;
void GenerateClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
@@ -72,7 +73,7 @@ class RepeatedMessageFieldGenerator : public FieldGenerator {
~RepeatedMessageFieldGenerator();
// implements FieldGenerator ---------------------------------------
- void GenerateMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer, bool lazy_init) const;
void GenerateClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
index c0717e6..3428f69 100644
--- a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
@@ -251,35 +251,41 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params param
} else {
(*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
}
- (*variables)["default"] = DefaultValue(params, descriptor);
- (*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
- // For C++-string types (string and bytes), we might need to have
- // the generated code do the unicode decoding (see comments in
- // InternalNano.java for gory details.). We would like to do this
- // once into a "private static final" field and re-use that from
+ // Deals with defaults. For C++-string types (string and bytes),
+ // we might need to have the generated code do the unicode decoding
+ // (see comments in InternalNano.java for gory details.). We would
+ // like to do this once into a static field and re-use that from
// then on.
if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
!descriptor->default_value_string().empty() &&
!params.use_reference_types_for_primitives()) {
- string default_value;
if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
- default_value = strings::Substitute(
+ (*variables)["default"] = DefaultValue(params, descriptor);
+ (*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
+ (*variables)["default_constant_value"] = strings::Substitute(
"com.google.protobuf.nano.InternalNano.bytesDefaultValue(\"$0\")",
CEscape(descriptor->default_value_string()));
- (*variables)["default_copy_if_needed"] = (*variables)["default"] + ".clone()";
+ (*variables)["default_copy_if_needed"] =
+ (*variables)["default"] + ".clone()";
+ } else if (AllAscii(descriptor->default_value_string())) {
+ // All chars are ASCII. In this case directly referencing a
+ // CEscape()'d string literal works fine.
+ (*variables)["default"] =
+ "\"" + CEscape(descriptor->default_value_string()) + "\"";
+ (*variables)["default_copy_if_needed"] = (*variables)["default"];
} else {
- if (AllAscii(descriptor->default_value_string())) {
- // All chars are ASCII. In this case CEscape() works fine.
- default_value = "\"" + CEscape(descriptor->default_value_string()) + "\"";
- } else {
- default_value = strings::Substitute(
- "com.google.protobuf.nano.InternalNano.stringDefaultValue(\"$0\")",
- CEscape(descriptor->default_value_string()));
- }
+ // Strings where some chars are non-ASCII. We need to save the
+ // default value.
+ (*variables)["default"] = DefaultValue(params, descriptor);
+ (*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
+ (*variables)["default_constant_value"] = strings::Substitute(
+ "com.google.protobuf.nano.InternalNano.stringDefaultValue(\"$0\")",
+ CEscape(descriptor->default_value_string()));
(*variables)["default_copy_if_needed"] = (*variables)["default"];
}
- (*variables)["default_constant_value"] = default_value;
} else {
+ // Non-string, non-bytes field. Defaults are literals.
+ (*variables)["default"] = DefaultValue(params, descriptor);
(*variables)["default_copy_if_needed"] = (*variables)["default"];
}
(*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
@@ -306,12 +312,29 @@ PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
+bool PrimitiveFieldGenerator::SavedDefaultNeeded() const {
+ return variables_.find("default_constant") != variables_.end();
+}
+
+void PrimitiveFieldGenerator::GenerateInitSavedDefaultCode(io::Printer* printer) const {
+ if (variables_.find("default_constant") != variables_.end()) {
+ printer->Print(variables_,
+ "$default_constant$ = $default_constant_value$;\n");
+ }
+}
+
void PrimitiveFieldGenerator::
-GenerateMembers(io::Printer* printer) const {
- if (variables_.find("default_constant_value") != variables_.end()) {
+GenerateMembers(io::Printer* printer, bool lazy_init) const {
+ if (variables_.find("default_constant") != variables_.end()) {
// Those primitive types that need a saved default.
- printer->Print(variables_,
- "private static final $type$ $default_constant$ = $default_constant_value$;\n");
+ if (lazy_init) {
+ printer->Print(variables_,
+ "private static $type$ $default_constant$;\n");
+ } else {
+ printer->Print(variables_,
+ "private static final $type$ $default_constant$ =\n"
+ " $default_constant_value$;\n");
+ }
}
printer->Print(variables_,
@@ -514,11 +537,30 @@ AccessorPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
AccessorPrimitiveFieldGenerator::~AccessorPrimitiveFieldGenerator() {}
+bool AccessorPrimitiveFieldGenerator::SavedDefaultNeeded() const {
+ return variables_.find("default_constant") != variables_.end();
+}
+
void AccessorPrimitiveFieldGenerator::
-GenerateMembers(io::Printer* printer) const {
- if (variables_.find("default_constant_value") != variables_.end()) {
+GenerateInitSavedDefaultCode(io::Printer* printer) const {
+ if (variables_.find("default_constant") != variables_.end()) {
printer->Print(variables_,
- "private static final $type$ $default_constant$ = $default_constant_value$;\n");
+ "$default_constant$ = $default_constant_value$;\n");
+ }
+}
+
+void AccessorPrimitiveFieldGenerator::
+GenerateMembers(io::Printer* printer, bool lazy_init) const {
+ if (variables_.find("default_constant") != variables_.end()) {
+ // Those primitive types that need a saved default.
+ if (lazy_init) {
+ printer->Print(variables_,
+ "private static $type$ $default_constant$;\n");
+ } else {
+ printer->Print(variables_,
+ "private static final $type$ $default_constant$ =\n"
+ " $default_constant_value$;\n");
+ }
}
printer->Print(variables_,
"private $type$ $name$_;\n"
@@ -671,7 +713,7 @@ RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params&
RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
void RepeatedPrimitiveFieldGenerator::
-GenerateMembers(io::Printer* printer) const {
+GenerateMembers(io::Printer* printer, bool /*unused init_defaults*/) const {
printer->Print(variables_,
"public $type$[] $name$;\n");
}
diff --git a/src/google/protobuf/compiler/javanano/javanano_primitive_field.h b/src/google/protobuf/compiler/javanano/javanano_primitive_field.h
index d207535..c04a19b 100644
--- a/src/google/protobuf/compiler/javanano/javanano_primitive_field.h
+++ b/src/google/protobuf/compiler/javanano/javanano_primitive_field.h
@@ -46,11 +46,14 @@ namespace javanano {
class PrimitiveFieldGenerator : public FieldGenerator {
public:
- explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params &params);
+ explicit PrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, const Params &params);
~PrimitiveFieldGenerator();
// implements FieldGenerator ---------------------------------------
- void GenerateMembers(io::Printer* printer) const;
+ bool SavedDefaultNeeded() const;
+ void GenerateInitSavedDefaultCode(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer, bool lazy_init) const;
void GenerateClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
@@ -69,12 +72,14 @@ class PrimitiveFieldGenerator : public FieldGenerator {
class AccessorPrimitiveFieldGenerator : public FieldGenerator {
public:
- explicit AccessorPrimitiveFieldGenerator( const FieldDescriptor* descriptor,
+ explicit AccessorPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
const Params &params, int has_bit_index);
~AccessorPrimitiveFieldGenerator();
// implements FieldGenerator ---------------------------------------
- void GenerateMembers(io::Printer* printer) const;
+ bool SavedDefaultNeeded() const;
+ void GenerateInitSavedDefaultCode(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer, bool lazy_init) const;
void GenerateClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
@@ -95,7 +100,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
~RepeatedPrimitiveFieldGenerator();
// implements FieldGenerator ---------------------------------------
- void GenerateMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer, bool lazy_init) const;
void GenerateClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateMergingCodeFromPacked(io::Printer* printer) const;