Merge "Avoid class initializers to help ProGuard."

pull/91/head
Max Cai 11 years ago committed by Gerrit Code Review
commit b3bc6095b2
  1. 12
      java/src/main/java/com/google/protobuf/nano/InternalNano.java
  2. 35
      java/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
  3. 6
      src/google/protobuf/compiler/javanano/javanano_enum_field.cc
  4. 12
      src/google/protobuf/compiler/javanano/javanano_enum_field.h
  5. 39
      src/google/protobuf/compiler/javanano/javanano_field.cc
  6. 20
      src/google/protobuf/compiler/javanano/javanano_field.h
  7. 4
      src/google/protobuf/compiler/javanano/javanano_helpers.cc
  8. 92
      src/google/protobuf/compiler/javanano/javanano_message.cc
  9. 6
      src/google/protobuf/compiler/javanano/javanano_message_field.cc
  10. 7
      src/google/protobuf/compiler/javanano/javanano_message_field.h
  11. 94
      src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
  12. 15
      src/google/protobuf/compiler/javanano/javanano_primitive_field.h

@ -45,6 +45,18 @@ public final class InternalNano {
private InternalNano() {}
/**
* An object to provide synchronization when lazily initializing static fields
* of {@link MessageNano} subclasses.
* <p>
* To enable earlier versions of ProGuard to inline short methods from a
* generated MessageNano subclass to the call sites, that class must not have
* a class initializer, which will be created if there is any static variable
* initializers. To lazily initialize the static variables in a thread-safe
* manner, the initialization code will synchronize on this object.
*/
public static final Object LAZY_INIT_LOCK = new Object();
/**
* Helper called by generated code to construct default values for string
* fields.

@ -62,7 +62,7 @@ public final class MessageNanoPrinter {
StringBuffer buf = new StringBuffer();
try {
print(null, message.getClass(), message, new StringBuffer(), buf);
print(null, message, new StringBuffer(), buf);
} catch (IllegalAccessException e) {
return "Error printing proto: " + e.getMessage();
}
@ -70,33 +70,32 @@ public final class MessageNanoPrinter {
}
/**
* Function that will print the given message/class into the StringBuffer.
* Function that will print the given message/field into the StringBuffer.
* Meant to be called recursively.
*
* @param identifier the identifier to use, or {@code null} if this is the root message to
* print.
* @param clazz the class of {@code message}.
* @param message the value to print. May in fact be a primitive value or byte array and not a
* @param object the value to print. May in fact be a primitive value or byte array and not a
* message.
* @param indentBuf the indentation each line should begin with.
* @param buf the output buffer.
*/
private static void print(String identifier, Class<?> clazz, Object message,
private static void print(String identifier, Object object,
StringBuffer indentBuf, StringBuffer buf) throws IllegalAccessException {
if (message == null) {
if (object == null) {
// This can happen if...
// - we're about to print a message, String, or byte[], but it not present;
// - we're about to print a primitive, but "reftype" optional style is enabled, and
// the field is unset.
// In both cases the appropriate behavior is to output nothing.
} else if (MessageNano.class.isAssignableFrom(clazz)) { // Nano proto message
} else if (object instanceof MessageNano) { // Nano proto message
int origIndentBufLength = indentBuf.length();
if (identifier != null) {
buf.append(indentBuf).append(deCamelCaseify(identifier)).append(" <\n");
indentBuf.append(INDENT);
}
for (Field field : clazz.getFields()) {
for (Field field : object.getClass().getFields()) {
// Proto fields are public, non-static variables that do not begin or end with '_'
int modifiers = field.getModifiers();
String fieldName = field.getName();
@ -106,24 +105,24 @@ public final class MessageNanoPrinter {
continue;
}
Class <?> fieldType = field.getType();
Object value = field.get(message);
Class<?> fieldType = field.getType();
Object value = field.get(object);
if (fieldType.isArray()) {
Class<?> arrayType = fieldType.getComponentType();
// bytes is special since it's not repeated, but is represented by an array
if (arrayType == byte.class) {
print(fieldName, fieldType, value, indentBuf, buf);
print(fieldName, value, indentBuf, buf);
} else {
int len = value == null ? 0 : Array.getLength(value);
for (int i = 0; i < len; i++) {
Object elem = Array.get(value, i);
print(fieldName, arrayType, elem, indentBuf, buf);
print(fieldName, elem, indentBuf, buf);
}
}
} else {
print(fieldName, fieldType, value, indentBuf, buf);
print(fieldName, value, indentBuf, buf);
}
}
if (identifier != null) {
@ -134,13 +133,13 @@ public final class MessageNanoPrinter {
// Non-null primitive value
identifier = deCamelCaseify(identifier);
buf.append(indentBuf).append(identifier).append(": ");
if (message instanceof String) {
String stringMessage = sanitizeString((String) message);
if (object instanceof String) {
String stringMessage = sanitizeString((String) object);
buf.append("\"").append(stringMessage).append("\"");
} else if (message instanceof byte[]) {
appendQuotedBytes((byte[]) message, buf);
} else if (object instanceof byte[]) {
appendQuotedBytes((byte[]) object, buf);
} else {
buf.append(message);
buf.append(object);
}
buf.append("\n");
}

@ -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");
}

@ -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;

@ -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

@ -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);

@ -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) {

@ -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()) {

@ -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::

@ -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;

@ -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");
}

@ -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;

Loading…
Cancel
Save