Browse Source

Initial check in for primitive oneof fields.

Jisi Liu 10 years ago
parent
commit
33222b5a02

+ 8 - 0
javanano/src/test/java/com/google/protobuf/nano/unittest_nano.proto

@@ -167,6 +167,14 @@ message TestAllTypesNano {
 
 
   // Try to fail with java reserved keywords
   // Try to fail with java reserved keywords
   optional int32 synchronized = 96;
   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 {
 message ForeignMessageNano {

+ 23 - 0
src/google/protobuf/compiler/javanano/javanano_field.cc

@@ -108,6 +108,13 @@ FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
       default:
       default:
         return new RepeatedPrimitiveFieldGenerator(field, params);
         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()
   } else if (params.optional_field_accessors() && field->is_optional()
       && java_type != JAVATYPE_MESSAGE) {
       && java_type != JAVATYPE_MESSAGE) {
     // We need a has-bit for each primitive/enum field because their default
     // 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()];
   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 javanano
 }  // namespace compiler
 }  // namespace compiler
 }  // namespace protobuf
 }  // namespace protobuf

+ 4 - 0
src/google/protobuf/compiler/javanano/javanano_field.h

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

+ 8 - 0
src/google/protobuf/compiler/javanano/javanano_helpers.cc

@@ -154,6 +154,14 @@ string UnderscoresToCamelCase(const MethodDescriptor* method) {
   return UnderscoresToCamelCaseImpl(method->name(), false);
   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) {
 string RenameJavaKeywords(const string& input) {
   return sRenameKeywords.RenameJavaKeywordsImpl(input);
   return sRenameKeywords.RenameJavaKeywordsImpl(input);
 }
 }

+ 5 - 0
src/google/protobuf/compiler/javanano/javanano_helpers.h

@@ -54,7 +54,9 @@ extern const char kThinSeparator[];
 // Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes
 // Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes
 // "fooBarBaz" or "FooBarBaz", respectively.
 // "fooBarBaz" or "FooBarBaz", respectively.
 string UnderscoresToCamelCase(const FieldDescriptor* field);
 string UnderscoresToCamelCase(const FieldDescriptor* field);
+string UnderscoresToCamelCase(const OneofDescriptor* oneof);
 string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field);
 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
 // 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_.
 // 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);
 bool HasMapField(const Descriptor* descriptor);
 
 
+void SetCommonOneofVariables(const FieldDescriptor* field,
+                             map<string, string>* variables);
+
 }  // namespace javanano
 }  // namespace javanano
 }  // namespace compiler
 }  // namespace compiler
 }  // namespace protobuf
 }  // namespace protobuf

+ 14 - 0
src/google/protobuf/compiler/javanano/javanano_message.cc

@@ -165,6 +165,20 @@ void MessageGenerator::Generate(io::Printer* printer) {
     MessageGenerator(descriptor_->nested_type(i), params_).Generate(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
   // Lazy initialization of otherwise static final fields can help prevent the
   // class initializer from being generated. We want to prevent it because it
   // 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
   // stops ProGuard from inlining any methods in this class into call sites and

+ 74 - 2
src/google/protobuf/compiler/javanano/javanano_primitive_field.cc

@@ -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) {
   : FieldGenerator(params), descriptor_(descriptor) {
   SetPrimitiveVariables(descriptor, params, &variables_);
   SetPrimitiveVariables(descriptor, params, &variables_);
 }
 }

+ 25 - 2
src/google/protobuf/compiler/javanano/javanano_primitive_field.h

@@ -47,7 +47,7 @@ namespace javanano {
 class PrimitiveFieldGenerator : public FieldGenerator {
 class PrimitiveFieldGenerator : public FieldGenerator {
  public:
  public:
   explicit PrimitiveFieldGenerator(
   explicit PrimitiveFieldGenerator(
-      const FieldDescriptor* descriptor, const Params &params);
+      const FieldDescriptor* descriptor, const Params& params);
   ~PrimitiveFieldGenerator();
   ~PrimitiveFieldGenerator();
 
 
   // implements FieldGenerator ---------------------------------------
   // implements FieldGenerator ---------------------------------------
@@ -94,9 +94,32 @@ class AccessorPrimitiveFieldGenerator : public FieldGenerator {
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AccessorPrimitiveFieldGenerator);
   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 {
 class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
  public:
  public:
-  explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params);
+  explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+                                           const Params& params);
   ~RepeatedPrimitiveFieldGenerator();
   ~RepeatedPrimitiveFieldGenerator();
 
 
   // implements FieldGenerator ---------------------------------------
   // implements FieldGenerator ---------------------------------------