| Index: third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc
|
| ===================================================================
|
| --- third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc (revision 216642)
|
| +++ third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc (working copy)
|
| @@ -32,17 +32,23 @@
|
| // Based on original Protocol Buffers design by
|
| // Sanjay Ghemawat, Jeff Dean, and others.
|
|
|
| +#include <google/protobuf/compiler/java/java_message.h>
|
| +
|
| #include <algorithm>
|
| #include <google/protobuf/stubs/hash.h>
|
| -#include <google/protobuf/compiler/java/java_message.h>
|
| +#include <map>
|
| +#include <vector>
|
| +
|
| +#include <google/protobuf/compiler/java/java_doc_comment.h>
|
| #include <google/protobuf/compiler/java/java_enum.h>
|
| #include <google/protobuf/compiler/java/java_extension.h>
|
| #include <google/protobuf/compiler/java/java_helpers.h>
|
| -#include <google/protobuf/stubs/strutil.h>
|
| +#include <google/protobuf/io/coded_stream.h>
|
| #include <google/protobuf/io/printer.h>
|
| -#include <google/protobuf/io/coded_stream.h>
|
| +#include <google/protobuf/descriptor.pb.h>
|
| #include <google/protobuf/wire_format.h>
|
| -#include <google/protobuf/descriptor.pb.h>
|
| +#include <google/protobuf/stubs/strutil.h>
|
| +#include <google/protobuf/stubs/substitute.h>
|
|
|
| namespace google {
|
| namespace protobuf {
|
| @@ -233,10 +239,8 @@
|
| "field_name",
|
| UnderscoresToCapitalizedCamelCase(descriptor_->field(i)));
|
| }
|
| - printer->Print("},\n"
|
| - " $classname$.class,\n"
|
| - " $classname$.Builder.class);\n",
|
| - "classname", ClassName(descriptor_));
|
| + printer->Print(
|
| + "});\n");
|
| }
|
|
|
| // Generate static member initializers for all nested types.
|
| @@ -250,7 +254,6 @@
|
| // ===================================================================
|
|
|
| void MessageGenerator::GenerateInterface(io::Printer* printer) {
|
| -
|
| if (descriptor_->extension_range_count() > 0) {
|
| if (HasDescriptorMethods(descriptor_)) {
|
| printer->Print(
|
| @@ -298,6 +301,10 @@
|
| descriptor_->containing_type() == NULL &&
|
| descriptor_->file()->options().java_multiple_files();
|
|
|
| + WriteMessageDocComment(printer, descriptor_);
|
| +
|
| + // The builder_type stores the super type name of the nested Builder class.
|
| + string builder_type;
|
| if (descriptor_->extension_range_count() > 0) {
|
| if (HasDescriptorMethods(descriptor_)) {
|
| printer->Print(
|
| @@ -306,6 +313,9 @@
|
| " $classname$> implements $classname$OrBuilder {\n",
|
| "static", is_own_file ? "" : "static",
|
| "classname", descriptor_->name());
|
| + builder_type = strings::Substitute(
|
| + "com.google.protobuf.GeneratedMessage.ExtendableBuilder<$0, ?>",
|
| + ClassName(descriptor_));
|
| } else {
|
| printer->Print(
|
| "public $static$ final class $classname$ extends\n"
|
| @@ -313,6 +323,9 @@
|
| " $classname$> implements $classname$OrBuilder {\n",
|
| "static", is_own_file ? "" : "static",
|
| "classname", descriptor_->name());
|
| + builder_type = strings::Substitute(
|
| + "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>",
|
| + ClassName(descriptor_));
|
| }
|
| } else {
|
| if (HasDescriptorMethods(descriptor_)) {
|
| @@ -322,6 +335,7 @@
|
| " implements $classname$OrBuilder {\n",
|
| "static", is_own_file ? "" : "static",
|
| "classname", descriptor_->name());
|
| + builder_type = "com.google.protobuf.GeneratedMessage.Builder<?>";
|
| } else {
|
| printer->Print(
|
| "public $static$ final class $classname$ extends\n"
|
| @@ -329,17 +343,28 @@
|
| " implements $classname$OrBuilder {\n",
|
| "static", is_own_file ? "" : "static",
|
| "classname", descriptor_->name());
|
| + builder_type = "com.google.protobuf.GeneratedMessageLite.Builder";
|
| }
|
| }
|
| printer->Indent();
|
| + // Using builder_type, instead of Builder, prevents the Builder class from
|
| + // being loaded into PermGen space when the default instance is created.
|
| + // This optimizes the PermGen space usage for clients that do not modify
|
| + // messages.
|
| printer->Print(
|
| "// Use $classname$.newBuilder() to construct.\n"
|
| - "private $classname$(Builder builder) {\n"
|
| + "private $classname$($buildertype$ builder) {\n"
|
| " super(builder);\n"
|
| - "}\n"
|
| + "$set_unknown_fields$\n"
|
| + "}\n",
|
| + "classname", descriptor_->name(),
|
| + "buildertype", builder_type,
|
| + "set_unknown_fields", HasUnknownFields(descriptor_)
|
| + ? " this.unknownFields = builder.getUnknownFields();" : "");
|
| + printer->Print(
|
| // Used when constructing the default instance, which cannot be initialized
|
| // immediately because it may cyclically refer to other default instances.
|
| - "private $classname$(boolean noInit) {}\n"
|
| + "private $classname$(boolean noInit) {$set_default_unknown_fields$}\n"
|
| "\n"
|
| "private static final $classname$ defaultInstance;\n"
|
| "public static $classname$ getDefaultInstance() {\n"
|
| @@ -350,9 +375,28 @@
|
| " return defaultInstance;\n"
|
| "}\n"
|
| "\n",
|
| - "classname", descriptor_->name());
|
| + "classname", descriptor_->name(),
|
| + "set_default_unknown_fields", HasUnknownFields(descriptor_)
|
| + ? " this.unknownFields ="
|
| + " com.google.protobuf.UnknownFieldSet.getDefaultInstance(); " : "");
|
|
|
| + if (HasUnknownFields(descriptor_)) {
|
| + printer->Print(
|
| + "private final com.google.protobuf.UnknownFieldSet unknownFields;\n"
|
| + ""
|
| + "@java.lang.Override\n"
|
| + "public final com.google.protobuf.UnknownFieldSet\n"
|
| + " getUnknownFields() {\n"
|
| + " return this.unknownFields;\n"
|
| + "}\n");
|
| + }
|
| +
|
| + if (HasGeneratedMethods(descriptor_)) {
|
| + GenerateParsingConstructor(printer);
|
| + }
|
| +
|
| GenerateDescriptorMethods(printer);
|
| + GenerateParser(printer);
|
|
|
| // Nested types
|
| for (int i = 0; i < descriptor_->enum_type_count(); i++) {
|
| @@ -567,68 +611,54 @@
|
| "public static $classname$ parseFrom(\n"
|
| " com.google.protobuf.ByteString data)\n"
|
| " throws com.google.protobuf.InvalidProtocolBufferException {\n"
|
| - " return newBuilder().mergeFrom(data).buildParsed();\n"
|
| + " return PARSER.parseFrom(data);\n"
|
| "}\n"
|
| "public static $classname$ parseFrom(\n"
|
| " com.google.protobuf.ByteString data,\n"
|
| " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
|
| " throws com.google.protobuf.InvalidProtocolBufferException {\n"
|
| - " return newBuilder().mergeFrom(data, extensionRegistry)\n"
|
| - " .buildParsed();\n"
|
| + " return PARSER.parseFrom(data, extensionRegistry);\n"
|
| "}\n"
|
| "public static $classname$ parseFrom(byte[] data)\n"
|
| " throws com.google.protobuf.InvalidProtocolBufferException {\n"
|
| - " return newBuilder().mergeFrom(data).buildParsed();\n"
|
| + " return PARSER.parseFrom(data);\n"
|
| "}\n"
|
| "public static $classname$ parseFrom(\n"
|
| " byte[] data,\n"
|
| " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
|
| " throws com.google.protobuf.InvalidProtocolBufferException {\n"
|
| - " return newBuilder().mergeFrom(data, extensionRegistry)\n"
|
| - " .buildParsed();\n"
|
| + " return PARSER.parseFrom(data, extensionRegistry);\n"
|
| "}\n"
|
| "public static $classname$ parseFrom(java.io.InputStream input)\n"
|
| " throws java.io.IOException {\n"
|
| - " return newBuilder().mergeFrom(input).buildParsed();\n"
|
| + " return PARSER.parseFrom(input);\n"
|
| "}\n"
|
| "public static $classname$ parseFrom(\n"
|
| " java.io.InputStream input,\n"
|
| " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
|
| " throws java.io.IOException {\n"
|
| - " return newBuilder().mergeFrom(input, extensionRegistry)\n"
|
| - " .buildParsed();\n"
|
| + " return PARSER.parseFrom(input, extensionRegistry);\n"
|
| "}\n"
|
| "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
|
| " throws java.io.IOException {\n"
|
| - " Builder builder = newBuilder();\n"
|
| - " if (builder.mergeDelimitedFrom(input)) {\n"
|
| - " return builder.buildParsed();\n"
|
| - " } else {\n"
|
| - " return null;\n"
|
| - " }\n"
|
| + " return PARSER.parseDelimitedFrom(input);\n"
|
| "}\n"
|
| "public static $classname$ parseDelimitedFrom(\n"
|
| " java.io.InputStream input,\n"
|
| " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
|
| " throws java.io.IOException {\n"
|
| - " Builder builder = newBuilder();\n"
|
| - " if (builder.mergeDelimitedFrom(input, extensionRegistry)) {\n"
|
| - " return builder.buildParsed();\n"
|
| - " } else {\n"
|
| - " return null;\n"
|
| - " }\n"
|
| + " return PARSER.parseDelimitedFrom(input, extensionRegistry);\n"
|
| "}\n"
|
| "public static $classname$ parseFrom(\n"
|
| " com.google.protobuf.CodedInputStream input)\n"
|
| " throws java.io.IOException {\n"
|
| - " return newBuilder().mergeFrom(input).buildParsed();\n"
|
| + " return PARSER.parseFrom(input);\n"
|
| "}\n"
|
| "public static $classname$ parseFrom(\n"
|
| " com.google.protobuf.CodedInputStream input,\n"
|
| " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
|
| " throws java.io.IOException {\n"
|
| - " return newBuilder().mergeFrom(input, extensionRegistry)\n"
|
| - " .buildParsed();\n"
|
| + " return PARSER.parseFrom(input, extensionRegistry);\n"
|
| "}\n"
|
| "\n",
|
| "classname", ClassName(descriptor_));
|
| @@ -669,6 +699,8 @@
|
| "}\n");
|
| }
|
|
|
| + WriteMessageDocComment(printer, descriptor_);
|
| +
|
| if (descriptor_->extension_range_count() > 0) {
|
| if (HasDescriptorMethods(descriptor_)) {
|
| printer->Print(
|
| @@ -739,17 +771,25 @@
|
|
|
| void MessageGenerator::GenerateDescriptorMethods(io::Printer* printer) {
|
| if (HasDescriptorMethods(descriptor_)) {
|
| + if (!descriptor_->options().no_standard_descriptor_accessor()) {
|
| + printer->Print(
|
| + "public static final com.google.protobuf.Descriptors.Descriptor\n"
|
| + " getDescriptor() {\n"
|
| + " return $fileclass$.internal_$identifier$_descriptor;\n"
|
| + "}\n"
|
| + "\n",
|
| + "fileclass", ClassName(descriptor_->file()),
|
| + "identifier", UniqueFileScopeIdentifier(descriptor_));
|
| + }
|
| printer->Print(
|
| - "public static final com.google.protobuf.Descriptors.Descriptor\n"
|
| - " getDescriptor() {\n"
|
| - " return $fileclass$.internal_$identifier$_descriptor;\n"
|
| - "}\n"
|
| - "\n"
|
| "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
|
| " internalGetFieldAccessorTable() {\n"
|
| - " return $fileclass$.internal_$identifier$_fieldAccessorTable;\n"
|
| + " return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
|
| + " .ensureFieldAccessorsInitialized(\n"
|
| + " $classname$.class, $classname$.Builder.class);\n"
|
| "}\n"
|
| "\n",
|
| + "classname", ClassName(descriptor_),
|
| "fileclass", ClassName(descriptor_->file()),
|
| "identifier", UniqueFileScopeIdentifier(descriptor_));
|
| }
|
| @@ -768,7 +808,8 @@
|
|
|
| if (HasDescriptorMethods(descriptor_)) {
|
| printer->Print(
|
| - "private Builder(BuilderParent parent) {\n"
|
| + "private Builder(\n"
|
| + " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
|
| " super(parent);\n"
|
| " maybeForceBuilderInitialization();\n"
|
| "}\n",
|
| @@ -830,10 +871,11 @@
|
| printer->Print(
|
| "public com.google.protobuf.Descriptors.Descriptor\n"
|
| " getDescriptorForType() {\n"
|
| - " return $classname$.getDescriptor();\n"
|
| + " return $fileclass$.internal_$identifier$_descriptor;\n"
|
| "}\n"
|
| "\n",
|
| - "classname", ClassName(descriptor_));
|
| + "fileclass", ClassName(descriptor_->file()),
|
| + "identifier", UniqueFileScopeIdentifier(descriptor_));
|
| }
|
| printer->Print(
|
| "public $classname$ getDefaultInstanceForType() {\n"
|
| @@ -853,16 +895,6 @@
|
| " return result;\n"
|
| "}\n"
|
| "\n"
|
| - "private $classname$ buildParsed()\n"
|
| - " throws com.google.protobuf.InvalidProtocolBufferException {\n"
|
| - " $classname$ result = buildPartial();\n"
|
| - " if (!result.isInitialized()) {\n"
|
| - " throw newUninitializedMessageException(\n"
|
| - " result).asInvalidProtocolBufferException();\n"
|
| - " }\n"
|
| - " return result;\n"
|
| - "}\n"
|
| - "\n"
|
| "public $classname$ buildPartial() {\n"
|
| " $classname$ result = new $classname$(this);\n",
|
| "classname", ClassName(descriptor_));
|
| @@ -969,108 +1001,25 @@
|
| // ===================================================================
|
|
|
| void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
|
| - scoped_array<const FieldDescriptor*> sorted_fields(
|
| - SortFieldsByNumber(descriptor_));
|
| -
|
| printer->Print(
|
| "public Builder mergeFrom(\n"
|
| " com.google.protobuf.CodedInputStream input,\n"
|
| " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
|
| - " throws java.io.IOException {\n");
|
| - printer->Indent();
|
| -
|
| - if (HasUnknownFields(descriptor_)) {
|
| - printer->Print(
|
| - "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
|
| - " com.google.protobuf.UnknownFieldSet.newBuilder(\n"
|
| - " this.getUnknownFields());\n");
|
| - }
|
| -
|
| - printer->Print(
|
| - "while (true) {\n");
|
| - printer->Indent();
|
| -
|
| - printer->Print(
|
| - "int tag = input.readTag();\n"
|
| - "switch (tag) {\n");
|
| - printer->Indent();
|
| -
|
| - if (HasUnknownFields(descriptor_)) {
|
| - printer->Print(
|
| - "case 0:\n" // zero signals EOF / limit reached
|
| - " this.setUnknownFields(unknownFields.build());\n"
|
| - " $on_changed$\n"
|
| - " return this;\n"
|
| - "default: {\n"
|
| - " if (!parseUnknownField(input, unknownFields,\n"
|
| - " extensionRegistry, tag)) {\n"
|
| - " this.setUnknownFields(unknownFields.build());\n"
|
| - " $on_changed$\n"
|
| - " return this;\n" // it's an endgroup tag
|
| - " }\n"
|
| - " break;\n"
|
| - "}\n",
|
| - "on_changed", HasDescriptorMethods(descriptor_) ? "onChanged();" : "");
|
| - } else {
|
| - printer->Print(
|
| - "case 0:\n" // zero signals EOF / limit reached
|
| - " $on_changed$\n"
|
| - " return this;\n"
|
| - "default: {\n"
|
| - " if (!parseUnknownField(input, extensionRegistry, tag)) {\n"
|
| - " $on_changed$\n"
|
| - " return this;\n" // it's an endgroup tag
|
| - " }\n"
|
| - " break;\n"
|
| - "}\n",
|
| - "on_changed", HasDescriptorMethods(descriptor_) ? "onChanged();" : "");
|
| - }
|
| -
|
| - for (int i = 0; i < descriptor_->field_count(); i++) {
|
| - const FieldDescriptor* field = sorted_fields[i];
|
| - uint32 tag = WireFormatLite::MakeTag(field->number(),
|
| - WireFormat::WireTypeForFieldType(field->type()));
|
| -
|
| - printer->Print(
|
| - "case $tag$: {\n",
|
| - "tag", SimpleItoa(tag));
|
| - printer->Indent();
|
| -
|
| - field_generators_.get(field).GenerateParsingCode(printer);
|
| -
|
| - printer->Outdent();
|
| - printer->Print(
|
| - " break;\n"
|
| - "}\n");
|
| -
|
| - if (field->is_packable()) {
|
| - // To make packed = true wire compatible, we generate parsing code from a
|
| - // packed version of this field regardless of field->options().packed().
|
| - uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
|
| - WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
|
| - printer->Print(
|
| - "case $tag$: {\n",
|
| - "tag", SimpleItoa(packed_tag));
|
| - printer->Indent();
|
| -
|
| - field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
|
| -
|
| - printer->Outdent();
|
| - printer->Print(
|
| - " break;\n"
|
| - "}\n");
|
| - }
|
| - }
|
| -
|
| - printer->Outdent();
|
| - printer->Outdent();
|
| - printer->Outdent();
|
| - printer->Print(
|
| - " }\n" // switch (tag)
|
| - " }\n" // while (true)
|
| - "}\n"
|
| -
|
| - "\n");
|
| + " throws java.io.IOException {\n"
|
| + " $classname$ parsedMessage = null;\n"
|
| + " try {\n"
|
| + " parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);\n"
|
| + " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
|
| + " parsedMessage = ($classname$) e.getUnfinishedMessage();\n"
|
| + " throw e;\n"
|
| + " } finally {\n"
|
| + " if (parsedMessage != null) {\n"
|
| + " mergeFrom(parsedMessage);\n"
|
| + " }\n"
|
| + " }\n"
|
| + " return this;\n"
|
| + "}\n",
|
| + "classname", ClassName(descriptor_));
|
| }
|
|
|
| // ===================================================================
|
| @@ -1232,10 +1181,19 @@
|
| "\n");
|
|
|
| printer->Print(
|
| + "private int memoizedHashCode = 0;\n");
|
| + printer->Print(
|
| "@java.lang.Override\n"
|
| "public int hashCode() {\n");
|
| printer->Indent();
|
| printer->Print(
|
| + "if (memoizedHashCode != 0) {\n");
|
| + printer->Indent();
|
| + printer->Print(
|
| + "return memoizedHashCode;\n");
|
| + printer->Outdent();
|
| + printer->Print(
|
| + "}\n"
|
| "int hash = 41;\n"
|
| "hash = (19 * hash) + getDescriptorForType().hashCode();\n");
|
| for (int i = 0; i < descriptor_->field_count(); i++) {
|
| @@ -1260,6 +1218,7 @@
|
| }
|
| printer->Print(
|
| "hash = (29 * hash) + getUnknownFields().hashCode();\n"
|
| + "memoizedHashCode = hash;\n"
|
| "return hash;\n");
|
| printer->Outdent();
|
| printer->Print(
|
| @@ -1281,6 +1240,195 @@
|
| }
|
| }
|
|
|
| +// ===================================================================
|
| +void MessageGenerator::GenerateParsingConstructor(io::Printer* printer) {
|
| + scoped_array<const FieldDescriptor*> sorted_fields(
|
| + SortFieldsByNumber(descriptor_));
|
| +
|
| + printer->Print(
|
| + "private $classname$(\n"
|
| + " com.google.protobuf.CodedInputStream input,\n"
|
| + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
|
| + " throws com.google.protobuf.InvalidProtocolBufferException {\n",
|
| + "classname", descriptor_->name());
|
| + printer->Indent();
|
| +
|
| + // Initialize all fields to default.
|
| + printer->Print(
|
| + "initFields();\n");
|
| +
|
| + // Use builder bits to track mutable repeated fields.
|
| + int totalBuilderBits = 0;
|
| + for (int i = 0; i < descriptor_->field_count(); i++) {
|
| + const FieldGenerator& field = field_generators_.get(descriptor_->field(i));
|
| + totalBuilderBits += field.GetNumBitsForBuilder();
|
| + }
|
| + int totalBuilderInts = (totalBuilderBits + 31) / 32;
|
| + for (int i = 0; i < totalBuilderInts; i++) {
|
| + printer->Print("int mutable_$bit_field_name$ = 0;\n",
|
| + "bit_field_name", GetBitFieldName(i));
|
| + }
|
| +
|
| + if (HasUnknownFields(descriptor_)) {
|
| + printer->Print(
|
| + "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
|
| + " com.google.protobuf.UnknownFieldSet.newBuilder();\n");
|
| + }
|
| +
|
| + printer->Print(
|
| + "try {\n");
|
| + printer->Indent();
|
| +
|
| + printer->Print(
|
| + "boolean done = false;\n"
|
| + "while (!done) {\n");
|
| + printer->Indent();
|
| +
|
| + printer->Print(
|
| + "int tag = input.readTag();\n"
|
| + "switch (tag) {\n");
|
| + printer->Indent();
|
| +
|
| + printer->Print(
|
| + "case 0:\n" // zero signals EOF / limit reached
|
| + " done = true;\n"
|
| + " break;\n"
|
| + "default: {\n"
|
| + " if (!parseUnknownField(input,$unknown_fields$\n"
|
| + " extensionRegistry, tag)) {\n"
|
| + " done = true;\n" // it's an endgroup tag
|
| + " }\n"
|
| + " break;\n"
|
| + "}\n",
|
| + "unknown_fields", HasUnknownFields(descriptor_)
|
| + ? " unknownFields," : "");
|
| +
|
| + for (int i = 0; i < descriptor_->field_count(); i++) {
|
| + const FieldDescriptor* field = sorted_fields[i];
|
| + uint32 tag = WireFormatLite::MakeTag(field->number(),
|
| + WireFormat::WireTypeForFieldType(field->type()));
|
| +
|
| + printer->Print(
|
| + "case $tag$: {\n",
|
| + "tag", SimpleItoa(tag));
|
| + printer->Indent();
|
| +
|
| + field_generators_.get(field).GenerateParsingCode(printer);
|
| +
|
| + printer->Outdent();
|
| + printer->Print(
|
| + " break;\n"
|
| + "}\n");
|
| +
|
| + if (field->is_packable()) {
|
| + // To make packed = true wire compatible, we generate parsing code from a
|
| + // packed version of this field regardless of field->options().packed().
|
| + uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
|
| + WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
|
| + printer->Print(
|
| + "case $tag$: {\n",
|
| + "tag", SimpleItoa(packed_tag));
|
| + printer->Indent();
|
| +
|
| + field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
|
| +
|
| + printer->Outdent();
|
| + printer->Print(
|
| + " break;\n"
|
| + "}\n");
|
| + }
|
| + }
|
| +
|
| + printer->Outdent();
|
| + printer->Outdent();
|
| + printer->Print(
|
| + " }\n" // switch (tag)
|
| + "}\n"); // while (!done)
|
| +
|
| + printer->Outdent();
|
| + printer->Print(
|
| + "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
|
| + " throw e.setUnfinishedMessage(this);\n"
|
| + "} catch (java.io.IOException e) {\n"
|
| + " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
|
| + " e.getMessage()).setUnfinishedMessage(this);\n"
|
| + "} finally {\n");
|
| + printer->Indent();
|
| +
|
| + // Make repeated field list immutable.
|
| + for (int i = 0; i < descriptor_->field_count(); i++) {
|
| + const FieldDescriptor* field = sorted_fields[i];
|
| + field_generators_.get(field).GenerateParsingDoneCode(printer);
|
| + }
|
| +
|
| + // Make unknown fields immutable.
|
| + if (HasUnknownFields(descriptor_)) {
|
| + printer->Print(
|
| + "this.unknownFields = unknownFields.build();\n");
|
| + }
|
| +
|
| + // Make extensions immutable.
|
| + printer->Print(
|
| + "makeExtensionsImmutable();\n");
|
| +
|
| + printer->Outdent();
|
| + printer->Outdent();
|
| + printer->Print(
|
| + " }\n" // finally
|
| + "}\n");
|
| +}
|
| +
|
| +// ===================================================================
|
| +void MessageGenerator::GenerateParser(io::Printer* printer) {
|
| + printer->Print(
|
| + "public static com.google.protobuf.Parser<$classname$> PARSER =\n"
|
| + " new com.google.protobuf.AbstractParser<$classname$>() {\n",
|
| + "classname", descriptor_->name());
|
| + printer->Indent();
|
| + printer->Print(
|
| + "public $classname$ parsePartialFrom(\n"
|
| + " com.google.protobuf.CodedInputStream input,\n"
|
| + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
|
| + " throws com.google.protobuf.InvalidProtocolBufferException {\n",
|
| + "classname", descriptor_->name());
|
| + if (HasGeneratedMethods(descriptor_)) {
|
| + printer->Print(
|
| + " return new $classname$(input, extensionRegistry);\n",
|
| + "classname", descriptor_->name());
|
| + } else {
|
| + // When parsing constructor isn't generated, use builder to parse messages.
|
| + // Note, will fallback to use reflection based mergeFieldFrom() in
|
| + // AbstractMessage.Builder.
|
| + printer->Indent();
|
| + printer->Print(
|
| + "Builder builder = newBuilder();\n"
|
| + "try {\n"
|
| + " builder.mergeFrom(input, extensionRegistry);\n"
|
| + "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
|
| + " throw e.setUnfinishedMessage(builder.buildPartial());\n"
|
| + "} catch (java.io.IOException e) {\n"
|
| + " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
|
| + " e.getMessage()).setUnfinishedMessage(builder.buildPartial());\n"
|
| + "}\n"
|
| + "return builder.buildPartial();\n");
|
| + printer->Outdent();
|
| + }
|
| + printer->Print(
|
| + "}\n");
|
| + printer->Outdent();
|
| + printer->Print(
|
| + "};\n"
|
| + "\n");
|
| +
|
| + printer->Print(
|
| + "@java.lang.Override\n"
|
| + "public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
|
| + " return PARSER;\n"
|
| + "}\n"
|
| + "\n",
|
| + "classname", descriptor_->name());
|
| +}
|
| +
|
| } // namespace java
|
| } // namespace compiler
|
| } // namespace protobuf
|
|
|