Merge "Avoid class initializers to help ProGuard."
This commit is contained in:
commit
b3bc6095b2
@ -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 ¶ms)
|
||||
// =============================================
|
||||
|
||||
FieldGeneratorMap::FieldGeneratorMap(
|
||||
const Descriptor* descriptor, const Params ¶ms)
|
||||
: 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 ¶ms, 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() {}
|
||||
|
||||
void PrimitiveFieldGenerator::
|
||||
GenerateMembers(io::Printer* printer) const {
|
||||
if (variables_.find("default_constant_value") != variables_.end()) {
|
||||
// Those primitive types that need a saved default.
|
||||
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_,
|
||||
"private static final $type$ $default_constant$ = $default_constant_value$;\n");
|
||||
"$default_constant$ = $default_constant_value$;\n");
|
||||
}
|
||||
}
|
||||
|
||||
void PrimitiveFieldGenerator::
|
||||
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_,
|
||||
@ -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 ¶ms);
|
||||
explicit PrimitiveFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Params ¶ms);
|
||||
~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 ¶ms, 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…
Reference in New Issue
Block a user