aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWink Saville <wink@google.com>2013-06-25 16:53:07 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2013-06-25 16:53:07 +0000
commit0a1429cc5ee4865550bcdddfae681a30cef58a5a (patch)
treed60a02039cea8773f7ba76efd0c7fd6f23768d70 /src
parent9459b5c45b0ad33bea9376c2afb66cf93da610ac (diff)
parent0e055f079f53b07de3705838a7b4742ce56839f8 (diff)
downloadexternal_protobuf-0a1429cc5ee4865550bcdddfae681a30cef58a5a.zip
external_protobuf-0a1429cc5ee4865550bcdddfae681a30cef58a5a.tar.gz
external_protobuf-0a1429cc5ee4865550bcdddfae681a30cef58a5a.tar.bz2
Merge "Nano support for extensions and unknown fields."
Diffstat (limited to 'src')
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_extension.cc96
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_extension.h74
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_file.cc11
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_generator.cc2
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_message.cc93
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_params.h9
-rw-r--r--src/google/protobuf/unittest_extension_nano.proto44
7 files changed, 308 insertions, 21 deletions
diff --git a/src/google/protobuf/compiler/javanano/javanano_extension.cc b/src/google/protobuf/compiler/javanano/javanano_extension.cc
new file mode 100644
index 0000000..ea74af9
--- /dev/null
+++ b/src/google/protobuf/compiler/javanano/javanano_extension.cc
@@ -0,0 +1,96 @@
+// 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: bduff@google.com (Brian Duff)
+
+#include <google/protobuf/compiler/javanano/javanano_extension.h>
+#include <google/protobuf/compiler/javanano/javanano_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/wire_format.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+using internal::WireFormat;
+
+void SetVariables(const FieldDescriptor* descriptor, const Params params,
+ map<string, string>* variables) {
+ (*variables)["name"] = UnderscoresToCamelCase(descriptor);
+ (*variables)["number"] = SimpleItoa(descriptor->number());
+ (*variables)["extends"] = ClassName(params, descriptor->containing_type());
+
+ string type;
+ JavaType java_type = GetJavaType(descriptor->type());
+ switch (java_type) {
+ case JAVATYPE_ENUM:
+ type = "java.lang.Integer";
+ break;
+ case JAVATYPE_MESSAGE:
+ type = ClassName(params, descriptor->message_type());
+ break;
+ default:
+ type = BoxedPrimitiveTypeName(java_type);
+ break;
+ }
+ (*variables)["type"] = type;
+}
+
+ExtensionGenerator::
+ExtensionGenerator(const FieldDescriptor* descriptor, const Params& params)
+ : params_(params), descriptor_(descriptor) {
+ SetVariables(descriptor, params, &variables_);
+}
+
+ExtensionGenerator::~ExtensionGenerator() {}
+
+void ExtensionGenerator::Generate(io::Printer* printer) const {
+ if (descriptor_->is_repeated()) {
+ printer->Print(variables_,
+ "// Extends $extends$\n"
+ "public static final com.google.protobuf.nano.Extension<java.util.List<$type$>> $name$ = \n"
+ " com.google.protobuf.nano.Extension.createRepeated($number$,\n"
+ " new com.google.protobuf.nano.Extension.TypeLiteral<java.util.List<$type$>>(){});\n");
+ } else {
+ printer->Print(variables_,
+ "// Extends $extends$\n"
+ "public static final com.google.protobuf.nano.Extension<$type$> $name$ =\n"
+ " com.google.protobuf.nano.Extension.create($number$,\n"
+ " new com.google.protobuf.nano.Extension.TypeLiteral<$type$>(){});\n");
+ }
+}
+
+} // namespace javanano
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
diff --git a/src/google/protobuf/compiler/javanano/javanano_extension.h b/src/google/protobuf/compiler/javanano/javanano_extension.h
new file mode 100644
index 0000000..c6543eb
--- /dev/null
+++ b/src/google/protobuf/compiler/javanano/javanano_extension.h
@@ -0,0 +1,74 @@
+// 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: bduff@google.com (Brian Duff)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H_
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H_
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/javanano/javanano_params.h>
+#include <google/protobuf/descriptor.pb.h>
+
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+class ExtensionGenerator {
+ public:
+ explicit ExtensionGenerator(const FieldDescriptor* descriptor, const Params& params);
+ ~ExtensionGenerator();
+
+ void Generate(io::Printer* printer) const;
+
+ private:
+ const Params& params_;
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
+};
+
+} // namespace javanano
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H_
diff --git a/src/google/protobuf/compiler/javanano/javanano_file.cc b/src/google/protobuf/compiler/javanano/javanano_file.cc
index 2f42fa0..6efa2bf 100644
--- a/src/google/protobuf/compiler/javanano/javanano_file.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_file.cc
@@ -34,6 +34,7 @@
#include <google/protobuf/compiler/javanano/javanano_file.h>
#include <google/protobuf/compiler/javanano/javanano_enum.h>
+#include <google/protobuf/compiler/javanano/javanano_extension.h>
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
#include <google/protobuf/compiler/javanano/javanano_message.h>
#include <google/protobuf/compiler/code_generator.h>
@@ -94,10 +95,11 @@ bool FileGenerator::Validate(string* error) {
// Check for extensions
FileDescriptorProto file_proto;
file_->CopyTo(&file_proto);
- if (UsesExtensions(file_proto)) {
+ if (UsesExtensions(file_proto) && !params_.store_unknown_fields()) {
error->assign(file_->name());
error->append(
- ": Java NANO_RUNTIME does not support extensions\"");
+ ": Java NANO_RUNTIME only supports extensions when the "
+ "'store_unknown_fields' generator option is 'true'.");
return false;
}
@@ -179,6 +181,11 @@ void FileGenerator::Generate(io::Printer* printer) {
// -----------------------------------------------------------------
+ // Extensions.
+ for (int i = 0; i < file_->extension_count(); i++) {
+ ExtensionGenerator(file_->extension(i), params_).Generate(printer);
+ }
+
if (!params_.java_multiple_files()) {
for (int i = 0; i < file_->enum_type_count(); i++) {
EnumGenerator(file_->enum_type(i), params_).Generate(printer);
diff --git a/src/google/protobuf/compiler/javanano/javanano_generator.cc b/src/google/protobuf/compiler/javanano/javanano_generator.cc
index 554f6d4..19a3dcc 100644
--- a/src/google/protobuf/compiler/javanano/javanano_generator.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_generator.cc
@@ -115,6 +115,8 @@ bool JavaNanoGenerator::Generate(const FileDescriptor* file,
return false;
}
params.set_java_outer_classname(parts[0], parts[1]);
+ } else if (options[i].first == "store_unknown_fields") {
+ params.set_store_unknown_fields(options[i].second == "true");
} else if (options[i].first == "java_multiple_files") {
params.set_java_multiple_files(options[i].second == "true");
} else {
diff --git a/src/google/protobuf/compiler/javanano/javanano_message.cc b/src/google/protobuf/compiler/javanano/javanano_message.cc
index f8a4fe7..2740779 100644
--- a/src/google/protobuf/compiler/javanano/javanano_message.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_message.cc
@@ -36,6 +36,7 @@
#include <google/protobuf/stubs/hash.h>
#include <google/protobuf/compiler/javanano/javanano_message.h>
#include <google/protobuf/compiler/javanano/javanano_enum.h>
+#include <google/protobuf/compiler/javanano/javanano_extension.h>
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/io/printer.h>
@@ -117,10 +118,6 @@ void MessageGenerator::GenerateStaticVariableInitializers(
MessageGenerator(descriptor_->nested_type(i), params_)
.GenerateStaticVariableInitializers(printer);
}
-
- if (descriptor_->extension_count() != 0) {
- GOOGLE_LOG(FATAL) << "Extensions not supported in NANO_RUNTIME\n";
- }
}
void MessageGenerator::Generate(io::Printer* printer) {
@@ -135,9 +132,10 @@ void MessageGenerator::Generate(io::Printer* printer) {
GOOGLE_LOG(INFO) << "has_java_outer_classname()=" << params_.has_java_outer_classname(file_->name());
#endif
- if ((descriptor_->extension_count() != 0)
- || (descriptor_->extension_range_count() != 0)) {
- GOOGLE_LOG(FATAL) << "Extensions not supported in NANO_RUNTIME\n";
+ if (!params_.store_unknown_fields() &&
+ (descriptor_->extension_count() != 0 || descriptor_->extension_range_count() != 0)) {
+ GOOGLE_LOG(FATAL) << "Extensions are only supported in NANO_RUNTIME if the "
+ "'store_unknown_fields' generator option is 'true'\n";
}
// Note: Fields (which will be emitted in the loop, below) may have the same names as fields in
@@ -156,7 +154,17 @@ void MessageGenerator::Generate(io::Printer* printer) {
"\n",
"classname", descriptor_->name());
+ if (params_.store_unknown_fields()) {
+ printer->Print(
+ "private java.util.List<com.google.protobuf.nano.UnknownFieldData>\n"
+ " unknownFieldData;\n");
+ }
+
// Nested types and extensions
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ ExtensionGenerator(descriptor_->extension(i), params_).Generate(printer);
+ }
+
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
EnumGenerator(descriptor_->enum_type(i), params_).Generate(printer);
}
@@ -173,6 +181,24 @@ void MessageGenerator::Generate(io::Printer* printer) {
}
GenerateClear(printer);
+
+ // If we have an extension range, generate accessors for extensions.
+ if (params_.store_unknown_fields()
+ && descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "public <T> T getExtension(com.google.protobuf.nano.Extension<T> extension) {\n"
+ " return com.google.protobuf.nano.WireFormatNano.getExtension(\n"
+ " extension, unknownFieldData);\n"
+ "}\n\n"
+ "public <T> void setExtension(com.google.protobuf.nano.Extension<T> extension, T value) {\n"
+ " if (unknownFieldData == null) {\n"
+ " unknownFieldData = \n"
+ " new java.util.ArrayList<com.google.protobuf.nano.UnknownFieldData>();\n"
+ " }\n"
+ " com.google.protobuf.nano.WireFormatNano.setExtension(\n"
+ " extension, value, unknownFieldData);\n"
+ "}\n\n");
+ }
GenerateMessageSerializationMethods(printer);
GenerateMergeFromMethods(printer);
GenerateParseFromMethods(printer);
@@ -188,12 +214,8 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
scoped_array<const FieldDescriptor*> sorted_fields(
SortFieldsByNumber(descriptor_));
- if (descriptor_->extension_range_count() != 0) {
- GOOGLE_LOG(FATAL) << "Extensions not supported in NANO_RUNTIME\n";
- }
-
// writeTo only throws an exception if it contains one or more fields to write
- if (descriptor_->field_count() > 0) {
+ if (descriptor_->field_count() > 0 || params_.store_unknown_fields()) {
printer->Print(
"@Override\n"
"public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output)\n"
@@ -207,7 +229,14 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
// Output the fields in sorted order
for (int i = 0; i < descriptor_->field_count(); i++) {
- GenerateSerializeOneField(printer, sorted_fields[i]);
+ GenerateSerializeOneField(printer, sorted_fields[i]);
+ }
+
+ // Write unknown fields.
+ if (params_.store_unknown_fields()) {
+ printer->Print(
+ "com.google.protobuf.nano.WireFormatNano.writeUnknownFields(\n"
+ " unknownFieldData, output);\n");
}
printer->Outdent();
@@ -233,6 +262,11 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
}
+ if (params_.store_unknown_fields()) {
+ printer->Print(
+ "size += com.google.protobuf.nano.WireFormatNano.computeWireSize(unknownFieldData);\n");
+ }
+
printer->Outdent();
printer->Print(
" cachedSize = size;\n"
@@ -266,12 +300,28 @@ void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) {
printer->Print(
"case 0:\n" // zero signals EOF / limit reached
" return this;\n"
- "default: {\n"
- " if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) {\n"
- " return this;\n" // it's an endgroup tag
- " }\n"
- " break;\n"
- "}\n");
+ "default: {\n");
+
+ printer->Indent();
+ if (params_.store_unknown_fields()) {
+ printer->Print(
+ "if (unknownFieldData == null) {\n"
+ " unknownFieldData = \n"
+ " new java.util.ArrayList<com.google.protobuf.nano.UnknownFieldData>();\n"
+ "}\n"
+ "if (!com.google.protobuf.nano.WireFormatNano.storeUnknownField(unknownFieldData, \n"
+ " input, tag)) {\n"
+ " return this;\n"
+ "}\n");
+ } else {
+ printer->Print(
+ "if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) {\n"
+ " return this;\n" // it's an endgroup tag
+ "}\n");
+ }
+ printer->Print("break;\n");
+ printer->Outdent();
+ printer->Print("}\n");
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = sorted_fields[i];
@@ -356,6 +406,11 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
}
}
+ // Clear unknown fields.
+ if (params_.store_unknown_fields()) {
+ printer->Print("unknownFieldData = null;\n");
+ }
+
printer->Outdent();
printer->Print(
" cachedSize = -1;\n"
diff --git a/src/google/protobuf/compiler/javanano/javanano_params.h b/src/google/protobuf/compiler/javanano/javanano_params.h
index f6192ea..30eedff 100644
--- a/src/google/protobuf/compiler/javanano/javanano_params.h
+++ b/src/google/protobuf/compiler/javanano/javanano_params.h
@@ -49,6 +49,7 @@ class Params {
string empty_;
string base_name_;
bool java_multiple_files_;
+ bool store_unknown_fields_;
NameMap java_packages_;
NameMap java_outer_classnames_;
@@ -56,6 +57,7 @@ class Params {
Params(const string & base_name) :
empty_(""),
base_name_(base_name),
+ store_unknown_fields_(false),
java_multiple_files_(false) {
}
@@ -107,6 +109,13 @@ class Params {
return java_outer_classnames_;
}
+ void set_store_unknown_fields(bool value) {
+ store_unknown_fields_ = value;
+ }
+ bool store_unknown_fields() const {
+ return store_unknown_fields_;
+ }
+
void set_java_multiple_files(bool value) {
java_multiple_files_ = value;
}
diff --git a/src/google/protobuf/unittest_extension_nano.proto b/src/google/protobuf/unittest_extension_nano.proto
new file mode 100644
index 0000000..f2906f0
--- /dev/null
+++ b/src/google/protobuf/unittest_extension_nano.proto
@@ -0,0 +1,44 @@
+syntax = "proto2";
+
+option java_outer_classname = "Extensions";
+option java_package = "com.google.protobuf.nano";
+
+message ExtendableMessage {
+ optional int32 field = 1;
+ extensions 10 to max;
+}
+
+enum AnEnum {
+ FIRST_VALUE = 1;
+ SECOND_VALUE = 2;
+}
+
+message AnotherMessage {
+ optional string string = 1;
+ optional bool value = 2;
+}
+
+extend ExtendableMessage {
+ optional string some_string = 10;
+ optional int32 some_int = 11;
+ optional int64 some_long = 12;
+ optional float some_float = 13;
+ optional double some_double = 14;
+ optional bool some_bool = 15;
+ optional AnEnum some_enum = 16;
+ optional AnotherMessage some_message = 17;
+ repeated string some_repeated_string = 18;
+ repeated int32 some_repeated_int = 19;
+ repeated int64 some_repeated_long = 20;
+ repeated float some_repeated_float = 21;
+ repeated double some_repeated_double = 22;
+ repeated bool some_repeated_bool = 23;
+ repeated AnEnum some_repeated_enum = 24;
+ repeated AnotherMessage some_repeated_message = 25;
+}
+
+message ContainerMessage {
+ extend ExtendableMessage {
+ optional bool another_thing = 100;
+ }
+}