Sfoglia il codice sorgente

am 44dc2f1e: Merge "Implement enum_style=java option."

* commit '44dc2f1eaead8d95d3f5a4f80f9da87852053bfb':
  Implement enum_style=java option.
Ulas Kirazci 12 anni fa
parent
commit
2775727bd8

+ 13 - 4
java/README.txt

@@ -93,8 +93,9 @@ Micro version
 The runtime and generated code for MICRO_RUNTIME is smaller
 because it does not include support for the descriptor and
 reflection, and enums are generated as integer constants in
-the parent message or the file's outer class. Also, not
-currently supported are packed repeated elements or
+the parent message or the file's outer class, with no
+protection against invalid values set to enum fields. Also,
+not currently supported are packed repeated elements or
 extensions.
 
 To create a jar file for the runtime and run tests invoke
@@ -409,12 +410,20 @@ Nano version
 ============================
 
 Nano is even smaller than micro, especially in the number of generated
-functions. It is like micro except:
+functions. It is like micro:
+
+- No support for descriptors and reflection;
+- Enum constants are integers with no protection against invalid
+  values set to enum fields.
+
+Except:
 
 - Setter/getter/hazzer/clearer functions are opt-in.
 - If not opted in, has state is not available. Serialization outputs
-  all fields not  equal to their default. (See important implications
+  all fields not equal to their default. (See important implications
   below.)
+- Enum constants can be generated into container interfaces bearing
+  the enum's name (so the referencing code is in Java style).
 - CodedInputStreamMicro is renamed to CodedInputByteBufferNano and can
   only take byte[] (not InputStream).
 - Similar rename from CodedOutputStreamMicro to

+ 13 - 0
java/src/test/java/com/google/protobuf/NanoTest.java

@@ -31,8 +31,11 @@
 package com.google.protobuf;
 
 import com.google.protobuf.nano.CodedInputByteBufferNano;
+import com.google.protobuf.nano.EnumClassNanoMultiple;
+import com.google.protobuf.nano.EnumClassNanos;
 import com.google.protobuf.nano.Extensions;
 import com.google.protobuf.nano.Extensions.AnotherMessage;
+import com.google.protobuf.nano.FileScopeEnumMultiple;
 import com.google.protobuf.nano.FileScopeEnumRefNano;
 import com.google.protobuf.nano.InternalNano;
 import com.google.protobuf.nano.MessageNano;
@@ -2391,6 +2394,16 @@ public class NanoTest extends TestCase {
     assertEquals(0, newMsg.id);
   }
 
+  public void testNanoJavaEnumStyle() throws Exception {
+    EnumClassNanos.EnumClassNano msg = new EnumClassNanos.EnumClassNano();
+    assertEquals(EnumClassNanos.FileScopeEnum.ONE, msg.one);
+    assertEquals(EnumClassNanos.EnumClassNano.MessageScopeEnum.TWO, msg.two);
+
+    EnumClassNanoMultiple msg2 = new EnumClassNanoMultiple();
+    assertEquals(FileScopeEnumMultiple.THREE, msg2.three);
+    assertEquals(EnumClassNanoMultiple.MessageScopeEnumMultiple.FOUR, msg2.four);
+  }
+
   /**
    * Tests that fields with a default value of NaN are not serialized when
    * set to NaN. This is a special case as NaN != NaN, so normal equality

+ 28 - 13
src/google/protobuf/compiler/javanano/javanano_enum.cc

@@ -68,25 +68,40 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, const Params& par
 EnumGenerator::~EnumGenerator() {}
 
 void EnumGenerator::Generate(io::Printer* printer) {
-  printer->Print("// enum $classname$\n", "classname", descriptor_->name());
-  for (int i = 0; i < canonical_values_.size(); i++) {
-    map<string, string> vars;
-    vars["name"] = RenameJavaKeywords(canonical_values_[i]->name());
-    vars["canonical_value"] = SimpleItoa(canonical_values_[i]->number());
-    printer->Print(vars,
-      "public static final int $name$ = $canonical_value$;\n");
+  printer->Print(
+      "// enum $classname$\n",
+      "classname", descriptor_->name());
+
+  // Start of container interface
+  bool use_shell_class = params_.java_enum_style();
+  if (use_shell_class) {
+    printer->Print(
+      "public interface $classname$ {\n",
+      "classname", RenameJavaKeywords(descriptor_->name()));
+    printer->Indent();
   }
 
-  // -----------------------------------------------------------------
+  // Canonical values
+  for (int i = 0; i < canonical_values_.size(); i++) {
+    printer->Print(
+      "public static final int $name$ = $canonical_value$;\n",
+      "name", RenameJavaKeywords(canonical_values_[i]->name()),
+      "canonical_value", SimpleItoa(canonical_values_[i]->number()));
+  }
 
+  // Aliases
   for (int i = 0; i < aliases_.size(); i++) {
-    map<string, string> vars;
-    vars["name"] = RenameJavaKeywords(aliases_[i].value->name());
-    vars["canonical_name"] = aliases_[i].canonical_value->name();
-    printer->Print(vars,
-      "public static final int $name$ = $canonical_name$;\n");
+    printer->Print(
+      "public static final int $name$ = $canonical_name$;\n",
+      "name", RenameJavaKeywords(aliases_[i].value->name()),
+      "canonical_name", RenameJavaKeywords(aliases_[i].canonical_value->name()));
   }
 
+  // End of container interface
+  if (use_shell_class) {
+    printer->Outdent();
+    printer->Print("}\n");
+  }
   printer->Print("\n");
 }
 

+ 15 - 0
src/google/protobuf/compiler/javanano/javanano_file.cc

@@ -138,6 +138,13 @@ bool FileGenerator::Validate(string* error) {
       found_conflict = true;
     }
   }
+  if (params_.java_enum_style()) {
+    for (int i = 0; !found_conflict && i < file_->enum_type_count(); i++) {
+      if (file_->enum_type(i)->name() == classname_) {
+        found_conflict = true;
+      }
+    }
+  }
   if (found_conflict) {
     error->assign(file_->name());
     error->append(
@@ -237,6 +244,14 @@ void FileGenerator::GenerateSiblings(const string& package_dir,
                                         file_->message_type(i),
                                         output_directory, file_list, params_);
     }
+
+    if (params_.java_enum_style()) {
+      for (int i = 0; i < file_->enum_type_count(); i++) {
+        GenerateSibling<EnumGenerator>(package_dir, java_package_,
+                                       file_->enum_type(i),
+                                       output_directory, file_list, params_);
+      }
+    }
   }
 }
 

+ 22 - 6
src/google/protobuf/compiler/javanano/javanano_helpers.cc

@@ -197,12 +197,23 @@ string FileJavaPackage(const Params& params, const FileDescriptor* file) {
 }
 
 bool IsOuterClassNeeded(const Params& params, const FileDescriptor* file) {
-  // Enums and extensions need the outer class as the scope.
-  if (file->enum_type_count() != 0 || file->extension_count() != 0) {
+  // If java_multiple_files is false, the outer class is always needed.
+  if (!params.java_multiple_files(file->name())) {
     return true;
   }
-  // Messages need the outer class only if java_multiple_files is false.
-  return !params.java_multiple_files(file->name());
+
+  // File-scope extensions need the outer class as the scope.
+  if (file->extension_count() != 0) {
+    return true;
+  }
+
+  // If container interfaces are not generated, file-scope enums need the
+  // outer class as the scope.
+  if (file->enum_type_count() != 0 && !params.java_enum_style()) {
+    return true;
+  }
+
+  return false;
 }
 
 string ToJavaName(const Params& params, const string& name, bool is_class,
@@ -228,9 +239,14 @@ string ClassName(const Params& params, const FileDescriptor* descriptor) {
 }
 
 string ClassName(const Params& params, const EnumDescriptor* descriptor) {
-  // An enum's class name is the enclosing message's class name or the outer
-  // class name.
   const Descriptor* parent = descriptor->containing_type();
+  // When using Java enum style, an enum's class name contains the enum name.
+  // Use the standard ToJavaName translation.
+  if (params.java_enum_style()) {
+    return ToJavaName(params, descriptor->name(), true, parent,
+                      descriptor->file());
+  }
+  // Otherwise the enum members are accessed from the enclosing class.
   if (parent != NULL) {
     return ClassName(params, parent);
   } else {

+ 48 - 0
src/google/protobuf/unittest_enum_class_multiple_nano.proto

@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: maxtroy@google.com (Max Cai)
+
+package protobuf_unittest;
+
+option java_package = "com.google.protobuf.nano";
+option java_multiple_files = true;
+
+enum FileScopeEnumMultiple {
+  THREE = 3;
+}
+
+message EnumClassNanoMultiple {
+  enum MessageScopeEnumMultiple {
+    FOUR = 4;
+  }
+  optional FileScopeEnumMultiple three = 3 [ default = THREE ];
+  optional MessageScopeEnumMultiple four = 4 [ default = FOUR ];
+}

+ 48 - 0
src/google/protobuf/unittest_enum_class_nano.proto

@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: maxtroy@google.com (Max Cai)
+
+package protobuf_unittest;
+
+option java_package = "com.google.protobuf.nano";
+option java_outer_classname = "EnumClassNanos";
+
+enum FileScopeEnum {
+  ONE = 1;
+}
+
+message EnumClassNano {
+  enum MessageScopeEnum {
+    TWO = 2;
+  }
+  optional FileScopeEnum one = 1 [ default = ONE ];
+  optional MessageScopeEnum two = 2 [ default = TWO ];
+}