Initial check in for primitive oneof fields.

changes/00/217000/1
Jisi Liu 10 years ago
parent f0e08fd4e4
commit 33222b5a02
  1. 8
      javanano/src/test/java/com/google/protobuf/nano/unittest_nano.proto
  2. 23
      src/google/protobuf/compiler/javanano/javanano_field.cc
  3. 4
      src/google/protobuf/compiler/javanano/javanano_field.h
  4. 8
      src/google/protobuf/compiler/javanano/javanano_helpers.cc
  5. 5
      src/google/protobuf/compiler/javanano/javanano_helpers.h
  6. 14
      src/google/protobuf/compiler/javanano/javanano_message.cc
  7. 76
      src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
  8. 25
      src/google/protobuf/compiler/javanano/javanano_primitive_field.h

@ -167,6 +167,14 @@ message TestAllTypesNano {
// Try to fail with java reserved keywords
optional int32 synchronized = 96;
oneof oneof_field {
uint32 oneof_uint32 = 111;
// NestedMessage oneof_nested_message = 112;
// string oneof_string = 123;
// bytes oneof_bytes = 124;
fixed64 oneof_fixed64 = 115;
}
}
message ForeignMessageNano {

@ -108,6 +108,13 @@ FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
default:
return new RepeatedPrimitiveFieldGenerator(field, params);
}
} else if (field->containing_oneof()) {
switch (java_type) {
case JAVATYPE_MESSAGE:
case JAVATYPE_ENUM:
default:
return new PrimitiveOneofFieldGenerator(field, params);
}
} else if (params.optional_field_accessors() && field->is_optional()
&& java_type != JAVATYPE_MESSAGE) {
// We need a has-bit for each primitive/enum field because their default
@ -142,6 +149,22 @@ const FieldGenerator& FieldGeneratorMap::get(
return *field_generators_[field->index()];
}
void SetCommonOneofVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
(*variables)["oneof_name"] =
UnderscoresToCamelCase(descriptor->containing_oneof());
(*variables)["oneof_capitalized_name"] =
UnderscoresToCapitalizedCamelCase(descriptor->containing_oneof());
(*variables)["oneof_index"] =
SimpleItoa(descriptor->containing_oneof()->index());
(*variables)["set_oneof_case"] =
(*variables)["oneof_name"] + "Case_ = " + SimpleItoa(descriptor->number());
(*variables)["clear_oneof_case"] =
(*variables)["oneof_name"] + "Case_ = 0";
(*variables)["has_oneof_case"] =
(*variables)["oneof_name"] + "Case_ == " + SimpleItoa(descriptor->number());
}
} // namespace javanano
} // namespace compiler
} // namespace protobuf

@ -35,6 +35,7 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVANANO_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_JAVANANO_FIELD_H__
#include <map>
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
@ -111,6 +112,9 @@ class FieldGeneratorMap {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
};
void SetCommonOneofVariables(const FieldDescriptor* descriptor,
map<string, string>* variables);
} // namespace javanano
} // namespace compiler
} // namespace protobuf

@ -154,6 +154,14 @@ string UnderscoresToCamelCase(const MethodDescriptor* method) {
return UnderscoresToCamelCaseImpl(method->name(), false);
}
string UnderscoresToCamelCase(const OneofDescriptor* oneof) {
return UnderscoresToCamelCaseImpl(oneof->name(), false);
}
string UnderscoresToCapitalizedCamelCase(const OneofDescriptor* oneof) {
return UnderscoresToCamelCaseImpl(oneof->name(), true);
}
string RenameJavaKeywords(const string& input) {
return sRenameKeywords.RenameJavaKeywordsImpl(input);
}

@ -54,7 +54,9 @@ extern const char kThinSeparator[];
// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes
// "fooBarBaz" or "FooBarBaz", respectively.
string UnderscoresToCamelCase(const FieldDescriptor* field);
string UnderscoresToCamelCase(const OneofDescriptor* oneof);
string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field);
string UnderscoresToCapitalizedCamelCase(const OneofDescriptor* oneof);
// Appends an "_" to the end of a field where the name is a reserved java
// keyword. For example int32 public = 1 will generate int public_.
@ -189,6 +191,9 @@ inline bool IsMapEntry(const Descriptor* descriptor) {
bool HasMapField(const Descriptor* descriptor);
void SetCommonOneofVariables(const FieldDescriptor* field,
map<string, string>* variables);
} // namespace javanano
} // namespace compiler
} // namespace protobuf

