summaryrefslogtreecommitdiffstats
path: root/contrib/libs/protoc/src/google/protobuf/compiler/cpp
diff options
context:
space:
mode:
authormikhnenko <[email protected]>2024-06-25 08:50:35 +0300
committermikhnenko <[email protected]>2024-06-25 09:00:27 +0300
commit509c9fc9e7b9c3b8be7307d72a4c966e5f9aa194 (patch)
tree4b8a6a44009906ac852e59efa0bc78bb12043a5b /contrib/libs/protoc/src/google/protobuf/compiler/cpp
parent7688f2313619a39a60ef3c2734d8efbc49a0a6db (diff)
Update protobuf to 3.20.2 and pyprotobuf to 3.20.3
Если это pull-request что-то сломал, то: - если это тест с канонизацией и еще нет pr с переканонизацией, то переканонизируйте пожалуйста сами - проверьте, что тест не флапает - приходите в [DEVTOOLSSUPPORT](https://st.yandex-team.ru/createTicket?queue=DEVTOOLSSUPPORT) - там вам обязательно помогут 987be5ed151f827f7f292f32420470b04b71a91d
Diffstat (limited to 'contrib/libs/protoc/src/google/protobuf/compiler/cpp')
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum.cc8
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum.h3
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum_field.cc68
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum_field.h7
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_extension.cc38
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_field.cc48
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_field.h15
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_file.cc278
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_file.h5
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_generator.cc26
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_generator.h3
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_helpers.cc32
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_helpers.h64
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_map_field.cc175
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_map_field.h4
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message.cc1026
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message.h29
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_field.cc258
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_field.h1
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h2
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_names.h1
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_options.h37
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc8
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc1302
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h91
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc79
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_primitive_field.h11
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_service.cc3
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_service.h3
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_string_field.cc264
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_string_field.h13
31 files changed, 1927 insertions, 1975 deletions
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum.cc
index 4ecd6a9cf76..960dfcadf79 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum.cc
@@ -38,10 +38,10 @@
#include <limits>
#include <map>
-#include <google/protobuf/compiler/cpp/cpp_helpers.h>
-#include <google/protobuf/compiler/cpp/cpp_names.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/compiler/cpp/cpp_names.h>
namespace google {
namespace protobuf {
@@ -88,7 +88,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
variables_["nested_name"] = descriptor_->name();
variables_["resolved_name"] = ResolveKeyword(descriptor_->name());
variables_["prefix"] =
- (descriptor_->containing_type() == NULL) ? "" : classname_ + "_";
+ (descriptor_->containing_type() == nullptr) ? "" : classname_ + "_";
}
EnumGenerator::~EnumGenerator() {}
@@ -405,7 +405,7 @@ void EnumGenerator::GenerateMethods(int idx, io::Printer* printer) {
descriptor_->value_count());
}
- if (descriptor_->containing_type() != NULL) {
+ if (descriptor_->containing_type() != nullptr) {
TProtoStringType parent = ClassName(descriptor_->containing_type(), false);
// Before C++17, we must define the static constants which were
// declared in the header, to give the linker a place to put them.
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum.h
index 43f1e5f4a5c..652a26b6db8 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum.h
@@ -38,8 +38,9 @@
#include <map>
#include <set>
#include <string>
-#include <google/protobuf/compiler/cpp/cpp_options.h>
+
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
namespace google {
namespace protobuf {
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index 79fa488b5fc..f50fca4926a 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -33,10 +33,11 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
-#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
namespace google {
namespace protobuf {
@@ -53,6 +54,9 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
(*variables)["type"] = QualifiedClassName(descriptor->enum_type(), options);
(*variables)["default"] = Int32ToString(default_value->number());
(*variables)["full_name"] = descriptor->full_name();
+ (*variables)["cached_byte_size_name"] = MakeVarintCachedSizeName(descriptor);
+ (*variables)["cached_byte_size_field"] =
+ MakeVarintCachedSizeFieldName(descriptor);
}
} // namespace
@@ -90,7 +94,7 @@ void EnumFieldGenerator::GenerateInlineAccessorDefinitions(
Formatter format(printer, variables_);
format(
"inline $type$ $classname$::_internal_$name$() const {\n"
- " return static_cast< $type$ >($name$_);\n"
+ " return static_cast< $type$ >($field$);\n"
"}\n"
"inline $type$ $classname$::$name$() const {\n"
"$annotate_get$"
@@ -103,7 +107,7 @@ void EnumFieldGenerator::GenerateInlineAccessorDefinitions(
}
format(
" $set_hasbit$\n"
- " $name$_ = value;\n"
+ " $field$ = value;\n"
"}\n"
"inline void $classname$::set_$name$($type$ value) {\n"
" _internal_set_$name$(value);\n"
@@ -114,7 +118,7 @@ void EnumFieldGenerator::GenerateInlineAccessorDefinitions(
void EnumFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_ = $default$;\n");
+ format("$field$ = $default$;\n");
}
void EnumFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
@@ -124,18 +128,18 @@ void EnumFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
void EnumFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
Formatter format(printer, variables_);
- format("swap($name$_, other->$name$_);\n");
+ format("swap($field$, other->$field$);\n");
}
void EnumFieldGenerator::GenerateConstructorCode(io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_ = $default$;\n");
+ format("$field$ = $default$;\n");
}
void EnumFieldGenerator::GenerateCopyConstructorCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_ = from.$name$_;\n");
+ format("$field$ = from.$field$;\n");
}
void EnumFieldGenerator::GenerateSerializeWithCachedSizesToArray(
@@ -143,7 +147,7 @@ void EnumFieldGenerator::GenerateSerializeWithCachedSizesToArray(
Formatter format(printer, variables_);
format(
"target = stream->EnsureSpace(target);\n"
- "target = ::$proto_ns$::internal::WireFormatLite::WriteEnumToArray(\n"
+ "target = ::_pbi::WireFormatLite::WriteEnumToArray(\n"
" $number$, this->_internal_$name$(), target);\n");
}
@@ -151,9 +155,7 @@ void EnumFieldGenerator::GenerateByteSize(io::Printer* printer) const {
Formatter format(printer, variables_);
format(
"total_size += $tag_size$ +\n"
- " "
- "::$proto_ns$::internal::WireFormatLite::EnumSize(this->_internal_$name$("
- "));\n");
+ " ::_pbi::WireFormatLite::EnumSize(this->_internal_$name$());\n");
}
void EnumFieldGenerator::GenerateConstinitInitializer(
@@ -178,7 +180,7 @@ void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions(
format(
"inline $type$ $classname$::_internal_$name$() const {\n"
" if (_internal_has_$name$()) {\n"
- " return static_cast< $type$ >($field_member$);\n"
+ " return static_cast< $type$ >($field$);\n"
" }\n"
" return static_cast< $type$ >($default$);\n"
"}\n"
@@ -196,7 +198,7 @@ void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" clear_$oneof_name$();\n"
" set_has_$name$();\n"
" }\n"
- " $field_member$ = value;\n"
+ " $field$ = value;\n"
"}\n"
"inline void $classname$::set_$name$($type$ value) {\n"
" _internal_set_$name$(value);\n"
@@ -207,7 +209,7 @@ void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions(
void EnumOneofFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$field_member$ = $default$;\n");
+ format("$field$ = $default$;\n");
}
void EnumOneofFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
@@ -217,7 +219,7 @@ void EnumOneofFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
void EnumOneofFieldGenerator::GenerateConstructorCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$ns$::_$classname$_default_instance_.$name$_ = $default$;\n");
+ format("$ns$::_$classname$_default_instance_.$field$ = $default$;\n");
}
// ===================================================================
@@ -236,7 +238,7 @@ void RepeatedEnumFieldGenerator::GeneratePrivateMembers(
format("::$proto_ns$::RepeatedField<int> $name$_;\n");
if (descriptor_->is_packed() &&
HasGeneratedMethods(descriptor_->file(), options_)) {
- format("mutable std::atomic<int> _$name$_cached_byte_size_;\n");
+ format("mutable std::atomic<int> $cached_byte_size_name$;\n");
}
}
@@ -265,7 +267,7 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions(
Formatter format(printer, variables_);
format(
"inline $type$ $classname$::_internal_$name$(int index) const {\n"
- " return static_cast< $type$ >($name$_.Get(index));\n"
+ " return static_cast< $type$ >($field$.Get(index));\n"
"}\n"
"inline $type$ $classname$::$name$(int index) const {\n"
"$annotate_get$"
@@ -277,7 +279,7 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions(
format(" assert($type$_IsValid(value));\n");
}
format(
- " $name$_.Set(index, value);\n"
+ " $field$.Set(index, value);\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
@@ -286,7 +288,7 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions(
format(" assert($type$_IsValid(value));\n");
}
format(
- " $name$_.Add(value);\n"
+ " $field$.Add(value);\n"
"}\n"
"inline void $classname$::add_$name$($type$ value) {\n"
" _internal_add_$name$(value);\n"
@@ -297,11 +299,11 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions(
"$classname$::$name$() const {\n"
"$annotate_list$"
" // @@protoc_insertion_point(field_list:$full_name$)\n"
- " return $name$_;\n"
+ " return $field$;\n"
"}\n"
"inline ::$proto_ns$::RepeatedField<int>*\n"
"$classname$::_internal_mutable_$name$() {\n"
- " return &$name$_;\n"
+ " return &$field$;\n"
"}\n"
"inline ::$proto_ns$::RepeatedField<int>*\n"
"$classname$::mutable_$name$() {\n"
@@ -314,19 +316,19 @@ void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions(
void RepeatedEnumFieldGenerator::GenerateClearingCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_.Clear();\n");
+ format("$field$.Clear();\n");
}
void RepeatedEnumFieldGenerator::GenerateMergingCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_.MergeFrom(from.$name$_);\n");
+ format("$field$.MergeFrom(from.$field$);\n");
}
void RepeatedEnumFieldGenerator::GenerateSwappingCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_.InternalSwap(&other->$name$_);\n");
+ format("$field$.InternalSwap(&other->$field$);\n");
}
void RepeatedEnumFieldGenerator::GenerateConstructorCode(
@@ -342,17 +344,17 @@ void RepeatedEnumFieldGenerator::GenerateSerializeWithCachedSizesToArray(
format(
"{\n"
" int byte_size = "
- "_$name$_cached_byte_size_.load(std::memory_order_relaxed);\n"
+ "$cached_byte_size_field$.load(std::memory_order_relaxed);\n"
" if (byte_size > 0) {\n"
" target = stream->WriteEnumPacked(\n"
- " $number$, $name$_, byte_size, target);\n"
+ " $number$, $field$, byte_size, target);\n"
" }\n"
"}\n");
} else {
format(
"for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n"
" target = stream->EnsureSpace(target);\n"
- " target = ::$proto_ns$::internal::WireFormatLite::WriteEnumToArray(\n"
+ " target = ::_pbi::WireFormatLite::WriteEnumToArray(\n"
" $number$, this->_internal_$name$(i), target);\n"
"}\n");
}
@@ -368,7 +370,7 @@ void RepeatedEnumFieldGenerator::GenerateByteSize(io::Printer* printer) const {
format.Indent();
format(
"for (unsigned int i = 0; i < count; i++) {\n"
- " data_size += ::$proto_ns$::internal::WireFormatLite::EnumSize(\n"
+ " data_size += ::_pbi::WireFormatLite::EnumSize(\n"
" this->_internal_$name$(static_cast<int>(i)));\n"
"}\n");
@@ -376,11 +378,11 @@ void RepeatedEnumFieldGenerator::GenerateByteSize(io::Printer* printer) const {
format(
"if (data_size > 0) {\n"
" total_size += $tag_size$ +\n"
- " ::$proto_ns$::internal::WireFormatLite::Int32Size(\n"
- " static_cast<$int32$>(data_size));\n"
+ " "
+ "::_pbi::WireFormatLite::Int32Size(static_cast<$int32$>(data_size));\n"
"}\n"
- "int cached_size = ::$proto_ns$::internal::ToCachedSize(data_size);\n"
- "_$name$_cached_byte_size_.store(cached_size,\n"
+ "int cached_size = ::_pbi::ToCachedSize(data_size);\n"
+ "$cached_byte_size_field$.store(cached_size,\n"
" std::memory_order_relaxed);\n"
"total_size += data_size;\n");
} else {
@@ -396,7 +398,7 @@ void RepeatedEnumFieldGenerator::GenerateConstinitInitializer(
format("$name$_()");
if (descriptor_->is_packed() &&
HasGeneratedMethods(descriptor_->file(), options_)) {
- format("\n, _$name$_cached_byte_size_(0)");
+ format("\n, $cached_byte_size_name$(0)");
}
}
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum_field.h
index e65ec0f5c07..2a4ca5162bf 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum_field.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum_field.h
@@ -37,6 +37,7 @@
#include <map>
#include <string>
+
#include <google/protobuf/compiler/cpp/cpp_field.h>
namespace google {
@@ -47,7 +48,7 @@ namespace cpp {
class EnumFieldGenerator : public FieldGenerator {
public:
EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
- ~EnumFieldGenerator();
+ ~EnumFieldGenerator() override;
// implements FieldGenerator ---------------------------------------
void GeneratePrivateMembers(io::Printer* printer) const override;
@@ -71,7 +72,7 @@ class EnumOneofFieldGenerator : public EnumFieldGenerator {
public:
EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
- ~EnumOneofFieldGenerator();
+ ~EnumOneofFieldGenerator() override;
// implements FieldGenerator ---------------------------------------
void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
@@ -87,7 +88,7 @@ class RepeatedEnumFieldGenerator : public FieldGenerator {
public:
RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
- ~RepeatedEnumFieldGenerator();
+ ~RepeatedEnumFieldGenerator() override;
// implements FieldGenerator ---------------------------------------
void GeneratePrivateMembers(io::Printer* printer) const override;
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_extension.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_extension.cc
index 72893b81c94..ef6cc81241f 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_extension.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_extension.cc
@@ -33,11 +33,13 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/cpp_extension.h>
+
#include <map>
-#include <google/protobuf/compiler/cpp/cpp_helpers.h>
-#include <google/protobuf/descriptor.pb.h>
+
#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/descriptor.pb.h>
namespace google {
namespace protobuf {
@@ -76,6 +78,7 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
break;
}
SetCommonVars(options, &variables_);
+ SetCommonMessageDataVariables(&variables_);
variables_["extendee"] =
QualifiedClassName(descriptor_->containing_type(), options_);
variables_["type_traits"] = type_traits_;
@@ -91,6 +94,19 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
variables_["scope"] = scope;
variables_["scoped_name"] = ExtensionName(descriptor_);
variables_["number"] = StrCat(descriptor_->number());
+
+ bool add_verify_fn =
+ // Only verify msgs.
+ descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ // Options say to verify.
+ ShouldVerify(descriptor_->message_type(), options_, scc_analyzer_) &&
+ ShouldVerify(descriptor_->containing_type(), options_, scc_analyzer_);
+
+ variables_["verify_fn"] =
+ add_verify_fn
+ ? StrCat("&", FieldMessageTypeName(descriptor_, options_),
+ "::InternalVerify")
+ : "nullptr";
}
ExtensionGenerator::~ExtensionGenerator() {}
@@ -164,23 +180,11 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
}
format(
- "PROTOBUF_ATTRIBUTE_INIT_PRIORITY "
+ "PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 "
"::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n"
- " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n"
- " $scoped_name$($constant_name$, $1$);\n",
+ " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$>\n"
+ " $scoped_name$($constant_name$, $1$, $verify_fn$);\n",
default_str);
-
- // Register extension verify function if needed.
- if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
- ShouldVerify(descriptor_->message_type(), options_, scc_analyzer_) &&
- ShouldVerify(descriptor_->containing_type(), options_, scc_analyzer_)) {
- format(
- "PROTOBUF_ATTRIBUTE_INIT_PRIORITY "
- "::$proto_ns$::internal::RegisterExtensionVerify< $extendee$,\n"
- " $1$, $number$> $2$_$name$_register;\n",
- ClassName(descriptor_->message_type(), true),
- IsScoped() ? ClassName(descriptor_->extension_scope(), false) : "");
- }
}
} // namespace cpp
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_field.cc
index 5f167a4d019..895f094c701 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_field.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_field.cc
@@ -38,19 +38,19 @@
#include <memory>
#include <string>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
#include <google/protobuf/compiler/cpp/cpp_string_field.h>
-#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format.h>
#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
#include <google/protobuf/compiler/cpp/cpp_map_field.h>
#include <google/protobuf/compiler/cpp/cpp_message_field.h>
#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/io/printer.h>
-#include <google/protobuf/wire_format.h>
namespace google {
namespace protobuf {
@@ -81,7 +81,7 @@ TProtoStringType GenerateTemplateForOneofString(const FieldDescriptor* descripto
TProtoStringType field_name = google::protobuf::compiler::cpp::FieldName(descriptor);
TProtoStringType field_pointer =
descriptor->options().ctype() == google::protobuf::FieldOptions::STRING
- ? "$0.GetPointer()"
+ ? "$0.UnsafeGetPointer()"
: "$0";
if (descriptor->default_value_string().empty()) {
@@ -103,7 +103,7 @@ TProtoStringType GenerateTemplateForOneofString(const FieldDescriptor* descripto
return strings::Substitute(
StrCat("_internal_has_", field_name, "() ? ", field_pointer, " : ",
default_value_pointer),
- field_member, MakeDefaultName(descriptor));
+ field_member, MakeDefaultFieldName(descriptor));
}
TProtoStringType GenerateTemplateForSingleString(const FieldDescriptor* descriptor,
@@ -114,8 +114,8 @@ TProtoStringType GenerateTemplateForSingleString(const FieldDescriptor* descript
if (descriptor->options().ctype() == google::protobuf::FieldOptions::STRING) {
return strings::Substitute(
- "$0.IsDefault(nullptr) ? &$1.get() : $0.GetPointer()", field_member,
- MakeDefaultName(descriptor));
+ "$0.IsDefault() ? &$1.get() : $0.UnsafeGetPointer()", field_member,
+ MakeDefaultFieldName(descriptor));
}
return StrCat("&", field_member);
@@ -150,14 +150,12 @@ void AddAccessorAnnotations(const FieldDescriptor* descriptor,
google::protobuf::FileOptions::LITE_RUNTIME) {
return;
}
- TProtoStringType field_member = (*variables)["field_member"];
+ TProtoStringType field_member = (*variables)["field"];
const google::protobuf::OneofDescriptor* oneof_member =
descriptor->real_containing_oneof();
- if (oneof_member) {
- field_member = StrCat(oneof_member->name(), "_.", field_member);
- }
const TProtoStringType proto_ns = (*variables)["proto_ns"];
- const TProtoStringType substitute_template_prefix = " _tracker_.$1<$0>(this, ";
+ const TProtoStringType substitute_template_prefix =
+ StrCat(" ", (*variables)["tracker"], ".$1<$0>(this, ");
TProtoStringType prepared_template;
// Flat template is needed if the prepared one is introspecting the values
@@ -178,7 +176,7 @@ void AddAccessorAnnotations(const FieldDescriptor* descriptor,
} else if (descriptor->is_map()) {
prepared_template = "nullptr";
} else if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE &&
- !descriptor->options().lazy()) {
+ !IsExplicitLazy(descriptor)) {
prepared_template = "nullptr";
} else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
if (oneof_member) {
@@ -238,13 +236,15 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
std::map<TProtoStringType, TProtoStringType>* variables,
const Options& options) {
SetCommonVars(options, variables);
+ SetCommonMessageDataVariables(variables);
+
(*variables)["ns"] = Namespace(descriptor, options);
(*variables)["name"] = FieldName(descriptor);
(*variables)["index"] = StrCat(descriptor->index());
(*variables)["number"] = StrCat(descriptor->number());
(*variables)["classname"] = ClassName(FieldScope(descriptor), false);
(*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
- (*variables)["field_member"] = FieldName(descriptor) + "_";
+ (*variables)["field"] = FieldMemberName(descriptor);
(*variables)["tag_size"] = StrCat(
WireFormat::TagSize(descriptor->number(), descriptor->type()));
@@ -254,7 +254,8 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
(*variables)["clear_hasbit"] = "";
if (HasHasbit(descriptor)) {
(*variables)["set_hasbit_io"] =
- "_Internal::set_has_" + FieldName(descriptor) + "(&_has_bits_);";
+ StrCat("_Internal::set_has_", FieldName(descriptor), "(&",
+ (*variables)["has_bits"], ");");
} else {
(*variables)["set_hasbit_io"] = "";
}
@@ -275,10 +276,10 @@ void FieldGenerator::SetHasBitIndex(arc_i32 has_bit_index) {
return;
}
variables_["set_hasbit"] = StrCat(
- "_has_bits_[", has_bit_index / 32, "] |= 0x",
+ variables_["has_bits"], "[", has_bit_index / 32, "] |= 0x",
strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;");
variables_["clear_hasbit"] = StrCat(
- "_has_bits_[", has_bit_index / 32, "] &= ~0x",
+ variables_["has_bits"], "[", has_bit_index / 32, "] &= ~0x",
strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;");
}
@@ -287,12 +288,17 @@ void FieldGenerator::SetInlinedStringIndex(arc_i32 inlined_string_index) {
GOOGLE_CHECK_EQ(inlined_string_index, -1);
return;
}
+ // The first bit is the tracking bit for on demand registering ArenaDtor.
+ GOOGLE_CHECK_GT(inlined_string_index, 0)
+ << "_inlined_string_donated_'s bit 0 is reserved for arena dtor tracking";
variables_["inlined_string_donated"] = StrCat(
- "(_inlined_string_donated_[", inlined_string_index / 32, "] & 0x",
+ "(", variables_["inlined_string_donated_array"], "[",
+ inlined_string_index / 32, "] & 0x",
strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8),
"u) != 0;");
variables_["donating_states_word"] =
- StrCat("_inlined_string_donated_[", inlined_string_index / 32, "]");
+ StrCat(variables_["inlined_string_donated_array"], "[",
+ inlined_string_index / 32, "]");
variables_["mask_for_undonate"] = StrCat(
"~0x", strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8),
"u");
@@ -303,8 +309,6 @@ void SetCommonOneofFieldVariables(
std::map<TProtoStringType, TProtoStringType>* variables) {
const TProtoStringType prefix = descriptor->containing_oneof()->name() + "_.";
(*variables)["oneof_name"] = descriptor->containing_oneof()->name();
- (*variables)["field_member"] =
- StrCat(prefix, (*variables)["name"], "_");
}
FieldGenerator::~FieldGenerator() {}
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_field.h
index e3386f446a3..9c3ec7fde4b 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_field.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_field.h
@@ -40,9 +40,9 @@
#include <memory>
#include <string>
+#include <google/protobuf/descriptor.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/compiler/cpp/cpp_options.h>
-#include <google/protobuf/descriptor.h>
namespace google {
namespace protobuf {
@@ -158,11 +158,10 @@ class FieldGenerator {
// Generate a manual destructor invocation for use when the message is on an
// arena. The code that this method generates will be executed inside a
// shared-for-the-whole-message-class method registered with
- // OwnDestructor(). The method should return |true| if it generated any code
- // that requires a call; this allows the message generator to eliminate the
- // OwnDestructor() registration if no fields require it.
- virtual bool GenerateArenaDestructorCode(io::Printer* printer) const {
- return false;
+ // OwnDestructor().
+ virtual void GenerateArenaDestructorCode(io::Printer* printer) const {
+ GOOGLE_CHECK(NeedsArenaDestructor() == ArenaDtorNeeds::kNone)
+ << descriptor_->cpp_type_name();
}
// Generate initialization code for private members declared by
@@ -187,6 +186,10 @@ class FieldGenerator {
virtual bool IsInlined() const { return false; }
+ virtual ArenaDtorNeeds NeedsArenaDestructor() const {
+ return ArenaDtorNeeds::kNone;
+ }
+
void SetHasBitIndex(arc_i32 has_bit_index);
void SetInlinedStringIndex(arc_i32 inlined_string_index);
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_file.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_file.cc
index 2a98ad0b02c..f27d876e2ac 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -43,16 +43,16 @@
#include <unordered_set>
#include <vector>
+#include <google/protobuf/compiler/scc.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/compiler/cpp/cpp_enum.h>
#include <google/protobuf/compiler/cpp/cpp_extension.h>
#include <google/protobuf/compiler/cpp/cpp_field.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/compiler/cpp/cpp_message.h>
#include <google/protobuf/compiler/cpp/cpp_service.h>
-#include <google/protobuf/compiler/scc.h>
#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/io/printer.h>
-#include <google/protobuf/stubs/strutil.h>
// Must be last.
#include <google/protobuf/port_def.inc>
@@ -88,6 +88,23 @@ std::vector<const T*> Sorted(const std::unordered_set<const T*>& vals) {
return sorted;
}
+// TODO(b/203101078): remove pragmas that suppresses uninitialized warnings when
+// clang bug is fixed.
+inline void MuteWuninitialized(Formatter& format) {
+ format(
+ "#if defined(__llvm__)\n"
+ " #pragma clang diagnostic push\n"
+ " #pragma clang diagnostic ignored \"-Wuninitialized\"\n"
+ "#endif // __llvm__\n");
+}
+
+inline void UnmuteWuninitialized(Formatter& format) {
+ format(
+ "#if defined(__llvm__)\n"
+ " #pragma clang diagnostic pop\n"
+ "#endif // __llvm__\n");
+}
+
} // namespace
FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
@@ -347,7 +364,14 @@ void FileGenerator::DoIncludeFile(const TProtoStringType& google3_name,
options_.runtime_include_base, path);
}
} else {
- format("#include \"$1$\"", google3_name);
+ TProtoStringType path = google3_name;
+ // The bootstrapped proto generated code needs to use the
+ // third_party/protobuf header paths to avoid circular dependencies.
+ if (options_.bootstrap) {
+ path = StringReplace(google3_name, "net/proto2/public",
+ "third_party/protobuf", false);
+ }
+ format("#include \"$1$\"", path);
}
if (do_export) {
@@ -444,12 +468,28 @@ void FileGenerator::GenerateSourceIncludes(io::Printer* printer) {
format("// @@protoc_insertion_point(includes)\n");
IncludeFile("net/proto2/public/port_def.inc", printer);
+}
+
+void FileGenerator::GenerateSourcePrelude(io::Printer* printer) {
+ Formatter format(printer, variables_);
// For MSVC builds, we use #pragma init_seg to move the initialization of our
// libraries to happen before the user code.
// This worksaround the fact that MSVC does not do constant initializers when
// required by the standard.
format("\nPROTOBUF_PRAGMA_INIT_SEG\n");
+
+ // Generate convenience aliases.
+ format(
+ "\n"
+ "namespace _pb = ::$1$;\n"
+ "namespace _pbi = _pb::internal;\n",
+ ProtobufNamespace(options_));
+ if (HasGeneratedMethods(file_, options_) &&
+ options_.tctable_mode != Options::kTCTableNever) {
+ format("namespace _fl = _pbi::field_layout;\n");
+ }
+ format("\n");
}
void FileGenerator::GenerateSourceDefaultInstance(int idx,
@@ -462,8 +502,8 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx,
// destructor that we need to elide.
format(
"struct $1$ {\n"
- " constexpr $1$()\n"
- " : _instance(::$proto_ns$::internal::ConstantInitialized{}) {}\n"
+ " PROTOBUF_CONSTEXPR $1$()\n"
+ " : _instance(::_pbi::ConstantInitialized{}) {}\n"
" ~$1$() {}\n"
" union {\n"
" $2$ _instance;\n"
@@ -475,7 +515,8 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx,
// enough. However, the empty destructor fails to be elided in some
// configurations (like non-opt or with certain sanitizers). NO_DESTROY is
// there just to improve performance and binary size in these builds.
- format("PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT $1$ $2$;\n",
+ format("PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT "
+ "PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 $1$ $2$;\n",
DefaultInstanceType(generator->descriptor_, options_),
DefaultInstanceName(generator->descriptor_, options_));
@@ -484,19 +525,21 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx,
if (IsStringInlined(field, options_)) {
// Force the initialization of the inlined string in the default instance.
format(
- "PROTOBUF_ATTRIBUTE_INIT_PRIORITY std::true_type "
+ "PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 std::true_type "
"$1$::_init_inline_$2$_ = "
- "($3$._instance.$2$_.Init(), std::true_type{});\n",
+ "($3$._instance.$4$.Init(), std::true_type{});\n",
ClassName(generator->descriptor_), FieldName(field),
- DefaultInstanceName(generator->descriptor_, options_));
+ DefaultInstanceName(generator->descriptor_, options_),
+ FieldMemberName(field));
}
}
if (options_.lite_implicit_weak_fields) {
- format("$1$* $2$ = &$3$;\n",
- DefaultInstanceType(generator->descriptor_, options_),
- DefaultInstancePtr(generator->descriptor_, options_),
- DefaultInstanceName(generator->descriptor_, options_));
+ format(
+ "PROTOBUF_CONSTINIT const void* $1$ =\n"
+ " &$2$;\n",
+ DefaultInstancePtr(generator->descriptor_, options_),
+ DefaultInstanceName(generator->descriptor_, options_));
}
}
@@ -550,11 +593,10 @@ void FileGenerator::GenerateInternalForwardDeclarations(
for (auto instance : Sorted(refs.weak_default_instances)) {
ns.ChangeTo(Namespace(instance, options_));
if (options_.lite_implicit_weak_fields) {
- format("extern $1$ $2$;\n", DefaultInstanceType(instance, options_),
- DefaultInstanceName(instance, options_));
- format("__attribute__((weak)) $1$* $2$ = nullptr;\n",
- DefaultInstanceType(instance, options_),
- DefaultInstancePtr(instance, options_));
+ format(
+ "PROTOBUF_CONSTINIT __attribute__((weak)) const void* $1$ =\n"
+ " &::_pbi::implicit_weak_message_default_instance;\n",
+ DefaultInstancePtr(instance, options_));
} else {
format("extern __attribute__((weak)) $1$ $2$;\n",
DefaultInstanceType(instance, options_),
@@ -565,8 +607,7 @@ void FileGenerator::GenerateInternalForwardDeclarations(
for (auto file : Sorted(refs.weak_reflection_files)) {
format(
- "extern __attribute__((weak)) const "
- "::$proto_ns$::internal::DescriptorTable $1$;\n",
+ "extern __attribute__((weak)) const ::_pbi::DescriptorTable $1$;\n",
DescriptorTableName(file, options_));
}
}
@@ -574,6 +615,9 @@ void FileGenerator::GenerateInternalForwardDeclarations(
void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) {
Formatter format(printer, variables_);
GenerateSourceIncludes(printer);
+ GenerateSourcePrelude(printer);
+
+ if (IsAnyMessage(file_, options_)) MuteWuninitialized(format);
CrossFileReferences refs;
ForEachField(message_generators_[idx]->descriptor_,
@@ -602,6 +646,8 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) {
message_generators_[idx]->GenerateSourceInProto2Namespace(printer);
}
+ if (IsAnyMessage(file_, options_)) UnmuteWuninitialized(format);
+
format(
"\n"
"// @@protoc_insertion_point(global_scope)\n");
@@ -610,6 +656,7 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) {
void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* printer) {
Formatter format(printer, variables_);
GenerateSourceIncludes(printer);
+ GenerateSourcePrelude(printer);
NamespaceOpener ns(Namespace(file_, options_), format);
extension_generators_[idx]->GenerateDefinition(printer);
}
@@ -617,10 +664,9 @@ void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* printer) {
void FileGenerator::GenerateGlobalSource(io::Printer* printer) {
Formatter format(printer, variables_);
GenerateSourceIncludes(printer);
+ GenerateSourcePrelude(printer);
{
- GenerateTables(printer);
-
// Define the code to initialize reflection. This code uses a global
// constructor to register reflection data with the runtime pre-main.
if (HasDescriptorMethods(file_, options_)) {
@@ -639,10 +685,13 @@ void FileGenerator::GenerateGlobalSource(io::Printer* printer) {
void FileGenerator::GenerateSource(io::Printer* printer) {
Formatter format(printer, variables_);
GenerateSourceIncludes(printer);
+ GenerateSourcePrelude(printer);
CrossFileReferences refs;
GetCrossFileReferencesForFile(file_, &refs);
GenerateInternalForwardDeclarations(refs, printer);
+ if (IsAnyMessage(file_, options_)) MuteWuninitialized(format);
+
{
NamespaceOpener ns(Namespace(file_, options_), format);
@@ -653,8 +702,6 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
}
{
- GenerateTables(printer);
-
if (HasDescriptorMethods(file_, options_)) {
// Define the code to initialize reflection. This code uses a global
// constructor to register reflection data with the runtime pre-main.
@@ -711,6 +758,8 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
"\n"
"// @@protoc_insertion_point(global_scope)\n");
+ if (IsAnyMessage(file_, options_)) UnmuteWuninitialized(format);
+
IncludeFile("net/proto2/public/port_undef.inc", printer);
}
@@ -718,31 +767,30 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
Formatter format(printer, variables_);
if (!message_generators_.empty()) {
- format("static ::$proto_ns$::Metadata $file_level_metadata$[$1$];\n",
+ format("static ::_pb::Metadata $file_level_metadata$[$1$];\n",
message_generators_.size());
}
if (!enum_generators_.empty()) {
format(
- "static "
- "const ::$proto_ns$::EnumDescriptor* "
+ "static const ::_pb::EnumDescriptor* "
"$file_level_enum_descriptors$[$1$];\n",
enum_generators_.size());
} else {
format(
"static "
- "constexpr ::$proto_ns$::EnumDescriptor const** "
+ "constexpr ::_pb::EnumDescriptor const** "
"$file_level_enum_descriptors$ = nullptr;\n");
}
if (HasGenericServices(file_, options_) && file_->service_count() > 0) {
format(
"static "
- "const ::$proto_ns$::ServiceDescriptor* "
+ "const ::_pb::ServiceDescriptor* "
"$file_level_service_descriptors$[$1$];\n",
file_->service_count());
} else {
format(
"static "
- "constexpr ::$proto_ns$::ServiceDescriptor const** "
+ "constexpr ::_pb::ServiceDescriptor const** "
"$file_level_service_descriptors$ = nullptr;\n");
}
@@ -760,7 +808,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
format.Outdent();
format(
"};\n"
- "static const ::$proto_ns$::internal::MigrationSchema schemas[] "
+ "static const ::_pbi::MigrationSchema schemas[] "
"PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
format.Indent();
{
@@ -774,16 +822,13 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
format.Outdent();
format(
"};\n"
- "\nstatic "
- "::$proto_ns$::Message const * const file_default_instances[] = {\n");
+ "\nstatic const ::_pb::Message* const file_default_instances[] = {\n");
format.Indent();
for (int i = 0; i < message_generators_.size(); i++) {
const Descriptor* descriptor = message_generators_[i]->descriptor_;
- format(
- "reinterpret_cast<const "
- "::$proto_ns$::Message*>(&$1$::_$2$_default_instance_),\n",
- Namespace(descriptor, options_), // 1
- ClassName(descriptor)); // 2
+ format("&$1$::_$2$_default_instance_._instance,\n",
+ Namespace(descriptor, options_), // 1
+ ClassName(descriptor)); // 2
}
format.Outdent();
format(
@@ -794,10 +839,8 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
format(
// MSVC doesn't like empty arrays, so we add a dummy.
"const $uint32$ $tablename$::offsets[1] = {};\n"
- "static constexpr ::$proto_ns$::internal::MigrationSchema* schemas = "
- "nullptr;"
- "\n"
- "static constexpr ::$proto_ns$::Message* const* "
+ "static constexpr ::_pbi::MigrationSchema* schemas = nullptr;\n"
+ "static constexpr ::_pb::Message* const* "
"file_default_instances = nullptr;\n"
"\n");
}
@@ -852,7 +895,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
// Build array of DescriptorTable deps.
if (num_deps > 0) {
format(
- "static const ::$proto_ns$::internal::DescriptorTable*const "
+ "static const ::_pbi::DescriptorTable* const "
"$desc_table$_deps[$1$] = {\n",
num_deps);
@@ -872,13 +915,14 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
// so disable for now.
bool eager = false;
format(
- "static ::$proto_ns$::internal::once_flag $desc_table$_once;\n"
- "const ::$proto_ns$::internal::DescriptorTable $desc_table$ = {\n"
- " false, $1$, $2$, $3$, \"$filename$\", \n"
- " &$desc_table$_once, $4$, $5$, $6$,\n"
- " schemas, file_default_instances, $tablename$::offsets,\n"
- " $7$, $file_level_enum_descriptors$, "
- "$file_level_service_descriptors$,\n"
+ "static ::_pbi::once_flag $desc_table$_once;\n"
+ "const ::_pbi::DescriptorTable $desc_table$ = {\n"
+ " false, $1$, $2$, $3$,\n"
+ " \"$filename$\",\n"
+ " &$desc_table$_once, $4$, $5$, $6$,\n"
+ " schemas, file_default_instances, $tablename$::offsets,\n"
+ " $7$, $file_level_enum_descriptors$,\n"
+ " $file_level_service_descriptors$,\n"
"};\n"
// This function exists to be marked as weak.
// It can significantly speed up compilation by breaking up LLVM's SCC in
@@ -891,7 +935,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
// vtables -> GetMetadata
// By adding a weak function here we break the connection from the
// individual vtables back into the descriptor table.
- "PROTOBUF_ATTRIBUTE_WEAK const ::$proto_ns$::internal::DescriptorTable* "
+ "PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* "
"$desc_table$_getter() {\n"
" return &$desc_table$;\n"
"}\n"
@@ -909,123 +953,12 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
if (file_->name() != "net/proto2/proto/descriptor.proto") {
format(
"// Force running AddDescriptors() at dynamic initialization time.\n"
- "PROTOBUF_ATTRIBUTE_INIT_PRIORITY "
- "static ::$proto_ns$::internal::AddDescriptorsRunner "
- "$1$(&$desc_table$);\n",
+ "PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 "
+ "static ::_pbi::AddDescriptorsRunner $1$(&$desc_table$);\n",
UniqueName("dynamic_init_dummy", file_, options_));
}
}
-void FileGenerator::GenerateTables(io::Printer* printer) {
- Formatter format(printer, variables_);
- if (options_.table_driven_parsing) {
- // TODO(ckennelly): Gate this with the same options flag to enable
- // table-driven parsing.
- format(
- "PROTOBUF_CONSTEXPR_VAR ::$proto_ns$::internal::ParseTableField\n"
- " const $tablename$::entries[] "
- "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
- format.Indent();
-
- std::vector<size_t> entries;
- size_t count = 0;
- for (int i = 0; i < message_generators_.size(); i++) {
- size_t value = message_generators_[i]->GenerateParseOffsets(printer);
- entries.push_back(value);
- count += value;
- }
-
- // We need these arrays to exist, and MSVC does not like empty arrays.
- if (count == 0) {
- format("{0, 0, 0, ::$proto_ns$::internal::kInvalidMask, 0, 0},\n");
- }
-
- format.Outdent();
- format(
- "};\n"
- "\n"
- "PROTOBUF_CONSTEXPR_VAR "
- "::$proto_ns$::internal::AuxiliaryParseTableField\n"
- " const $tablename$::aux[] "
- "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
- format.Indent();
-
- std::vector<size_t> aux_entries;
- count = 0;
- for (int i = 0; i < message_generators_.size(); i++) {
- size_t value = message_generators_[i]->GenerateParseAuxTable(printer);
- aux_entries.push_back(value);
- count += value;
- }
-
- if (count == 0) {
- format("::$proto_ns$::internal::AuxiliaryParseTableField(),\n");
- }
-
- format.Outdent();
- format(
- "};\n"
- "PROTOBUF_CONSTEXPR_VAR ::$proto_ns$::internal::ParseTable const\n"
- " $tablename$::schema[] "
- "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
- format.Indent();
-
- size_t offset = 0;
- size_t aux_offset = 0;
- for (int i = 0; i < message_generators_.size(); i++) {
- message_generators_[i]->GenerateParseTable(printer, offset, aux_offset);
- offset += entries[i];
- aux_offset += aux_entries[i];
- }
-
- if (message_generators_.empty()) {
- format("{ nullptr, nullptr, 0, -1, -1, false },\n");
- }
-
- format.Outdent();
- format(
- "};\n"
- "\n");
- }
-
- if (!message_generators_.empty() && options_.table_driven_serialization) {
- format(
- "const ::$proto_ns$::internal::FieldMetadata "
- "$tablename$::field_metadata[] "
- "= {\n");
- format.Indent();
- std::vector<int> field_metadata_offsets;
- int idx = 0;
- for (int i = 0; i < message_generators_.size(); i++) {
- field_metadata_offsets.push_back(idx);
- idx += message_generators_[i]->GenerateFieldMetadata(printer);
- }
- field_metadata_offsets.push_back(idx);
- format.Outdent();
- format(
- "};\n"
- "const ::$proto_ns$::internal::SerializationTable "
- "$tablename$::serialization_table[] = {\n");
- format.Indent();
- // We rely on the order we layout the tables to match the order we
- // calculate them with FlattenMessagesInFile, so we check here that
- // these match exactly.
- std::vector<const Descriptor*> calculated_order =
- FlattenMessagesInFile(file_);
- GOOGLE_CHECK_EQ(calculated_order.size(), message_generators_.size());
- for (int i = 0; i < message_generators_.size(); i++) {
- GOOGLE_CHECK_EQ(calculated_order[i], message_generators_[i]->descriptor_);
- format("{$1$, $tablename$::field_metadata + $2$},\n",
- field_metadata_offsets[i + 1] - field_metadata_offsets[i], // 1
- field_metadata_offsets[i]); // 2
- }
- format.Outdent();
- format(
- "};\n"
- "\n");
- }
-}
-
class FileGenerator::ForwardDeclarations {
public:
void AddMessage(const Descriptor* d) { classes_[ClassName(d)] = d; }
@@ -1229,7 +1162,6 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
if (HasSimpleBaseClasses(file_, options_)) {
IncludeFile("net/proto2/public/generated_message_bases.h", printer);
}
- IncludeFile("net/proto2/public/generated_message_table_driven.h", printer);
if (HasGeneratedMethods(file_, options_) &&
options_.tctable_mode != Options::kTCTableNever) {
IncludeFile("net/proto2/public/generated_message_tctable_decl.h", printer);
@@ -1362,20 +1294,8 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations(
"\n"
"// Internal implementation detail -- do not use these members.\n"
"struct $dllexport_decl $$tablename$ {\n"
- // These tables describe how to serialize and parse messages. Used
- // for table driven code.
- " static const ::$proto_ns$::internal::ParseTableField entries[]\n"
- " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n"
- " static const ::$proto_ns$::internal::AuxiliaryParseTableField aux[]\n"
- " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n"
- " static const ::$proto_ns$::internal::ParseTable schema[$1$]\n"
- " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n"
- " static const ::$proto_ns$::internal::FieldMetadata field_metadata[];\n"
- " static const ::$proto_ns$::internal::SerializationTable "
- "serialization_table[];\n"
" static const $uint32$ offsets[];\n"
- "};\n",
- std::max(size_t(1), message_generators_.size()));
+ "};\n");
if (HasDescriptorMethods(file_, options_)) {
format(
"$dllexport_decl $extern const ::$proto_ns$::internal::DescriptorTable "
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_file.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_file.h
index 041d5ea4aba..d8eff2feedb 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_file.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_file.h
@@ -40,11 +40,12 @@
#include <set>
#include <string>
#include <vector>
+
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/cpp/cpp_field.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
-#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/compiler/scc.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
namespace google {
namespace protobuf {
@@ -123,11 +124,11 @@ class FileGenerator {
void GenerateInternalForwardDeclarations(const CrossFileReferences& refs,
io::Printer* printer);
void GenerateSourceIncludes(io::Printer* printer);
+ void GenerateSourcePrelude(io::Printer* printer);
void GenerateSourceDefaultInstance(int idx, io::Printer* printer);
void GenerateInitForSCC(const SCC* scc, const CrossFileReferences& refs,
io::Printer* printer);
- void GenerateTables(io::Printer* printer);
void GenerateReflectionInitializationCode(io::Printer* printer);
// For other imports, generates their forward-declarations.
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_generator.cc
index 3673c09a617..69443f5bf2f 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_generator.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -40,11 +40,11 @@
#include <vector>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/compiler/cpp/cpp_file.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/io/printer.h>
-#include <google/protobuf/io/zero_copy_stream.h>
namespace google {
namespace protobuf {
@@ -82,6 +82,12 @@ bool CppGenerator::Generate(const FileDescriptor* file,
// FOO_EXPORT is a macro which should expand to __declspec(dllexport) or
// __declspec(dllimport) depending on what is being compiled.
//
+ // If the proto_h option is passed to the compiler, we will generate all
+ // classes and enums so that they can be forward-declared from files that
+ // need them from imports.
+ //
+ // If the lite option is passed to the compiler, we will generate the
+ // current files and all transitive dependencies using the LITE runtime.
Options file_options;
file_options.opensource_runtime = opensource_runtime_;
@@ -109,8 +115,10 @@ bool CppGenerator::Generate(const FileDescriptor* file,
file_options.lite_implicit_weak_fields = true;
if (!options[i].second.empty()) {
file_options.num_cc_files =
- strto32(options[i].second.c_str(), NULL, 10);
+ strto32(options[i].second.c_str(), nullptr, 10);
}
+ } else if (options[i].first == "proto_h") {
+ file_options.proto_h = true;
} else if (options[i].first == "annotate_accessor") {
file_options.annotate_accessor = true;
} else if (options[i].first == "inject_field_listener_events") {
@@ -127,14 +135,14 @@ bool CppGenerator::Generate(const FileDescriptor* file,
.insert(options[i].second.substr(pos, next_pos - pos));
pos = next_pos + 1;
} while (pos < options[i].second.size());
+ } else if (options[i].first == "verified_lazy_message_sets") {
+ file_options.unverified_lazy_message_sets = false;
+ } else if (options[i].first == "unverified_lazy_message_sets") {
+ file_options.unverified_lazy_message_sets = true;
} else if (options[i].first == "eagerly_verified_lazy") {
file_options.eagerly_verified_lazy = true;
} else if (options[i].first == "force_eagerly_verified_lazy") {
file_options.force_eagerly_verified_lazy = true;
- } else if (options[i].first == "table_driven_parsing") {
- file_options.table_driven_parsing = true;
- } else if (options[i].first == "table_driven_serialization") {
- file_options.table_driven_serialization = true;
} else if (options[i].first == "experimental_tail_call_table_mode") {
if (options[i].second == "never") {
file_options.tctable_mode = Options::kTCTableNever;
@@ -185,7 +193,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
TProtoStringType info_path = basename + ".proto.h.meta";
io::Printer printer(
output.get(), '$',
- file_options.annotate_headers ? &annotation_collector : NULL);
+ file_options.annotate_headers ? &annotation_collector : nullptr);
file_generator.GenerateProtoHeader(
&printer, file_options.annotate_headers ? info_path : "");
if (file_options.annotate_headers) {
@@ -204,7 +212,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
TProtoStringType info_path = basename + ".pb.h.meta";
io::Printer printer(
output.get(), '$',
- file_options.annotate_headers ? &annotation_collector : NULL);
+ file_options.annotate_headers ? &annotation_collector : nullptr);
file_generator.GeneratePBHeader(
&printer, file_options.annotate_headers ? info_path : "");
if (file_options.annotate_headers) {
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_generator.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_generator.h
index 235d02325f0..aa63845d300 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_generator.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_generator.h
@@ -40,6 +40,7 @@
#include <string>
#include <google/protobuf/compiler/code_generator.h>
+// Must be included last.
#include <google/protobuf/port_def.inc>
namespace google {
@@ -54,7 +55,7 @@ namespace cpp {
class PROTOC_EXPORT CppGenerator : public CodeGenerator {
public:
CppGenerator();
- ~CppGenerator();
+ ~CppGenerator() override;
enum class Runtime {
kGoogle3, // Use the internal google3 runtime.
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index 5191a7e7309..f726d0fc9b5 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -44,10 +44,10 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/compiler/cpp/cpp_options.h>
+#include <google/protobuf/descriptor.h>
#include <google/protobuf/compiler/cpp/cpp_names.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/descriptor.h>
#include <google/protobuf/compiler/scc.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
@@ -233,6 +233,18 @@ void SetCommonVars(const Options& options,
(*variables)["string"] = "TProtoStringType";
}
+void SetCommonMessageDataVariables(
+ std::map<TProtoStringType, TProtoStringType>* variables) {
+ (*variables)["any_metadata"] = "_any_metadata_";
+ (*variables)["cached_size"] = "_cached_size_";
+ (*variables)["extensions"] = "_extensions_";
+ (*variables)["has_bits"] = "_has_bits_";
+ (*variables)["inlined_string_donated_array"] = "_inlined_string_donated_";
+ (*variables)["oneof_case"] = "_oneof_case_";
+ (*variables)["tracker"] = "_tracker_";
+ (*variables)["weak_field_map"] = "_weak_field_map_";
+}
+
void SetUnknownFieldsVariable(const Descriptor* descriptor,
const Options& options,
std::map<TProtoStringType, TProtoStringType>* variables) {
@@ -457,6 +469,14 @@ TProtoStringType FieldName(const FieldDescriptor* field) {
return result;
}
+TProtoStringType FieldMemberName(const FieldDescriptor* field) {
+ if (field->real_containing_oneof() == nullptr) {
+ return StrCat(FieldName(field), "_");
+ }
+ return StrCat(field->containing_oneof()->name(), "_.", FieldName(field),
+ "_");
+}
+
TProtoStringType OneofCaseConstantName(const FieldDescriptor* field) {
GOOGLE_DCHECK(field->containing_oneof());
TProtoStringType field_name = UnderscoresToCamelCase(field->name(), true);
@@ -1151,7 +1171,6 @@ bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
return UsingImplicitWeakFields(field->file(), options) &&
field->type() == FieldDescriptor::TYPE_MESSAGE &&
!field->is_required() && !field->is_map() && !field->is_extension() &&
- !field->real_containing_oneof() &&
!IsWellKnownMessage(field->message_type()->file()) &&
field->message_type()->file()->name() !=
"net/proto2/proto/descriptor.proto" &&
@@ -1268,7 +1287,7 @@ bool GetBootstrapBasename(const Options& options, const TProtoStringType& basena
std::unordered_map<TProtoStringType, TProtoStringType> bootstrap_mapping{
{"net/proto2/proto/descriptor",
- "net/proto2/internal/descriptor"},
+ "third_party/protobuf/descriptor"},
{"net/proto2/compiler/proto/plugin",
"net/proto2/compiler/proto/plugin"},
{"net/proto2/compiler/proto/profile",
@@ -1301,7 +1320,7 @@ bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context,
*basename = bootstrap_basename;
return false;
} else {
- TProtoStringType forward_to_basename = bootstrap_basename;
+ const TProtoStringType& forward_to_basename = bootstrap_basename;
// Generate forwarding headers and empty .pb.cc.
{
@@ -1490,8 +1509,9 @@ FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
return FileOptions::SPEED;
}
-bool EnableMessageOwnedArena(const Descriptor* desc) {
+bool EnableMessageOwnedArena(const Descriptor* desc, const Options& options) {
(void)desc;
+ (void)options;
return false;
}
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_helpers.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_helpers.h
index ceb9a54f389..f7735da12f0 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -41,10 +41,10 @@
#include <map>
#include <string>
-#include <google/protobuf/compiler/cpp/cpp_options.h>
-#include <google/protobuf/compiler/cpp/cpp_names.h>
#include <google/protobuf/compiler/scc.h>
#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/compiler/cpp/cpp_names.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.h>
@@ -59,6 +59,8 @@ namespace protobuf {
namespace compiler {
namespace cpp {
+enum class ArenaDtorNeeds { kNone = 0, kOnDemand = 1, kRequired = 2 };
+
inline TProtoStringType ProtobufNamespace(const Options& /* options */) {
return "PROTOBUF_NAMESPACE_ID";
}
@@ -85,6 +87,10 @@ extern const char kThinSeparator[];
void SetCommonVars(const Options& options,
std::map<TProtoStringType, TProtoStringType>* variables);
+// Variables to access message data from the message scope.
+void SetCommonMessageDataVariables(
+ std::map<TProtoStringType, TProtoStringType>* variables);
+
void SetUnknownFieldsVariable(const Descriptor* descriptor,
const Options& options,
std::map<TProtoStringType, TProtoStringType>* variables);
@@ -186,6 +192,9 @@ TProtoStringType ResolveKeyword(const TProtoStringType& name);
// anyway, so normally this just returns field->name().
TProtoStringType FieldName(const FieldDescriptor* field);
+// Returns the (unqualified) private member name for this field in C++ code.
+TProtoStringType FieldMemberName(const FieldDescriptor* field);
+
// Returns an estimate of the compiler's alignment for the field. This
// can't guarantee to be correct because the generated code could be compiled on
// different systems with different alignment rules. The estimates below assume
@@ -348,9 +357,16 @@ bool HasLazyFields(const FileDescriptor* file, const Options& options,
bool IsLazy(const FieldDescriptor* field, const Options& options,
MessageSCCAnalyzer* scc_analyzer);
+// Is this an explicit (non-profile driven) lazy field, as denoted by
+// lazy/unverified_lazy in the descriptor?
+inline bool IsExplicitLazy(const FieldDescriptor* field) {
+ return field->options().lazy() || field->options().unverified_lazy();
+}
+
inline bool IsLazilyVerifiedLazy(const FieldDescriptor* field,
const Options& options) {
- return field->options().lazy() && !field->is_repeated() &&
+ // TODO(b/211906113): Make lazy() imply eagerly verified lazy.
+ return IsExplicitLazy(field) && !field->is_repeated() &&
field->type() == FieldDescriptor::TYPE_MESSAGE &&
GetOptimizeFor(field->file(), options) != FileOptions::LITE_RUNTIME &&
!options.opensource_runtime;
@@ -359,7 +375,8 @@ inline bool IsLazilyVerifiedLazy(const FieldDescriptor* field,
inline bool IsEagerlyVerifiedLazy(const FieldDescriptor* field,
const Options& options,
MessageSCCAnalyzer* scc_analyzer) {
- return IsLazy(field, options, scc_analyzer) && !field->options().lazy();
+ // TODO(b/211906113): Make lazy() imply eagerly verified lazy.
+ return IsLazy(field, options, scc_analyzer) && !IsExplicitLazy(field);
}
inline bool IsFieldUsed(const FieldDescriptor* /* field */,
@@ -472,6 +489,43 @@ inline TProtoStringType MakeDefaultName(const FieldDescriptor* field) {
"_";
}
+// Semantically distinct from MakeDefaultName in that it gives the C++ code
+// referencing a default field from the message scope, rather than just the
+// variable name.
+// For example, declarations of default variables should always use just
+// MakeDefaultName to produce code like:
+// Type _i_give_permission_to_break_this_code_default_field_;
+//
+// Code that references these should use MakeDefaultFieldName, in case the field
+// exists at some nested level like:
+// internal_container_._i_give_permission_to_break_this_code_default_field_;
+inline TProtoStringType MakeDefaultFieldName(const FieldDescriptor* field) {
+ return MakeDefaultName(field);
+}
+
+inline TProtoStringType MakeVarintCachedSizeName(const FieldDescriptor* field) {
+ return StrCat("_", FieldName(field), "_cached_byte_size_");
+}
+
+// Semantically distinct from MakeVarintCachedSizeName in that it gives the C++
+// code referencing the object from the message scope, rather than just the
+// variable name.
+// For example, declarations of default variables should always use just
+// MakeVarintCachedSizeName to produce code like:
+// Type _field_cached_byte_size_;
+//
+// Code that references these variables should use
+// MakeVarintCachedSizeFieldName, in case the field exists at some nested level
+// like:
+// internal_container_._field_cached_byte_size_;
+inline TProtoStringType MakeVarintCachedSizeFieldName(const FieldDescriptor* field) {
+ return StrCat("_", FieldName(field), "_cached_byte_size_");
+}
+
+// Note: A lot of libraries detect Any protos based on Descriptor::full_name()
+// while the two functions below use FileDescriptor::name(). In a sane world the
+// two approaches should be equivalent. But if you are dealing with descriptors
+// from untrusted sources, you might need to match semantics across libraries.
bool IsAnyMessage(const FileDescriptor* descriptor, const Options& options);
bool IsAnyMessage(const Descriptor* descriptor, const Options& options);
@@ -956,7 +1010,7 @@ inline OneOfRangeImpl OneOfRange(const Descriptor* desc) { return {desc}; }
PROTOC_EXPORT TProtoStringType StripProto(const TProtoStringType& filename);
-bool EnableMessageOwnedArena(const Descriptor* desc);
+bool EnableMessageOwnedArena(const Descriptor* desc, const Options& options);
bool ShouldVerify(const Descriptor* descriptor, const Options& options,
MessageSCCAnalyzer* scc_analyzer);
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_map_field.cc
index c5028fdb1d2..4d3e00ac89b 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_map_field.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_map_field.cc
@@ -30,10 +30,10 @@
#include <google/protobuf/compiler/cpp/cpp_map_field.h>
-#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
namespace google {
@@ -53,10 +53,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
(*variables)["type"] = ClassName(descriptor->message_type(), false);
(*variables)["full_name"] = descriptor->full_name();
- const FieldDescriptor* key =
- descriptor->message_type()->FindFieldByName("key");
- const FieldDescriptor* val =
- descriptor->message_type()->FindFieldByName("value");
+ const FieldDescriptor* key = descriptor->message_type()->map_key();
+ const FieldDescriptor* val = descriptor->message_type()->map_value();
(*variables)["key_cpp"] = PrimitiveTypeName(options, key->cpp_type());
switch (val->cpp_type()) {
case FieldDescriptor::CPPTYPE_MESSAGE:
@@ -128,7 +126,7 @@ void MapFieldGenerator::GenerateInlineAccessorDefinitions(
format(
"inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
"$classname$::_internal_$name$() const {\n"
- " return $name$_.GetMap();\n"
+ " return $field$.GetMap();\n"
"}\n"
"inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
"$classname$::$name$() const {\n"
@@ -138,7 +136,7 @@ void MapFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n"
"inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
"$classname$::_internal_mutable_$name$() {\n"
- " return $name$_.MutableMap();\n"
+ " return $field$.MutableMap();\n"
"}\n"
"inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
"$classname$::mutable_$name$() {\n"
@@ -150,17 +148,17 @@ void MapFieldGenerator::GenerateInlineAccessorDefinitions(
void MapFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_.Clear();\n");
+ format("$field$.Clear();\n");
}
void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_.MergeFrom(from.$name$_);\n");
+ format("$field$.MergeFrom(from.$field$);\n");
}
void MapFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_.InternalSwap(&other->$name$_);\n");
+ format("$field$.InternalSwap(&other->$field$);\n");
}
void MapFieldGenerator::GenerateCopyConstructorCode(
@@ -169,35 +167,27 @@ void MapFieldGenerator::GenerateCopyConstructorCode(
GenerateMergingCode(printer);
}
-static void GenerateSerializationLoop(const Formatter& format, bool string_key,
+static void GenerateSerializationLoop(Formatter& format, bool string_key,
bool string_value,
bool is_deterministic) {
- TProtoStringType ptr;
if (is_deterministic) {
- format("for (size_type i = 0; i < n; i++) {\n");
- ptr = string_key ? "items[static_cast<ptrdiff_t>(i)]"
- : "items[static_cast<ptrdiff_t>(i)].second";
- } else {
format(
- "for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
- " it = this->_internal_$name$().begin();\n"
- " it != this->_internal_$name$().end(); ++it) {\n");
- ptr = "it";
+ "for (const auto& entry : "
+ "::_pbi::MapSorter$1$<MapType>(map_field)) {\n",
+ (string_key ? "Ptr" : "Flat"));
+ } else {
+ format("for (const auto& entry : map_field) {\n");
}
- format.Indent();
+ {
+ auto loop_scope = format.ScopedIndent();
+ format(
+ "target = WireHelper::InternalSerialize($number$, "
+ "entry.first, entry.second, target, stream);\n");
- format(
- "target = $map_classname$::Funcs::InternalSerialize($number$, "
- "$1$->first, $1$->second, target, stream);\n",
- ptr);
-
- if (string_key || string_value) {
- // ptr is either an actual pointer or an iterator, either way we can
- // create a pointer by taking the address after de-referencing it.
- format("Utf8Check::Check(&(*$1$));\n", ptr);
+ if (string_key || string_value) {
+ format("check_utf8(entry);\n");
+ }
}
-
- format.Outdent();
format("}\n");
}
@@ -206,77 +196,53 @@ void MapFieldGenerator::GenerateSerializeWithCachedSizesToArray(
Formatter format(printer, variables_);
format("if (!this->_internal_$name$().empty()) {\n");
format.Indent();
- const FieldDescriptor* key_field =
- descriptor_->message_type()->FindFieldByName("key");
- const FieldDescriptor* value_field =
- descriptor_->message_type()->FindFieldByName("value");
+ const FieldDescriptor* key_field = descriptor_->message_type()->map_key();
+ const FieldDescriptor* value_field = descriptor_->message_type()->map_value();
const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING;
const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING;
format(
- "typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_pointer\n"
- " ConstPtr;\n");
- if (string_key) {
- format(
- "typedef ConstPtr SortItem;\n"
- "typedef ::$proto_ns$::internal::"
- "CompareByDerefFirst<SortItem> Less;\n");
- } else {
- format(
- "typedef ::$proto_ns$::internal::SortItem< $key_cpp$, ConstPtr > "
- "SortItem;\n"
- "typedef ::$proto_ns$::internal::CompareByFirstField<SortItem> "
- "Less;\n");
- }
+ "using MapType = ::_pb::Map<$key_cpp$, $val_cpp$>;\n"
+ "using WireHelper = $map_classname$::Funcs;\n"
+ "const auto& map_field = this->_internal_$name$();\n");
bool utf8_check = string_key || string_value;
if (utf8_check) {
- format(
- "struct Utf8Check {\n"
- " static void Check(ConstPtr p) {\n"
- // p may be unused when GetUtf8CheckMode evaluates to kNone,
- // thus disabling the validation.
- " (void)p;\n");
- format.Indent();
- format.Indent();
- if (string_key) {
- GenerateUtf8CheckCodeForString(
- key_field, options_, false,
- "p->first.data(), static_cast<int>(p->first.length()),\n", format);
+ format("auto check_utf8 = [](const MapType::value_type& entry) {\n");
+ {
+ auto check_scope = format.ScopedIndent();
+ // p may be unused when GetUtf8CheckMode evaluates to kNone,
+ // thus disabling the validation.
+ format("(void)entry;\n");
+ if (string_key) {
+ GenerateUtf8CheckCodeForString(
+ key_field, options_, false,
+ "entry.first.data(), static_cast<int>(entry.first.length()),\n",
+ format);
+ }
+ if (string_value) {
+ GenerateUtf8CheckCodeForString(
+ value_field, options_, false,
+ "entry.second.data(), static_cast<int>(entry.second.length()),\n",
+ format);
+ }
}
- if (string_value) {
- GenerateUtf8CheckCodeForString(
- value_field, options_, false,
- "p->second.data(), static_cast<int>(p->second.length()),\n", format);
- }
- format.Outdent();
- format.Outdent();
format(
- " }\n"
"};\n");
}
format(
"\n"
- "if (stream->IsSerializationDeterministic() &&\n"
- " this->_internal_$name$().size() > 1) {\n"
- " ::std::unique_ptr<SortItem[]> items(\n"
- " new SortItem[this->_internal_$name$().size()]);\n"
- " typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::size_type "
- "size_type;\n"
- " size_type n = 0;\n"
- " for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
- " it = this->_internal_$name$().begin();\n"
- " it != this->_internal_$name$().end(); ++it, ++n) {\n"
- " items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);\n"
- " }\n"
- " ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());\n");
- format.Indent();
- GenerateSerializationLoop(format, string_key, string_value, true);
- format.Outdent();
+ "if (stream->IsSerializationDeterministic() && "
+ "map_field.size() > 1) {\n");
+ {
+ auto deterministic_scope = format.ScopedIndent();
+ GenerateSerializationLoop(format, string_key, string_value, true);
+ }
format("} else {\n");
- format.Indent();
- GenerateSerializationLoop(format, string_key, string_value, false);
- format.Outdent();
+ {
+ auto map_order_scope = format.ScopedIndent();
+ GenerateSerializationLoop(format, string_key, string_value, false);
+ }
format("}\n");
format.Outdent();
format("}\n");
@@ -301,7 +267,7 @@ void MapFieldGenerator::GenerateIsInitialized(io::Printer* printer) const {
Formatter format(printer, variables_);
format(
- "if (!::$proto_ns$::internal::AllAreInitialized($name$_)) return "
+ "if (!::$proto_ns$::internal::AllAreInitialized($field$)) return "
"false;\n");
}
@@ -315,17 +281,28 @@ void MapFieldGenerator::GenerateConstinitInitializer(
}
}
-bool MapFieldGenerator::GenerateArenaDestructorCode(
- io::Printer* printer) const {
+void MapFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
+ GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
+
Formatter format(printer, variables_);
- if (HasDescriptorMethods(descriptor_->file(), options_)) {
- // _this is the object being destructed (we are inside a static method
- // here).
- format("_this->$name$_. ~MapField();\n");
- return true;
- } else {
- return false;
+ format("$field$.Destruct();\n");
+}
+
+void MapFieldGenerator::GenerateArenaDestructorCode(
+ io::Printer* printer) const {
+ if (NeedsArenaDestructor() == ArenaDtorNeeds::kNone) {
+ return;
}
+
+ Formatter format(printer, variables_);
+ // _this is the object being destructed (we are inside a static method here).
+ format("_this->$field$.Destruct();\n");
+}
+
+ArenaDtorNeeds MapFieldGenerator::NeedsArenaDestructor() const {
+ return HasDescriptorMethods(descriptor_->file(), options_)
+ ? ArenaDtorNeeds::kRequired
+ : ArenaDtorNeeds::kNone;
}
} // namespace cpp
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_map_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_map_field.h
index c01ae498b1a..9e71267c0f1 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_map_field.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_map_field.h
@@ -62,7 +62,9 @@ class MapFieldGenerator : public FieldGenerator {
void GenerateByteSize(io::Printer* printer) const override;
void GenerateIsInitialized(io::Printer* printer) const override;
void GenerateConstinitInitializer(io::Printer* printer) const override;
- bool GenerateArenaDestructorCode(io::Printer* printer) const override;
+ void GenerateDestructorCode(io::Printer* printer) const override;
+ void GenerateArenaDestructorCode(io::Printer* printer) const override;
+ ArenaDtorNeeds NeedsArenaDestructor() const override;
private:
const bool has_required_fields_;
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message.cc
index 4b5e0f2e95c..a56c6fbda1e 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -44,22 +44,21 @@
#include <vector>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/compiler/cpp/cpp_enum.h>
-#include <google/protobuf/compiler/cpp/cpp_extension.h>
-#include <google/protobuf/compiler/cpp/cpp_field.h>
-#include <google/protobuf/compiler/cpp/cpp_helpers.h>
-#include <google/protobuf/compiler/cpp/cpp_padding_optimizer.h>
-#include <google/protobuf/compiler/cpp/cpp_parse_function_generator.h>
-#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.h>
-#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/map_entry_lite.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/compiler/cpp/cpp_enum.h>
+#include <google/protobuf/compiler/cpp/cpp_extension.h>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/compiler/cpp/cpp_padding_optimizer.h>
+#include <google/protobuf/compiler/cpp/cpp_parse_function_generator.h>
+#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/hash.h>
@@ -109,7 +108,7 @@ void PrintPresenceCheck(const Formatter& format, const FieldDescriptor* field,
int has_bit_index = has_bit_indices[field->index()];
if (*cached_has_word_index != (has_bit_index / 32)) {
*cached_has_word_index = (has_bit_index / 32);
- format("cached_has_bits = _has_bits_[$1$];\n", *cached_has_word_index);
+ format("cached_has_bits = $has_bits$[$1$];\n", *cached_has_word_index);
}
const TProtoStringType mask =
StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
@@ -276,8 +275,8 @@ void CollectMapInfo(const Options& options, const Descriptor* descriptor,
std::map<TProtoStringType, TProtoStringType>* variables) {
GOOGLE_CHECK(IsMapEntryMessage(descriptor));
std::map<TProtoStringType, TProtoStringType>& vars = *variables;
- const FieldDescriptor* key = descriptor->FindFieldByName("key");
- const FieldDescriptor* val = descriptor->FindFieldByName("value");
+ const FieldDescriptor* key = descriptor->map_key();
+ const FieldDescriptor* val = descriptor->map_value();
vars["key_cpp"] = PrimitiveTypeName(options, key->cpp_type());
switch (val->cpp_type()) {
case FieldDescriptor::CPPTYPE_MESSAGE:
@@ -323,64 +322,6 @@ bool ShouldSerializeInOrder(const Descriptor* descriptor,
return true;
}
-bool TableDrivenParsingEnabled(const Descriptor* descriptor,
- const Options& options,
- MessageSCCAnalyzer* scc_analyzer) {
- if (!options.table_driven_parsing) {
- return false;
- }
-
- // Consider table-driven parsing. We only do this if:
- // - We have has_bits for fields. This avoids a check on every field we set
- // when are present (the common case).
- bool has_hasbit = false;
- for (int i = 0; i < descriptor->field_count(); i++) {
- if (HasHasbit(descriptor->field(i))) {
- has_hasbit = true;
- break;
- }
- }
-
- if (!has_hasbit) return false;
-
- const double table_sparseness = 0.5;
- int max_field_number = 0;
- for (auto field : FieldRange(descriptor)) {
- if (max_field_number < field->number()) {
- max_field_number = field->number();
- }
-
- // - There are no weak fields.
- if (IsWeak(field, options)) {
- return false;
- }
-
- // - There are no lazy fields (they require the non-lite library).
- if (IsLazy(field, options, scc_analyzer)) {
- return false;
- }
- }
-
- // - There range of field numbers is "small"
- if (max_field_number >= (2 << 14)) {
- return false;
- }
-
- // - Field numbers are relatively dense within the actual number of fields.
- // We check for strictly greater than in the case where there are no fields
- // (only extensions) so max_field_number == descriptor->field_count() == 0.
- if (max_field_number * table_sparseness > descriptor->field_count()) {
- return false;
- }
-
- // - This is not a MapEntryMessage.
- if (IsMapEntryMessage(descriptor)) {
- return false;
- }
-
- return true;
-}
-
bool IsCrossFileMapField(const FieldDescriptor* field) {
if (!field->is_map()) {
return false;
@@ -406,8 +347,8 @@ bool IsRequired(const std::vector<const FieldDescriptor*>& v) {
bool HasSingularString(const Descriptor* desc, const Options& options) {
for (const auto* field : FieldRange(desc)) {
- if (IsString(field, options) && !IsStringInlined(field, options) &&
- !field->is_repeated() && !field->real_containing_oneof()) {
+ if (IsString(field, options) && !field->is_repeated() &&
+ !field->real_containing_oneof()) {
return true;
}
}
@@ -470,6 +411,7 @@ class ColdChunkSkipper {
access_info_map_(options.access_info_map),
cold_threshold_(cold_threshold) {
SetCommonVars(options, &variables_);
+ SetCommonMessageDataVariables(&variables_);
}
// May open an external if check for a batch of cold fields. "from" is the
@@ -610,6 +552,8 @@ void GenerateExtensionAnnotations(
google::protobuf::FileOptions::LITE_RUNTIME) {
return;
}
+ StringPiece tracker = (*variables)["tracker"];
+ StringPiece extensions = (*variables)["extensions"];
for (const auto& annotation : accessor_annotations_to_hooks) {
const TProtoStringType& annotation_name = annotation.first;
const TProtoStringType& listener_call = annotation.second;
@@ -619,29 +563,29 @@ void GenerateExtensionAnnotations(
// Primitive fields accessors.
// "Has" is here as users calling "has" on a repeated field is a mistake.
(*variables)[annotation_name] = StrCat(
- " _tracker_.", listener_call,
- "(this, id.number(), _proto_TypeTraits::GetPtr(id.number(), "
- "_extensions_, id.default_value_ref()));");
+ " ", tracker, ".", listener_call,
+ "(this, id.number(), _proto_TypeTraits::GetPtr(id.number(), ",
+ extensions, ", id.default_value_ref()));");
} else if (StrContains(annotation_name, "repeated") &&
!StrContains(annotation_name, "list") &&
!StrContains(annotation_name, "size")) {
// Repeated index accessors.
TProtoStringType str_index = "index";
if (StrContains(annotation_name, "add")) {
- str_index = "_extensions_.ExtensionSize(id.number()) - 1";
+ str_index = StrCat(extensions, ".ExtensionSize(id.number()) - 1");
}
(*variables)[annotation_name] =
- StrCat(" _tracker_.", listener_call,
+ StrCat(" ", tracker, ".", listener_call,
"(this, id.number(), "
- "_proto_TypeTraits::GetPtr(id.number(), _extensions_, ",
- str_index, "));");
+ "_proto_TypeTraits::GetPtr(id.number(), ",
+ extensions, ", ", str_index, "));");
} else if (StrContains(annotation_name, "list") ||
StrContains(annotation_name, "size")) {
// Repeated full accessors.
(*variables)[annotation_name] = StrCat(
- " _tracker_.", listener_call,
- "(this, id.number(), _proto_TypeTraits::GetRepeatedPtr(id.number(), "
- "_extensions_));");
+ " ", tracker, ".", listener_call,
+ "(this, id.number(), _proto_TypeTraits::GetRepeatedPtr(id.number(), ",
+ extensions, "));");
} else {
// Generic accessors such as "clear".
// TODO(b/190614678): Generalize clear from both repeated and non repeated
@@ -673,6 +617,7 @@ MessageGenerator::MessageGenerator(
if (!message_layout_helper_) {
message_layout_helper_.reset(new PaddingOptimizer());
}
+ SetCommonMessageDataVariables(&variables_);
// Variables that apply to this class
variables_["classname"] = classname_;
@@ -688,7 +633,8 @@ MessageGenerator::MessageGenerator(
if (options.field_listener_options.inject_field_listener_events &&
descriptor->file()->options().optimize_for() !=
google::protobuf::FileOptions::LITE_RUNTIME) {
- const TProtoStringType injector_template = " _tracker_.";
+ const TProtoStringType injector_template =
+ StrCat(" ", variables_["tracker"], ".");
MaySetAnnotationVariable(options, "serialize", injector_template,
"OnSerialize(this);\n", &variables_);
@@ -738,6 +684,9 @@ MessageGenerator::MessageGenerator(
if (IsStringInlined(field, options_)) {
if (inlined_string_indices_.empty()) {
inlined_string_indices_.resize(descriptor_->field_count(), kNoHasbit);
+ // The bitset[0] is for arena dtor tracking. Donating states start from
+ // bitset[1];
+ max_inlined_string_index_++;
}
inlined_string_indices_[field->index()] = max_inlined_string_index_++;
}
@@ -758,8 +707,6 @@ MessageGenerator::MessageGenerator(
}
}
- table_driven_ =
- TableDrivenParsingEnabled(descriptor_, options_, scc_analyzer_);
parse_function_generator_.reset(new ParseFunctionGenerator(
descriptor_, max_has_bit_index_, has_bit_indices_,
inlined_string_indices_, options_, scc_analyzer_, variables_));
@@ -903,7 +850,7 @@ inline bool HasExtension(
const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const {
$annotate_extension_has$
- return _extensions_.Has(id.number());
+ return $extensions$.Has(id.number());
}
template <typename _proto_TypeTraits,
@@ -912,7 +859,7 @@ template <typename _proto_TypeTraits,
inline void ClearExtension(
const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id) {
- _extensions_.ClearExtension(id.number());
+ $extensions$.ClearExtension(id.number());
$annotate_extension_clear$
}
@@ -923,7 +870,7 @@ inline int ExtensionSize(
const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const {
$annotate_extension_repeated_size$
- return _extensions_.ExtensionSize(id.number());
+ return $extensions$.ExtensionSize(id.number());
}
template <typename _proto_TypeTraits,
@@ -933,7 +880,7 @@ inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const {
$annotate_extension_get$
- return _proto_TypeTraits::Get(id.number(), _extensions_,
+ return _proto_TypeTraits::Get(id.number(), $extensions$,
id.default_value());
}
@@ -945,7 +892,7 @@ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id) {
$annotate_extension_mutable$
return _proto_TypeTraits::Mutable(id.number(), _field_type,
- &_extensions_);
+ &$extensions$);
}
template <typename _proto_TypeTraits,
@@ -955,7 +902,7 @@ inline void SetExtension(
const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
typename _proto_TypeTraits::Singular::ConstType value) {
- _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);
+ _proto_TypeTraits::Set(id.number(), _field_type, value, &$extensions$);
$annotate_extension_set$
}
@@ -967,7 +914,7 @@ inline void SetAllocatedExtension(
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
typename _proto_TypeTraits::Singular::MutableType value) {
_proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
- &_extensions_);
+ &$extensions$);
$annotate_extension_set$
}
template <typename _proto_TypeTraits,
@@ -978,7 +925,7 @@ inline void UnsafeArenaSetAllocatedExtension(
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
typename _proto_TypeTraits::Singular::MutableType value) {
_proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
- value, &_extensions_);
+ value, &$extensions$);
$annotate_extension_set$
}
template <typename _proto_TypeTraits,
@@ -991,7 +938,7 @@ PROTOBUF_NODISCARD inline
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id) {
$annotate_extension_release$
return _proto_TypeTraits::Release(id.number(), _field_type,
- &_extensions_);
+ &$extensions$);
}
template <typename _proto_TypeTraits,
::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
@@ -1002,7 +949,7 @@ UnsafeArenaReleaseExtension(
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id) {
$annotate_extension_release$
return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
- &_extensions_);
+ &$extensions$);
}
template <typename _proto_TypeTraits,
@@ -1013,7 +960,7 @@ inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
int index) const {
$annotate_repeated_extension_get$
- return _proto_TypeTraits::Get(id.number(), _extensions_, index);
+ return _proto_TypeTraits::Get(id.number(), $extensions$, index);
}
template <typename _proto_TypeTraits,
@@ -1024,7 +971,7 @@ inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
int index) {
$annotate_repeated_extension_mutable$
- return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);
+ return _proto_TypeTraits::Mutable(id.number(), index, &$extensions$);
}
template <typename _proto_TypeTraits,
@@ -1034,7 +981,7 @@ inline void SetExtension(
const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
int index, typename _proto_TypeTraits::Repeated::ConstType value) {
- _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);
+ _proto_TypeTraits::Set(id.number(), index, value, &$extensions$);
$annotate_repeated_extension_set$
}
@@ -1045,7 +992,7 @@ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id) {
typename _proto_TypeTraits::Repeated::MutableType to_add =
- _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);
+ _proto_TypeTraits::Add(id.number(), _field_type, &$extensions$);
$annotate_repeated_extension_add_mutable$
return to_add;
}
@@ -1058,7 +1005,7 @@ inline void AddExtension(
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id,
typename _proto_TypeTraits::Repeated::ConstType value) {
_proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
- &_extensions_);
+ &$extensions$);
$annotate_repeated_extension_add$
}
@@ -1070,7 +1017,7 @@ GetRepeatedExtension(
const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const {
$annotate_repeated_extension_list$
- return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);
+ return _proto_TypeTraits::GetRepeated(id.number(), $extensions$);
}
template <typename _proto_TypeTraits,
@@ -1082,7 +1029,7 @@ MutableRepeatedExtension(
$classname$, _proto_TypeTraits, _field_type, _is_packed>& id) {
$annotate_repeated_extension_list_mutable$
return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
- _is_packed, &_extensions_);
+ _is_packed, &$extensions$);
}
)");
@@ -1119,7 +1066,7 @@ void MessageGenerator::GenerateSingularFieldHasBits(
format(
"inline bool $classname$::has_$name$() const {\n"
"$annotate_has$"
- " return _weak_field_map_.Has($number$);\n"
+ " return $weak_field_map$.Has($number$);\n"
"}\n");
return;
}
@@ -1133,14 +1080,14 @@ void MessageGenerator::GenerateSingularFieldHasBits(
format(
"inline bool $classname$::_internal_has_$name$() const {\n"
" bool value = "
- "(_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n");
+ "($has_bits$[$has_array_index$] & 0x$has_mask$u) != 0;\n");
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
!IsLazy(field, options_, scc_analyzer_)) {
// We maintain the invariant that for a submessage x, has_x() returning
// true implies that x_ is not null. By giving this information to the
// compiler, we allow it to eliminate unnecessary null checks later on.
- format(" PROTOBUF_ASSUME(!value || $name$_ != nullptr);\n");
+ format(" PROTOBUF_ASSUME(!value || $field$ != nullptr);\n");
}
format(
@@ -1155,13 +1102,13 @@ void MessageGenerator::GenerateSingularFieldHasBits(
if (IsLazy(field, options_, scc_analyzer_)) {
format(
"inline bool $classname$::_internal_has_$name$() const {\n"
- " return !$name$_.IsCleared();\n"
+ " return !$field$.IsCleared();\n"
"}\n");
} else {
format(
"inline bool $classname$::_internal_has_$name$() const {\n"
" return this != internal_default_instance() "
- "&& $name$_ != nullptr;\n"
+ "&& $field$ != nullptr;\n"
"}\n");
}
format(
@@ -1183,7 +1130,7 @@ void MessageGenerator::GenerateOneofHasBits(io::Printer* printer) {
" return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
"}\n"
"inline void $classname$::clear_has_$oneof_name$() {\n"
- " _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
+ " $oneof_case$[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
"}\n");
}
}
@@ -1229,7 +1176,7 @@ void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field,
// annotated.
format(
"inline void $classname$::set_has_$name$() {\n"
- " _oneof_case_[$oneof_index$] = k$field_name$;\n"
+ " $oneof_case$[$oneof_index$] = k$field_name$;\n"
"}\n");
}
@@ -1264,7 +1211,7 @@ void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field,
format.Set("has_array_index", has_bit_index / 32);
format.Set("has_mask",
strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
- format("_has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n");
+ format("$has_bits$[$has_array_index$] &= ~0x$has_mask$u;\n");
}
}
format("$annotate_clear$");
@@ -1298,12 +1245,13 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) {
} else {
format(
"inline int $classname$::_internal_$name$_size() const {\n"
- " return $name$_$1$.size();\n"
+ " return $1$$2$.size();\n"
"}\n"
"inline int $classname$::$name$_size() const {\n"
"$annotate_size$"
" return _internal_$name$_size();\n"
"}\n",
+ FieldMemberName(field),
IsImplicitWeakField(field, options_, scc_analyzer_) &&
field->message_type()
? ".weak"
@@ -1360,7 +1308,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
" ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> "
"SuperType;\n"
" $classname$();\n"
- " explicit constexpr $classname$(\n"
+ " explicit PROTOBUF_CONSTEXPR $classname$(\n"
" ::$proto_ns$::internal::ConstantInitialized);\n"
" explicit $classname$(::$proto_ns$::Arena* arena);\n"
" void MergeFrom(const $classname$& other);\n"
@@ -1432,7 +1380,9 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
""
" ::$proto_ns$::Metadata GetMetadata() const final;\n");
}
- format("};\n");
+ format(
+ " friend struct ::$tablename$;\n"
+ "};\n");
return;
}
@@ -1444,11 +1394,10 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
format(" public:\n");
format.Indent();
- if (EnableMessageOwnedArena(descriptor_)) {
+ if (EnableMessageOwnedArena(descriptor_, options_)) {
format(
"inline $classname$() : $classname$("
- "::$proto_ns$::Arena::InternalHelper<$classname$>::\n"
- " CreateMessageOwnedArena(), true) {}\n");
+ "::$proto_ns$::Arena::InternalCreateMessageOwnedArena(), true) {}\n");
} else {
format("inline $classname$() : $classname$(nullptr) {}\n");
}
@@ -1456,7 +1405,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
format("~$classname$() override;\n");
}
format(
- "explicit constexpr "
+ "explicit PROTOBUF_CONSTEXPR "
"$classname$(::$proto_ns$::internal::ConstantInitialized);\n"
"\n"
"$classname$(const $classname$& from);\n"
@@ -1484,14 +1433,6 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
"}\n"
"\n");
- if (options_.table_driven_serialization) {
- format(
- "private:\n"
- "const void* InternalGetTable() const override;\n"
- "public:\n"
- "\n");
- }
-
if (PublicUnknownFieldsAccessors(descriptor_)) {
format(
"inline const $unknown_fields_type$& unknown_fields() const {\n"
@@ -1569,16 +1510,16 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
if (HasDescriptorMethods(descriptor_->file(), options_)) {
format(
"bool PackFrom(const ::$proto_ns$::Message& message) {\n"
- " return _any_metadata_.PackFrom(GetArena(), message);\n"
+ " return $any_metadata$.PackFrom(GetArena(), message);\n"
"}\n"
"bool PackFrom(const ::$proto_ns$::Message& message,\n"
" ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
"type_url_prefix) {\n"
- " return _any_metadata_.PackFrom(GetArena(), message, "
+ " return $any_metadata$.PackFrom(GetArena(), message, "
"type_url_prefix);\n"
"}\n"
"bool UnpackTo(::$proto_ns$::Message* message) const {\n"
- " return _any_metadata_.UnpackTo(message);\n"
+ " return $any_metadata$.UnpackTo(message);\n"
"}\n"
"static bool GetAnyFieldDescriptors(\n"
" const ::$proto_ns$::Message& message,\n"
@@ -1588,7 +1529,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
"!std::is_convertible<T, const ::$proto_ns$::Message&>"
"::value>::type>\n"
"bool PackFrom(const T& message) {\n"
- " return _any_metadata_.PackFrom<T>(GetArena(), message);\n"
+ " return $any_metadata$.PackFrom<T>(GetArena(), message);\n"
"}\n"
"template <typename T, class = typename std::enable_if<"
"!std::is_convertible<T, const ::$proto_ns$::Message&>"
@@ -1596,36 +1537,36 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
"bool PackFrom(const T& message,\n"
" ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
"type_url_prefix) {\n"
- " return _any_metadata_.PackFrom<T>(GetArena(), message, "
+ " return $any_metadata$.PackFrom<T>(GetArena(), message, "
"type_url_prefix);"
"}\n"
"template <typename T, class = typename std::enable_if<"
"!std::is_convertible<T, const ::$proto_ns$::Message&>"
"::value>::type>\n"
"bool UnpackTo(T* message) const {\n"
- " return _any_metadata_.UnpackTo<T>(message);\n"
+ " return $any_metadata$.UnpackTo<T>(message);\n"
"}\n");
} else {
format(
"template <typename T>\n"
"bool PackFrom(const T& message) {\n"
- " return _any_metadata_.PackFrom(GetArena(), message);\n"
+ " return $any_metadata$.PackFrom(GetArena(), message);\n"
"}\n"
"template <typename T>\n"
"bool PackFrom(const T& message,\n"
" ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
"type_url_prefix) {\n"
- " return _any_metadata_.PackFrom(GetArena(), message, "
+ " return $any_metadata$.PackFrom(GetArena(), message, "
"type_url_prefix);\n"
"}\n"
"template <typename T>\n"
"bool UnpackTo(T* message) const {\n"
- " return _any_metadata_.UnpackTo(message);\n"
+ " return $any_metadata$.UnpackTo(message);\n"
"}\n");
}
format(
"template<typename T> bool Is() const {\n"
- " return _any_metadata_.Is<T>();\n"
+ " return $any_metadata$.Is<T>();\n"
"}\n"
"static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam "
"type_url,\n"
@@ -1732,7 +1673,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
if (!HasSimpleBaseClass(descriptor_, options_)) {
format(
- "int GetCachedSize() const final { return _cached_size_.Get(); }"
+ "int GetCachedSize() const final { return "
+ "$cached_size$.Get(); }"
"\n\nprivate:\n"
"void SharedCtor();\n"
"void SharedDtor();\n"
@@ -1756,13 +1698,32 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
// we rely on.
"protected:\n"
"explicit $classname$(::$proto_ns$::Arena* arena,\n"
- " bool is_message_owned = false);\n"
- "private:\n");
+ " bool is_message_owned = false);\n");
- if (!HasSimpleBaseClass(descriptor_, options_)) {
- format(
- "static void ArenaDtor(void* object);\n"
- "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n");
+ switch (NeedsArenaDestructor()) {
+ case ArenaDtorNeeds::kOnDemand:
+ format(
+ "private:\n"
+ "static void ArenaDtor(void* object);\n"
+ "inline void OnDemandRegisterArenaDtor(::$proto_ns$::Arena* arena) "
+ "override {\n"
+ " if (arena == nullptr || ($inlined_string_donated_array$[0] & "
+ "0x1u) "
+ "== "
+ "0) {\n"
+ " return;\n"
+ " }\n"
+ " $inlined_string_donated_array$[0] &= 0xFFFFFFFEu;\n"
+ " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n"
+ "}\n");
+ break;
+ case ArenaDtorNeeds::kRequired:
+ format(
+ "private:\n"
+ "static void ArenaDtor(void* object);\n");
+ break;
+ case ArenaDtorNeeds::kNone:
+ break;
}
format(
@@ -1866,7 +1827,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
// Prepare decls for _cached_size_ and _has_bits_. Their position in the
// output will be determined later.
- bool need_to_emit_cached_size = true;
+ bool need_to_emit_cached_size = !HasSimpleBaseClass(descriptor_, options_);
const TProtoStringType cached_size_decl =
"mutable ::$proto_ns$::internal::CachedSize _cached_size_;\n";
@@ -1917,8 +1878,10 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
// _cached_size_ together with _has_bits_ improves cache locality despite
// potential alignment padding.
format(has_bits_decl.c_str());
- format(cached_size_decl.c_str());
- need_to_emit_cached_size = false;
+ if (need_to_emit_cached_size) {
+ format(cached_size_decl.c_str());
+ need_to_emit_cached_size = false;
+ }
}
// Field members:
@@ -2001,73 +1964,12 @@ void MessageGenerator::GenerateInlineMethods(io::Printer* printer) {
"inline $classname$::$camel_oneof_name$Case $classname$::"
"${1$$oneof_name$_case$}$() const {\n"
" return $classname$::$camel_oneof_name$Case("
- "_oneof_case_[$oneof_index$]);\n"
+ "$oneof_case$[$oneof_index$]);\n"
"}\n",
oneof);
}
}
-bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset,
- size_t aux_offset) {
- Formatter format(printer, variables_);
-
- if (!table_driven_) {
- format("{ nullptr, nullptr, 0, -1, -1, -1, -1, nullptr, false },\n");
- return false;
- }
-
- int max_field_number = 0;
- for (auto field : FieldRange(descriptor_)) {
- if (max_field_number < field->number()) {
- max_field_number = field->number();
- }
- }
-
- format("{\n");
- format.Indent();
-
- format(
- "$tablename$::entries + $1$,\n"
- "$tablename$::aux + $2$,\n"
- "$3$,\n",
- offset, aux_offset, max_field_number);
-
- if (has_bit_indices_.empty()) {
- // If no fields have hasbits, then _has_bits_ does not exist.
- format("-1,\n");
- } else {
- format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n");
- }
-
- if (descriptor_->real_oneof_decl_count() > 0) {
- format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_),\n");
- } else {
- format("-1, // no _oneof_case_\n");
- }
-
- if (descriptor_->extension_range_count() > 0) {
- format("PROTOBUF_FIELD_OFFSET($classtype$, _extensions_),\n");
- } else {
- format("-1, // no _extensions_\n");
- }
-
- // TODO(ckennelly): Consolidate this with the calculation for
- // AuxiliaryParseTableField.
- format(
- "PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n"
- "&$package_ns$::_$classname$_default_instance_,\n");
-
- if (UseUnknownFieldSet(descriptor_->file(), options_)) {
- format("true,\n");
- } else {
- format("false,\n");
- }
-
- format.Outdent();
- format("},\n");
- return true;
-}
-
void MessageGenerator::GenerateSchema(io::Printer* printer, int offset,
int has_offset) {
Formatter format(printer, variables_);
@@ -2087,218 +1989,6 @@ void MessageGenerator::GenerateSchema(io::Printer* printer, int offset,
inlined_string_indices_offset);
}
-namespace {
-
-// We need to calculate for each field what function the table driven code
-// should use to serialize it. This returns the index in a lookup table.
-arc_ui32 CalcFieldNum(const FieldGenerator& generator,
- const FieldDescriptor* field, const Options& options) {
- bool is_a_map = IsMapEntryMessage(field->containing_type());
- int type = field->type();
- if (type == FieldDescriptor::TYPE_STRING ||
- type == FieldDescriptor::TYPE_BYTES) {
- // string field
- if (generator.IsInlined()) {
- type = internal::FieldMetadata::kInlinedType;
- } else if (IsCord(field, options)) {
- type = internal::FieldMetadata::kCordType;
- } else if (IsStringPiece(field, options)) {
- type = internal::FieldMetadata::kStringPieceType;
- }
- }
-
- if (field->real_containing_oneof()) {
- return internal::FieldMetadata::CalculateType(
- type, internal::FieldMetadata::kOneOf);
- } else if (field->is_packed()) {
- return internal::FieldMetadata::CalculateType(
- type, internal::FieldMetadata::kPacked);
- } else if (field->is_repeated()) {
- return internal::FieldMetadata::CalculateType(
- type, internal::FieldMetadata::kRepeated);
- } else if (HasHasbit(field) || field->real_containing_oneof() || is_a_map) {
- return internal::FieldMetadata::CalculateType(
- type, internal::FieldMetadata::kPresence);
- } else {
- return internal::FieldMetadata::CalculateType(
- type, internal::FieldMetadata::kNoPresence);
- }
-}
-
-int FindMessageIndexInFile(const Descriptor* descriptor) {
- std::vector<const Descriptor*> flatten =
- FlattenMessagesInFile(descriptor->file());
- return std::find(flatten.begin(), flatten.end(), descriptor) -
- flatten.begin();
-}
-
-} // namespace
-
-int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
- Formatter format(printer, variables_);
- if (!options_.table_driven_serialization) {
- return 0;
- }
-
- std::vector<const FieldDescriptor*> sorted = SortFieldsByNumber(descriptor_);
- if (IsMapEntryMessage(descriptor_)) {
- for (int i = 0; i < 2; i++) {
- const FieldDescriptor* field = sorted[i];
- const FieldGenerator& generator = field_generators_.get(field);
-
- arc_ui32 tag = internal::WireFormatLite::MakeTag(
- field->number(), WireFormat::WireTypeForFieldType(field->type()));
-
- std::map<TProtoStringType, TProtoStringType> vars;
- vars["classtype"] = QualifiedClassName(descriptor_, options_);
- vars["field_name"] = FieldName(field);
- vars["tag"] = StrCat(tag);
- vars["hasbit"] = StrCat(i);
- vars["type"] = StrCat(CalcFieldNum(generator, field, options_));
- vars["ptr"] = "nullptr";
- if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- GOOGLE_CHECK(!IsMapEntryMessage(field->message_type()));
- vars["ptr"] =
- "::" + UniqueName("TableStruct", field->message_type(), options_) +
- "::serialization_table + " +
- StrCat(FindMessageIndexInFile(field->message_type()));
- }
- Formatter::SaveState saver(&format);
- format.AddMap(vars);
- format(
- "{PROTOBUF_FIELD_OFFSET("
- "::$proto_ns$::internal::MapEntryHelper<$classtype$::"
- "SuperType>, $field_name$_), $tag$,"
- "PROTOBUF_FIELD_OFFSET("
- "::$proto_ns$::internal::MapEntryHelper<$classtype$::"
- "SuperType>, _has_bits_) * 8 + $hasbit$, $type$, "
- "$ptr$},\n");
- }
- return 2;
- }
- format(
- "{PROTOBUF_FIELD_OFFSET($classtype$, _cached_size_),"
- " 0, 0, 0, nullptr},\n");
- std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
- sorted_extensions.reserve(descriptor_->extension_range_count());
- for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
- sorted_extensions.push_back(descriptor_->extension_range(i));
- }
- std::sort(sorted_extensions.begin(), sorted_extensions.end(),
- ExtensionRangeSorter());
- for (int i = 0, extension_idx = 0; /* no range */; i++) {
- for (; extension_idx < sorted_extensions.size() &&
- (i == sorted.size() ||
- sorted_extensions[extension_idx]->start < sorted[i]->number());
- extension_idx++) {
- const Descriptor::ExtensionRange* range =
- sorted_extensions[extension_idx];
- format(
- "{PROTOBUF_FIELD_OFFSET($classtype$, _extensions_), "
- "$1$, $2$, ::$proto_ns$::internal::FieldMetadata::kSpecial, "
- "reinterpret_cast<const "
- "void*>(::$proto_ns$::internal::ExtensionSerializer)},\n",
- range->start, range->end);
- }
- if (i == sorted.size()) break;
- const FieldDescriptor* field = sorted[i];
-
- arc_ui32 tag = internal::WireFormatLite::MakeTag(
- field->number(), WireFormat::WireTypeForFieldType(field->type()));
- if (field->is_packed()) {
- tag = internal::WireFormatLite::MakeTag(
- field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
- }
-
- TProtoStringType classfieldname = FieldName(field);
- if (field->real_containing_oneof()) {
- classfieldname = field->containing_oneof()->name();
- }
- format.Set("field_name", classfieldname);
- TProtoStringType ptr = "nullptr";
- if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- if (IsMapEntryMessage(field->message_type())) {
- format(
- "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), $1$, $2$, "
- "::$proto_ns$::internal::FieldMetadata::kSpecial, "
- "reinterpret_cast<const void*>(static_cast< "
- "::$proto_ns$::internal::SpecialSerializer>("
- "::$proto_ns$::internal::MapFieldSerializer< "
- "::$proto_ns$::internal::MapEntryToMapField<"
- "$3$>::MapFieldType, "
- "$tablename$::serialization_table>))},\n",
- tag, FindMessageIndexInFile(field->message_type()),
- QualifiedClassName(field->message_type(), options_));
- continue;
- } else if (!field->message_type()->options().message_set_wire_format()) {
- // message_set doesn't have the usual table and we need to
- // dispatch to generated serializer, hence ptr stays zero.
- ptr =
- "::" + UniqueName("TableStruct", field->message_type(), options_) +
- "::serialization_table + " +
- StrCat(FindMessageIndexInFile(field->message_type()));
- }
- }
-
- const FieldGenerator& generator = field_generators_.get(field);
- int type = CalcFieldNum(generator, field, options_);
-
- if (IsLazy(field, options_, scc_analyzer_)) {
- type = internal::FieldMetadata::kSpecial;
- ptr = "reinterpret_cast<const void*>(::" + variables_["proto_ns"] +
- "::internal::LazyFieldSerializer";
- if (field->real_containing_oneof()) {
- ptr += "OneOf";
- } else if (!HasHasbit(field)) {
- ptr += "NoPresence";
- }
- ptr += ")";
- }
-
- if (field->options().weak()) {
- // TODO(gerbens) merge weak fields into ranges
- format(
- "{PROTOBUF_FIELD_OFFSET("
- "$classtype$, _weak_field_map_), $1$, $1$, "
- "::$proto_ns$::internal::FieldMetadata::kSpecial, "
- "reinterpret_cast<const "
- "void*>(::$proto_ns$::internal::WeakFieldSerializer)},\n",
- tag);
- } else if (field->real_containing_oneof()) {
- format.Set("oneofoffset",
- sizeof(arc_ui32) * field->containing_oneof()->index());
- format(
- "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), $1$,"
- " PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_) + "
- "$oneofoffset$, $2$, $3$},\n",
- tag, type, ptr);
- } else if (HasHasbit(field)) {
- format.Set("hasbitsoffset", has_bit_indices_[field->index()]);
- format(
- "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), "
- "$1$, PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_) * 8 + "
- "$hasbitsoffset$, $2$, $3$},\n",
- tag, type, ptr);
- } else {
- format(
- "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), "
- "$1$, ~0u, $2$, $3$},\n",
- tag, type, ptr);
- }
- }
- int num_field_metadata = 1 + sorted.size() + sorted_extensions.size();
- num_field_metadata++;
- TProtoStringType serializer = UseUnknownFieldSet(descriptor_->file(), options_)
- ? "UnknownFieldSetSerializer"
- : "UnknownFieldSerializerLite";
- format(
- "{PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_), 0, ~0u, "
- "::$proto_ns$::internal::FieldMetadata::kSpecial, reinterpret_cast<const "
- "void*>(::$proto_ns$::internal::$1$)},\n",
- serializer);
- return num_field_metadata;
-}
-
void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
Formatter format(printer, variables_);
if (IsMapEntryMessage(descriptor_)) {
@@ -2314,7 +2004,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
format(
"::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
"$annotate_reflection$"
- " return ::$proto_ns$::internal::AssignDescriptors(\n"
+ " return ::_pbi::AssignDescriptors(\n"
" &$desc_table$_getter, &$desc_table$_once,\n"
" $file_level_metadata$[$1$]);\n"
"}\n",
@@ -2322,7 +2012,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
} else {
format(
"::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
- " return ::$proto_ns$::internal::AssignDescriptors(\n"
+ " return ::_pbi::AssignDescriptors(\n"
" &$desc_table$_getter, &$desc_table$_once,\n"
" $file_level_metadata$[$1$]);\n"
"}\n",
@@ -2339,7 +2029,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
" const ::$proto_ns$::Message& message,\n"
" const ::$proto_ns$::FieldDescriptor** type_url_field,\n"
" const ::$proto_ns$::FieldDescriptor** value_field) {\n"
- " return ::$proto_ns$::internal::GetAnyFieldDescriptors(\n"
+ " return ::_pbi::GetAnyFieldDescriptors(\n"
" message, type_url_field, value_field);\n"
"}\n");
}
@@ -2347,8 +2037,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
"bool $classname$::ParseAnyTypeUrl(\n"
" ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url,\n"
" TProtoStringType* full_type_name) {\n"
- " return ::$proto_ns$::internal::ParseAnyTypeUrl(type_url,\n"
- " full_type_name);\n"
+ " return ::_pbi::ParseAnyTypeUrl(type_url, full_type_name);\n"
"}\n"
"\n");
}
@@ -2359,7 +2048,8 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
format.Indent();
if (!has_bit_indices_.empty()) {
format(
- "using HasBits = decltype(std::declval<$classname$>()._has_bits_);\n");
+ "using HasBits = "
+ "decltype(std::declval<$classname$>().$has_bits$);\n");
}
for (auto field : FieldRange(descriptor_)) {
field_generators_.get(field).GenerateInternalAccessorDeclarations(printer);
@@ -2455,20 +2145,12 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
GenerateSwap(printer);
format("\n");
- if (options_.table_driven_serialization) {
- format(
- "const void* $classname$::InternalGetTable() const {\n"
- " return ::$tablename$::serialization_table + $1$;\n"
- "}\n"
- "\n",
- index_in_file_messages_);
- }
if (HasDescriptorMethods(descriptor_->file(), options_)) {
if (!descriptor_->options().map_entry()) {
format(
"::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
"$annotate_reflection$"
- " return ::$proto_ns$::internal::AssignDescriptors(\n"
+ " return ::_pbi::AssignDescriptors(\n"
" &$desc_table$_getter, &$desc_table$_once,\n"
" $file_level_metadata$[$1$]);\n"
"}\n",
@@ -2476,7 +2158,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
} else {
format(
"::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
- " return ::$proto_ns$::internal::AssignDescriptors(\n"
+ " return ::_pbi::AssignDescriptors(\n"
" &$desc_table$_getter, &$desc_table$_once,\n"
" $file_level_metadata$[$1$]);\n"
"}\n",
@@ -2495,234 +2177,40 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
google::protobuf::FileOptions::LITE_RUNTIME) {
format(
"::$proto_ns$::AccessListener<$classtype$> "
- "$1$::_tracker_(&FullMessageName);\n",
+ "$1$::$tracker$(&FullMessageName);\n",
ClassName(descriptor_));
}
}
-size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) {
- Formatter format(printer, variables_);
-
- if (!table_driven_) {
- return 0;
- }
-
- // Field "0" is special: We use it in our switch statement of processing
- // types to handle the successful end tag case.
- format("{0, 0, 0, ::$proto_ns$::internal::kInvalidMask, 0, 0},\n");
- int last_field_number = 1;
-
- std::vector<const FieldDescriptor*> ordered_fields =
- SortFieldsByNumber(descriptor_);
-
- for (auto field : ordered_fields) {
- Formatter::SaveState saver(&format);
- GOOGLE_CHECK_GE(field->number(), last_field_number);
-
- for (; last_field_number < field->number(); last_field_number++) {
- format(
- "{ 0, 0, ::$proto_ns$::internal::kInvalidMask,\n"
- " ::$proto_ns$::internal::kInvalidMask, 0, 0 },\n");
- }
- last_field_number++;
-
- unsigned char normal_wiretype, packed_wiretype, processing_type;
- normal_wiretype = WireFormat::WireTypeForFieldType(field->type());
-
- if (field->is_packable()) {
- packed_wiretype = WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
- } else {
- packed_wiretype = internal::kNotPackedMask;
- }
-
- processing_type = static_cast<unsigned>(field->type());
- const FieldGenerator& generator = field_generators_.get(field);
- if (field->type() == FieldDescriptor::TYPE_STRING) {
- switch (EffectiveStringCType(field, options_)) {
- case FieldOptions::STRING:
- if (generator.IsInlined()) {
- processing_type = internal::TYPE_STRING_INLINED;
- }
- break;
- case FieldOptions::CORD:
- processing_type = internal::TYPE_STRING_CORD;
- break;
- case FieldOptions::STRING_PIECE:
- processing_type = internal::TYPE_STRING_STRING_PIECE;
- break;
- }
- } else if (field->type() == FieldDescriptor::TYPE_BYTES) {
- switch (EffectiveStringCType(field, options_)) {
- case FieldOptions::STRING:
- if (generator.IsInlined()) {
- processing_type = internal::TYPE_BYTES_INLINED;
- }
- break;
- case FieldOptions::CORD:
- processing_type = internal::TYPE_BYTES_CORD;
- break;
- case FieldOptions::STRING_PIECE:
- processing_type = internal::TYPE_BYTES_STRING_PIECE;
- break;
- }
- }
-
- processing_type |= static_cast<unsigned>(
- field->is_repeated() ? internal::kRepeatedMask : 0);
- processing_type |= static_cast<unsigned>(
- field->real_containing_oneof() ? internal::kOneofMask : 0);
-
- if (field->is_map()) {
- processing_type = internal::TYPE_MAP;
- }
-
- const unsigned char tag_size =
- WireFormat::TagSize(field->number(), field->type());
-
- std::map<TProtoStringType, TProtoStringType> vars;
- if (field->real_containing_oneof()) {
- vars["name"] = field->containing_oneof()->name();
- vars["presence"] = StrCat(field->containing_oneof()->index());
- } else {
- vars["name"] = FieldName(field);
- vars["presence"] = StrCat(has_bit_indices_[field->index()]);
- }
- vars["nwtype"] = StrCat(normal_wiretype);
- vars["pwtype"] = StrCat(packed_wiretype);
- vars["ptype"] = StrCat(processing_type);
- vars["tag_size"] = StrCat(tag_size);
-
- format.AddMap(vars);
-
- format(
- "{\n"
- " PROTOBUF_FIELD_OFFSET($classtype$, $name$_),\n"
- " static_cast<$uint32$>($presence$),\n"
- " $nwtype$, $pwtype$, $ptype$, $tag_size$\n"
- "},\n");
- }
-
- return last_field_number;
-}
-
-size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) {
- Formatter format(printer, variables_);
-
- if (!table_driven_) {
- return 0;
- }
-
- std::vector<const FieldDescriptor*> ordered_fields =
- SortFieldsByNumber(descriptor_);
-
- format("::$proto_ns$::internal::AuxiliaryParseTableField(),\n");
- int last_field_number = 1;
- for (auto field : ordered_fields) {
- Formatter::SaveState saver(&format);
-
- GOOGLE_CHECK_GE(field->number(), last_field_number);
- for (; last_field_number < field->number(); last_field_number++) {
- format("::$proto_ns$::internal::AuxiliaryParseTableField(),\n");
- }
-
- std::map<TProtoStringType, TProtoStringType> vars;
- SetCommonFieldVariables(field, &vars, options_);
- format.AddMap(vars);
-
- switch (field->cpp_type()) {
- case FieldDescriptor::CPPTYPE_ENUM:
- if (HasPreservingUnknownEnumSemantics(field)) {
- format(
- "{::$proto_ns$::internal::AuxiliaryParseTableField::enum_aux{"
- "nullptr}},\n");
- } else {
- format(
- "{::$proto_ns$::internal::AuxiliaryParseTableField::enum_aux{"
- "$1$_IsValid}},\n",
- ClassName(field->enum_type(), true));
- }
- last_field_number++;
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE: {
- if (field->is_map()) {
- format(
- "{::$proto_ns$::internal::AuxiliaryParseTableField::map_"
- "aux{&::$proto_ns$::internal::ParseMap<$1$>}},\n",
- QualifiedClassName(field->message_type(), options_));
- last_field_number++;
- break;
- }
- format.Set("field_classname", ClassName(field->message_type(), false));
- format.Set("default_instance", QualifiedDefaultInstanceName(
- field->message_type(), options_));
-
- format(
- "{::$proto_ns$::internal::AuxiliaryParseTableField::message_aux{\n"
- " &$default_instance$}},\n");
- last_field_number++;
- break;
- }
- case FieldDescriptor::CPPTYPE_STRING: {
- TProtoStringType default_val;
- switch (EffectiveStringCType(field, options_)) {
- case FieldOptions::STRING:
- default_val = field->default_value_string().empty()
- ? "&::" + variables_["proto_ns"] +
- "::internal::fixed_address_empty_string"
- : "&" +
- QualifiedClassName(descriptor_, options_) +
- "::" + MakeDefaultName(field);
- break;
- case FieldOptions::CORD:
- case FieldOptions::STRING_PIECE:
- default_val =
- "\"" + CEscape(field->default_value_string()) + "\"";
- break;
- }
- format(
- "{::$proto_ns$::internal::AuxiliaryParseTableField::string_aux{\n"
- " $1$,\n"
- " \"$2$\"\n"
- "}},\n",
- default_val, field->full_name());
- last_field_number++;
- break;
- }
- default:
- break;
- }
- }
-
- return last_field_number;
-}
-
std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
io::Printer* printer) {
Formatter format(printer, variables_);
if (!has_bit_indices_.empty() || IsMapEntryMessage(descriptor_)) {
- format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n");
+ format("PROTOBUF_FIELD_OFFSET($classtype$, $has_bits$),\n");
} else {
format("~0u, // no _has_bits_\n");
}
format("PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n");
if (descriptor_->extension_range_count() > 0) {
- format("PROTOBUF_FIELD_OFFSET($classtype$, _extensions_),\n");
+ format("PROTOBUF_FIELD_OFFSET($classtype$, $extensions$),\n");
} else {
format("~0u, // no _extensions_\n");
}
if (descriptor_->real_oneof_decl_count() > 0) {
- format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_[0]),\n");
+ format("PROTOBUF_FIELD_OFFSET($classtype$, $oneof_case$[0]),\n");
} else {
format("~0u, // no _oneof_case_\n");
}
if (num_weak_fields_ > 0) {
- format("PROTOBUF_FIELD_OFFSET($classtype$, _weak_field_map_),\n");
+ format("PROTOBUF_FIELD_OFFSET($classtype$, $weak_field_map$),\n");
} else {
format("~0u, // no _weak_field_map_\n");
}
if (!inlined_string_indices_.empty()) {
- format("PROTOBUF_FIELD_OFFSET($classtype$, _inlined_string_donated_),\n");
+ format(
+ "PROTOBUF_FIELD_OFFSET($classtype$, "
+ "$inlined_string_donated_array$),\n");
} else {
format("~0u, // no _inlined_string_donated_\n");
}
@@ -2740,9 +2228,9 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
if (field->options().weak() || field->real_containing_oneof()) {
// Mark the field to prevent unintentional access through reflection.
// Don't use the top bit because that is for unused fields.
- format("::$proto_ns$::internal::kInvalidFieldOffsetTag");
+ format("::_pbi::kInvalidFieldOffsetTag");
} else {
- format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_)", FieldName(field));
+ format("PROTOBUF_FIELD_OFFSET($classtype$, $1$)", FieldMemberName(field));
}
// Some information about a field is in the pdproto profile. The profile is
@@ -2750,11 +2238,6 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
// offset of the field, so that the information is available when
// reflectively accessing the field at run time.
//
- // Embed whether the field is used to the MSB of the offset.
- if (!IsFieldUsed(field, options_)) {
- format(" | 0x80000000u // unused\n");
- }
-
// Embed whether the field is eagerly verified lazy or inlined string to the
// LSB of the offset.
if (IsEagerlyVerifiedLazy(field, options_, scc_analyzer_)) {
@@ -2787,11 +2270,12 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
}
if (!inlined_string_indices_.empty()) {
entries += inlined_string_indices_.size();
- for (int inlined_string_indice : inlined_string_indices_) {
- const TProtoStringType index = inlined_string_indice >= 0
- ? StrCat(inlined_string_indice)
- : "~0u";
- format("$1$,\n", index);
+ for (int inlined_string_index : inlined_string_indices_) {
+ const TProtoStringType index =
+ inlined_string_index >= 0
+ ? StrCat(inlined_string_index, ", // inlined_string_index")
+ : "~0u,";
+ format("$1$\n", index);
}
}
@@ -2837,7 +2321,7 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) {
}
if (num_weak_fields_) {
- format("_weak_field_map_.ClearAll();\n");
+ format("$weak_field_map$.ClearAll();\n");
}
format.Outdent();
format(
@@ -2845,8 +2329,20 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) {
"\n");
}
+ArenaDtorNeeds MessageGenerator::NeedsArenaDestructor() const {
+ if (HasSimpleBaseClass(descriptor_, options_)) return ArenaDtorNeeds::kNone;
+ ArenaDtorNeeds needs = ArenaDtorNeeds::kNone;
+ for (const auto* field : FieldRange(descriptor_)) {
+ if (IsFieldStripped(field, options_)) continue;
+ needs =
+ std::max(needs, field_generators_.get(field).NeedsArenaDestructor());
+ }
+ return needs;
+}
+
void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) {
- if (HasSimpleBaseClass(descriptor_, options_)) return;
+ GOOGLE_CHECK(NeedsArenaDestructor() > ArenaDtorNeeds::kNone);
+
Formatter format(printer, variables_);
// Generate the ArenaDtor() method. Track whether any fields actually produced
@@ -2858,56 +2354,33 @@ void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) {
// since that simplifies Arena's destructor list (ordinary function pointers
// rather than member function pointers). _this is the object being
// destructed.
- format(
- "$classname$* _this = reinterpret_cast< $classname$* >(object);\n"
- // avoid an "unused variable" warning in case no fields have dtor code.
- "(void)_this;\n");
+ format("$classname$* _this = reinterpret_cast< $classname$* >(object);\n");
- bool need_registration = false;
// Process non-oneof fields first.
for (auto field : optimized_order_) {
- if (field_generators_.get(field).GenerateArenaDestructorCode(printer)) {
- need_registration = true;
- }
+ if (IsFieldStripped(field, options_)) continue;
+ const FieldGenerator& fg = field_generators_.get(field);
+ fg.GenerateArenaDestructorCode(printer);
}
// Process oneof fields.
- //
- // Note: As of 10/5/2016, GenerateArenaDestructorCode does not emit anything
- // and returns false for oneof fields.
for (auto oneof : OneOfRange(descriptor_)) {
for (auto field : FieldRange(oneof)) {
- if (!IsFieldStripped(field, options_) &&
- field_generators_.get(field).GenerateArenaDestructorCode(printer)) {
- need_registration = true;
- }
+ if (IsFieldStripped(field, options_)) continue;
+ field_generators_.get(field).GenerateArenaDestructorCode(printer);
}
}
format.Outdent();
format("}\n");
-
- if (need_registration) {
- format(
- "inline void $classname$::RegisterArenaDtor(::$proto_ns$::Arena* "
- "arena) {\n"
- " if (arena != nullptr) {\n"
- " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n"
- " }\n"
- "}\n");
- } else {
- format(
- "void $classname$::RegisterArenaDtor(::$proto_ns$::Arena*) {\n"
- "}\n");
- }
}
void MessageGenerator::GenerateConstexprConstructor(io::Printer* printer) {
Formatter format(printer, variables_);
format(
- "constexpr $classname$::$classname$(\n"
- " ::$proto_ns$::internal::ConstantInitialized)");
+ "PROTOBUF_CONSTEXPR $classname$::$classname$(\n"
+ " ::_pbi::ConstantInitialized)");
format.Indent();
const char* field_sep = ":";
const auto put_sep = [&] {
@@ -2953,16 +2426,16 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer,
TProtoStringType pod_template;
if (copy_constructor) {
pod_template =
- "::memcpy(&$first$_, &from.$first$_,\n"
- " static_cast<size_t>(reinterpret_cast<char*>(&$last$_) -\n"
- " reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n";
+ "::memcpy(&$first$, &from.$first$,\n"
+ " static_cast<size_t>(reinterpret_cast<char*>(&$last$) -\n"
+ " reinterpret_cast<char*>(&$first$)) + sizeof($last$));\n";
} else {
pod_template =
"::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(\n"
- " reinterpret_cast<char*>(&$first$_) - "
+ " reinterpret_cast<char*>(&$first$) - "
"reinterpret_cast<char*>(this)),\n"
- " 0, static_cast<size_t>(reinterpret_cast<char*>(&$last$_) -\n"
- " reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n";
+ " 0, static_cast<size_t>(reinterpret_cast<char*>(&$last$) -\n"
+ " reinterpret_cast<char*>(&$first$)) + sizeof($last$));\n";
}
for (int i = 0; i < optimized_order_.size(); ++i) {
@@ -2978,9 +2451,9 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer,
if (it != runs.end() && it->second > 1) {
// Use a memset, then skip run_length fields.
const size_t run_length = it->second;
- const TProtoStringType first_field_name = FieldName(field);
+ const TProtoStringType first_field_name = FieldMemberName(field);
const TProtoStringType last_field_name =
- FieldName(optimized_order_[i + run_length - 1]);
+ FieldMemberName(optimized_order_[i + run_length - 1]);
format.Set("first", first_field_name);
format.Set("last", last_field_name);
@@ -3049,19 +2522,37 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) {
if (!inlined_string_indices_.empty()) {
// Donate inline string fields.
- format(" if (arena != nullptr) {\n");
- for (size_t i = 0; i < InlinedStringDonatedSize(); ++i) {
- format(" _inlined_string_donated_[$1$] = ~0u;\n", i);
+ format.Indent();
+ // The last bit is the tracking bit for registering ArenaDtor. The bit is 1
+ // means ArenaDtor is not registered on construction, and on demand register
+ // is needed.
+ format("if (arena != nullptr) {\n");
+ if (NeedsArenaDestructor() == ArenaDtorNeeds::kOnDemand) {
+ format(
+ " if (!is_message_owned) {\n"
+ " $inlined_string_donated_array$[0] = ~0u;\n"
+ " } else {\n"
+ // We should not register ArenaDtor for MOA.
+ " $inlined_string_donated_array$[0] = 0xFFFFFFFEu;\n"
+ " }\n");
+ } else {
+ format(" $inlined_string_donated_array$[0] = 0xFFFFFFFEu;\n");
}
- format(" }\n");
+ for (size_t i = 1; i < InlinedStringDonatedSize(); ++i) {
+ format(" $inlined_string_donated_array$[$1$] = ~0u;\n", i);
+ }
+ format("}\n");
+ format.Outdent();
}
if (!HasSimpleBaseClass(descriptor_, options_)) {
- format(
- " SharedCtor();\n"
- " if (!is_message_owned) {\n"
- " RegisterArenaDtor(arena);\n"
- " }\n");
+ format(" SharedCtor();\n");
+ if (NeedsArenaDestructor() == ArenaDtorNeeds::kRequired) {
+ format(
+ " if (arena != nullptr && !is_message_owned) {\n"
+ " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n"
+ " }\n");
+ }
}
format(
" // @@protoc_insertion_point(arena_constructor:$full_name$)\n"
@@ -3126,8 +2617,8 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
format(
- "_extensions_.MergeFrom(internal_default_instance(), "
- "from._extensions_);\n");
+ "$extensions$.MergeFrom(internal_default_instance(), "
+ "from.$extensions$);\n");
}
GenerateConstructorBody(printer, processed, true);
@@ -3172,10 +2663,19 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) {
if (!HasSimpleBaseClass(descriptor_, options_)) {
format(
"$classname$::~$classname$() {\n"
- " // @@protoc_insertion_point(destructor:$full_name$)\n"
- " if (GetArenaForAllocation() != nullptr) return;\n"
+ " // @@protoc_insertion_point(destructor:$full_name$)\n");
+ format(
+ " if (auto *arena = "
+ "_internal_metadata_.DeleteReturnArena<$unknown_fields_type$>()) {\n"
+ " (void)arena;\n");
+ if (NeedsArenaDestructor() > ArenaDtorNeeds::kNone) {
+ format(" ArenaDtor(this);\n");
+ }
+ format(
+ " return;\n"
+ " }\n");
+ format(
" SharedDtor();\n"
- " _internal_metadata_.Delete<$unknown_fields_type$>();\n"
"}\n"
"\n");
} else {
@@ -3190,13 +2690,15 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) {
GenerateSharedDestructorCode(printer);
// Generate the arena-specific destructor code.
- GenerateArenaDestructorCode(printer);
+ if (NeedsArenaDestructor() > ArenaDtorNeeds::kNone) {
+ GenerateArenaDestructorCode(printer);
+ }
if (!HasSimpleBaseClass(descriptor_, options_)) {
// Generate SetCachedSize.
format(
"void $classname$::SetCachedSize(int size) const {\n"
- " _cached_size_.Set(size);\n"
+ " $cached_size$.Set(size);\n"
"}\n");
}
}
@@ -3205,8 +2707,8 @@ void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) {
Formatter format(printer, variables_);
format(
"template<> "
- "PROTOBUF_NOINLINE "
- "$classtype$* Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n"
+ "PROTOBUF_NOINLINE $classtype$*\n"
+ "Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n"
" return Arena::CreateMessageInternal< $classtype$ >(arena);\n"
"}\n");
}
@@ -3232,7 +2734,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
"(void) cached_has_bits;\n\n");
if (descriptor_->extension_range_count() > 0) {
- format("_extensions_.Clear();\n");
+ format("$extensions$.Clear();\n");
}
// Collect fields into chunks. Each chunk may have an if() condition that
@@ -3305,7 +2807,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
if (cached_has_word_index != HasWordIndex(chunk.front())) {
cached_has_word_index = HasWordIndex(chunk.front());
- format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index);
+ format("cached_has_bits = $has_bits$[$1$];\n", cached_has_word_index);
}
format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str);
format.Indent();
@@ -3318,10 +2820,10 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
.GenerateMessageClearingCode(printer);
} else {
format(
- "::memset(&$1$_, 0, static_cast<size_t>(\n"
- " reinterpret_cast<char*>(&$2$_) -\n"
- " reinterpret_cast<char*>(&$1$_)) + sizeof($2$_));\n",
- FieldName(memset_start), FieldName(memset_end));
+ "::memset(&$1$, 0, static_cast<size_t>(\n"
+ " reinterpret_cast<char*>(&$2$) -\n"
+ " reinterpret_cast<char*>(&$1$)) + sizeof($2$));\n",
+ FieldMemberName(memset_start), FieldMemberName(memset_end));
}
}
@@ -3367,14 +2869,14 @@ void MessageGenerator::GenerateClear(io::Printer* printer) {
}
if (num_weak_fields_) {
- format("_weak_field_map_.ClearAll();\n");
+ format("$weak_field_map$.ClearAll();\n");
}
// We don't clear donated status.
if (!has_bit_indices_.empty()) {
// Step 5: Everything else.
- format("_has_bits_.Clear();\n");
+ format("$has_bits$.Clear();\n");
}
std::map<TProtoStringType, TProtoStringType> vars;
@@ -3420,7 +2922,7 @@ void MessageGenerator::GenerateOneofClear(io::Printer* printer) {
format.Outdent();
format(
"}\n"
- "_oneof_case_[$1$] = $2$_NOT_SET;\n",
+ "$oneof_case$[$1$] = $2$_NOT_SET;\n",
i, ToUpper(oneof->name()));
format.Outdent();
format(
@@ -3440,7 +2942,9 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) {
if (HasGeneratedMethods(descriptor_->file(), options_)) {
if (descriptor_->extension_range_count() > 0) {
- format("_extensions_.InternalSwap(&other->_extensions_);\n");
+ format(
+ "$extensions$.InternalSwap(&other->$extensions$);"
+ "\n");
}
std::map<TProtoStringType, TProtoStringType> vars;
@@ -3455,7 +2959,7 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) {
if (!has_bit_indices_.empty()) {
for (int i = 0; i < HasBitsSize(); ++i) {
- format("swap(_has_bits_[$1$], other->_has_bits_[$1$]);\n", i);
+ format("swap($has_bits$[$1$], other->$has_bits$[$1$]);\n", i);
}
}
@@ -3475,20 +2979,20 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) {
if (it != runs.end() && it->second > 1) {
// Use a memswap, then skip run_length fields.
const size_t run_length = it->second;
- const TProtoStringType first_field_name = FieldName(field);
+ const TProtoStringType first_field_name = FieldMemberName(field);
const TProtoStringType last_field_name =
- FieldName(optimized_order_[i + run_length - 1]);
+ FieldMemberName(optimized_order_[i + run_length - 1]);
format.Set("first", first_field_name);
format.Set("last", last_field_name);
format(
"::PROTOBUF_NAMESPACE_ID::internal::memswap<\n"
- " PROTOBUF_FIELD_OFFSET($classname$, $last$_)\n"
- " + sizeof($classname$::$last$_)\n"
- " - PROTOBUF_FIELD_OFFSET($classname$, $first$_)>(\n"
- " reinterpret_cast<char*>(&$first$_),\n"
- " reinterpret_cast<char*>(&other->$first$_));\n");
+ " PROTOBUF_FIELD_OFFSET($classname$, $last$)\n"
+ " + sizeof($classname$::$last$)\n"
+ " - PROTOBUF_FIELD_OFFSET($classname$, $first$)>(\n"
+ " reinterpret_cast<char*>(&$first$),\n"
+ " reinterpret_cast<char*>(&other->$first$));\n");
i += run_length - 1;
// ++i at the top of the loop.
@@ -3502,11 +3006,25 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) {
}
for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
- format("swap(_oneof_case_[$1$], other->_oneof_case_[$1$]);\n", i);
+ format(
+ "swap($oneof_case$[$1$], "
+ "other->$oneof_case$[$1$]);\n",
+ i);
}
if (num_weak_fields_) {
- format("_weak_field_map_.UnsafeArenaSwap(&other->_weak_field_map_);\n");
+ format(
+ "$weak_field_map$.UnsafeArenaSwap(&other->$weak_field_map$)"
+ ";\n");
+ }
+
+ if (!inlined_string_indices_.empty()) {
+ for (size_t i = 0; i < InlinedStringDonatedSize(); ++i) {
+ format(
+ "swap($inlined_string_donated_array$[$1$], "
+ "other->$inlined_string_donated_array$[$1$]);\n",
+ i);
+ }
}
} else {
format("GetReflection()->Swap(this, other);");
@@ -3549,7 +3067,7 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* printer) {
format(
"void $classname$::CheckTypeAndMergeFrom(\n"
" const ::$proto_ns$::MessageLite& from) {\n"
- " MergeFrom(*::$proto_ns$::internal::DownCast<const $classname$*>(\n"
+ " MergeFrom(*::_pbi::DownCast<const $classname$*>(\n"
" &from));\n"
"}\n");
}
@@ -3619,7 +3137,7 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) {
if (cached_has_word_index != HasWordIndex(chunk.front())) {
cached_has_word_index = HasWordIndex(chunk.front());
- format("cached_has_bits = from._has_bits_[$1$];\n",
+ format("cached_has_bits = from.$has_bits$[$1$];\n",
cached_has_word_index);
}
@@ -3680,7 +3198,7 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) {
if (deferred_has_bit_changes) {
// Flush the has bits for the primitives we deferred.
GOOGLE_CHECK_LE(0, cached_has_word_index);
- format("_has_bits_[$1$] |= cached_has_bits;\n", cached_has_word_index);
+ format("$has_bits$[$1$] |= cached_has_bits;\n", cached_has_word_index);
}
format.Outdent();
@@ -3716,15 +3234,17 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) {
format("}\n");
}
if (num_weak_fields_) {
- format("_weak_field_map_.MergeFrom(from._weak_field_map_);\n");
+ format(
+ "$weak_field_map$.MergeFrom(from.$weak_field_map$);"
+ "\n");
}
// Merging of extensions and unknown fields is done last, to maximize
// the opportunity for tail calls.
if (descriptor_->extension_range_count() > 0) {
format(
- "_extensions_.MergeFrom(internal_default_instance(), "
- "from._extensions_);\n");
+ "$extensions$.MergeFrom(internal_default_instance(), "
+ "from.$extensions$);\n");
}
format(
@@ -3860,7 +3380,7 @@ void MessageGenerator::GenerateSerializeOneExtensionRange(
Formatter format(printer, vars);
format("// Extension range [$start$, $end$)\n");
format(
- "target = _extensions_._InternalSerialize(\n"
+ "target = $extensions$._InternalSerialize(\n"
"internal_default_instance(), $start$, $end$, target, stream);\n\n");
}
@@ -3875,14 +3395,14 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray(
" $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
"const {\n"
"$annotate_serialize$"
- " target = _extensions_."
+ " target = $extensions$."
"InternalSerializeMessageSetWithCachedSizesToArray(\n" //
"internal_default_instance(), target, stream);\n");
std::map<TProtoStringType, TProtoStringType> vars;
SetUnknownFieldsVariable(descriptor_, options_, &vars);
format.AddMap(vars);
format(
- " target = ::$proto_ns$::internal::"
+ " target = ::_pbi::"
"InternalSerializeUnknownMessageSetItemsToArray(\n"
" $unknown_fields$, target, stream);\n");
format(
@@ -4077,8 +3597,8 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody(
ExtensionRangeSorter());
if (num_weak_fields_) {
format(
- "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer("
- "_weak_field_map_);\n");
+ "::_pbi::WeakFieldMap::FieldWriter field_writer("
+ "$weak_field_map$);\n");
}
format(
@@ -4126,7 +3646,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody(
if (UseUnknownFieldSet(descriptor_->file(), options_)) {
format(
"target = "
- "::$proto_ns$::internal::WireFormat::"
+ "::_pbi::WireFormat::"
"InternalSerializeUnknownFieldsToArray(\n"
" $unknown_fields$, target, stream);\n");
} else {
@@ -4167,8 +3687,8 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled(
if (num_weak_fields_) {
format(
- "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer("
- "_weak_field_map_);\n");
+ "::_pbi::WeakFieldMap::FieldWriter field_writer("
+ "$weak_field_map$);\n");
}
format("for (int i = $1$; i >= 0; i-- ) {\n", num_fields - 1);
@@ -4218,7 +3738,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled(
if (UseUnknownFieldSet(descriptor_->file(), options_)) {
format(
"target = "
- "::$proto_ns$::internal::WireFormat::"
+ "::_pbi::WireFormat::"
"InternalSerializeUnknownFieldsToArray(\n"
" $unknown_fields$, target, stream);\n");
} else {
@@ -4259,13 +3779,13 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) {
"size_t $classname$::ByteSizeLong() const {\n"
"$annotate_bytesize$"
"// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n"
- " size_t total_size = _extensions_.MessageSetByteSize();\n"
+ " size_t total_size = $extensions$.MessageSetByteSize();\n"
" if ($have_unknown_fields$) {\n"
- " total_size += ::$proto_ns$::internal::\n"
+ " total_size += ::_pbi::\n"
" ComputeUnknownMessageSetItemsSize($unknown_fields$);\n"
" }\n"
" int cached_size = "
- "::$proto_ns$::internal::ToCachedSize(total_size);\n"
+ "::_pbi::ToCachedSize(total_size);\n"
" SetCachedSize(cached_size);\n"
" return total_size;\n"
"}\n");
@@ -4312,7 +3832,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
format(
- "total_size += _extensions_.ByteSize();\n"
+ "total_size += $extensions$.ByteSize();\n"
"\n");
}
@@ -4393,7 +3913,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) {
if (cached_has_word_index != HasWordIndex(chunk.front())) {
cached_has_word_index = HasWordIndex(chunk.front());
- format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index);
+ format("cached_has_bits = $has_bits$[$1$];\n", cached_has_word_index);
}
format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str);
format.Indent();
@@ -4473,7 +3993,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) {
if (num_weak_fields_) {
// TagSize + MessageSize
- format("total_size += _weak_field_map_.ByteSizeLong();\n");
+ format("total_size += $weak_field_map$.ByteSizeLong();\n");
}
if (UseUnknownFieldSet(descriptor_->file(), options_)) {
@@ -4481,7 +4001,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) {
// unknown fields in tail position. This allows for better code generation
// of this function for simple protos.
format(
- "return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);\n");
+ "return MaybeComputeUnknownFieldsSize(total_size, &$cached_size$);\n");
} else {
format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n");
format(" total_size += $unknown_fields$.size();\n");
@@ -4496,7 +4016,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) {
// where even relaxed memory order might have perf impact to replace it with
// ordinary loads and stores.
format(
- "int cached_size = ::$proto_ns$::internal::ToCachedSize(total_size);\n"
+ "int cached_size = ::_pbi::ToCachedSize(total_size);\n"
"SetCachedSize(cached_size);\n"
"return total_size;\n");
}
@@ -4513,14 +4033,14 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
format(
- "if (!_extensions_.IsInitialized()) {\n"
+ "if (!$extensions$.IsInitialized()) {\n"
" return false;\n"
"}\n\n");
}
if (num_required_fields_ > 0) {
format(
- "if (_Internal::MissingRequiredFields(_has_bits_))"
+ "if (_Internal::MissingRequiredFields($has_bits$))"
" return false;\n");
}
@@ -4530,7 +4050,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
}
if (num_weak_fields_) {
// For Weak fields.
- format("if (!_weak_field_map_.IsInitialized()) return false;\n");
+ format("if (!$weak_field_map$.IsInitialized()) return false;\n");
}
// Go through the oneof fields, emitting a switch if any might have required
// fields.
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message.h
index 939f21a1dac..5e4bbe84b83 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -96,22 +96,10 @@ class MessageGenerator {
void GenerateFieldAccessorDeclarations(io::Printer* printer);
void GenerateFieldAccessorDefinitions(io::Printer* printer);
- // Generate the table-driven parsing array. Returns the number of entries
- // generated.
- size_t GenerateParseOffsets(io::Printer* printer);
- size_t GenerateParseAuxTable(io::Printer* printer);
- // Generates a ParseTable entry. Returns whether the proto uses
- // table-driven parsing.
- bool GenerateParseTable(io::Printer* printer, size_t offset,
- size_t aux_offset);
-
// Generate the field offsets array. Returns the a pair of the total number
// of entries generated and the index of the first has_bit entry.
std::pair<size_t, size_t> GenerateOffsets(io::Printer* printer);
void GenerateSchema(io::Printer* printer, int offset, int has_offset);
- // For each field generates a table entry describing the field for the
- // table driven serializer.
- int GenerateFieldMetadata(io::Printer* printer);
// Generate constructors and destructor.
void GenerateStructors(io::Printer* printer);
@@ -177,6 +165,18 @@ class MessageGenerator {
std::vector<bool> already_processed,
bool copy_constructor) const;
+ // Returns the level that this message needs ArenaDtor. If the message has
+ // a field that is not arena-exclusive, it needs an ArenaDtor
+ // (go/proto-destructor).
+ //
+ // - Returning kNone means we don't need to generate ArenaDtor.
+ // - Returning kOnDemand means we need to generate ArenaDtor, but don't need
+ // to register ArenaDtor at construction. Such as when the message's
+ // ArenaDtor code is only for destructing inlined string.
+ // - Returning kRequired means we meed to generate ArenaDtor and register it
+ // at construction.
+ ArenaDtorNeeds NeedsArenaDestructor() const;
+
size_t HasBitsSize() const;
size_t InlinedStringDonatedSize() const;
int HasBitIndex(const FieldDescriptor* a) const;
@@ -200,7 +200,8 @@ class MessageGenerator {
int max_has_bit_index_;
// A map from field index to inlined_string index. For non-inlined-string
- // fields, the element is -1.
+ // fields, the element is -1. If there is no inlined string in the message,
+ // this is empty.
std::vector<int> inlined_string_indices_;
// The count of inlined_string fields in the message.
int max_inlined_string_index_;
@@ -209,8 +210,6 @@ class MessageGenerator {
std::vector<const ExtensionGenerator*> extension_generators_;
int num_required_fields_;
int num_weak_fields_;
- // table_driven_ indicates the generated message uses table-driven parsing.
- bool table_driven_;
std::unique_ptr<MessageLayoutHelper> message_layout_helper_;
std::unique_ptr<ParseFunctionGenerator> parse_function_generator_;
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index 04f45492c31..3b9f09c8c8b 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -33,8 +33,9 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/cpp_message_field.h>
-#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+
#include <google/protobuf/io/printer.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/stubs/strutil.h>
@@ -60,11 +61,16 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
SetCommonFieldVariables(descriptor, variables, options);
(*variables)["type"] = FieldMessageTypeName(descriptor, options);
(*variables)["casted_member"] = ReinterpretCast(
- (*variables)["type"] + "*", (*variables)["name"] + "_", implicit_weak);
+ (*variables)["type"] + "*", (*variables)["field"], implicit_weak);
+ (*variables)["casted_member_const"] =
+ ReinterpretCast("const " + (*variables)["type"] + "&",
+ "*" + (*variables)["field"], implicit_weak);
(*variables)["type_default_instance"] =
QualifiedDefaultInstanceName(descriptor->message_type(), options);
- (*variables)["type_default_instance_ptr"] =
- QualifiedDefaultInstancePtr(descriptor->message_type(), options);
+ (*variables)["type_default_instance_ptr"] = ReinterpretCast(
+ "const ::PROTOBUF_NAMESPACE_ID::MessageLite*",
+ QualifiedDefaultInstancePtr(descriptor->message_type(), options),
+ implicit_weak);
(*variables)["type_reference_function"] =
implicit_weak ? (" ::" + (*variables)["proto_ns"] +
"::internal::StrongReference(reinterpret_cast<const " +
@@ -176,14 +182,13 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
// If we're not on an arena, free whatever we were holding before.
// (If we are on arena, we can just forget the earlier pointer.)
" if (GetArenaForAllocation() == nullptr) {\n"
- " delete reinterpret_cast<::$proto_ns$::MessageLite*>($name$_);\n"
+ " delete reinterpret_cast<::$proto_ns$::MessageLite*>($field$);\n"
" }\n");
if (implicit_weak_field_) {
format(
- " $name$_ = "
- "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n");
+ " $field$ = reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n");
} else {
- format(" $name$_ = $name$;\n");
+ format(" $field$ = $name$;\n");
}
format(
" if ($name$) {\n"
@@ -201,7 +206,7 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
"$annotate_release$"
" $clear_hasbit$\n"
" $type$* temp = $casted_member$;\n"
- " $name$_ = nullptr;\n"
+ " $field$ = nullptr;\n"
"#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE\n"
" auto* old = reinterpret_cast<::$proto_ns$::MessageLite*>(temp);\n"
" temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
@@ -219,7 +224,7 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
"$type_reference_function$"
" $clear_hasbit$\n"
" $type$* temp = $casted_member$;\n"
- " $name$_ = nullptr;\n"
+ " $field$ = nullptr;\n"
" return temp;\n"
"}\n");
@@ -227,12 +232,12 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
"inline $type$* $classname$::_internal_mutable_$name$() {\n"
"$type_reference_function$"
" $set_hasbit$\n"
- " if ($name$_ == nullptr) {\n"
+ " if ($field$ == nullptr) {\n"
" auto* p = CreateMaybeMessage<$type$>(GetArenaForAllocation());\n");
if (implicit_weak_field_) {
- format(" $name$_ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n");
+ format(" $field$ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n");
} else {
- format(" $name$_ = p;\n");
+ format(" $field$ = p;\n");
}
format(
" }\n"
@@ -253,9 +258,9 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
format(" if (message_arena == nullptr) {\n");
if (IsCrossFileMessage(descriptor_)) {
format(
- " delete reinterpret_cast< ::$proto_ns$::MessageLite*>($name$_);\n");
+ " delete reinterpret_cast< ::$proto_ns$::MessageLite*>($field$);\n");
} else {
- format(" delete $name$_;\n");
+ format(" delete $field$;\n");
}
format(
" }\n"
@@ -265,14 +270,13 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
// isn't defined in this file.
format(
" ::$proto_ns$::Arena* submessage_arena =\n"
- " ::$proto_ns$::Arena::InternalHelper<\n"
- " ::$proto_ns$::MessageLite>::GetOwningArena(\n"
+ " ::$proto_ns$::Arena::InternalGetOwningArena(\n"
" reinterpret_cast<::$proto_ns$::MessageLite*>("
"$name$));\n");
} else {
format(
" ::$proto_ns$::Arena* submessage_arena =\n"
- " ::$proto_ns$::Arena::InternalHelper<$type$>::GetOwningArena("
+ " ::$proto_ns$::Arena::InternalGetOwningArena("
"$name$);\n");
}
format(
@@ -285,9 +289,9 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
" $clear_hasbit$\n"
" }\n");
if (implicit_weak_field_) {
- format(" $name$_ = reinterpret_cast<MessageLite*>($name$);\n");
+ format(" $field$ = reinterpret_cast<MessageLite*>($name$);\n");
} else {
- format(" $name$_ = $name$;\n");
+ format(" $field$ = $name$;\n");
}
format(
"$annotate_set$"
@@ -322,14 +326,10 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions(
format(
"const ::$proto_ns$::MessageLite& $classname$::_Internal::$name$(\n"
" const $classname$* msg) {\n"
- " if (msg->$name$_ != nullptr) {\n"
- " return *msg->$name$_;\n"
- " } else if ($type_default_instance_ptr$ != nullptr) {\n"
- " return *reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
- " $type_default_instance_ptr$);\n"
+ " if (msg->$field$ != nullptr) {\n"
+ " return *msg->$field$;\n"
" } else {\n"
- " return "
- "*::$proto_ns$::internal::ImplicitWeakMessage::default_instance();\n"
+ " return *$type_default_instance_ptr$;\n"
" }\n"
"}\n");
format(
@@ -338,20 +338,19 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions(
if (HasHasbit(descriptor_)) {
format(" msg->$set_hasbit$\n");
}
+ if (descriptor_->real_containing_oneof() == nullptr) {
+ format(" if (msg->$field$ == nullptr) {\n");
+ } else {
+ format(
+ " if (!msg->_internal_has_$name$()) {\n"
+ " msg->clear_$oneof_name$();\n"
+ " msg->set_has_$name$();\n");
+ }
format(
- " if (msg->$name$_ == nullptr) {\n"
- " if ($type_default_instance_ptr$ == nullptr) {\n"
- " msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n"
- " ::$proto_ns$::internal::ImplicitWeakMessage>(\n"
- " msg->GetArenaForAllocation());\n"
- " } else {\n"
- " msg->$name$_ = \n"
- " reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
- " $type_default_instance_ptr$)->New(\n"
- " msg->GetArenaForAllocation());\n"
- " }\n"
+ " msg->$field$ = $type_default_instance_ptr$->New(\n"
+ " msg->GetArenaForAllocation());\n"
" }\n"
- " return msg->$name$_;\n"
+ " return msg->$field$;\n"
"}\n");
} else {
// This inline accessor directly returns member field and is used in
@@ -360,7 +359,7 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions(
format(
"const $type$&\n"
"$classname$::_Internal::$name$(const $classname$* msg) {\n"
- " return *msg->$field_member$;\n"
+ " return *msg->$field$;\n"
"}\n");
}
}
@@ -371,14 +370,14 @@ void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
Formatter format(printer, variables_);
if (!HasHasbit(descriptor_)) {
// If we don't have has-bits, message presence is indicated only by ptr !=
- // NULL. Thus on clear, we need to delete the object.
+ // nullptr. Thus on clear, we need to delete the object.
format(
- "if (GetArenaForAllocation() == nullptr && $name$_ != nullptr) {\n"
- " delete $name$_;\n"
+ "if (GetArenaForAllocation() == nullptr && $field$ != nullptr) {\n"
+ " delete $field$;\n"
"}\n"
- "$name$_ = nullptr;\n");
+ "$field$ = nullptr;\n");
} else {
- format("if ($name$_ != nullptr) $name$_->Clear();\n");
+ format("if ($field$ != nullptr) $field$->Clear();\n");
}
}
@@ -389,16 +388,16 @@ void MessageFieldGenerator::GenerateMessageClearingCode(
Formatter format(printer, variables_);
if (!HasHasbit(descriptor_)) {
// If we don't have has-bits, message presence is indicated only by ptr !=
- // NULL. Thus on clear, we need to delete the object.
+ // nullptr. Thus on clear, we need to delete the object.
format(
- "if (GetArenaForAllocation() == nullptr && $name$_ != nullptr) {\n"
- " delete $name$_;\n"
+ "if (GetArenaForAllocation() == nullptr && $field$ != nullptr) {\n"
+ " delete $field$;\n"
"}\n"
- "$name$_ = nullptr;\n");
+ "$field$ = nullptr;\n");
} else {
format(
- "$DCHK$($name$_ != nullptr);\n"
- "$name$_->Clear();\n");
+ "$DCHK$($field$ != nullptr);\n"
+ "$field$->Clear();\n");
}
}
@@ -421,7 +420,7 @@ void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
Formatter format(printer, variables_);
- format("swap($name$_, other->$name$_);\n");
+ format("swap($field$, other->$field$);\n");
}
void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
@@ -436,7 +435,7 @@ void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
// care when handling them.
format("if (this != internal_default_instance()) ");
}
- format("delete $name$_;\n");
+ format("delete $field$;\n");
}
void MessageFieldGenerator::GenerateConstructorCode(
@@ -444,7 +443,7 @@ void MessageFieldGenerator::GenerateConstructorCode(
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
Formatter format(printer, variables_);
- format("$name$_ = nullptr;\n");
+ format("$field$ = nullptr;\n");
}
void MessageFieldGenerator::GenerateCopyConstructorCode(
@@ -454,9 +453,9 @@ void MessageFieldGenerator::GenerateCopyConstructorCode(
Formatter format(printer, variables_);
format(
"if (from._internal_has_$name$()) {\n"
- " $name$_ = new $type$(*from.$name$_);\n"
+ " $field$ = new $type$(*from.$field$);\n"
"} else {\n"
- " $name$_ = nullptr;\n"
+ " $field$ = nullptr;\n"
"}\n");
}
@@ -465,11 +464,18 @@ void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
Formatter format(printer, variables_);
- format(
- "target = stream->EnsureSpace(target);\n"
- "target = ::$proto_ns$::internal::WireFormatLite::\n"
- " InternalWrite$declared_type$(\n"
- " $number$, _Internal::$name$(this), target, stream);\n");
+ if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
+ format(
+ "target = ::$proto_ns$::internal::WireFormatLite::\n"
+ " InternalWrite$declared_type$($number$, _Internal::$name$(this),\n"
+ " _Internal::$name$(this).GetCachedSize(), target, stream);\n");
+ } else {
+ format(
+ "target = stream->EnsureSpace(target);\n"
+ "target = ::$proto_ns$::internal::WireFormatLite::\n"
+ " InternalWrite$declared_type$(\n"
+ " $number$, _Internal::$name$(this), target, stream);\n");
+ }
}
void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const {
@@ -479,7 +485,7 @@ void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const {
format(
"total_size += $tag_size$ +\n"
" ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
- " *$field_member$);\n");
+ " *$field$);\n");
}
void MessageFieldGenerator::GenerateIsInitialized(io::Printer* printer) const {
@@ -490,7 +496,7 @@ void MessageFieldGenerator::GenerateIsInitialized(io::Printer* printer) const {
Formatter format(printer, variables_);
format(
"if (_internal_has_$name$()) {\n"
- " if (!$name$_->IsInitialized()) return false;\n"
+ " if (!$field$->IsInitialized()) return false;\n"
"}\n");
}
@@ -524,15 +530,13 @@ void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
// isn't defined in this file.
format(
" ::$proto_ns$::Arena* submessage_arena =\n"
- " ::$proto_ns$::Arena::InternalHelper<\n"
- " ::$proto_ns$::MessageLite>::GetOwningArena(\n"
+ " ::$proto_ns$::Arena::InternalGetOwningArena(\n"
" reinterpret_cast<::$proto_ns$::MessageLite*>("
"$name$));\n");
} else {
format(
" ::$proto_ns$::Arena* submessage_arena =\n"
- " ::$proto_ns$::Arena::InternalHelper<"
- "$type$>::GetOwningArena($name$);\n");
+ " ::$proto_ns$::Arena::InternalGetOwningArena($name$);\n");
}
format(
" if (message_arena != submessage_arena) {\n"
@@ -540,7 +544,7 @@ void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
" message_arena, $name$, submessage_arena);\n"
" }\n"
" set_has_$name$();\n"
- " $field_member$ = $name$;\n"
+ " $field$ = $name$;\n"
" }\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
@@ -554,13 +558,14 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
"inline $type$* $classname$::$release_name$() {\n"
"$annotate_release$"
" // @@protoc_insertion_point(field_release:$full_name$)\n"
+ "$type_reference_function$"
" if (_internal_has_$name$()) {\n"
" clear_has_$oneof_name$();\n"
- " $type$* temp = $field_member$;\n"
+ " $type$* temp = $casted_member$;\n"
" if (GetArenaForAllocation() != nullptr) {\n"
" temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
" }\n"
- " $field_member$ = nullptr;\n"
+ " $field$ = nullptr;\n"
" return temp;\n"
" } else {\n"
" return nullptr;\n"
@@ -569,8 +574,9 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
format(
"inline const $type$& $classname$::_internal_$name$() const {\n"
+ "$type_reference_function$"
" return _internal_has_$name$()\n"
- " ? *$field_member$\n"
+ " ? $casted_member_const$\n"
" : reinterpret_cast< $type$&>($type_default_instance$);\n"
"}\n"
"inline const $type$& $classname$::$name$() const {\n"
@@ -582,10 +588,11 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
"$annotate_release$"
" // @@protoc_insertion_point(field_unsafe_arena_release"
":$full_name$)\n"
+ "$type_reference_function$"
" if (_internal_has_$name$()) {\n"
" clear_has_$oneof_name$();\n"
- " $type$* temp = $field_member$;\n"
- " $field_member$ = nullptr;\n"
+ " $type$* temp = $casted_member$;\n"
+ " $field$ = nullptr;\n"
" return temp;\n"
" } else {\n"
" return nullptr;\n"
@@ -598,21 +605,38 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
// new value.
" clear_$oneof_name$();\n"
" if ($name$) {\n"
- " set_has_$name$();\n"
- " $field_member$ = $name$;\n"
+ " set_has_$name$();\n");
+ if (implicit_weak_field_) {
+ format(
+ " $field$ = "
+ "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n");
+ } else {
+ format(" $field$ = $name$;\n");
+ }
+ format(
" }\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
"$full_name$)\n"
"}\n"
"inline $type$* $classname$::_internal_mutable_$name$() {\n"
+ "$type_reference_function$"
" if (!_internal_has_$name$()) {\n"
" clear_$oneof_name$();\n"
- " set_has_$name$();\n"
- " $field_member$ = CreateMaybeMessage< $type$ "
- ">(GetArenaForAllocation());\n"
+ " set_has_$name$();\n");
+ if (implicit_weak_field_) {
+ format(
+ " $field$ = "
+ "reinterpret_cast<::$proto_ns$::MessageLite*>(CreateMaybeMessage< "
+ "$type$ >(GetArenaForAllocation()));\n");
+ } else {
+ format(
+ " $field$ = CreateMaybeMessage< $type$ "
+ ">(GetArenaForAllocation());\n");
+ }
+ format(
" }\n"
- " return $field_member$;\n"
+ " return $casted_member$;\n"
"}\n"
"inline $type$* $classname$::mutable_$name$() {\n"
" $type$* _msg = _internal_mutable_$name$();\n"
@@ -629,7 +653,7 @@ void MessageOneofFieldGenerator::GenerateClearingCode(
Formatter format(printer, variables_);
format(
"if (GetArenaForAllocation() == nullptr) {\n"
- " delete $field_member$;\n"
+ " delete $field$;\n"
"}\n");
}
@@ -662,7 +686,7 @@ void MessageOneofFieldGenerator::GenerateIsInitialized(
Formatter format(printer, variables_);
format(
"if (_internal_has_$name$()) {\n"
- " if (!$field_member$->IsInitialized()) return false;\n"
+ " if (!$field$->IsInitialized()) return false;\n"
"}\n");
}
@@ -741,21 +765,21 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
// TODO(dlj): move insertion points
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
"$type_reference_function$"
- " return $name$_$weak$.Mutable(index);\n"
+ " return $field$$weak$.Mutable(index);\n"
"}\n"
"inline ::$proto_ns$::RepeatedPtrField< $type$ >*\n"
"$classname$::mutable_$name$() {\n"
"$annotate_mutable_list$"
" // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
"$type_reference_function$"
- " return &$name$_$weak$;\n"
+ " return &$field$$weak$;\n"
"}\n");
if (options_.safe_boundary_check) {
format(
"inline const $type$& $classname$::_internal_$name$(int index) const "
"{\n"
- " return $name$_$weak$.InternalCheckedGet(index,\n"
+ " return $field$$weak$.InternalCheckedGet(index,\n"
" reinterpret_cast<const $type$&>($type_default_instance$));\n"
"}\n");
} else {
@@ -763,7 +787,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
"inline const $type$& $classname$::_internal_$name$(int index) const "
"{\n"
"$type_reference_function$"
- " return $name$_$weak$.Get(index);\n"
+ " return $field$$weak$.Get(index);\n"
"}\n");
}
@@ -774,7 +798,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
" return _internal_$name$(index);\n"
"}\n"
"inline $type$* $classname$::_internal_add_$name$() {\n"
- " return $name$_$weak$.Add();\n"
+ " return $field$$weak$.Add();\n"
"}\n"
"inline $type$* $classname$::add_$name$() {\n"
" $type$* _add = _internal_add_$name$();\n"
@@ -789,7 +813,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
"$annotate_list$"
" // @@protoc_insertion_point(field_list:$full_name$)\n"
"$type_reference_function$"
- " return $name$_$weak$;\n"
+ " return $field$$weak$;\n"
"}\n");
}
@@ -798,7 +822,7 @@ void RepeatedMessageFieldGenerator::GenerateClearingCode(
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
Formatter format(printer, variables_);
- format("$name$_.Clear();\n");
+ format("$field$.Clear();\n");
}
void RepeatedMessageFieldGenerator::GenerateMergingCode(
@@ -806,7 +830,7 @@ void RepeatedMessageFieldGenerator::GenerateMergingCode(
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
Formatter format(printer, variables_);
- format("$name$_.MergeFrom(from.$name$_);\n");
+ format("$field$.MergeFrom(from.$field$);\n");
}
void RepeatedMessageFieldGenerator::GenerateSwappingCode(
@@ -814,7 +838,7 @@ void RepeatedMessageFieldGenerator::GenerateSwappingCode(
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
Formatter format(printer, variables_);
- format("$name$_.InternalSwap(&other->$name$_);\n");
+ format("$field$.InternalSwap(&other->$field$);\n");
}
void RepeatedMessageFieldGenerator::GenerateConstructorCode(
@@ -829,23 +853,41 @@ void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
Formatter format(printer, variables_);
if (implicit_weak_field_) {
format(
- "for (auto it = this->$name$_.pointer_begin(),\n"
- " end = this->$name$_.pointer_end(); it < end; ++it) {\n"
- " target = stream->EnsureSpace(target);\n"
- " target = ::$proto_ns$::internal::WireFormatLite::\n"
- " InternalWrite$declared_type$($number$, **it, target, stream);\n"
- "}\n");
+ "for (auto it = this->$field$.pointer_begin(),\n"
+ " end = this->$field$.pointer_end(); it < end; ++it) {\n");
+ if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
+ format(
+ " target = ::$proto_ns$::internal::WireFormatLite::\n"
+ " InternalWrite$declared_type$($number$, "
+ "**it, (**it).GetCachedSize(), target, stream);\n");
+ } else {
+ format(
+ " target = stream->EnsureSpace(target);\n"
+ " target = ::$proto_ns$::internal::WireFormatLite::\n"
+ " InternalWrite$declared_type$($number$, **it, target, "
+ "stream);\n");
+ }
+ format("}\n");
} else {
format(
- "for (unsigned int i = 0,\n"
- " n = static_cast<unsigned int>(this->_internal_$name$_size()); i < "
- "n; i++) "
- "{\n"
- " target = stream->EnsureSpace(target);\n"
- " target = ::$proto_ns$::internal::WireFormatLite::\n"
- " InternalWrite$declared_type$($number$, "
- "this->_internal_$name$(i), target, stream);\n"
- "}\n");
+ "for (unsigned i = 0,\n"
+ " n = static_cast<unsigned>(this->_internal_$name$_size());"
+ " i < n; i++) {\n");
+ if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
+ format(
+ " const auto& repfield = this->_internal_$name$(i);\n"
+ " target = ::$proto_ns$::internal::WireFormatLite::\n"
+ " InternalWrite$declared_type$($number$, "
+ "repfield, repfield.GetCachedSize(), target, stream);\n"
+ "}\n");
+ } else {
+ format(
+ " target = stream->EnsureSpace(target);\n"
+ " target = ::$proto_ns$::internal::WireFormatLite::\n"
+ " InternalWrite$declared_type$($number$, "
+ "this->_internal_$name$(i), target, stream);\n"
+ "}\n");
+ }
}
}
@@ -856,7 +898,7 @@ void RepeatedMessageFieldGenerator::GenerateByteSize(
Formatter format(printer, variables_);
format(
"total_size += $tag_size$UL * this->_internal_$name$_size();\n"
- "for (const auto& msg : this->$name$_) {\n"
+ "for (const auto& msg : this->$field$) {\n"
" total_size +=\n"
" ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(msg);\n"
"}\n");
@@ -871,11 +913,11 @@ void RepeatedMessageFieldGenerator::GenerateIsInitialized(
Formatter format(printer, variables_);
if (implicit_weak_field_) {
format(
- "if (!::$proto_ns$::internal::AllAreInitializedWeak($name$_.weak))\n"
+ "if (!::$proto_ns$::internal::AllAreInitializedWeak($field$.weak))\n"
" return false;\n");
} else {
format(
- "if (!::$proto_ns$::internal::AllAreInitialized($name$_))\n"
+ "if (!::$proto_ns$::internal::AllAreInitialized($field$))\n"
" return false;\n");
}
}
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_field.h
index 2beac6253b9..528b4197048 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_field.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_field.h
@@ -37,6 +37,7 @@
#include <map>
#include <string>
+
#include <google/protobuf/compiler/cpp/cpp_field.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h
index 9d8063d9cab..80860053f17 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h
@@ -35,8 +35,8 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__
-#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
namespace google {
namespace protobuf {
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_names.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_names.h
index 8b745ff21c5..39563cd0cdf 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_names.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_names.h
@@ -33,6 +33,7 @@
#include <string>
+// Must be included last.
#include <google/protobuf/port_def.inc>
namespace google {
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_options.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_options.h
index 23adb91430e..48512a64c87 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_options.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_options.h
@@ -58,34 +58,39 @@ struct FieldListenerOptions {
// Generator options (see generator.cc for a description of each):
struct Options {
+ const AccessInfoMap* access_info_map = nullptr;
TProtoStringType dllexport_decl;
+ TProtoStringType runtime_include_base;
+ TProtoStringType annotation_pragma_name;
+ TProtoStringType annotation_guard_name;
+ FieldListenerOptions field_listener_options;
+ EnforceOptimizeMode enforce_mode = EnforceOptimizeMode::kNoEnforcement;
+ enum {
+ kTCTableNever,
+ kTCTableGuarded,
+ kTCTableAlways
+ } tctable_mode = kTCTableNever;
+ int num_cc_files = 0;
bool safe_boundary_check = false;
bool proto_h = false;
bool transitive_pb_h = true;
bool annotate_headers = false;
- EnforceOptimizeMode enforce_mode = EnforceOptimizeMode::kNoEnforcement;
- bool table_driven_parsing = false;
- bool table_driven_serialization = false;
bool lite_implicit_weak_fields = false;
bool bootstrap = false;
bool opensource_runtime = false;
bool annotate_accessor = false;
bool unused_field_stripping = false;
+ bool unverified_lazy_message_sets = true;
+ bool eagerly_verified_lazy = true;
bool profile_driven_inline_string = true;
- bool force_inline_string = false;
- TProtoStringType runtime_include_base;
- int num_cc_files = 0;
- TProtoStringType annotation_pragma_name;
- TProtoStringType annotation_guard_name;
- const AccessInfoMap* access_info_map = nullptr;
- enum {
- kTCTableNever,
- kTCTableGuarded,
- kTCTableAlways
- } tctable_mode = kTCTableNever;
- FieldListenerOptions field_listener_options;
- bool eagerly_verified_lazy = false;
+ bool force_split = false;
+#ifdef PROTOBUF_STABLE_EXPERIMENTS
+ bool force_eagerly_verified_lazy = true;
+ bool force_inline_string = true;
+#else // PROTOBUF_STABLE_EXPERIMENTS
bool force_eagerly_verified_lazy = false;
+ bool force_inline_string = false;
+#endif // !PROTOBUF_STABLE_EXPERIMENTS
};
} // namespace cpp
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc
index 0b660c75b7b..f48ba718a54 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc
@@ -47,7 +47,7 @@ class FieldGroup {
FieldGroup() : preferred_location_(0) {}
// A group with a single field.
- FieldGroup(float preferred_location, const FieldDescriptor* field)
+ FieldGroup(double preferred_location, const FieldDescriptor* field)
: preferred_location_(preferred_location), fields_(1, field) {}
// Append the fields in 'other' to this group.
@@ -63,7 +63,7 @@ class FieldGroup {
fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
}
- void SetPreferredLocation(float location) { preferred_location_ = location; }
+ void SetPreferredLocation(double location) { preferred_location_ = location; }
const std::vector<const FieldDescriptor*>& fields() const { return fields_; }
// FieldGroup objects sort by their preferred location.
@@ -77,7 +77,7 @@ class FieldGroup {
// field in this group in the original ordering of fields. This is very
// approximate, but should put this group close to where its member fields
// originally went.
- float preferred_location_;
+ double preferred_location_;
std::vector<const FieldDescriptor*> fields_;
// We rely on the default copy constructor and operator= so this type can be
// used in a vector.
@@ -203,7 +203,7 @@ void PaddingOptimizer::OptimizeLayout(
field_group.SetPreferredLocation(-1);
} else {
// Move incomplete 4-byte block to the end.
- field_group.SetPreferredLocation(fields->size() + 1);
+ field_group.SetPreferredLocation(double{FieldDescriptor::kMaxNumber});
}
}
aligned_to_8[f].push_back(field_group);
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc
index 282d70e3917..e033856f0c7 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc
@@ -33,9 +33,10 @@
#include <algorithm>
#include <limits>
#include <string>
+#include <utility>
-#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/wire_format.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
namespace google {
namespace protobuf {
@@ -43,7 +44,6 @@ namespace compiler {
namespace cpp {
namespace {
-using google::protobuf::internal::TcFieldData;
using google::protobuf::internal::WireFormat;
using google::protobuf::internal::WireFormatLite;
@@ -73,167 +73,351 @@ int TagSize(arc_ui32 field_number) {
return 2;
}
-const char* CodedTagType(int tag_size) {
- return tag_size == 1 ? "uint8_t" : "uint16_t";
-}
+TProtoStringType FieldParseFunctionName(
+ const TailCallTableInfo::FieldEntryInfo& entry, const Options& options);
+
+bool IsFieldEligibleForFastParsing(
+ const TailCallTableInfo::FieldEntryInfo& entry, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ const auto* field = entry.field;
+ // Map, oneof, weak, and lazy fields are not handled on the fast path.
+ if (field->is_map() || field->real_containing_oneof() ||
+ field->options().weak() ||
+ IsImplicitWeakField(field, options, scc_analyzer) ||
+ IsLazy(field, options, scc_analyzer)) {
+ return false;
+ }
-const char* TagType(const FieldDescriptor* field) {
- return CodedTagType(TagSize(field->number()));
-}
+ // We will check for a valid auxiliary index range later. However, we might
+ // want to change the value we check for inlined string fields.
+ int aux_idx = entry.aux_idx;
-TProtoStringType TcParserName(const Options& options) {
- return StrCat("::", ProtobufNamespace(options),
- "::internal::TcParser::");
-}
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_ENUM:
+ // If enum values are not validated at parse time, then this field can be
+ // handled on the fast path like an int32.
+ if (HasPreservingUnknownEnumSemantics(field)) {
+ break;
+ }
+ if (field->is_repeated() && field->is_packed()) {
+ return false;
+ }
+ break;
+
+ // Some bytes fields can be handled on fast path.
+ case FieldDescriptor::TYPE_STRING:
+ case FieldDescriptor::TYPE_BYTES:
+ if (field->options().ctype() != FieldOptions::STRING) {
+ return false;
+ }
+ if (IsStringInlined(field, options)) {
+ GOOGLE_CHECK(!field->is_repeated());
+ // For inlined strings, the donation state index is stored in the
+ // `aux_idx` field of the fast parsing info. We need to check the range
+ // of that value instead of the auxiliary index.
+ aux_idx = entry.inlined_string_idx;
+ }
+ break;
-TProtoStringType MessageTcParseFunctionName(const FieldDescriptor* field,
- const Options& options) {
- if (field->message_type()->field_count() == 0 ||
- !HasGeneratedMethods(field->message_type()->file(), options)) {
- // For files with `option optimize_for = CODE_SIZE`, or which derive from
- // `ZeroFieldsBase`, we need to call the `_InternalParse` function, because
- // there is no generated tailcall function. For tailcall parsing, this is
- // done by helpers in TcParser.
- return StrCat(TcParserName(options),
- (field->is_repeated() ? "Repeated" : "Singular"),
- "ParseMessage<",
- QualifiedClassName(field->message_type()), //
- ", ", TagType(field), ">");
+ default:
+ break;
}
- // This matches macros in generated_message_tctable_impl.h:
- return StrCat("PROTOBUF_TC_PARSE_",
- (field->is_repeated() ? "REPEATED" : "SINGULAR"),
- TagSize(field->number()), "(",
- QualifiedClassName(field->message_type()), ")");
+
+ if (HasHasbit(field)) {
+ // The tailcall parser can only update the first 32 hasbits. Fields with
+ // has-bits beyond the first 32 are handled by mini parsing/fallback.
+ GOOGLE_CHECK_GE(entry.hasbit_idx, 0) << field->DebugString();
+ if (entry.hasbit_idx >= 32) return false;
+ }
+
+ // If the field needs auxiliary data, then the aux index is needed. This
+ // must fit in a uint8_t.
+ if (aux_idx > std::numeric_limits<uint8_t>::max()) {
+ return false;
+ }
+
+ // The largest tag that can be read by the tailcall parser is two bytes
+ // when varint-coded. This allows 14 bits for the numeric tag value:
+ // byte 0 byte 1
+ // 1nnnnttt 0nnnnnnn
+ // ^^^^^^^ ^^^^^^^
+ if (field->number() >= 1 << 11) return false;
+
+ return true;
}
-TProtoStringType FieldParseFunctionName(const FieldDescriptor* field,
- const Options& options);
+std::vector<TailCallTableInfo::FastFieldInfo> SplitFastFieldsForSize(
+ const std::vector<TailCallTableInfo::FieldEntryInfo>& field_entries,
+ int table_size_log2, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ std::vector<TailCallTableInfo::FastFieldInfo> result(1 << table_size_log2);
+ const arc_ui32 idx_mask = result.size() - 1;
-} // namespace
+ for (const auto& entry : field_entries) {
+ if (!IsFieldEligibleForFastParsing(entry, options, scc_analyzer)) {
+ continue;
+ }
-TailCallTableInfo::TailCallTableInfo(const Descriptor* descriptor,
- const Options& options,
- const std::vector<int>& has_bit_indices,
- MessageSCCAnalyzer* scc_analyzer) {
- std::vector<const FieldDescriptor*> ordered_fields =
- GetOrderedFields(descriptor, options);
-
- // The table size is rounded up to the nearest power of 2, clamping at 2^5.
- // Note that this is a naive approach: a better approach should only consider
- // table-eligible fields. We may also want to push rarely-encountered fields
- // into the fallback, to make the table smaller.
- table_size_log2 = ordered_fields.size() >= 16 ? 5
- : ordered_fields.size() >= 8 ? 4
- : ordered_fields.size() >= 4 ? 3
- : ordered_fields.size() >= 2 ? 2
- : 1;
- const unsigned table_size = 1 << table_size_log2;
-
- // Construct info for each possible entry. Fields that do not use table-driven
- // parsing will still have an entry that nominates the fallback function.
- fast_path_fields.resize(table_size);
-
- for (const auto* field : ordered_fields) {
- // Eagerly assume slow path. If we can handle this field on the fast path,
- // we will pop its entry from `fallback_fields`.
- fallback_fields.push_back(field);
-
- // Anything difficult slow path:
- if (field->is_map()) continue;
- if (field->real_containing_oneof()) continue;
- if (field->options().weak()) continue;
- if (IsImplicitWeakField(field, options, scc_analyzer)) continue;
- if (IsLazy(field, options, scc_analyzer)) continue;
-
- // The largest tag that can be read by the tailcall parser is two bytes
- // when varint-coded. This allows 14 bits for the numeric tag value:
- // byte 0 byte 1
- // 1nnnnttt 0nnnnnnn
- // ^^^^^^^ ^^^^^^^
+ const auto* field = entry.field;
arc_ui32 tag = WireFormat::MakeTag(field);
- if (tag >= 1 << 14) {
- continue;
- } else if (tag >= 1 << 7) {
- tag = ((tag << 1) & 0x7F00) | 0x80 | (tag & 0x7F);
+
+ // Construct the varint-coded tag. If it is more than 7 bits, we need to
+ // shift the high bits and add a continue bit.
+ if (arc_ui32 hibits = tag & 0xFFFFFF80) {
+ tag = tag + hibits + 128; // tag = lobits + 2*hibits + 128
}
+
// The field index is determined by the low bits of the field number, where
// the table size determines the width of the mask. The largest table
// supported is 32 entries. The parse loop uses these bits directly, so that
// the dispatch does not require arithmetic:
- // byte 0 byte 1
- // 1nnnnttt 0nnnnnnn
- // ^^^^^
+ // byte 0 byte 1
+ // tag: 1nnnnttt 0nnnnnnn
+ // ^^^^^
+ // idx (table_size_log2=5)
// This means that any field number that does not fit in the lower 4 bits
- // will always have the top bit of its table index asserted:
- arc_ui32 idx = (tag >> 3) & (table_size - 1);
- // If this entry in the table is already used, then this field will be
- // handled by the generated fallback function.
- if (!fast_path_fields[idx].func_name.empty()) continue;
-
- // Determine the hasbit mask for this field, if needed. (Note that fields
- // without hasbits use different parse functions.)
- int hasbit_idx;
- if (HasHasbit(field)) {
- hasbit_idx = has_bit_indices[field->index()];
- GOOGLE_CHECK_NE(-1, hasbit_idx) << field->DebugString();
- // The tailcall parser can only update the first 32 hasbits. If this
- // field's has-bit is beyond that, then it will need to be handled by the
- // fallback parse function.
- if (hasbit_idx >= 32) continue;
+ // will always have the top bit of its table index asserted.
+ const arc_ui32 fast_idx = (tag >> 3) & idx_mask;
+
+ TailCallTableInfo::FastFieldInfo& info = result[fast_idx];
+ if (info.field != nullptr) {
+ // This field entry is already filled.
+ continue;
+ }
+
+ // Fill in this field's entry:
+ GOOGLE_CHECK(info.func_name.empty()) << info.func_name;
+ info.func_name = FieldParseFunctionName(entry, options);
+ info.field = field;
+ info.coded_tag = tag;
+ // If this field does not have presence, then it can set an out-of-bounds
+ // bit (tailcall parsing uses a arc_ui64 for hasbits, but only stores 32).
+ info.hasbit_idx = HasHasbit(field) ? entry.hasbit_idx : 63;
+ if (IsStringInlined(field, options)) {
+ GOOGLE_CHECK(!field->is_repeated());
+ info.aux_idx = static_cast<uint8_t>(entry.inlined_string_idx);
} else {
- // The tailcall parser only ever syncs 32 has-bits, so if there is no
- // presence, set a bit that will not be used.
- hasbit_idx = 63;
+ info.aux_idx = static_cast<uint8_t>(entry.aux_idx);
}
+ }
+ return result;
+}
- // Determine the name of the fastpath parse function to use for this field.
- TProtoStringType name;
+// Filter out fields that will be handled by mini parsing.
+std::vector<const FieldDescriptor*> FilterMiniParsedFields(
+ const std::vector<const FieldDescriptor*>& fields, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ std::vector<const FieldDescriptor*> generated_fallback_fields;
+ for (const auto* field : fields) {
+ bool handled = false;
switch (field->type()) {
- case FieldDescriptor::TYPE_MESSAGE:
- name = MessageTcParseFunctionName(field, options);
- break;
-
- case FieldDescriptor::TYPE_FIXED64:
- case FieldDescriptor::TYPE_FIXED32:
- case FieldDescriptor::TYPE_SFIXED64:
- case FieldDescriptor::TYPE_SFIXED32:
case FieldDescriptor::TYPE_DOUBLE:
case FieldDescriptor::TYPE_FLOAT:
- case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_FIXED32:
+ case FieldDescriptor::TYPE_SFIXED32:
+ case FieldDescriptor::TYPE_FIXED64:
+ case FieldDescriptor::TYPE_SFIXED64:
+ case FieldDescriptor::TYPE_BOOL:
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_SINT32:
case FieldDescriptor::TYPE_INT32:
case FieldDescriptor::TYPE_UINT64:
- case FieldDescriptor::TYPE_UINT32:
case FieldDescriptor::TYPE_SINT64:
- case FieldDescriptor::TYPE_SINT32:
- case FieldDescriptor::TYPE_BOOL:
- name = FieldParseFunctionName(field, options);
+ case FieldDescriptor::TYPE_INT64:
+ // These are handled by MiniParse, so we don't need any generated
+ // fallback code.
+ handled = true;
break;
- case FieldDescriptor::TYPE_BYTES:
- if (field->options().ctype() == FieldOptions::STRING &&
- field->default_value_string().empty() &&
- !IsStringInlined(field, options)) {
- name = FieldParseFunctionName(field, options);
+ case FieldDescriptor::TYPE_ENUM:
+ if (field->is_repeated() &&
+ !HasPreservingUnknownEnumSemantics(field)) {
+ // TODO(b/206890171): handle packed repeated closed enums
+ // Non-packed repeated can be handled using tables, but we still
+ // need to generate fallback code for all repeated enums in order to
+ // handle packed encoding. This is because of the lite/full split
+ // when handling invalid enum values in a packed field.
+ handled = false;
+ } else {
+ handled = true;
+ }
+ break;
+
+ case FieldDescriptor::TYPE_BYTES:
+ case FieldDescriptor::TYPE_STRING:
+ if (IsStringInlined(field, options)) {
+ // TODO(b/198211897): support InilnedStringField.
+ handled = false;
+ } else {
+ handled = true;
+ }
+ break;
+
+ case FieldDescriptor::TYPE_MESSAGE:
+ case FieldDescriptor::TYPE_GROUP:
+ // TODO(b/210762816): support remaining field types.
+ if (field->is_map() || IsWeak(field, options) ||
+ IsImplicitWeakField(field, options, scc_analyzer) ||
+ IsLazy(field, options, scc_analyzer)) {
+ handled = false;
+ } else {
+ handled = true;
}
break;
default:
+ handled = false;
break;
}
+ if (!handled) generated_fallback_fields.push_back(field);
+ }
- if (name.empty()) {
- continue;
+ return generated_fallback_fields;
+}
+
+} // namespace
+
+TailCallTableInfo::TailCallTableInfo(
+ const Descriptor* descriptor, const Options& options,
+ const std::vector<const FieldDescriptor*>& ordered_fields,
+ const std::vector<int>& has_bit_indices,
+ const std::vector<int>& inlined_string_indices,
+ MessageSCCAnalyzer* scc_analyzer) {
+ int oneof_count = descriptor->real_oneof_decl_count();
+ // If this message has any oneof fields, store the case offset in the first
+ // auxiliary entry.
+ if (oneof_count > 0) {
+ GOOGLE_LOG_IF(DFATAL, ordered_fields.empty())
+ << "Invalid message: " << descriptor->full_name() << " has "
+ << oneof_count << " oneof declarations, but no fields";
+ aux_entries.push_back(StrCat(
+ "_fl::Offset{offsetof(", ClassName(descriptor), ", _oneof_case_)}"));
+ }
+
+ // If this message has any inlined string fields, store the donation state
+ // offset in the second auxiliary entry.
+ if (!inlined_string_indices.empty()) {
+ aux_entries.resize(2); // pad if necessary
+ aux_entries[1] =
+ StrCat("_fl::Offset{offsetof(", ClassName(descriptor),
+ ", _inlined_string_donated_)}");
+ }
+
+ // Fill in mini table entries.
+ for (const FieldDescriptor* field : ordered_fields) {
+ field_entries.push_back(
+ {field, (HasHasbit(field) ? has_bit_indices[field->index()] : -1)});
+ auto& entry = field_entries.back();
+
+ if (field->type() == FieldDescriptor::TYPE_MESSAGE ||
+ field->type() == FieldDescriptor::TYPE_GROUP) {
+ // Message-typed fields have a FieldAux with the default instance pointer.
+ if (field->is_map()) {
+ // TODO(b/205904770): generate aux entries for maps
+ } else if (IsWeak(field, options)) {
+ // Don't generate anything for weak fields. They are handled by the
+ // generated fallback.
+ } else if (IsImplicitWeakField(field, options, scc_analyzer)) {
+ // Implicit weak fields don't need to store a default instance pointer.
+ } else if (IsLazy(field, options, scc_analyzer)) {
+ // Lazy fields are handled by the generated fallback function.
+ } else {
+ field_entries.back().aux_idx = aux_entries.size();
+ const Descriptor* field_type = field->message_type();
+ aux_entries.push_back(StrCat(
+ "reinterpret_cast<const ", QualifiedClassName(field_type, options),
+ "*>(&", QualifiedDefaultInstanceName(field_type, options), ")"));
+ }
+ } else if (field->type() == FieldDescriptor::TYPE_ENUM &&
+ !HasPreservingUnknownEnumSemantics(field)) {
+ // Enum fields which preserve unknown values (proto3 behavior) are
+ // effectively int32 fields with respect to parsing -- i.e., the value
+ // does not need to be validated at parse time.
+ //
+ // Enum fields which do not preserve unknown values (proto2 behavior) use
+ // a FieldAux to store validation information. If the enum values are
+ // sequential (and within a range we can represent), then the FieldAux
+ // entry represents the range using the minimum value (which must fit in
+ // an int16_t) and count (a uint16_t). Otherwise, the entry holds a
+ // pointer to the generated Name_IsValid function.
+
+ entry.aux_idx = aux_entries.size();
+ const EnumDescriptor* enum_type = field->enum_type();
+ GOOGLE_CHECK_GT(enum_type->value_count(), 0) << enum_type->DebugString();
+
+ // Check if the enum values are a single, contiguous range.
+ std::vector<int> enum_values;
+ for (int i = 0, N = enum_type->value_count(); i < N; ++i) {
+ enum_values.push_back(enum_type->value(i)->number());
+ }
+ auto values_begin = enum_values.begin();
+ auto values_end = enum_values.end();
+ std::sort(values_begin, values_end);
+ enum_values.erase(std::unique(values_begin, values_end), values_end);
+
+ if (enum_values.back() - enum_values[0] == enum_values.size() - 1 &&
+ enum_values[0] >= std::numeric_limits<int16_t>::min() &&
+ enum_values[0] <= std::numeric_limits<int16_t>::max() &&
+ enum_values.size() <= std::numeric_limits<uint16_t>::max()) {
+ entry.is_enum_range = true;
+ aux_entries.push_back(
+ StrCat(enum_values[0], ", ", enum_values.size()));
+ } else {
+ entry.is_enum_range = false;
+ aux_entries.push_back(
+ StrCat(QualifiedClassName(enum_type, options), "_IsValid"));
+ }
+ } else if ((field->type() == FieldDescriptor::TYPE_STRING ||
+ field->type() == FieldDescriptor::TYPE_BYTES) &&
+ IsStringInlined(field, options)) {
+ GOOGLE_CHECK(!field->is_repeated());
+ // Inlined strings have an extra marker to represent their donation state.
+ int idx = inlined_string_indices[field->index()];
+ // For mini parsing, the donation state index is stored as an `offset`
+ // auxiliary entry.
+ entry.aux_idx = aux_entries.size();
+ aux_entries.push_back(StrCat("_fl::Offset{", idx, "}"));
+ // For fast table parsing, the donation state index is stored instead of
+ // the aux_idx (this will limit the range to 8 bits).
+ entry.inlined_string_idx = idx;
+ }
+ }
+
+ // Choose the smallest fast table that covers the maximum number of fields.
+ table_size_log2 = 0; // fallback value
+ int num_fast_fields = -1;
+ for (int try_size_log2 : {0, 1, 2, 3, 4, 5}) {
+ size_t try_size = 1 << try_size_log2;
+ auto split_fields = SplitFastFieldsForSize(field_entries, try_size_log2,
+ options, scc_analyzer);
+ GOOGLE_CHECK_EQ(split_fields.size(), try_size);
+ int try_num_fast_fields = 0;
+ for (const auto& info : split_fields) {
+ if (info.field != nullptr) ++try_num_fast_fields;
+ }
+ // Use this size if (and only if) it covers more fields.
+ if (try_num_fast_fields > num_fast_fields) {
+ fast_path_fields = std::move(split_fields);
+ table_size_log2 = try_size_log2;
+ num_fast_fields = try_num_fast_fields;
+ }
+ // The largest table we allow has the same number of entries as the message
+ // has fields, rounded up to the next power of 2 (e.g., a message with 5
+ // fields can have a fast table of size 8). A larger table *might* cover
+ // more fields in certain cases, but a larger table in that case would have
+ // mostly empty entries; so, we cap the size to avoid pathologically sparse
+ // tables.
+ if (try_size > ordered_fields.size()) {
+ break;
}
- // This field made it into the fast path, so remove it from the fallback
- // fields and fill in the table entry.
- fallback_fields.pop_back();
- fast_path_fields[idx].func_name = name;
- fast_path_fields[idx].bits = TcFieldData(tag, hasbit_idx, 0);
- fast_path_fields[idx].field = field;
}
+ // Filter out fields that are handled by MiniParse. We don't need to generate
+ // a fallback for these, which saves code size.
+ fallback_fields = FilterMiniParsedFields(ordered_fields, options,
+ scc_analyzer);
+
// If there are no fallback fields, and at most one extension range, the
// parser can use a generic fallback function. Otherwise, a message-specific
// fallback routine is needed.
@@ -252,12 +436,15 @@ ParseFunctionGenerator::ParseFunctionGenerator(
options_(options),
variables_(vars),
inlined_string_indices_(inlined_string_indices),
+ ordered_fields_(GetOrderedFields(descriptor_, options_)),
num_hasbits_(max_has_bit_index) {
if (should_generate_tctable()) {
- tc_table_info_.reset(new TailCallTableInfo(descriptor_, options_,
- has_bit_indices, scc_analyzer));
+ tc_table_info_.reset(new TailCallTableInfo(
+ descriptor_, options_, ordered_fields_, has_bit_indices,
+ inlined_string_indices, scc_analyzer));
}
SetCommonVars(options_, &variables_);
+ SetCommonMessageDataVariables(&variables_);
SetUnknownFieldsVariable(descriptor_, options_, &variables_);
variables_["classname"] = ClassName(descriptor, false);
}
@@ -265,45 +452,18 @@ ParseFunctionGenerator::ParseFunctionGenerator(
void ParseFunctionGenerator::GenerateMethodDecls(io::Printer* printer) {
Formatter format(printer, variables_);
if (should_generate_tctable()) {
- auto declare_function = [&format](const char* name,
- const TProtoStringType& guard) {
- if (!guard.empty()) {
- format.Outdent();
- format("#if $1$\n", guard);
- format.Indent();
- }
- format("static const char* $1$(PROTOBUF_TC_PARAM_DECL);\n", name);
- if (!guard.empty()) {
- format.Outdent();
- format("#endif // $1$\n", guard);
- format.Indent();
- }
- };
+ format.Outdent();
if (should_generate_guarded_tctable()) {
- format.Outdent();
format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
- format.Indent();
- }
- format("// The Tct_* functions are internal to the protobuf runtime:\n");
- // These guards are defined in port_def.inc:
- declare_function("Tct_ParseS1", "PROTOBUF_TC_STATIC_PARSE_SINGULAR1");
- declare_function("Tct_ParseS2", "PROTOBUF_TC_STATIC_PARSE_SINGULAR2");
- declare_function("Tct_ParseR1", "PROTOBUF_TC_STATIC_PARSE_REPEATED1");
- declare_function("Tct_ParseR2", "PROTOBUF_TC_STATIC_PARSE_REPEATED2");
- if (tc_table_info_->use_generated_fallback) {
- format.Outdent();
- format(
- " private:\n"
- " ");
- declare_function("Tct_ParseFallback", "");
- format(" public:\n");
- format.Indent();
}
+ format(
+ " private:\n"
+ " static const char* Tct_ParseFallback(PROTOBUF_TC_PARAM_DECL);\n"
+ " public:\n");
if (should_generate_guarded_tctable()) {
- format.Outdent();
format("#endif\n");
- format.Indent();
}
+ format.Indent();
}
format(
"const char* _InternalParse(const char* ptr, "
@@ -318,9 +478,15 @@ void ParseFunctionGenerator::GenerateMethodImpls(io::Printer* printer) {
need_parse_function = false;
format(
"const char* $classname$::_InternalParse(const char* ptr,\n"
- " ::$proto_ns$::internal::ParseContext* ctx) {\n"
- "$annotate_deserialize$"
- " return _extensions_.ParseMessageSet(ptr, \n"
+ " ::_pbi::ParseContext* ctx) {\n"
+ "$annotate_deserialize$");
+ if (!options_.unverified_lazy_message_sets &&
+ ShouldVerify(descriptor_, options_, scc_analyzer_)) {
+ format(
+ " ctx->set_lazy_eager_verify_func(&$classname$::InternalVerify);\n");
+ }
+ format(
+ " return $extensions$.ParseMessageSet(ptr, \n"
" internal_default_instance(), &_internal_metadata_, ctx);\n"
"}\n");
}
@@ -339,7 +505,6 @@ void ParseFunctionGenerator::GenerateMethodImpls(io::Printer* printer) {
if (tc_table_info_->use_generated_fallback) {
GenerateTailcallFallbackFunction(format);
}
- GenerateTailcallFieldParseFunctions(format);
if (should_generate_guarded_tctable()) {
if (need_parse_function) {
format("\n#else // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n\n");
@@ -362,10 +527,10 @@ void ParseFunctionGenerator::GenerateTailcallParseFunction(Formatter& format) {
// Generate an `_InternalParse` that starts the tail-calling loop.
format(
"const char* $classname$::_InternalParse(\n"
- " const char* ptr, ::$proto_ns$::internal::ParseContext* ctx) {\n"
+ " const char* ptr, ::_pbi::ParseContext* ctx) {\n"
"$annotate_deserialize$"
- " ptr = ::$proto_ns$::internal::TcParser::ParseLoop(\n"
- " this, ptr, ctx, &_table_.header);\n");
+ " ptr = ::_pbi::TcParser::ParseLoop(this, ptr, ctx, "
+ "&_table_.header);\n");
format(
" return ptr;\n"
"}\n\n");
@@ -384,6 +549,7 @@ void ParseFunctionGenerator::GenerateTailcallFallbackFunction(
// Sync hasbits
format("typed_msg->_has_bits_[0] = hasbits;\n");
}
+ format("arc_ui32 tag = data.tag();\n");
format.Set("msg", "typed_msg->");
format.Set("this", "typed_msg");
@@ -401,62 +567,30 @@ void ParseFunctionGenerator::GenerateTailcallFallbackFunction(
"}\n");
}
-void ParseFunctionGenerator::GenerateTailcallFieldParseFunctions(
- Formatter& format) {
- GOOGLE_CHECK(should_generate_tctable());
- // There are four cases where a tailcall target are needed for messages:
- // {singular, repeated} x {1, 2}-byte tag
- struct {
- const char* type;
- int size;
- } const kTagLayouts[] = {
- {"uint8_t", 1},
- {"uint16_t", 2},
- };
- // Singular:
- for (const auto& layout : kTagLayouts) {
- // Guard macros are defined in port_def.inc.
- format(
- "#if PROTOBUF_TC_STATIC_PARSE_SINGULAR$1$\n"
- "const char* $classname$::Tct_ParseS$1$(PROTOBUF_TC_PARAM_DECL) {\n"
- " if (PROTOBUF_PREDICT_FALSE(data.coded_tag<$2$>() != 0))\n"
- " PROTOBUF_MUSTTAIL "
- "return table->fallback(PROTOBUF_TC_PARAM_PASS);\n"
- " ptr += $1$;\n"
- " hasbits |= (arc_ui64{1} << data.hasbit_idx());\n"
- " ::$proto_ns$::internal::TcParser::SyncHasbits"
- "(msg, hasbits, table);\n"
- " auto& field = ::$proto_ns$::internal::TcParser::"
- "RefAt<$classtype$*>(msg, data.offset());\n"
- " if (field == nullptr)\n"
- " field = CreateMaybeMessage<$classtype$>(ctx->data().arena);\n"
- " return ctx->ParseMessage(field, ptr);\n"
- "}\n"
- "#endif // PROTOBUF_TC_STATIC_PARSE_SINGULAR$1$\n",
- layout.size, layout.type);
- }
- // Repeated:
- for (const auto& layout : kTagLayouts) {
- // Guard macros are defined in port_def.inc.
- format(
- "#if PROTOBUF_TC_STATIC_PARSE_REPEATED$1$\n"
- "const char* $classname$::Tct_ParseR$1$(PROTOBUF_TC_PARAM_DECL) {\n"
- " if (PROTOBUF_PREDICT_FALSE(data.coded_tag<$2$>() != 0)) {\n"
- " PROTOBUF_MUSTTAIL "
- "return table->fallback(PROTOBUF_TC_PARAM_PASS);\n"
- " }\n"
- " ptr += $1$;\n"
- " auto& field = ::$proto_ns$::internal::TcParser::RefAt<"
- "::$proto_ns$::RepeatedPtrField<$classname$>>(msg, data.offset());\n"
- " ::$proto_ns$::internal::TcParser::SyncHasbits"
- "(msg, hasbits, table);\n"
- " ptr = ctx->ParseMessage(field.Add(), ptr);\n"
- " return ptr;\n"
- "}\n"
- "#endif // PROTOBUF_TC_STATIC_PARSE_REPEATED$1$\n",
- layout.size, layout.type);
+struct SkipEntry16 {
+ uint16_t skipmap;
+ uint16_t field_entry_offset;
+};
+struct SkipEntryBlock {
+ arc_ui32 first_fnum;
+ std::vector<SkipEntry16> entries;
+};
+struct NumToEntryTable {
+ arc_ui32 skipmap32; // for fields #1 - #32
+ std::vector<SkipEntryBlock> blocks;
+ // Compute the number of uint16_t required to represent this table.
+ int size16() const {
+ int size = 2; // for the termination field#
+ for (const auto& block : blocks) {
+ // 2 for the field#, 1 for a count of skip entries, 2 for each entry.
+ size += 3 + block.entries.size() * 2;
+ }
+ return size;
}
-}
+};
+
+static NumToEntryTable MakeNumToEntryTable(
+ const std::vector<const FieldDescriptor*>& field_descriptors);
void ParseFunctionGenerator::GenerateDataDecls(io::Printer* printer) {
if (!should_generate_tctable()) {
@@ -468,10 +602,13 @@ void ParseFunctionGenerator::GenerateDataDecls(io::Printer* printer) {
format("#ifdef PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
format.Indent();
}
+ auto field_num_to_entry_table = MakeNumToEntryTable(ordered_fields_);
format(
- "static const ::$proto_ns$::internal::TcParseTable<$1$>\n"
- " _table_;\n",
- tc_table_info_->table_size_log2);
+ "static const ::$proto_ns$::internal::"
+ "TcParseTable<$1$, $2$, $3$, $4$, $5$> _table_;\n",
+ tc_table_info_->table_size_log2, ordered_fields_.size(),
+ tc_table_info_->aux_entries.size(), CalculateFieldNamesSize(),
+ field_num_to_entry_table.size16());
if (should_generate_guarded_tctable()) {
format.Outdent();
format("#endif // PROTOBUF_TAIL_CALL_TABLE_PARSER_ENABLED\n");
@@ -496,7 +633,7 @@ void ParseFunctionGenerator::GenerateDataDefinitions(io::Printer* printer) {
void ParseFunctionGenerator::GenerateLoopingParseFunction(Formatter& format) {
format(
"const char* $classname$::_InternalParse(const char* ptr, "
- "::$proto_ns$::internal::ParseContext* ctx) {\n"
+ "::_pbi::ParseContext* ctx) {\n"
"$annotate_deserialize$"
"#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure\n");
format.Indent();
@@ -518,8 +655,10 @@ void ParseFunctionGenerator::GenerateLoopingParseFunction(Formatter& format) {
format("while (!ctx->Done(&ptr)) {\n");
format.Indent();
- GenerateParseIterationBody(format, descriptor_,
- GetOrderedFields(descriptor_, options_));
+ format(
+ "arc_ui32 tag;\n"
+ "ptr = ::_pbi::ReadTag(ptr, &tag);\n");
+ GenerateParseIterationBody(format, descriptor_, ordered_fields_);
format.Outdent();
format("} // while\n");
@@ -537,6 +676,68 @@ void ParseFunctionGenerator::GenerateLoopingParseFunction(Formatter& format) {
"}\n");
}
+static NumToEntryTable MakeNumToEntryTable(
+ const std::vector<const FieldDescriptor*>& field_descriptors) {
+ NumToEntryTable num_to_entry_table;
+ num_to_entry_table.skipmap32 = static_cast<arc_ui32>(-1);
+
+ // skip_entry_block is the current block of SkipEntries that we're
+ // appending to. cur_block_first_fnum is the number of the first
+ // field represented by the block.
+ uint16_t field_entry_index = 0;
+ uint16_t N = field_descriptors.size();
+ // First, handle field numbers 1-32, which affect only the initial
+ // skipmap32 and don't generate additional skip-entry blocks.
+ for (; field_entry_index != N; ++field_entry_index) {
+ auto* field_descriptor = field_descriptors[field_entry_index];
+ if (field_descriptor->number() > 32) break;
+ auto skipmap32_index = field_descriptor->number() - 1;
+ num_to_entry_table.skipmap32 -= 1 << skipmap32_index;
+ }
+ // If all the field numbers were less than or equal to 32, we will have
+ // no further entries to process, and we are already done.
+ if (field_entry_index == N) return num_to_entry_table;
+
+ SkipEntryBlock* block = nullptr;
+ bool start_new_block = true;
+ // To determine sparseness, track the field number corresponding to
+ // the start of the most recent skip entry.
+ arc_ui32 last_skip_entry_start = 0;
+ for (; field_entry_index != N; ++field_entry_index) {
+ auto* field_descriptor = field_descriptors[field_entry_index];
+ arc_ui32 fnum = field_descriptor->number();
+ GOOGLE_CHECK_GT(fnum, last_skip_entry_start);
+ if (start_new_block == false) {
+ // If the next field number is within 15 of the last_skip_entry_start, we
+ // continue writing just to that entry. If it's between 16 and 31 more,
+ // then we just extend the current block by one. If it's more than 31
+ // more, we have to add empty skip entries in order to continue using the
+ // existing block. Obviously it's just 32 more, it doesn't make sense to
+ // start a whole new block, since new blocks mean having to write out
+ // their starting field number, which is 32 bits, as well as the size of
+ // the additional block, which is 16... while an empty SkipEntry16 only
+ // costs 32 bits. So if it was 48 more, it's a slight space win; we save
+ // 16 bits, but probably at the cost of slower run time. We're choosing
+ // 96 for now.
+ if (fnum - last_skip_entry_start > 96) start_new_block = true;
+ }
+ if (start_new_block) {
+ num_to_entry_table.blocks.push_back(SkipEntryBlock{fnum});
+ block = &num_to_entry_table.blocks.back();
+ start_new_block = false;
+ }
+
+ auto skip_entry_num = (fnum - block->first_fnum) / 16;
+ auto skip_entry_index = (fnum - block->first_fnum) % 16;
+ while (skip_entry_num >= block->entries.size())
+ block->entries.push_back({0xFFFF, field_entry_index});
+ block->entries[skip_entry_num].skipmap -= 1 << (skip_entry_index);
+
+ last_skip_entry_start = fnum - skip_entry_index;
+ }
+ return num_to_entry_table;
+}
+
void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) {
GOOGLE_CHECK(should_generate_tctable());
// All entries without a fast-path parsing function need a fallback.
@@ -544,7 +745,7 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) {
if (tc_table_info_->use_generated_fallback) {
fallback = ClassName(descriptor_) + "::Tct_ParseFallback";
} else {
- fallback = TcParserName(options_) + "GenericFallback";
+ fallback = "::_pbi::TcParser::GenericFallback";
if (GetOptimizeFor(descriptor_->file(), options_) ==
FileOptions::LITE_RUNTIME) {
fallback += "Lite";
@@ -558,10 +759,15 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) {
// maps, weak fields, lazy, more than 1 extension range. In the cases
// the table is sufficient we can use a generic routine, that just handles
// unknown fields and potentially an extension range.
+ auto field_num_to_entry_table = MakeNumToEntryTable(ordered_fields_);
format(
- "const ::$proto_ns$::internal::TcParseTable<$1$>\n"
- " $classname$::_table_ = {\n",
- tc_table_info_->table_size_log2);
+ "PROTOBUF_ATTRIBUTE_INIT_PRIORITY1\n"
+ "const ::_pbi::TcParseTable<$1$, $2$, $3$, $4$, $5$> "
+ "$classname$::_table_ = "
+ "{\n",
+ tc_table_info_->table_size_log2, ordered_fields_.size(),
+ tc_table_info_->aux_entries.size(), CalculateFieldNamesSize(),
+ field_num_to_entry_table.size16());
{
auto table_scope = format.ScopedIndent();
format("{\n");
@@ -574,86 +780,364 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) {
}
if (descriptor_->extension_range_count() == 1) {
format(
- "PROTOBUF_FIELD_OFFSET($classname$, _extensions_),\n"
+ "PROTOBUF_FIELD_OFFSET($classname$, $extensions$),\n"
"$1$, $2$, // extension_range_{low,high}\n",
descriptor_->extension_range(0)->start,
descriptor_->extension_range(0)->end);
} else {
format("0, 0, 0, // no _extensions_\n");
}
+ format("$1$, $2$, // max_field_number, fast_idx_mask\n",
+ (ordered_fields_.empty() ? 0 : ordered_fields_.back()->number()),
+ (((1 << tc_table_info_->table_size_log2) - 1) << 3));
+ format(
+ "offsetof(decltype(_table_), field_lookup_table),\n"
+ "$1$, // skipmap\n",
+ field_num_to_entry_table.skipmap32);
+ if (ordered_fields_.empty()) {
+ format(
+ "offsetof(decltype(_table_), field_names), // no field_entries\n");
+ } else {
+ format("offsetof(decltype(_table_), field_entries),\n");
+ }
+
+ format(
+ "$1$, // num_field_entries\n"
+ "$2$, // num_aux_entries\n",
+ ordered_fields_.size(), tc_table_info_->aux_entries.size());
+ if (tc_table_info_->aux_entries.empty()) {
+ format(
+ "offsetof(decltype(_table_), field_names), // no aux_entries\n");
+ } else {
+ format("offsetof(decltype(_table_), aux_entries),\n");
+ }
format(
- "$1$, 0, $2$, // fast_idx_mask, reserved, num_fields\n"
- "&$3$._instance,\n"
- "$4$ // fallback\n",
- (((1 << tc_table_info_->table_size_log2) - 1) << 3),
- descriptor_->field_count(),
+ "&$1$._instance,\n"
+ "$2$, // fallback\n"
+ "",
DefaultInstanceName(descriptor_, options_), fallback);
}
- format("}, {\n");
+ format("}, {{\n");
{
+ // fast_entries[]
auto fast_scope = format.ScopedIndent();
- GenerateFastFieldEntries(format, fallback);
+ GenerateFastFieldEntries(format);
+ }
+ format("}}, {{\n");
+ {
+ // field_lookup_table[]
+ auto field_lookup_scope = format.ScopedIndent();
+ int line_entries = 0;
+ for (int i = 0, N = field_num_to_entry_table.blocks.size(); i < N; ++i) {
+ SkipEntryBlock& entry_block = field_num_to_entry_table.blocks[i];
+ format("$1$, $2$, $3$,\n", entry_block.first_fnum & 65535,
+ entry_block.first_fnum / 65536, entry_block.entries.size());
+ for (auto se16 : entry_block.entries) {
+ if (line_entries == 0) {
+ format("$1$, $2$,", se16.skipmap, se16.field_entry_offset);
+ ++line_entries;
+ } else if (line_entries < 5) {
+ format(" $1$, $2$,", se16.skipmap, se16.field_entry_offset);
+ ++line_entries;
+ } else {
+ format(" $1$, $2$,\n", se16.skipmap, se16.field_entry_offset);
+ line_entries = 0;
+ }
+ }
+ }
+ if (line_entries) format("\n");
+ format("65535, 65535\n");
+ }
+ if (ordered_fields_.empty()) {
+ GOOGLE_LOG_IF(DFATAL, !tc_table_info_->aux_entries.empty())
+ << "Invalid message: " << descriptor_->full_name() << " has "
+ << tc_table_info_->aux_entries.size()
+ << " auxiliary field entries, but no fields";
+ format(
+ "}},\n"
+ "// no field_entries, or aux_entries\n"
+ "{{\n");
+ } else {
+ format("}}, {{\n");
+ {
+ // field_entries[]
+ auto field_scope = format.ScopedIndent();
+ GenerateFieldEntries(format);
+ }
+ if (tc_table_info_->aux_entries.empty()) {
+ format(
+ "}},\n"
+ "// no aux_entries\n"
+ "{{\n");
+ } else {
+ format("}}, {{\n");
+ {
+ // aux_entries[]
+ auto aux_scope = format.ScopedIndent();
+ for (const TProtoStringType& aux_entry : tc_table_info_->aux_entries) {
+ format("{$1$},\n", aux_entry);
+ }
+ }
+ format("}}, {{\n");
+ }
+ } // ordered_fields_.empty()
+ {
+ // field_names[]
+ auto field_name_scope = format.ScopedIndent();
+ GenerateFieldNames(format);
}
- format("},\n"); // entries[]
+ format("}},\n");
}
format("};\n\n"); // _table_
}
-void ParseFunctionGenerator::GenerateFastFieldEntries(
- Formatter& format, const TProtoStringType& fallback) {
+void ParseFunctionGenerator::GenerateFastFieldEntries(Formatter& format) {
for (const auto& info : tc_table_info_->fast_path_fields) {
if (info.field != nullptr) {
PrintFieldComment(format, info.field);
}
- format("{$1$, ", info.func_name.empty() ? fallback : info.func_name);
- if (info.bits.data) {
- GOOGLE_DCHECK_NE(nullptr, info.field);
+ if (info.func_name.empty()) {
+ format("{::_pbi::TcParser::MiniParse, {}},\n");
+ } else {
format(
- "{$1$, $2$, "
- "static_cast<uint16_t>(PROTOBUF_FIELD_OFFSET($classname$, $3$_))}",
- info.bits.coded_tag(), info.bits.hasbit_idx(), FieldName(info.field));
+ "{$1$,\n"
+ " {$2$, $3$, $4$, PROTOBUF_FIELD_OFFSET($classname$, $5$)}},\n",
+ info.func_name, info.coded_tag, info.hasbit_idx, info.aux_idx,
+ FieldMemberName(info.field));
+ }
+ }
+}
+
+static void FormatFieldKind(Formatter& format,
+ const TailCallTableInfo::FieldEntryInfo& entry,
+ const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ const FieldDescriptor* field = entry.field;
+ // Spell the field kind in proto language declaration order, starting with
+ // cardinality:
+ format("(::_fl::kFc");
+ if (HasHasbit(field)) {
+ format("Optional");
+ } else if (field->is_repeated()) {
+ format("Repeated");
+ } else if (field->real_containing_oneof()) {
+ format("Oneof");
+ } else {
+ format("Singular");
+ }
+
+ // The rest of the type uses convenience aliases:
+ format(" | ::_fl::k");
+ if (field->is_repeated() && field->is_packed()) {
+ format("Packed");
+ }
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_DOUBLE:
+ format("Double");
+ break;
+ case FieldDescriptor::TYPE_FLOAT:
+ format("Float");
+ break;
+ case FieldDescriptor::TYPE_FIXED32:
+ format("Fixed32");
+ break;
+ case FieldDescriptor::TYPE_SFIXED32:
+ format("SFixed32");
+ break;
+ case FieldDescriptor::TYPE_FIXED64:
+ format("Fixed64");
+ break;
+ case FieldDescriptor::TYPE_SFIXED64:
+ format("SFixed64");
+ break;
+ case FieldDescriptor::TYPE_BOOL:
+ format("Bool");
+ break;
+ case FieldDescriptor::TYPE_ENUM:
+ if (HasPreservingUnknownEnumSemantics(field)) {
+ // No validation is required.
+ format("OpenEnum");
+ } else if (entry.is_enum_range) {
+ // Validation is done by range check (start/length in FieldAux).
+ format("EnumRange");
+ } else {
+ // Validation uses the generated _IsValid function.
+ format("Enum");
+ }
+ break;
+ case FieldDescriptor::TYPE_UINT32:
+ format("UInt32");
+ break;
+ case FieldDescriptor::TYPE_SINT32:
+ format("SInt32");
+ break;
+ case FieldDescriptor::TYPE_INT32:
+ format("Int32");
+ break;
+ case FieldDescriptor::TYPE_UINT64:
+ format("UInt64");
+ break;
+ case FieldDescriptor::TYPE_SINT64:
+ format("SInt64");
+ break;
+ case FieldDescriptor::TYPE_INT64:
+ format("Int64");
+ break;
+
+ case FieldDescriptor::TYPE_BYTES:
+ format("Bytes");
+ break;
+ case FieldDescriptor::TYPE_STRING: {
+ auto mode = GetUtf8CheckMode(field, options);
+ switch (mode) {
+ case Utf8CheckMode::kStrict:
+ format("Utf8String");
+ break;
+ case Utf8CheckMode::kVerify:
+ format("RawString");
+ break;
+ case Utf8CheckMode::kNone:
+ // Treat LITE_RUNTIME strings as bytes.
+ format("Bytes");
+ break;
+ default:
+ GOOGLE_LOG(FATAL) << "Invalid Utf8CheckMode (" << static_cast<int>(mode)
+ << ") for " << field->DebugString();
+ }
+ break;
+ }
+
+ case FieldDescriptor::TYPE_GROUP:
+ format("Message | ::_fl::kRepGroup");
+ break;
+ case FieldDescriptor::TYPE_MESSAGE:
+ if (field->is_map()) {
+ format("Map");
+ } else {
+ format("Message");
+ if (IsLazy(field, options, scc_analyzer)) {
+ format(" | ::_fl::kRepLazy");
+ } else if (IsImplicitWeakField(field, options, scc_analyzer)) {
+ format(" | ::_fl::kRepIWeak");
+ }
+ }
+ break;
+ }
+
+ // Fill in extra information about string and bytes field representations.
+ if (field->type() == FieldDescriptor::TYPE_BYTES ||
+ field->type() == FieldDescriptor::TYPE_STRING) {
+ if (field->is_repeated()) {
+ format(" | ::_fl::kRepSString");
+ } else {
+ format(" | ::_fl::kRepAString");
+ }
+ }
+
+ format(")");
+}
+
+void ParseFunctionGenerator::GenerateFieldEntries(Formatter& format) {
+ for (const auto& entry : tc_table_info_->field_entries) {
+ const FieldDescriptor* field = entry.field;
+ PrintFieldComment(format, field);
+ format("{");
+ if (IsWeak(field, options_)) {
+ // Weak fields are handled by the generated fallback function.
+ // (These are handled by legacy Google-internal logic.)
+ format("/* weak */ 0, 0, 0, 0");
} else {
- format("{}");
+ const OneofDescriptor* oneof = field->real_containing_oneof();
+ format("PROTOBUF_FIELD_OFFSET($classname$, $1$), $2$, $3$,\n ",
+ FieldMemberName(field),
+ (oneof ? oneof->index() : entry.hasbit_idx), entry.aux_idx);
+ FormatFieldKind(format, entry, options_, scc_analyzer_);
}
format("},\n");
}
}
+static constexpr int kMaxNameLength = 255;
+
+int ParseFunctionGenerator::CalculateFieldNamesSize() const {
+ // The full name of the message appears first.
+ int size = std::min(static_cast<int>(descriptor_->full_name().size()),
+ kMaxNameLength);
+ int lengths_size = 1;
+ for (const auto& entry : tc_table_info_->field_entries) {
+ const FieldDescriptor* field = entry.field;
+ GOOGLE_CHECK_LE(field->name().size(), kMaxNameLength);
+ size += field->name().size();
+ lengths_size += 1;
+ }
+ // align to an 8-byte boundary
+ lengths_size = (lengths_size + 7) & -8;
+ return size + lengths_size + 1;
+}
+
+static void FormatOctal(Formatter& format, int size) {
+ int octal_size = ((size >> 6) & 3) * 100 + //
+ ((size >> 3) & 7) * 10 + //
+ ((size >> 0) & 7);
+ format("\\$1$", octal_size);
+}
+
+void ParseFunctionGenerator::GenerateFieldNames(Formatter& format) {
+ // First, we output the size of each string, as an unsigned byte. The first
+ // string is the message name.
+ int count = 1;
+ format("\"");
+ FormatOctal(format,
+ std::min(static_cast<int>(descriptor_->full_name().size()), 255));
+ for (const auto& entry : tc_table_info_->field_entries) {
+ FormatOctal(format, entry.field->name().size());
+ ++count;
+ }
+ while (count & 7) { // align to an 8-byte boundary
+ format("\\0");
+ ++count;
+ }
+ format("\"\n");
+ // The message name is stored at the beginning of the string
+ TProtoStringType message_name = descriptor_->full_name();
+ if (message_name.size() > kMaxNameLength) {
+ static constexpr int kNameHalfLength = (kMaxNameLength - 3) / 2;
+ message_name = StrCat(
+ message_name.substr(0, kNameHalfLength), "...",
+ message_name.substr(message_name.size() - kNameHalfLength));
+ }
+ format("\"$1$\"\n", message_name);
+ // Then we output the actual field names
+ for (const auto& entry : tc_table_info_->field_entries) {
+ const FieldDescriptor* field = entry.field;
+ format("\"$1$\"\n", field->name());
+ }
+}
+
void ParseFunctionGenerator::GenerateArenaString(Formatter& format,
const FieldDescriptor* field) {
if (HasHasbit(field)) {
format("_Internal::set_has_$1$(&$has_bits$);\n", FieldName(field));
}
- TProtoStringType default_string =
- field->default_value_string().empty()
- ? "::" + ProtobufNamespace(options_) +
- "::internal::GetEmptyStringAlreadyInited()"
- : QualifiedClassName(field->containing_type(), options_) +
- "::" + MakeDefaultName(field) + ".get()";
format(
"if (arena != nullptr) {\n"
- " ptr = ctx->ReadArenaString(ptr, &$msg$$name$_, arena");
+ " ptr = ctx->ReadArenaString(ptr, &$msg$$field$, arena");
if (IsStringInlined(field, options_)) {
GOOGLE_DCHECK(!inlined_string_indices_.empty());
int inlined_string_index = inlined_string_indices_[field->index()];
- GOOGLE_DCHECK_GE(inlined_string_index, 0);
- format(
- ", $msg$_internal_$name$_donated()"
- ", &$msg$_inlined_string_donated_[$1$]"
- ", ~0x$2$u",
- inlined_string_index / 32,
- strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8));
+ GOOGLE_DCHECK_GT(inlined_string_index, 0);
+ format(", &$msg$$inlined_string_donated_array$[0], $1$, $this$",
+ inlined_string_index);
} else {
GOOGLE_DCHECK(field->default_value_string().empty());
}
format(
");\n"
"} else {\n"
- " ptr = ::$proto_ns$::internal::InlineGreedyStringParser("
- "$msg$$name$_.MutableNoArenaNoDefault(&$1$), ptr, ctx);\n"
+ " ptr = ::_pbi::InlineGreedyStringParser("
+ "$msg$$field$.MutableNoCopy(nullptr), ptr, ctx);\n"
"}\n"
- "const TProtoStringType* str = &$msg$$name$_.Get(); (void)str;\n",
- default_string);
+ "const TProtoStringType* str = &$msg$$field$.Get(); (void)str;\n");
}
void ParseFunctionGenerator::GenerateStrings(Formatter& format,
@@ -685,11 +1169,14 @@ void ParseFunctionGenerator::GenerateStrings(Formatter& format,
}
format(
"auto str = $msg$$1$$2$_$name$();\n"
- "ptr = ::$proto_ns$::internal::Inline$3$(str, ptr, ctx);\n",
+ "ptr = ::_pbi::Inline$3$(str, ptr, ctx);\n",
HasInternalAccessors(ctype) ? "_internal_" : "",
field->is_repeated() && !field->is_packable() ? "add" : "mutable",
parser_name);
}
+ // It is intentionally placed before VerifyUTF8 because it doesn't make sense
+ // to verify UTF8 when we already know parsing failed.
+ format("CHK_(ptr);\n");
if (!check_utf8) return; // return if this is a bytes field
auto level = GetUtf8CheckMode(field, options_);
switch (level) {
@@ -707,7 +1194,7 @@ void ParseFunctionGenerator::GenerateStrings(Formatter& format,
if (HasDescriptorMethods(field->file(), options_)) {
field_name = StrCat("\"", field->full_name(), "\"");
}
- format("::$proto_ns$::internal::VerifyUTF8(str, $1$)", field_name);
+ format("::_pbi::VerifyUTF8(str, $1$)", field_name);
switch (level) {
case Utf8CheckMode::kNone:
return;
@@ -740,6 +1227,7 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format,
"$msg$_internal_mutable_$name$(), ptr, ctx);\n",
DeclaredTypeMethodName(field->type()));
}
+ format("CHK_(ptr);\n");
} else {
auto field_type = field->type();
switch (field_type) {
@@ -751,48 +1239,64 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format,
break;
case FieldDescriptor::TYPE_MESSAGE: {
if (field->is_map()) {
- const FieldDescriptor* val =
- field->message_type()->FindFieldByName("value");
+ const FieldDescriptor* val = field->message_type()->map_value();
GOOGLE_CHECK(val);
if (val->type() == FieldDescriptor::TYPE_ENUM &&
!HasPreservingUnknownEnumSemantics(field)) {
format(
"auto object = "
"::$proto_ns$::internal::InitEnumParseWrapper<"
- "$unknown_fields_type$>(&$msg$$name$_, $1$_IsValid, "
+ "$unknown_fields_type$>(&$msg$$field$, $1$_IsValid, "
"$2$, &$msg$_internal_metadata_);\n"
"ptr = ctx->ParseMessage(&object, ptr);\n",
QualifiedClassName(val->enum_type(), options_),
field->number());
} else {
- format("ptr = ctx->ParseMessage(&$msg$$name$_, ptr);\n");
+ format("ptr = ctx->ParseMessage(&$msg$$field$, ptr);\n");
}
} else if (IsLazy(field, options_, scc_analyzer_)) {
+ bool eager_verify =
+ IsEagerlyVerifiedLazy(field, options_, scc_analyzer_);
+ if (ShouldVerify(descriptor_, options_, scc_analyzer_)) {
+ format(
+ "ctx->set_lazy_eager_verify_func($1$);\n",
+ eager_verify
+ ? StrCat("&", ClassName(field->message_type(), true),
+ "::InternalVerify")
+ : "nullptr");
+ }
if (field->real_containing_oneof()) {
format(
"if (!$msg$_internal_has_$name$()) {\n"
" $msg$clear_$1$();\n"
- " $msg$$1$_.$name$_ = ::$proto_ns$::Arena::CreateMessage<\n"
+ " $msg$$field$ = ::$proto_ns$::Arena::CreateMessage<\n"
" ::$proto_ns$::internal::LazyField>("
"$msg$GetArenaForAllocation());\n"
" $msg$set_has_$name$();\n"
"}\n"
- "auto* lazy_field = $msg$$1$_.$name$_;\n",
+ "auto* lazy_field = $msg$$field$;\n",
field->containing_oneof()->name());
} else if (HasHasbit(field)) {
format(
"_Internal::set_has_$name$(&$has_bits$);\n"
- "auto* lazy_field = &$msg$$name$_;\n");
+ "auto* lazy_field = &$msg$$field$;\n");
} else {
- format("auto* lazy_field = &$msg$$name$_;\n");
+ format("auto* lazy_field = &$msg$$field$;\n");
}
format(
"::$proto_ns$::internal::LazyFieldParseHelper<\n"
" ::$proto_ns$::internal::LazyField> parse_helper(\n"
" $1$::default_instance(),\n"
- " $msg$GetArenaForAllocation(), lazy_field);\n"
+ " $msg$GetArenaForAllocation(),\n"
+ " ::google::protobuf::internal::LazyVerifyOption::$2$,\n"
+ " lazy_field);\n"
"ptr = ctx->ParseMessage(&parse_helper, ptr);\n",
- FieldMessageTypeName(field, options_));
+ FieldMessageTypeName(field, options_),
+ eager_verify ? "kEager" : "kLazy");
+ if (ShouldVerify(descriptor_, options_, scc_analyzer_) &&
+ eager_verify) {
+ format("ctx->set_lazy_eager_verify_func(nullptr);\n");
+ }
} else if (IsImplicitWeakField(field, options_, scc_analyzer_)) {
if (!field->is_repeated()) {
format(
@@ -800,7 +1304,7 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format,
"ptr);\n");
} else {
format(
- "ptr = ctx->ParseMessage($msg$$name$_.AddWeak("
+ "ptr = ctx->ParseMessage($msg$$field$.AddWeak("
"reinterpret_cast<const ::$proto_ns$::MessageLite*>($1$ptr_)"
"), ptr);\n",
QualifiedDefaultInstanceName(field->message_type(), options_));
@@ -809,7 +1313,7 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format,
format(
"{\n"
" auto* default_ = &reinterpret_cast<const Message&>($1$);\n"
- " ptr = ctx->ParseMessage($msg$_weak_field_map_.MutableMessage("
+ " ptr = ctx->ParseMessage($msg$$weak_field_map$.MutableMessage("
"$2$, default_), ptr);\n"
"}\n",
QualifiedDefaultInstanceName(field->message_type(), options_),
@@ -819,6 +1323,7 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format,
"ptr = ctx->ParseMessage($msg$_internal_$mutable_field$(), "
"ptr);\n");
}
+ format("CHK_(ptr);\n");
break;
}
default:
@@ -898,7 +1403,7 @@ void ParseFunctionGenerator::GenerateFieldBody(
format("_Internal::set_has_$name$(&$has_bits$);\n");
}
format(
- "$msg$$name$_ = ::$proto_ns$::internal::ReadVarint$1$$2$(&ptr);\n"
+ "$msg$$field$ = ::$proto_ns$::internal::ReadVarint$1$$2$(&ptr);\n"
"CHK_(ptr);\n",
zigzag, size);
}
@@ -917,7 +1422,7 @@ void ParseFunctionGenerator::GenerateFieldBody(
format("_Internal::set_has_$name$(&$has_bits$);\n");
}
format(
- "$msg$$name$_ = "
+ "$msg$$field$ = "
"::$proto_ns$::internal::UnalignedLoad<$primitive_type$>(ptr);\n"
"ptr += sizeof($primitive_type$);\n");
}
@@ -925,7 +1430,6 @@ void ParseFunctionGenerator::GenerateFieldBody(
}
case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
GenerateLengthDelim(format, field);
- format("CHK_(ptr);\n");
break;
}
case WireFormatLite::WIRETYPE_START_GROUP: {
@@ -983,13 +1487,9 @@ static arc_ui32 ExpectedTag(const FieldDescriptor* field,
// parse the next tag in the stream.
void ParseFunctionGenerator::GenerateParseIterationBody(
Formatter& format, const Descriptor* descriptor,
- const std::vector<const FieldDescriptor*>& ordered_fields) {
- format(
- "$uint32$ tag;\n"
- "ptr = ::$proto_ns$::internal::ReadTag(ptr, &tag);\n");
-
- if (!ordered_fields.empty()) {
- GenerateFieldSwitch(format, ordered_fields);
+ const std::vector<const FieldDescriptor*>& fields) {
+ if (!fields.empty()) {
+ GenerateFieldSwitch(format, fields);
// Each field `case` only considers field number. Field numbers that are
// not defined in the message, or tags with an incompatible wire type, are
// considered "unusual" cases. They will be handled by the logic below.
@@ -1028,7 +1528,7 @@ void ParseFunctionGenerator::GenerateParseIterationBody(
}
format(
") {\n"
- " ptr = $msg$_extensions_.ParseField(tag, ptr, "
+ " ptr = $msg$$extensions$.ParseField(tag, ptr, "
"internal_default_instance(), &$msg$_internal_metadata_, ctx);\n"
" CHK_(ptr != nullptr);\n"
" $next_tag$;\n"
@@ -1045,12 +1545,12 @@ void ParseFunctionGenerator::GenerateParseIterationBody(
}
void ParseFunctionGenerator::GenerateFieldSwitch(
- Formatter& format,
- const std::vector<const FieldDescriptor*>& ordered_fields) {
+ Formatter& format, const std::vector<const FieldDescriptor*>& fields) {
format("switch (tag >> 3) {\n");
format.Indent();
- for (const auto* field : ordered_fields) {
+ for (const auto* field : fields) {
+ format.Set("field", FieldMemberName(field));
PrintFieldComment(format, field);
format("case $1$:\n", field->number());
format.Indent();
@@ -1104,199 +1604,111 @@ void ParseFunctionGenerator::GenerateFieldSwitch(
namespace {
-TProtoStringType FieldParseFunctionName(const FieldDescriptor* field,
- const Options& options) {
- ParseCardinality card = //
- field->is_packed() ? ParseCardinality::kPacked
- : field->is_repeated() ? ParseCardinality::kRepeated
- : field->real_containing_oneof() ? ParseCardinality::kOneof
- : ParseCardinality::kSingular;
+TProtoStringType FieldParseFunctionName(
+ const TailCallTableInfo::FieldEntryInfo& entry, const Options& options) {
+ const FieldDescriptor* field = entry.field;
+ TProtoStringType name = "::_pbi::TcParser::Fast";
- TypeFormat type_format;
switch (field->type()) {
- case FieldDescriptor::TYPE_FIXED64:
- case FieldDescriptor::TYPE_SFIXED64:
- case FieldDescriptor::TYPE_DOUBLE:
- type_format = TypeFormat::kFixed64;
- break;
-
case FieldDescriptor::TYPE_FIXED32:
case FieldDescriptor::TYPE_SFIXED32:
case FieldDescriptor::TYPE_FLOAT:
- type_format = TypeFormat::kFixed32;
+ name.append("F32");
break;
- case FieldDescriptor::TYPE_INT64:
- case FieldDescriptor::TYPE_UINT64:
- type_format = TypeFormat::kVar64;
+ case FieldDescriptor::TYPE_FIXED64:
+ case FieldDescriptor::TYPE_SFIXED64:
+ case FieldDescriptor::TYPE_DOUBLE:
+ name.append("F64");
break;
+ case FieldDescriptor::TYPE_BOOL:
+ name.append("V8");
+ break;
case FieldDescriptor::TYPE_INT32:
case FieldDescriptor::TYPE_UINT32:
- type_format = TypeFormat::kVar32;
+ name.append("V32");
+ break;
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_UINT64:
+ name.append("V64");
break;
- case FieldDescriptor::TYPE_SINT64:
- type_format = TypeFormat::kSInt64;
+ case FieldDescriptor::TYPE_ENUM:
+ if (HasPreservingUnknownEnumSemantics(field)) {
+ name.append("V32");
+ break;
+ }
+ if (field->is_repeated() && field->is_packed()) {
+ GOOGLE_LOG(DFATAL) << "Enum validation not handled: " << field->DebugString();
+ return "";
+ }
+ name.append(entry.is_enum_range ? "Er" : "Ev");
break;
case FieldDescriptor::TYPE_SINT32:
- type_format = TypeFormat::kSInt32;
+ name.append("Z32");
break;
-
- case FieldDescriptor::TYPE_BOOL:
- type_format = TypeFormat::kBool;
+ case FieldDescriptor::TYPE_SINT64:
+ name.append("Z64");
break;
case FieldDescriptor::TYPE_BYTES:
- type_format = TypeFormat::kBytes;
+ name.append("B");
+ if (IsStringInlined(field, options)) {
+ name.append("i");
+ }
break;
-
case FieldDescriptor::TYPE_STRING:
switch (GetUtf8CheckMode(field, options)) {
case Utf8CheckMode::kNone:
- type_format = TypeFormat::kBytes;
- break;
- case Utf8CheckMode::kStrict:
- type_format = TypeFormat::kString;
+ name.append("B");
break;
case Utf8CheckMode::kVerify:
- type_format = TypeFormat::kStringValidateOnly;
+ name.append("S");
+ break;
+ case Utf8CheckMode::kStrict:
+ name.append("U");
break;
default:
GOOGLE_LOG(DFATAL) << "Mode not handled: "
<< static_cast<int>(GetUtf8CheckMode(field, options));
return "";
}
+ if (IsStringInlined(field, options)) {
+ name.append("i");
+ }
break;
- default:
- GOOGLE_LOG(DFATAL) << "Type not handled: " << field->DebugString();
- return "";
- }
-
- return "::" + ProtobufNamespace(options) + "::internal::TcParser::" +
- GetTailCallFieldHandlerName(card, type_format,
- TagSize(field->number()), options);
-}
-
-} // namespace
-
-TProtoStringType GetTailCallFieldHandlerName(ParseCardinality card,
- TypeFormat type_format,
- int tag_length_bytes,
- const Options& options) {
- TProtoStringType name;
-
- // The field implementation functions are prefixed by cardinality:
- // `Singular` for optional or implicit fields.
- // `Repeated` for non-packed repeated.
- // `Packed` for packed repeated.
- switch (card) {
- case ParseCardinality::kSingular:
- name.append("Singular");
- break;
- case ParseCardinality::kOneof:
- name.append("Oneof");
- break;
- case ParseCardinality::kRepeated:
- name.append("Repeated");
- break;
- case ParseCardinality::kPacked:
- name.append("Packed");
- break;
- }
-
- // Next in the function name is the TypeFormat-specific name.
- switch (type_format) {
- case TypeFormat::kFixed64:
- case TypeFormat::kFixed32:
- name.append("Fixed");
- break;
-
- case TypeFormat::kVar64:
- case TypeFormat::kVar32:
- case TypeFormat::kSInt64:
- case TypeFormat::kSInt32:
- case TypeFormat::kBool:
- name.append("Varint");
- break;
-
- case TypeFormat::kBytes:
- case TypeFormat::kString:
- case TypeFormat::kStringValidateOnly:
- name.append("String");
- break;
-
- default:
- break;
- }
-
- name.append("<");
-
- // Determine the numeric layout type for the parser to use, independent of
- // the specific parsing logic used.
- switch (type_format) {
- case TypeFormat::kVar64:
- case TypeFormat::kFixed64:
- name.append("arc_ui64, ");
- break;
-
- case TypeFormat::kSInt64:
- name.append("arc_i64, ");
- break;
-
- case TypeFormat::kVar32:
- case TypeFormat::kFixed32:
- name.append("arc_ui32, ");
- break;
-
- case TypeFormat::kSInt32:
- name.append("arc_i32, ");
+ case FieldDescriptor::TYPE_MESSAGE:
+ name.append("M");
break;
-
- case TypeFormat::kBool:
- name.append("bool, ");
+ case FieldDescriptor::TYPE_GROUP:
+ name.append("G");
break;
default:
- break;
+ GOOGLE_LOG(DFATAL) << "Type not handled: " << field->DebugString();
+ return "";
}
- name.append(CodedTagType(tag_length_bytes));
-
- switch (type_format) {
- case TypeFormat::kVar64:
- case TypeFormat::kVar32:
- case TypeFormat::kBool:
- StrAppend(&name, ", ", TcParserName(options), "kNoConversion");
- break;
-
- case TypeFormat::kSInt64:
- case TypeFormat::kSInt32:
- StrAppend(&name, ", ", TcParserName(options), "kZigZag");
- break;
-
- case TypeFormat::kBytes:
- StrAppend(&name, ", ", TcParserName(options), "kNoUtf8");
- break;
-
- case TypeFormat::kString:
- StrAppend(&name, ", ", TcParserName(options), "kUtf8");
- break;
-
- case TypeFormat::kStringValidateOnly:
- StrAppend(&name, ", ", TcParserName(options), "kUtf8ValidateOnly");
- break;
+ // The field implementation functions are prefixed by cardinality:
+ // `S` for optional or implicit fields.
+ // `R` for non-packed repeated.
+ // `P` for packed repeated.
+ name.append(field->is_packed() ? "P"
+ : field->is_repeated() ? "R"
+ : field->real_containing_oneof() ? "O"
+ : "S");
- default:
- break;
- }
+ // Append the tag length. Fast parsing only handles 1- or 2-byte tags.
+ name.append(TagSize(field->number()) == 1 ? "1" : "2");
- name.append(">");
return name;
}
+} // namespace
+
} // namespace cpp
} // namespace compiler
} // namespace protobuf
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h
index 02460791462..3c8209534a4 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h
@@ -35,12 +35,11 @@
#include <string>
#include <vector>
-#include <google/protobuf/compiler/cpp/cpp_helpers.h>
-#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.h>
-#include <google/protobuf/generated_message_tctable_decl.h>
#include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
namespace google {
namespace protobuf {
@@ -50,18 +49,36 @@ namespace cpp {
// Helper class for generating tailcall parsing functions.
struct TailCallTableInfo {
TailCallTableInfo(const Descriptor* descriptor, const Options& options,
+ const std::vector<const FieldDescriptor*>& ordered_fields,
const std::vector<int>& has_bit_indices,
+ const std::vector<int>& inlined_string_indices,
MessageSCCAnalyzer* scc_analyzer);
- // Information to generate field entries.
- struct FieldInfo {
- const FieldDescriptor* field;
- google::protobuf::internal::TcFieldData bits;
+
+ // Fields parsed by the table fast-path.
+ struct FastFieldInfo {
TProtoStringType func_name;
+ const FieldDescriptor* field;
+ uint16_t coded_tag;
+ uint8_t hasbit_idx;
+ uint8_t aux_idx;
};
- // Fields parsed by the table fast-path.
- std::vector<FieldInfo> fast_path_fields;
- // Fields parsed by slow-path fallback.
+ std::vector<FastFieldInfo> fast_path_fields;
+
+ // Fields parsed by mini parsing routines.
+ struct FieldEntryInfo {
+ const FieldDescriptor* field;
+ int hasbit_idx;
+ int inlined_string_idx;
+ uint16_t aux_idx;
+ // True for enums entirely covered by the start/length fields of FieldAux:
+ bool is_enum_range;
+ };
+ std::vector<FieldEntryInfo> field_entries;
+ std::vector<TProtoStringType> aux_entries;
+
+ // Fields parsed by generated fallback function.
std::vector<const FieldDescriptor*> fallback_fields;
+
// Table size.
int table_size_log2;
// Mask for has-bits of required fields.
@@ -110,15 +127,15 @@ class ParseFunctionGenerator {
// Generates a fallback function for tailcall table-based parsing.
void GenerateTailcallFallbackFunction(Formatter& format);
- // Generates functions for parsing this message as a field.
- void GenerateTailcallFieldParseFunctions(Formatter& format);
-
// Generates a looping `_InternalParse` function.
void GenerateLoopingParseFunction(Formatter& format);
// Generates the tail-call table definition.
void GenerateTailCallTable(Formatter& format);
- void GenerateFastFieldEntries(Formatter& format, const TProtoStringType& fallback);
+ void GenerateFastFieldEntries(Formatter& format);
+ void GenerateFieldEntries(Formatter& format);
+ int CalculateFieldNamesSize() const;
+ void GenerateFieldNames(Formatter& format);
// Generates parsing code for an `ArenaString` field.
void GenerateArenaString(Formatter& format, const FieldDescriptor* field);
@@ -139,12 +156,11 @@ class ParseFunctionGenerator {
// Generates code to parse the next field from the input stream.
void GenerateParseIterationBody(
Formatter& format, const Descriptor* descriptor,
- const std::vector<const FieldDescriptor*>& ordered_fields);
+ const std::vector<const FieldDescriptor*>& fields);
- // Generates a `switch` statement to parse each of `ordered_fields`.
- void GenerateFieldSwitch(
- Formatter& format,
- const std::vector<const FieldDescriptor*>& ordered_fields);
+ // Generates a `switch` statement to parse each of `fields`.
+ void GenerateFieldSwitch(Formatter& format,
+ const std::vector<const FieldDescriptor*>& fields);
const Descriptor* descriptor_;
MessageSCCAnalyzer* scc_analyzer_;
@@ -152,45 +168,10 @@ class ParseFunctionGenerator {
std::map<TProtoStringType, TProtoStringType> variables_;
std::unique_ptr<TailCallTableInfo> tc_table_info_;
std::vector<int> inlined_string_indices_;
+ const std::vector<const FieldDescriptor*> ordered_fields_;
int num_hasbits_;
};
-enum class ParseCardinality {
- kSingular,
- kOneof,
- kRepeated,
- kPacked,
-};
-
-// TypeFormat defines parsing types, which encapsulates the expected wire
-// format, conversion or validation, and the in-memory layout.
-enum class TypeFormat {
- // Fixed types:
- kFixed64, // fixed64, sfixed64, double
- kFixed32, // fixed32, sfixed32, float
-
- // Varint types:
- kVar64, // int64, uint64
- kVar32, // int32, uint32
- kSInt64, // sint64
- kSInt32, // sint32
- kBool, // bool
-
- // Length-delimited types:
- kBytes, // bytes
- kString, // string (proto3/UTF-8 strict)
- kStringValidateOnly, // string (proto2/UTF-8 validate only)
-};
-
-// Returns the name of a field parser function.
-//
-// These are out-of-line functions generated by
-// parse_function_inc_generator_main.
-TProtoStringType GetTailCallFieldHandlerName(ParseCardinality card,
- TypeFormat type_format,
- int tag_length_bytes,
- const Options& options);
-
} // namespace cpp
} // namespace compiler
} // namespace protobuf
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
index 8b37b866aec..910b59a21a7 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -34,10 +34,10 @@
#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
-#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
namespace google {
namespace protobuf {
@@ -104,6 +104,9 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
SetCommonFieldVariables(descriptor, variables, options);
(*variables)["type"] = PrimitiveTypeName(options, descriptor->cpp_type());
(*variables)["default"] = DefaultValue(options, descriptor);
+ (*variables)["cached_byte_size_name"] = MakeVarintCachedSizeName(descriptor);
+ (*variables)["cached_byte_size_field"] =
+ MakeVarintCachedSizeFieldName(descriptor);
(*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor));
int fixed_size = FixedSize(descriptor->type());
if (fixed_size != -1) {
@@ -150,7 +153,7 @@ void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
Formatter format(printer, variables_);
format(
"inline $type$ $classname$::_internal_$name$() const {\n"
- " return $name$_;\n"
+ " return $field$;\n"
"}\n"
"inline $type$ $classname$::$name$() const {\n"
"$annotate_get$"
@@ -159,7 +162,7 @@ void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n"
"inline void $classname$::_internal_set_$name$($type$ value) {\n"
" $set_hasbit$\n"
- " $name$_ = value;\n"
+ " $field$ = value;\n"
"}\n"
"inline void $classname$::set_$name$($type$ value) {\n"
" _internal_set_$name$(value);\n"
@@ -170,7 +173,7 @@ void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
void PrimitiveFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_ = $default$;\n");
+ format("$field$ = $default$;\n");
}
void PrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
@@ -180,19 +183,19 @@ void PrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
void PrimitiveFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
Formatter format(printer, variables_);
- format("swap($name$_, other->$name$_);\n");
+ format("swap($field$, other->$field$);\n");
}
void PrimitiveFieldGenerator::GenerateConstructorCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_ = $default$;\n");
+ format("$field$ = $default$;\n");
}
void PrimitiveFieldGenerator::GenerateCopyConstructorCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_ = from.$name$_;\n");
+ format("$field$ = from.$field$;\n");
}
void PrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray(
@@ -201,7 +204,7 @@ void PrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray(
format(
"target = stream->EnsureSpace(target);\n"
"target = "
- "::$proto_ns$::internal::WireFormatLite::Write$declared_type$ToArray("
+ "::_pbi::WireFormatLite::Write$declared_type$ToArray("
"$number$, this->_internal_$name$(), target);\n");
}
@@ -214,12 +217,12 @@ void PrimitiveFieldGenerator::GenerateByteSize(io::Printer* printer) const {
// Adding one is very common and it turns out it can be done for
// free inside of WireFormatLite, so we can save an instruction here.
format(
- "total_size += ::$proto_ns$::internal::WireFormatLite::"
+ "total_size += ::_pbi::WireFormatLite::"
"$declared_type$SizePlusOne(this->_internal_$name$());\n");
} else {
format(
"total_size += $tag_size$ +\n"
- " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
+ " ::_pbi::WireFormatLite::$declared_type$Size(\n"
" this->_internal_$name$());\n");
}
} else {
@@ -249,7 +252,7 @@ void PrimitiveOneofFieldGenerator::GenerateInlineAccessorDefinitions(
format(
"inline $type$ $classname$::_internal_$name$() const {\n"
" if (_internal_has_$name$()) {\n"
- " return $field_member$;\n"
+ " return $field$;\n"
" }\n"
" return $default$;\n"
"}\n"
@@ -258,7 +261,7 @@ void PrimitiveOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" clear_$oneof_name$();\n"
" set_has_$name$();\n"
" }\n"
- " $field_member$ = value;\n"
+ " $field$ = value;\n"
"}\n"
"inline $type$ $classname$::$name$() const {\n"
"$annotate_get$"
@@ -275,7 +278,7 @@ void PrimitiveOneofFieldGenerator::GenerateInlineAccessorDefinitions(
void PrimitiveOneofFieldGenerator::GenerateClearingCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$field_member$ = $default$;\n");
+ format("$field$ = $default$;\n");
}
void PrimitiveOneofFieldGenerator::GenerateSwappingCode(
@@ -286,7 +289,7 @@ void PrimitiveOneofFieldGenerator::GenerateSwappingCode(
void PrimitiveOneofFieldGenerator::GenerateConstructorCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$ns$::_$classname$_default_instance_.$name$_ = $default$;\n");
+ format("$ns$::_$classname$_default_instance_.$field$ = $default$;\n");
}
// ===================================================================
@@ -313,7 +316,7 @@ void RepeatedPrimitiveFieldGenerator::GeneratePrivateMembers(
format("::$proto_ns$::RepeatedField< $type$ > $name$_;\n");
if (descriptor_->is_packed() && FixedSize(descriptor_->type()) == -1 &&
HasGeneratedMethods(descriptor_->file(), options_)) {
- format("mutable std::atomic<int> _$name$_cached_byte_size_;\n");
+ format("mutable std::atomic<int> $cached_byte_size_name$;\n");
}
}
@@ -344,7 +347,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
Formatter format(printer, variables_);
format(
"inline $type$ $classname$::_internal_$name$(int index) const {\n"
- " return $name$_.Get(index);\n"
+ " return $field$.Get(index);\n"
"}\n"
"inline $type$ $classname$::$name$(int index) const {\n"
"$annotate_get$"
@@ -353,11 +356,11 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n"
"inline void $classname$::set_$name$(int index, $type$ value) {\n"
"$annotate_set$"
- " $name$_.Set(index, value);\n"
+ " $field$.Set(index, value);\n"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
"inline void $classname$::_internal_add_$name$($type$ value) {\n"
- " $name$_.Add(value);\n"
+ " $field$.Add(value);\n"
"}\n"
"inline void $classname$::add_$name$($type$ value) {\n"
" _internal_add_$name$(value);\n"
@@ -366,7 +369,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n"
"inline const ::$proto_ns$::RepeatedField< $type$ >&\n"
"$classname$::_internal_$name$() const {\n"
- " return $name$_;\n"
+ " return $field$;\n"
"}\n"
"inline const ::$proto_ns$::RepeatedField< $type$ >&\n"
"$classname$::$name$() const {\n"
@@ -376,7 +379,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n"
"inline ::$proto_ns$::RepeatedField< $type$ >*\n"
"$classname$::_internal_mutable_$name$() {\n"
- " return &$name$_;\n"
+ " return &$field$;\n"
"}\n"
"inline ::$proto_ns$::RepeatedField< $type$ >*\n"
"$classname$::mutable_$name$() {\n"
@@ -389,30 +392,19 @@ void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
void RepeatedPrimitiveFieldGenerator::GenerateClearingCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_.Clear();\n");
+ format("$field$.Clear();\n");
}
void RepeatedPrimitiveFieldGenerator::GenerateMergingCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_.MergeFrom(from.$name$_);\n");
+ format("$field$.MergeFrom(from.$field$);\n");
}
void RepeatedPrimitiveFieldGenerator::GenerateSwappingCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_.InternalSwap(&other->$name$_);\n");
-}
-
-void RepeatedPrimitiveFieldGenerator::GenerateConstructorCode(
- io::Printer* printer) const {
- // Not needed for repeated fields.
-}
-
-void RepeatedPrimitiveFieldGenerator::GenerateCopyConstructorCode(
- io::Printer* printer) const {
- Formatter format(printer, variables_);
- format("$name$_.CopyFrom(from.$name$_);\n");
+ format("$field$.InternalSwap(&other->$field$);\n");
}
void RepeatedPrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray(
@@ -423,7 +415,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray(
format(
"{\n"
" int byte_size = "
- "_$name$_cached_byte_size_.load(std::memory_order_relaxed);\n"
+ "$cached_byte_size_field$.load(std::memory_order_relaxed);\n"
" if (byte_size > 0) {\n"
" target = stream->Write$declared_type$Packed(\n"
" $number$, _internal_$name$(), byte_size, target);\n"
@@ -440,7 +432,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray(
format(
"for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n"
" target = stream->EnsureSpace(target);\n"
- " target = ::$proto_ns$::internal::WireFormatLite::"
+ " target = ::_pbi::WireFormatLite::"
"Write$declared_type$ToArray($number$, this->_internal_$name$(i), "
"target);\n"
"}\n");
@@ -455,8 +447,8 @@ void RepeatedPrimitiveFieldGenerator::GenerateByteSize(
int fixed_size = FixedSize(descriptor_->type());
if (fixed_size == -1) {
format(
- "size_t data_size = ::$proto_ns$::internal::WireFormatLite::\n"
- " $declared_type$Size(this->$name$_);\n");
+ "size_t data_size = ::_pbi::WireFormatLite::\n"
+ " $declared_type$Size(this->$field$);\n");
} else {
format(
"unsigned int count = static_cast<unsigned "
@@ -468,13 +460,12 @@ void RepeatedPrimitiveFieldGenerator::GenerateByteSize(
format(
"if (data_size > 0) {\n"
" total_size += $tag_size$ +\n"
- " ::$proto_ns$::internal::WireFormatLite::Int32Size(\n"
- " static_cast<$int32$>(data_size));\n"
+ " ::_pbi::WireFormatLite::Int32Size(static_cast<$int32$>(data_size));\n"
"}\n");
if (FixedSize(descriptor_->type()) == -1) {
format(
- "int cached_size = ::$proto_ns$::internal::ToCachedSize(data_size);\n"
- "_$name$_cached_byte_size_.store(cached_size,\n"
+ "int cached_size = ::_pbi::ToCachedSize(data_size);\n"
+ "$cached_byte_size_field$.store(cached_size,\n"
" std::memory_order_relaxed);\n");
}
format("total_size += data_size;\n");
@@ -482,7 +473,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateByteSize(
format(
"total_size += $tag_size$ *\n"
" "
- "::$proto_ns$::internal::FromIntSize(this->_internal_$name$_size());\n"
+ "::_pbi::FromIntSize(this->_internal_$name$_size());\n"
"total_size += data_size;\n");
}
format.Outdent();
@@ -495,7 +486,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateConstinitInitializer(
format("$name$_()");
if (descriptor_->is_packed() && FixedSize(descriptor_->type()) == -1 &&
HasGeneratedMethods(descriptor_->file(), options_)) {
- format("\n, _$name$_cached_byte_size_(0)");
+ format("\n, $cached_byte_size_name$(0)");
}
}
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
index ff7c208ff29..77ac598e905 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
@@ -37,6 +37,7 @@
#include <map>
#include <string>
+
#include <google/protobuf/compiler/cpp/cpp_field.h>
namespace google {
@@ -48,7 +49,7 @@ class PrimitiveFieldGenerator : public FieldGenerator {
public:
PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
- ~PrimitiveFieldGenerator();
+ ~PrimitiveFieldGenerator() override;
// implements FieldGenerator ---------------------------------------
void GeneratePrivateMembers(io::Printer* printer) const override;
@@ -72,7 +73,7 @@ class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
public:
PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
- ~PrimitiveOneofFieldGenerator();
+ ~PrimitiveOneofFieldGenerator() override;
// implements FieldGenerator ---------------------------------------
void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
@@ -88,7 +89,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
public:
RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
- ~RepeatedPrimitiveFieldGenerator();
+ ~RepeatedPrimitiveFieldGenerator() override;
// implements FieldGenerator ---------------------------------------
void GeneratePrivateMembers(io::Printer* printer) const override;
@@ -97,8 +98,8 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
void GenerateClearingCode(io::Printer* printer) const override;
void GenerateMergingCode(io::Printer* printer) const override;
void GenerateSwappingCode(io::Printer* printer) const override;
- void GenerateConstructorCode(io::Printer* printer) const override;
- void GenerateCopyConstructorCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override {}
+ void GenerateCopyConstructorCode(io::Printer* printer) const override {}
void GenerateSerializeWithCachedSizesToArray(
io::Printer* printer) const override;
void GenerateByteSize(io::Printer* printer) const override;
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_service.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_service.cc
index 944b41ba906..7bf589fa388 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_service.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_service.cc
@@ -33,9 +33,10 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/cpp_service.h>
-#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+
#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
namespace google {
namespace protobuf {
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_service.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_service.h
index f510716fedc..d237f9d732e 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_service.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_service.h
@@ -37,8 +37,9 @@
#include <map>
#include <string>
-#include <google/protobuf/compiler/cpp/cpp_options.h>
+
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
namespace google {
namespace protobuf {
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index c736ce95272..4d8744976ba 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -33,10 +33,11 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/cpp_string_field.h>
-#include <google/protobuf/compiler/cpp/cpp_helpers.h>
-#include <google/protobuf/descriptor.pb.h>
+
#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/descriptor.pb.h>
namespace google {
@@ -50,36 +51,30 @@ void SetStringVariables(const FieldDescriptor* descriptor,
std::map<TProtoStringType, TProtoStringType>* variables,
const Options& options) {
SetCommonFieldVariables(descriptor, variables, options);
+
+ const TProtoStringType kNS = "::" + (*variables)["proto_ns"] + "::internal::";
+ const TProtoStringType kArenaStringPtr = kNS + "ArenaStringPtr";
+
(*variables)["default"] = DefaultValue(options, descriptor);
(*variables)["default_length"] =
StrCat(descriptor->default_value_string().length());
- TProtoStringType default_variable_string = MakeDefaultName(descriptor);
- (*variables)["default_variable_name"] = default_variable_string;
+ (*variables)["default_variable_name"] = MakeDefaultName(descriptor);
+ (*variables)["default_variable_field"] = MakeDefaultFieldName(descriptor);
- if (!descriptor->default_value_string().empty()) {
+ if (descriptor->default_value_string().empty()) {
+ (*variables)["default_string"] = kNS + "GetEmptyStringAlreadyInited()";
+ (*variables)["default_value"] = "&" + (*variables)["default_string"];
+ (*variables)["lazy_variable_args"] = "";
+ } else {
(*variables)["lazy_variable"] =
- QualifiedClassName(descriptor->containing_type(), options) +
- "::" + default_variable_string;
- }
-
- (*variables)["default_string"] =
- descriptor->default_value_string().empty()
- ? "::" + (*variables)["proto_ns"] +
- "::internal::GetEmptyStringAlreadyInited()"
- : (*variables)["lazy_variable"] + ".get()";
- (*variables)["init_value"] =
- descriptor->default_value_string().empty()
- ? "&::" + (*variables)["proto_ns"] +
- "::internal::GetEmptyStringAlreadyInited()"
- : "nullptr";
- (*variables)["default_value_tag"] =
- "::" + (*variables)["proto_ns"] + "::internal::ArenaStringPtr::" +
- (descriptor->default_value_string().empty() ? "Empty" : "NonEmpty") +
- "Default{}";
- (*variables)["default_variable_or_tag"] =
- (*variables)[descriptor->default_value_string().empty()
- ? "default_value_tag"
- : "lazy_variable"];
+ StrCat(QualifiedClassName(descriptor->containing_type(), options),
+ "::", MakeDefaultFieldName(descriptor));
+
+ (*variables)["default_string"] = (*variables)["lazy_variable"] + ".get()";
+ (*variables)["default_value"] = "nullptr";
+ (*variables)["lazy_variable_args"] = (*variables)["lazy_variable"] + ", ";
+ }
+
(*variables)["pointer_type"] =
descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
(*variables)["setter"] =
@@ -116,9 +111,14 @@ void StringFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
if (!inlined_) {
format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n");
} else {
+ // Skips the automatic destruction; rather calls it explicitly if
+ // allocating arena is null. This is required to support message-owned
+ // arena (go/path-to-arenas) where a root proto is destroyed but
+ // InlinedStringField may have arena-allocated memory.
+ //
// `_init_inline_xxx` is used for initializing default instances.
format(
- "::$proto_ns$::internal::InlinedStringField $name$_;\n"
+ "union { ::$proto_ns$::internal::InlinedStringField $name$_; };\n"
"static std::true_type _init_inline_$name$_;\n");
}
}
@@ -204,8 +204,8 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
" // @@protoc_insertion_point(field_get:$full_name$)\n");
if (!descriptor_->default_value_string().empty()) {
format(
- " if ($name$_.IsDefault(nullptr)) return "
- "$default_variable_name$.get();\n");
+ " if ($field$.IsDefault()) return "
+ "$default_variable_field$.get();\n");
}
format(
" return _internal_$name$();\n"
@@ -216,7 +216,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
"inline PROTOBUF_ALWAYS_INLINE\n"
"void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n"
" $set_hasbit$\n"
- " $name$_.$setter$($default_value_tag$, static_cast<ArgT0 &&>(arg0),"
+ " $field$.$setter$(static_cast<ArgT0 &&>(arg0),"
" args..., GetArenaForAllocation());\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
@@ -227,9 +227,9 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
"inline PROTOBUF_ALWAYS_INLINE\n"
"void $classname$::set_$name$(ArgT0&& arg0, ArgT... args) {\n"
" $set_hasbit$\n"
- " $name$_.$setter$(nullptr, static_cast<ArgT0 &&>(arg0),"
+ " $field$.$setter$(static_cast<ArgT0 &&>(arg0),"
" args..., GetArenaForAllocation(), _internal_$name$_donated(), "
- "&$donating_states_word$, $mask_for_undonate$);\n"
+ "&$donating_states_word$, $mask_for_undonate$, this);\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
@@ -246,20 +246,20 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
" return _s;\n"
"}\n"
"inline const TProtoStringType& $classname$::_internal_$name$() const {\n"
- " return $name$_.Get();\n"
+ " return $field$.Get();\n"
"}\n"
"inline void $classname$::_internal_set_$name$(const TProtoStringType& "
"value) {\n"
" $set_hasbit$\n");
if (!inlined_) {
format(
- " $name$_.Set($default_value_tag$, value, GetArenaForAllocation());\n"
+ " $field$.Set(value, GetArenaForAllocation());\n"
"}\n");
} else {
format(
- " $name$_.Set(nullptr, value, GetArenaForAllocation(),\n"
+ " $field$.Set(value, GetArenaForAllocation(),\n"
" _internal_$name$_donated(), &$donating_states_word$, "
- "$mask_for_undonate$);\n"
+ "$mask_for_undonate$, this);\n"
"}\n");
}
format(
@@ -267,14 +267,14 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
" $set_hasbit$\n");
if (!inlined_) {
format(
- " return $name$_.Mutable($default_variable_or_tag$, "
+ " return $field$.Mutable($lazy_variable_args$"
"GetArenaForAllocation());\n"
"}\n");
} else {
format(
- " return $name$_.Mutable($default_variable_or_tag$, "
+ " return $field$.Mutable($lazy_variable_args$"
"GetArenaForAllocation(), _internal_$name$_donated(), "
- "&$donating_states_word$, $mask_for_undonate$);\n"
+ "&$donating_states_word$, $mask_for_undonate$, this);\n"
"}\n");
}
format(
@@ -289,26 +289,23 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
" }\n"
" $clear_hasbit$\n");
if (!inlined_) {
- format(
- " auto* p = $name$_.ReleaseNonDefault($init_value$, "
- "GetArenaForAllocation());\n");
+ format(" auto* p = $field$.Release();\n");
if (descriptor_->default_value_string().empty()) {
format(
"#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"
- " if ($name$_.IsDefault($init_value$)) {\n"
- " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n"
+ " if ($field$.IsDefault()) {\n"
+ " $field$.Set(\"\", GetArenaForAllocation());\n"
" }\n"
"#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n");
}
format(" return p;\n");
} else {
format(
- " return $name$_.Release(nullptr, GetArenaForAllocation(), "
+ " return $field$.Release(GetArenaForAllocation(), "
"_internal_$name$_donated());\n");
}
} else {
- format(
- " return $name$_.Release($init_value$, GetArenaForAllocation());\n");
+ format(" return $field$.Release();\n");
}
format(
@@ -320,23 +317,21 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions(
" $clear_hasbit$\n"
" }\n");
if (!inlined_) {
- format(
- " $name$_.SetAllocated($init_value$, $name$,\n"
- " GetArenaForAllocation());\n");
+ format(" $field$.SetAllocated($name$, GetArenaForAllocation());\n");
if (descriptor_->default_value_string().empty()) {
format(
"#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"
- " if ($name$_.IsDefault($init_value$)) {\n"
- " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n"
+ " if ($field$.IsDefault()) {\n"
+ " $field$.Set(\"\", GetArenaForAllocation());\n"
" }\n"
"#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n");
}
} else {
// Currently, string fields with default value can't be inlined.
format(
- " $name$_.SetAllocated(nullptr, $name$, GetArenaForAllocation(), "
+ " $field$.SetAllocated(nullptr, $name$, GetArenaForAllocation(), "
"_internal_$name$_donated(), &$donating_states_word$, "
- "$mask_for_undonate$);\n");
+ "$mask_for_undonate$, this);\n");
}
format(
"$annotate_set$"
@@ -350,7 +345,7 @@ void StringFieldGenerator::GenerateNonInlineAccessorDefinitions(
if (!descriptor_->default_value_string().empty()) {
format(
"const ::$proto_ns$::internal::LazyString "
- "$classname$::$default_variable_name$"
+ "$classname$::$default_variable_field$"
"{{{$default$, $default_length$}}, {nullptr}};\n");
}
}
@@ -358,11 +353,11 @@ void StringFieldGenerator::GenerateNonInlineAccessorDefinitions(
void StringFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
Formatter format(printer, variables_);
if (descriptor_->default_value_string().empty()) {
- format("$name$_.ClearToEmpty();\n");
+ format("$field$.ClearToEmpty();\n");
} else {
GOOGLE_DCHECK(!inlined_);
format(
- "$name$_.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n");
+ "$field$.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n");
}
}
@@ -388,20 +383,20 @@ void StringFieldGenerator::GenerateMessageClearingCode(
//
// For non-inlined strings, we distinguish from non-default by comparing
// instances, rather than contents.
- format("$DCHK$(!$name$_.IsDefault(nullptr));\n");
+ format("$DCHK$(!$field$.IsDefault());\n");
}
if (descriptor_->default_value_string().empty()) {
if (must_be_present) {
- format("$name$_.ClearNonDefaultToEmpty();\n");
+ format("$field$.ClearNonDefaultToEmpty();\n");
} else {
- format("$name$_.ClearToEmpty();\n");
+ format("$field$.ClearToEmpty();\n");
}
} else {
// Clear to a non-empty default is more involved, as we try to use the
// Arena if one is present and may need to reallocate the string.
format(
- "$name$_.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n ");
+ "$field$.ClearToDefault($lazy_variable$, GetArenaForAllocation());\n ");
}
}
@@ -416,34 +411,31 @@ void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
if (!inlined_) {
format(
"::$proto_ns$::internal::ArenaStringPtr::InternalSwap(\n"
- " $init_value$,\n"
- " &$name$_, lhs_arena,\n"
- " &other->$name$_, rhs_arena\n"
+ " &$field$, lhs_arena,\n"
+ " &other->$field$, rhs_arena\n"
");\n");
} else {
- // At this point, it's guaranteed that the two fields being swapped are on
- // the same arena.
format(
- "$name$_.Swap(&other->$name$_, nullptr, GetArenaForAllocation(), "
- "_internal_$name$_donated(), other->_internal_$name$_donated(), "
- "&$donating_states_word$, &(other->$donating_states_word$), "
- "$mask_for_undonate$);\n");
+ "::$proto_ns$::internal::InlinedStringField::InternalSwap(\n"
+ " &$field$, lhs_arena, "
+ "($inlined_string_donated_array$[0] & 0x1u) == 0, this,\n"
+ " &other->$field$, rhs_arena, "
+ "(other->$inlined_string_donated_array$[0] & 0x1u) == 0, other);\n");
}
}
void StringFieldGenerator::GenerateConstructorCode(io::Printer* printer) const {
Formatter format(printer, variables_);
if (inlined_ && descriptor_->default_value_string().empty()) {
- // Automatic initialization will construct the string.
return;
}
GOOGLE_DCHECK(!inlined_);
- format("$name$_.UnsafeSetDefault($init_value$);\n");
+ format("$field$.InitDefault();\n");
if (IsString(descriptor_, options_) &&
descriptor_->default_value_string().empty()) {
format(
"#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"
- " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n"
+ " $field$.Set(\"\", GetArenaForAllocation());\n"
"#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n");
}
}
@@ -452,6 +444,9 @@ void StringFieldGenerator::GenerateCopyConstructorCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
GenerateConstructorCode(printer);
+ if (inlined_) {
+ format("new (&$field$) ::_pbi::InlinedStringField();\n");
+ }
if (HasHasbit(descriptor_)) {
format("if (from._internal_has_$name$()) {\n");
@@ -463,13 +458,13 @@ void StringFieldGenerator::GenerateCopyConstructorCode(
if (!inlined_) {
format(
- "$name$_.Set($default_value_tag$, from._internal_$name$(), \n"
+ "$field$.Set(from._internal_$name$(), \n"
" GetArenaForAllocation());\n");
} else {
format(
- "$name$_.Set(nullptr, from._internal_$name$(),\n"
+ "$field$.Set(from._internal_$name$(),\n"
" GetArenaForAllocation(), _internal_$name$_donated(), "
- "&$donating_states_word$, $mask_for_undonate$);\n");
+ "&$donating_states_word$, $mask_for_undonate$, this);\n");
}
format.Outdent();
@@ -478,12 +473,30 @@ void StringFieldGenerator::GenerateCopyConstructorCode(
void StringFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
Formatter format(printer, variables_);
- if (inlined_) {
- // The destructor is automatically invoked.
+ if (!inlined_) {
+ format("$field$.Destroy();\n");
return;
}
+ // Explicitly calls ~InlinedStringField as its automatic call is disabled.
+ // Destructor has been implicitly skipped as a union, and even the
+ // message-owned arena is enabled, arena could still be missing for
+ // Arena::CreateMessage(nullptr).
+ format("$field$.~InlinedStringField();\n");
+}
- format("$name$_.DestroyNoArena($init_value$);\n");
+ArenaDtorNeeds StringFieldGenerator::NeedsArenaDestructor() const {
+ return inlined_ ? ArenaDtorNeeds::kOnDemand : ArenaDtorNeeds::kNone;
+}
+
+void StringFieldGenerator::GenerateArenaDestructorCode(
+ io::Printer* printer) const {
+ if (!inlined_) return;
+ Formatter format(printer, variables_);
+ // _this is the object being destructed (we are inside a static method here).
+ format(
+ "if (!_this->_internal_$name$_donated()) {\n"
+ " _this->$field$.~InlinedStringField();\n"
+ "}\n");
}
void StringFieldGenerator::GenerateSerializeWithCachedSizesToArray(
@@ -517,9 +530,11 @@ void StringFieldGenerator::GenerateConstinitInitializer(
return;
}
if (descriptor_->default_value_string().empty()) {
- format("$name$_(&::$proto_ns$::internal::fixed_address_empty_string)");
+ format(
+ "$name$_(&::_pbi::fixed_address_empty_string, "
+ "::_pbi::ConstantInitialized{})");
} else {
- format("$name$_(nullptr)");
+ format("$name$_(nullptr, ::_pbi::ConstantInitialized{})");
}
}
@@ -550,9 +565,9 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" if (!_internal_has_$name$()) {\n"
" clear_$oneof_name$();\n"
" set_has_$name$();\n"
- " $field_member$.UnsafeSetDefault($init_value$);\n"
+ " $field$.InitDefault();\n"
" }\n"
- " $field_member$.$setter$($default_value_tag$,"
+ " $field$.$setter$("
" static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
@@ -565,7 +580,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
"}\n"
"inline const TProtoStringType& $classname$::_internal_$name$() const {\n"
" if (_internal_has_$name$()) {\n"
- " return $field_member$.Get();\n"
+ " return $field$.Get();\n"
" }\n"
" return $default_string$;\n"
"}\n"
@@ -574,28 +589,26 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" if (!_internal_has_$name$()) {\n"
" clear_$oneof_name$();\n"
" set_has_$name$();\n"
- " $field_member$.UnsafeSetDefault($init_value$);\n"
+ " $field$.InitDefault();\n"
" }\n"
- " $field_member$.Set($default_value_tag$, value, "
- "GetArenaForAllocation());\n"
+ " $field$.Set(value, GetArenaForAllocation());\n"
"}\n");
format(
"inline TProtoStringType* $classname$::_internal_mutable_$name$() {\n"
" if (!_internal_has_$name$()) {\n"
" clear_$oneof_name$();\n"
" set_has_$name$();\n"
- " $field_member$.UnsafeSetDefault($init_value$);\n"
+ " $field$.InitDefault();\n"
" }\n"
- " return $field_member$.Mutable(\n"
- " $default_variable_or_tag$, GetArenaForAllocation());\n"
+ " return $field$.Mutable($lazy_variable_args$"
+ " GetArenaForAllocation());\n"
"}\n"
"inline TProtoStringType* $classname$::$release_name$() {\n"
"$annotate_release$"
" // @@protoc_insertion_point(field_release:$full_name$)\n"
" if (_internal_has_$name$()) {\n"
" clear_has_$oneof_name$();\n"
- " return $field_member$.ReleaseNonDefault($init_value$, "
- "GetArenaForAllocation());\n"
+ " return $field$.Release();\n"
" } else {\n"
" return nullptr;\n"
" }\n"
@@ -606,11 +619,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
" }\n"
" if ($name$ != nullptr) {\n"
" set_has_$name$();\n"
- " $field_member$.UnsafeSetDefault($name$);\n"
- " ::$proto_ns$::Arena* arena = GetArenaForAllocation();\n"
- " if (arena != nullptr) {\n"
- " arena->Own($name$);\n"
- " }\n"
+ " $field$.InitAllocated($name$, GetArenaForAllocation());\n"
" }\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
@@ -620,9 +629,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
void StringOneofFieldGenerator::GenerateClearingCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format(
- "$field_member$.Destroy($default_value_tag$, "
- "GetArenaForAllocation());\n");
+ format("$field$.Destroy();\n");
}
void StringOneofFieldGenerator::GenerateMessageClearingCode(
@@ -737,14 +744,14 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
format(
"inline const TProtoStringType& $classname$::_internal_$name$(int index) "
"const {\n"
- " return $name$_.InternalCheckedGet(\n"
+ " return $field$.InternalCheckedGet(\n"
" index, ::$proto_ns$::internal::GetEmptyStringAlreadyInited());\n"
"}\n");
} else {
format(
"inline const TProtoStringType& $classname$::_internal_$name$(int index) "
"const {\n"
- " return $name$_.Get(index);\n"
+ " return $field$.Get(index);\n"
"}\n");
}
format(
@@ -756,23 +763,23 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
"inline TProtoStringType* $classname$::mutable_$name$(int index) {\n"
"$annotate_mutable$"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
- " return $name$_.Mutable(index);\n"
+ " return $field$.Mutable(index);\n"
"}\n"
"inline void $classname$::set_$name$(int index, const TProtoStringType& "
"value) "
"{\n"
- " $name$_.Mutable(index)->assign(value);\n"
+ " $field$.Mutable(index)->assign(value);\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
"inline void $classname$::set_$name$(int index, TProtoStringType&& value) {\n"
- " $name$_.Mutable(index)->assign(std::move(value));\n"
+ " $field$.Mutable(index)->assign(std::move(value));\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set:$full_name$)\n"
"}\n"
"inline void $classname$::set_$name$(int index, const char* value) {\n"
" $null_check$"
- " $name$_.Mutable(index)->assign(value);\n"
+ " $field$.Mutable(index)->assign(value);\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set_char:$full_name$)\n"
"}\n");
@@ -780,7 +787,7 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
format(
"inline void "
"$classname$::set_$name$(int index, StringPiece value) {\n"
- " $name$_.Mutable(index)->assign(value.data(), value.size());\n"
+ " $field$.Mutable(index)->assign(value.data(), value.size());\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
"}\n");
@@ -789,34 +796,34 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
"inline void "
"$classname$::set_$name$"
"(int index, const $pointer_type$* value, size_t size) {\n"
- " $name$_.Mutable(index)->assign(\n"
+ " $field$.Mutable(index)->assign(\n"
" reinterpret_cast<const char*>(value), size);\n"
"$annotate_set$"
" // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
"}\n"
"inline TProtoStringType* $classname$::_internal_add_$name$() {\n"
- " return $name$_.Add();\n"
+ " return $field$.Add();\n"
"}\n"
"inline void $classname$::add_$name$(const TProtoStringType& value) {\n"
- " $name$_.Add()->assign(value);\n"
+ " $field$.Add()->assign(value);\n"
"$annotate_add$"
" // @@protoc_insertion_point(field_add:$full_name$)\n"
"}\n"
"inline void $classname$::add_$name$(TProtoStringType&& value) {\n"
- " $name$_.Add(std::move(value));\n"
+ " $field$.Add(std::move(value));\n"
"$annotate_add$"
" // @@protoc_insertion_point(field_add:$full_name$)\n"
"}\n"
"inline void $classname$::add_$name$(const char* value) {\n"
" $null_check$"
- " $name$_.Add()->assign(value);\n"
+ " $field$.Add()->assign(value);\n"
"$annotate_add$"
" // @@protoc_insertion_point(field_add_char:$full_name$)\n"
"}\n");
if (!options_.opensource_runtime) {
format(
"inline void $classname$::add_$name$(StringPiece value) {\n"
- " $name$_.Add()->assign(value.data(), value.size());\n"
+ " $field$.Add()->assign(value.data(), value.size());\n"
"$annotate_add$"
" // @@protoc_insertion_point(field_add_string_piece:$full_name$)\n"
"}\n");
@@ -824,7 +831,7 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
format(
"inline void "
"$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
- " $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
+ " $field$.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
"$annotate_add$"
" // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
"}\n"
@@ -832,43 +839,32 @@ void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
"$classname$::$name$() const {\n"
"$annotate_list$"
" // @@protoc_insertion_point(field_list:$full_name$)\n"
- " return $name$_;\n"
+ " return $field$;\n"
"}\n"
"inline ::$proto_ns$::RepeatedPtrField<TProtoStringType>*\n"
"$classname$::mutable_$name$() {\n"
"$annotate_mutable_list$"
" // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
- " return &$name$_;\n"
+ " return &$field$;\n"
"}\n");
}
void RepeatedStringFieldGenerator::GenerateClearingCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_.Clear();\n");
+ format("$field$.Clear();\n");
}
void RepeatedStringFieldGenerator::GenerateMergingCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_.MergeFrom(from.$name$_);\n");
+ format("$field$.MergeFrom(from.$field$);\n");
}
void RepeatedStringFieldGenerator::GenerateSwappingCode(
io::Printer* printer) const {
Formatter format(printer, variables_);
- format("$name$_.InternalSwap(&other->$name$_);\n");
-}
-
-void RepeatedStringFieldGenerator::GenerateConstructorCode(
- io::Printer* printer) const {
- // Not needed for repeated fields.
-}
-
-void RepeatedStringFieldGenerator::GenerateCopyConstructorCode(
- io::Printer* printer) const {
- Formatter format(printer, variables_);
- format("$name$_.CopyFrom(from.$name$_);");
+ format("$field$.InternalSwap(&other->$field$);\n");
}
void RepeatedStringFieldGenerator::GenerateSerializeWithCachedSizesToArray(
@@ -895,11 +891,11 @@ void RepeatedStringFieldGenerator::GenerateByteSize(
Formatter format(printer, variables_);
format(
"total_size += $tag_size$ *\n"
- " ::$proto_ns$::internal::FromIntSize($name$_.size());\n"
- "for (int i = 0, n = $name$_.size(); i < n; i++) {\n"
+ " ::$proto_ns$::internal::FromIntSize($field$.size());\n"
+ "for (int i = 0, n = $field$.size(); i < n; i++) {\n"
" total_size += "
"::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
- " $name$_.Get(i));\n"
+ " $field$.Get(i));\n"
"}\n");
}
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_string_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_string_field.h
index 3f05443f582..845bf073a93 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_string_field.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_string_field.h
@@ -37,6 +37,7 @@
#include <map>
#include <string>
+
#include <google/protobuf/compiler/cpp/cpp_field.h>
namespace google {
@@ -48,7 +49,7 @@ class StringFieldGenerator : public FieldGenerator {
public:
StringFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
- ~StringFieldGenerator();
+ ~StringFieldGenerator() override;
// implements FieldGenerator ---------------------------------------
void GeneratePrivateMembers(io::Printer* printer) const override;
@@ -64,11 +65,13 @@ class StringFieldGenerator : public FieldGenerator {
void GenerateConstructorCode(io::Printer* printer) const override;
void GenerateCopyConstructorCode(io::Printer* printer) const override;
void GenerateDestructorCode(io::Printer* printer) const override;
+ void GenerateArenaDestructorCode(io::Printer* printer) const override;
void GenerateSerializeWithCachedSizesToArray(
io::Printer* printer) const override;
void GenerateByteSize(io::Printer* printer) const override;
void GenerateConstinitInitializer(io::Printer* printer) const override;
bool IsInlined() const override { return inlined_; }
+ ArenaDtorNeeds NeedsArenaDestructor() const override;
private:
bool inlined_;
@@ -79,7 +82,7 @@ class StringOneofFieldGenerator : public StringFieldGenerator {
public:
StringOneofFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
- ~StringOneofFieldGenerator();
+ ~StringOneofFieldGenerator() override;
// implements FieldGenerator ---------------------------------------
void GenerateInlineAccessorDefinitions(io::Printer* printer) const override;
@@ -99,7 +102,7 @@ class RepeatedStringFieldGenerator : public FieldGenerator {
public:
RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
- ~RepeatedStringFieldGenerator();
+ ~RepeatedStringFieldGenerator() override;
// implements FieldGenerator ---------------------------------------
void GeneratePrivateMembers(io::Printer* printer) const override;
@@ -108,8 +111,8 @@ class RepeatedStringFieldGenerator : public FieldGenerator {
void GenerateClearingCode(io::Printer* printer) const override;
void GenerateMergingCode(io::Printer* printer) const override;
void GenerateSwappingCode(io::Printer* printer) const override;
- void GenerateConstructorCode(io::Printer* printer) const override;
- void GenerateCopyConstructorCode(io::Printer* printer) const override;
+ void GenerateConstructorCode(io::Printer* printer) const override {}
+ void GenerateCopyConstructorCode(io::Printer* printer) const override {}
void GenerateSerializeWithCachedSizesToArray(
io::Printer* printer) const override;
void GenerateByteSize(io::Printer* printer) const override;