Use monomorphic static dispatch for Java Protobuf submessage parsing

PiperOrigin-RevId: 970550003
This commit is contained in:
Protobuf Team Bot 2026-08-25 07:47:58 -07:00 committed by Copybara-Service
parent d3daee4c68
commit d17cf67434
3 changed files with 100 additions and 25 deletions

View file

@ -609,7 +609,7 @@ public abstract class CodedInputStream {
@CanIgnoreReturnValue
public abstract int pushLimit(int byteLimit) throws InvalidProtocolBufferException;
final int pushLimitBeforeMessage() throws IOException {
public final int pushLimitBeforeMessage() throws IOException {
final int length = readRawVarint32();
checkRecursionLimit();
final int oldLimit = pushLimit(length);
@ -624,7 +624,7 @@ public abstract class CodedInputStream {
*/
public abstract void popLimit(final int oldLimit);
final void popLimitAfterMessage(int oldLimit) throws IOException {
public final void popLimitAfterMessage(int oldLimit) throws IOException {
checkLastTagWas(0);
--messageDepth;
if (getBytesUntilLimit() != 0) {

View file

@ -11,6 +11,7 @@
#include "google/protobuf/compiler/java/full/message_field.h"
#include <cstdint>
#include <string>
#include "absl/log/absl_check.h"
@ -85,6 +86,8 @@ void SetMessageVariables(
(*variables)["get_has_field_bit_from_local"] =
GenerateGetBitFromLocal(bit_index);
(*variables)["tag"] = absl::StrCat(
static_cast<int32_t>(internal::WireFormat::MakeTag(descriptor)));
(*variables)["tag_size"] = absl::StrCat(
internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
}
@ -181,6 +184,29 @@ void ImmutableMessageFieldGenerator::GenerateMembers(
GenerateHasMethod(printer);
GenerateGetMethod(printer);
GenerateGetOrBuilderMethod(printer);
GenerateWriteFieldMethod(printer);
}
void ImmutableMessageFieldGenerator::GenerateWriteFieldMethod(
io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
"private void write$capitalized_name$Field(\n"
" com.google.protobuf.CodedOutputStream output)\n"
" throws java.io.IOException {\n"
" output.writeGroup($number$, get$capitalized_name$());\n"
"}\n");
} else {
printer->Print(variables_,
"private void write$capitalized_name$Field(\n"
" com.google.protobuf.CodedOutputStream output)\n"
" throws java.io.IOException {\n"
" $type$ tmp = get$capitalized_name$();\n"
" output.writeUInt32NoTag($tag$);\n"
" output.writeUInt32NoTag(tmp.getSerializedSize());\n"
" tmp.writeTo(output);\n"
"}\n");
}
}
void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
@ -394,14 +420,15 @@ void ImmutableMessageFieldGenerator::GenerateBuilderParseMethod(
} else {
printer->Print(
variables_,
"final int oldLimit = input.pushLimitBeforeMessage();\n"
"if ($name$_ != null || $name$Builder_ != null) {\n"
" input.readMessage(\n"
" "
"internalGet$capitalized_name$FieldBuilder().getBuilder(),\n"
" extensionRegistry);\n"
" internalGet$capitalized_name$FieldBuilder().getBuilder()\n"
" .mergeFrom(input, extensionRegistry);\n"
"} else {\n"
" $name$_ = input.readMessage($type$.parser(), extensionRegistry);\n"
" $name$_ = $type$.parser().parsePartialFrom(input, "
"extensionRegistry);\n"
"}\n"
"input.popLimitAfterMessage(oldLimit);\n"
"$set_has_field_bit$\n");
}
printer->Outdent();
@ -482,11 +509,10 @@ void ImmutableMessageFieldGenerator::GenerateBuilderParsingCode(
void ImmutableMessageFieldGenerator::GenerateSerializationCode(
io::Printer* printer) const {
printer->Print(
variables_,
"if ($is_field_present$) {\n"
" output.write$group_or_message$($number$, get$capitalized_name$());\n"
"}\n");
printer->Print(variables_,
"if ($is_field_present$) {\n"
" write$capitalized_name$Field(output);\n"
"}\n");
}
void ImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
@ -578,6 +604,29 @@ void ImmutableMessageOneofFieldGenerator::GenerateMembers(
GenerateHasMethod(printer);
GenerateGetMethod(printer);
GenerateGetOrBuilderMethod(printer);
GenerateWriteFieldMethod(printer);
}
void ImmutableMessageOneofFieldGenerator::GenerateWriteFieldMethod(
io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
"private void write$capitalized_name$Field(\n"
" com.google.protobuf.CodedOutputStream output)\n"
" throws java.io.IOException {\n"
" output.writeGroup($number$, ($type$) $oneof_name$_);\n"
"}\n");
} else {
printer->Print(variables_,
"private void write$capitalized_name$Field(\n"
" com.google.protobuf.CodedOutputStream output)\n"
" throws java.io.IOException {\n"
" $type$ tmp = ($type$) $oneof_name$_;\n"
" output.writeUInt32NoTag($tag$);\n"
" output.writeUInt32NoTag(tmp.getSerializedSize());\n"
" tmp.writeTo(output);\n"
"}\n");
}
}
void ImmutableMessageOneofFieldGenerator::GenerateBuilderHasMethod(
@ -826,11 +875,10 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderParsingCode(
void ImmutableMessageOneofFieldGenerator::GenerateSerializationCode(
io::Printer* printer) const {
printer->Print(
variables_,
"if ($has_oneof_case_message$) {\n"
" output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n"
"}\n");
printer->Print(variables_,
"if ($has_oneof_case_message$) {\n"
" write$capitalized_name$Field(output);\n"
"}\n");
}
void ImmutableMessageOneofFieldGenerator::GenerateSerializedSizeCode(
@ -982,6 +1030,33 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
GenerateGetCountMethod(printer);
GenerateGetMethod(printer);
GenerateGetOrBuilderMethod(printer);
GenerateWriteFieldMethod(printer);
}
void RepeatedImmutableMessageFieldGenerator::GenerateWriteFieldMethod(
io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
"private void write$capitalized_name$Field(\n"
" com.google.protobuf.CodedOutputStream output)\n"
" throws java.io.IOException {\n"
" for (int i = 0; i < $name$_.size(); i++) {\n"
" output.writeGroup($number$, $name$_.get(i));\n"
" }\n"
"}\n");
} else {
printer->Print(variables_,
"private void write$capitalized_name$Field(\n"
" com.google.protobuf.CodedOutputStream output)\n"
" throws java.io.IOException {\n"
" for (int i = 0; i < $name$_.size(); i++) {\n"
" $type$ tmp = $name$_.get(i);\n"
" output.writeUInt32NoTag($tag$);\n"
" output.writeUInt32NoTag(tmp.getSerializedSize());\n"
" tmp.writeTo(output);\n"
" }\n"
"}\n");
}
}
void RepeatedImmutableMessageFieldGenerator::GenerateEnsureIsMutableMethod(
@ -1436,10 +1511,10 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderParsingCode(
" extensionRegistry);\n");
} else {
printer->Print(variables_,
"$type$ m =\n"
" input.readMessage(\n"
" $type$.$get_parser$,\n"
" extensionRegistry);\n");
"final int oldLimit = input.pushLimitBeforeMessage();\n"
"$type$ m = $type$.parser().parsePartialFrom(input, "
"extensionRegistry);\n"
"input.popLimitAfterMessage(oldLimit);\n");
}
PrintNestedBuilderCondition(printer,
"ensure$capitalized_name$IsMutable();\n"
@ -1451,10 +1526,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderParsingCode(
void RepeatedImmutableMessageFieldGenerator::GenerateSerializationCode(
io::Printer* printer) const {
printer->Print(variables_,
"for (int i = 0; i < $name$_.size(); i++) {\n"
" output.write$group_or_message$($number$, $name$_.get(i));\n"
"}\n");
printer->Print(variables_, "write$capitalized_name$Field(output);\n");
}
void RepeatedImmutableMessageFieldGenerator::GenerateSerializedSizeCode(

View file

@ -83,6 +83,7 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator {
void GenerateHasMethod(io::Printer* printer) const;
void GenerateGetMethod(io::Printer* printer) const;
void GenerateGetOrBuilderMethod(io::Printer* printer) const;
void GenerateWriteFieldMethod(io::Printer* printer) const;
void GenerateBuilderHasMethod(io::Printer* printer) const;
void GenerateBuilderGetMethod(io::Printer* printer) const;
@ -120,6 +121,7 @@ class ImmutableMessageOneofFieldGenerator
void GenerateHasMethod(io::Printer* printer) const;
void GenerateGetMethod(io::Printer* printer) const;
void GenerateGetOrBuilderMethod(io::Printer* printer) const;
void GenerateWriteFieldMethod(io::Printer* printer) const;
void GenerateBuilderHasMethod(io::Printer* printer) const;
void GenerateBuilderGetMethod(io::Printer* printer) const;
@ -173,6 +175,7 @@ class RepeatedImmutableMessageFieldGenerator
void GenerateGetMethod(io::Printer* printer) const;
void GenerateGetOrBuilderListMethod(io::Printer* printer) const;
void GenerateGetOrBuilderMethod(io::Printer* printer) const;
void GenerateWriteFieldMethod(io::Printer* printer) const;
void GenerateEnsureIsMutableMethod(io::Printer* printer) const;
void GenerateBuilderGetListMethod(io::Printer* printer) const;