@ -165,6 +165,20 @@ void MessageGenerator::Generate(io::Printer* printer) {
MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer);
}
// oneof
map<string, string> vars;
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
vars["oneof_name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i));
vars["oneof_capitalized_name"] =
UnderscoresToCapitalizedCamelCase(descriptor_->oneof_decl(i));
vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
// oneofCase_ and oneof_
printer->Print(vars,
"private int $oneof_name$Case_ = 0;\n"
"private java.lang.Object $oneof_name$_;\n");
// OneofCase enum
}
// 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

@ -706,8 +706,80 @@ GenerateHashCodeCode(io::Printer* printer) const {
// ===================================================================
RepeatedPrimitiveFieldGenerator::
RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator(
const FieldDescriptor* descriptor, const Params& params)
: FieldGenerator(params), descriptor_(descriptor) {
SetPrimitiveVariables(descriptor, params, &variables_);
SetCommonOneofVariables(descriptor, &variables_);
}
PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {}
void PrimitiveOneofFieldGenerator::GenerateMembers(
io::Printer* printer, bool /*unused lazy_init*/) const {
printer->Print(variables_,
"public boolean has$capitalized_name$() {\n"
" return $has_oneof_case$;\n"
"}\n"
"public $type$ get$capitalized_name$() {\n"
" if ($has_oneof_case$) {\n"
" return ($type$) ($boxed_type$) $oneof_name$_;\n"
" }\n"
" return $default$;\n"
"}\n"
"public $message_name$ set$capitalized_name$($type$ value) {\n"
" $set_oneof_case$;\n"
" $oneof_name$_ = value;\n"
" return this;\n"
"}\n"
"public $message_name$ clear$capitalized_name$() {\n"
" $clear_oneof_case$;\n"
" $oneof_name$_ = null;\n"
" return this;\n"
"}\n");
}
void PrimitiveOneofFieldGenerator::GenerateClearCode(
io::Printer* printer) const {
// No clear method for oneof fields.
}
void PrimitiveOneofFieldGenerator::GenerateMergingCode(
io::Printer* printer) const {
printer->Print(variables_,
"$oneof_name$_ = input.read$capitalized_type$();\n"
"$set_oneof_case$;\n");
}
void PrimitiveOneofFieldGenerator::GenerateSerializationCode(
io::Printer* printer) const {
printer->Print(variables_,
"if ($has_oneof_case$) {\n"
" output.write$capitalized_type$(\n"
" $number$, ($boxed_type$) $oneof_name$_);\n"
"}\n");
}
void PrimitiveOneofFieldGenerator::GenerateSerializedSizeCode(
io::Printer* printer) const {
printer->Print(variables_,
"if ($has_oneof_case$) {\n"
" size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
" .compute$capitalized_type$Size(\n"
" $number$, ($boxed_type$) $oneof_name$_);\n"
"}\n");
}
void PrimitiveOneofFieldGenerator::GenerateEqualsCode(io::Printer* printer) const {
}
void PrimitiveOneofFieldGenerator::GenerateHashCodeCode(io::Printer* printer) const {
}
// ===================================================================
RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
const FieldDescriptor* descriptor, const Params& params)
: FieldGenerator(params), descriptor_(descriptor) {
SetPrimitiveVariables(descriptor, params, &variables_);
}

@ -94,9 +94,32 @@ class AccessorPrimitiveFieldGenerator : public FieldGenerator {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AccessorPrimitiveFieldGenerator);
};
class PrimitiveOneofFieldGenerator : public FieldGenerator {
public:
explicit PrimitiveOneofFieldGenerator(
const FieldDescriptor* descriptor, const Params& params);
~PrimitiveOneofFieldGenerator();
// implements FieldGenerator ---------------------------------------
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;
void GenerateSerializedSizeCode(io::Printer* printer) const;
void GenerateEqualsCode(io::Printer* printer) const;
void GenerateHashCodeCode(io::Printer* printer) const;
private:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveOneofFieldGenerator);
};
class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
public:
explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params);
explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
const Params& params);
~RepeatedPrimitiveFieldGenerator();
// implements FieldGenerator ---------------------------------------

Loading…
Cancel
Save