| Index: third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc
|
| diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc
|
| index 5715a43294ba3e4e6b57bde35f60d892141d6cad..4c474a48a692f0fee2cea85f46632d969631de12 100644
|
| --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc
|
| +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc
|
| @@ -89,19 +89,20 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor)
|
| MessageGenerator::~MessageGenerator() {}
|
|
|
| // ===================================================================
|
| -// TODO(api): Move this class to a separate immutable_message.cc file.
|
| ImmutableMessageGenerator::ImmutableMessageGenerator(
|
| const Descriptor* descriptor, Context* context)
|
| : MessageGenerator(descriptor), context_(context),
|
| name_resolver_(context->GetNameResolver()),
|
| field_generators_(descriptor, context_) {
|
| - GOOGLE_CHECK_NE(
|
| - FileOptions::LITE_RUNTIME, descriptor->file()->options().optimize_for());
|
| + GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
|
| + << "Generator factory error: A non-lite message generator is used to "
|
| + "generate lite messages.";
|
| }
|
|
|
| ImmutableMessageGenerator::~ImmutableMessageGenerator() {}
|
|
|
| -void ImmutableMessageGenerator::GenerateStaticVariables(io::Printer* printer) {
|
| +void ImmutableMessageGenerator::GenerateStaticVariables(
|
| + io::Printer* printer, int* bytecode_estimate) {
|
| // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
|
| // used in the construction of descriptors, we have a tricky bootstrapping
|
| // problem. To help control static initialization order, we make sure all
|
| @@ -124,23 +125,29 @@ void ImmutableMessageGenerator::GenerateStaticVariables(io::Printer* printer) {
|
| } else {
|
| vars["private"] = "private ";
|
| }
|
| + if (*bytecode_estimate <= kMaxStaticSize) {
|
| + vars["final"] = "final ";
|
| + } else {
|
| + vars["final"] = "";
|
| + }
|
|
|
| // The descriptor for this type.
|
| printer->Print(vars,
|
| // TODO(teboring): final needs to be added back. The way to fix it is to
|
| // generate methods that can construct the types, and then still declare the
|
| // types, and then init them in clinit with the new method calls.
|
| - "$private$static com.google.protobuf.Descriptors.Descriptor\n"
|
| + "$private$static $final$com.google.protobuf.Descriptors.Descriptor\n"
|
| " internal_$identifier$_descriptor;\n");
|
| + *bytecode_estimate += 30;
|
|
|
| // And the FieldAccessorTable.
|
| - GenerateFieldAccessorTable(printer);
|
| + GenerateFieldAccessorTable(printer, bytecode_estimate);
|
|
|
| // Generate static members for all nested types.
|
| for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
| // TODO(kenton): Reuse MessageGenerator objects?
|
| ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
|
| - .GenerateStaticVariables(printer);
|
| + .GenerateStaticVariables(printer, bytecode_estimate);
|
| }
|
| }
|
|
|
| @@ -183,7 +190,7 @@ int ImmutableMessageGenerator::GenerateStaticVariableInitializers(
|
| }
|
|
|
| void ImmutableMessageGenerator::
|
| -GenerateFieldAccessorTable(io::Printer* printer) {
|
| +GenerateFieldAccessorTable(io::Printer* printer, int* bytecode_estimate) {
|
| map<string, string> vars;
|
| vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
|
| if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
|
| @@ -193,10 +200,19 @@ GenerateFieldAccessorTable(io::Printer* printer) {
|
| } else {
|
| vars["private"] = "private ";
|
| }
|
| + if (*bytecode_estimate <= kMaxStaticSize) {
|
| + vars["final"] = "final ";
|
| + } else {
|
| + vars["final"] = "";
|
| + }
|
| printer->Print(vars,
|
| - "$private$static\n"
|
| + "$private$static $final$\n"
|
| " com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
|
| " internal_$identifier$_fieldAccessorTable;\n");
|
| +
|
| + // 6 bytes per field and oneof
|
| + *bytecode_estimate += 10 + 6 * descriptor_->field_count()
|
| + + 6 * descriptor_->oneof_decl_count();
|
| }
|
|
|
| int ImmutableMessageGenerator::
|
| @@ -342,7 +358,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
|
| printer->Print(
|
| "}\n");
|
|
|
| - if (HasGeneratedMethods(descriptor_)) {
|
| + if (context_->HasGeneratedMethods(descriptor_)) {
|
| GenerateParsingConstructor(printer);
|
| }
|
|
|
| @@ -408,12 +424,20 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
|
| "cap_oneof_name",
|
| ToUpper(vars["oneof_name"]));
|
| printer->Print(vars,
|
| - "private int value = 0;\n"
|
| + "private final int value;\n"
|
| "private $oneof_capitalized_name$Case(int value) {\n"
|
| " this.value = value;\n"
|
| "}\n");
|
| printer->Print(vars,
|
| + "/**\n"
|
| + " * @deprecated Use {@link #forNumber(int)} instead.\n"
|
| + " */\n"
|
| + "@java.lang.Deprecated\n"
|
| "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
|
| + " return forNumber(value);\n"
|
| + "}\n"
|
| + "\n"
|
| + "public static $oneof_capitalized_name$Case forNumber(int value) {\n"
|
| " switch (value) {\n");
|
| for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
|
| const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
|
| @@ -426,8 +450,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
|
| }
|
| printer->Print(
|
| " case 0: return $cap_oneof_name$_NOT_SET;\n"
|
| - " default: throw new java.lang.IllegalArgumentException(\n"
|
| - " \"Value is undefined for this oneof enum.\");\n"
|
| + " default: return null;\n"
|
| " }\n"
|
| "}\n"
|
| "public int getNumber() {\n"
|
| @@ -440,7 +463,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
|
| printer->Print(vars,
|
| "public $oneof_capitalized_name$Case\n"
|
| "get$oneof_capitalized_name$Case() {\n"
|
| - " return $oneof_capitalized_name$Case.valueOf(\n"
|
| + " return $oneof_capitalized_name$Case.forNumber(\n"
|
| " $oneof_name$Case_);\n"
|
| "}\n"
|
| "\n");
|
| @@ -459,7 +482,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
|
| printer->Print("\n");
|
| }
|
|
|
| - if (HasGeneratedMethods(descriptor_)) {
|
| + if (context_->HasGeneratedMethods(descriptor_)) {
|
| GenerateIsInitialized(printer);
|
| GenerateMessageSerializationMethods(printer);
|
| }
|
| @@ -664,34 +687,40 @@ GenerateParseFromMethods(io::Printer* printer) {
|
| "}\n"
|
| "public static $classname$ parseFrom(java.io.InputStream input)\n"
|
| " throws java.io.IOException {\n"
|
| - " return PARSER.parseFrom(input);\n"
|
| + " return com.google.protobuf.GeneratedMessage\n"
|
| + " .parseWithIOException(PARSER, 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 PARSER.parseFrom(input, extensionRegistry);\n"
|
| + " return com.google.protobuf.GeneratedMessage\n"
|
| + " .parseWithIOException(PARSER, input, extensionRegistry);\n"
|
| "}\n"
|
| "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
|
| " throws java.io.IOException {\n"
|
| - " return PARSER.parseDelimitedFrom(input);\n"
|
| + " return com.google.protobuf.GeneratedMessage\n"
|
| + " .parseDelimitedWithIOException(PARSER, input);\n"
|
| "}\n"
|
| "public static $classname$ parseDelimitedFrom(\n"
|
| " java.io.InputStream input,\n"
|
| " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
|
| " throws java.io.IOException {\n"
|
| - " return PARSER.parseDelimitedFrom(input, extensionRegistry);\n"
|
| + " return com.google.protobuf.GeneratedMessage\n"
|
| + " .parseDelimitedWithIOException(PARSER, input, extensionRegistry);\n"
|
| "}\n"
|
| "public static $classname$ parseFrom(\n"
|
| " com.google.protobuf.CodedInputStream input)\n"
|
| " throws java.io.IOException {\n"
|
| - " return PARSER.parseFrom(input);\n"
|
| + " return com.google.protobuf.GeneratedMessage\n"
|
| + " .parseWithIOException(PARSER, 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 PARSER.parseFrom(input, extensionRegistry);\n"
|
| + " return com.google.protobuf.GeneratedMessage\n"
|
| + " .parseWithIOException(PARSER, input, extensionRegistry);\n"
|
| "}\n"
|
| "\n",
|
| "classname", name_resolver_->GetImmutableClassName(descriptor_));
|
| @@ -1049,22 +1078,52 @@ GenerateEqualsAndHashCode(io::Printer* printer) {
|
|
|
| printer->Print("hash = (19 * hash) + getDescriptorForType().hashCode();\n");
|
|
|
| + // hashCode non-oneofs.
|
| for (int i = 0; i < descriptor_->field_count(); i++) {
|
| const FieldDescriptor* field = descriptor_->field(i);
|
| - const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
|
| - bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
|
| - if (check_has_bits) {
|
| + if (field->containing_oneof() == NULL) {
|
| + const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
|
| + bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
|
| + if (check_has_bits) {
|
| + printer->Print(
|
| + "if (has$name$()) {\n",
|
| + "name", info->capitalized_name);
|
| + printer->Indent();
|
| + }
|
| + field_generators_.get(field).GenerateHashCode(printer);
|
| + if (check_has_bits) {
|
| + printer->Outdent();
|
| + printer->Print("}\n");
|
| + }
|
| + }
|
| + }
|
| +
|
| + // hashCode oneofs.
|
| + for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
| + printer->Print(
|
| + "switch ($oneof_name$Case_) {\n",
|
| + "oneof_name",
|
| + context_->GetOneofGeneratorInfo(
|
| + descriptor_->oneof_decl(i))->name);
|
| + printer->Indent();
|
| + for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
|
| + const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
|
| printer->Print(
|
| - "if (has$name$()) {\n",
|
| - "name", info->capitalized_name);
|
| + "case $field_number$:\n",
|
| + "field_number",
|
| + SimpleItoa(field->number()));
|
| printer->Indent();
|
| - }
|
| - field_generators_.get(field).GenerateHashCode(printer);
|
| - if (check_has_bits) {
|
| + field_generators_.get(field).GenerateHashCode(printer);
|
| + printer->Print("break;\n");
|
| printer->Outdent();
|
| - printer->Print("}\n");
|
| }
|
| + printer->Print(
|
| + "case 0:\n"
|
| + "default:\n");
|
| + printer->Outdent();
|
| + printer->Print("}\n");
|
| }
|
| +
|
| if (descriptor_->extension_range_count() > 0) {
|
| printer->Print(
|
| "hash = hashFields(hash, getExtensionFields());\n");
|
| @@ -1105,7 +1164,8 @@ GenerateParsingConstructor(io::Printer* printer) {
|
| printer->Print(
|
| "private $classname$(\n"
|
| " com.google.protobuf.CodedInputStream input,\n"
|
| - " com.google.protobuf.ExtensionRegistryLite extensionRegistry) {\n",
|
| + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
|
| + " throws com.google.protobuf.InvalidProtocolBufferException {\n",
|
| "classname", descriptor_->name());
|
| printer->Indent();
|
|
|
| @@ -1165,7 +1225,8 @@ GenerateParsingConstructor(io::Printer* printer) {
|
| "default: {\n"
|
| " if (!input.skipField(tag)) {\n"
|
| " done = true;\n" // it's an endgroup tag
|
| - " }\n"
|
| + " }\n");
|
| + printer->Print(
|
| " break;\n"
|
| "}\n");
|
| }
|
| @@ -1215,11 +1276,10 @@ GenerateParsingConstructor(io::Printer* printer) {
|
| printer->Outdent();
|
| printer->Print(
|
| "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
|
| - " throw new RuntimeException(e.setUnfinishedMessage(this));\n"
|
| + " throw e.setUnfinishedMessage(this);\n"
|
| "} catch (java.io.IOException e) {\n"
|
| - " throw new RuntimeException(\n"
|
| - " new com.google.protobuf.InvalidProtocolBufferException(\n"
|
| - " e.getMessage()).setUnfinishedMessage(this));\n"
|
| + " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
|
| + " e).setUnfinishedMessage(this);\n"
|
| "} finally {\n");
|
| printer->Indent();
|
|
|
| @@ -1261,20 +1321,9 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
|
| " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
|
| " throws com.google.protobuf.InvalidProtocolBufferException {\n",
|
| "classname", descriptor_->name());
|
| - if (HasGeneratedMethods(descriptor_)) {
|
| - // The parsing constructor throws an InvalidProtocolBufferException via a
|
| - // RuntimeException to aid in method pruning. We unwrap it here.
|
| + if (context_->HasGeneratedMethods(descriptor_)) {
|
| printer->Print(
|
| - " try {\n"
|
| - " return new $classname$(input, extensionRegistry);\n"
|
| - " } catch (RuntimeException e) {\n"
|
| - " if (e.getCause() instanceof\n"
|
| - " com.google.protobuf.InvalidProtocolBufferException) {\n"
|
| - " throw (com.google.protobuf.InvalidProtocolBufferException)\n"
|
| - " e.getCause();\n"
|
| - " }\n"
|
| - " throw e;\n"
|
| - " }\n",
|
| + " return new $classname$(input, extensionRegistry);\n",
|
| "classname", descriptor_->name());
|
| } else {
|
| // When parsing constructor isn't generated, use builder to parse
|
| @@ -1329,14 +1378,39 @@ void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) {
|
| void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) {
|
| printer->Print(
|
| "private static String getTypeUrl(\n"
|
| + " java.lang.String typeUrlPrefix,\n"
|
| " com.google.protobuf.Descriptors.Descriptor descriptor) {\n"
|
| - " return \"type.googleapis.com/\" + descriptor.getFullName();\n"
|
| + " return typeUrlPrefix.endsWith(\"/\")\n"
|
| + " ? typeUrlPrefix + descriptor.getFullName()\n"
|
| + " : typeUrlPrefix + \"/\" + descriptor.getFullName();\n"
|
| + "}\n"
|
| + "\n"
|
| + "private static String getTypeNameFromTypeUrl(\n"
|
| + " java.lang.String typeUrl) {\n"
|
| + " int pos = typeUrl.lastIndexOf('/');\n"
|
| + " return pos == -1 ? \"\" : typeUrl.substring(pos + 1);\n"
|
| "}\n"
|
| "\n"
|
| "public static <T extends com.google.protobuf.Message> Any pack(\n"
|
| " T message) {\n"
|
| " return Any.newBuilder()\n"
|
| - " .setTypeUrl(getTypeUrl(message.getDescriptorForType()))\n"
|
| + " .setTypeUrl(getTypeUrl(\"type.googleapis.com\",\n"
|
| + " message.getDescriptorForType()))\n"
|
| + " .setValue(message.toByteString())\n"
|
| + " .build();\n"
|
| + "}\n"
|
| + "\n"
|
| + "/**\n"
|
| + " * Packs a message uisng the given type URL prefix. The type URL will\n"
|
| + " * be constructed by concatenating the message type's full name to the\n"
|
| + " * prefix with an optional \"/\" separator if the prefix doesn't end\n"
|
| + " * with \"/\" already.\n"
|
| + " */\n"
|
| + "public static <T extends com.google.protobuf.Message> Any pack(\n"
|
| + " T message, java.lang.String typeUrlPrefix) {\n"
|
| + " return Any.newBuilder()\n"
|
| + " .setTypeUrl(getTypeUrl(typeUrlPrefix,\n"
|
| + " message.getDescriptorForType()))\n"
|
| " .setValue(message.toByteString())\n"
|
| " .build();\n"
|
| "}\n"
|
| @@ -1345,8 +1419,8 @@ void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) {
|
| " java.lang.Class<T> clazz) {\n"
|
| " T defaultInstance =\n"
|
| " com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
|
| - " return getTypeUrl().equals(\n"
|
| - " getTypeUrl(defaultInstance.getDescriptorForType()));\n"
|
| + " return getTypeNameFromTypeUrl(getTypeUrl()).equals(\n"
|
| + " defaultInstance.getDescriptorForType().getFullName());\n"
|
| "}\n"
|
| "\n"
|
| "private volatile com.google.protobuf.Message cachedUnpackValue;\n"
|
|
|