diff options
author | Brian Duff <bduff@google.com> | 2013-06-19 13:17:43 -0700 |
---|---|---|
committer | Brian Duff <bduff@google.com> | 2013-06-24 16:02:12 -0700 |
commit | 5659cca8c854f82d11da10a8d4b3547598fc9a43 (patch) | |
tree | 797240173edc1976ce3ef4c40757e022e2905b14 /src/google/protobuf/compiler/javanano/javanano_message.cc | |
parent | 661f87ceb8d729cfdf634fc859b3077eccaa5ed7 (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.cc | 93 |
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" |