diff options
author | nechda <[email protected]> | 2024-08-29 23:50:27 +0300 |
---|---|---|
committer | nechda <[email protected]> | 2024-08-30 00:05:25 +0300 |
commit | e10d6638f07a82edae3ea8197b9f5c0affcc07ea (patch) | |
tree | 571c38cec05813766a1ad290c9d51ce7ace52919 /contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.h | |
parent | e79b38f2bbbf78d295d1901d2a79f898022d5224 (diff) |
Update cpp-protobuf to 22.5
Привет!\
Этот PR переключат cpp & python библиотеки protobuf на версию 22.5
Если у вас возникли проблемы после влития этого PR:
1. Если начали падать канон тесты, то проведите их переканонизацию
2. Прочитайте <https://wiki.yandex-team.ru/users/nechda/obnovlenie-cpp-protobuf-22.5/> страничку с основными изменениями
3. Если страничка в вики не помогла, то пишите в [DEVTOOLSSUPPORT](https://st.yandex-team.ru/DEVTOOLSSUPPORT)
7fecade616c20a841b9e9af7b7998bdfc8d2807d
Diffstat (limited to 'contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.h')
-rw-r--r-- | contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.h | 496 |
1 files changed, 324 insertions, 172 deletions
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.h index 95eb96f499d..0d00011ff74 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.h @@ -36,232 +36,384 @@ #define GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__ #include <cstdint> -#include <map> #include <memory> #include <string> +#include <tuple> +#include <vector> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/compiler/cpp/helpers.h> -#include <google/protobuf/compiler/cpp/options.h> - -namespace google { -namespace protobuf { -namespace io { -class Printer; // printer.h -} -} // namespace protobuf -} // namespace google +#include "google/protobuf/descriptor.h" +#include "y_absl/container/flat_hash_map.h" +#include "y_absl/log/absl_check.h" +#include "google/protobuf/compiler/cpp/helpers.h" +#include "google/protobuf/compiler/cpp/options.h" +#include "google/protobuf/io/printer.h" namespace google { namespace protobuf { namespace compiler { namespace cpp { -// Helper function: set variables in the map that are the same for all -// field code generators. -// ['name', 'index', 'number', 'classname', 'declared_type', 'tag_size', -// 'deprecation']. -void SetCommonFieldVariables(const FieldDescriptor* descriptor, - std::map<TProtoStringType, TProtoStringType>* variables, - const Options& options); +// Customization points for each field codegen type. See FieldGenerator to +// see how each of these functions is used. +// +// TODO(b/245791219): Make every function except the dtor in this generator +// non-pure-virtual. A generator with no implementation should be able to +// automatically not contribute any code to the message it is part of, as a +// matter of clean composability. +class FieldGeneratorBase { + public: + FieldGeneratorBase(const FieldDescriptor* descriptor, const Options& options) + : descriptor_(descriptor), options_(options) {} + + FieldGeneratorBase(const FieldGeneratorBase&) = delete; + FieldGeneratorBase& operator=(const FieldGeneratorBase&) = delete; + + virtual ~FieldGeneratorBase() = 0; + + virtual std::vector<io::Printer::Sub> MakeVars() const { return {}; } + + virtual void GeneratePrivateMembers(io::Printer* p) const = 0; + + virtual void GenerateStaticMembers(io::Printer* p) const {} + + virtual void GenerateAccessorDeclarations(io::Printer* p) const = 0; + + virtual void GenerateInlineAccessorDefinitions(io::Printer* p) const = 0; + + virtual void GenerateNonInlineAccessorDefinitions(io::Printer* p) const {} + + virtual void GenerateInternalAccessorDefinitions(io::Printer* p) const {} + + virtual void GenerateInternalAccessorDeclarations(io::Printer* p) const {} + + virtual void GenerateClearingCode(io::Printer* p) const = 0; + + virtual void GenerateMessageClearingCode(io::Printer* p) const { + GenerateClearingCode(p); + } + + virtual void GenerateMergingCode(io::Printer* p) const = 0; + + virtual void GenerateCopyConstructorCode(io::Printer* p) const; + + virtual void GenerateSwappingCode(io::Printer* p) const = 0; + + virtual void GenerateConstructorCode(io::Printer* p) const = 0; + + virtual void GenerateDestructorCode(io::Printer* p) const {} + + virtual void GenerateArenaDestructorCode(io::Printer* p) const { + Y_ABSL_CHECK(NeedsArenaDestructor() == ArenaDtorNeeds::kNone) + << descriptor_->cpp_type_name(); + } + + virtual void GenerateAggregateInitializer(io::Printer* p) const; + + virtual void GenerateConstexprAggregateInitializer(io::Printer* p) const; + + virtual void GenerateCopyAggregateInitializer(io::Printer* p) const; + + virtual void GenerateSerializeWithCachedSizesToArray( + io::Printer* p) const = 0; + + virtual void GenerateByteSize(io::Printer* p) const = 0; -void SetCommonOneofFieldVariables( - const FieldDescriptor* descriptor, - std::map<TProtoStringType, TProtoStringType>* variables); + virtual void GenerateIsInitialized(io::Printer* p) const {} + + virtual void GenerateIfHasField(io::Printer* p) const; + + virtual bool IsInlined() const { return false; } + + virtual ArenaDtorNeeds NeedsArenaDestructor() const { + return ArenaDtorNeeds::kNone; + } + + protected: + // TODO(b/245791219): Remove these members and make this a pure interface. + const FieldDescriptor* descriptor_; + const Options& options_; + y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> variables_; +}; + +inline FieldGeneratorBase::~FieldGeneratorBase() = default; class FieldGenerator { + private: + // This function must be defined here so that the inline definitions below + // can see it, which is required because it has deduced return type. + auto PushVarsForCall(io::Printer* p) const { + // NOTE: we use a struct here because: + // * We want to ensure that order of evaluation below is well-defined, + // which {...} guarantees but (...) does not. + // * We do not require C++17 as of writing and therefore cannot use + // std::tuple with CTAD. + // * std::make_tuple uses (...), not {...}. + struct Vars { + decltype(p->WithVars(field_vars_)) cleanup1; + decltype(p->WithVars(tracker_vars_)) cleanup2; + decltype(p->WithVars(per_generator_vars_)) cleanup3; + }; + + return Vars{p->WithVars(field_vars_), p->WithVars(tracker_vars_), + p->WithVars(per_generator_vars_)}; + } + public: - explicit FieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : descriptor_(descriptor), options_(options) {} - virtual ~FieldGenerator(); - virtual void GenerateSerializeWithCachedSizes( - io::Printer* printer) const final{}; - // Generate lines of code declaring members fields of the message class - // needed to represent this field. These are placed inside the message - // class. - virtual void GeneratePrivateMembers(io::Printer* printer) const = 0; - - // Generate static default variable for this field. These are placed inside - // the message class. Most field types don't need this, so the default - // implementation is empty. - virtual void GenerateStaticMembers(io::Printer* /*printer*/) const {} - - // Generate prototypes for all of the accessor functions related to this - // field. These are placed inside the class definition. - virtual void GenerateAccessorDeclarations(io::Printer* printer) const = 0; - - // Generate inline definitions of accessor functions for this field. - // These are placed inside the header after all class definitions. - virtual void GenerateInlineAccessorDefinitions( - io::Printer* printer) const = 0; - - // Generate definitions of accessors that aren't inlined. These are - // placed somewhere in the .cc file. - // Most field types don't need this, so the default implementation is empty. - virtual void GenerateNonInlineAccessorDefinitions( - io::Printer* /*printer*/) const {} - - // Generate declarations of accessors that are for internal purposes only. - // Most field types don't need this, so the default implementation is empty. - virtual void GenerateInternalAccessorDefinitions( - io::Printer* /*printer*/) const {} - - // Generate definitions of accessors that are for internal purposes only. - // Most field types don't need this, so the default implementation is empty. - virtual void GenerateInternalAccessorDeclarations( - io::Printer* /*printer*/) const {} - - // Generate lines of code (statements, not declarations) which clear the - // field. This is used to define the clear_$name$() method - virtual void GenerateClearingCode(io::Printer* printer) const = 0; - - // Generate lines of code (statements, not declarations) which clear the - // field as part of the Clear() method for the whole message. For message - // types which have field presence bits, MessageGenerator::GenerateClear - // will have already checked the presence bits. + FieldGenerator(const FieldGenerator&) = delete; + FieldGenerator& operator=(const FieldGenerator&) = delete; + FieldGenerator(FieldGenerator&&) = default; + FieldGenerator& operator=(FieldGenerator&&) = default; + + // Prints private members needed to represent this field. // - // Since most field types can re-use GenerateClearingCode, this method is - // not pure virtual. - virtual void GenerateMessageClearingCode(io::Printer* printer) const { - GenerateClearingCode(printer); + // These are placed inside the class definition. + void GeneratePrivateMembers(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GeneratePrivateMembers(p); } - // Generate lines of code (statements, not declarations) which merges the - // contents of the field from the current message to the target message, - // which is stored in the generated code variable "from". + // Prints static members needed to represent this field. + // + // These are placed inside the class definition. + void GenerateStaticMembers(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateStaticMembers(p); + } + + // Generates declarations for all of the accessor functions related to this + // field. + // + // These are placed inside the class definition. + void GenerateAccessorDeclarations(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateAccessorDeclarations(p); + } + + // Generates inline definitions of accessor functions for this field. + // + // These are placed in namespace scope in the header after all class + // definitions. + void GenerateInlineAccessorDefinitions(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateInlineAccessorDefinitions(p); + } + + // Generates definitions of accessors that aren't inlined. + // + // These are placed in namespace scope in the .cc file. + void GenerateNonInlineAccessorDefinitions(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateNonInlineAccessorDefinitions(p); + } + + // Generates declarations of accessors that are for internal purposes only. + void GenerateInternalAccessorDefinitions(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateInternalAccessorDefinitions(p); + } + + // Generates definitions of accessors that are for internal purposes only. + void GenerateInternalAccessorDeclarations(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateInternalAccessorDeclarations(p); + } + + // Generates statements which clear the field. + // + // This is used to define the clear_$name$() method. + void GenerateClearingCode(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateClearingCode(p); + } + + // Generates statements which clear the field as part of the Clear() method + // for the whole message. + // + // For message types which have field presence bits, + // MessageGenerator::GenerateClear will have already checked the presence + // bits. + void GenerateMessageClearingCode(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateMessageClearingCode(p); + } + + // Generates statements which merge the contents of the field from the current + // message to the target message, which is stored in the generated code + // variable `from`. + // // This is used to fill in the MergeFrom method for the whole message. + // // Details of this usage can be found in message.cc under the // GenerateMergeFrom method. - virtual void GenerateMergingCode(io::Printer* printer) const = 0; + void GenerateMergingCode(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateMergingCode(p); + } // Generates a copy constructor - virtual void GenerateCopyConstructorCode(io::Printer* printer) const; + // + // TODO(b/245791219): Document this properly. + void GenerateCopyConstructorCode(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateCopyConstructorCode(p); + } - // Generate lines of code (statements, not declarations) which swaps - // this field and the corresponding field of another message, which - // is stored in the generated code variable "other". This is used to - // define the Swap method. Details of usage can be found in + // Generates statements which swap this field and the corresponding field of + // another message, which is stored in the generated code variable `other`. + // + // This is used to define the Swap method. Details of usage can be found in // message.cc under the GenerateSwap method. - virtual void GenerateSwappingCode(io::Printer* printer) const = 0; - - // Generate initialization code for private members declared by - // GeneratePrivateMembers(). These go into the message class's SharedCtor() - // method, invoked by each of the generated constructors. - virtual void GenerateConstructorCode(io::Printer* printer) const = 0; + void GenerateSwappingCode(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateSwappingCode(p); + } - // Generate initialization code for private members in the cold struct. - virtual void GenerateCreateSplitMessageCode(io::Printer* printer) const {} + // Generates initialization code for private members declared by + // GeneratePrivateMembers(). + // + // These go into the message class's SharedCtor() method, invoked by each of + // the generated constructors. + void GenerateConstructorCode(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateConstructorCode(p); + } - // Generate any code that needs to go in the class's SharedDtor() method, + // Generates any code that needs to go in the class's SharedDtor() method, // invoked by the destructor. - // Most field types don't need this, so the default implementation is empty. - virtual void GenerateDestructorCode(io::Printer* /*printer*/) const {} - - // 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(). - virtual void GenerateArenaDestructorCode(io::Printer* printer) const { - GOOGLE_CHECK(NeedsArenaDestructor() == ArenaDtorNeeds::kNone) - << descriptor_->cpp_type_name(); + void GenerateDestructorCode(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateDestructorCode(p); } - // Generate initialization code for private members declared by - // GeneratePrivateMembers(). These go into the SharedCtor's - // aggregate initialization of the _impl_ struct and must follow the syntax - // (e.g. `decltype($field$){$default$}`). Does not include `:` or `,` - // separators. Default values should be specified here when possible. + // Generates a manual destructor invocation for use when the message is on an + // arena. // - // Note: We use `decltype($field$)` for both explicit construction and the - // fact that it's self-documenting. Pre-C++17, copy elision isn't guaranteed + // The code that this method generates will be executed inside a + // shared-for-the-whole-message-class method registered with OwnDestructor(). + void GenerateArenaDestructorCode(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateArenaDestructorCode(p); + } + + // Generates initialization code for private members declared by + // GeneratePrivateMembers(). + // + // These go into the SharedCtor's aggregate initialization of the _impl_ + // struct and must follow the syntax `decltype($field$){$default$}`. + // Does not include `:` or `,` separators. Default values should be specified + // here when possible. + // + // NOTE: We use `decltype($field$)` for both explicit construction and the + // fact that it's self-documenting. Pre-C++17, copy elision isn't guaranteed // in aggregate initialization so a valid copy/move constructor must exist - // (even though it's not used). Because of this, we need to comment out the + // (even though it's not used). Because of this, we need to comment out the // decltype and fallback to implicit construction. - virtual void GenerateAggregateInitializer(io::Printer* printer) const; - - // Generate constinit initialization code for private members declared by - // GeneratePrivateMembers(). These go into the constexpr constructor's - // aggregate initialization of the _impl_ struct and must follow the syntax - // (e.g. `/*decltype($field$)*/{}`, see above). Does not - // include `:` or `,` separators. - virtual void GenerateConstexprAggregateInitializer( - io::Printer* printer) const; - - // Generate copy initialization code for private members declared by - // GeneratePrivateMembers(). These go into the copy constructor's - // aggregate initialization of the _impl_ struct and must follow the syntax - // (e.g. `decltype($field$){from.$field$}`, see above). Does not - // include `:` or `,` separators. - virtual void GenerateCopyAggregateInitializer(io::Printer* printer) const; - - // Generate lines to serialize this field directly to the array "target", - // which are placed within the message's SerializeWithCachedSizesToArray() - // method. This must also advance "target" past the written bytes. - virtual void GenerateSerializeWithCachedSizesToArray( - io::Printer* printer) const = 0; + void GenerateAggregateInitializer(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateAggregateInitializer(p); + } + + // Generates constinit initialization code for private members declared by + // GeneratePrivateMembers(). + // + // These go into the constexpr constructor's aggregate initialization of the + // _impl_ struct and must follow the syntax `/*decltype($field$)*/{}` (see + // above). Does not include `:` or `,` separators. + void GenerateConstexprAggregateInitializer(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateConstexprAggregateInitializer(p); + } + + // Generates copy initialization code for private members declared by + // GeneratePrivateMembers(). + // + // These go into the copy constructor's aggregate initialization of the _impl_ + // struct and must follow the syntax `decltype($field$){from.$field$}` (see + // above). Does not include `:` or `,` separators. + void GenerateCopyAggregateInitializer(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateCopyAggregateInitializer(p); + } + + // Generates statements to serialize this field directly to the array + // `target`, which are placed within the message's + // SerializeWithCachedSizesToArray() method. + // + // This must also advance `target` past the written bytes. + void GenerateSerializeWithCachedSizesToArray(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateSerializeWithCachedSizesToArray(p); + } - // Generate lines to compute the serialized size of this field, which + // Generates statements to compute the serialized size of this field, which // are placed in the message's ByteSize() method. - virtual void GenerateByteSize(io::Printer* printer) const = 0; + void GenerateByteSize(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateByteSize(p); + } // 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 GenerateIsInitialized(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateIsInitialized(p); + } - virtual ArenaDtorNeeds NeedsArenaDestructor() const { - return ArenaDtorNeeds::kNone; + // TODO(b/245791219): Document this properly. + void GenerateIfHasField(io::Printer* p) const { + auto vars = PushVarsForCall(p); + impl_->GenerateIfHasField(p); } - void SetHasBitIndex(arc_i32 has_bit_index); - void SetInlinedStringIndex(arc_i32 inlined_string_index); + // TODO(b/245791219): Document this properly. + bool IsInlined() const { return impl_->IsInlined(); } - protected: - const FieldDescriptor* descriptor_; - const Options& options_; - std::map<TProtoStringType, TProtoStringType> variables_; + // TODO(b/245791219): Document this properly. + ArenaDtorNeeds NeedsArenaDestructor() const { + return impl_->NeedsArenaDestructor(); + } private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator); + friend class FieldGeneratorTable; + FieldGenerator(const FieldDescriptor* field, const Options& options, + MessageSCCAnalyzer* scc_analyzer, + y_absl::optional<arc_ui32> hasbit_index, + y_absl::optional<arc_ui32> inlined_string_index); + + std::unique_ptr<FieldGeneratorBase> impl_; + std::vector<io::Printer::Sub> field_vars_; + std::vector<io::Printer::Sub> tracker_vars_; + std::vector<io::Printer::Sub> per_generator_vars_; }; -// Convenience class which constructs FieldGenerators for a Descriptor. -class FieldGeneratorMap { +// Convenience class which constructs FieldGeneratorBases for a Descriptor. +class FieldGeneratorTable { public: - FieldGeneratorMap(const Descriptor* descriptor, const Options& options, - MessageSCCAnalyzer* scc_analyzer); - ~FieldGeneratorMap(); + explicit FieldGeneratorTable(const Descriptor* descriptor) + : descriptor_(descriptor) {} - const FieldGenerator& get(const FieldDescriptor* field) const; + FieldGeneratorTable(const FieldGeneratorTable&) = delete; + FieldGeneratorTable& operator=(const FieldGeneratorTable&) = delete; - void SetHasBitIndices(const std::vector<int>& has_bit_indices_) { - for (int i = 0; i < descriptor_->field_count(); ++i) { - field_generators_[i]->SetHasBitIndex(has_bit_indices_[i]); - } - } + void Build(const Options& options, MessageSCCAnalyzer* scc_analyzer, + y_absl::Span<const arc_i32> has_bit_indices, + y_absl::Span<const arc_i32> inlined_string_indices); - void SetInlinedStringIndices(const std::vector<int>& inlined_string_indices) { - for (int i = 0; i < descriptor_->field_count(); ++i) { - field_generators_[i]->SetInlinedStringIndex(inlined_string_indices[i]); - } + const FieldGenerator& get(const FieldDescriptor* field) const { + Y_ABSL_CHECK_EQ(field->containing_type(), descriptor_); + return fields_[field->index()]; } private: const Descriptor* descriptor_; - std::vector<std::unique_ptr<FieldGenerator>> field_generators_; - - static FieldGenerator* MakeGoogleInternalGenerator( - const FieldDescriptor* field, const Options& options, - MessageSCCAnalyzer* scc_analyzer); - static FieldGenerator* MakeGenerator(const FieldDescriptor* field, - const Options& options, - MessageSCCAnalyzer* scc_analyzer); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); + std::vector<FieldGenerator> fields_; }; +// Returns variables common to all fields. +// +// TODO(b/245791219): Make this function .cc-private. +std::vector<io::Printer::Sub> FieldVars(const FieldDescriptor* field, + const Options& opts); } // namespace cpp } // namespace compiler } // namespace protobuf |