diff options
author | pg <pg@yandex-team.com> | 2023-02-08 14:47:59 +0300 |
---|---|---|
committer | pg <pg@yandex-team.com> | 2023-02-08 14:47:59 +0300 |
commit | 2999295666a93b51c9226cee88ea70b996d43727 (patch) | |
tree | 6cd1a5290a2653689a33c6269c0eebb7dd05729d /contrib/libs/protoc/src/google/protobuf/compiler/cpp | |
parent | e615f3f87f0fc3dcc0d45c304883339ab1eab8c1 (diff) | |
download | ydb-2999295666a93b51c9226cee88ea70b996d43727.tar.gz |
3.19.0
Diffstat (limited to 'contrib/libs/protoc/src/google/protobuf/compiler/cpp')
22 files changed, 332 insertions, 346 deletions
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_enum.cc index 263dff4079..4ecd6a9cf7 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 @@ -409,10 +409,10 @@ void EnumGenerator::GenerateMethods(int idx, io::Printer* printer) { 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. - // But pre-2015 MSVC++ insists that we not. + // But MSVC++ pre-2015 and post-2017 (version 15.5+) insists that we not. format( "#if (__cplusplus < 201703) && " - "(!defined(_MSC_VER) || _MSC_VER >= 1900)\n"); + "(!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))\n"); for (int i = 0; i < descriptor_->value_count(); i++) { format("constexpr $classname$ $1$::$2$;\n", parent, @@ -428,7 +428,7 @@ void EnumGenerator::GenerateMethods(int idx, io::Printer* printer) { format( "#endif // (__cplusplus < 201703) && " - "(!defined(_MSC_VER) || _MSC_VER >= 1900)\n"); + "(!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))\n"); } } 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 ce2a0e4591..79fa488b5f 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 @@ -334,106 +334,6 @@ void RepeatedEnumFieldGenerator::GenerateConstructorCode( // Not needed for repeated fields. } -void RepeatedEnumFieldGenerator::GenerateMergeFromCodedStream( - io::Printer* printer) const { - Formatter format(printer, variables_); - // Don't use ReadRepeatedPrimitive here so that the enum can be validated. - format( - "int value = 0;\n" - "DO_((::$proto_ns$::internal::WireFormatLite::ReadPrimitive<\n" - " int, ::$proto_ns$::internal::WireFormatLite::TYPE_ENUM>(\n" - " input, &value)));\n"); - if (HasPreservingUnknownEnumSemantics(descriptor_)) { - format("add_$name$(static_cast< $type$ >(value));\n"); - } else { - format( - "if ($type$_IsValid(value)) {\n" - " add_$name$(static_cast< $type$ >(value));\n"); - if (UseUnknownFieldSet(descriptor_->file(), options_)) { - format( - "} else {\n" - " mutable_unknown_fields()->AddVarint(\n" - " $number$, static_cast<$uint64$>(value));\n"); - } else { - format( - "} else {\n" - " unknown_fields_stream.WriteVarint32(tag);\n" - " unknown_fields_stream.WriteVarint32(\n" - " static_cast<$uint32$>(value));\n"); - } - format("}\n"); - } -} - -void RepeatedEnumFieldGenerator::GenerateMergeFromCodedStreamWithPacking( - io::Printer* printer) const { - Formatter format(printer, variables_); - if (!descriptor_->is_packed()) { - // This path is rarely executed, so we use a non-inlined implementation. - if (HasPreservingUnknownEnumSemantics(descriptor_)) { - format( - "DO_((::$proto_ns$::internal::" - "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n" - " input,\n" - " $number$,\n" - " nullptr,\n" - " nullptr,\n" - " this->_internal_mutable_$name$())));\n"); - } else if (UseUnknownFieldSet(descriptor_->file(), options_)) { - format( - "DO_((::$proto_ns$::internal::WireFormat::" - "ReadPackedEnumPreserveUnknowns(\n" - " input,\n" - " $number$,\n" - " $type$_IsValid,\n" - " mutable_unknown_fields(),\n" - " this->_internal_mutable_$name$())));\n"); - } else { - format( - "DO_((::$proto_ns$::internal::" - "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n" - " input,\n" - " $number$,\n" - " $type$_IsValid,\n" - " &unknown_fields_stream,\n" - " this->_internal_mutable_$name$())));\n"); - } - } else { - format( - "$uint32$ length;\n" - "DO_(input->ReadVarint32(&length));\n" - "::$proto_ns$::io::CodedInputStream::Limit limit = " - "input->PushLimit(static_cast<int>(length));\n" - "while (input->BytesUntilLimit() > 0) {\n" - " int value = 0;\n" - " DO_((::$proto_ns$::internal::WireFormatLite::ReadPrimitive<\n" - " int, ::$proto_ns$::internal::WireFormatLite::TYPE_ENUM>(\n" - " input, &value)));\n"); - if (HasPreservingUnknownEnumSemantics(descriptor_)) { - format(" add_$name$(static_cast< $type$ >(value));\n"); - } else { - format( - " if ($type$_IsValid(value)) {\n" - " _internal_add_$name$(static_cast< $type$ >(value));\n" - " } else {\n"); - if (UseUnknownFieldSet(descriptor_->file(), options_)) { - format( - " mutable_unknown_fields()->AddVarint(\n" - " $number$, static_cast<$uint64$>(value));\n"); - } else { - format( - " unknown_fields_stream.WriteVarint32(tag);\n" - " unknown_fields_stream.WriteVarint32(\n" - " static_cast<$uint32$>(value));\n"); - } - format(" }\n"); - } - format( - "}\n" - "input->PopLimit(limit);\n"); - } -} - void RepeatedEnumFieldGenerator::GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const { Formatter format(printer, variables_); 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 793ab2d793..e65ec0f5c0 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 @@ -98,8 +98,6 @@ class RepeatedEnumFieldGenerator : public FieldGenerator { void GenerateSwappingCode(io::Printer* printer) const override; void GenerateConstructorCode(io::Printer* printer) const override; void GenerateCopyConstructorCode(io::Printer* printer) const override {} - void GenerateMergeFromCodedStream(io::Printer* printer) const; - void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const; 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_extension.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/cpp_extension.cc index 23ab1bc0bb..72893b81c9 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 @@ -44,18 +44,6 @@ namespace protobuf { namespace compiler { namespace cpp { -namespace { - -// Returns the fully-qualified class name of the message that this field -// extends. This function is used in the Google-internal code to handle some -// legacy cases. -TProtoStringType ExtendeeClassName(const FieldDescriptor* descriptor) { - const Descriptor* extendee = descriptor->containing_type(); - return ClassName(extendee, true); -} - -} // anonymous namespace - ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, const Options& options, MessageSCCAnalyzer* scc_analyzer) @@ -88,7 +76,8 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, break; } SetCommonVars(options, &variables_); - variables_["extendee"] = ExtendeeClassName(descriptor_); + variables_["extendee"] = + QualifiedClassName(descriptor_->containing_type(), options_); variables_["type_traits"] = type_traits_; TProtoStringType name = descriptor_->name(); variables_["name"] = ResolveKeyword(name); @@ -169,7 +158,7 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { // Likewise, class members need to declare the field constant variable. if (IsScoped()) { format( - "#if !defined(_MSC_VER) || _MSC_VER >= 1900\n" + "#if !defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)\n" "const int $scope$$constant_name$;\n" "#endif\n"); } 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 0a5d2cd772..5f167a4d01 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 @@ -340,7 +340,7 @@ FieldGenerator* FieldGeneratorMap::MakeGenerator( switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_MESSAGE: if (field->is_map()) { - return new MapFieldGenerator(field, options); + return new MapFieldGenerator(field, options, scc_analyzer); } else { return new RepeatedMessageFieldGenerator(field, options, scc_analyzer); 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 8d50f88f12..e3386f446a 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 @@ -181,6 +181,10 @@ class FieldGenerator { // are placed in the message's ByteSize() method. virtual void GenerateByteSize(io::Printer* printer) const = 0; + // Generates lines to call IsInitialized() for eligible message fields. Non + // message fields won't need to override this function. + virtual void GenerateIsInitialized(io::Printer* printer) const {} + virtual bool IsInlined() const { return false; } void SetHasBitIndex(arc_i32 has_bit_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 6e3f174c5b..681e16a947 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 @@ -155,8 +155,8 @@ void FileGenerator::GenerateMacroUndefs(io::Printer* printer) { for (int i = 0; i < fields.size(); i++) { const TProtoStringType& name = fields[i]->name(); static const char* kMacroNames[] = {"major", "minor"}; - for (int i = 0; i < GOOGLE_ARRAYSIZE(kMacroNames); ++i) { - if (name == kMacroNames[i]) { + for (int j = 0; j < GOOGLE_ARRAYSIZE(kMacroNames); ++j) { + if (name == kMacroNames[j]) { names_to_undef.push_back(name); break; } @@ -1211,7 +1211,8 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { IncludeFile("net/proto2/io/public/coded_stream.h", printer); IncludeFile("net/proto2/public/arena.h", printer); IncludeFile("net/proto2/public/arenastring.h", printer); - if (options_.force_inline_string || options_.profile_driven_inline_string) { + if ((options_.force_inline_string || options_.profile_driven_inline_string) && + !options_.opensource_runtime) { IncludeFile("net/proto2/public/inlined_string_field.h", printer); } if (HasSimpleBaseClasses(file_, options_)) { 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 c5aa700c24..5191a7e730 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 @@ -58,6 +58,7 @@ #include <google/protobuf/stubs/substitute.h> #include <google/protobuf/stubs/hash.h> +// Must be last. #include <google/protobuf/port_def.inc> namespace google { @@ -174,11 +175,7 @@ static std::unordered_set<TProtoStringType>* MakeKeywordsMap() { static std::unordered_set<TProtoStringType>& kKeywords = *MakeKeywordsMap(); TProtoStringType IntTypeName(const Options& options, const TProtoStringType& type) { - if (options.opensource_runtime) { - return "::PROTOBUF_NAMESPACE_ID::" + type; - } else { - return "::" + type; - } + return "::NProtoBuf::" + type; } void SetIntVar(const Options& options, const TProtoStringType& type, @@ -460,6 +457,19 @@ TProtoStringType FieldName(const FieldDescriptor* field) { return result; } +TProtoStringType OneofCaseConstantName(const FieldDescriptor* field) { + GOOGLE_DCHECK(field->containing_oneof()); + TProtoStringType field_name = UnderscoresToCamelCase(field->name(), true); + return "k" + field_name; +} + +TProtoStringType QualifiedOneofCaseConstantName(const FieldDescriptor* field) { + GOOGLE_DCHECK(field->containing_oneof()); + const TProtoStringType qualification = + QualifiedClassName(field->containing_type()); + return StrCat(qualification, "::", OneofCaseConstantName(field)); +} + TProtoStringType EnumValueName(const EnumValueDescriptor* enum_value) { TProtoStringType result = enum_value->name(); if (kKeywords.count(result) > 0) { @@ -526,13 +536,13 @@ TProtoStringType StripProto(const TProtoStringType& filename) { const char* PrimitiveTypeName(FieldDescriptor::CppType type) { switch (type) { case FieldDescriptor::CPPTYPE_INT32: - return "::google::protobuf::int32"; + return "arc_i32"; case FieldDescriptor::CPPTYPE_INT64: - return "::google::protobuf::int64"; + return "arc_i64"; case FieldDescriptor::CPPTYPE_UINT32: - return "::google::protobuf::uint32"; + return "arc_ui32"; case FieldDescriptor::CPPTYPE_UINT64: - return "::google::protobuf::uint64"; + return "arc_ui64"; case FieldDescriptor::CPPTYPE_DOUBLE: return "double"; case FieldDescriptor::CPPTYPE_FLOAT: @@ -781,8 +791,10 @@ TProtoStringType SafeFunctionName(const Descriptor* descriptor, return function_name; } -bool IsStringInlined(const FieldDescriptor* /* descriptor */, - const Options& /* options */) { +bool IsStringInlined(const FieldDescriptor* descriptor, + const Options& options) { + (void)descriptor; + (void)options; return false; } @@ -943,15 +955,19 @@ bool HasEnumDefinitions(const FileDescriptor* file) { return false; } -bool ShouldVerify(const Descriptor* /* descriptor */, - const Options& /* options */, - MessageSCCAnalyzer* /* scc_analyzer */) { +bool ShouldVerify(const Descriptor* descriptor, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + (void)descriptor; + (void)options; + (void)scc_analyzer; return false; } -bool ShouldVerify(const FileDescriptor* /* file */, - const Options& /* options */, - MessageSCCAnalyzer* /* scc_analyzer */) { +bool ShouldVerify(const FileDescriptor* file, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + (void)file; + (void)options; + (void)scc_analyzer; return false; } @@ -1156,8 +1172,8 @@ MessageAnalysis MessageSCCAnalyzer::GetSCCAnalysis(const SCC* scc) { if (descriptor->extension_range_count() > 0) { result.contains_extension = true; } - for (int i = 0; i < descriptor->field_count(); i++) { - const FieldDescriptor* field = descriptor->field(i); + for (int j = 0; j < descriptor->field_count(); j++) { + const FieldDescriptor* field = descriptor->field(j); if (field->is_required()) { result.contains_required = true; } @@ -1474,7 +1490,8 @@ FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file, return FileOptions::SPEED; } -bool EnableMessageOwnedArena(const Descriptor* /* desc */) { +bool EnableMessageOwnedArena(const Descriptor* desc) { + (void)desc; 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 8923903452..12c8cdbde1 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 @@ -63,8 +63,8 @@ inline TProtoStringType ProtobufNamespace(const Options& /* options */) { return "PROTOBUF_NAMESPACE_ID"; } -inline TProtoStringType MacroPrefix(const Options& options) { - return options.opensource_runtime ? "GOOGLE_PROTOBUF" : "GOOGLE_PROTOBUF"; +inline TProtoStringType MacroPrefix(const Options& /* options */) { + return "GOOGLE_PROTOBUF"; } inline TProtoStringType DeprecatedAttribute(const Options& /* options */, @@ -743,6 +743,27 @@ class PROTOC_EXPORT Formatter { void Outdent() const { printer_->Outdent(); } io::Printer* printer() const { return printer_; } + class PROTOC_EXPORT ScopedIndenter { + public: + explicit ScopedIndenter(Formatter* format) : format_(format) { + format_->Indent(); + } + ~ScopedIndenter() { format_->Outdent(); } + + private: + Formatter* format_; + }; + + PROTOBUF_NODISCARD ScopedIndenter ScopedIndent() { + return ScopedIndenter(this); + } + template <typename... Args> + PROTOBUF_NODISCARD ScopedIndenter ScopedIndent(const char* format, + const Args&&... args) { + (*this)(format, static_cast<Args&&>(args)...); + return ScopedIndenter(this); + } + class PROTOC_EXPORT SaveState { public: explicit SaveState(Formatter* format) 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 f8e1c380cc..c5028fdb1d 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 @@ -84,8 +84,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor, } MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : FieldGenerator(descriptor, options) { + const Options& options, + MessageSCCAnalyzer* scc_analyzer) + : FieldGenerator(descriptor, options), + has_required_fields_( + scc_analyzer->HasRequiredFields(descriptor->message_type())) { SetMessageVariables(descriptor, &variables_, options); } @@ -293,6 +296,15 @@ void MapFieldGenerator::GenerateByteSize(io::Printer* printer) const { "}\n"); } +void MapFieldGenerator::GenerateIsInitialized(io::Printer* printer) const { + if (!has_required_fields_) return; + + Formatter format(printer, variables_); + format( + "if (!::$proto_ns$::internal::AllAreInitialized($name$_)) return " + "false;\n"); +} + void MapFieldGenerator::GenerateConstinitInitializer( io::Printer* printer) const { Formatter format(printer, variables_); 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 5ea04290e6..c01ae498b1 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 @@ -34,6 +34,7 @@ #include <map> #include <string> +#include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/compiler/cpp/cpp_message_field.h> namespace google { @@ -43,8 +44,9 @@ namespace cpp { class MapFieldGenerator : public FieldGenerator { public: - MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - ~MapFieldGenerator(); + MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options, + MessageSCCAnalyzer* scc_analyzer); + ~MapFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; @@ -58,10 +60,13 @@ class MapFieldGenerator : public FieldGenerator { void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; 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; private: + const bool has_required_fields_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldGenerator); }; 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 062b2bb754..4b5e0f2e95 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 @@ -230,12 +230,22 @@ bool EmitFieldNonDefaultCondition(io::Printer* printer, } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { // Message fields still have has_$name$() methods. format("if ($prefix$_internal_has_$name$()) {\n"); - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE || - field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT) { - // Handle float comparison to prevent -Wfloat-equal warnings + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT) { format( - "if (!($prefix$_internal_$name$() <= 0 && $prefix$_internal_$name$() " - ">= 0)) {\n"); + "static_assert(sizeof(arc_ui32) == sizeof(float), \"Code assumes " + "arc_ui32 and float are the same size.\");\n" + "float tmp_$name$ = $prefix$_internal_$name$();\n" + "arc_ui32 raw_$name$;\n" + "memcpy(&raw_$name$, &tmp_$name$, sizeof(tmp_$name$));\n" + "if (raw_$name$ != 0) {\n"); + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE) { + format( + "static_assert(sizeof(arc_ui64) == sizeof(double), \"Code assumes " + "arc_ui64 and double are the same size.\");\n" + "double tmp_$name$ = $prefix$_internal_$name$();\n" + "arc_ui64 raw_$name$;\n" + "memcpy(&raw_$name$, &tmp_$name$, sizeof(tmp_$name$));\n" + "if (raw_$name$ != 0) {\n"); } else { format("if ($prefix$_internal_$name$() != 0) {\n"); } @@ -974,7 +984,7 @@ $annotate_extension_set$ template <typename _proto_TypeTraits, ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, bool _is_packed> -inline PROTOBUF_MUST_USE_RESULT +PROTOBUF_NODISCARD inline typename _proto_TypeTraits::Singular::MutableType ReleaseExtension( const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< @@ -1437,7 +1447,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { if (EnableMessageOwnedArena(descriptor_)) { format( "inline $classname$() : $classname$(" - "new ::$proto_ns$::Arena(), true) {}\n"); + "::$proto_ns$::Arena::InternalHelper<$classname$>::\n" + " CreateMessageOwnedArena(), true) {}\n"); } else { format("inline $classname$() : $classname$(nullptr) {}\n"); } @@ -1530,10 +1541,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { format("enum $1$Case {\n", UnderscoresToCamelCase(oneof->name(), true)); format.Indent(); for (auto field : FieldRange(oneof)) { - TProtoStringType oneof_enum_case_field_name = - UnderscoresToCamelCase(field->name(), true); - format("k$1$ = $2$,\n", oneof_enum_case_field_name, // 1 - field->number()); // 2 + format("$1$ = $2$,\n", OneofCaseConstantName(field), // 1 + field->number()); // 2 } format("$1$_NOT_SET = 0,\n", ToUpper(oneof->name())); format.Outdent(); @@ -1565,7 +1574,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "bool PackFrom(const ::$proto_ns$::Message& message,\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url_prefix) {\n" - " return _any_metadata_.PackFrom(GetArena(), message, type_url_prefix);\n" + " 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" @@ -1586,7 +1596,8 @@ 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, type_url_prefix);" + " 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&>" @@ -1598,13 +1609,14 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { format( "template <typename T>\n" "bool PackFrom(const T& message) {\n" - " return _any_metadata_.PackFrom(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(message, type_url_prefix);\n" + " return _any_metadata_.PackFrom(GetArena(), message, " + "type_url_prefix);\n" "}\n" "template <typename T>\n" "bool UnpackTo(T* message) const {\n" @@ -1626,12 +1638,12 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "}\n" "inline void Swap($classname$* other) {\n" " if (other == this) return;\n" -#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + "#ifdef PROTOBUF_FORCE_COPY_IN_SWAP\n" " if (GetOwningArena() != nullptr &&\n" - " GetOwningArena() == other->GetOwningArena()) {\n" -#else // PROTOBUF_FORCE_COPY_IN_SWAP + " GetOwningArena() == other->GetOwningArena()) {\n " + "#else // PROTOBUF_FORCE_COPY_IN_SWAP\n" " if (GetOwningArena() == other->GetOwningArena()) {\n" -#endif // !PROTOBUF_FORCE_COPY_IN_SWAP + "#endif // !PROTOBUF_FORCE_COPY_IN_SWAP\n" " InternalSwap(other);\n" " } else {\n" " ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);\n" @@ -1647,11 +1659,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "\n" "// implements Message ----------------------------------------------\n" "\n" - "inline $classname$* New() const final {\n" - " return new $classname$();\n" - "}\n" - "\n" - "$classname$* New(::$proto_ns$::Arena* arena) const final {\n" + "$classname$* New(::$proto_ns$::Arena* arena = nullptr) const final {\n" " return CreateMaybeMessage<$classname$>(arena);\n" "}\n"); @@ -1714,12 +1722,6 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "$uint8$* _InternalSerialize(\n" " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) " "const final;\n"); - - // DiscardUnknownFields() is implemented in message.cc using reflections. - // We need to implement this function in generated code for messages. - if (!UseUnknownFieldSet(descriptor_->file(), options_)) { - format("void DiscardUnknownFields()$ full_final$;\n"); - } } } @@ -1740,6 +1742,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { format( // Friend AnyMetadata so that it can call this FullMessageName() method. + "\nprivate:\n" "friend class ::$proto_ns$::internal::AnyMetadata;\n" "static $1$ FullMessageName() {\n" " return \"$full_name$\";\n" @@ -2744,19 +2747,22 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets( // Some information about a field is in the pdproto profile. The profile is // only available at compile time. So we embed such information in the - // offset of the field, so that the information is available when reflective - // accessing the field at run time. + // 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"); - } else if (IsEagerlyVerifiedLazy(field, options_, scc_analyzer_)) { - format(" | 0x1u, // eagerly verified lazy\n"); + 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_)) { + format(" | 0x1u // eagerly verified lazy\n"); } else if (IsStringInlined(field, options_)) { - format(" | 0x1u, // inlined\n"); - } else { - format(",\n"); + format(" | 0x1u // inlined\n"); } + format(",\n"); } int count = 0; @@ -2796,7 +2802,7 @@ void MessageGenerator::GenerateSharedConstructorCode(io::Printer* printer) { if (HasSimpleBaseClass(descriptor_, options_)) return; Formatter format(printer, variables_); - format("void $classname$::SharedCtor() {\n"); + format("inline void $classname$::SharedCtor() {\n"); std::vector<bool> processed(optimized_order_.size(), false); GenerateConstructorBody(printer, processed, false); @@ -3119,7 +3125,9 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { "metadata_);\n"); if (descriptor_->extension_range_count() > 0) { - format("_extensions_.MergeFrom(from._extensions_);\n"); + format( + "_extensions_.MergeFrom(internal_default_instance(), " + "from._extensions_);\n"); } GenerateConstructorBody(printer, processed, true); @@ -3714,7 +3722,9 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { // 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(from._extensions_);\n"); + format( + "_extensions_.MergeFrom(internal_default_instance(), " + "from._extensions_);\n"); } format( @@ -4516,42 +4526,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { // Now check that all non-oneof embedded messages are initialized. for (auto field : optimized_order_) { - // TODO(ckennelly): Push this down into a generator? - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !ShouldIgnoreRequiredFieldCheck(field, options_) && - scc_analyzer_->HasRequiredFields(field->message_type())) { - if (field->is_repeated()) { - if (IsImplicitWeakField(field, options_, scc_analyzer_)) { - format( - "if " - "(!::$proto_ns$::internal::AllAreInitializedWeak($1$_.weak)" - ")" - " return false;\n", - FieldName(field)); - } else { - format( - "if (!::$proto_ns$::internal::AllAreInitialized($1$_))" - " return false;\n", - FieldName(field)); - } - } else if (field->options().weak()) { - continue; - } else if (IsEagerlyVerifiedLazy(field, options_, scc_analyzer_)) { - GOOGLE_CHECK(!field->real_containing_oneof()); - format( - "if (_internal_has_$1$()) {\n" - " if (!$1$().IsInitialized()) return false;\n" - "}\n", - FieldName(field)); - } else { - GOOGLE_CHECK(!field->real_containing_oneof()); - format( - "if (_internal_has_$1$()) {\n" - " if (!$1$_->IsInitialized()) return false;\n" - "}\n", - FieldName(field)); - } - } + field_generators_.get(field).GenerateIsInitialized(printer); } if (num_weak_fields_) { // For Weak fields. @@ -4579,23 +4554,9 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { for (auto field : FieldRange(oneof)) { format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); format.Indent(); - - if (!IsFieldStripped(field, options_) && - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !ShouldIgnoreRequiredFieldCheck(field, options_) && - scc_analyzer_->HasRequiredFields(field->message_type())) { - GOOGLE_CHECK(!(field->options().weak() || !field->real_containing_oneof())); - if (field->options().weak()) { - // Just skip. - } else { - format( - "if (has_$1$()) {\n" - " if (!this->$1$().IsInitialized()) return false;\n" - "}\n", - FieldName(field)); - } + if (!IsFieldStripped(field, options_)) { + field_generators_.get(field).GenerateIsInitialized(printer); } - format("break;\n"); format.Outdent(); format("}\n"); 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 720ce273bd..04f45492c3 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 @@ -87,7 +87,9 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, MessageSCCAnalyzer* scc_analyzer) : FieldGenerator(descriptor, options), implicit_weak_field_( - IsImplicitWeakField(descriptor, options, scc_analyzer)) { + IsImplicitWeakField(descriptor, options, scc_analyzer)), + has_required_fields_( + scc_analyzer->HasRequiredFields(descriptor->message_type())) { SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_); } @@ -109,7 +111,7 @@ void MessageFieldGenerator::GenerateAccessorDeclarations( format( "$deprecated_attr$const $type$& ${1$$name$$}$() const { " "__builtin_trap(); }\n" - "PROTOBUF_MUST_USE_RESULT $deprecated_attr$$type$* " + "PROTOBUF_NODISCARD $deprecated_attr$$type$* " "${1$$release_name$$}$() { " "__builtin_trap(); }\n" "$deprecated_attr$$type$* ${1$mutable_$name$$}$() { " @@ -126,7 +128,7 @@ void MessageFieldGenerator::GenerateAccessorDeclarations( } format( "$deprecated_attr$const $type$& ${1$$name$$}$() const;\n" - "PROTOBUF_MUST_USE_RESULT $deprecated_attr$$type$* " + "PROTOBUF_NODISCARD $deprecated_attr$$type$* " "${1$$release_name$$}$();\n" "$deprecated_attr$$type$* ${1$mutable_$name$$}$();\n" "$deprecated_attr$void ${1$set_allocated_$name$$}$" @@ -480,6 +482,18 @@ void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const { " *$field_member$);\n"); } +void MessageFieldGenerator::GenerateIsInitialized(io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + + if (!has_required_fields_) return; + + Formatter format(printer, variables_); + format( + "if (_internal_has_$name$()) {\n" + " if (!$name$_->IsInitialized()) return false;\n" + "}\n"); +} + void MessageFieldGenerator::GenerateConstinitInitializer( io::Printer* printer) const { Formatter format(printer, variables_); @@ -641,6 +655,17 @@ void MessageOneofFieldGenerator::GenerateConstructorCode( // space only when this field is used. } +void MessageOneofFieldGenerator::GenerateIsInitialized( + io::Printer* printer) const { + if (!has_required_fields_) return; + + Formatter format(printer, variables_); + format( + "if (_internal_has_$name$()) {\n" + " if (!$field_member$->IsInitialized()) return false;\n" + "}\n"); +} + // =================================================================== RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( @@ -648,7 +673,9 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( MessageSCCAnalyzer* scc_analyzer) : FieldGenerator(descriptor, options), implicit_weak_field_( - IsImplicitWeakField(descriptor, options, scc_analyzer)) { + IsImplicitWeakField(descriptor, options, scc_analyzer)), + has_required_fields_( + scc_analyzer->HasRequiredFields(descriptor->message_type())) { SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_); } @@ -835,6 +862,24 @@ void RepeatedMessageFieldGenerator::GenerateByteSize( "}\n"); } +void RepeatedMessageFieldGenerator::GenerateIsInitialized( + io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + + if (!has_required_fields_) return; + + Formatter format(printer, variables_); + if (implicit_weak_field_) { + format( + "if (!::$proto_ns$::internal::AllAreInitializedWeak($name$_.weak))\n" + " return false;\n"); + } else { + format( + "if (!::$proto_ns$::internal::AllAreInitialized($name$_))\n" + " return false;\n"); + } +} + void RepeatedMessageFieldGenerator::GenerateConstinitInitializer( io::Printer* printer) const { Formatter format(printer, variables_); 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 712ddbfea1..2beac6253b 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 @@ -50,7 +50,7 @@ class MessageFieldGenerator : public FieldGenerator { MessageFieldGenerator(const FieldDescriptor* descriptor, const Options& options, MessageSCCAnalyzer* scc_analyzer); - ~MessageFieldGenerator(); + ~MessageFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; @@ -71,10 +71,12 @@ class MessageFieldGenerator : public FieldGenerator { void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; + void GenerateIsInitialized(io::Printer* printer) const override; void GenerateConstinitInitializer(io::Printer* printer) const override; protected: const bool implicit_weak_field_; + const bool has_required_fields_; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); @@ -85,7 +87,7 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator { MessageOneofFieldGenerator(const FieldDescriptor* descriptor, const Options& options, MessageSCCAnalyzer* scc_analyzer); - ~MessageOneofFieldGenerator(); + ~MessageOneofFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GenerateInlineAccessorDefinitions(io::Printer* printer) const override; @@ -99,6 +101,7 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator { void GenerateSwappingCode(io::Printer* printer) const override; void GenerateDestructorCode(io::Printer* printer) const override; void GenerateConstructorCode(io::Printer* printer) const override; + void GenerateIsInitialized(io::Printer* printer) const override; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator); @@ -109,7 +112,7 @@ class RepeatedMessageFieldGenerator : public FieldGenerator { RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, const Options& options, MessageSCCAnalyzer* scc_analyzer); - ~RepeatedMessageFieldGenerator(); + ~RepeatedMessageFieldGenerator() override; // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const override; @@ -123,10 +126,12 @@ class RepeatedMessageFieldGenerator : public FieldGenerator { void GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; + void GenerateIsInitialized(io::Printer* printer) const override; void GenerateConstinitInitializer(io::Printer* printer) const override; private: const bool implicit_weak_field_; + const bool has_required_fields_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); }; 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 877908f7ad..8b745ff21c 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 @@ -73,6 +73,12 @@ TProtoStringType QualifiedExtensionName(const FieldDescriptor* d); // anyway, so normally this just returns field->name(). TProtoStringType FieldName(const FieldDescriptor* field); +// Requires that this field is in a oneof. Returns the (unqualified) case +// constant for this field. +TProtoStringType OneofCaseConstantName(const FieldDescriptor* field); +// Returns the quafilied case constant for this field. +TProtoStringType QualifiedOneofCaseConstantName(const FieldDescriptor* field); + // Get the (unqualified) name that should be used for this enum value in C++ // code. TProtoStringType EnumValueName(const EnumValueDescriptor* enum_value); 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 bc174c3d6e..23adb91430 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 @@ -71,7 +71,7 @@ struct Options { bool opensource_runtime = false; bool annotate_accessor = false; bool unused_field_stripping = false; - bool profile_driven_inline_string = false; + bool profile_driven_inline_string = true; bool force_inline_string = false; TProtoStringType runtime_include_base; int num_cc_files = 0; 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 ac3e57cda8..282d70e391 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 @@ -81,9 +81,9 @@ const char* TagType(const FieldDescriptor* field) { return CodedTagType(TagSize(field->number())); } -TProtoStringType TcParserBaseName(const Options& options) { +TProtoStringType TcParserName(const Options& options) { return StrCat("::", ProtobufNamespace(options), - "::internal::TcParserBase::"); + "::internal::TcParser::"); } TProtoStringType MessageTcParseFunctionName(const FieldDescriptor* field, @@ -93,8 +93,8 @@ TProtoStringType MessageTcParseFunctionName(const FieldDescriptor* field, // 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 TcParserBase. - return StrCat(TcParserBaseName(options), + // done by helpers in TcParser. + return StrCat(TcParserName(options), (field->is_repeated() ? "Repeated" : "Singular"), "ParseMessage<", QualifiedClassName(field->message_type()), // @@ -108,8 +108,7 @@ TProtoStringType MessageTcParseFunctionName(const FieldDescriptor* field, } TProtoStringType FieldParseFunctionName(const FieldDescriptor* field, - const Options& options, - arc_ui32 table_size_log2); + const Options& options); } // namespace @@ -209,14 +208,14 @@ TailCallTableInfo::TailCallTableInfo(const Descriptor* descriptor, case FieldDescriptor::TYPE_SINT64: case FieldDescriptor::TYPE_SINT32: case FieldDescriptor::TYPE_BOOL: - name = FieldParseFunctionName(field, options, table_size_log2); + name = FieldParseFunctionName(field, options); break; case FieldDescriptor::TYPE_BYTES: if (field->options().ctype() == FieldOptions::STRING && field->default_value_string().empty() && !IsStringInlined(field, options)) { - name = FieldParseFunctionName(field, options, table_size_log2); + name = FieldParseFunctionName(field, options); } break; @@ -365,9 +364,8 @@ void ParseFunctionGenerator::GenerateTailcallParseFunction(Formatter& format) { "const char* $classname$::_InternalParse(\n" " const char* ptr, ::$proto_ns$::internal::ParseContext* ctx) {\n" "$annotate_deserialize$" - " ptr = ::$proto_ns$::internal::TcParser<$1$>::ParseLoop(\n" - " this, ptr, ctx, &_table_.header);\n", - tc_table_info_->table_size_log2); + " ptr = ::$proto_ns$::internal::TcParser::ParseLoop(\n" + " this, ptr, ctx, &_table_.header);\n"); format( " return ptr;\n" "}\n\n"); @@ -426,9 +424,9 @@ void ParseFunctionGenerator::GenerateTailcallFieldParseFunctions( "return table->fallback(PROTOBUF_TC_PARAM_PASS);\n" " ptr += $1$;\n" " hasbits |= (arc_ui64{1} << data.hasbit_idx());\n" - " ::$proto_ns$::internal::TcParserBase::SyncHasbits" + " ::$proto_ns$::internal::TcParser::SyncHasbits" "(msg, hasbits, table);\n" - " auto& field = ::$proto_ns$::internal::TcParserBase::" + " auto& field = ::$proto_ns$::internal::TcParser::" "RefAt<$classtype$*>(msg, data.offset());\n" " if (field == nullptr)\n" " field = CreateMaybeMessage<$classtype$>(ctx->data().arena);\n" @@ -448,9 +446,9 @@ void ParseFunctionGenerator::GenerateTailcallFieldParseFunctions( "return table->fallback(PROTOBUF_TC_PARAM_PASS);\n" " }\n" " ptr += $1$;\n" - " auto& field = ::$proto_ns$::internal::TcParserBase::RefAt<" + " auto& field = ::$proto_ns$::internal::TcParser::RefAt<" "::$proto_ns$::RepeatedPtrField<$classname$>>(msg, data.offset());\n" - " ::$proto_ns$::internal::TcParserBase::SyncHasbits" + " ::$proto_ns$::internal::TcParser::SyncHasbits" "(msg, hasbits, table);\n" " ptr = ctx->ParseMessage(field.Add(), ptr);\n" " return ptr;\n" @@ -471,7 +469,7 @@ void ParseFunctionGenerator::GenerateDataDecls(io::Printer* printer) { format.Indent(); } format( - "static const ::$proto_ns$::internal::TailCallParseTable<$1$>\n" + "static const ::$proto_ns$::internal::TcParseTable<$1$>\n" " _table_;\n", tc_table_info_->table_size_log2); if (should_generate_guarded_tctable()) { @@ -546,7 +544,7 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { if (tc_table_info_->use_generated_fallback) { fallback = ClassName(descriptor_) + "::Tct_ParseFallback"; } else { - fallback = TcParserBaseName(options_) + "GenericFallback"; + fallback = TcParserName(options_) + "GenericFallback"; if (GetOptimizeFor(descriptor_->file(), options_) == FileOptions::LITE_RUNTIME) { fallback += "Lite"; @@ -561,33 +559,48 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { // the table is sufficient we can use a generic routine, that just handles // unknown fields and potentially an extension range. format( - "const ::$proto_ns$::internal::TailCallParseTable<$1$>\n" + "const ::$proto_ns$::internal::TcParseTable<$1$>\n" " $classname$::_table_ = {\n", tc_table_info_->table_size_log2); - format.Indent(); - format("{\n"); - format.Indent(); - if (num_hasbits_ > 0 || IsMapEntryMessage(descriptor_)) { - format("PROTOBUF_FIELD_OFFSET($classname$, _has_bits_),\n"); - } else { - format("0, // no _has_bits_\n"); - } - if (descriptor_->extension_range_count() == 1) { - format( - "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"); + { + auto table_scope = format.ScopedIndent(); + format("{\n"); + { + auto header_scope = format.ScopedIndent(); + if (num_hasbits_ > 0 || IsMapEntryMessage(descriptor_)) { + format("PROTOBUF_FIELD_OFFSET($classname$, _has_bits_),\n"); + } else { + format("0, // no _has_bits_\n"); + } + if (descriptor_->extension_range_count() == 1) { + format( + "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$, 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(), + DefaultInstanceName(descriptor_, options_), fallback); + } + format("}, {\n"); + { + auto fast_scope = format.ScopedIndent(); + GenerateFastFieldEntries(format, fallback); + } + format("},\n"); // entries[] } - format( - "&$1$._instance,\n" - "$2$ // fallback\n", - DefaultInstanceName(descriptor_, options_), fallback); - format.Outdent(); - format("}, {\n"); - format.Indent(); + format("};\n\n"); // _table_ +} + +void ParseFunctionGenerator::GenerateFastFieldEntries( + Formatter& format, const TProtoStringType& fallback) { for (const auto& info : tc_table_info_->fast_path_fields) { if (info.field != nullptr) { PrintFieldComment(format, info.field); @@ -604,10 +617,6 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { } format("},\n"); } - format.Outdent(); - format("},\n"); // entries[] - format.Outdent(); - format("};\n\n"); // _table_ } void ParseFunctionGenerator::GenerateArenaString(Formatter& format, @@ -634,6 +643,8 @@ void ParseFunctionGenerator::GenerateArenaString(Formatter& format, ", ~0x$2$u", inlined_string_index / 32, strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8)); + } else { + GOOGLE_DCHECK(field->default_value_string().empty()); } format( ");\n" @@ -766,15 +777,22 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, "$msg$GetArenaForAllocation());\n" " $msg$set_has_$name$();\n" "}\n" - "ptr = ctx->ParseMessage($msg$$1$_.$name$_, ptr);\n", + "auto* lazy_field = $msg$$1$_.$name$_;\n", field->containing_oneof()->name()); } else if (HasHasbit(field)) { format( "_Internal::set_has_$name$(&$has_bits$);\n" - "ptr = ctx->ParseMessage(&$msg$$name$_, ptr);\n"); + "auto* lazy_field = &$msg$$name$_;\n"); } else { - format("ptr = ctx->ParseMessage(&$msg$$name$_, ptr);\n"); + format("auto* lazy_field = &$msg$$name$_;\n"); } + format( + "::$proto_ns$::internal::LazyFieldParseHelper<\n" + " ::$proto_ns$::internal::LazyField> parse_helper(\n" + " $1$::default_instance(),\n" + " $msg$GetArenaForAllocation(), lazy_field);\n" + "ptr = ctx->ParseMessage(&parse_helper, ptr);\n", + FieldMessageTypeName(field, options_)); } else if (IsImplicitWeakField(field, options_, scc_analyzer_)) { if (!field->is_repeated()) { format( @@ -859,7 +877,8 @@ void ParseFunctionGenerator::GenerateFieldBody( field->number()); } } else { - TProtoStringType size = (field->type() == FieldDescriptor::TYPE_SINT32 || + TProtoStringType size = (field->type() == FieldDescriptor::TYPE_INT32 || + field->type() == FieldDescriptor::TYPE_SINT32 || field->type() == FieldDescriptor::TYPE_UINT32) ? "32" : "64"; @@ -1086,8 +1105,7 @@ void ParseFunctionGenerator::GenerateFieldSwitch( namespace { TProtoStringType FieldParseFunctionName(const FieldDescriptor* field, - const Options& options, - arc_ui32 table_size_log2) { + const Options& options) { ParseCardinality card = // field->is_packed() ? ParseCardinality::kPacked : field->is_repeated() ? ParseCardinality::kRepeated @@ -1146,9 +1164,8 @@ TProtoStringType FieldParseFunctionName(const FieldDescriptor* field, type_format = TypeFormat::kStringValidateOnly; break; default: - GOOGLE_LOG(DFATAL) - << "Mode not handled: " - << static_cast<int>(GetUtf8CheckMode(field, options)); + GOOGLE_LOG(DFATAL) << "Mode not handled: " + << static_cast<int>(GetUtf8CheckMode(field, options)); return ""; } break; @@ -1158,8 +1175,8 @@ TProtoStringType FieldParseFunctionName(const FieldDescriptor* field, return ""; } - return "::" + ProtobufNamespace(options) + "::internal::" + - GetTailCallFieldHandlerName(card, type_format, table_size_log2, + return "::" + ProtobufNamespace(options) + "::internal::TcParser::" + + GetTailCallFieldHandlerName(card, type_format, TagSize(field->number()), options); } @@ -1167,32 +1184,10 @@ TProtoStringType FieldParseFunctionName(const FieldDescriptor* field, TProtoStringType GetTailCallFieldHandlerName(ParseCardinality card, TypeFormat type_format, - int table_size_log2, int tag_length_bytes, const Options& options) { TProtoStringType name; - switch (card) { - case ParseCardinality::kPacked: - case ParseCardinality::kRepeated: - name = "TcParserBase::"; - break; - - case ParseCardinality::kSingular: - case ParseCardinality::kOneof: - switch (type_format) { - case TypeFormat::kBytes: - case TypeFormat::kString: - case TypeFormat::kStringValidateOnly: - name = "TcParserBase::"; - break; - - default: - name = StrCat("TcParser<", table_size_log2, ">::"); - break; - } - } - // The field implementation functions are prefixed by cardinality: // `Singular` for optional or implicit fields. // `Repeated` for non-packed repeated. @@ -1274,26 +1269,24 @@ TProtoStringType GetTailCallFieldHandlerName(ParseCardinality card, case TypeFormat::kVar64: case TypeFormat::kVar32: case TypeFormat::kBool: - name.append( - StrCat(", ", TcParserBaseName(options), "kNoConversion")); + StrAppend(&name, ", ", TcParserName(options), "kNoConversion"); break; case TypeFormat::kSInt64: case TypeFormat::kSInt32: - name.append(StrCat(", ", TcParserBaseName(options), "kZigZag")); + StrAppend(&name, ", ", TcParserName(options), "kZigZag"); break; case TypeFormat::kBytes: - name.append(StrCat(", ", TcParserBaseName(options), "kNoUtf8")); + StrAppend(&name, ", ", TcParserName(options), "kNoUtf8"); break; case TypeFormat::kString: - name.append(StrCat(", ", TcParserBaseName(options), "kUtf8")); + StrAppend(&name, ", ", TcParserName(options), "kUtf8"); break; case TypeFormat::kStringValidateOnly: - name.append( - StrCat(", ", TcParserBaseName(options), "kUtf8ValidateOnly")); + StrAppend(&name, ", ", TcParserName(options), "kUtf8ValidateOnly"); break; default: 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 820f7b3089..0246079146 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 @@ -118,6 +118,7 @@ class ParseFunctionGenerator { // Generates the tail-call table definition. void GenerateTailCallTable(Formatter& format); + void GenerateFastFieldEntries(Formatter& format, const TProtoStringType& fallback); // Generates parsing code for an `ArenaString` field. void GenerateArenaString(Formatter& format, const FieldDescriptor* field); @@ -187,7 +188,6 @@ enum class TypeFormat { // parse_function_inc_generator_main. TProtoStringType GetTailCallFieldHandlerName(ParseCardinality card, TypeFormat type_format, - int table_size_log2, int tag_length_bytes, const Options& options); 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 ce0f97d930..ff7c208ff2 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 @@ -59,7 +59,8 @@ class PrimitiveFieldGenerator : public FieldGenerator { void GenerateSwappingCode(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 GenerateSerializeWithCachedSizesToArray( + io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; void GenerateConstinitInitializer(io::Printer* printer) const override; @@ -98,7 +99,8 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator { void GenerateSwappingCode(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 GenerateSerializeWithCachedSizesToArray( + io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; void GenerateConstinitInitializer(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 0a30646fd0..944b41ba90 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 @@ -241,12 +241,12 @@ void ServiceGenerator::GenerateCallMethod(io::Printer* printer) { for (int i = 0; i < descriptor_->method_count(); i++) { const MethodDescriptor* method = descriptor_->method(i); - Formatter format(printer, vars_); - InitMethodVariables(method, options_, &format); + Formatter format_method(printer, vars_); + InitMethodVariables(method, options_, &format_method); // Note: down_cast does not work here because it only works on pointers, // not references. - format( + format_method( " case $1$:\n" " $name$(controller,\n" " ::$proto_ns$::internal::DownCast<const $input_type$*>(\n" 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 0adde4e777..c736ce9527 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 @@ -170,7 +170,7 @@ void StringFieldGenerator::GenerateAccessorDeclarations( descriptor_); format( "$deprecated_attr$TProtoStringType* ${1$mutable_$name$$}$();\n" - "PROTOBUF_MUST_USE_RESULT $deprecated_attr$TProtoStringType* " + "PROTOBUF_NODISCARD $deprecated_attr$TProtoStringType* " "${1$$release_name$$}$();\n" "$deprecated_attr$void ${1$set_allocated_$name$$}$(TProtoStringType* " "$name$);\n", @@ -290,8 +290,17 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " $clear_hasbit$\n"); if (!inlined_) { format( - " return $name$_.ReleaseNonDefault($init_value$, " + " auto* p = $name$_.ReleaseNonDefault($init_value$, " "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" + " }\n" + "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"); + } + format(" return p;\n"); } else { format( " return $name$_.Release(nullptr, GetArenaForAllocation(), " @@ -314,6 +323,14 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( format( " $name$_.SetAllocated($init_value$, $name$,\n" " 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" + " }\n" + "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"); + } } else { // Currently, string fields with default value can't be inlined. format( @@ -422,6 +439,13 @@ void StringFieldGenerator::GenerateConstructorCode(io::Printer* printer) const { } GOOGLE_DCHECK(!inlined_); format("$name$_.UnsafeSetDefault($init_value$);\n"); + if (IsString(descriptor_, options_) && + descriptor_->default_value_string().empty()) { + format( + "#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING\n" + " $name$_.Set($init_value$, \"\", GetArenaForAllocation());\n" + "#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING\n"); + } } void StringFieldGenerator::GenerateCopyConstructorCode( 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 85689bbec8..3f05443f58 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 @@ -55,7 +55,8 @@ class StringFieldGenerator : public FieldGenerator { void GenerateStaticMembers(io::Printer* printer) const override; void GenerateAccessorDeclarations(io::Printer* printer) const override; void GenerateInlineAccessorDefinitions(io::Printer* printer) const override; - void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const override; + void GenerateNonInlineAccessorDefinitions( + io::Printer* printer) const override; void GenerateClearingCode(io::Printer* printer) const override; void GenerateMessageClearingCode(io::Printer* printer) const override; void GenerateMergingCode(io::Printer* printer) const override; @@ -63,7 +64,8 @@ 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 GenerateSerializeWithCachedSizesToArray(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_; } @@ -108,7 +110,8 @@ class RepeatedStringFieldGenerator : public FieldGenerator { void GenerateSwappingCode(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 GenerateSerializeWithCachedSizesToArray( + io::Printer* printer) const override; void GenerateByteSize(io::Printer* printer) const override; void GenerateConstinitInitializer(io::Printer* printer) const override; |