summaryrefslogtreecommitdiffstats
path: root/contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.h
diff options
context:
space:
mode:
authornechda <[email protected]>2024-08-29 23:50:27 +0300
committernechda <[email protected]>2024-08-30 00:05:25 +0300
commite10d6638f07a82edae3ea8197b9f5c0affcc07ea (patch)
tree571c38cec05813766a1ad290c9d51ce7ace52919 /contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.h
parente79b38f2bbbf78d295d1901d2a79f898022d5224 (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.h496
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