aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler/javanano/javanano_message.cc
diff options
context:
space:
mode:
authorGravatar Brian Duff <bduff@google.com>2013-06-19 13:17:43 -0700
committerGravatar Brian Duff <bduff@google.com>2013-06-24 16:02:12 -0700
commit5659cca8c854f82d11da10a8d4b3547598fc9a43 (patch)
tree797240173edc1976ce3ef4c40757e022e2905b14 /src/google/protobuf/compiler/javanano/javanano_message.cc
parent661f87ceb8d729cfdf634fc859b3077eccaa5ed7 (diff)
Nano support for extensions and unknown fields.
You can use the processor option store_unknown_fields to switch this support on: aprotoc --javanano_out=store_unknown_fields=true:/tmp/out A separate option for extensions isn't required. Support for unknown fields must be turned on to allow storing and retrieving extensions, because they are just stored as unknown fields. If unknown fields are switched on, extension related code will be generated when a proto message includes an extension range, or an extension is encountered. By default, store_unknown_fields is false. No additional code is generated, and the generator will error out if protos contain extension ranges or extensions. Change-Id: I1e034c9e8f3305612953f72438189a7da6ed2167
Diffstat (limited to 'src/google/protobuf/compiler/javanano/javanano_message.cc')
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_message.cc93
1 files changed, 74 insertions, 19 deletions
diff --git a/src/google/protobuf/compiler/javanano/javanano_message.cc b/src/google/protobuf/compiler/javanano/javanano_message.cc
index f8a4fe78..27407794 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"