diff options
author | mikhnenko <mikhnenko@yandex-team.com> | 2024-06-25 08:50:35 +0300 |
---|---|---|
committer | mikhnenko <mikhnenko@yandex-team.com> | 2024-06-25 09:00:27 +0300 |
commit | 509c9fc9e7b9c3b8be7307d72a4c966e5f9aa194 (patch) | |
tree | 4b8a6a44009906ac852e59efa0bc78bb12043a5b /contrib/libs/protoc/src | |
parent | 7688f2313619a39a60ef3c2734d8efbc49a0a6db (diff) | |
download | ydb-509c9fc9e7b9c3b8be7307d72a4c966e5f9aa194.tar.gz |
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')
126 files changed, 4031 insertions, 3129 deletions
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/code_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/code_generator.cc index 9ad4d14ef1..f714df372a 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/code_generator.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/code_generator.cc @@ -76,13 +76,13 @@ GeneratorContext::~GeneratorContext() {} io::ZeroCopyOutputStream* GeneratorContext::OpenForAppend( const TProtoStringType& filename) { - return NULL; + return nullptr; } io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert( const TProtoStringType& filename, const TProtoStringType& insertion_point) { GOOGLE_LOG(FATAL) << "This GeneratorContext does not support insertion."; - return NULL; // make compiler happy + return nullptr; // make compiler happy } io::ZeroCopyOutputStream* GeneratorContext::OpenForInsertWithGeneratedCodeInfo( diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/code_generator.h b/contrib/libs/protoc/src/google/protobuf/compiler/code_generator.h index a65c381842..81f0ea748e 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/code_generator.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/code_generator.h @@ -43,6 +43,7 @@ #include <vector> #include <google/protobuf/stubs/common.h> +// Must be included last. #include <google/protobuf/port_def.inc> namespace google { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/command_line_interface.cc b/contrib/libs/protoc/src/google/protobuf/compiler/command_line_interface.cc index 7731c611d1..e1cbfee896 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/command_line_interface.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/command_line_interface.cc @@ -53,10 +53,11 @@ #endif #include <ctype.h> #include <errno.h> + #include <fstream> #include <iostream> -#include <limits.h> //For PATH_MAX +#include <limits.h> // For PATH_MAX #include <memory> @@ -68,7 +69,6 @@ #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/logging.h> -#include <google/protobuf/stubs/stringprintf.h> #include <google/protobuf/compiler/subprocess.h> #include <google/protobuf/compiler/zip_writer.h> #include <google/protobuf/compiler/plugin.pb.h> @@ -81,12 +81,14 @@ #include <google/protobuf/dynamic_message.h> #include <google/protobuf/text_format.h> #include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/stringprintf.h> #include <google/protobuf/stubs/substitute.h> #include <google/protobuf/io/io_win32.h> #include <google/protobuf/stubs/map_util.h> #include <google/protobuf/stubs/stl_util.h> +// Must be included last. #include <google/protobuf/port_def.inc> namespace google { @@ -195,7 +197,7 @@ bool TryCreateParentDirectory(const TProtoStringType& prefix, bool GetProtocAbsolutePath(TProtoStringType* path) { #ifdef _WIN32 char buffer[MAX_PATH]; - int len = GetModuleFileNameA(NULL, buffer, MAX_PATH); + int len = GetModuleFileNameA(nullptr, buffer, MAX_PATH); #elif defined(__APPLE__) char buffer[PATH_MAX]; int len = 0; @@ -210,7 +212,7 @@ bool GetProtocAbsolutePath(TProtoStringType* path) { char buffer[PATH_MAX]; size_t len = PATH_MAX; int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; - if (sysctl(mib, 4, &buffer, &len, NULL, 0) != 0) { + if (sysctl(mib, 4, &buffer, &len, nullptr, 0) != 0) { len = 0; } #else @@ -289,12 +291,12 @@ class CommandLineInterface::ErrorPrinter public io::ErrorCollector, public DescriptorPool::ErrorCollector { public: - ErrorPrinter(ErrorFormat format, DiskSourceTree* tree = NULL) + ErrorPrinter(ErrorFormat format, DiskSourceTree* tree = nullptr) : format_(format), tree_(tree), found_errors_(false), found_warnings_(false) {} - ~ErrorPrinter() {} + ~ErrorPrinter() override {} // implements MultiFileErrorCollector ------------------------------ void AddError(const TProtoStringType& filename, int line, int column, @@ -341,8 +343,8 @@ class CommandLineInterface::ErrorPrinter std::ostream& out) { // Print full path when running under MSVS TProtoStringType dfile; - if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS && tree_ != NULL && - tree_->VirtualFileToDiskFile(filename, &dfile)) { + if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS && + tree_ != nullptr && tree_->VirtualFileToDiskFile(filename, &dfile)) { out << dfile; } else { out << filename; @@ -434,7 +436,7 @@ class CommandLineInterface::MemoryOutputStream const TProtoStringType& filename, const TProtoStringType& insertion_point, const google::protobuf::GeneratedCodeInfo& info); - virtual ~MemoryOutputStream(); + ~MemoryOutputStream() override; // implements ZeroCopyOutputStream --------------------------------- bool Next(void** data, int* size) override { @@ -1116,7 +1118,7 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { FileDescriptorProto file; file.set_name("empty_message.proto"); file.add_message_type()->set_name("EmptyMessage"); - GOOGLE_CHECK(pool.BuildFile(file) != NULL); + GOOGLE_CHECK(pool.BuildFile(file) != nullptr); codec_type_ = "EmptyMessage"; if (!EncodeOrDecode(&pool)) { return 1; @@ -1270,7 +1272,7 @@ bool CommandLineInterface::ParseInputFiles( // Import the file. const FileDescriptor* parsed_file = descriptor_pool->FindFileByName(input_file); - if (parsed_file == NULL) { + if (parsed_file == nullptr) { result = false; break; } @@ -1496,7 +1498,7 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments( for (std::vector<OutputDirective>::const_iterator j = output_directives_.begin(); j != output_directives_.end(); ++j) { - if (j->generator == NULL) { + if (j->generator == nullptr) { TProtoStringType plugin_name = PluginName(plugin_prefix_, j->name); if (plugin_name == i->first) { foundImplicitPlugin = true; @@ -1613,7 +1615,7 @@ bool CommandLineInterface::ParseArgument(const char* arg, TProtoStringType* name // Two dashes: Multi-character name, with '=' separating name and // value. const char* equals_pos = strchr(arg, '='); - if (equals_pos != NULL) { + if (equals_pos != nullptr) { *name = TProtoStringType(arg, equals_pos - arg); *value = equals_pos + 1; parsed_value = true; @@ -1681,8 +1683,9 @@ CommandLineInterface::InterpretArgument(const TProtoStringType& name, // On Windows, the shell (typically cmd.exe) does not expand wildcards in // file names (e.g. foo\*.proto), so we do it ourselves. switch (google::protobuf::io::win32::ExpandWildcards( - value, - [this](const string& path) { this->input_files_.push_back(path); })) { + value, [this](const TProtoStringType& path) { + this->input_files_.push_back(path); + })) { case google::protobuf::io::win32::ExpandWildcardsResult::kSuccess: break; case google::protobuf::io::win32::ExpandWildcardsResult:: @@ -1982,11 +1985,11 @@ CommandLineInterface::InterpretArgument(const TProtoStringType& name, // Some other flag. Look it up in the generators list. const GeneratorInfo* generator_info = FindOrNull(generators_by_flag_name_, name); - if (generator_info == NULL && + if (generator_info == nullptr && (plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) { // Check if it's a generator option flag. generator_info = FindOrNull(generators_by_option_name_, name); - if (generator_info != NULL) { + if (generator_info != nullptr) { TProtoStringType* parameters = &generator_parameters_[generator_info->flag_name]; if (!parameters->empty()) { @@ -2015,8 +2018,8 @@ CommandLineInterface::InterpretArgument(const TProtoStringType& name, OutputDirective directive; directive.name = name; - if (generator_info == NULL) { - directive.generator = NULL; + if (generator_info == nullptr) { + directive.generator = nullptr; } else { directive.generator = generator_info->generator; } @@ -2176,7 +2179,7 @@ bool CommandLineInterface::GenerateOutput( GeneratorContext* generator_context) { // Call the generator. TProtoStringType error; - if (output_directive.generator == NULL) { + if (output_directive.generator == nullptr) { // This is a plugin. GOOGLE_CHECK(HasPrefixString(output_directive.name, "--") && HasSuffixString(output_directive.name, "_out")) @@ -2344,7 +2347,7 @@ bool CommandLineInterface::GeneratePluginOutput( if (!output_file.insertion_point().empty()) { TProtoStringType filename = output_file.name(); // Open a file for insert. - // We reset current_output to NULL first so that the old file is closed + // We reset current_output to nullptr first so that the old file is closed // before the new one is opened. current_output.reset(); current_output.reset( @@ -2353,11 +2356,11 @@ bool CommandLineInterface::GeneratePluginOutput( output_file.generated_code_info())); } else if (!output_file.name().empty()) { // Starting a new file. Open it. - // We reset current_output to NULL first so that the old file is closed + // We reset current_output to nullptr first so that the old file is closed // before the new one is opened. current_output.reset(); current_output.reset(generator_context->Open(output_file.name())); - } else if (current_output == NULL) { + } else if (current_output == nullptr) { *error = strings::Substitute( "$0: First file chunk returned by plugin did not specify a file " "name.", @@ -2387,7 +2390,7 @@ bool CommandLineInterface::GeneratePluginOutput( bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { // Look up the type. const Descriptor* type = pool->FindMessageTypeByName(codec_type_); - if (type == NULL) { + if (type == nullptr) { std::cerr << "Type not defined: " << codec_type_ << std::endl; return false; } @@ -2650,7 +2653,8 @@ void FormatFreeFieldNumbers(const TProtoStringType& name, StringAppendF(&output, " %d", next_free_number); } else { // Range - StringAppendF(&output, " %d-%d", next_free_number, i->first - 1); + StringAppendF(&output, " %d-%d", next_free_number, + i->first - 1); } } next_free_number = i->second; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/command_line_interface.h b/contrib/libs/protoc/src/google/protobuf/compiler/command_line_interface.h index a5f1fc7008..a2a3dffe4b 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/command_line_interface.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/command_line_interface.h @@ -49,6 +49,8 @@ #include <vector> #include <google/protobuf/stubs/common.h> + +// Must be included last. #include <google/protobuf/port_def.inc> namespace google { 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 4ecd6a9cf7..960dfcadf7 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 43f1e5f4a5..652a26b6db 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 79fa488b5f..f50fca4926 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 e65ec0f5c0..2a4ca5162b 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 72893b81c9..ef6cc81241 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 5f167a4d01..895f094c70 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 e3386f446a..9c3ec7fde4 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 2a98ad0b02..f27d876e2a 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 041d5ea4ab..d8eff2feed 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 3673c09a61..69443f5bf2 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 235d02325f..aa63845d30 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 5191a7e730..f726d0fc9b 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 ceb9a54f38..f7735da12f 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 c5028fdb1d..4d3e00ac89 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 c01ae498b1..9e71267c0f 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 4b5e0f2e95..a56c6fbda1 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 939f21a1da..5e4bbe84b8 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 04f45492c3..3b9f09c8c8 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 2beac6253b..528b419704 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 9d8063d9ca..80860053f1 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 8b745ff21c..39563cd0cd 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 23adb91430..48512a64c8 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 0b660c75b7..f48ba718a5 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 282d70e391..e033856f0c 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 0246079146..3c8209534a 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 8b37b866ae..910b59a21a 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 ff7c208ff2..77ac598e90 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 944b41ba90..7bf589fa38 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 f510716fed..d237f9d732 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 c736ce9527..4d8744976b 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 3f05443f58..845bf073a9 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; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_field_base.cc index 5e97b46441..ec39b10888 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_field_base.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -61,7 +61,7 @@ void FieldGeneratorBase::SetCommonFieldVariables( part_tag_size /= 2; } uint tag = internal::WireFormat::MakeTag(descriptor_); - uint8 tag_array[5]; + uint8_t tag_array[5]; io::CodedOutputStream::WriteTagToArray(tag, tag_array); TProtoStringType tag_bytes = StrCat(tag_array[0]); for (int i = 1; i < part_tag_size; i++) { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_helpers.h b/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_helpers.h index 29ff9e8eb6..db93b6211e 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_helpers.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_helpers.h @@ -130,7 +130,8 @@ uint GetGroupEndTag(const Descriptor* descriptor); // descriptors etc, for use in the runtime. This is the only type which is // allowed to use proto2 syntax, and it generates internal classes. inline bool IsDescriptorProto(const FileDescriptor* descriptor) { - return descriptor->name() == "google/protobuf/descriptor.proto"; + return descriptor->name() == "google/protobuf/descriptor.proto" || + descriptor->name() == "net/proto2/proto/descriptor.proto"; } // Determines whether the given message is an options message within descriptor.proto. @@ -138,15 +139,15 @@ inline bool IsDescriptorOptionMessage(const Descriptor* descriptor) { if (!IsDescriptorProto(descriptor->file())) { return false; } - const TProtoStringType name = descriptor->full_name(); - return name == "google.protobuf.FileOptions" || - name == "google.protobuf.MessageOptions" || - name == "google.protobuf.FieldOptions" || - name == "google.protobuf.OneofOptions" || - name == "google.protobuf.EnumOptions" || - name == "google.protobuf.EnumValueOptions" || - name == "google.protobuf.ServiceOptions" || - name == "google.protobuf.MethodOptions"; + const TProtoStringType name = descriptor->name(); + return name == "FileOptions" || + name == "MessageOptions" || + name == "FieldOptions" || + name == "OneofOptions" || + name == "EnumOptions" || + name == "EnumValueOptions" || + name == "ServiceOptions" || + name == "MethodOptions"; } inline bool IsWrapperType(const FieldDescriptor* descriptor) { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_map_field.cc index 44c13e2f63..a13b995da8 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_map_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_map_field.cc @@ -57,9 +57,9 @@ MapFieldGenerator::~MapFieldGenerator() { void MapFieldGenerator::GenerateMembers(io::Printer* printer) { const FieldDescriptor* key_descriptor = - descriptor_->message_type()->FindFieldByName("key"); + descriptor_->message_type()->map_key(); const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); + descriptor_->message_type()->map_value(); variables_["key_type_name"] = type_name(key_descriptor); variables_["value_type_name"] = type_name(value_descriptor); std::unique_ptr<FieldGeneratorBase> key_generator( diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_message.cc b/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_message.cc index f3e2eff8a1..cc966488f7 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -717,7 +717,7 @@ void MessageGenerator::GenerateMainParseLoop(io::Printer* printer, bool use_pars const FieldDescriptor* field = fields_by_number()[i]; internal::WireFormatLite::WireType wt = internal::WireFormat::WireTypeForFieldType(field->type()); - uint32 tag = internal::WireFormatLite::MakeTag(field->number(), wt); + arc_ui32 tag = internal::WireFormatLite::MakeTag(field->number(), wt); // Handle both packed and unpacked repeated fields with the same Read*Array call; // the two generated cases are the packed and unpacked tags. // TODO(jonskeet): Check that is_packable is equivalent to diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/importer.cc b/contrib/libs/protoc/src/google/protobuf/compiler/importer.cc index 7032f2a747..80bb1270ef 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/importer.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/importer.cc @@ -93,13 +93,13 @@ class SourceTreeDescriptorDatabase::SingleFileErrorCollector : filename_(filename), multi_file_error_collector_(multi_file_error_collector), had_errors_(false) {} - ~SingleFileErrorCollector() {} + ~SingleFileErrorCollector() override {} bool had_errors() { return had_errors_; } // implements ErrorCollector --------------------------------------- void AddError(int line, int column, const TProtoStringType& message) override { - if (multi_file_error_collector_ != NULL) { + if (multi_file_error_collector_ != nullptr) { multi_file_error_collector_->AddError(filename_, line, column, message); } had_errors_ = true; @@ -134,12 +134,12 @@ SourceTreeDescriptorDatabase::~SourceTreeDescriptorDatabase() {} bool SourceTreeDescriptorDatabase::FindFileByName(const TProtoStringType& filename, FileDescriptorProto* output) { std::unique_ptr<io::ZeroCopyInputStream> input(source_tree_->Open(filename)); - if (input == NULL) { + if (input == nullptr) { if (fallback_database_ != nullptr && fallback_database_->FindFileByName(filename, output)) { return true; } - if (error_collector_ != NULL) { + if (error_collector_ != nullptr) { error_collector_->AddError(filename, -1, 0, source_tree_->GetLastErrorMessage()); } @@ -151,7 +151,7 @@ bool SourceTreeDescriptorDatabase::FindFileByName(const TProtoStringType& filena io::Tokenizer tokenizer(input.get(), &file_error_collector); Parser parser; - if (error_collector_ != NULL) { + if (error_collector_ != nullptr) { parser.RecordErrorsTo(&file_error_collector); } if (using_validation_error_collector_) { @@ -187,7 +187,7 @@ void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddError( const TProtoStringType& filename, const TProtoStringType& element_name, const Message* descriptor, ErrorLocation location, const TProtoStringType& message) { - if (owner_->error_collector_ == NULL) return; + if (owner_->error_collector_ == nullptr) return; int line, column; if (location == DescriptorPool::ErrorCollector::IMPORT) { @@ -203,7 +203,7 @@ void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddWarning( const TProtoStringType& filename, const TProtoStringType& element_name, const Message* descriptor, ErrorLocation location, const TProtoStringType& message) { - if (owner_->error_collector_ == NULL) return; + if (owner_->error_collector_ == nullptr) return; int line, column; if (location == DescriptorPool::ErrorCollector::IMPORT) { @@ -429,7 +429,7 @@ DiskSourceTree::DiskFileToVirtualFile(const TProtoStringType& disk_file, // of verifying that we are not canonicalizing away any non-existent // directories. std::unique_ptr<io::ZeroCopyInputStream> stream(OpenDiskFile(disk_file)); - if (stream == NULL) { + if (stream == nullptr) { return CANNOT_OPEN; } @@ -440,11 +440,11 @@ bool DiskSourceTree::VirtualFileToDiskFile(const TProtoStringType& virtual_file, TProtoStringType* disk_file) { std::unique_ptr<io::ZeroCopyInputStream> stream( OpenVirtualFile(virtual_file, disk_file)); - return stream != NULL; + return stream != nullptr; } io::ZeroCopyInputStream* DiskSourceTree::Open(const TProtoStringType& filename) { - return OpenVirtualFile(filename, NULL); + return OpenVirtualFile(filename, nullptr); } TProtoStringType DiskSourceTree::GetLastErrorMessage() { @@ -461,7 +461,7 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile( last_error_message_ = "Backslashes, consecutive slashes, \".\", or \"..\" " "are not allowed in the virtual path"; - return NULL; + return nullptr; } for (const auto& mapping : mappings_) { @@ -469,8 +469,8 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile( if (ApplyMapping(virtual_file, mapping.virtual_path, mapping.disk_path, &temp_disk_file)) { io::ZeroCopyInputStream* stream = OpenDiskFile(temp_disk_file); - if (stream != NULL) { - if (disk_file != NULL) { + if (stream != nullptr) { + if (disk_file != nullptr) { *disk_file = temp_disk_file; } return stream; @@ -480,12 +480,12 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile( // The file exists but is not readable. last_error_message_ = "Read access is denied for file: " + temp_disk_file; - return NULL; + return nullptr; } } } last_error_message_ = "File not found."; - return NULL; + return nullptr; } io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( @@ -498,12 +498,12 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( #if defined(_WIN32) if (ret == 0 && sb.st_mode & S_IFDIR) { last_error_message_ = "Input file is a directory."; - return NULL; + return nullptr; } #else if (ret == 0 && S_ISDIR(sb.st_mode)) { last_error_message_ = "Input file is a directory."; - return NULL; + return nullptr; } #endif int file_descriptor; @@ -515,7 +515,7 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( result->SetCloseOnDelete(true); return result; } else { - return NULL; + return nullptr; } } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/importer.h b/contrib/libs/protoc/src/google/protobuf/compiler/importer.h index f38fcf2d67..c13821a243 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/importer.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/importer.h @@ -41,10 +41,12 @@ #include <string> #include <utility> #include <vector> + #include <google/protobuf/compiler/parser.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor_database.h> +// Must be included last. #include <google/protobuf/port_def.inc> namespace google { @@ -85,7 +87,7 @@ class PROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase { // the specified source_tree. SourceTreeDescriptorDatabase(SourceTree* source_tree, DescriptorDatabase* fallback_database); - ~SourceTreeDescriptorDatabase(); + ~SourceTreeDescriptorDatabase() override; // Instructs the SourceTreeDescriptorDatabase to report any parse errors // to the given MultiFileErrorCollector. This should be called before @@ -124,7 +126,7 @@ class PROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase { : public DescriptorPool::ErrorCollector { public: ValidationErrorCollector(SourceTreeDescriptorDatabase* owner); - ~ValidationErrorCollector(); + ~ValidationErrorCollector() override; // implements ErrorCollector --------------------------------------- void AddError(const TProtoStringType& filename, const TProtoStringType& element_name, @@ -241,7 +243,7 @@ class PROTOBUF_EXPORT SourceTree { class PROTOBUF_EXPORT DiskSourceTree : public SourceTree { public: DiskSourceTree(); - ~DiskSourceTree(); + ~DiskSourceTree() override; // Map a path on disk to a location in the SourceTree. The path may be // either a file or a directory. If it is a directory, the entire tree diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_context.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_context.cc index 3403cfca2c..9ee161f7f3 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_context.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_context.cc @@ -30,11 +30,11 @@ #include <google/protobuf/compiler/java/java_context.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/compiler/java/java_field.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/map_util.h> namespace google { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_doc_comment.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_doc_comment.cc index 2d30eabce9..2252d122fa 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_doc_comment.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_doc_comment.cc @@ -36,9 +36,9 @@ #include <vector> -#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/descriptor.pb.h> namespace google { namespace protobuf { @@ -199,7 +199,16 @@ void WriteDeprecatedJavadoc(io::Printer* printer, const FieldDescriptor* field, return; } - printer->Print(" * @deprecated\n"); + TProtoStringType startLine = "0"; + SourceLocation location; + if (field->GetSourceLocation(&location)) { + startLine = std::to_string(location.start_line); + } + + printer->Print(" * @deprecated $name$ is deprecated.\n", "name", + field->full_name()); + printer->Print(" * See $file$;l=$line$\n", "file", field->file()->name(), + "line", startLine); } void WriteFieldAccessorDocComment(io::Printer* printer, diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_doc_comment.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_doc_comment.h index e7faa4a6a0..52d6f77474 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_doc_comment.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_doc_comment.h @@ -37,6 +37,7 @@ #include <google/protobuf/descriptor.h> +// Must be included last. #include <google/protobuf/port_def.inc> namespace google { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum.cc index d9070eeaab..8574527f0b 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum.cc @@ -32,17 +32,18 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include <google/protobuf/compiler/java/java_enum.h> + #include <map> #include <string> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> -#include <google/protobuf/compiler/java/java_enum.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_field.cc index 8c658eef9b..59df1132e7 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_field.cc @@ -40,13 +40,13 @@ #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/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_field.h index 5d3564530e..3fb65ae546 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_field.h @@ -37,6 +37,7 @@ #include <map> #include <string> + #include <google/protobuf/compiler/java/java_field.h> namespace google { @@ -99,7 +100,7 @@ class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator { ImmutableEnumOneofFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableEnumOneofFieldGenerator(); + ~ImmutableEnumOneofFieldGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_field_lite.cc index f7e7b2dab7..33cff57cf3 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_field_lite.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_field_lite.cc @@ -40,13 +40,13 @@ #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/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_lite.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_lite.cc index bf84607aac..7ec742d19f 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_lite.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_enum_lite.cc @@ -32,17 +32,18 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include <google/protobuf/compiler/java/java_enum_lite.h> + #include <map> #include <string> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> -#include <google/protobuf/compiler/java/java_enum_lite.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/map_util.h> namespace google { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension.cc index 9602780c49..d90994503d 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension.cc @@ -34,12 +34,12 @@ #include <google/protobuf/compiler/java/java_extension.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension.h index d796c56c76..f9bd326f9b 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension.h @@ -92,7 +92,7 @@ class ImmutableExtensionGenerator : public ExtensionGenerator { public: explicit ImmutableExtensionGenerator(const FieldDescriptor* descriptor, Context* context); - virtual ~ImmutableExtensionGenerator(); + ~ImmutableExtensionGenerator() override; void Generate(io::Printer* printer) override; int GenerateNonNestedInitializationCode(io::Printer* printer) override; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension_lite.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension_lite.cc index 3f12f20a57..0135d9ee03 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension_lite.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension_lite.cc @@ -30,12 +30,12 @@ #include <google/protobuf/compiler/java/java_extension_lite.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension_lite.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension_lite.h index 117b87f7a8..3e13db7028 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension_lite.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_extension_lite.h @@ -49,7 +49,7 @@ class ImmutableExtensionLiteGenerator : public ExtensionGenerator { public: explicit ImmutableExtensionLiteGenerator(const FieldDescriptor* descriptor, Context* context); - virtual ~ImmutableExtensionLiteGenerator(); + ~ImmutableExtensionLiteGenerator() override; void Generate(io::Printer* printer) override; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_field.cc index 15283e1083..9373e568cf 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_field.cc @@ -38,6 +38,9 @@ #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_enum_field.h> #include <google/protobuf/compiler/java/java_enum_field_lite.h> @@ -50,9 +53,6 @@ #include <google/protobuf/compiler/java/java_primitive_field_lite.h> #include <google/protobuf/compiler/java/java_string_field.h> #include <google/protobuf/compiler/java/java_string_field_lite.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> namespace google { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_field.h index 09384c483a..481fbdb456 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_field.h @@ -156,7 +156,7 @@ template <> FieldGeneratorMap<ImmutableFieldLiteGenerator>::~FieldGeneratorMap(); -// Field information used in FieldGeneartors. +// Field information used in FieldGenerators. struct FieldGeneratorInfo { TProtoStringType name; TProtoStringType capitalized_name; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_file.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_file.cc index 0809febb8b..c2261ddfeb 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_file.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_file.cc @@ -37,6 +37,11 @@ #include <memory> #include <set> +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/dynamic_message.h> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_enum.h> #include <google/protobuf/compiler/java/java_enum_lite.h> @@ -47,12 +52,7 @@ #include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/compiler/java/java_service.h> #include <google/protobuf/compiler/java/java_shared_code_generator.h> -#include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/dynamic_message.h> -#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_file.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_file.h index b567b62fd9..7a5a8ec01d 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_file.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_file.h @@ -38,6 +38,7 @@ #include <memory> #include <string> #include <vector> + #include <google/protobuf/stubs/common.h> #include <google/protobuf/compiler/java/java_options.h> diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_generator.cc index 2b5728579e..ce198c7692 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_generator.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_generator.cc @@ -37,6 +37,9 @@ #include <memory> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/stubs/stringprintf.h> #include <google/protobuf/compiler/java/java_file.h> #include <google/protobuf/compiler/java/java_generator_factory.h> #include <google/protobuf/compiler/java/java_helpers.h> @@ -44,8 +47,6 @@ #include <google/protobuf/compiler/java/java_options.h> #include <google/protobuf/compiler/java/java_shared_code_generator.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/stubs/strutil.h> diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_generator.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_generator.h index 90d2610550..e08c980788 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_generator.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_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 java { class PROTOC_EXPORT JavaGenerator : public CodeGenerator { public: JavaGenerator(); - ~JavaGenerator(); + ~JavaGenerator() override; // implements CodeGenerator ---------------------------------------- bool Generate(const FileDescriptor* file, const TProtoStringType& parameter, diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_generator_factory.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_generator_factory.h index 831d9dd857..807bca383a 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_generator_factory.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_generator_factory.h @@ -78,7 +78,7 @@ class GeneratorFactory { class ImmutableGeneratorFactory : public GeneratorFactory { public: ImmutableGeneratorFactory(Context* context); - virtual ~ImmutableGeneratorFactory(); + ~ImmutableGeneratorFactory() override; MessageGenerator* NewMessageGenerator( const Descriptor* descriptor) const override; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_helpers.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_helpers.cc index 4c613af8ea..3f1f058c9e 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_helpers.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_helpers.cc @@ -40,13 +40,13 @@ #include <unordered_set> #include <vector> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/stubs/substitute.h> #include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/compiler/java/java_names.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> #include <google/protobuf/stubs/hash.h> // for hash<T *> namespace google { @@ -66,15 +66,27 @@ namespace { const char* kDefaultPackage = ""; -// Names that should be avoided as field names. -// Using them will cause the compiler to generate accessors whose names are -// colliding with methods defined in base classes. +// Names that should be avoided (in UpperCamelCase format). +// Using them will cause the compiler to generate accessors whose names +// collide with methods defined in base classes. +// Keep this list in sync with specialFieldNames in +// java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java const char* kForbiddenWordList[] = { - // message base class: - "cached_size", - "serialized_size", // java.lang.Object: - "class", + "Class", + // com.google.protobuf.MessageLiteOrBuilder: + "DefaultInstanceForType", + // com.google.protobuf.MessageLite: + "ParserForType", + "SerializedSize", + // com.google.protobuf.MessageOrBuilder: + "AllFields", + "DescriptorForType", + "InitializationErrorString", + // TODO(b/219045204): re-enable + // "UnknownFields", + // obsolete. kept for backwards compatibility of generated code + "CachedSize", }; const std::unordered_set<TProtoStringType>* kReservedNames = @@ -93,7 +105,7 @@ const std::unordered_set<TProtoStringType>* kReservedNames = bool IsForbidden(const TProtoStringType& field_name) { for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) { - if (field_name == kForbiddenWordList[i]) { + if (UnderscoresToCamelCase(field_name, true) == kForbiddenWordList[i]) { return true; } } @@ -1049,8 +1061,7 @@ int GetExperimentalJavaFieldType(const FieldDescriptor* field) { if (field->is_map()) { if (!SupportUnknownEnumValue(field)) { - const FieldDescriptor* value = - field->message_type()->FindFieldByName("value"); + const FieldDescriptor* value = field->message_type()->map_value(); if (GetJavaType(value) == JAVATYPE_ENUM) { extra_bits |= kMapWithProto2EnumValue; } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_helpers.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_helpers.h index b0cce4949b..59bb718bc9 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_helpers.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_helpers.h @@ -38,10 +38,10 @@ #include <cstdint> #include <string> -#include <google/protobuf/compiler/java/java_context.h> -#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.h> +#include <google/protobuf/compiler/java/java_context.h> +#include <google/protobuf/descriptor.pb.h> namespace google { namespace protobuf { @@ -151,6 +151,21 @@ inline bool IsDescriptorProto(const Descriptor* descriptor) { // fields. TProtoStringType GetOneofStoredType(const FieldDescriptor* field); +// We use either the proto1 enums if the enum is generated, otherwise fall back +// to use integers. +enum class Proto1EnumRepresentation { + kEnum, + kInteger, +}; + +// Returns which representation we should use. +inline Proto1EnumRepresentation GetProto1EnumRepresentation( + const EnumDescriptor* descriptor) { + if (descriptor->containing_type() != nullptr) { + return Proto1EnumRepresentation::kEnum; + } + return Proto1EnumRepresentation::kInteger; +} // Whether we should generate multiple java files for messages. inline bool MultipleJavaFiles(const FileDescriptor* descriptor, diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_kotlin_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_kotlin_generator.cc index 9a18926275..fc0d823671 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_kotlin_generator.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_kotlin_generator.cc @@ -30,11 +30,11 @@ #include <google/protobuf/compiler/java/java_kotlin_generator.h> +#include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/java/java_file.h> +#include <google/protobuf/compiler/java/java_generator.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_options.h> -#include <google/protobuf/compiler/java/java_generator.h> -#include <google/protobuf/compiler/code_generator.h> namespace google { namespace protobuf { @@ -63,11 +63,13 @@ bool KotlinGenerator::Generate(const FileDescriptor* file, if (option.first == "output_list_file") { file_options.output_list_file = option.second; } else if (option.first == "immutable") { + // Note: the option is considered always set regardless of the input. file_options.generate_immutable_code = true; } else if (option.first == "mutable") { *error = "Mutable not supported by Kotlin generator"; return false; } else if (option.first == "shared") { + // Note: the option is considered always set regardless of the input. file_options.generate_shared_code = true; } else if (option.first == "lite") { file_options.enforce_lite = true; @@ -81,23 +83,17 @@ bool KotlinGenerator::Generate(const FileDescriptor* file, } } - // By default we generate immutable code and shared code for immutable API. - if (!file_options.generate_immutable_code && - !file_options.generate_shared_code) { - file_options.generate_immutable_code = true; - file_options.generate_shared_code = true; - } + // We only support generation of immutable code so we do it. + file_options.generate_immutable_code = true; + file_options.generate_shared_code = true; std::vector<TProtoStringType> all_files; std::vector<TProtoStringType> all_annotations; - std::unique_ptr<FileGenerator> file_generator; - if (file_options.generate_immutable_code) { - file_generator.reset( + std::unique_ptr<FileGenerator> file_generator( new FileGenerator(file, file_options, /* immutable_api = */ true)); - } - if (!file_generator->Validate(error)) { + if (!file_generator || !file_generator->Validate(error)) { return false; } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_kotlin_generator.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_kotlin_generator.h index 6e0fa8c276..195acb6537 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_kotlin_generator.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_kotlin_generator.h @@ -36,6 +36,8 @@ #include <string> #include <google/protobuf/compiler/code_generator.h> + +// Must be included last. #include <google/protobuf/port_def.inc> namespace google { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_map_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_map_field.cc index a35bd42ebe..7a93f4696d 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_map_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_map_field.cc @@ -30,11 +30,11 @@ #include <google/protobuf/compiler/java/java_map_field.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> namespace google { namespace protobuf { @@ -47,14 +47,14 @@ const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) { GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); const Descriptor* message = descriptor->message_type(); GOOGLE_CHECK(message->options().map_entry()); - return message->FindFieldByName("key"); + return message->map_key(); } const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) { GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); const Descriptor* message = descriptor->message_type(); GOOGLE_CHECK(message->options().map_entry()); - return message->FindFieldByName("value"); + return message->map_value(); } TProtoStringType TypeName(const FieldDescriptor* field, @@ -99,6 +99,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, const JavaType keyJavaType = GetJavaType(key); const JavaType valueJavaType = GetJavaType(value); + TProtoStringType pass_through_nullness = "/* nullable */\n"; + (*variables)["key_type"] = TypeName(key, name_resolver, false); TProtoStringType boxed_key_type = TypeName(key, name_resolver, true); (*variables)["boxed_key_type"] = boxed_key_type; @@ -129,6 +131,9 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["value_enum_type"] = TypeName(value, name_resolver, false); + (*variables)["value_enum_type_pass_through_nullness"] = + pass_through_nullness + (*variables)["value_enum_type"]; + if (SupportUnknownEnumValue(descriptor->file())) { // Map unknown values to a special UNRECOGNIZED value if supported. (*variables)["unrecognized_value"] = @@ -140,6 +145,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, } } else { (*variables)["value_type"] = TypeName(value, name_resolver, false); + + (*variables)["value_type_pass_through_nullness"] = + (IsReferenceType(valueJavaType) ? pass_through_nullness : "") + + (*variables)["value_type"]; + (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true); (*variables)["value_wire_type"] = WireType(value); (*variables)["value_default_value"] = @@ -218,11 +228,12 @@ void ImmutableMapFieldGenerator::GenerateInterfaceMembers( "${$get$capitalized_name$Map$}$();\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print( - variables_, - "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" - " $key_type$ key,\n" - " $value_enum_type$ defaultValue);\n"); + printer->Print(variables_, + "$deprecation$$value_enum_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_enum_type_pass_through_nullness$ " + " defaultValue);\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( @@ -276,9 +287,10 @@ void ImmutableMapFieldGenerator::GenerateInterfaceMembers( WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$\n" - "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n" + "$value_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" - " $value_type$ defaultValue);\n"); + " $value_type_pass_through_nullness$ defaultValue);\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -538,9 +550,10 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( variables_, "@java.lang.Override\n" "$deprecation$\n" - "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" + "public $value_enum_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" - " $value_enum_type$ defaultValue) {\n" + " $value_enum_type_pass_through_nullness$ defaultValue) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" " internalGet$capitalized_name$().getMap();\n" diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_map_field_lite.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_map_field_lite.cc index 2c52ccaea7..8817f27339 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_map_field_lite.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_map_field_lite.cc @@ -32,11 +32,11 @@ #include <cstdint> +#include <google/protobuf/io/printer.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> namespace google { namespace protobuf { @@ -49,14 +49,14 @@ const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) { GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); const Descriptor* message = descriptor->message_type(); GOOGLE_CHECK(message->options().map_entry()); - return message->FindFieldByName("key"); + return message->map_key(); } const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) { GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); const Descriptor* message = descriptor->message_type(); GOOGLE_CHECK(message->options().map_entry()); - return message->FindFieldByName("value"); + return message->map_value(); } TProtoStringType TypeName(const FieldDescriptor* field, @@ -101,6 +101,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, const JavaType keyJavaType = GetJavaType(key); const JavaType valueJavaType = GetJavaType(value); + TProtoStringType pass_through_nullness = "/* nullable */\n"; + (*variables)["key_type"] = TypeName(key, name_resolver, false); (*variables)["boxed_key_type"] = TypeName(key, name_resolver, true); (*variables)["kt_key_type"] = KotlinTypeName(key, name_resolver); @@ -128,6 +130,9 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["value_enum_type"] = TypeName(value, name_resolver, false); + (*variables)["value_enum_type_pass_through_nullness"] = + pass_through_nullness + (*variables)["value_enum_type"]; + if (SupportUnknownEnumValue(descriptor->file())) { // Map unknown values to a special UNRECOGNIZED value if supported. (*variables)["unrecognized_value"] = @@ -139,6 +144,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, } } else { (*variables)["value_type"] = TypeName(value, name_resolver, false); + + (*variables)["value_type_pass_through_nullness"] = + (IsReferenceType(valueJavaType) ? pass_through_nullness : "") + + (*variables)["value_type"]; + (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true); (*variables)["value_wire_type"] = WireType(value); (*variables)["value_default_value"] = @@ -203,11 +213,12 @@ void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers( "${$get$capitalized_name$Map$}$();\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print( - variables_, - "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" - " $key_type$ key,\n" - " $value_enum_type$ defaultValue);\n"); + printer->Print(variables_, + "$deprecation$$value_enum_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_enum_type_pass_through_nullness$ " + " defaultValue);\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( @@ -261,9 +272,10 @@ void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers( WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$\n" - "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n" + "$value_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" - " $value_type$ defaultValue);\n"); + " $value_type_pass_through_nullness$ defaultValue);\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -606,9 +618,10 @@ void ImmutableMapFieldLiteGenerator::GenerateBuilderMembers( variables_, "@java.lang.Override\n" "$deprecation$\n" - "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" + "public $value_enum_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" - " $value_enum_type$ defaultValue) {\n" + " $value_enum_type_pass_through_nullness$ defaultValue) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n" " instance.get$capitalized_name$Map();\n" diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message.cc index e5343d6762..9a5c25a538 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message.cc @@ -40,6 +40,11 @@ #include <memory> #include <vector> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_enum.h> @@ -50,11 +55,6 @@ #include <google/protobuf/compiler/java/java_message_builder_lite.h> #include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> namespace google { namespace protobuf { @@ -67,7 +67,7 @@ using internal::WireFormatLite; namespace { TProtoStringType MapValueImmutableClassdName(const Descriptor* descriptor, ClassNameResolver* name_resolver) { - const FieldDescriptor* value_field = descriptor->FindFieldByName("value"); + const FieldDescriptor* value_field = descriptor->map_value(); GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type()); return name_resolver->GetImmutableClassName(value_field->message_type()); } @@ -1273,6 +1273,9 @@ void ImmutableMessageGenerator::GenerateParsingConstructor( printer->Print( "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" " throw e.setUnfinishedMessage(this);\n" + "} catch (com.google.protobuf.UninitializedMessageException e) {\n" + " throw " + "e.asInvalidProtocolBufferException().setUnfinishedMessage(this);\n" "} catch (java.io.IOException e) {\n" " throw new com.google.protobuf.InvalidProtocolBufferException(\n" " e).setUnfinishedMessage(this);\n" @@ -1455,7 +1458,7 @@ void ImmutableMessageGenerator::GenerateKotlinDsl(io::Printer* printer) const { void ImmutableMessageGenerator::GenerateKotlinMembers( io::Printer* printer) const { printer->Print( - "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"-initialize$camelcase_name$\")\n" "public inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> " "kotlin.Unit): " "$message$ " @@ -1486,7 +1489,7 @@ void ImmutableMessageGenerator::GenerateTopLevelKotlinMembers( "kotlin.Unit): " "$message$ =\n" " $message_kt$.Dsl._create(this.toBuilder()).apply { block() " - "}._build()\n", + "}._build()\n\n", "message", name_resolver_->GetClassName(descriptor_, true), "message_kt", name_resolver_->GetKotlinExtensionsClassName(descriptor_)); @@ -1495,6 +1498,24 @@ void ImmutableMessageGenerator::GenerateTopLevelKotlinMembers( ImmutableMessageGenerator(descriptor_->nested_type(i), context_) .GenerateTopLevelKotlinMembers(printer); } + + GenerateKotlinOrNull(printer); +} + +void ImmutableMessageGenerator::GenerateKotlinOrNull(io::Printer* printer) const { + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->has_presence() && GetJavaType(field) == JAVATYPE_MESSAGE) { + printer->Print( + "val $full_classname$OrBuilder.$camelcase_name$OrNull: $full_name$?\n" + " get() = if (has$name$()) get$name$() else null\n\n", + "full_classname", name_resolver_->GetClassName(descriptor_, true), + "camelcase_name", context_->GetFieldGeneratorInfo(field)->name, + "full_name", + name_resolver_->GetImmutableClassName(field->message_type()), "name", + context_->GetFieldGeneratorInfo(field)->capitalized_name); + } + } } void ImmutableMessageGenerator::GenerateKotlinExtensions( @@ -1504,7 +1525,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@Suppress(\"UNCHECKED_CAST\")\n" "@kotlin.jvm.JvmSynthetic\n" - "public operator fun <T> get(extension: " + "public operator fun <T : kotlin.Any> get(extension: " "com.google.protobuf.ExtensionLite<$message$, T>): T {\n" " return if (extension.isRepeated) {\n" " get(extension as com.google.protobuf.ExtensionLite<$message$, " @@ -1520,7 +1541,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( "@kotlin.OptIn" "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n" - "public operator fun <E> get(\n" + "public operator fun <E : kotlin.Any> get(\n" " extension: com.google.protobuf.ExtensionLite<$message$, List<E>>\n" "): com.google.protobuf.kotlin.ExtensionList<E, $message$> {\n" " return com.google.protobuf.kotlin.ExtensionList(extension, " @@ -1549,7 +1570,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@kotlin.PublishedApi\n" - "internal fun <T> setExtension(extension: " + "internal fun <T : kotlin.Any> setExtension(extension: " "com.google.protobuf.ExtensionLite<$message$, T>, " "value: T) {\n" " _builder.setExtension(extension, value)\n" @@ -1592,7 +1613,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public fun <E> com.google.protobuf.kotlin.ExtensionList<E, " + "public fun <E : kotlin.Any> com.google.protobuf.kotlin.ExtensionList<E, " "$message$>.add(value: E) {\n" " _builder.addExtension(this.extension, value)\n" "}\n\n", @@ -1601,7 +1622,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" - "public inline operator fun <E> " + "public inline operator fun <E : kotlin.Any> " "com.google.protobuf.kotlin.ExtensionList<E, " "$message$>.plusAssign" "(value: E) {\n" @@ -1611,7 +1632,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public fun <E> com.google.protobuf.kotlin.ExtensionList<E, " + "public fun <E : kotlin.Any> com.google.protobuf.kotlin.ExtensionList<E, " "$message$>.addAll(values: Iterable<E>) {\n" " for (value in values) {\n" " add(value)\n" @@ -1622,7 +1643,7 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" - "public inline operator fun <E> " + "public inline operator fun <E : kotlin.Any> " "com.google.protobuf.kotlin.ExtensionList<E, " "$message$>.plusAssign(values: " "Iterable<E>) {\n" @@ -1632,7 +1653,8 @@ void ImmutableMessageGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, " + "public operator fun <E : kotlin.Any> " + "com.google.protobuf.kotlin.ExtensionList<E, " "$message$>.set(index: Int, value: " "E) {\n" " _builder.setExtension(this.extension, index, value)\n" diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message.h index cafc91e68b..cc24d73d35 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message.h @@ -37,6 +37,7 @@ #include <map> #include <string> + #include <google/protobuf/compiler/java/java_field.h> namespace google { @@ -100,7 +101,7 @@ class MessageGenerator { class ImmutableMessageGenerator : public MessageGenerator { public: ImmutableMessageGenerator(const Descriptor* descriptor, Context* context); - virtual ~ImmutableMessageGenerator(); + ~ImmutableMessageGenerator() override; void Generate(io::Printer* printer) override; void GenerateInterface(io::Printer* printer) override; @@ -136,6 +137,7 @@ class ImmutableMessageGenerator : public MessageGenerator { void GenerateParsingConstructor(io::Printer* printer); void GenerateMutableCopy(io::Printer* printer); void GenerateKotlinExtensions(io::Printer* printer) const; + void GenerateKotlinOrNull(io::Printer* printer) const; void GenerateAnyMethods(io::Printer* printer); Context* context_; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder.cc index 510b9d785c..e8ff5fa33b 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder.cc @@ -39,6 +39,11 @@ #include <memory> #include <vector> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_enum.h> @@ -47,11 +52,6 @@ #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> namespace google { namespace protobuf { @@ -61,7 +61,7 @@ namespace java { namespace { TProtoStringType MapValueImmutableClassdName(const Descriptor* descriptor, ClassNameResolver* name_resolver) { - const FieldDescriptor* value_field = descriptor->FindFieldByName("value"); + const FieldDescriptor* value_field = descriptor->map_value(); GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type()); return name_resolver->GetImmutableClassName(value_field->message_type()); } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder.h index fcd73b3436..619bf9eca1 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder.h @@ -37,6 +37,7 @@ #include <map> #include <string> + #include <google/protobuf/compiler/java/java_field.h> namespace google { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder_lite.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder_lite.cc index bff99b7b1a..5f90e8d691 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder_lite.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder_lite.cc @@ -39,6 +39,11 @@ #include <memory> #include <vector> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_enum.h> @@ -47,11 +52,6 @@ #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> namespace google { namespace protobuf { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder_lite.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder_lite.h index 3402adf332..03ecbf870b 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder_lite.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_builder_lite.h @@ -37,6 +37,7 @@ #include <map> #include <string> + #include <google/protobuf/compiler/java/java_field.h> namespace google { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field.cc index bdd80a811f..5db89dbe21 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field.cc @@ -32,17 +32,18 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include <google/protobuf/compiler/java/java_message_field.h> + #include <map> #include <string> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/compiler/java/java_message_field.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { @@ -438,6 +439,16 @@ void ImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" "}\n"); + + GenerateKotlinOrNull(printer); +} + +void ImmutableMessageFieldGenerator::GenerateKotlinOrNull(io::Printer* printer) const { + if (descriptor_->has_optional_keyword()) { + printer->Print(variables_, + "public val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n" + " get() = $kt_dsl_builder$.$name$OrNull\n"); + } } void ImmutableMessageFieldGenerator::GenerateFieldBuilderInitializationCode( @@ -698,8 +709,9 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( "if ($has_oneof_case_message$) {\n" " $name$Builder_.mergeFrom(value);\n" - "}\n" - "$name$Builder_.setMessage(value);\n", + "} else {\n" + " $name$Builder_.setMessage(value);\n" + "}\n", "$set_oneof_case_message$;\n" "return this;\n"); @@ -1426,7 +1438,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "add(value: $kt_type$) {\n" " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, /* builder */ false); @@ -1438,7 +1450,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "plusAssign(value: $kt_type$) {\n" " add(value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, /* builder */ false); @@ -1449,7 +1461,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n" " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, /* builder */ false); @@ -1462,7 +1474,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n" " addAll(values)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, /* builder */ false); @@ -1474,7 +1486,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "set(index: kotlin.Int, value: $kt_type$) {\n" " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, /* builder */ false); @@ -1485,7 +1497,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "clear() {\n" " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" - "}"); + "}\n\n"); } } // namespace java diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field.h index a0c24ae7b7..94a144d4ae 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field.h @@ -37,6 +37,7 @@ #include <map> #include <string> + #include <google/protobuf/compiler/java/java_field.h> namespace google { @@ -61,7 +62,7 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator { int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableMessageFieldGenerator(); + ~ImmutableMessageFieldGenerator() override; // implements ImmutableFieldGenerator // --------------------------------------- @@ -102,6 +103,7 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator { private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldGenerator); + void GenerateKotlinOrNull(io::Printer* printer) const; }; class ImmutableMessageOneofFieldGenerator @@ -110,7 +112,7 @@ class ImmutableMessageOneofFieldGenerator ImmutableMessageOneofFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableMessageOneofFieldGenerator(); + ~ImmutableMessageOneofFieldGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field_lite.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field_lite.cc index 100726856c..523190d85a 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field_lite.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field_lite.cc @@ -38,13 +38,13 @@ #include <map> #include <string> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { @@ -308,6 +308,15 @@ void ImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" "}\n"); + GenerateKotlinOrNull(printer); +} + +void ImmutableMessageFieldLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const { + if (descriptor_->has_optional_keyword()) { + printer->Print(variables_, + "public val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n" + " get() = $kt_dsl_builder$.$name$OrNull\n"); + } } void ImmutableMessageFieldLiteGenerator::GenerateFieldInfo( @@ -816,7 +825,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "add(value: $kt_type$) {\n" " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, /* builder */ false); @@ -828,7 +837,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "plusAssign(value: $kt_type$) {\n" " add(value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, /* builder */ false); @@ -839,7 +848,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n" " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, /* builder */ false); @@ -852,7 +861,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n" " addAll(values)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, /* builder */ false); @@ -864,7 +873,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "set(index: kotlin.Int, value: $kt_type$) {\n" " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" - "}"); + "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, /* builder */ false); @@ -875,7 +884,7 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." "clear() {\n" " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" - "}"); + "}\n"); } } // namespace java diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field_lite.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field_lite.h index 9f778da45b..189d760afe 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field_lite.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_field_lite.h @@ -62,7 +62,7 @@ class ImmutableMessageFieldLiteGenerator : public ImmutableFieldLiteGenerator { explicit ImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor, int messageBitIndex, Context* context); - ~ImmutableMessageFieldLiteGenerator(); + ~ImmutableMessageFieldLiteGenerator() override; // implements ImmutableFieldLiteGenerator // ------------------------------------ @@ -85,6 +85,7 @@ class ImmutableMessageFieldLiteGenerator : public ImmutableFieldLiteGenerator { private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldLiteGenerator); + void GenerateKotlinOrNull(io::Printer* printer) const; }; class ImmutableMessageOneofFieldLiteGenerator @@ -93,7 +94,7 @@ class ImmutableMessageOneofFieldLiteGenerator ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor, int messageBitIndex, Context* context); - ~ImmutableMessageOneofFieldLiteGenerator(); + ~ImmutableMessageOneofFieldLiteGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_lite.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_lite.cc index f5d7c9362a..615dece6cb 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_lite.cc @@ -40,6 +40,11 @@ #include <memory> #include <vector> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_enum_lite.h> @@ -50,11 +55,6 @@ #include <google/protobuf/compiler/java/java_message_builder_lite.h> #include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> namespace google { namespace protobuf { @@ -779,7 +779,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinDsl( void ImmutableMessageLiteGenerator::GenerateKotlinMembers( io::Printer* printer) const { printer->Print( - "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"-initialize$camelcase_name$\")\n" "public inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> " "kotlin.Unit): " "$message$ =\n" @@ -808,7 +808,7 @@ void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers( "kotlin.Unit): " "$message$ =\n" " $message_kt$.Dsl._create(this.toBuilder()).apply { block() " - "}._build()\n", + "}._build()\n\n", "message", name_resolver_->GetClassName(descriptor_, true), "message_kt", name_resolver_->GetKotlinExtensionsClassName(descriptor_)); @@ -817,6 +817,26 @@ void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers( ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) .GenerateTopLevelKotlinMembers(printer); } + + GenerateKotlinOrNull(printer); +} + +void ImmutableMessageLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const { + // Generate getFieldOrNull getters for all optional message fields. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->has_presence() && GetJavaType(field) == JAVATYPE_MESSAGE) { + printer->Print( + "val $full_classname$OrBuilder.$camelcase_name$OrNull: " + "$full_name$?\n" + " get() = if (has$name$()) get$name$() else null\n\n", + "full_classname", name_resolver_->GetClassName(descriptor_, true), + "camelcase_name", context_->GetFieldGeneratorInfo(field)->name, + "full_name", + name_resolver_->GetImmutableClassName(field->message_type()), "name", + context_->GetFieldGeneratorInfo(field)->capitalized_name); + } + } } void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( @@ -826,7 +846,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@Suppress(\"UNCHECKED_CAST\")\n" "@kotlin.jvm.JvmSynthetic\n" - "public operator fun <T> get(extension: " + "public operator fun <T : kotlin.Any> get(extension: " "com.google.protobuf.ExtensionLite<$message$, T>): T {\n" " return if (extension.isRepeated) {\n" " get(extension as com.google.protobuf.ExtensionLite<$message$, " @@ -842,7 +862,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( "@kotlin.OptIn" "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n" - "public operator fun <E> get(\n" + "public operator fun <E : kotlin.Any> get(\n" " extension: com.google.protobuf.ExtensionLite<$message$, List<E>>\n" "): com.google.protobuf.kotlin.ExtensionList<E, $message$> {\n" " return com.google.protobuf.kotlin.ExtensionList(extension, " @@ -871,7 +891,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@kotlin.PublishedApi\n" - "internal fun <T> setExtension(extension: " + "internal fun <T : kotlin.Any> setExtension(extension: " "com.google.protobuf.ExtensionLite<$message$, T>, " "value: T) {\n" " _builder.setExtension(extension, value)\n" @@ -914,7 +934,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public fun<E> com.google.protobuf.kotlin.ExtensionList<E, " + "public fun<E : kotlin.Any> com.google.protobuf.kotlin.ExtensionList<E, " "$message$>.add(value: E) {\n" " _builder.addExtension(this.extension, value)\n" "}\n\n", @@ -923,7 +943,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" - "public inline operator fun <E> " + "public inline operator fun <E : kotlin.Any> " "com.google.protobuf.kotlin.ExtensionList<E, " "$message$>.plusAssign" "(value: E) {\n" @@ -933,7 +953,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public fun<E> com.google.protobuf.kotlin.ExtensionList<E, " + "public fun<E : kotlin.Any> com.google.protobuf.kotlin.ExtensionList<E, " "$message$>.addAll(values: Iterable<E>) {\n" " for (value in values) {\n" " add(value)\n" @@ -944,7 +964,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" - "public inline operator fun <E> " + "public inline operator fun <E : kotlin.Any> " "com.google.protobuf.kotlin.ExtensionList<E, " "$message$>.plusAssign(values: " "Iterable<E>) {\n" @@ -954,7 +974,8 @@ void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( printer->Print( "@kotlin.jvm.JvmSynthetic\n" - "public operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, " + "public operator fun <E : kotlin.Any> " + "com.google.protobuf.kotlin.ExtensionList<E, " "$message$>.set(index: Int, value: " "E) {\n" " _builder.setExtension(this.extension, index, value)\n" diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_lite.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_lite.h index adb0df7cc7..c0afbc99ec 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_lite.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_message_lite.h @@ -37,6 +37,7 @@ #include <map> #include <string> + #include <google/protobuf/compiler/java/java_field.h> #include <google/protobuf/compiler/java/java_message.h> @@ -48,7 +49,7 @@ namespace java { class ImmutableMessageLiteGenerator : public MessageGenerator { public: ImmutableMessageLiteGenerator(const Descriptor* descriptor, Context* context); - virtual ~ImmutableMessageLiteGenerator(); + ~ImmutableMessageLiteGenerator() override; void Generate(io::Printer* printer) override; void GenerateInterface(io::Printer* printer) override; @@ -70,6 +71,7 @@ class ImmutableMessageLiteGenerator : public MessageGenerator { void GenerateConstructor(io::Printer* printer); void GenerateDynamicMethodNewBuildMessageInfo(io::Printer* printer); void GenerateKotlinExtensions(io::Printer* printer) const; + void GenerateKotlinOrNull(io::Printer* printer) const; Context* context_; ClassNameResolver* name_resolver_; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_name_resolver.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_name_resolver.cc index 595ead4955..a257409ab7 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_name_resolver.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_name_resolver.cc @@ -33,10 +33,10 @@ #include <map> #include <string> -#include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/compiler/java/java_names.h> #include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_names.h> namespace google { namespace protobuf { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_name_resolver.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_name_resolver.h index 180f3de630..46f699c6aa 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_name_resolver.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_name_resolver.h @@ -123,7 +123,6 @@ class ClassNameResolver { TProtoStringType GetDowngradedFileClassName(const FileDescriptor* file); TProtoStringType GetDowngradedClassName(const Descriptor* descriptor); - private: // Get the full name of a Java class by prepending the Java package name // or outer class name. TProtoStringType GetClassFullName(const TProtoStringType& name_without_package, @@ -132,6 +131,8 @@ class ClassNameResolver { TProtoStringType GetClassFullName(const TProtoStringType& name_without_package, const FileDescriptor* file, bool immutable, bool is_own_file, bool kotlin); + + private: // Get the Java Class style full name of a message. TProtoStringType GetJavaClassFullName(const TProtoStringType& name_without_package, const FileDescriptor* file, bool immutable); diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field.cc index 8b3d234469..abe88b67e0 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -40,13 +40,13 @@ #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/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field.h index f04fd0f7b5..8883b83d66 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field.h @@ -37,6 +37,7 @@ #include <map> #include <string> + #include <google/protobuf/compiler/java/java_field.h> namespace google { @@ -101,7 +102,7 @@ class ImmutablePrimitiveOneofFieldGenerator ImmutablePrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutablePrimitiveOneofFieldGenerator(); + ~ImmutablePrimitiveOneofFieldGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field_lite.cc index 6ab207e7af..20ba2a4051 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field_lite.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field_lite.cc @@ -40,13 +40,13 @@ #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/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { @@ -161,7 +161,6 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); } else { (*variables)["set_has_field_bit_message"] = ""; - (*variables)["set_has_field_bit_message"] = ""; (*variables)["clear_has_field_bit_message"] = ""; switch (descriptor->type()) { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field_lite.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field_lite.h index 445012e0e3..a7f03e2acc 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field_lite.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_primitive_field_lite.h @@ -93,7 +93,7 @@ class ImmutablePrimitiveOneofFieldLiteGenerator ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor, int messageBitIndex, Context* context); - ~ImmutablePrimitiveOneofFieldLiteGenerator(); + ~ImmutablePrimitiveOneofFieldLiteGenerator() override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_service.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_service.cc index 05748f5847..59e11deb77 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_service.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_service.cc @@ -34,12 +34,12 @@ #include <google/protobuf/compiler/java/java_service.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_service.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_service.h index 58d2c8d750..a03a3de561 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_service.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_service.h @@ -78,7 +78,7 @@ class ImmutableServiceGenerator : public ServiceGenerator { public: ImmutableServiceGenerator(const ServiceDescriptor* descriptor, Context* context); - virtual ~ImmutableServiceGenerator(); + ~ImmutableServiceGenerator() override; void Generate(io::Printer* printer) override; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_shared_code_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_shared_code_generator.cc index a0d5e2b45f..7d7e95dfba 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_shared_code_generator.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_shared_code_generator.cc @@ -34,15 +34,15 @@ #include <memory> -#include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/compiler/java/java_names.h> #include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_name_resolver.h> +#include <google/protobuf/compiler/java/java_names.h> +#include <google/protobuf/descriptor.pb.h> namespace google { namespace protobuf { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_string_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_string_field.cc index 0c9ba04e56..5628441a74 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_string_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_string_field.cc @@ -41,13 +41,13 @@ #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/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { @@ -992,7 +992,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateKotlinDslMembers( // List<String> += String WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, /* builder */ false); - printer->Print(variables_, + printer->Print(variables_, "@kotlin.jvm.JvmSynthetic\n" "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n" "@Suppress(\"NOTHING_TO_INLINE\")\n" diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_string_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_string_field.h index 02f0734aea..f282163b55 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_string_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_string_field.h @@ -38,6 +38,7 @@ #include <map> #include <string> + #include <google/protobuf/compiler/java/java_field.h> namespace google { @@ -61,7 +62,7 @@ class ImmutableStringFieldGenerator : public ImmutableFieldGenerator { explicit ImmutableStringFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableStringFieldGenerator(); + ~ImmutableStringFieldGenerator() override; // implements ImmutableFieldGenerator // --------------------------------------- @@ -101,7 +102,7 @@ class ImmutableStringOneofFieldGenerator ImmutableStringOneofFieldGenerator(const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, Context* context); - ~ImmutableStringOneofFieldGenerator(); + ~ImmutableStringOneofFieldGenerator() override; private: void GenerateMembers(io::Printer* printer) const override; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_string_field_lite.cc b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_string_field_lite.cc index 3150c766ce..d2cfad0dcd 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/java/java_string_field_lite.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/java/java_string_field_lite.cc @@ -41,13 +41,13 @@ #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/stubs/strutil.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_doc_comment.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/js/js_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/js/js_generator.cc index 019ef3a5b5..8c9fadf067 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/js/js_generator.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/js/js_generator.cc @@ -3625,16 +3625,19 @@ void Generator::GenerateFile(const GeneratorOptions& options, if (options.import_style == GeneratorOptions::kImportCommonJsStrict) { printer->Print("var proto = {};\n\n"); } else { - // To get the global object we call a function with .call(null), this will set "this" inside the - // function to the global object. - // This does not work if we are running in strict mode ("use strict"), - // so we fallback to the following things (in order from first to last): + // To get the global object we call a function with .call(null), this will + // set "this" inside the function to the global object. This does not work + // if we are running in strict mode ("use strict"), so we fallback to the + // following things (in order from first to last): // - window: defined in browsers // - global: defined in most server side environments like NodeJS // - self: defined inside Web Workers (WorkerGlobalScope) - // - Function('return this')(): this will work on most platforms, but it may be blocked by things like CSP. + // - Function('return this')(): this will work on most platforms, but it + // may be blocked by things like CSP. // Function('') is almost the same as eval('') - printer->Print("var global = (function() { return this || window || global || self || Function('return this')(); }).call(null);\n\n"); + printer->Print( + "var global = (function() { return this || window || global || self " + "|| Function('return this')(); }).call(null);\n\n"); } for (int i = 0; i < file->dependency_count(); i++) { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/main.cc b/contrib/libs/protoc/src/google/protobuf/compiler/main.cc index 10de997f0c..ce6b49d84e 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/main.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/main.cc @@ -35,11 +35,13 @@ #include <google/protobuf/compiler/command_line_interface.h> #include <google/protobuf/compiler/perlxs/perlxs_generator.h> #include <google/protobuf/compiler/python/python_generator.h> +#include <google/protobuf/compiler/python/python_pyi_generator.h> #include <google/protobuf/compiler/csharp/csharp_generator.h> #include <google/protobuf/compiler/objectivec/objectivec_generator.h> #include <google/protobuf/compiler/php/php_generator.h> #include <google/protobuf/compiler/ruby/ruby_generator.h> +// Must be included last. #include <google/protobuf/port_def.inc> namespace google { @@ -76,6 +78,10 @@ int ProtobufMain(int argc, char* argv[]) { python::Generator py_generator; cli.RegisterGenerator("--python_out", "--python_opt", &py_generator, "Generate Python source file."); + // Python pyi + python::PyiGenerator pyi_generator; + cli.RegisterGenerator("--pyi_out", &pyi_generator, + "Generate python pyi stub."); // PHP php::Generator php_generator; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc index 474b70a8ad..9f87d2c71e 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc @@ -65,9 +65,8 @@ void SetEnumVariables(const FieldDescriptor* descriptor, } } // namespace -EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : SingleFieldGenerator(descriptor, options) { +EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { SetEnumVariables(descriptor, &variables_); } @@ -116,12 +115,16 @@ void EnumFieldGenerator::GenerateCFunctionImplementations( } void EnumFieldGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const { - SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls); - // If it is an enum defined in a different file, then we'll need a forward - // declaration for it. When it is in our file, all the enums are output - // before the message, so it will be declared before it is needed. - if (descriptor_->file() != descriptor_->enum_type()->file()) { + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const { + SingleFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); + // If it is an enum defined in a different file (and not a WKT), then we'll + // need a forward declaration for it. When it is in our file, all the enums + // are output before the message, so it will be declared before it is needed. + if (include_external_types && + descriptor_->file() != descriptor_->enum_type()->file() && + !IsProtobufLibraryBundledProtoFile(descriptor_->enum_type()->file())) { // Enum name is already in "storage_type". const TProtoStringType& name = variable("storage_type"); fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")"); @@ -129,8 +132,8 @@ void EnumFieldGenerator::DetermineForwardDeclarations( } RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetEnumVariables(descriptor, &variables_); variables_["array_storage_type"] = "GPBEnumArray"; } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h index 89d3e6907c..8c27a3702f 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h @@ -41,8 +41,7 @@ namespace compiler { namespace objectivec { class EnumFieldGenerator : public SingleFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); EnumFieldGenerator(const EnumFieldGenerator&) = delete; EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete; @@ -53,23 +52,22 @@ class EnumFieldGenerator : public SingleFieldGenerator { virtual void GenerateCFunctionImplementations( io::Printer* printer) const override; virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const override; + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const override; protected: - EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); + EnumFieldGenerator(const FieldDescriptor* descriptor); virtual ~EnumFieldGenerator(); }; class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); public: virtual void FinishInitialization() override; protected: - RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedEnumFieldGenerator(); }; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.cc index 0e1bb33070..cd0ad8a016 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.cc @@ -118,40 +118,39 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, } // namespace -FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options) { +FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) { FieldGenerator* result = NULL; if (field->is_repeated()) { switch (GetObjectiveCType(field)) { case OBJECTIVECTYPE_MESSAGE: { if (field->is_map()) { - result = new MapFieldGenerator(field, options); + result = new MapFieldGenerator(field); } else { - result = new RepeatedMessageFieldGenerator(field, options); + result = new RepeatedMessageFieldGenerator(field); } break; } case OBJECTIVECTYPE_ENUM: - result = new RepeatedEnumFieldGenerator(field, options); + result = new RepeatedEnumFieldGenerator(field); break; default: - result = new RepeatedPrimitiveFieldGenerator(field, options); + result = new RepeatedPrimitiveFieldGenerator(field); break; } } else { switch (GetObjectiveCType(field)) { case OBJECTIVECTYPE_MESSAGE: { - result = new MessageFieldGenerator(field, options); + result = new MessageFieldGenerator(field); break; } case OBJECTIVECTYPE_ENUM: - result = new EnumFieldGenerator(field, options); + result = new EnumFieldGenerator(field); break; default: if (IsReferenceType(field)) { - result = new PrimitiveObjFieldGenerator(field, options); + result = new PrimitiveObjFieldGenerator(field); } else { - result = new PrimitiveFieldGenerator(field, options); + result = new PrimitiveFieldGenerator(field); } break; } @@ -160,8 +159,7 @@ FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, return result; } -FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor, - const Options& options) +FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor) : descriptor_(descriptor) { SetCommonFieldVariables(descriptor, &variables_); } @@ -185,7 +183,8 @@ void FieldGenerator::GenerateCFunctionImplementations( } void FieldGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const { + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const { // Nothing } @@ -266,9 +265,8 @@ void FieldGenerator::FinishInitialization(void) { } } -SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : FieldGenerator(descriptor, options) { +SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor) + : FieldGenerator(descriptor) { // Nothing } @@ -310,9 +308,8 @@ bool SingleFieldGenerator::RuntimeUsesHasBit(void) const { return true; } -ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : SingleFieldGenerator(descriptor, options) { +ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { variables_["property_storage_attribute"] = "strong"; if (IsRetainedName(variables_["name"])) { variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; @@ -353,8 +350,8 @@ void ObjCObjFieldGenerator::GeneratePropertyDeclaration( } RepeatedFieldGenerator::RepeatedFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { // Default to no comment and let the cases needing it fill it in. variables_["array_comment"] = ""; } @@ -407,19 +404,18 @@ bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const { return false; // The array (or map/dict) having anything is what is used. } -FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, - const Options& options) +FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) : descriptor_(descriptor), field_generators_(descriptor->field_count()), extension_generators_(descriptor->extension_count()) { // Construct all the FieldGenerators. for (int i = 0; i < descriptor->field_count(); i++) { field_generators_[i].reset( - FieldGenerator::Make(descriptor->field(i), options)); + FieldGenerator::Make(descriptor->field(i))); } for (int i = 0; i < descriptor->extension_count(); i++) { extension_generators_[i].reset( - FieldGenerator::Make(descriptor->extension(i), options)); + FieldGenerator::Make(descriptor->extension(i))); } } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.h index b2d2e676b1..bc1fb11b8a 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.h @@ -33,7 +33,6 @@ #include <map> #include <string> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/io/printer.h> @@ -44,8 +43,7 @@ namespace objectivec { class FieldGenerator { public: - static FieldGenerator* Make(const FieldDescriptor* field, - const Options& options); + static FieldGenerator* Make(const FieldDescriptor* field); virtual ~FieldGenerator(); @@ -66,7 +64,8 @@ class FieldGenerator { // Exposed for subclasses, should always call it on the parent class also. virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const; + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const; virtual void DetermineObjectiveCClassDefinitions( std::set<TProtoStringType>* fwd_decls) const; @@ -96,7 +95,7 @@ class FieldGenerator { TProtoStringType raw_field_name() const { return variable("raw_field_name"); } protected: - FieldGenerator(const FieldDescriptor* descriptor, const Options& options); + FieldGenerator(const FieldDescriptor* descriptor); virtual void FinishInitialization(void); bool WantsHasProperty(void) const; @@ -120,8 +119,7 @@ class SingleFieldGenerator : public FieldGenerator { virtual bool RuntimeUsesHasBit(void) const override; protected: - SingleFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + SingleFieldGenerator(const FieldDescriptor* descriptor); }; // Subclass with common support for when the field ends up as an ObjC Object. @@ -136,8 +134,7 @@ class ObjCObjFieldGenerator : public SingleFieldGenerator { virtual void GeneratePropertyDeclaration(io::Printer* printer) const override; protected: - ObjCObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + ObjCObjFieldGenerator(const FieldDescriptor* descriptor); }; class RepeatedFieldGenerator : public ObjCObjFieldGenerator { @@ -155,15 +152,14 @@ class RepeatedFieldGenerator : public ObjCObjFieldGenerator { virtual bool RuntimeUsesHasBit(void) const override; protected: - RepeatedFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedFieldGenerator(const FieldDescriptor* descriptor); virtual void FinishInitialization(void) override; }; // Convenience class which constructs FieldGenerators for a Descriptor. class FieldGeneratorMap { public: - FieldGeneratorMap(const Descriptor* descriptor, const Options& options); + FieldGeneratorMap(const Descriptor* descriptor); ~FieldGeneratorMap(); FieldGeneratorMap(const FieldGeneratorMap&) = delete; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.cc index abb8bb7811..0f4828c3ac 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -31,6 +31,7 @@ #include <google/protobuf/compiler/objectivec/objectivec_file.h> #include <google/protobuf/compiler/objectivec/objectivec_enum.h> #include <google/protobuf/compiler/objectivec/objectivec_extension.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> #include <google/protobuf/compiler/objectivec/objectivec_message.h> #include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/io/printer.h> @@ -56,6 +57,10 @@ const arc_i32 GOOGLE_PROTOBUF_OBJC_VERSION = 30004; const char* kHeaderExtension = ".pbobjc.h"; +TProtoStringType BundledFileName(const FileDescriptor* file) { + return "GPB" + FilePathBasename(file) + kHeaderExtension; +} + // Checks if a message contains any enums definitions (on the message or // a nested message under it). bool MessageContainsEnums(const Descriptor* message) { @@ -185,18 +190,19 @@ bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) { } // namespace -FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) +FileGenerator::FileGenerator(const FileDescriptor* file, + const GenerationOptions& generation_options) : file_(file), + generation_options_(generation_options), root_class_name_(FileClassName(file)), - is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)), - options_(options) { + is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)) { for (int i = 0; i < file_->enum_type_count(); i++) { EnumGenerator* generator = new EnumGenerator(file_->enum_type(i)); enum_generators_.emplace_back(generator); } for (int i = 0; i < file_->message_type_count(); i++) { MessageGenerator* generator = - new MessageGenerator(root_class_name_, file_->message_type(i), options_); + new MessageGenerator(root_class_name_, file_->message_type(i)); message_generators_.emplace_back(generator); } for (int i = 0; i < file_->extension_count(); i++) { @@ -216,6 +222,10 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { headers.push_back("GPBDescriptor.h"); headers.push_back("GPBMessage.h"); headers.push_back("GPBRootObject.h"); + for (int i = 0; i < file_->dependency_count(); i++) { + const TProtoStringType header_name = BundledFileName(file_->dependency(i)); + headers.push_back(header_name); + } } else { headers.push_back("GPBProtocolBuffers.h"); } @@ -237,16 +247,26 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { "\n", "google_protobuf_objc_version", StrCat(GOOGLE_PROTOBUF_OBJC_VERSION)); - // #import any headers for "public imports" in the proto file. + // The bundled protos (WKTs) don't use of forward declarations. + bool headers_use_forward_declarations = + generation_options_.headers_use_forward_declarations && !is_bundled_proto_; + { ImportWriter import_writer( - options_.generate_for_named_framework, - options_.named_framework_to_proto_path_mappings_path, - options_.runtime_import_prefix, - is_bundled_proto_); + generation_options_.generate_for_named_framework, + generation_options_.named_framework_to_proto_path_mappings_path, + generation_options_.runtime_import_prefix, + /* include_wkt_imports = */ false); const TProtoStringType header_extension(kHeaderExtension); - for (int i = 0; i < file_->public_dependency_count(); i++) { - import_writer.AddFile(file_->public_dependency(i), header_extension); + if (headers_use_forward_declarations) { + // #import any headers for "public imports" in the proto file. + for (int i = 0; i < file_->public_dependency_count(); i++) { + import_writer.AddFile(file_->public_dependency(i), header_extension); + } + } else { + for (int i = 0; i < file_->dependency_count(); i++) { + import_writer.AddFile(file_->dependency(i), header_extension); + } } import_writer.Print(printer); } @@ -266,7 +286,9 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { std::set<TProtoStringType> fwd_decls; for (const auto& generator : message_generators_) { - generator->DetermineForwardDeclarations(&fwd_decls); + generator->DetermineForwardDeclarations( + &fwd_decls, + /* include_external_types = */ headers_use_forward_declarations); } for (std::set<TProtoStringType>::const_iterator i(fwd_decls.begin()); i != fwd_decls.end(); ++i) { @@ -340,6 +362,9 @@ void FileGenerator::GenerateSource(io::Printer* printer) { // #import the runtime support. std::vector<TProtoStringType> headers; headers.push_back("GPBProtocolBuffers_RuntimeSupport.h"); + if (is_bundled_proto_) { + headers.push_back(BundledFileName(file_)); + } PrintFileRuntimePreamble(printer, headers); // Enums use atomic in the generated code, so add the system import as needed. @@ -352,28 +377,34 @@ void FileGenerator::GenerateSource(io::Printer* printer) { std::vector<const FileDescriptor*> deps_with_extensions; CollectMinimalFileDepsContainingExtensions(file_, &deps_with_extensions); + // The bundled protos (WKTs) don't use of forward declarations. + bool headers_use_forward_declarations = + generation_options_.headers_use_forward_declarations && !is_bundled_proto_; + { ImportWriter import_writer( - options_.generate_for_named_framework, - options_.named_framework_to_proto_path_mappings_path, - options_.runtime_import_prefix, - is_bundled_proto_); + generation_options_.generate_for_named_framework, + generation_options_.named_framework_to_proto_path_mappings_path, + generation_options_.runtime_import_prefix, + /* include_wkt_imports = */ false); const TProtoStringType header_extension(kHeaderExtension); // #import the header for this proto file. import_writer.AddFile(file_, header_extension); - // #import the headers for anything that a plain dependency of this proto - // file (that means they were just an include, not a "public" include). - std::set<TProtoStringType> public_import_names; - for (int i = 0; i < file_->public_dependency_count(); i++) { - public_import_names.insert(file_->public_dependency(i)->name()); - } - for (int i = 0; i < file_->dependency_count(); i++) { - const FileDescriptor *dep = file_->dependency(i); - bool public_import = (public_import_names.count(dep->name()) != 0); - if (!public_import) { - import_writer.AddFile(dep, header_extension); + if (headers_use_forward_declarations) { + // #import the headers for anything that a plain dependency of this proto + // file (that means they were just an include, not a "public" include). + std::set<TProtoStringType> public_import_names; + for (int i = 0; i < file_->public_dependency_count(); i++) { + public_import_names.insert(file_->public_dependency(i)->name()); + } + for (int i = 0; i < file_->dependency_count(); i++) { + const FileDescriptor *dep = file_->dependency(i); + bool public_import = (public_import_names.count(dep->name()) != 0); + if (!public_import) { + import_writer.AddFile(dep, header_extension); + } } } @@ -599,8 +630,26 @@ void FileGenerator::PrintFileRuntimePreamble( "// source: $filename$\n" "\n", "filename", file_->name()); - ImportWriter::PrintRuntimeImports( - printer, headers_to_import, options_.runtime_import_prefix, true); + + if (is_bundled_proto_) { + // This is basically a clone of ImportWriter::PrintRuntimeImports() but + // without the CPP symbol gate, since within the bundled files, that isn't + // needed. + TProtoStringType import_prefix = generation_options_.runtime_import_prefix; + if (!import_prefix.empty()) { + import_prefix += "/"; + } + for (const auto& header : headers_to_import) { + printer->Print( + "#import \"$import_prefix$$header$\"\n", + "import_prefix", import_prefix, + "header", header); + } + } else { + ImportWriter::PrintRuntimeImports( + printer, headers_to_import, generation_options_.runtime_import_prefix, true); + } + printer->Print("\n"); } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.h index 6bd747ac5e..6d2c970f81 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.h @@ -34,7 +34,6 @@ #include <string> #include <set> #include <vector> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/io/printer.h> @@ -49,7 +48,19 @@ class MessageGenerator; class FileGenerator { public: - FileGenerator(const FileDescriptor* file, const Options& options); + struct GenerationOptions { + GenerationOptions() + // TODO(thomasvl): Eventually flip this default to false for better + // interop with Swift if proto usages span modules made from ObjC sources. + : headers_use_forward_declarations(true) {} + TProtoStringType generate_for_named_framework; + TProtoStringType named_framework_to_proto_path_mappings_path; + TProtoStringType runtime_import_prefix; + bool headers_use_forward_declarations; + }; + + FileGenerator(const FileDescriptor* file, + const GenerationOptions& generation_options); ~FileGenerator(); FileGenerator(const FileGenerator&) = delete; @@ -60,6 +71,7 @@ class FileGenerator { private: const FileDescriptor* file_; + const GenerationOptions& generation_options_; TProtoStringType root_class_name_; bool is_bundled_proto_; @@ -67,8 +79,6 @@ class FileGenerator { std::vector<std::unique_ptr<MessageGenerator>> message_generators_; std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_; - const Options options_; - void PrintFileRuntimePreamble( io::Printer* printer, const std::vector<TProtoStringType>& headers_to_import) const; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.cc index 160af71080..552d7e7273 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.cc @@ -94,7 +94,8 @@ bool ObjectiveCGenerator::GenerateAll( // // e.g. protoc ... --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework - Options generation_options; + Options validation_options; + FileGenerator::GenerationOptions generation_options; std::vector<std::pair<TProtoStringType, TProtoStringType> > options; ParseGeneratorParameter(parameter, &options); @@ -110,17 +111,20 @@ bool ObjectiveCGenerator::GenerateAll( // - Comments start with "#". // - A comment can go on a line after a expected package/prefix pair. // (i.e. - "package=prefix # comment") + // - For files that do NOT have a proto package (not recommended), an + // entry can be made as "no_package:PATH=prefix", where PATH is the + // path for the .proto file. // // There is no validation that the prefixes are good prefixes, it is // assumed that they are when you create the file. - generation_options.expected_prefixes_path = options[i].second; + validation_options.expected_prefixes_path = options[i].second; } else if (options[i].first == "expected_prefixes_suppressions") { // A semicolon delimited string that lists the paths of .proto files to // exclude from the package prefix validations (expected_prefixes_path). // This is provided as an "out", to skip some files being checked. for (StringPiece split_piece : Split( options[i].second, ";", true)) { - generation_options.expected_prefixes_suppressions.push_back( + validation_options.expected_prefixes_suppressions.push_back( TProtoStringType(split_piece)); } } else if (options[i].first == "prefixes_must_be_registered") { @@ -132,7 +136,7 @@ bool ObjectiveCGenerator::GenerateAll( // tried to use a prefix that isn't registered. // Default is "no". if (!StringToBool(options[i].second, - &generation_options.prefixes_must_be_registered)) { + &validation_options.prefixes_must_be_registered)) { *error = "error: Unknown value for prefixes_must_be_registered: " + options[i].second; return false; } @@ -144,7 +148,7 @@ bool ObjectiveCGenerator::GenerateAll( // raised if a files doesn't have one. // Default is "no". if (!StringToBool(options[i].second, - &generation_options.require_prefixes)) { + &validation_options.require_prefixes)) { *error = "error: Unknown value for require_prefixes: " + options[i].second; return false; } @@ -185,8 +189,22 @@ bool ObjectiveCGenerator::GenerateAll( // generated files. When integrating ObjC protos into a build system, // this can be used to avoid having to add the runtime directory to the // header search path since the generate #import will be more complete. - generation_options.runtime_import_prefix = - StripSuffixString(options[i].second, "/"); + generation_options.runtime_import_prefix = StripSuffixString(options[i].second, "/"); + } else if (options[i].first == "package_to_prefix_mappings_path") { + // Path to use for when loading the objc class prefix mappings to use. + // The `objc_class_prefix` file option is always honored first if one is present. + // This option also has precedent over the use_package_as_prefix option. + // + // The format of the file is: + // - An entry is a line of "package=prefix". + // - Comments start with "#". + // - A comment can go on a line after a expected package/prefix pair. + // (i.e. - "package=prefix # comment") + // - For files that do NOT have a proto package (not recommended), an + // entry can be made as "no_package:PATH=prefix", where PATH is the + // path for the .proto file. + // + SetPackageToPrefixMappingsPath(options[i].second); } else if (options[i].first == "use_package_as_prefix") { // Controls how the symbols should be prefixed to avoid symbols // collisions. The objc_class_prefix file option is always honored, this @@ -212,6 +230,12 @@ bool ObjectiveCGenerator::GenerateAll( // - A comment can go on a line after a expected package/prefix pair. // (i.e. - "some.proto.package # comment") SetProtoPackagePrefixExceptionList(options[i].second); + } else if (options[i].first == "headers_use_forward_declarations") { + if (!StringToBool(options[i].second, + &generation_options.headers_use_forward_declarations)) { + *error = "error: Unknown value for headers_use_forward_declarations: " + options[i].second; + return false; + } } else { *error = "error: Unknown generator option: " + options[i].first; return false; @@ -240,7 +264,7 @@ bool ObjectiveCGenerator::GenerateAll( // ----------------------------------------------------------------- // Validate the objc prefix/package pairings. - if (!ValidateObjCClassPrefixes(files, generation_options, error)) { + if (!ValidateObjCClassPrefixes(files, validation_options, error)) { // *error will have been filled in. return false; } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index cbe70bac36..5122fa46c0 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -74,6 +74,14 @@ using ::open; namespace { +bool BoolFromEnvVar(const char* env_var, bool default_value) { + const char* value = getenv(env_var); + if (value) { + return TProtoStringType("YES") == ToUpper(value); + } + return default_value; +} + class SimpleLineCollector : public LineConsumer { public: SimpleLineCollector(std::unordered_set<TProtoStringType>* inout_set) @@ -88,10 +96,31 @@ class SimpleLineCollector : public LineConsumer { std::unordered_set<TProtoStringType>* set_; }; +class PackageToPrefixesCollector : public LineConsumer { + public: + PackageToPrefixesCollector(const TProtoStringType &usage, + std::map<TProtoStringType, TProtoStringType>* inout_package_to_prefix_map) + : usage_(usage), prefix_map_(inout_package_to_prefix_map) {} + + virtual bool ConsumeLine(const StringPiece& line, TProtoStringType* out_error) override; + + private: + const TProtoStringType usage_; + std::map<TProtoStringType, TProtoStringType>* prefix_map_; +}; + class PrefixModeStorage { public: PrefixModeStorage(); + const TProtoStringType package_to_prefix_mappings_path() const { return package_to_prefix_mappings_path_; } + void set_package_to_prefix_mappings_path(const TProtoStringType& path) { + package_to_prefix_mappings_path_ = path; + package_to_prefix_map_.clear(); + } + + TProtoStringType prefix_from_proto_package_mappings(const FileDescriptor* file); + bool use_package_name() const { return use_package_name_; } void set_use_package_name(bool on_or_off) { use_package_name_ = on_or_off; } @@ -103,9 +132,16 @@ class PrefixModeStorage { bool is_package_exempted(const TProtoStringType& package); + // When using a proto package as the prefix, this should be added as the + // prefix in front of it. + const TProtoStringType& forced_package_prefix() const { return forced_prefix_; } + private: bool use_package_name_; + std::map<TProtoStringType, TProtoStringType> package_to_prefix_map_; + TProtoStringType package_to_prefix_mappings_path_; TProtoStringType exception_path_; + TProtoStringType forced_prefix_; std::unordered_set<TProtoStringType> exceptions_; }; @@ -113,14 +149,57 @@ PrefixModeStorage::PrefixModeStorage() { // Even thought there are generation options, have an env back door since some // of these helpers could be used in other plugins. - const char* use_package_cstr = getenv("GPB_OBJC_USE_PACKAGE_AS_PREFIX"); - use_package_name_ = - (use_package_cstr && (TProtoStringType("YES") == ToUpper(use_package_cstr))); + use_package_name_ = BoolFromEnvVar("GPB_OBJC_USE_PACKAGE_AS_PREFIX", false); const char* exception_path = getenv("GPB_OBJC_PACKAGE_PREFIX_EXCEPTIONS_PATH"); if (exception_path) { exception_path_ = exception_path; } + + // This one is a not expected to be common, so it doesn't get a generation + // option, just the env var. + const char* prefix = getenv("GPB_OBJC_USE_PACKAGE_AS_PREFIX_PREFIX"); + if (prefix) { + forced_prefix_ = prefix; + } +} + +TProtoStringType PrefixModeStorage::prefix_from_proto_package_mappings(const FileDescriptor* file) { + if (!file) { + return ""; + } + + if (package_to_prefix_map_.empty() && !package_to_prefix_mappings_path_.empty()) { + TProtoStringType error_str; + // Re use the same collector as we use for expected_prefixes_path since the file + // format is the same. + PackageToPrefixesCollector collector("Package to prefixes", &package_to_prefix_map_); + if (!ParseSimpleFile(package_to_prefix_mappings_path_, &collector, &error_str)) { + if (error_str.empty()) { + error_str = TProtoStringType("protoc:0: warning: Failed to parse") + + TProtoStringType(" prefix to proto package mappings file: ") + + package_to_prefix_mappings_path_; + } + std::cerr << error_str << std::endl; + std::cerr.flush(); + package_to_prefix_map_.clear(); + } + } + + const TProtoStringType package = file->package(); + // For files without packages, the can be registered as "no_package:PATH", + // allowing the expected prefixes file. + static const TProtoStringType no_package_prefix("no_package:"); + const TProtoStringType lookup_key = package.empty() ? no_package_prefix + file->name() : package; + + std::map<TProtoStringType, TProtoStringType>::const_iterator prefix_lookup = + package_to_prefix_map_.find(lookup_key); + + if (prefix_lookup != package_to_prefix_map_.end()) { + return prefix_lookup->second; + } + + return ""; } bool PrefixModeStorage::is_package_exempted(const TProtoStringType& package) { @@ -152,6 +231,14 @@ PrefixModeStorage g_prefix_mode; } // namespace +TProtoStringType GetPackageToPrefixMappingsPath() { + return g_prefix_mode.package_to_prefix_mappings_path(); +} + +void SetPackageToPrefixMappingsPath(const TProtoStringType& file_path) { + g_prefix_mode.set_package_to_prefix_mappings_path(file_path); +} + bool UseProtoPackageAsDefaultPrefix() { return g_prefix_mode.use_package_name(); } @@ -169,7 +256,9 @@ void SetProtoPackagePrefixExceptionList(const TProtoStringType& file_path) { } Options::Options() { - // Default is the value of the env for the package prefixes. + // While there are generator options, also support env variables to help with + // build systems where it isn't as easy to hook in for add the generation + // options when invoking protoc. const char* file_path = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES"); if (file_path) { expected_prefixes_path = file_path; @@ -179,8 +268,9 @@ Options::Options() { expected_prefixes_suppressions = Split(suppressions, ";", true); } - prefixes_must_be_registered = false; - require_prefixes = false; + prefixes_must_be_registered = + BoolFromEnvVar("GPB_OBJC_PREFIXES_MUST_BE_REGISTERED", false); + require_prefixes = BoolFromEnvVar("GPB_OBJC_REQUIRE_PREFIXES", false); } namespace { @@ -353,9 +443,9 @@ bool IsReservedCIdentifier(const TProtoStringType& input) { } TProtoStringType SanitizeNameForObjC(const TProtoStringType& prefix, - const TProtoStringType& input, - const TProtoStringType& extension, - TProtoStringType* out_suffix_added) { + const TProtoStringType& input, + const TProtoStringType& extension, + TProtoStringType* out_suffix_added) { static const std::unordered_set<TProtoStringType> kReservedWords = MakeWordsMap(kReservedWordList, GOOGLE_ARRAYSIZE(kReservedWordList)); static const std::unordered_set<TProtoStringType> kNSObjectMethods = @@ -511,8 +601,14 @@ TProtoStringType FileClassPrefix(const FileDescriptor* file) { return file->options().objc_class_prefix(); } - // If package prefix isn't enabled or no package, done. - if (!g_prefix_mode.use_package_name() || file->package().empty()) { + // If package prefix is specified in an prefix to proto mappings file then use that. + TProtoStringType objc_class_prefix = g_prefix_mode.prefix_from_proto_package_mappings(file); + if (!objc_class_prefix.empty()) { + return objc_class_prefix; + } + + // If package prefix isn't enabled, done. + if (!g_prefix_mode.use_package_name()) { return ""; } @@ -539,7 +635,7 @@ TProtoStringType FileClassPrefix(const FileDescriptor* file) { if (!result.empty()) { result.append("_"); } - return result; + return g_prefix_mode.forced_package_prefix() + result; } TProtoStringType FilePath(const FileDescriptor* file) { @@ -1185,23 +1281,11 @@ void RemoveComment(StringPiece* input) { namespace { -class ExpectedPrefixesCollector : public LineConsumer { - public: - ExpectedPrefixesCollector(std::map<TProtoStringType, TProtoStringType>* inout_package_to_prefix_map) - : prefix_map_(inout_package_to_prefix_map) {} - - virtual bool ConsumeLine(const StringPiece& line, TProtoStringType* out_error) override; - - private: - std::map<TProtoStringType, TProtoStringType>* prefix_map_; -}; - -bool ExpectedPrefixesCollector::ConsumeLine( +bool PackageToPrefixesCollector::ConsumeLine( const StringPiece& line, TProtoStringType* out_error) { int offset = line.find('='); if (offset == StringPiece::npos) { - *out_error = TProtoStringType("Expected prefixes file line without equal sign: '") + - TProtoStringType(line) + "'."; + *out_error = usage_ + " file line without equal sign: '" + StrCat(line) + "'."; return false; } StringPiece package = line.substr(0, offset); @@ -1215,16 +1299,16 @@ bool ExpectedPrefixesCollector::ConsumeLine( return true; } -bool LoadExpectedPackagePrefixes(const Options& generation_options, +bool LoadExpectedPackagePrefixes(const TProtoStringType& expected_prefixes_path, std::map<TProtoStringType, TProtoStringType>* prefix_map, TProtoStringType* out_error) { - if (generation_options.expected_prefixes_path.empty()) { + if (expected_prefixes_path.empty()) { return true; } - ExpectedPrefixesCollector collector(prefix_map); + PackageToPrefixesCollector collector("Expected prefixes", prefix_map); return ParseSimpleFile( - generation_options.expected_prefixes_path, &collector, out_error); + expected_prefixes_path, &collector, out_error); } bool ValidateObjCClassPrefix( @@ -1241,6 +1325,11 @@ bool ValidateObjCClassPrefix( const TProtoStringType prefix = file->options().objc_class_prefix(); const TProtoStringType package = file->package(); + // For files without packages, the can be registered as "no_package:PATH", + // allowing the expected prefixes file. + static const TProtoStringType no_package_prefix("no_package:"); + const TProtoStringType lookup_key = + package.empty() ? no_package_prefix + file->name() : package; // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some // error cases, so it seems to be ok to use as a back door for warnings. @@ -1248,7 +1337,7 @@ bool ValidateObjCClassPrefix( // Check: Error - See if there was an expected prefix for the package and // report if it doesn't match (wrong or missing). std::map<TProtoStringType, TProtoStringType>::const_iterator package_match = - expected_package_prefixes.find(package); + expected_package_prefixes.find(lookup_key); if (package_match != expected_package_prefixes.end()) { // There was an entry, and... if (has_prefix && package_match->second == prefix) { @@ -1257,8 +1346,11 @@ bool ValidateObjCClassPrefix( } else { // ...it didn't match! *out_error = "error: Expected 'option objc_class_prefix = \"" + - package_match->second + "\";' for package '" + package + - "' in '" + file->name() + "'"; + package_match->second + "\";'"; + if (!package.empty()) { + *out_error += " for package '" + package + "'"; + } + *out_error += " in '" + file->name() + "'"; if (has_prefix) { *out_error += "; but found '" + prefix + "' instead"; } @@ -1287,35 +1379,12 @@ bool ValidateObjCClassPrefix( i != expected_package_prefixes.end(); ++i) { if (i->second == prefix) { other_package_for_prefix = i->first; - break; - } - } - - // Check: Warning - If the file does not have a package, check whether the - // prefix was declared is being used by another package or not. This is - // a special case for empty packages. - if (package.empty()) { - // The file does not have a package and ... - if (other_package_for_prefix.empty()) { - // ... no other package has declared that prefix. - std::cerr - << "protoc:0: warning: File '" << file->name() << "' has no " - << "package. Consider adding a new package to the proto and adding '" - << "new.package = " << prefix << "' to the expected prefixes file (" - << expected_prefixes_path << ")." << std::endl; - std::cerr.flush(); - } else { - // ... another package has declared the same prefix. - std::cerr - << "protoc:0: warning: File '" << file->name() << "' has no package " - << "and package '" << other_package_for_prefix << "' already uses '" - << prefix << "' as its prefix. Consider either adding a new package " - << "to the proto, or reusing one of the packages already using this " - << "prefix in the expected prefixes file (" - << expected_prefixes_path << ")." << std::endl; - std::cerr.flush(); + // Stop on the first real package listing, if it was a no_package file + // specific entry, keep looking to try and find a package one. + if (!HasPrefixString(other_package_for_prefix, no_package_prefix)) { + break; + } } - return true; } // Check: Error - Make sure the prefix wasn't expected for a different @@ -1324,14 +1393,20 @@ bool ValidateObjCClassPrefix( if (!other_package_for_prefix.empty()) { *out_error = "error: Found 'option objc_class_prefix = \"" + prefix + - "\";' in '" + file->name() + - "'; that prefix is already used for 'package " + - other_package_for_prefix + ";'. It can only be reused by listing " + - "it in the expected file (" + - expected_prefixes_path + ")."; + "\";' in '" + file->name() + "'; that prefix is already used for "; + if (HasPrefixString(other_package_for_prefix, no_package_prefix)) { + *out_error += "file '" + + StripPrefixString(other_package_for_prefix, no_package_prefix) + + "'."; + } else { + *out_error += "'package " + other_package_for_prefix + ";'."; + } + *out_error += + " It can only be reused by adding '" + lookup_key + " = " + prefix + + "' to the expected prefixes file (" + expected_prefixes_path + ")."; return false; // Only report first usage of the prefix. } - } // !prefix.empty() + } // !prefix.empty() && have_expected_prefix_file // Check: Warning - Make sure the prefix is is a reasonable value according // to Apple's rules (the checks above implicitly whitelist anything that @@ -1360,17 +1435,18 @@ bool ValidateObjCClassPrefix( if (prefixes_must_be_registered) { *out_error = "error: '" + file->name() + "' has 'option objc_class_prefix = \"" + - prefix + "\";', but it is not registered; add it to the expected " + - "prefixes file (" + expected_prefixes_path + ") for the package '" + - package + "'."; + prefix + "\";', but it is not registered. Add '" + lookup_key + " = " + + (prefix.empty() ? "\"\"" : prefix) + + "' to the expected prefixes file (" + expected_prefixes_path + ")."; return false; } std::cerr << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \"" - << prefix << "\";' in '" << file->name() << "';" - << " consider adding it to the expected prefixes file (" - << expected_prefixes_path << ")." << std::endl; + << prefix << "\";' in '" << file->name() << "'; consider adding '" + << lookup_key << " = " << (prefix.empty() ? "\"\"" : prefix) + << "' to the expected prefixes file (" << expected_prefixes_path + << ")." << std::endl; std::cerr.flush(); } @@ -1380,6 +1456,13 @@ bool ValidateObjCClassPrefix( } // namespace bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files, + TProtoStringType* out_error) { + // Options's ctor load from the environment. + Options options; + return ValidateObjCClassPrefixes(files, options, out_error); +} + +bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files, const Options& generation_options, TProtoStringType* out_error) { // Allow a '-' as the path for the expected prefixes to completely disable @@ -1390,7 +1473,7 @@ bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files, // Load the expected package prefixes, if available, to validate against. std::map<TProtoStringType, TProtoStringType> expected_package_prefixes; - if (!LoadExpectedPackagePrefixes(generation_options, + if (!LoadExpectedPackagePrefixes(generation_options.expected_prefixes_path, &expected_package_prefixes, out_error)) { return false; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index 28acf4affd..afbf34b7ad 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -47,6 +47,10 @@ namespace protobuf { namespace compiler { namespace objectivec { +// Get/Set the path to a file to load for objc class prefix lookups. +TProtoStringType PROTOC_EXPORT GetPackageToPrefixMappingsPath(); +void PROTOC_EXPORT SetPackageToPrefixMappingsPath( + const TProtoStringType& file_path); // Get/Set if the proto package should be used to make the default prefix for // symbols. This will then impact most of the type naming apis below. It is done // as a global to not break any other generator reusing the methods since they @@ -54,20 +58,18 @@ namespace objectivec { bool PROTOC_EXPORT UseProtoPackageAsDefaultPrefix(); void PROTOC_EXPORT SetUseProtoPackageAsDefaultPrefix(bool on_or_off); // Get/Set the path to a file to load as exceptions when -// `UseProtoPackageAsDefaultPrefixUseProtoPackageAsDefaultPrefix()` is `true`. -// And empty string means there should be no exceptions loaded. +// `UseProtoPackageAsDefaultPrefix()` is `true`. An empty string means there +// should be no exceptions. TProtoStringType PROTOC_EXPORT GetProtoPackagePrefixExceptionList(); void PROTOC_EXPORT SetProtoPackagePrefixExceptionList( const TProtoStringType& file_path); -// Generator options (see objectivec_generator.cc for a description of each): +// Generator Prefix Validation Options (see objectivec_generator.cc for a +// description of each): struct Options { Options(); TProtoStringType expected_prefixes_path; std::vector<TProtoStringType> expected_prefixes_suppressions; - TProtoStringType generate_for_named_framework; - TProtoStringType named_framework_to_proto_path_mappings_path; - TProtoStringType runtime_import_prefix; bool prefixes_must_be_registered; bool require_prefixes; }; @@ -251,7 +253,11 @@ IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); // and the result is false. bool PROTOC_EXPORT ValidateObjCClassPrefixes( const std::vector<const FileDescriptor*>& files, - const Options& generation_options, TProtoStringType* out_error); + const Options& validation_options, TProtoStringType* out_error); +// Same was the other ValidateObjCClassPrefixes() calls, but the options all +// come from the environment variables. +bool PROTOC_EXPORT ValidateObjCClassPrefixes( + const std::vector<const FileDescriptor*>& files, TProtoStringType* out_error); // Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform // the input into the expected output. diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc index ed21b6526c..933f0ce73d 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc @@ -81,14 +81,13 @@ const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) { } // namespace -MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : RepeatedFieldGenerator(descriptor, options) { +MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { const FieldDescriptor* key_descriptor = descriptor->message_type()->map_key(); const FieldDescriptor* value_descriptor = descriptor->message_type()->map_value(); - value_field_generator_.reset(FieldGenerator::Make(value_descriptor, options)); + value_field_generator_.reset(FieldGenerator::Make(value_descriptor)); // Pull over some variables_ from the value. variables_["field_type"] = value_field_generator_->variable("field_type"); @@ -153,7 +152,7 @@ void MapFieldGenerator::FinishInitialization(void) { // Use the array_comment support in RepeatedFieldGenerator to output what the // values in the map are. const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); + descriptor_->message_type()->map_value(); if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_ENUM) { variables_["array_comment"] = "// |" + variables_["name"] + "| values are |" + value_field_generator_->variable("storage_type") + "|\n"; @@ -161,11 +160,19 @@ void MapFieldGenerator::FinishInitialization(void) { } void MapFieldGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const { - RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const { + RepeatedFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); - if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { + descriptor_->message_type()->map_value(); + // Within a file there is no requirement on the order of the messages, so + // local references need a forward declaration. External files (not WKTs), + // need one when requested. + if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE && + ((include_external_types && + !IsProtobufLibraryBundledProtoFile(value_descriptor->file())) || + descriptor_->file() == value_descriptor->file())) { const TProtoStringType& value_storage_type = value_field_generator_->variable("storage_type"); fwd_decls->insert("@class " + value_storage_type); @@ -176,7 +183,7 @@ void MapFieldGenerator::DetermineObjectiveCClassDefinitions( std::set<TProtoStringType>* fwd_decls) const { // Class name is already in "storage_type". const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); + descriptor_->message_type()->map_value(); if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { fwd_decls->insert(ObjCClassDeclaration( value_field_generator_->variable("storage_type"))); diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.h index fd2b466dcc..2ec2e43435 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.h @@ -41,8 +41,7 @@ namespace compiler { namespace objectivec { class MapFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); public: virtual void FinishInitialization(void) override; @@ -51,13 +50,14 @@ class MapFieldGenerator : public RepeatedFieldGenerator { MapFieldGenerator& operator=(const MapFieldGenerator&) = delete; protected: - MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options); + MapFieldGenerator(const FieldDescriptor* descriptor); virtual ~MapFieldGenerator(); virtual void DetermineObjectiveCClassDefinitions( std::set<TProtoStringType>* fwd_decls) const override; virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const override; + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const override; private: std::unique_ptr<FieldGenerator> value_field_generator_; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.cc index 39f8fd50fb..ab5b29628f 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.cc @@ -171,11 +171,10 @@ const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) { } // namespace MessageGenerator::MessageGenerator(const TProtoStringType& root_classname, - const Descriptor* descriptor, - const Options& options) + const Descriptor* descriptor) : root_classname_(root_classname), descriptor_(descriptor), - field_generators_(descriptor, options), + field_generators_(descriptor), class_name_(ClassName(descriptor_)), deprecated_attribute_(GetOptionalDeprecatedAttribute( descriptor, descriptor->file(), false, true)) { @@ -197,8 +196,7 @@ MessageGenerator::MessageGenerator(const TProtoStringType& root_classname, for (int i = 0; i < descriptor_->nested_type_count(); i++) { MessageGenerator* generator = new MessageGenerator(root_classname_, - descriptor_->nested_type(i), - options); + descriptor_->nested_type(i)); nested_message_generators_.emplace_back(generator); } } @@ -217,17 +215,18 @@ void MessageGenerator::GenerateStaticVariablesInitialization( } void MessageGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) { + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) { if (!IsMapEntryMessage(descriptor_)) { for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* fieldDescriptor = descriptor_->field(i); field_generators_.get(fieldDescriptor) - .DetermineForwardDeclarations(fwd_decls); + .DetermineForwardDeclarations(fwd_decls, include_external_types); } } for (const auto& generator : nested_message_generators_) { - generator->DetermineForwardDeclarations(fwd_decls); + generator->DetermineForwardDeclarations(fwd_decls, include_external_types); } } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.h index a55351b1a2..71eec0d0c7 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.h @@ -35,7 +35,6 @@ #include <set> #include <vector> #include <google/protobuf/compiler/objectivec/objectivec_field.h> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> #include <google/protobuf/compiler/objectivec/objectivec_oneof.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/io/printer.h> @@ -51,7 +50,7 @@ class EnumGenerator; class MessageGenerator { public: MessageGenerator(const TProtoStringType& root_classname, - const Descriptor* descriptor, const Options& options); + const Descriptor* descriptor); ~MessageGenerator(); MessageGenerator(const MessageGenerator&) = delete; @@ -63,7 +62,8 @@ class MessageGenerator { void GenerateSource(io::Printer* printer); void GenerateExtensionRegistrationSource(io::Printer* printer); void DetermineObjectiveCClassDefinitions(std::set<TProtoStringType>* fwd_decls); - void DetermineForwardDeclarations(std::set<TProtoStringType>* fwd_decls); + void DetermineForwardDeclarations(std::set<TProtoStringType>* fwd_decls, + bool include_external_types); // Checks if the message or a nested message includes a oneof definition. bool IncludesOneOfDefinition() const; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc index f26bbc8de5..828b75c868 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc @@ -58,19 +58,27 @@ void SetMessageVariables(const FieldDescriptor* descriptor, } // namespace -MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { +MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { SetMessageVariables(descriptor, &variables_); } MessageFieldGenerator::~MessageFieldGenerator() {} void MessageFieldGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const { - ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls); - // Class name is already in "storage_type". - fwd_decls->insert("@class " + variable("storage_type")); + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const { + ObjCObjFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); + // Within a file there is no requirement on the order of the messages, so + // local references need a forward declaration. External files (not WKTs), + // need one when requested. + if ((include_external_types && + !IsProtobufLibraryBundledProtoFile(descriptor_->message_type()->file())) || + descriptor_->file() == descriptor_->message_type()->file()) { + // Class name is already in "storage_type". + fwd_decls->insert("@class " + variable("storage_type")); + } } void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( @@ -79,8 +87,8 @@ void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( } RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetMessageVariables(descriptor, &variables_); variables_["array_storage_type"] = "NSMutableArray"; variables_["array_property_type"] = @@ -90,10 +98,19 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} void RepeatedMessageFieldGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const { - RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); - // Class name is already in "storage_type". - fwd_decls->insert("@class " + variable("storage_type")); + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const { + RepeatedFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); + // Within a file there is no requirement on the order of the messages, so + // local references need a forward declaration. External files (not WKTs), + // need one when requested. + if ((include_external_types && + !IsProtobufLibraryBundledProtoFile(descriptor_->message_type()->file())) || + descriptor_->file() == descriptor_->message_type()->file()) { + // Class name is already in "storage_type". + fwd_decls->insert("@class " + variable("storage_type")); + } } void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions( diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.h index 8897c9b7b6..44b5aabcfd 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.h @@ -41,12 +41,10 @@ namespace compiler { namespace objectivec { class MessageFieldGenerator : public ObjCObjFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + MessageFieldGenerator(const FieldDescriptor* descriptor); MessageFieldGenerator(const MessageFieldGenerator&) = delete; MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete; @@ -55,18 +53,17 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator { public: virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const override; + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const override; virtual void DetermineObjectiveCClassDefinitions( std::set<TProtoStringType>* fwd_decls) const override; }; class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedMessageFieldGenerator(); RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete; @@ -74,7 +71,8 @@ class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { public: virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const override; + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const override; virtual void DetermineObjectiveCClassDefinitions( std::set<TProtoStringType>* fwd_decls) const override; }; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc index 767068107a..c8233b1441 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc @@ -125,8 +125,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, } // namespace PrimitiveFieldGenerator::PrimitiveFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : SingleFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); } @@ -159,8 +159,8 @@ void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) { } PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); variables_["property_storage_attribute"] = "copy"; } @@ -168,8 +168,8 @@ PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator( PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {} RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); TProtoStringType base_name = PrimitiveArrayTypeName(descriptor); diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h index a9f30f6419..291d11a2e3 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h @@ -41,12 +41,10 @@ namespace compiler { namespace objectivec { class PrimitiveFieldGenerator : public SingleFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - PrimitiveFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + PrimitiveFieldGenerator(const FieldDescriptor* descriptor); virtual ~PrimitiveFieldGenerator(); PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete; @@ -59,12 +57,10 @@ class PrimitiveFieldGenerator : public SingleFieldGenerator { }; class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor); virtual ~PrimitiveObjFieldGenerator(); PrimitiveObjFieldGenerator(const PrimitiveObjFieldGenerator&) = delete; @@ -73,12 +69,10 @@ class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { }; class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedPrimitiveFieldGenerator(); RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) = diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/parser.cc b/contrib/libs/protoc/src/google/protobuf/compiler/parser.cc index 335edcf30c..332556e9c4 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/parser.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/parser.cc @@ -46,11 +46,11 @@ #include <google/protobuf/stubs/casts.h> #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/tokenizer.h> -#include <google/protobuf/descriptor.h> #include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/map_util.h> #include <google/protobuf/stubs/hash.h> @@ -180,9 +180,9 @@ bool IsNumberFollowUnderscore(const TProtoStringType& name) { // =================================================================== Parser::Parser() - : input_(NULL), - error_collector_(NULL), - source_location_table_(NULL), + : input_(nullptr), + error_collector_(nullptr), + source_location_table_(nullptr), had_errors_(false), require_syntax_identifier_(false), stop_after_syntax_identifier_(false) { @@ -221,12 +221,8 @@ bool Parser::Consume(const char* text, const char* error) { } bool Parser::Consume(const char* text) { - if (TryConsume(text)) { - return true; - } else { - AddError("Expected \"" + TProtoStringType(text) + "\"."); - return false; - } + TProtoStringType error = "Expected \"" + TProtoStringType(text) + "\"."; + return Consume(text, error.c_str()); } bool Parser::ConsumeIdentifier(TProtoStringType* output, const char* error) { @@ -347,7 +343,7 @@ bool Parser::TryConsumeEndOfDeclaration(const char* text, // from last time. leading.swap(upcoming_doc_comments_); - if (location != NULL) { + if (location != nullptr) { upcoming_detached_comments_.swap(detached); location->AttachComments(&leading, &trailing, &detached); } else if (strcmp(text, "}") == 0) { @@ -380,7 +376,7 @@ bool Parser::ConsumeEndOfDeclaration(const char* text, // ------------------------------------------------------------------- void Parser::AddError(int line, int column, const TProtoStringType& error) { - if (error_collector_ != NULL) { + if (error_collector_ != nullptr) { error_collector_->AddError(line, column, error); } had_errors_ = true; @@ -473,7 +469,7 @@ void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) { void Parser::LocationRecorder::RecordLegacyLocation( const Message* descriptor, DescriptorPool::ErrorCollector::ErrorLocation location) { - if (parser_->source_location_table_ != NULL) { + if (parser_->source_location_table_ != nullptr) { parser_->source_location_table_->Add( descriptor, location, location_->span(0), location_->span(1)); } @@ -516,7 +512,7 @@ void Parser::SkipStatement() { if (AtEnd()) { return; } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { return; } else if (TryConsume("{")) { SkipRestOfBlock(); @@ -534,7 +530,7 @@ void Parser::SkipRestOfBlock() { if (AtEnd()) { return; } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { - if (TryConsumeEndOfDeclaration("}", NULL)) { + if (TryConsumeEndOfDeclaration("}", nullptr)) { return; } else if (TryConsume("{")) { SkipRestOfBlock(); @@ -628,7 +624,7 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { if (LookingAtType(io::Tokenizer::TYPE_START)) { // Advance to first token. - input_->NextWithComments(NULL, &upcoming_detached_comments_, + input_->NextWithComments(nullptr, &upcoming_detached_comments_, &upcoming_doc_comments_); } @@ -644,7 +640,7 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { return false; } // Store the syntax into the file. - if (file != NULL) file->set_syntax(syntax_identifier_); + if (file != nullptr) file->set_syntax(syntax_identifier_); } else if (!stop_after_syntax_identifier_) { syntax_identifier_ = "proto2"; } @@ -660,16 +656,16 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { if (LookingAt("}")) { AddError("Unmatched \"}\"."); - input_->NextWithComments(NULL, &upcoming_detached_comments_, + input_->NextWithComments(nullptr, &upcoming_detached_comments_, &upcoming_doc_comments_); } } } } - input_ = NULL; - source_code_info_ = NULL; - assert(file != NULL); + input_ = nullptr; + source_code_info_ = nullptr; + assert(file != nullptr); source_code_info.Swap(file->mutable_source_code_info()); return !had_errors_; } @@ -702,7 +698,7 @@ bool Parser::ParseSyntaxIdentifier(const LocationRecorder& parent) { bool Parser::ParseTopLevelStatement(FileDescriptorProto* file, const LocationRecorder& root_location) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore return true; } else if (LookingAt("message")) { @@ -858,7 +854,7 @@ bool Parser::ParseMessageBlock(DescriptorProto* message, const FileDescriptorProto* containing_file) { DO(ConsumeEndOfDeclaration("{", &message_location)); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsumeEndOfDeclaration("}", nullptr)) { if (AtEnd()) { AddError("Reached end of input in message definition (missing '}')."); return false; @@ -883,7 +879,7 @@ bool Parser::ParseMessageBlock(DescriptorProto* message, bool Parser::ParseMessageStatement(DescriptorProto* message, const LocationRecorder& message_location, const FileDescriptorProto* containing_file) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore return true; } else if (LookingAt("message")) { @@ -941,7 +937,7 @@ bool Parser::ParseMessageField(FieldDescriptorProto* field, const FileDescriptorProto* containing_file) { { FieldDescriptorProto::Label label; - if (ParseLabel(&label, field_location, containing_file)) { + if (ParseLabel(&label, field_location)) { field->set_label(label); if (label == FieldDescriptorProto::LABEL_OPTIONAL && syntax_identifier_ == "proto3") { @@ -1454,7 +1450,7 @@ bool Parser::ParseOption(Message* options, // Create an entry in the uninterpreted_option field. const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()->FindFieldByName("uninterpreted_option"); - GOOGLE_CHECK(uninterpreted_option_field != NULL) + GOOGLE_CHECK(uninterpreted_option_field != nullptr) << "No field named \"uninterpreted_option\" in the Options proto."; const Reflection* reflection = options->GetReflection(); @@ -1902,7 +1898,7 @@ bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, // other statements. SkipStatement(); } - } while (!TryConsumeEndOfDeclaration("}", NULL)); + } while (!TryConsumeEndOfDeclaration("}", nullptr)); return true; } @@ -1966,7 +1962,7 @@ bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl, // other statements. SkipStatement(); } - } while (!TryConsumeEndOfDeclaration("}", NULL)); + } while (!TryConsumeEndOfDeclaration("}", nullptr)); return true; } @@ -1999,7 +1995,7 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type, const FileDescriptorProto* containing_file) { DO(ConsumeEndOfDeclaration("{", &enum_location)); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsumeEndOfDeclaration("}", nullptr)) { if (AtEnd()) { AddError("Reached end of input in enum definition (missing '}')."); return false; @@ -2018,7 +2014,7 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type, bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type, const LocationRecorder& enum_location, const FileDescriptorProto* containing_file) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore return true; } else if (LookingAt("option")) { @@ -2116,7 +2112,7 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service, const FileDescriptorProto* containing_file) { DO(ConsumeEndOfDeclaration("{", &service_location)); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsumeEndOfDeclaration("}", nullptr)) { if (AtEnd()) { AddError("Reached end of input in service definition (missing '}')."); return false; @@ -2135,7 +2131,7 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service, bool Parser::ParseServiceStatement(ServiceDescriptorProto* service, const LocationRecorder& service_location, const FileDescriptorProto* containing_file) { - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore return true; } else if (LookingAt("option")) { @@ -2173,7 +2169,6 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method, DescriptorPool::ErrorCollector::OTHER); method->set_client_streaming(true); DO(Consume("stream")); - } LocationRecorder location(method_location, MethodDescriptorProto::kInputTypeFieldNumber); @@ -2194,7 +2189,6 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method, DescriptorPool::ErrorCollector::OTHER); DO(Consume("stream")); method->set_server_streaming(true); - } LocationRecorder location(method_location, MethodDescriptorProto::kOutputTypeFieldNumber); @@ -2222,13 +2216,13 @@ bool Parser::ParseMethodOptions(const LocationRecorder& parent_location, Message* mutable_options) { // Options! ConsumeEndOfDeclaration("{", &parent_location); - while (!TryConsumeEndOfDeclaration("}", NULL)) { + while (!TryConsumeEndOfDeclaration("}", nullptr)) { if (AtEnd()) { AddError("Reached end of input in method options (missing '}')."); return false; } - if (TryConsumeEndOfDeclaration(";", NULL)) { + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore } else { LocationRecorder location(parent_location, optionsFieldNumber); @@ -2247,8 +2241,7 @@ bool Parser::ParseMethodOptions(const LocationRecorder& parent_location, // ------------------------------------------------------------------- bool Parser::ParseLabel(FieldDescriptorProto::Label* label, - const LocationRecorder& field_location, - const FileDescriptorProto* containing_file) { + const LocationRecorder& field_location) { if (!LookingAt("optional") && !LookingAt("repeated") && !LookingAt("required")) { return false; @@ -2392,7 +2385,7 @@ bool SourceLocationTable::Find( int* column) const { const std::pair<int, int>* result = FindOrNull(location_map_, std::make_pair(descriptor, location)); - if (result == NULL) { + if (result == nullptr) { *line = -1; *column = 0; return false; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/parser.h b/contrib/libs/protoc/src/google/protobuf/compiler/parser.h index 0a1bfc6827..f60a97c44c 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/parser.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/parser.h @@ -42,9 +42,9 @@ #include <string> #include <utility> +#include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/tokenizer.h> -#include <google/protobuf/descriptor.h> #include <google/protobuf/repeated_field.h> // Must be included last. @@ -281,9 +281,6 @@ class PROTOBUF_EXPORT Parser { std::vector<TProtoStringType>* detached_comments) const; private: - // Indexes of parent and current location in the parent - // SourceCodeInfo.location repeated field. For top-level elements, - // parent_index_ is -1. Parser* parser_; SourceCodeInfo* source_code_info_; SourceCodeInfo::Location* location_; @@ -434,7 +431,6 @@ class PROTOBUF_EXPORT Parser { const LocationRecorder& method_location, const FileDescriptorProto* containing_file); - // Parse options of a single method or stream. bool ParseMethodOptions(const LocationRecorder& parent_location, const FileDescriptorProto* containing_file, @@ -444,8 +440,7 @@ class PROTOBUF_EXPORT Parser { // Parse "required", "optional", or "repeated" and fill in "label" // with the value. Returns true if such a label is consumed. bool ParseLabel(FieldDescriptorProto::Label* label, - const LocationRecorder& field_location, - const FileDescriptorProto* containing_file); + const LocationRecorder& field_location); // Parse a type name and fill in "type" (if it is a primitive) or // "type_name" (if it is not) with the type parsed. diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/php/php_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/php/php_generator.cc index 03aca43b04..b06200a986 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/php/php_generator.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/php/php_generator.cc @@ -50,28 +50,29 @@ const TProtoStringType kDescriptorMetadataFile = const TProtoStringType kDescriptorDirName = "Google/Protobuf/Internal"; const TProtoStringType kDescriptorPackageName = "Google\\Protobuf\\Internal"; const char* const kReservedNames[] = { - "abstract", "and", "array", "as", "break", - "callable", "case", "catch", "class", "clone", - "const", "continue", "declare", "default", "die", - "do", "echo", "else", "elseif", "empty", - "enddeclare", "endfor", "endforeach", "endif", "endswitch", - "endwhile", "eval", "exit", "extends", "final", - "finally", "fn", "for", "foreach", "function", - "global", "goto", "if", "implements", "include", - "include_once", "instanceof", "insteadof", "interface", "isset", - "list", "match", "namespace", "new", "or", - "print", "private", "protected", "public", "require", - "require_once", "return", "static", "switch", "throw", - "trait", "try", "unset", "use", "var", - "while", "xor", "yield", "int", "float", - "bool", "string", "true", "false", "null", - "void", "iterable"}; + "abstract", "and", "array", "as", "break", + "callable", "case", "catch", "class", "clone", + "const", "continue", "declare", "default", "die", + "do", "echo", "else", "elseif", "empty", + "enddeclare", "endfor", "endforeach", "endif", "endswitch", + "endwhile", "eval", "exit", "extends", "final", + "finally", "fn", "for", "foreach", "function", + "global", "goto", "if", "implements", "include", + "include_once", "instanceof", "insteadof", "interface", "isset", + "list", "match", "namespace", "new", "or", + "parent", "print", "private", "protected", "public", + "require", "require_once", "return", "self", "static", + "switch", "throw", "trait", "try", "unset", + "use", "var", "while", "xor", "yield", + "int", "float", "bool", "string", "true", + "false", "null", "void", "iterable"}; const char* const kValidConstantNames[] = { "int", "float", "bool", "string", "true", - "false", "null", "void", "iterable", + "false", "null", "void", "iterable", "parent", + "self" }; -const int kReservedNamesSize = 77; -const int kValidConstantNamesSize = 9; +const int kReservedNamesSize = 79; +const int kValidConstantNamesSize = 11; const int kFieldSetter = 1; const int kFieldGetter = 2; const int kFieldProperty = 3; @@ -85,14 +86,14 @@ struct Options { bool is_descriptor = false; bool aggregate_metadata = false; bool gen_c_wkt = false; - std::set<string> aggregate_metadata_prefixes; + std::set<TProtoStringType> aggregate_metadata_prefixes; }; namespace { // Forward decls. TProtoStringType PhpName(const TProtoStringType& full_name, const Options& options); -TProtoStringType IntToString(int32 value); +TProtoStringType IntToString(arc_i32 value); TProtoStringType FilenameToClassname(const TProtoStringType& filename); TProtoStringType GeneratedMetadataFileName(const FileDescriptor* file, const Options& options); @@ -432,7 +433,7 @@ TProtoStringType GeneratedServiceFileName(const ServiceDescriptor* service, return result + ".php"; } -TProtoStringType IntToString(int32 value) { +TProtoStringType IntToString(arc_i32 value) { std::ostringstream os; os << value; return TProtoStringType{os.str()}; @@ -743,8 +744,8 @@ void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options, // Type check. if (field->is_map()) { const Descriptor* map_entry = field->message_type(); - const FieldDescriptor* key = map_entry->FindFieldByName("key"); - const FieldDescriptor* value = map_entry->FindFieldByName("value"); + const FieldDescriptor* key = map_entry->map_key(); + const FieldDescriptor* value = map_entry->map_value(); printer->Print( "$arr = GPBUtil::checkMapField($var, " "\\Google\\Protobuf\\Internal\\GPBType::^key_type^, " @@ -891,9 +892,9 @@ void GenerateMessageToPool(const TProtoStringType& name_prefix, const FieldDescriptor* field = message->field(i); if (field->is_map()) { const FieldDescriptor* key = - field->message_type()->FindFieldByName("key"); + field->message_type()->map_key(); const FieldDescriptor* val = - field->message_type()->FindFieldByName("value"); + field->message_type()->map_value(); printer->Print( "->map('^field^', \\Google\\Protobuf\\Internal\\GPBType::^key^, " "\\Google\\Protobuf\\Internal\\GPBType::^value^, ^number^^other^)\n", @@ -1116,7 +1117,7 @@ void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options, std::map<const FileDescriptor*, int> dependency_count; std::set<const FileDescriptor*> nodes_without_dependency; FileDescriptorSet sorted_file_set; - + AnalyzeDependencyForFile( file, &nodes_without_dependency, &deps, &dependency_count); @@ -1871,44 +1872,45 @@ void GenerateCEnum(const EnumDescriptor* desc, io::Printer* printer) { "\n" "PHP_METHOD($c_name$, name) {\n" " $file_c_name$_AddDescriptor();\n" - " const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n" - " const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n" - " const char *name;\n" + " const upb_DefPool *symtab = DescriptorPool_GetSymbolTable();\n" + " const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, \"$name$\");\n" " zend_long value;\n" " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"l\", &value) ==\n" " FAILURE) {\n" " return;\n" " }\n" - " name = upb_enumdef_iton(e, value);\n" - " if (!name) {\n" + " const upb_EnumValueDef* ev =\n" + " upb_EnumDef_FindValueByNumber(e, value);\n" + " if (!ev) {\n" " zend_throw_exception_ex(NULL, 0,\n" " \"$php_name$ has no name \"\n" " \"defined for value \" ZEND_LONG_FMT \".\",\n" " value);\n" " return;\n" " }\n" - " RETURN_STRING(name);\n" + " RETURN_STRING(upb_EnumValueDef_Name(ev));\n" "}\n" "\n" "PHP_METHOD($c_name$, value) {\n" " $file_c_name$_AddDescriptor();\n" - " const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n" - " const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n" + " const upb_DefPool *symtab = DescriptorPool_GetSymbolTable();\n" + " const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, \"$name$\");\n" " char *name = NULL;\n" " size_t name_len;\n" - " arc_i32 num;\n" " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"s\", &name,\n" " &name_len) == FAILURE) {\n" " return;\n" " }\n" - " if (!upb_enumdef_ntoi(e, name, name_len, &num)) {\n" + " const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNameWithSize(\n" + " e, name, name_len);\n" + " if (!ev) {\n" " zend_throw_exception_ex(NULL, 0,\n" " \"$php_name$ has no value \"\n" " \"defined for name %s.\",\n" " name);\n" " return;\n" " }\n" - " RETURN_LONG(num);\n" + " RETURN_LONG(upb_EnumValueDef_Number(ev));\n" "}\n" "\n" "static zend_function_entry $c_name$_phpmethods[] = {\n" @@ -1967,8 +1969,8 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) { printer->Print( "static PHP_METHOD($c_name$, get$camel_name$) {\n" " Message* intern = (Message*)Z_OBJ_P(getThis());\n" - " const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n" - " \"$name$\");\n" + " const upb_FieldDef *f = upb_MessageDef_FindFieldByName(\n" + " intern->desc->msgdef, \"$name$\");\n" " zval ret;\n" " Message_get(intern, f, &ret);\n" " RETURN_COPY_VALUE(&ret);\n" @@ -1976,8 +1978,8 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) { "\n" "static PHP_METHOD($c_name$, set$camel_name$) {\n" " Message* intern = (Message*)Z_OBJ_P(getThis());\n" - " const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n" - " \"$name$\");\n" + " const upb_FieldDef *f = upb_MessageDef_FindFieldByName(\n" + " intern->desc->msgdef, \"$name$\");\n" " zval *val;\n" " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"z\", &val)\n" " == FAILURE) {\n" @@ -1997,10 +1999,11 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) { printer->Print( "static PHP_METHOD($c_name$, get$camel_name$) {\n" " Message* intern = (Message*)Z_OBJ_P(getThis());\n" - " const upb_oneofdef *oneof = upb_msgdef_ntooz(intern->desc->msgdef,\n" - " \"$name$\");\n" - " const upb_fielddef *field = upb_msg_whichoneof(intern->msg, oneof);\n" - " RETURN_STRING(field ? upb_fielddef_name(field) : \"\");\n" + " const upb_OneofDef *oneof = upb_MessageDef_FindOneofByName(\n" + " intern->desc->msgdef, \"$name$\");\n" + " const upb_FieldDef *field = \n" + " upb_Message_WhichOneof(intern->msg, oneof);\n" + " RETURN_STRING(field ? upb_FieldDef_Name(field) : \"\");\n" "}\n", "c_name", c_name, "name", oneof->name(), @@ -2067,7 +2070,7 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) { break; default: break; - } + } printer->Print( " ZEND_FE_END\n" diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/plugin.cc b/contrib/libs/protoc/src/google/protobuf/compiler/plugin.cc index 3d51e1e1cd..2d7fc6fcb5 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/plugin.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/plugin.cc @@ -68,7 +68,7 @@ class GeneratorResponseContext : public GeneratorContext { : compiler_version_(compiler_version), response_(response), parsed_files_(parsed_files) {} - virtual ~GeneratorResponseContext() {} + ~GeneratorResponseContext() override {} // implements GeneratorContext -------------------------------------- @@ -117,7 +117,7 @@ bool GenerateCode(const CodeGeneratorRequest& request, DescriptorPool pool; for (int i = 0; i < request.proto_file_size(); i++) { const FileDescriptor* file = pool.BuildFile(request.proto_file(i)); - if (file == NULL) { + if (file == nullptr) { // BuildFile() already wrote an error message. return false; } @@ -126,7 +126,7 @@ bool GenerateCode(const CodeGeneratorRequest& request, std::vector<const FileDescriptor*> parsed_files; for (int i = 0; i < request.file_to_generate_size(); i++) { parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i))); - if (parsed_files.back() == NULL) { + if (parsed_files.back() == nullptr) { *error_msg = "protoc asked plugin to generate a file but " "did not provide a descriptor for the file: " + diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/plugin.h b/contrib/libs/protoc/src/google/protobuf/compiler/plugin.h index efbf9e8707..65af26e0f7 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/plugin.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/plugin.h @@ -65,6 +65,7 @@ #include <string> #include <google/protobuf/stubs/port.h> +// Must be included last. #include <google/protobuf/port_def.inc> namespace google { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/plugin.pb.cc b/contrib/libs/protoc/src/google/protobuf/compiler/plugin.pb.cc index 6370bf1fb1..34126b9d9a 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/plugin.pb.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/plugin.pb.cc @@ -16,72 +16,76 @@ #include <google/protobuf/port_def.inc> PROTOBUF_PRAGMA_INIT_SEG + +namespace _pb = ::PROTOBUF_NAMESPACE_ID; +namespace _pbi = _pb::internal; + PROTOBUF_NAMESPACE_OPEN namespace compiler { -constexpr Version::Version( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) - : suffix_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) +PROTOBUF_CONSTEXPR Version::Version( + ::_pbi::ConstantInitialized) + : suffix_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , major_(0) , minor_(0) , patch_(0){} struct VersionDefaultTypeInternal { - constexpr VersionDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR VersionDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~VersionDefaultTypeInternal() {} union { Version _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT VersionDefaultTypeInternal _Version_default_instance_; -constexpr CodeGeneratorRequest::CodeGeneratorRequest( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 VersionDefaultTypeInternal _Version_default_instance_; +PROTOBUF_CONSTEXPR CodeGeneratorRequest::CodeGeneratorRequest( + ::_pbi::ConstantInitialized) : file_to_generate_() , proto_file_() - , parameter_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , parameter_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , compiler_version_(nullptr){} struct CodeGeneratorRequestDefaultTypeInternal { - constexpr CodeGeneratorRequestDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR CodeGeneratorRequestDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorRequestDefaultTypeInternal() {} union { CodeGeneratorRequest _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_; -constexpr CodeGeneratorResponse_File::CodeGeneratorResponse_File( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) - : name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , insertion_point_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) - , content_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_; +PROTOBUF_CONSTEXPR CodeGeneratorResponse_File::CodeGeneratorResponse_File( + ::_pbi::ConstantInitialized) + : name_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) + , insertion_point_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) + , content_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , generated_code_info_(nullptr){} struct CodeGeneratorResponse_FileDefaultTypeInternal { - constexpr CodeGeneratorResponse_FileDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR CodeGeneratorResponse_FileDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorResponse_FileDefaultTypeInternal() {} union { CodeGeneratorResponse_File _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_; -constexpr CodeGeneratorResponse::CodeGeneratorResponse( - ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized) +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_; +PROTOBUF_CONSTEXPR CodeGeneratorResponse::CodeGeneratorResponse( + ::_pbi::ConstantInitialized) : file_() - , error_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string) + , error_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , supported_features_(arc_ui64{0u}){} struct CodeGeneratorResponseDefaultTypeInternal { - constexpr CodeGeneratorResponseDefaultTypeInternal() - : _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {} + PROTOBUF_CONSTEXPR CodeGeneratorResponseDefaultTypeInternal() + : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorResponseDefaultTypeInternal() {} union { CodeGeneratorResponse _instance; }; }; -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT CodeGeneratorResponseDefaultTypeInternal _CodeGeneratorResponse_default_instance_; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorResponseDefaultTypeInternal _CodeGeneratorResponse_default_instance_; } // namespace compiler PROTOBUF_NAMESPACE_CLOSE -static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[4]; -static const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]; -static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr; +static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[4]; +static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]; +static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr; const arc_ui32 TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::compiler::Version, _has_bits_), @@ -139,18 +143,18 @@ const arc_ui32 TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offset 1, ~0u, }; -static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { +static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { { 0, 10, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::Version)}, { 14, 24, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest)}, { 28, 38, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File)}, { 42, 51, -1, sizeof(::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse)}, }; -static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { - reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_), - reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorRequest_default_instance_), - reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_File_default_instance_), - reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_default_instance_), +static const ::_pb::Message* const file_default_instances[] = { + &::PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_._instance, + &::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorRequest_default_instance_._instance, + &::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_File_default_instance_._instance, + &::PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_default_instance_._instance, }; const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = @@ -175,22 +179,24 @@ const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2epro "uginProtosZ)google.golang.org/protobuf/t" "ypes/pluginpb" ; -static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps[1] = { +static const ::_pbi::DescriptorTable* const descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps[1] = { &::descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, }; -static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once; -const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = { - false, false, 773, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto", - &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps, 1, 4, - schemas, file_default_instances, TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets, - file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, +static ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once; +const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = { + false, false, 773, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, + "google/protobuf/compiler/plugin.proto", + &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps, 1, 4, + schemas, file_default_instances, TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets, + file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, + file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, }; -PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter() { +PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto; } // Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fplugin_2eproto(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fplugin_2eproto(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto); PROTOBUF_NAMESPACE_OPEN namespace compiler { const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* CodeGeneratorResponse_Feature_descriptor() { @@ -238,21 +244,18 @@ Version::Version(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned) : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.Version) } Version::Version(const Version& from) : ::PROTOBUF_NAMESPACE_ID::Message(), _has_bits_(from._has_bits_) { _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + suffix_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + suffix_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_suffix()) { - suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_suffix(), + suffix_.Set(from._internal_suffix(), GetArenaForAllocation()); } ::memcpy(&major_, &from.major_, @@ -262,9 +265,9 @@ Version::Version(const Version& from) } inline void Version::SharedCtor() { -suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +suffix_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + suffix_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>( reinterpret_cast<char*>(&major_) - reinterpret_cast<char*>(this)), @@ -274,22 +277,18 @@ suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlrea Version::~Version() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.Version) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void Version::SharedDtor() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - suffix_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + suffix_.Destroy(); } -void Version::ArenaDtor(void* object) { - Version* _this = reinterpret_cast< Version* >(object); - (void)_this; -} -void Version::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { -} void Version::SetCachedSize(int size) const { _cached_size_.Set(size); } @@ -313,12 +312,12 @@ void Version::Clear() { _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* Version::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; while (!ctx->Done(&ptr)) { arc_ui32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // optional int32 major = 1; case 1: @@ -351,11 +350,11 @@ const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::in case 4: if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) { auto str = _internal_mutable_suffix(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.Version.suffix"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.Version.suffix"); #endif // !NDEBUG - CHK_(ptr); } else goto handle_unusual; continue; @@ -393,19 +392,19 @@ uint8_t* Version::_InternalSerialize( // optional int32 major = 1; if (cached_has_bits & 0x00000002u) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_major(), target); + target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_major(), target); } // optional int32 minor = 2; if (cached_has_bits & 0x00000004u) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_minor(), target); + target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_minor(), target); } // optional int32 patch = 3; if (cached_has_bits & 0x00000008u) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->_internal_patch(), target); + target = ::_pbi::WireFormatLite::WriteInt32ToArray(3, this->_internal_patch(), target); } // optional string suffix = 4; @@ -419,7 +418,7 @@ uint8_t* Version::_InternalSerialize( } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.Version) @@ -445,17 +444,17 @@ size_t Version::ByteSizeLong() const { // optional int32 major = 1; if (cached_has_bits & 0x00000002u) { - total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_major()); + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_major()); } // optional int32 minor = 2; if (cached_has_bits & 0x00000004u) { - total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_minor()); + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_minor()); } // optional int32 patch = 3; if (cached_has_bits & 0x00000008u) { - total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_patch()); + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_patch()); } } @@ -518,7 +517,6 @@ void Version::InternalSwap(Version* other) { _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &suffix_, lhs_arena, &other->suffix_, rhs_arena ); @@ -531,7 +529,7 @@ void Version::InternalSwap(Version* other) { } ::PROTOBUF_NAMESPACE_ID::Metadata Version::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[0]); } @@ -563,9 +561,6 @@ CodeGeneratorRequest::CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena file_to_generate_(arena), proto_file_(arena) { SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorRequest) } CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) @@ -574,12 +569,12 @@ CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) file_to_generate_(from.file_to_generate_), proto_file_(from.proto_file_) { _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - parameter_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + parameter_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + parameter_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_parameter()) { - parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_parameter(), + parameter_.Set(from._internal_parameter(), GetArenaForAllocation()); } if (from._internal_has_compiler_version()) { @@ -591,32 +586,28 @@ CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) } inline void CodeGeneratorRequest::SharedCtor() { -parameter_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +parameter_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + parameter_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING compiler_version_ = nullptr; } CodeGeneratorRequest::~CodeGeneratorRequest() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorRequest) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void CodeGeneratorRequest::SharedDtor() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - parameter_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + parameter_.Destroy(); if (this != internal_default_instance()) delete compiler_version_; } -void CodeGeneratorRequest::ArenaDtor(void* object) { - CodeGeneratorRequest* _this = reinterpret_cast< CodeGeneratorRequest* >(object); - (void)_this; -} -void CodeGeneratorRequest::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { -} void CodeGeneratorRequest::SetCachedSize(int size) const { _cached_size_.Set(size); } @@ -643,12 +634,12 @@ void CodeGeneratorRequest::Clear() { _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; while (!ctx->Done(&ptr)) { arc_ui32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // repeated string file_to_generate = 1; case 1: @@ -657,11 +648,11 @@ const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAM do { ptr += 1; auto str = _internal_add_file_to_generate(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate"); #endif // !NDEBUG - CHK_(ptr); if (!ctx->DataAvailable(ptr)) break; } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr)); } else @@ -671,11 +662,11 @@ const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAM case 2: if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { auto str = _internal_mutable_parameter(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.parameter"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorRequest.parameter"); #endif // !NDEBUG - CHK_(ptr); } else goto handle_unusual; continue; @@ -753,22 +744,21 @@ uint8_t* CodeGeneratorRequest::_InternalSerialize( // optional .google.protobuf.compiler.Version compiler_version = 3; if (cached_has_bits & 0x00000002u) { - target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage( - 3, _Internal::compiler_version(this), target, stream); + InternalWriteMessage(3, _Internal::compiler_version(this), + _Internal::compiler_version(this).GetCachedSize(), target, stream); } // repeated .google.protobuf.FileDescriptorProto proto_file = 15; - for (unsigned int i = 0, - n = static_cast<unsigned int>(this->_internal_proto_file_size()); i < n; i++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast<unsigned>(this->_internal_proto_file_size()); i < n; i++) { + const auto& repfield = this->_internal_proto_file(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(15, this->_internal_proto_file(i), target, stream); + InternalWriteMessage(15, repfield, repfield.GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorRequest) @@ -873,7 +863,6 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { file_to_generate_.InternalSwap(&other->file_to_generate_); proto_file_.InternalSwap(&other->proto_file_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ¶meter_, lhs_arena, &other->parameter_, rhs_arena ); @@ -881,7 +870,7 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { } ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorRequest::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]); } @@ -918,37 +907,34 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID:: bool is_message_owned) : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) { SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse.File) } CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from) : ::PROTOBUF_NAMESPACE_ID::Message(), _has_bits_(from._has_bits_) { _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + name_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_name()) { - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + name_.Set(from._internal_name(), GetArenaForAllocation()); } - insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + insertion_point_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + insertion_point_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_insertion_point()) { - insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_insertion_point(), + insertion_point_.Set(from._internal_insertion_point(), GetArenaForAllocation()); } - content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + content_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + content_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_content()) { - content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_content(), + content_.Set(from._internal_content(), GetArenaForAllocation()); } if (from._internal_has_generated_code_info()) { @@ -960,42 +946,38 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorRespon } inline void CodeGeneratorResponse_File::SharedCtor() { -name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +name_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + name_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +insertion_point_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + insertion_point_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING -content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +content_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + content_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING generated_code_info_ = nullptr; } CodeGeneratorResponse_File::~CodeGeneratorResponse_File() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse.File) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void CodeGeneratorResponse_File::SharedDtor() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - insertion_point_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - content_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.Destroy(); + insertion_point_.Destroy(); + content_.Destroy(); if (this != internal_default_instance()) delete generated_code_info_; } -void CodeGeneratorResponse_File::ArenaDtor(void* object) { - CodeGeneratorResponse_File* _this = reinterpret_cast< CodeGeneratorResponse_File* >(object); - (void)_this; -} -void CodeGeneratorResponse_File::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { -} void CodeGeneratorResponse_File::SetCachedSize(int size) const { _cached_size_.Set(size); } @@ -1026,22 +1008,22 @@ void CodeGeneratorResponse_File::Clear() { _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; while (!ctx->Done(&ptr)) { arc_ui32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // optional string name = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { auto str = _internal_mutable_name(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.name"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.name"); #endif // !NDEBUG - CHK_(ptr); } else goto handle_unusual; continue; @@ -1049,11 +1031,11 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOB case 2: if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) { auto str = _internal_mutable_insertion_point(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point"); #endif // !NDEBUG - CHK_(ptr); } else goto handle_unusual; continue; @@ -1061,11 +1043,11 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOB case 15: if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 122)) { auto str = _internal_mutable_content(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.content"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.File.content"); #endif // !NDEBUG - CHK_(ptr); } else goto handle_unusual; continue; @@ -1140,14 +1122,13 @@ uint8_t* CodeGeneratorResponse_File::_InternalSerialize( // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; if (cached_has_bits & 0x00000008u) { - target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage( - 16, _Internal::generated_code_info(this), target, stream); + InternalWriteMessage(16, _Internal::generated_code_info(this), + _Internal::generated_code_info(this).GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse.File) @@ -1251,17 +1232,14 @@ void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) _internal_metadata_.InternalSwap(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &name_, lhs_arena, &other->name_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &insertion_point_, lhs_arena, &other->insertion_point_, rhs_arena ); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &content_, lhs_arena, &other->content_, rhs_arena ); @@ -1269,7 +1247,7 @@ void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) } ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse_File::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[2]); } @@ -1292,9 +1270,6 @@ CodeGeneratorResponse::CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* are : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned), file_(arena) { SharedCtor(); - if (!is_message_owned) { - RegisterArenaDtor(arena); - } // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse) } CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) @@ -1302,12 +1277,12 @@ CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) _has_bits_(from._has_bits_), file_(from.file_) { _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); - error_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + error_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + error_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING if (from._internal_has_error()) { - error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_error(), + error_.Set(from._internal_error(), GetArenaForAllocation()); } supported_features_ = from.supported_features_; @@ -1315,31 +1290,27 @@ CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) } inline void CodeGeneratorResponse::SharedCtor() { -error_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +error_.InitDefault(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + error_.Set("", GetArenaForAllocation()); #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING supported_features_ = arc_ui64{0u}; } CodeGeneratorResponse::~CodeGeneratorResponse() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse) - if (GetArenaForAllocation() != nullptr) return; + if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) { + (void)arena; + return; + } SharedDtor(); - _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } inline void CodeGeneratorResponse::SharedDtor() { GOOGLE_DCHECK(GetArenaForAllocation() == nullptr); - error_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + error_.Destroy(); } -void CodeGeneratorResponse::ArenaDtor(void* object) { - CodeGeneratorResponse* _this = reinterpret_cast< CodeGeneratorResponse* >(object); - (void)_this; -} -void CodeGeneratorResponse::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { -} void CodeGeneratorResponse::SetCachedSize(int size) const { _cached_size_.Set(size); } @@ -1360,22 +1331,22 @@ void CodeGeneratorResponse::Clear() { _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } -const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; while (!ctx->Done(&ptr)) { arc_ui32 tag; - ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + ptr = ::_pbi::ReadTag(ptr, &tag); switch (tag >> 3) { // optional string error = 1; case 1: if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) { auto str = _internal_mutable_error(); - ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); #ifndef NDEBUG - ::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.error"); + ::_pbi::VerifyUTF8(str, "google.protobuf.compiler.CodeGeneratorResponse.error"); #endif // !NDEBUG - CHK_(ptr); } else goto handle_unusual; continue; @@ -1445,19 +1416,19 @@ uint8_t* CodeGeneratorResponse::_InternalSerialize( // optional uint64 supported_features = 2; if (cached_has_bits & 0x00000002u) { target = stream->EnsureSpace(target); - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt64ToArray(2, this->_internal_supported_features(), target); + target = ::_pbi::WireFormatLite::WriteUInt64ToArray(2, this->_internal_supported_features(), target); } // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; - for (unsigned int i = 0, - n = static_cast<unsigned int>(this->_internal_file_size()); i < n; i++) { - target = stream->EnsureSpace(target); + for (unsigned i = 0, + n = static_cast<unsigned>(this->_internal_file_size()); i < n; i++) { + const auto& repfield = this->_internal_file(i); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: - InternalWriteMessage(15, this->_internal_file(i), target, stream); + InternalWriteMessage(15, repfield, repfield.GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { - target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse) @@ -1490,7 +1461,7 @@ size_t CodeGeneratorResponse::ByteSizeLong() const { // optional uint64 supported_features = 2; if (cached_has_bits & 0x00000002u) { - total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64SizePlusOne(this->_internal_supported_features()); + total_size += ::_pbi::WireFormatLite::UInt64SizePlusOne(this->_internal_supported_features()); } } @@ -1549,7 +1520,6 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { swap(_has_bits_[0], other->_has_bits_[0]); file_.InternalSwap(&other->file_); ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), &error_, lhs_arena, &other->error_, rhs_arena ); @@ -1557,7 +1527,7 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { } ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse::GetMetadata() const { - return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors( + return ::_pbi::AssignDescriptors( &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[3]); } @@ -1566,16 +1536,20 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { } // namespace compiler PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::Version* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::Version >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::Version* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::Version >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::compiler::Version >(arena); } -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest >(arena); } -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >(arena); } -template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse* Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse >(Arena* arena) { +template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse* +Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse >(Arena* arena) { return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse >(arena); } PROTOBUF_NAMESPACE_CLOSE diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/plugin.pb.h b/contrib/libs/protoc/src/google/protobuf/compiler/plugin.pb.h index 2edc4f2ce4..64d7be56fd 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/plugin.pb.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/plugin.pb.h @@ -8,12 +8,12 @@ #include <string> #include <google/protobuf/port_def.inc> -#if PROTOBUF_VERSION < 3019000 +#if PROTOBUF_VERSION < 3020000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3019000 < PROTOBUF_MIN_PROTOC_VERSION +#if 3020002 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -23,7 +23,6 @@ #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/arena.h> #include <google/protobuf/arenastring.h> -#include <google/protobuf/generated_message_table_driven.h> #include <google/protobuf/generated_message_util.h> #include <google/protobuf/metadata_lite.h> #include <google/protobuf/generated_message_reflection.h> @@ -50,14 +49,6 @@ PROTOBUF_NAMESPACE_CLOSE // Internal implementation detail -- do not use these members. struct PROTOC_EXPORT TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto { - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[4] - PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; - static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; static const arc_ui32 offsets[]; }; PROTOC_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto; @@ -116,7 +107,7 @@ class PROTOC_EXPORT Version final : public: inline Version() : Version(nullptr) {} ~Version() override; - explicit constexpr Version(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Version(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Version(const Version& from); Version(Version&& from) noexcept @@ -225,9 +216,6 @@ class PROTOC_EXPORT Version final : protected: explicit Version(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -324,7 +312,7 @@ class PROTOC_EXPORT CodeGeneratorRequest final : public: inline CodeGeneratorRequest() : CodeGeneratorRequest(nullptr) {} ~CodeGeneratorRequest() override; - explicit constexpr CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); CodeGeneratorRequest(const CodeGeneratorRequest& from); CodeGeneratorRequest(CodeGeneratorRequest&& from) noexcept @@ -433,9 +421,6 @@ class PROTOC_EXPORT CodeGeneratorRequest final : protected: explicit CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -553,7 +538,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : public: inline CodeGeneratorResponse_File() : CodeGeneratorResponse_File(nullptr) {} ~CodeGeneratorResponse_File() override; - explicit constexpr CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from); CodeGeneratorResponse_File(CodeGeneratorResponse_File&& from) noexcept @@ -662,9 +647,6 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : protected: explicit CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -776,7 +758,7 @@ class PROTOC_EXPORT CodeGeneratorResponse final : public: inline CodeGeneratorResponse() : CodeGeneratorResponse(nullptr) {} ~CodeGeneratorResponse() override; - explicit constexpr CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); CodeGeneratorResponse(const CodeGeneratorResponse& from); CodeGeneratorResponse(CodeGeneratorResponse&& from) noexcept @@ -885,9 +867,6 @@ class PROTOC_EXPORT CodeGeneratorResponse final : protected: explicit CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned = false); - private: - static void ArenaDtor(void* object); - inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: static const ClassData _class_data_; @@ -1114,7 +1093,7 @@ template <typename ArgT0, typename... ArgT> inline PROTOBUF_ALWAYS_INLINE void Version::set_suffix(ArgT0&& arg0, ArgT... args) { _has_bits_[0] |= 0x00000001u; - suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + suffix_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.suffix) } inline TProtoStringType* Version::mutable_suffix() { @@ -1127,11 +1106,11 @@ inline const TProtoStringType& Version::_internal_suffix() const { } inline void Version::_internal_set_suffix(const TProtoStringType& value) { _has_bits_[0] |= 0x00000001u; - suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + suffix_.Set(value, GetArenaForAllocation()); } inline TProtoStringType* Version::_internal_mutable_suffix() { _has_bits_[0] |= 0x00000001u; - return suffix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return suffix_.Mutable(GetArenaForAllocation()); } inline TProtoStringType* Version::release_suffix() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.Version.suffix) @@ -1139,10 +1118,10 @@ inline TProtoStringType* Version::release_suffix() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - auto* p = suffix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + auto* p = suffix_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (suffix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (suffix_.IsDefault()) { + suffix_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; @@ -1153,11 +1132,10 @@ inline void Version::set_allocated_suffix(TProtoStringType* suffix) { } else { _has_bits_[0] &= ~0x00000001u; } - suffix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), suffix, - GetArenaForAllocation()); + suffix_.SetAllocated(suffix, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (suffix_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (suffix_.IsDefault()) { + suffix_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.Version.suffix) @@ -1262,7 +1240,7 @@ template <typename ArgT0, typename... ArgT> inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorRequest::set_parameter(ArgT0&& arg0, ArgT... args) { _has_bits_[0] |= 0x00000001u; - parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + parameter_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter) } inline TProtoStringType* CodeGeneratorRequest::mutable_parameter() { @@ -1275,11 +1253,11 @@ inline const TProtoStringType& CodeGeneratorRequest::_internal_parameter() const } inline void CodeGeneratorRequest::_internal_set_parameter(const TProtoStringType& value) { _has_bits_[0] |= 0x00000001u; - parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + parameter_.Set(value, GetArenaForAllocation()); } inline TProtoStringType* CodeGeneratorRequest::_internal_mutable_parameter() { _has_bits_[0] |= 0x00000001u; - return parameter_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return parameter_.Mutable(GetArenaForAllocation()); } inline TProtoStringType* CodeGeneratorRequest::release_parameter() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.parameter) @@ -1287,10 +1265,10 @@ inline TProtoStringType* CodeGeneratorRequest::release_parameter() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - auto* p = parameter_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + auto* p = parameter_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (parameter_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (parameter_.IsDefault()) { + parameter_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; @@ -1301,11 +1279,10 @@ inline void CodeGeneratorRequest::set_allocated_parameter(TProtoStringType* para } else { _has_bits_[0] &= ~0x00000001u; } - parameter_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), parameter, - GetArenaForAllocation()); + parameter_.SetAllocated(parameter, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (parameter_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (parameter_.IsDefault()) { + parameter_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter) @@ -1425,7 +1402,7 @@ inline void CodeGeneratorRequest::set_allocated_compiler_version(::PROTOBUF_NAME } if (compiler_version) { ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = - ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::PROTOBUF_NAMESPACE_ID::compiler::Version>::GetOwningArena(compiler_version); + ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(compiler_version); if (message_arena != submessage_arena) { compiler_version = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( message_arena, compiler_version, submessage_arena); @@ -1462,7 +1439,7 @@ template <typename ArgT0, typename... ArgT> inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse_File::set_name(ArgT0&& arg0, ArgT... args) { _has_bits_[0] |= 0x00000001u; - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name) } inline TProtoStringType* CodeGeneratorResponse_File::mutable_name() { @@ -1475,11 +1452,11 @@ inline const TProtoStringType& CodeGeneratorResponse_File::_internal_name() cons } inline void CodeGeneratorResponse_File::_internal_set_name(const TProtoStringType& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + name_.Set(value, GetArenaForAllocation()); } inline TProtoStringType* CodeGeneratorResponse_File::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return name_.Mutable(GetArenaForAllocation()); } inline TProtoStringType* CodeGeneratorResponse_File::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.name) @@ -1487,10 +1464,10 @@ inline TProtoStringType* CodeGeneratorResponse_File::release_name() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - auto* p = name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + auto* p = name_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (name_.IsDefault()) { + name_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; @@ -1501,11 +1478,10 @@ inline void CodeGeneratorResponse_File::set_allocated_name(TProtoStringType* nam } else { _has_bits_[0] &= ~0x00000001u; } - name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaForAllocation()); + name_.SetAllocated(name, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (name_.IsDefault()) { + name_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name) @@ -1531,7 +1507,7 @@ template <typename ArgT0, typename... ArgT> inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse_File::set_insertion_point(ArgT0&& arg0, ArgT... args) { _has_bits_[0] |= 0x00000002u; - insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + insertion_point_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) } inline TProtoStringType* CodeGeneratorResponse_File::mutable_insertion_point() { @@ -1544,11 +1520,11 @@ inline const TProtoStringType& CodeGeneratorResponse_File::_internal_insertion_p } inline void CodeGeneratorResponse_File::_internal_set_insertion_point(const TProtoStringType& value) { _has_bits_[0] |= 0x00000002u; - insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + insertion_point_.Set(value, GetArenaForAllocation()); } inline TProtoStringType* CodeGeneratorResponse_File::_internal_mutable_insertion_point() { _has_bits_[0] |= 0x00000002u; - return insertion_point_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return insertion_point_.Mutable(GetArenaForAllocation()); } inline TProtoStringType* CodeGeneratorResponse_File::release_insertion_point() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) @@ -1556,10 +1532,10 @@ inline TProtoStringType* CodeGeneratorResponse_File::release_insertion_point() { return nullptr; } _has_bits_[0] &= ~0x00000002u; - auto* p = insertion_point_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + auto* p = insertion_point_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (insertion_point_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (insertion_point_.IsDefault()) { + insertion_point_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; @@ -1570,11 +1546,10 @@ inline void CodeGeneratorResponse_File::set_allocated_insertion_point(TProtoStri } else { _has_bits_[0] &= ~0x00000002u; } - insertion_point_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), insertion_point, - GetArenaForAllocation()); + insertion_point_.SetAllocated(insertion_point, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (insertion_point_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (insertion_point_.IsDefault()) { + insertion_point_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) @@ -1600,7 +1575,7 @@ template <typename ArgT0, typename... ArgT> inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse_File::set_content(ArgT0&& arg0, ArgT... args) { _has_bits_[0] |= 0x00000004u; - content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + content_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content) } inline TProtoStringType* CodeGeneratorResponse_File::mutable_content() { @@ -1613,11 +1588,11 @@ inline const TProtoStringType& CodeGeneratorResponse_File::_internal_content() c } inline void CodeGeneratorResponse_File::_internal_set_content(const TProtoStringType& value) { _has_bits_[0] |= 0x00000004u; - content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + content_.Set(value, GetArenaForAllocation()); } inline TProtoStringType* CodeGeneratorResponse_File::_internal_mutable_content() { _has_bits_[0] |= 0x00000004u; - return content_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return content_.Mutable(GetArenaForAllocation()); } inline TProtoStringType* CodeGeneratorResponse_File::release_content() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.content) @@ -1625,10 +1600,10 @@ inline TProtoStringType* CodeGeneratorResponse_File::release_content() { return nullptr; } _has_bits_[0] &= ~0x00000004u; - auto* p = content_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + auto* p = content_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (content_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (content_.IsDefault()) { + content_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; @@ -1639,11 +1614,10 @@ inline void CodeGeneratorResponse_File::set_allocated_content(TProtoStringType* } else { _has_bits_[0] &= ~0x00000004u; } - content_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), content, - GetArenaForAllocation()); + content_.SetAllocated(content, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (content_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (content_.IsDefault()) { + content_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content) @@ -1722,8 +1696,7 @@ inline void CodeGeneratorResponse_File::set_allocated_generated_code_info(::PROT } if (generated_code_info) { ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = - ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper< - ::PROTOBUF_NAMESPACE_ID::MessageLite>::GetOwningArena( + ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena( reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info)); if (message_arena != submessage_arena) { generated_code_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( @@ -1761,7 +1734,7 @@ template <typename ArgT0, typename... ArgT> inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse::set_error(ArgT0&& arg0, ArgT... args) { _has_bits_[0] |= 0x00000001u; - error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); + error_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation()); // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error) } inline TProtoStringType* CodeGeneratorResponse::mutable_error() { @@ -1774,11 +1747,11 @@ inline const TProtoStringType& CodeGeneratorResponse::_internal_error() const { } inline void CodeGeneratorResponse::_internal_set_error(const TProtoStringType& value) { _has_bits_[0] |= 0x00000001u; - error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation()); + error_.Set(value, GetArenaForAllocation()); } inline TProtoStringType* CodeGeneratorResponse::_internal_mutable_error() { _has_bits_[0] |= 0x00000001u; - return error_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation()); + return error_.Mutable(GetArenaForAllocation()); } inline TProtoStringType* CodeGeneratorResponse::release_error() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.error) @@ -1786,10 +1759,10 @@ inline TProtoStringType* CodeGeneratorResponse::release_error() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - auto* p = error_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation()); + auto* p = error_.Release(); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (error_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (error_.IsDefault()) { + error_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING return p; @@ -1800,11 +1773,10 @@ inline void CodeGeneratorResponse::set_allocated_error(TProtoStringType* error) } else { _has_bits_[0] &= ~0x00000001u; } - error_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), error, - GetArenaForAllocation()); + error_.SetAllocated(error, GetArenaForAllocation()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (error_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) { - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation()); + if (error_.IsDefault()) { + error_.Set("", GetArenaForAllocation()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error) diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/python/python_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/python/python_generator.cc index ba79c25908..7c723febb3 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/python/python_generator.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/python/python_generator.cc @@ -54,13 +54,15 @@ #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/stringprintf.h> -#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/compiler/python/python_helpers.h> +#include <google/protobuf/compiler/python/python_pyi_generator.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/stringprintf.h> #include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/descriptor.pb.h> namespace google { namespace protobuf { @@ -68,22 +70,6 @@ namespace compiler { namespace python { namespace { - -TProtoStringType FixEv(const TProtoStringType& filename) { - if (HasSuffixString(filename, ".ev")) { - return StripSuffixString(filename, ".ev") + "_ev.proto"; - } - return filename; -} - -// Returns the Python module name expected for a given .proto filename. -TProtoStringType ModuleName(const TProtoStringType& filename) { - TProtoStringType basename = StripProto(FixEv(filename)); - ReplaceCharacters(&basename, "-", '_'); - ReplaceCharacters(&basename, "/", '.'); - return basename + "_pb2"; -} - // Returns the alias we assign to the module of the given .proto filename // when importing. See testPackageInitializationImport in // net/proto2/python/internal/reflection_test.py @@ -98,78 +84,18 @@ TProtoStringType ModuleAlias(const TProtoStringType& filename) { return module_name; } -// Keywords reserved by the Python language. -const char* const kKeywords[] = { - "False", "None", "True", "and", "as", "assert", - "async", "await", "break", "class", "continue", "def", - "del", "elif", "else", "except", "finally", "for", - "from", "global", "if", "import", "in", "is", - "lambda", "nonlocal", "not", "or", "pass", "raise", - "return", "try", "while", "with", "yield", "print", -}; -const char* const* kKeywordsEnd = - kKeywords + (sizeof(kKeywords) / sizeof(kKeywords[0])); - -bool ContainsPythonKeyword(const TProtoStringType& module_name) { - std::vector<TProtoStringType> tokens = Split(module_name, "."); - for (int i = 0; i < tokens.size(); ++i) { - if (std::find(kKeywords, kKeywordsEnd, tokens[i]) != kKeywordsEnd) { - return true; - } - } - return false; -} - -inline bool IsPythonKeyword(const TProtoStringType& name) { - return (std::find(kKeywords, kKeywordsEnd, name) != kKeywordsEnd); -} - -TProtoStringType ResolveKeyword(const TProtoStringType& name) { - if (IsPythonKeyword(name)) { - return "globals()['" + name + "']"; - } - return name; -} - -// Returns the name of all containing types for descriptor, -// in order from outermost to innermost, followed by descriptor's -// own name. Each name is separated by |separator|. -template <typename DescriptorT> -TProtoStringType NamePrefixedWithNestedTypes(const DescriptorT& descriptor, - const TProtoStringType& separator) { - TProtoStringType name = descriptor.name(); - const Descriptor* parent = descriptor.containing_type(); - if (parent != nullptr) { - TProtoStringType prefix = NamePrefixedWithNestedTypes(*parent, separator); - if (separator == "." && IsPythonKeyword(name)) { - return "getattr(" + prefix + ", '" + name + "')"; - } else { - return prefix + separator + name; - } - } - if (separator == ".") { - name = ResolveKeyword(name); - } - return name; -} - // Name of the class attribute where we store the Python // descriptor.Descriptor instance for the generated class. // Must stay consistent with the _DESCRIPTOR_KEY constant // in proto2/public/reflection.py. const char kDescriptorKey[] = "DESCRIPTOR"; + // Does the file have top-level enums? inline bool HasTopLevelEnums(const FileDescriptor* file) { return file->enum_type_count() > 0; } -// Should we generate generic services for this file? -inline bool HasGenericServices(const FileDescriptor* file) { - return file->service_count() > 0 && file->options().py_generic_services(); -} - -// Prints the common boilerplate needed at the top of every .py // file output by this generator. void PrintTopBoilerplate(io::Printer* printer, const FileDescriptor* file, bool descriptor_proto) { @@ -180,27 +106,16 @@ void PrintTopBoilerplate(io::Printer* printer, const FileDescriptor* file, "# source: $filename$\n" "\"\"\"Generated protocol buffer code.\"\"\"\n", "filename", file->name()); - if (HasTopLevelEnums(file)) { - printer->Print( - "from google.protobuf.internal import enum_type_wrapper\n"); - } printer->Print( + "from google.protobuf.internal import builder as _builder\n" "from google.protobuf import descriptor as _descriptor\n" "from google.protobuf import descriptor_pool as " "_descriptor_pool\n" - "from google.protobuf import message as _message\n" - "from google.protobuf import reflection as _reflection\n" "from google.protobuf import symbol_database as " "_symbol_database\n"); - if (HasGenericServices(file)) { - printer->Print( - "from google.protobuf import service as _service\n" - "from google.protobuf import service_reflection\n"); - } - printer->Print( - "# @@protoc_insertion_point(imports)\n\n" - "_sym_db = _symbol_database.Default()\n"); + printer->Print("# @@protoc_insertion_point(imports)\n\n"); + printer->Print("_sym_db = _symbol_database.Default()\n"); printer->Print("\n\n"); } @@ -315,6 +230,11 @@ bool Generator::Generate(const FileDescriptor* file, for (int i = 0; i < options.size(); i++) { if (options[i].first == "cpp_generated_lib_linked") { cpp_generated_lib_linked = true; + } else if (options[i].first == "pyi_out") { + python::PyiGenerator pyi_generator; + if (!pyi_generator.Generate(file, "", context, error)) { + return false; + } } else { *error = "Unknown generator option: " + options[i].first; return false; @@ -330,11 +250,8 @@ bool Generator::Generate(const FileDescriptor* file, // to have any mutable members. Then it is implicitly thread-safe. MutexLock lock(&mutex_); file_ = file; - TProtoStringType module_name = ModuleName(file->name()); - TProtoStringType filename = module_name; - ReplaceCharacters(&filename, ".", '/'); - filename += ".py"; + TProtoStringType filename = GetFileName(file, ".py"); pure_python_workable_ = !cpp_generated_lib_linked; if (HasPrefixString(file->name(), "google/protobuf/")) { pure_python_workable_ = true; @@ -355,15 +272,13 @@ bool Generator::Generate(const FileDescriptor* file, PrintImports(); } PrintFileDescriptor(); - PrintTopLevelEnums(); - PrintTopLevelExtensions(); if (pure_python_workable_) { if (GeneratingDescriptorProto()) { printer_->Print("if _descriptor._USE_C_DESCRIPTORS == False:\n"); printer_->Indent(); // Create enums before message descriptors - PrintAllNestedEnumsInFile(StripPrintDescriptor::kCreate); - PrintMessageDescriptors(StripPrintDescriptor::kCreate); + PrintAllNestedEnumsInFile(); + PrintMessageDescriptors(); FixForeignFieldsInDescriptors(); printer_->Outdent(); printer_->Print("else:\n"); @@ -371,16 +286,18 @@ bool Generator::Generate(const FileDescriptor* file, } // Find the message descriptors first and then use the message // descriptor to find enums. - PrintMessageDescriptors(StripPrintDescriptor::kFind); - PrintAllNestedEnumsInFile(StripPrintDescriptor::kFind); + printer_->Print( + "_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())\n"); if (GeneratingDescriptorProto()) { printer_->Outdent(); } } - PrintMessages(); + TProtoStringType module_name = ModuleName(file->name()); + printer_->Print( + "_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, '$module_name$', " + "globals())\n", + "module_name", module_name); if (pure_python_workable_) { - PrintServiceDescriptors(); - printer.Print("if _descriptor._USE_C_DESCRIPTORS == False:\n"); printer_->Indent(); @@ -401,7 +318,9 @@ bool Generator::Generate(const FileDescriptor* file, printer_->Outdent(); } if (HasGenericServices(file)) { - PrintServices(); + printer_->Print( + "_builder.BuildServices(DESCRIPTOR, '$module_name$', globals())\n", + "module_name", module_name); } printer.Print("# @@protoc_insertion_point(module_scope)\n"); @@ -409,7 +328,6 @@ bool Generator::Generate(const FileDescriptor* file, return !printer.failed(); } - // Prints Python imports for all modules imported by |file|. void Generator::PrintImports() const { for (int i = 0; i < file_->dependency_count(); ++i) { @@ -522,47 +440,17 @@ void Generator::PrintFileDescriptor() const { printer_->Print("\n"); } -// Prints descriptors and module-level constants for all top-level -// enums defined in |file|. -void Generator::PrintTopLevelEnums() const { - std::vector<std::pair<TProtoStringType, int> > top_level_enum_values; - for (int i = 0; i < file_->enum_type_count(); ++i) { - const EnumDescriptor& enum_descriptor = *file_->enum_type(i); - PrintFindEnum(enum_descriptor); - printer_->Print( - "$name$ = " - "enum_type_wrapper.EnumTypeWrapper($descriptor_name$)", - "name", ResolveKeyword(enum_descriptor.name()), "descriptor_name", - ModuleLevelDescriptorName(enum_descriptor)); - printer_->Print("\n"); - - for (int j = 0; j < enum_descriptor.value_count(); ++j) { - const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(j); - top_level_enum_values.push_back( - std::make_pair(value_descriptor.name(), value_descriptor.number())); - } - } - - for (int i = 0; i < top_level_enum_values.size(); ++i) { - printer_->Print("$name$ = $value$\n", "name", - ResolveKeyword(top_level_enum_values[i].first), "value", - StrCat(top_level_enum_values[i].second)); - } - printer_->Print("\n"); -} - // Prints all enums contained in all message types in |file|. -void Generator::PrintAllNestedEnumsInFile( - StripPrintDescriptor print_mode) const { +void Generator::PrintAllNestedEnumsInFile() const { for (int i = 0; i < file_->message_type_count(); ++i) { - PrintNestedEnums(*file_->message_type(i), print_mode); + PrintNestedEnums(*file_->message_type(i)); } } // Prints a Python statement assigning the appropriate module-level // enum name to a Python EnumDescriptor object equivalent to // enum_descriptor. -void Generator::PrintCreateEnum(const EnumDescriptor& enum_descriptor) const { +void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { std::map<TProtoStringType, TProtoStringType> m; TProtoStringType module_level_descriptor_name = ModuleLevelDescriptorName(enum_descriptor); @@ -606,68 +494,23 @@ void Generator::PrintCreateEnum(const EnumDescriptor& enum_descriptor) const { printer_->Print("\n"); } -void Generator::PrintFindEnum(const EnumDescriptor& enum_descriptor) const { - std::map<TProtoStringType, TProtoStringType> m; - m["descriptor_name"] = ModuleLevelDescriptorName(enum_descriptor); - m["name"] = enum_descriptor.name(); - m["file"] = kDescriptorKey; - if (enum_descriptor.containing_type()) { - m["containing_type"] = - ModuleLevelDescriptorName(*enum_descriptor.containing_type()); - printer_->Print(m, - "$descriptor_name$ = " - "$containing_type$.enum_types_by_name['$name$']\n"); - } else { - printer_->Print( - m, "$descriptor_name$ = $file$.enum_types_by_name['$name$']\n"); - } -} - // Recursively prints enums in nested types within descriptor, then // prints enums contained at the top level in descriptor. -void Generator::PrintNestedEnums(const Descriptor& descriptor, - StripPrintDescriptor print_mode) const { +void Generator::PrintNestedEnums(const Descriptor& descriptor) const { for (int i = 0; i < descriptor.nested_type_count(); ++i) { - PrintNestedEnums(*descriptor.nested_type(i), print_mode); + PrintNestedEnums(*descriptor.nested_type(i)); } for (int i = 0; i < descriptor.enum_type_count(); ++i) { - if (print_mode == StripPrintDescriptor::kCreate) { - PrintCreateEnum(*descriptor.enum_type(i)); - } else { - PrintFindEnum(*descriptor.enum_type(i)); - } + PrintEnum(*descriptor.enum_type(i)); } } -void Generator::PrintTopLevelExtensions() const { - for (int i = 0; i < file_->extension_count(); ++i) { - const FieldDescriptor& extension_field = *file_->extension(i); - TProtoStringType constant_name = extension_field.name() + "_FIELD_NUMBER"; - ToUpper(&constant_name); - printer_->Print("$constant_name$ = $number$\n", "constant_name", - constant_name, "number", - StrCat(extension_field.number())); - printer_->Print( - "$resolved_name$ = " - "$file$.extensions_by_name['$name$']\n", - "resolved_name", ResolveKeyword(extension_field.name()), "file", - kDescriptorKey, "name", extension_field.name()); - } - printer_->Print("\n"); -} - // Prints Python equivalents of all Descriptors in |file|. -void Generator::PrintMessageDescriptors(StripPrintDescriptor print_mode) const { - if (print_mode == StripPrintDescriptor::kCreate) { - for (int i = 0; i < file_->message_type_count(); ++i) { - PrintCreateDescriptor(*file_->message_type(i)); - printer_->Print("\n"); - } - } else { - for (int i = 0; i < file_->message_type_count(); ++i) { - PrintFindDescriptor(*file_->message_type(i)); - } +void Generator::PrintMessageDescriptors() const { + for (int i = 0; i < file_->message_type_count(); ++i) { + PrintDescriptor(*file_->message_type(i)); + printer_->Print("\n"); } } @@ -736,14 +579,13 @@ void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const { // to a Python Descriptor object for message_descriptor. // // Mutually recursive with PrintNestedDescriptors(). -void Generator::PrintCreateDescriptor( - const Descriptor& message_descriptor) const { +void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { std::map<TProtoStringType, TProtoStringType> m; m["name"] = message_descriptor.name(); m["full_name"] = message_descriptor.full_name(); m["file"] = kDescriptorKey; - PrintNestedDescriptors(message_descriptor, StripPrintDescriptor::kCreate); + PrintNestedDescriptors(message_descriptor); printer_->Print("\n"); printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n", @@ -829,41 +671,14 @@ void Generator::PrintCreateDescriptor( printer_->Print(")\n"); } -void Generator::PrintFindDescriptor( - const Descriptor& message_descriptor) const { - std::map<TProtoStringType, TProtoStringType> m; - m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor); - m["name"] = message_descriptor.name(); - - if (message_descriptor.containing_type()) { - m["containing_type"] = - ModuleLevelDescriptorName(*message_descriptor.containing_type()); - printer_->Print(m, - "$descriptor_name$ = " - "$containing_type$.nested_types_by_name['$name$']\n"); - } else { - m["file"] = kDescriptorKey; - printer_->Print( - m, "$descriptor_name$ = $file$.message_types_by_name['$name$']\n"); - } - - PrintNestedDescriptors(message_descriptor, StripPrintDescriptor::kFind); -} - // Prints Python Descriptor objects for all nested types contained in // message_descriptor. // // Mutually recursive with PrintDescriptor(). -void Generator::PrintNestedDescriptors(const Descriptor& containing_descriptor, - StripPrintDescriptor print_mode) const { - if (print_mode == StripPrintDescriptor::kCreate) { - for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { - PrintCreateDescriptor(*containing_descriptor.nested_type(i)); - } - } else { - for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { - PrintFindDescriptor(*containing_descriptor.nested_type(i)); - } +void Generator::PrintNestedDescriptors( + const Descriptor& containing_descriptor) const { + for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { + PrintDescriptor(*containing_descriptor.nested_type(i)); } } @@ -1469,7 +1284,7 @@ void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const { if (value_options != "None") { PrintDescriptorOptionsFixingCode( StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(), - value_descriptor.name().c_str()), + value_descriptor.name().c_str()), value_options, printer_); } } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/python/python_generator.h b/contrib/libs/protoc/src/google/protobuf/compiler/python/python_generator.h index d5af959fce..359d802aee 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/python/python_generator.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/python/python_generator.h @@ -40,6 +40,7 @@ #include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/stubs/mutex.h> +// Must be included last. #include <google/protobuf/port_def.inc> namespace google { @@ -59,8 +60,6 @@ class Printer; namespace compiler { namespace python { -enum class StripPrintDescriptor { kCreate, kFind }; - // CodeGenerator implementation for generated Python protocol buffer classes. // If you create your own protocol compiler binary and you want it to support // Python output, you can do so by registering an instance of this @@ -68,7 +67,7 @@ enum class StripPrintDescriptor { kCreate, kFind }; class PROTOC_EXPORT Generator : public CodeGenerator { public: Generator(); - virtual ~Generator(); + ~Generator() override; // CodeGenerator methods. bool Generate(const FileDescriptor* file, const TProtoStringType& parameter, @@ -80,14 +79,9 @@ class PROTOC_EXPORT Generator : public CodeGenerator { private: void PrintImports() const; void PrintFileDescriptor() const; - void PrintTopLevelEnums() const; - void PrintAllNestedEnumsInFile(StripPrintDescriptor print_mode) const; - void PrintNestedEnums(const Descriptor& descriptor, - StripPrintDescriptor print_mode) const; - void PrintCreateEnum(const EnumDescriptor& enum_descriptor) const; - void PrintFindEnum(const EnumDescriptor& enum_descriptor) const; - - void PrintTopLevelExtensions() const; + void PrintAllNestedEnumsInFile() const; + void PrintNestedEnums(const Descriptor& descriptor) const; + void PrintEnum(const EnumDescriptor& enum_descriptor) const; void PrintFieldDescriptor(const FieldDescriptor& field, bool is_extension) const; @@ -97,11 +91,9 @@ class PROTOC_EXPORT Generator : public CodeGenerator { const FieldDescriptor* (Descriptor::*GetterFn)(int)const) const; void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const; void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const; - void PrintMessageDescriptors(StripPrintDescriptor print_mode) const; - void PrintCreateDescriptor(const Descriptor& message_descriptor) const; - void PrintFindDescriptor(const Descriptor& message_descriptor) const; - void PrintNestedDescriptors(const Descriptor& containing_descriptor, - StripPrintDescriptor print_mode) const; + void PrintMessageDescriptors() const; + void PrintDescriptor(const Descriptor& message_descriptor) const; + void PrintNestedDescriptors(const Descriptor& containing_descriptor) const; void PrintMessages() const; void PrintMessage(const Descriptor& message_descriptor, diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/python/python_helpers.cc b/contrib/libs/protoc/src/google/protobuf/compiler/python/python_helpers.cc new file mode 100644 index 0000000000..7a9721c02c --- /dev/null +++ b/contrib/libs/protoc/src/google/protobuf/compiler/python/python_helpers.cc @@ -0,0 +1,138 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/compiler/python/python_helpers.h> + +#include <algorithm> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/descriptor.pb.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace python { + +TProtoStringType FixEv(const TProtoStringType& filename) { + if (HasSuffixString(filename, ".ev")) { + return StripSuffixString(filename, ".ev") + "_ev.proto"; + } + return filename; +} + +// Returns the Python module name expected for a given .proto filename. +TProtoStringType ModuleName(const TProtoStringType& filename) { + TProtoStringType basename = StripProto(FixEv(filename)); + ReplaceCharacters(&basename, "-", '_'); + ReplaceCharacters(&basename, "/", '.'); + return basename + "_pb2"; +} + +TProtoStringType StrippedModuleName(const TProtoStringType& filename) { + TProtoStringType module_name = ModuleName(filename); + return module_name; +} + +// Keywords reserved by the Python language. +const char* const kKeywords[] = { + "False", "None", "True", "and", "as", "assert", + "async", "await", "break", "class", "continue", "def", + "del", "elif", "else", "except", "finally", "for", + "from", "global", "if", "import", "in", "is", + "lambda", "nonlocal", "not", "or", "pass", "raise", + "return", "try", "while", "with", "yield", "print", +}; +const char* const* kKeywordsEnd = + kKeywords + (sizeof(kKeywords) / sizeof(kKeywords[0])); + +bool ContainsPythonKeyword(const TProtoStringType& module_name) { + std::vector<TProtoStringType> tokens = Split(module_name, "."); + for (int i = 0; i < static_cast<int>(tokens.size()); ++i) { + if (std::find(kKeywords, kKeywordsEnd, tokens[i]) != kKeywordsEnd) { + return true; + } + } + return false; +} + +bool IsPythonKeyword(const TProtoStringType& name) { + return (std::find(kKeywords, kKeywordsEnd, name) != kKeywordsEnd); +} + +TProtoStringType ResolveKeyword(const TProtoStringType& name) { + if (IsPythonKeyword(name)) { + return "globals()['" + name + "']"; + } + return name; +} + +TProtoStringType GetFileName(const FileDescriptor* file_des, + const TProtoStringType& suffix) { + TProtoStringType module_name = ModuleName(file_des->name()); + TProtoStringType filename = module_name; + ReplaceCharacters(&filename, ".", '/'); + filename += suffix; + return filename; +} + +bool HasGenericServices(const FileDescriptor* file) { + return file->service_count() > 0 && file->options().py_generic_services(); +} + +template <typename DescriptorT> +TProtoStringType NamePrefixedWithNestedTypes(const DescriptorT& descriptor, + const TProtoStringType& separator) { + TProtoStringType name = descriptor.name(); + const Descriptor* parent = descriptor.containing_type(); + if (parent != nullptr) { + TProtoStringType prefix = NamePrefixedWithNestedTypes(*parent, separator); + if (separator == "." && IsPythonKeyword(name)) { + return "getattr(" + prefix + ", '" + name + "')"; + } else { + return prefix + separator + name; + } + } + if (separator == ".") { + name = ResolveKeyword(name); + } + return name; +} + +template TProtoStringType NamePrefixedWithNestedTypes<Descriptor>( + const Descriptor& descriptor, const TProtoStringType& separator); +template TProtoStringType NamePrefixedWithNestedTypes<EnumDescriptor>( + const EnumDescriptor& descriptor, const TProtoStringType& separator); + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/python/python_helpers.h b/contrib/libs/protoc/src/google/protobuf/compiler/python/python_helpers.h new file mode 100644 index 0000000000..8745698acf --- /dev/null +++ b/contrib/libs/protoc/src/google/protobuf/compiler/python/python_helpers.h @@ -0,0 +1,62 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_HELPERS_H__ +#define GOOGLE_PROTOBUF_COMPILER_PYTHON_HELPERS_H__ + +#include <string> + +#include <google/protobuf/descriptor.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace python { + + +TProtoStringType ModuleName(const TProtoStringType& filename); +TProtoStringType StrippedModuleName(const TProtoStringType& filename); +bool ContainsPythonKeyword(const TProtoStringType& module_name); +bool IsPythonKeyword(const TProtoStringType& name); +TProtoStringType ResolveKeyword(const TProtoStringType& name); +TProtoStringType GetFileName(const FileDescriptor* file_des, + const TProtoStringType& suffix); +bool HasGenericServices(const FileDescriptor* file); + +template <typename DescriptorT> +TProtoStringType NamePrefixedWithNestedTypes(const DescriptorT& descriptor, + const TProtoStringType& separator); + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_HELPERS_H__ diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/python/python_pyi_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/python/python_pyi_generator.cc new file mode 100644 index 0000000000..89cfbf86fe --- /dev/null +++ b/contrib/libs/protoc/src/google/protobuf/compiler/python/python_pyi_generator.cc @@ -0,0 +1,558 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/compiler/python/python_pyi_generator.h> + +#include <string> + +#include <google/protobuf/compiler/python/python_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/descriptor.pb.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace python { + +template <typename DescriptorT> +struct SortByName { + bool operator()(const DescriptorT* l, const DescriptorT* r) const { + return l->name() < r->name(); + } +}; + +PyiGenerator::PyiGenerator() : file_(nullptr) {} + +PyiGenerator::~PyiGenerator() {} + +void PyiGenerator::PrintItemMap( + const std::map<TProtoStringType, TProtoStringType>& item_map) const { + for (const auto& entry : item_map) { + printer_->Print("$key$: $value$\n", "key", entry.first, "value", + entry.second); + } +} + +template <typename DescriptorT> +TProtoStringType PyiGenerator::ModuleLevelName(const DescriptorT& descriptor) const { + TProtoStringType name = NamePrefixedWithNestedTypes(descriptor, "."); + if (descriptor.file() != file_) { + TProtoStringType module_name = ModuleName(descriptor.file()->name()); + std::vector<TProtoStringType> tokens = Split(module_name, "."); + name = "_" + tokens.back() + "." + name; + } + return name; +} + +struct ImportModules { + bool has_repeated = false; // _containers + bool has_iterable = false; // typing.Iterable + bool has_messages = false; // _message + bool has_enums = false; // _enum_type_wrapper + bool has_extendable = false; // _python_message + bool has_mapping = false; // typing.Mapping + bool has_optional = false; // typing.Optional + bool has_union = false; // typing.Uion +}; + +// Checks what modules should be imported for this message +// descriptor. +void CheckImportModules(const Descriptor* descriptor, + ImportModules* import_modules) { + if (descriptor->extension_range_count() > 0) { + import_modules->has_extendable = true; + } + if (descriptor->enum_type_count() > 0) { + import_modules->has_enums = true; + } + for (int i = 0; i < descriptor->field_count(); ++i) { + const FieldDescriptor* field = descriptor->field(i); + if (IsPythonKeyword(field->name())) { + continue; + } + import_modules->has_optional = true; + if (field->is_repeated()) { + import_modules->has_repeated = true; + } + if (field->is_map()) { + import_modules->has_mapping = true; + const FieldDescriptor* value_des = field->message_type()->field(1); + if (value_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || + value_des->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + import_modules->has_union = true; + } + } else { + if (field->is_repeated()) { + import_modules->has_iterable = true; + } + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + import_modules->has_union = true; + import_modules->has_mapping = true; + } + if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + import_modules->has_union = true; + } + } + } + for (int i = 0; i < descriptor->nested_type_count(); ++i) { + CheckImportModules(descriptor->nested_type(i), import_modules); + } +} + +void PyiGenerator::PrintImports( + std::map<TProtoStringType, TProtoStringType>* item_map) const { + // Prints imported dependent _pb2 files. + for (int i = 0; i < file_->dependency_count(); ++i) { + const TProtoStringType& filename = file_->dependency(i)->name(); + TProtoStringType module_name = StrippedModuleName(filename); + size_t last_dot_pos = module_name.rfind('.'); + TProtoStringType import_statement; + if (last_dot_pos == TProtoStringType::npos) { + import_statement = "import " + module_name; + } else { + import_statement = "from " + module_name.substr(0, last_dot_pos) + + " import " + module_name.substr(last_dot_pos + 1); + module_name = module_name.substr(last_dot_pos + 1); + } + printer_->Print("$statement$ as _$module_name$\n", "statement", + import_statement, "module_name", module_name); + } + + // Checks what modules should be imported. + ImportModules import_modules; + if (file_->message_type_count() > 0) { + import_modules.has_messages = true; + } + if (file_->enum_type_count() > 0) { + import_modules.has_enums = true; + } + for (int i = 0; i < file_->message_type_count(); i++) { + CheckImportModules(file_->message_type(i), &import_modules); + } + + // Prints modules (e.g. _containers, _messages, typing) that are + // required in the proto file. + if (import_modules.has_repeated) { + printer_->Print( + "from google.protobuf.internal import containers as " + "_containers\n"); + } + if (import_modules.has_enums) { + printer_->Print( + "from google.protobuf.internal import enum_type_wrapper" + " as _enum_type_wrapper\n"); + } + if (import_modules.has_extendable) { + printer_->Print( + "from google.protobuf.internal import python_message" + " as _python_message\n"); + } + printer_->Print( + "from google.protobuf import" + " descriptor as _descriptor\n"); + if (import_modules.has_messages) { + printer_->Print( + "from google.protobuf import message as _message\n"); + } + if (HasGenericServices(file_)) { + printer_->Print( + "from google.protobuf import service as" + " _service\n"); + } + printer_->Print("from typing import "); + printer_->Print("ClassVar"); + if (import_modules.has_iterable) { + printer_->Print(", Iterable"); + } + if (import_modules.has_mapping) { + printer_->Print(", Mapping"); + } + if (import_modules.has_optional) { + printer_->Print(", Optional"); + } + if (file_->service_count() > 0) { + printer_->Print(", Text"); + } + if (import_modules.has_union) { + printer_->Print(", Union"); + } + printer_->Print("\n\n"); + + // Public imports + for (int i = 0; i < file_->public_dependency_count(); ++i) { + const FileDescriptor* public_dep = file_->public_dependency(i); + TProtoStringType module_name = StrippedModuleName(public_dep->name()); + // Top level messages in public imports + for (int i = 0; i < public_dep->message_type_count(); ++i) { + printer_->Print("from $module$ import $message_class$\n", "module", + module_name, "message_class", + public_dep->message_type(i)->name()); + } + // Top level enums for public imports + for (int i = 0; i < public_dep->enum_type_count(); ++i) { + printer_->Print("from $module$ import $enum_class$\n", "module", + module_name, "enum_class", + public_dep->enum_type(i)->name()); + } + // Enum values for public imports + for (int i = 0; i < public_dep->enum_type_count(); ++i) { + const EnumDescriptor* enum_descriptor = public_dep->enum_type(i); + for (int j = 0; j < enum_descriptor->value_count(); ++j) { + (*item_map)[enum_descriptor->value(j)->name()] = + ModuleLevelName(*enum_descriptor); + } + } + // Top level extensions for public imports + AddExtensions(*public_dep, item_map); + } +} + +void PyiGenerator::PrintEnum(const EnumDescriptor& enum_descriptor) const { + TProtoStringType enum_name = enum_descriptor.name(); + printer_->Print( + "class $enum_name$(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):\n" + " __slots__ = []\n", + "enum_name", enum_name); +} + +// Adds enum value to item map which will be ordered and printed later. +void PyiGenerator::AddEnumValue( + const EnumDescriptor& enum_descriptor, + std::map<TProtoStringType, TProtoStringType>* item_map) const { + // enum values + TProtoStringType module_enum_name = ModuleLevelName(enum_descriptor); + for (int j = 0; j < enum_descriptor.value_count(); ++j) { + const EnumValueDescriptor* value_descriptor = enum_descriptor.value(j); + (*item_map)[value_descriptor->name()] = module_enum_name; + } +} + +// Prints top level enums +void PyiGenerator::PrintTopLevelEnums() const { + for (int i = 0; i < file_->enum_type_count(); ++i) { + printer_->Print("\n"); + PrintEnum(*file_->enum_type(i)); + } +} + +// Add top level extensions to item_map which will be ordered and +// printed later. +template <typename DescriptorT> +void PyiGenerator::AddExtensions( + const DescriptorT& descriptor, + std::map<TProtoStringType, TProtoStringType>* item_map) const { + for (int i = 0; i < descriptor.extension_count(); ++i) { + const FieldDescriptor* extension_field = descriptor.extension(i); + TProtoStringType constant_name = extension_field->name() + "_FIELD_NUMBER"; + ToUpper(&constant_name); + (*item_map)[constant_name] = "ClassVar[int]"; + (*item_map)[extension_field->name()] = "_descriptor.FieldDescriptor"; + } +} + +// Returns the string format of a field's cpp_type +TProtoStringType PyiGenerator::GetFieldType(const FieldDescriptor& field_des) const { + switch (field_des.cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + case FieldDescriptor::CPPTYPE_UINT32: + case FieldDescriptor::CPPTYPE_INT64: + case FieldDescriptor::CPPTYPE_UINT64: + return "int"; + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + return "float"; + case FieldDescriptor::CPPTYPE_BOOL: + return "bool"; + case FieldDescriptor::CPPTYPE_ENUM: + return ModuleLevelName(*field_des.enum_type()); + case FieldDescriptor::CPPTYPE_STRING: + if (field_des.type() == FieldDescriptor::TYPE_STRING) { + return "str"; + } else { + return "bytes"; + } + case FieldDescriptor::CPPTYPE_MESSAGE: + return ModuleLevelName(*field_des.message_type()); + default: + GOOGLE_LOG(FATAL) << "Unsuppoted field type."; + } + return ""; +} + +void PyiGenerator::PrintMessage(const Descriptor& message_descriptor, + bool is_nested) const { + if (!is_nested) { + printer_->Print("\n"); + } + TProtoStringType class_name = message_descriptor.name(); + printer_->Print("class $class_name$(_message.Message):\n", "class_name", + class_name); + printer_->Indent(); + printer_->Indent(); + + std::vector<const FieldDescriptor*> fields; + fields.reserve(message_descriptor.field_count()); + for (int i = 0; i < message_descriptor.field_count(); ++i) { + fields.push_back(message_descriptor.field(i)); + } + std::sort(fields.begin(), fields.end(), SortByName<FieldDescriptor>()); + + // Prints slots + printer_->Print("__slots__ = [", "class_name", class_name); + bool first_item = true; + for (const auto& field_des : fields) { + if (IsPythonKeyword(field_des->name())) { + continue; + } + if (first_item) { + first_item = false; + } else { + printer_->Print(", "); + } + printer_->Print("\"$field_name$\"", "field_name", field_des->name()); + } + printer_->Print("]\n"); + + std::map<TProtoStringType, TProtoStringType> item_map; + // Prints Extensions for extendable messages + if (message_descriptor.extension_range_count() > 0) { + item_map["Extensions"] = "_python_message._ExtensionDict"; + } + + // Prints nested enums + std::vector<const EnumDescriptor*> nested_enums; + nested_enums.reserve(message_descriptor.enum_type_count()); + for (int i = 0; i < message_descriptor.enum_type_count(); ++i) { + nested_enums.push_back(message_descriptor.enum_type(i)); + } + std::sort(nested_enums.begin(), nested_enums.end(), + SortByName<EnumDescriptor>()); + + for (const auto& entry : nested_enums) { + PrintEnum(*entry); + // Adds enum value to item_map which will be ordered and printed later + AddEnumValue(*entry, &item_map); + } + + // Prints nested messages + std::vector<const Descriptor*> nested_messages; + nested_messages.reserve(message_descriptor.nested_type_count()); + for (int i = 0; i < message_descriptor.nested_type_count(); ++i) { + nested_messages.push_back(message_descriptor.nested_type(i)); + } + std::sort(nested_messages.begin(), nested_messages.end(), + SortByName<Descriptor>()); + + for (const auto& entry : nested_messages) { + PrintMessage(*entry, true); + } + + // Adds extensions to item_map which will be ordered and printed later + AddExtensions(message_descriptor, &item_map); + + // Adds field number and field descriptor to item_map + for (int i = 0; i < message_descriptor.field_count(); ++i) { + const FieldDescriptor& field_des = *message_descriptor.field(i); + item_map[ToUpper(field_des.name()) + "_FIELD_NUMBER"] = + "ClassVar[int]"; + if (IsPythonKeyword(field_des.name())) { + continue; + } + TProtoStringType field_type = ""; + if (field_des.is_map()) { + const FieldDescriptor* key_des = field_des.message_type()->field(0); + const FieldDescriptor* value_des = field_des.message_type()->field(1); + field_type = (value_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE + ? "_containers.MessageMap[" + : "_containers.ScalarMap["); + field_type += GetFieldType(*key_des); + field_type += ", "; + field_type += GetFieldType(*value_des); + } else { + if (field_des.is_repeated()) { + field_type = (field_des.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE + ? "_containers.RepeatedCompositeFieldContainer[" + : "_containers.RepeatedScalarFieldContainer["); + } + field_type += GetFieldType(field_des); + } + + if (field_des.is_repeated()) { + field_type += "]"; + } + item_map[field_des.name()] = field_type; + } + + // Prints all items in item_map + PrintItemMap(item_map); + + // Prints __init__ + printer_->Print("def __init__(self"); + bool has_key_words = false; + bool is_first = true; + for (int i = 0; i < message_descriptor.field_count(); ++i) { + const FieldDescriptor* field_des = message_descriptor.field(i); + if (IsPythonKeyword(field_des->name())) { + has_key_words = true; + continue; + } + TProtoStringType field_name = field_des->name(); + if (is_first && field_name == "self") { + // See b/144146793 for an example of real code that generates a (self, + // self) method signature. Since repeating a parameter name is illegal in + // Python, we rename the duplicate self. + field_name = "self_"; + } + is_first = false; + printer_->Print(", $field_name$: ", "field_name", field_name); + if (field_des->is_repeated() || + field_des->cpp_type() != FieldDescriptor::CPPTYPE_BOOL) { + printer_->Print("Optional["); + } + if (field_des->is_map()) { + const Descriptor* map_entry = field_des->message_type(); + printer_->Print("Mapping[$key_type$, $value_type$]", "key_type", + GetFieldType(*map_entry->field(0)), "value_type", + GetFieldType(*map_entry->field(1))); + } else { + if (field_des->is_repeated()) { + printer_->Print("Iterable["); + } + if (field_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + printer_->Print("Union[$type_name$, Mapping]", "type_name", + GetFieldType(*field_des)); + } else { + if (field_des->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + printer_->Print("Union[$type_name$, str]", "type_name", + ModuleLevelName(*field_des->enum_type())); + } else { + printer_->Print("$type_name$", "type_name", GetFieldType(*field_des)); + } + } + if (field_des->is_repeated()) { + printer_->Print("]"); + } + } + if (field_des->is_repeated() || + field_des->cpp_type() != FieldDescriptor::CPPTYPE_BOOL) { + printer_->Print("]"); + } + printer_->Print(" = ..."); + } + if (has_key_words) { + printer_->Print(", **kwargs"); + } + printer_->Print(") -> None: ...\n"); + + printer_->Outdent(); + printer_->Outdent(); +} + +void PyiGenerator::PrintMessages() const { + // Order the descriptors by name to have same output with proto_to_pyi.py + std::vector<const Descriptor*> messages; + messages.reserve(file_->message_type_count()); + for (int i = 0; i < file_->message_type_count(); ++i) { + messages.push_back(file_->message_type(i)); + } + std::sort(messages.begin(), messages.end(), SortByName<Descriptor>()); + + for (const auto& entry : messages) { + PrintMessage(*entry, false); + } +} + +void PyiGenerator::PrintServices() const { + std::vector<const ServiceDescriptor*> services; + services.reserve(file_->service_count()); + for (int i = 0; i < file_->service_count(); ++i) { + services.push_back(file_->service(i)); + } + std::sort(services.begin(), services.end(), SortByName<ServiceDescriptor>()); + + // Prints $Service$ and $Service$_Stub classes + for (const auto& entry : services) { + printer_->Print("\n"); + printer_->Print( + "class $service_name$(_service.service): ...\n\n" + "class $service_name$_Stub($service_name$): ...\n", + "service_name", entry->name()); + } +} + +bool PyiGenerator::Generate(const FileDescriptor* file, + const TProtoStringType& parameter, + GeneratorContext* context, + TProtoStringType* error) const { + MutexLock lock(&mutex_); + // Calculate file name. + file_ = file; + // proto_to_pyi.py may set the output file name directly. To replace + // proto_to_pyi.py in google3, protoc also accept --pyi_out to set + // the output file name. + TProtoStringType filename = + parameter.empty() ? GetFileName(file, ".pyi") : parameter; + + std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); + GOOGLE_CHECK(output.get()); + io::Printer printer(output.get(), '$'); + printer_ = &printer; + + // item map will store "DESCRIPTOR", top level extensions, top level enum + // values. The items will be sorted and printed later. + std::map<TProtoStringType, TProtoStringType> item_map; + + // Adds "DESCRIPTOR" into item_map. + item_map["DESCRIPTOR"] = "_descriptor.FileDescriptor"; + PrintImports(&item_map); + // Adds top level enum values to item_map. + for (int i = 0; i < file_->enum_type_count(); ++i) { + AddEnumValue(*file_->enum_type(i), &item_map); + } + // Adds top level extensions to item_map. + AddExtensions(*file_, &item_map); + // Prints item map + PrintItemMap(item_map); + + PrintMessages(); + PrintTopLevelEnums(); + if (HasGenericServices(file)) { + PrintServices(); + } + return true; +} + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/python/python_pyi_generator.h b/contrib/libs/protoc/src/google/protobuf/compiler/python/python_pyi_generator.h new file mode 100644 index 0000000000..d7f5437e49 --- /dev/null +++ b/contrib/libs/protoc/src/google/protobuf/compiler/python/python_pyi_generator.h @@ -0,0 +1,104 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jieluo@google.com (Jie Luo) +// +// Generates Python stub (.pyi) for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ + +#include <map> +#include <string> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/stubs/mutex.h> + +// Must be included last. +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +class Descriptor; +class EnumDescriptor; +class FieldDescriptor; +class MethodDescriptor; +class ServiceDescriptor; + +namespace io { +class Printer; +} + +namespace compiler { +namespace python { + +class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenerator { + public: + PyiGenerator(); + ~PyiGenerator() override; + + // CodeGenerator methods. + bool Generate(const FileDescriptor* file, const TProtoStringType& parameter, + GeneratorContext* generator_context, + TProtoStringType* error) const override; + + private: + void PrintImports(std::map<TProtoStringType, TProtoStringType>* item_map) const; + void PrintEnum(const EnumDescriptor& enum_descriptor) const; + void AddEnumValue(const EnumDescriptor& enum_descriptor, + std::map<TProtoStringType, TProtoStringType>* item_map) const; + void PrintTopLevelEnums() const; + template <typename DescriptorT> + void AddExtensions(const DescriptorT& descriptor, + std::map<TProtoStringType, TProtoStringType>* item_map) const; + void PrintMessages() const; + void PrintMessage(const Descriptor& message_descriptor, bool is_nested) const; + void PrintServices() const; + void PrintItemMap(const std::map<TProtoStringType, TProtoStringType>& item_map) const; + TProtoStringType GetFieldType(const FieldDescriptor& field_des) const; + template <typename DescriptorT> + TProtoStringType ModuleLevelName(const DescriptorT& descriptor) const; + + // Very coarse-grained lock to ensure that Generate() is reentrant. + // Guards file_ and printer_. + mutable Mutex mutex_; + mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_. + mutable io::Printer* printer_; // Set in Generate(). Under mutex_. + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PyiGenerator); +}; + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/ruby/ruby_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/ruby/ruby_generator.cc index d4b4b482d6..0e85c22f1e 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/ruby/ruby_generator.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/ruby/ruby_generator.cc @@ -421,7 +421,7 @@ int GeneratePackageModules(const FileDescriptor* file, io::Printer* printer) { // -> A.B.C if (package_name.find("::") != TProtoStringType::npos) { need_change_to_module = false; - } else { + } else if (package_name.find(".") != TProtoStringType::npos) { GOOGLE_LOG(WARNING) << "ruby_package option should be in the form of:" << " 'A::B::C' and not 'A.B.C'"; } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/scc.h b/contrib/libs/protoc/src/google/protobuf/compiler/scc.h index a1394602f7..7b95689d7a 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/scc.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/scc.h @@ -37,6 +37,7 @@ #include <google/protobuf/stubs/common.h> #include <google/protobuf/descriptor.h> +// Must be included last. #include <google/protobuf/port_def.inc> namespace google { diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/subprocess.cc b/contrib/libs/protoc/src/google/protobuf/compiler/subprocess.cc index 9a660733b3..1d01fb7e83 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/subprocess.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/subprocess.cc @@ -55,7 +55,7 @@ namespace compiler { namespace { char* portable_strdup(const char* s) { char* ns = (char*)malloc(strlen(s) + 1); - if (ns != NULL) { + if (ns != nullptr) { strcpy(ns, s); } return ns; @@ -73,15 +73,15 @@ static void CloseHandleOrDie(HANDLE handle) { Subprocess::Subprocess() : process_start_error_(ERROR_SUCCESS), - child_handle_(NULL), - child_stdin_(NULL), - child_stdout_(NULL) {} + child_handle_(nullptr), + child_stdin_(nullptr), + child_stdout_(nullptr) {} Subprocess::~Subprocess() { - if (child_stdin_ != NULL) { + if (child_stdin_ != nullptr) { CloseHandleOrDie(child_stdin_); } - if (child_stdout_ != NULL) { + if (child_stdout_ != nullptr) { CloseHandleOrDie(child_stdout_); } } @@ -93,10 +93,10 @@ void Subprocess::Start(const TProtoStringType& program, SearchMode search_mode) HANDLE stdout_pipe_read; HANDLE stdout_pipe_write; - if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, NULL, 0)) { + if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, nullptr, 0)) { GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError()); } - if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, NULL, 0)) { + if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, nullptr, 0)) { GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError()); } @@ -134,14 +134,14 @@ void Subprocess::Start(const TProtoStringType& program, SearchMode search_mode) // Create the process. PROCESS_INFORMATION process_info; - if (CreateProcessA((search_mode == SEARCH_PATH) ? NULL : program.c_str(), - (search_mode == SEARCH_PATH) ? command_line : NULL, - NULL, // process security attributes - NULL, // thread security attributes - TRUE, // inherit handles? - 0, // obscure creation flags - NULL, // environment (inherit from parent) - NULL, // current directory (inherit from parent) + if (CreateProcessA((search_mode == SEARCH_PATH) ? nullptr : program.c_str(), + (search_mode == SEARCH_PATH) ? command_line : nullptr, + nullptr, // process security attributes + nullptr, // thread security attributes + TRUE, // inherit handles? + 0, // obscure creation flags + nullptr, // environment (inherit from parent) + nullptr, // current directory (inherit from parent) &startup_info, &process_info)) { child_handle_ = process_info.hProcess; CloseHandleOrDie(process_info.hThread); @@ -165,28 +165,28 @@ bool Subprocess::Communicate(const Message& input, Message* output, return false; } - GOOGLE_CHECK(child_handle_ != NULL) << "Must call Start() first."; + GOOGLE_CHECK(child_handle_ != nullptr) << "Must call Start() first."; TProtoStringType input_data = input.SerializeAsString(); TProtoStringType output_data; int input_pos = 0; - while (child_stdout_ != NULL) { + while (child_stdout_ != nullptr) { HANDLE handles[2]; int handle_count = 0; - if (child_stdin_ != NULL) { + if (child_stdin_ != nullptr) { handles[handle_count++] = child_stdin_; } - if (child_stdout_ != NULL) { + if (child_stdout_ != nullptr) { handles[handle_count++] = child_stdout_; } DWORD wait_result = WaitForMultipleObjects(handle_count, handles, FALSE, INFINITE); - HANDLE signaled_handle = NULL; + HANDLE signaled_handle = nullptr; if (wait_result >= WAIT_OBJECT_0 && wait_result < WAIT_OBJECT_0 + handle_count) { signaled_handle = handles[wait_result - WAIT_OBJECT_0]; @@ -201,7 +201,7 @@ bool Subprocess::Communicate(const Message& input, Message* output, if (signaled_handle == child_stdin_) { DWORD n; if (!WriteFile(child_stdin_, input_data.data() + input_pos, - input_data.size() - input_pos, &n, NULL)) { + input_data.size() - input_pos, &n, nullptr)) { // Child closed pipe. Presumably it will report an error later. // Pretend we're done for now. input_pos = input_data.size(); @@ -212,27 +212,27 @@ bool Subprocess::Communicate(const Message& input, Message* output, if (input_pos == input_data.size()) { // We're done writing. Close. CloseHandleOrDie(child_stdin_); - child_stdin_ = NULL; + child_stdin_ = nullptr; } } else if (signaled_handle == child_stdout_) { char buffer[4096]; DWORD n; - if (!ReadFile(child_stdout_, buffer, sizeof(buffer), &n, NULL)) { + if (!ReadFile(child_stdout_, buffer, sizeof(buffer), &n, nullptr)) { // We're done reading. Close. CloseHandleOrDie(child_stdout_); - child_stdout_ = NULL; + child_stdout_ = nullptr; } else { output_data.append(buffer, n); } } } - if (child_stdin_ != NULL) { + if (child_stdin_ != nullptr) { // Child did not finish reading input before it closed the output. // Presumably it exited with an error. CloseHandleOrDie(child_stdin_); - child_stdin_ = NULL; + child_stdin_ = nullptr; } DWORD wait_result = WaitForSingleObject(child_handle_, INFINITE); @@ -252,7 +252,7 @@ bool Subprocess::Communicate(const Message& input, Message* output, } CloseHandleOrDie(child_handle_); - child_handle_ = NULL; + child_handle_ = nullptr; if (exit_code != 0) { *error = strings::Substitute("Plugin failed with status code $0.", exit_code); @@ -273,9 +273,10 @@ TProtoStringType Subprocess::Win32ErrorMessage(DWORD error_code) { // WTF? FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, error_code, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + nullptr, error_code, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPSTR)&message, // NOT A BUG! - 0, NULL); + 0, nullptr); TProtoStringType result = message; LocalFree(message); @@ -309,7 +310,7 @@ void Subprocess::Start(const TProtoStringType& program, SearchMode search_mode) GOOGLE_CHECK(pipe(stdin_pipe) != -1); GOOGLE_CHECK(pipe(stdout_pipe) != -1); - char* argv[2] = {portable_strdup(program.c_str()), NULL}; + char* argv[2] = {portable_strdup(program.c_str()), nullptr}; child_pid_ = fork(); if (child_pid_ == -1) { @@ -386,7 +387,7 @@ bool Subprocess::Communicate(const Message& input, Message* output, FD_SET(child_stdin_, &write_fds); } - if (select(max_fd + 1, &read_fds, &write_fds, NULL, NULL) < 0) { + if (select(max_fd + 1, &read_fds, &write_fds, nullptr, nullptr) < 0) { if (errno == EINTR) { // Interrupted by signal. Try again. continue; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/subprocess.h b/contrib/libs/protoc/src/google/protobuf/compiler/subprocess.h index ed9790f9b5..a6a320ab47 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/subprocess.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/subprocess.h @@ -46,6 +46,7 @@ #include <string> +// Must be included last. #include <google/protobuf/port_def.inc> namespace google { |