mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
Internal change.
PiperOrigin-RevId: 970073736
This commit is contained in:
parent
dee117a787
commit
4d20214ca8
2 changed files with 91 additions and 138 deletions
|
|
@ -77,24 +77,6 @@ std::string MapValueImmutableClassdName(const Descriptor* descriptor,
|
|||
ABSL_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
|
||||
return name_resolver->GetImmutableClassName(value_field->message_type());
|
||||
}
|
||||
|
||||
bool BitfieldTracksMutability(const FieldDescriptor* const descriptor) {
|
||||
if (!descriptor->is_repeated() || IsMapField(descriptor)) {
|
||||
return false;
|
||||
}
|
||||
// TODO: update this to migrate repeated fields to use
|
||||
// ProtobufList (which tracks immutability internally). That allows us to use
|
||||
// the presence bit to skip work on the repeated field if it is not populated.
|
||||
// Once all repeated fields are held in ProtobufLists, this method shouldn't
|
||||
// be needed.
|
||||
switch (descriptor->type()) {
|
||||
case FieldDescriptor::TYPE_GROUP:
|
||||
case FieldDescriptor::TYPE_MESSAGE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
MessageBuilderGenerator::MessageBuilderGenerator(
|
||||
|
|
@ -150,11 +132,7 @@ void MessageBuilderGenerator::Generate(io::Printer* printer) {
|
|||
}
|
||||
|
||||
// Integers for bit fields.
|
||||
int totalBits = 0;
|
||||
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||
totalBits += field_generators_.get(descriptor_->field(i)).GetNumBits();
|
||||
}
|
||||
int totalInts = (totalBits + 31) / 32;
|
||||
int totalInts = (descriptor_->field_count() + 31) / 32;
|
||||
for (int i = 0; i < totalInts; i++) {
|
||||
printer->Print("private int $bit_field_name$;\n", "bit_field_name",
|
||||
GetBitFieldName(i));
|
||||
|
|
@ -582,20 +560,10 @@ void MessageBuilderGenerator::GenerateBuildPartial(io::Printer* printer) {
|
|||
|
||||
printer->Indent();
|
||||
|
||||
// Handle the repeated fields first so that the "mutable bits" are cleared.
|
||||
bool has_repeated_fields = false;
|
||||
for (int i = 0; i < descriptor_->field_count(); ++i) {
|
||||
if (BitfieldTracksMutability(descriptor_->field(i))) {
|
||||
has_repeated_fields = true;
|
||||
printer->Print("buildPartialRepeatedFields(result);\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// One buildPartial_autosplit_#() per from_bit_field
|
||||
int totalBuilderInts = (descriptor_->field_count() + 31) / 32;
|
||||
if (totalBuilderInts > 0) {
|
||||
for (int i = 0; i < totalBuilderInts; ++i) {
|
||||
int totalInts = (descriptor_->field_count() + 31) / 32;
|
||||
if (totalInts > 0) {
|
||||
for (int i = 0; i < totalInts; ++i) {
|
||||
printer->Print(
|
||||
"if ($bit_field_name$ != 0) { "
|
||||
"buildPartial_autosplit_$shard$(result); }\n",
|
||||
|
|
@ -615,26 +583,9 @@ void MessageBuilderGenerator::GenerateBuildPartial(io::Printer* printer) {
|
|||
"\n",
|
||||
"classname", name_resolver_->GetImmutableClassName(descriptor_));
|
||||
|
||||
// Build Repeated Fields
|
||||
if (has_repeated_fields) {
|
||||
printer->Print(
|
||||
"private void buildPartialRepeatedFields($classname$ result) {\n",
|
||||
"classname", name_resolver_->GetImmutableClassName(descriptor_));
|
||||
printer->Indent();
|
||||
for (int i = 0; i < descriptor_->field_count(); ++i) {
|
||||
if (BitfieldTracksMutability(descriptor_->field(i))) {
|
||||
const ImmutableFieldGenerator& field =
|
||||
field_generators_.get(descriptor_->field(i));
|
||||
field.GenerateBuildingCode(printer);
|
||||
}
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
|
||||
// Build all fields in shards organized by bitfield membership.
|
||||
int start_field = 0;
|
||||
for (int i = 0; i < totalBuilderInts; i++) {
|
||||
for (int i = 0; i < totalInts; i++) {
|
||||
start_field = GenerateBuildPartialShard(printer, i, start_field);
|
||||
}
|
||||
|
||||
|
|
@ -665,34 +616,21 @@ int MessageBuilderGenerator::GenerateBuildPartialShard(io::Printer* printer,
|
|||
|
||||
int bit = 0;
|
||||
int next = first_field;
|
||||
for (; bit < 32 && next < descriptor_->field_count(); ++next) {
|
||||
for (; bit < 32 && next < descriptor_->field_count(); ++next, ++bit) {
|
||||
const ImmutableFieldGenerator& field =
|
||||
field_generators_.get(descriptor_->field(next));
|
||||
bit += field.GetNumBits();
|
||||
|
||||
// Skip oneof fields that are handled separately
|
||||
if (IsRealOneof(descriptor_->field(next))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip repeated fields because they are currently handled
|
||||
// in separate buildPartial sub-methods.
|
||||
if (BitfieldTracksMutability(descriptor_->field(next))) {
|
||||
continue;
|
||||
}
|
||||
// Skip fields without presence bits in the builder
|
||||
if (field.GetNumBits() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Track message bits if necessary
|
||||
if (field.GetNumBits() > 0) {
|
||||
int to_bitfield = field.GetBitIndex() / 32;
|
||||
if (declared_to_bitfields.count(to_bitfield) == 0) {
|
||||
printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name",
|
||||
GetBitFieldName(to_bitfield));
|
||||
declared_to_bitfields.insert(to_bitfield);
|
||||
}
|
||||
int to_bitfield = field.GetBitIndex() / 32;
|
||||
if (declared_to_bitfields.count(to_bitfield) == 0) {
|
||||
printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name",
|
||||
GetBitFieldName(to_bitfield));
|
||||
declared_to_bitfields.insert(to_bitfield);
|
||||
}
|
||||
|
||||
// Copy the field from the builder to the message
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ void SetMessageVariables(
|
|||
(*variables)["group_or_message"] =
|
||||
(GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group"
|
||||
: "Message";
|
||||
(*variables)["empty_list"] =
|
||||
absl::StrCat("emptyList(", (*variables)["type"], ".class)");
|
||||
|
||||
// TODO: Add @deprecated javadoc when generating javadoc is supported
|
||||
// by the proto compiler
|
||||
(*variables)["deprecation"] =
|
||||
|
|
@ -359,6 +362,7 @@ void ImmutableMessageFieldGenerator::
|
|||
" isClean());\n"
|
||||
" $name$_ = null;\n"
|
||||
" }\n"
|
||||
" $set_has_field_bit$\n"
|
||||
" return $name$Builder_;\n"
|
||||
"}\n");
|
||||
}
|
||||
|
|
@ -968,9 +972,10 @@ void RepeatedImmutableMessageFieldGenerator::GenerateGetOrBuilderMethod(
|
|||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
|
||||
io::Printer* printer) const {
|
||||
printer->Print(variables_,
|
||||
"@SuppressWarnings(\"serial\")\n"
|
||||
"private java.util.List<$type$> $name$_;\n");
|
||||
printer->Print(
|
||||
variables_,
|
||||
"private com.google.protobuf.Internal.ProtobufList<$type$> $name$_ =\n"
|
||||
" $empty_list$;\n");
|
||||
PrintExtraFieldInfo(variables_, printer);
|
||||
GenerateGetListMethod(printer);
|
||||
GenerateGetOrBuilderListMethod(printer);
|
||||
|
|
@ -981,30 +986,29 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
|
|||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateEnsureIsMutableMethod(
|
||||
io::Printer* printer) const {
|
||||
printer->Print(
|
||||
variables_,
|
||||
"private void ensure$capitalized_name$IsMutable() {\n"
|
||||
" if (!$get_mutable_bit_builder$) {\n"
|
||||
" $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
|
||||
" $set_mutable_bit_builder$;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
printer->Print(variables_,
|
||||
"private void ensure$capitalized_name$IsMutable() {\n"
|
||||
" if (!$name$_.isModifiable()) {\n"
|
||||
" $name$_ = makeMutableCopy($name$_);\n"
|
||||
" }\n"
|
||||
" $set_has_field_bit$\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateBuilderGetListMethod(
|
||||
io::Printer* printer) const {
|
||||
// List<Field> getRepeatedFieldList()
|
||||
WriteFieldDocComment(printer, descriptor_, context_->options());
|
||||
PrintNestedBuilderFunction(
|
||||
printer,
|
||||
"$deprecation$public java.util.List<$type$> "
|
||||
"${$get$capitalized_name$List$}$()",
|
||||
PrintNestedBuilderFunction(printer,
|
||||
"$deprecation$public java.util.List<$type$> "
|
||||
"${$get$capitalized_name$List$}$()",
|
||||
|
||||
"return java.util.Collections.unmodifiableList($name$_);\n",
|
||||
"return $name$Builder_.getMessageList();\n",
|
||||
"$name$_.makeImmutable();\n"
|
||||
"return $name$_;\n",
|
||||
|
||||
nullptr);
|
||||
"return $name$Builder_.getMessageList();\n",
|
||||
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateBuilderGetCountMethod(
|
||||
|
|
@ -1046,8 +1050,9 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderSetMethod(
|
|||
"ensure$capitalized_name$IsMutable();\n"
|
||||
"$name$_.set(index, value);\n"
|
||||
"$on_changed$\n",
|
||||
"$name$Builder_.setMessage(index, value);\n", "return this;\n",
|
||||
Semantic::kSet);
|
||||
"$name$Builder_.setMessage(index, "
|
||||
"value);\n$set_has_field_bit$\n$on_changed$\n",
|
||||
"return this;\n", Semantic::kSet);
|
||||
}
|
||||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateBuilderSetBuilderMethod(
|
||||
|
|
@ -1078,7 +1083,9 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderAddMethod(
|
|||
|
||||
"$on_changed$\n",
|
||||
|
||||
"$name$Builder_.addMessage(value);\n",
|
||||
"$name$Builder_.addMessage(value);\n"
|
||||
"$set_has_field_bit$\n"
|
||||
"$on_changed$\n",
|
||||
|
||||
"return this;\n", Semantic::kSet);
|
||||
}
|
||||
|
|
@ -1097,7 +1104,9 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderAddAtIndexMethod(
|
|||
"$name$_.add(index, value);\n"
|
||||
"$on_changed$\n",
|
||||
|
||||
"$name$Builder_.addMessage(index, value);\n",
|
||||
"$name$Builder_.addMessage(index, value);\n"
|
||||
"$set_has_field_bit$\n"
|
||||
"$on_changed$\n",
|
||||
|
||||
"return this;\n", Semantic::kSet);
|
||||
}
|
||||
|
|
@ -1138,14 +1147,17 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderAddAllMethod(
|
|||
"$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
|
||||
" java.lang.Iterable<? extends $type$> values)",
|
||||
|
||||
"ensure$capitalized_name$IsMutable();\n"
|
||||
"com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
|
||||
" values, $name$_);\n"
|
||||
"$on_changed$\n",
|
||||
"$name$_ = com.google.protobuf.Internal.ProtobufList.concatenate(\n"
|
||||
" $name$_, values);\n",
|
||||
|
||||
"$name$Builder_.addAllMessages(values);\n",
|
||||
|
||||
"return this;\n", Semantic::kSet);
|
||||
"if (get$capitalized_name$Count() > 0) {\n"
|
||||
" $set_has_field_bit$;\n"
|
||||
"}\n"
|
||||
"$on_changed$\n"
|
||||
"return this;\n",
|
||||
Semantic::kSet);
|
||||
}
|
||||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearMethod(
|
||||
|
|
@ -1155,13 +1167,14 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearMethod(
|
|||
PrintNestedBuilderFunction(
|
||||
printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
|
||||
|
||||
"$name$_ = java.util.Collections.emptyList();\n"
|
||||
"$clear_mutable_bit_builder$;\n"
|
||||
"$on_changed$\n",
|
||||
"$name$_ = $empty_list$;\n",
|
||||
|
||||
"$name$Builder_.clear();\n",
|
||||
|
||||
"return this;\n", Semantic::kSet);
|
||||
"$clear_has_field_bit$\n"
|
||||
"$on_changed$\n"
|
||||
"return this;\n",
|
||||
Semantic::kSet);
|
||||
}
|
||||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateBuilderRemoveMethod(
|
||||
|
|
@ -1173,12 +1186,16 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderRemoveMethod(
|
|||
"$deprecation$public Builder ${$remove$capitalized_name$$}$(int index)",
|
||||
|
||||
"ensure$capitalized_name$IsMutable();\n"
|
||||
"$name$_.remove(index);\n"
|
||||
"$on_changed$\n",
|
||||
"$name$_.remove(index);\n",
|
||||
|
||||
"$name$Builder_.remove(index);\n",
|
||||
|
||||
"return this;\n", Semantic::kSet);
|
||||
"if (get$capitalized_name$Count() == 0) {\n"
|
||||
" $clear_has_field_bit$;\n"
|
||||
"}\n"
|
||||
"$on_changed$\n"
|
||||
"return this;\n",
|
||||
Semantic::kSet);
|
||||
}
|
||||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateBuilderGetBuilderMethod(
|
||||
|
|
@ -1224,7 +1241,8 @@ void RepeatedImmutableMessageFieldGenerator::
|
|||
" if ($name$Builder_ != null) {\n"
|
||||
" return $name$Builder_.getMessageOrBuilderList();\n"
|
||||
" } else {\n"
|
||||
" return java.util.Collections.unmodifiableList($name$_);\n"
|
||||
" $name$_.makeImmutable();\n"
|
||||
" return $name$_;\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
printer->Annotate("{", "}", descriptor_);
|
||||
|
|
@ -1232,11 +1250,13 @@ void RepeatedImmutableMessageFieldGenerator::
|
|||
|
||||
void RepeatedImmutableMessageFieldGenerator::
|
||||
GenerateBuilderAddBuilderNoArgsMethod(io::Printer* printer) const {
|
||||
// Field.Builder addRepeatedField()
|
||||
// Field.Builder addRepeatedFieldBuilder()
|
||||
WriteFieldDocComment(printer, descriptor_, context_->options());
|
||||
printer->Print(variables_,
|
||||
"$deprecation$public $type$.Builder "
|
||||
"${$add$capitalized_name$Builder$}$() {\n"
|
||||
" $set_has_field_bit$\n"
|
||||
" $on_changed$\n"
|
||||
" return "
|
||||
"internalGet$capitalized_name$FieldBuilder().addBuilder(\n"
|
||||
" $type$.getDefaultInstance());\n"
|
||||
|
|
@ -1252,6 +1272,8 @@ void RepeatedImmutableMessageFieldGenerator::
|
|||
variables_,
|
||||
"$deprecation$public $type$.Builder ${$add$capitalized_name$Builder$}$(\n"
|
||||
" int index) {\n"
|
||||
" $set_has_field_bit$\n"
|
||||
" $on_changed$\n"
|
||||
" return "
|
||||
"internalGet$capitalized_name$FieldBuilder().addBuilder(\n"
|
||||
" index, $type$.getDefaultInstance());\n"
|
||||
|
|
@ -1284,30 +1306,23 @@ void RepeatedImmutableMessageFieldGenerator::
|
|||
"com.google.protobuf.RepeatedFieldBuilder<\n"
|
||||
" $type$, $type$.Builder, $type$OrBuilder>(\n"
|
||||
" $name$_,\n"
|
||||
" $get_mutable_bit_builder$,\n"
|
||||
" $name$_.isModifiable(),\n"
|
||||
" getParentForChildren(),\n"
|
||||
" isClean());\n"
|
||||
" $name$_ = null;\n"
|
||||
" }\n"
|
||||
" $set_has_field_bit$\n"
|
||||
" $on_changed$\n"
|
||||
" return $name$Builder_;\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
|
||||
io::Printer* printer) const {
|
||||
// Used when the builder is null.
|
||||
// One field is the list and the other field keeps track of whether the
|
||||
// list is immutable. If it's immutable, the invariant is that it must
|
||||
// either an instance of Collections.emptyList() or it's an ArrayList
|
||||
// wrapped in a Collections.unmodifiableList() wrapper and nobody else has
|
||||
// a reference to the underlying ArrayList. This invariant allows us to
|
||||
// share instances of lists between protocol buffers avoiding expensive
|
||||
// memory allocations. Note, immutable is a strong guarantee here -- not
|
||||
// just that the list cannot be modified via the reference but that the
|
||||
// list can never be modified.
|
||||
printer->Print(variables_,
|
||||
"private java.util.List<$type$> $name$_ =\n"
|
||||
" java.util.Collections.emptyList();\n");
|
||||
printer->Print(
|
||||
variables_,
|
||||
"private com.google.protobuf.Internal.ProtobufList<$type$> $name$_ =\n"
|
||||
" emptyList($type$.class);\n");
|
||||
|
||||
GenerateEnsureIsMutableMethod(printer);
|
||||
|
||||
|
|
@ -1339,7 +1354,6 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
|
|||
GenerateBuilderGetBuilderListMethod(printer);
|
||||
GenerateBuilderInternalGetFieldBuilderMethod(printer);
|
||||
}
|
||||
|
||||
void RepeatedImmutableMessageFieldGenerator::
|
||||
GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
|
||||
printer->Print(variables_, "internalGet$capitalized_name$FieldBuilder();\n");
|
||||
|
|
@ -1347,18 +1361,16 @@ void RepeatedImmutableMessageFieldGenerator::
|
|||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateInitializationCode(
|
||||
io::Printer* printer) const {
|
||||
printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
|
||||
printer->Print(variables_, "$name$_ = $empty_list$;\n");
|
||||
}
|
||||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearCode(
|
||||
io::Printer* printer) const {
|
||||
PrintNestedBuilderCondition(printer,
|
||||
"$name$_ = java.util.Collections.emptyList();\n",
|
||||
PrintNestedBuilderCondition(printer, "$name$_ = $empty_list$;\n",
|
||||
|
||||
"$name$_ = null;\n"
|
||||
"$name$Builder_.clear();\n");
|
||||
|
||||
printer->Print(variables_, "$clear_mutable_bit_builder$;\n");
|
||||
printer->Print(variables_, "$clear_has_field_bit$;\n");
|
||||
}
|
||||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode(
|
||||
|
|
@ -1373,7 +1385,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode(
|
|||
"if (!other.$name$_.isEmpty()) {\n"
|
||||
" if ($name$_.isEmpty()) {\n"
|
||||
" $name$_ = other.$name$_;\n"
|
||||
" $clear_mutable_bit_builder$;\n"
|
||||
" $set_has_field_bit$\n"
|
||||
" } else {\n"
|
||||
" ensure$capitalized_name$IsMutable();\n"
|
||||
" $name$_.addAll(other.$name$_);\n"
|
||||
|
|
@ -1386,14 +1398,16 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode(
|
|||
" $name$Builder_.dispose();\n"
|
||||
" $name$Builder_ = null;\n"
|
||||
" $name$_ = other.$name$_;\n"
|
||||
" $clear_mutable_bit_builder$;\n"
|
||||
" $set_has_field_bit$\n"
|
||||
" $name$Builder_ = \n"
|
||||
" com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders "
|
||||
"?\n"
|
||||
" internalGet$capitalized_name$FieldBuilder() : null;\n"
|
||||
" } else {\n"
|
||||
" $name$Builder_.addAllMessages(other.$name$_);\n"
|
||||
" $set_has_field_bit$\n"
|
||||
" }\n"
|
||||
" $on_changed$\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
|
|
@ -1402,15 +1416,14 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuildingCode(
|
|||
// The code below (non-nested builder case) ensures that the result has an
|
||||
// immutable list. If our list is immutable, we can just reuse it. If not,
|
||||
// we make it immutable.
|
||||
printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n");
|
||||
PrintNestedBuilderCondition(
|
||||
printer,
|
||||
"if ($get_mutable_bit_builder$) {\n"
|
||||
" $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
|
||||
" $clear_mutable_bit_builder$;\n"
|
||||
"}\n"
|
||||
"$name$_.makeImmutable();\n"
|
||||
"result.$name$_ = $name$_;\n",
|
||||
|
||||
"result.$name$_ = $name$Builder_.build();\n");
|
||||
"result.$name$_ = $name$Builder_.buildProtobufList();\n");
|
||||
printer->Print("}\n");
|
||||
}
|
||||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateBuilderParsingCode(
|
||||
|
|
@ -1431,7 +1444,9 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderParsingCode(
|
|||
PrintNestedBuilderCondition(printer,
|
||||
"ensure$capitalized_name$IsMutable();\n"
|
||||
"$name$_.add(m);\n",
|
||||
"$name$Builder_.addMessage(m);\n");
|
||||
"$name$Builder_.addMessage(m);\n"
|
||||
"$set_has_field_bit$\n"
|
||||
"$on_changed$\n");
|
||||
}
|
||||
|
||||
void RepeatedImmutableMessageFieldGenerator::GenerateSerializationCode(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue