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/helpers.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/helpers.h')
| -rw-r--r-- | contrib/libs/protoc/src/google/protobuf/compiler/cpp/helpers.h | 387 |
1 files changed, 198 insertions, 189 deletions
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/helpers.h b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/helpers.h index 690a577591e..437c178c60c 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/helpers.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/helpers.h @@ -38,21 +38,27 @@ #include <algorithm> #include <cstdint> #include <iterator> -#include <map> #include <string> - -#include <google/protobuf/compiler/scc.h> -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/compiler/cpp/names.h> -#include <google/protobuf/compiler/cpp/options.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/port.h> -#include <google/protobuf/stubs/strutil.h> +#include <tuple> + +#include "google/protobuf/compiler/scc.h" +#include "google/protobuf/compiler/code_generator.h" +#include "y_absl/container/flat_hash_map.h" +#include "y_absl/log/absl_check.h" +#include "y_absl/strings/match.h" +#include "y_absl/strings/str_split.h" +#include "y_absl/strings/string_view.h" +#include "y_absl/types/optional.h" +#include "google/protobuf/compiler/cpp/names.h" +#include "google/protobuf/compiler/cpp/options.h" +#include "google/protobuf/descriptor.pb.h" +#include "google/protobuf/descriptor.h" +#include "google/protobuf/port.h" +#include "y_absl/strings/str_cat.h" +#include "google/protobuf/io/printer.h" // Must be included last. -#include <google/protobuf/port_def.inc> +#include "google/protobuf/port_def.inc" namespace google { namespace protobuf { @@ -84,19 +90,22 @@ inline TProtoStringType DeprecatedAttribute(const Options& /* options */, extern const char kThickSeparator[]; extern const char kThinSeparator[]; -void SetCommonVars(const Options& options, - std::map<TProtoStringType, TProtoStringType>* variables); +y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> MessageVars( + const Descriptor* desc); // Variables to access message data from the message scope. void SetCommonMessageDataVariables( const Descriptor* descriptor, - std::map<TProtoStringType, TProtoStringType>* variables); + y_absl::flat_hash_map<y_absl::string_view, TProtoStringType>* variables); + +y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> UnknownFieldsVars( + const Descriptor* desc, const Options& opts); -void SetUnknownFieldsVariable(const Descriptor* descriptor, - const Options& options, - std::map<TProtoStringType, TProtoStringType>* variables); +void SetUnknownFieldsVariable( + const Descriptor* descriptor, const Options& options, + y_absl::flat_hash_map<y_absl::string_view, TProtoStringType>* variables); -bool GetBootstrapBasename(const Options& options, const TProtoStringType& basename, +bool GetBootstrapBasename(const Options& options, y_absl::string_view basename, TProtoStringType* bootstrap_basename); bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context, bool bootstrap_flag, TProtoStringType* basename); @@ -110,18 +119,31 @@ TProtoStringType Namespace(const FileDescriptor* d, const Options& options); TProtoStringType Namespace(const Descriptor* d, const Options& options); TProtoStringType Namespace(const FieldDescriptor* d, const Options& options); TProtoStringType Namespace(const EnumDescriptor* d, const Options& options); +PROTOC_EXPORT TProtoStringType Namespace(const FileDescriptor* d); +PROTOC_EXPORT TProtoStringType Namespace(const Descriptor* d); +PROTOC_EXPORT TProtoStringType Namespace(const FieldDescriptor* d); +PROTOC_EXPORT TProtoStringType Namespace(const EnumDescriptor* d); + +class MessageSCCAnalyzer; +// Returns true if it's safe to init "field" to zero. +bool CanInitializeByZeroing(const FieldDescriptor* field, + const Options& options, + MessageSCCAnalyzer* scc_analyzer); // Returns true if it's safe to reset "field" to zero. -bool CanInitializeByZeroing(const FieldDescriptor* field); +bool CanClearByZeroing(const FieldDescriptor* field); +// Determines if swap can be implemented via memcpy. +bool HasTrivialSwap(const FieldDescriptor* field, const Options& options, + MessageSCCAnalyzer* scc_analyzer); -TProtoStringType ClassName(const Descriptor* descriptor); -TProtoStringType ClassName(const EnumDescriptor* enum_descriptor); +PROTOC_EXPORT TProtoStringType ClassName(const Descriptor* descriptor); +PROTOC_EXPORT TProtoStringType ClassName(const EnumDescriptor* enum_descriptor); TProtoStringType QualifiedClassName(const Descriptor* d, const Options& options); TProtoStringType QualifiedClassName(const EnumDescriptor* d, const Options& options); -TProtoStringType QualifiedClassName(const Descriptor* d); -TProtoStringType QualifiedClassName(const EnumDescriptor* d); +PROTOC_EXPORT TProtoStringType QualifiedClassName(const Descriptor* d); +PROTOC_EXPORT TProtoStringType QualifiedClassName(const EnumDescriptor* d); // DEPRECATED just use ClassName or QualifiedClassName, a boolean is very // unreadable at the callsite. @@ -187,13 +209,13 @@ TProtoStringType SuperClassName(const Descriptor* descriptor, const Options& options); // Adds an underscore if necessary to prevent conflicting with a keyword. -TProtoStringType ResolveKeyword(const TProtoStringType& name); +TProtoStringType ResolveKeyword(y_absl::string_view name); // Get the (unqualified) name that should be used for this field in C++ code. // The name is coerced to lower-case to emulate proto1 behavior. People // should be using lowercase-with-underscores style for proto field names // anyway, so normally this just returns field->name(). -TProtoStringType FieldName(const FieldDescriptor* field); +PROTOC_EXPORT TProtoStringType FieldName(const FieldDescriptor* field); // Returns the (unqualified) private member name for this field in C++ code. TProtoStringType FieldMemberName(const FieldDescriptor* field, bool split); @@ -220,7 +242,7 @@ inline const Descriptor* FieldScope(const FieldDescriptor* field) { TProtoStringType FieldMessageTypeName(const FieldDescriptor* field, const Options& options); -// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.). +// Get the C++ type name for a primitive type (e.g. "double", "::int32", etc.). const char* PrimitiveTypeName(FieldDescriptor::CppType type); TProtoStringType PrimitiveTypeName(const Options& options, FieldDescriptor::CppType type); @@ -239,25 +261,25 @@ TProtoStringType DefaultValue(const Options& options, const FieldDescriptor* fie TProtoStringType DefaultValue(const FieldDescriptor* field); // Convert a file name into a valid identifier. -TProtoStringType FilenameIdentifier(const TProtoStringType& filename); +TProtoStringType FilenameIdentifier(y_absl::string_view filename); // For each .proto file generates a unique name. To prevent collisions of // symbols in the global namespace -TProtoStringType UniqueName(const TProtoStringType& name, const TProtoStringType& filename, +TProtoStringType UniqueName(y_absl::string_view name, y_absl::string_view filename, const Options& options); -inline TProtoStringType UniqueName(const TProtoStringType& name, const FileDescriptor* d, +inline TProtoStringType UniqueName(y_absl::string_view name, const FileDescriptor* d, const Options& options) { return UniqueName(name, d->name(), options); } -inline TProtoStringType UniqueName(const TProtoStringType& name, const Descriptor* d, +inline TProtoStringType UniqueName(y_absl::string_view name, const Descriptor* d, const Options& options) { return UniqueName(name, d->file(), options); } -inline TProtoStringType UniqueName(const TProtoStringType& name, const EnumDescriptor* d, +inline TProtoStringType UniqueName(y_absl::string_view name, const EnumDescriptor* d, const Options& options) { return UniqueName(name, d->file(), options); } -inline TProtoStringType UniqueName(const TProtoStringType& name, +inline TProtoStringType UniqueName(y_absl::string_view name, const ServiceDescriptor* d, const Options& options) { return UniqueName(name, d->file(), options); @@ -270,38 +292,36 @@ inline Options InternalRuntimeOptions() { options.opensource_runtime = false; return options; } -inline TProtoStringType UniqueName(const TProtoStringType& name, - const TProtoStringType& filename) { +inline TProtoStringType UniqueName(y_absl::string_view name, + y_absl::string_view filename) { return UniqueName(name, filename, InternalRuntimeOptions()); } -inline TProtoStringType UniqueName(const TProtoStringType& name, - const FileDescriptor* d) { +inline TProtoStringType UniqueName(y_absl::string_view name, const FileDescriptor* d) { return UniqueName(name, d->name(), InternalRuntimeOptions()); } -inline TProtoStringType UniqueName(const TProtoStringType& name, const Descriptor* d) { +inline TProtoStringType UniqueName(y_absl::string_view name, const Descriptor* d) { return UniqueName(name, d->file(), InternalRuntimeOptions()); } -inline TProtoStringType UniqueName(const TProtoStringType& name, - const EnumDescriptor* d) { +inline TProtoStringType UniqueName(y_absl::string_view name, const EnumDescriptor* d) { return UniqueName(name, d->file(), InternalRuntimeOptions()); } -inline TProtoStringType UniqueName(const TProtoStringType& name, +inline TProtoStringType UniqueName(y_absl::string_view name, const ServiceDescriptor* d) { return UniqueName(name, d->file(), InternalRuntimeOptions()); } // Return the qualified C++ name for a file level symbol. TProtoStringType QualifiedFileLevelSymbol(const FileDescriptor* file, - const TProtoStringType& name, + y_absl::string_view name, const Options& options); // Escape C++ trigraphs by escaping question marks to \? -TProtoStringType EscapeTrigraphs(const TProtoStringType& to_escape); +TProtoStringType EscapeTrigraphs(y_absl::string_view to_escape); // Escaped function name to eliminate naming conflict. TProtoStringType SafeFunctionName(const Descriptor* descriptor, const FieldDescriptor* field, - const TProtoStringType& prefix); + y_absl::string_view prefix); // Returns true if generated messages have public unknown fields accessors inline bool PublicUnknownFieldsAccessors(const Descriptor* message) { @@ -321,12 +341,14 @@ inline bool UseUnknownFieldSet(const FileDescriptor* file, inline bool IsWeak(const FieldDescriptor* field, const Options& options) { if (field->options().weak()) { - GOOGLE_CHECK(!options.opensource_runtime); + Y_ABSL_CHECK(!options.opensource_runtime); return true; } return false; } +bool IsProfileDriven(const Options& options); + bool IsStringInlined(const FieldDescriptor* descriptor, const Options& options); // For a string field, returns the effective ctype. If the actual ctype is @@ -350,8 +372,6 @@ inline bool IsStringPiece(const FieldDescriptor* field, EffectiveStringCType(field, options) == FieldOptions::STRING_PIECE; } -class MessageSCCAnalyzer; - // Does the given FileDescriptor use lazy fields? bool HasLazyFields(const FileDescriptor* file, const Options& options, MessageSCCAnalyzer* scc_analyzer); @@ -377,17 +397,16 @@ bool ShouldSplit(const Descriptor* desc, const Options& options); // Is the given field being split out? bool ShouldSplit(const FieldDescriptor* field, const Options& options); +// Should we generate code that force creating an allocation in the constructor +// of the given message? +bool ShouldForceAllocationOnConstruction(const Descriptor* desc, + const Options& options); + inline bool IsFieldUsed(const FieldDescriptor* /* field */, const Options& /* options */) { return true; } -// Returns true if "field" is stripped. -inline bool IsFieldStripped(const FieldDescriptor* /*field*/, - const Options& /*options*/) { - return false; -} - // Does the file contain any definitions that need extension_set.h? bool HasExtensionsOrExtendableMessage(const FileDescriptor* file); @@ -448,42 +467,20 @@ inline bool IsMapEntryMessage(const Descriptor* descriptor) { // Returns true if the field's CPPTYPE is string or message. bool IsStringOrMessage(const FieldDescriptor* field); -TProtoStringType UnderscoresToCamelCase(const TProtoStringType& input, +TProtoStringType UnderscoresToCamelCase(y_absl::string_view input, bool cap_next_letter); inline bool IsProto3(const FileDescriptor* file) { return file->syntax() == FileDescriptor::SYNTAX_PROTO3; } -inline bool HasHasbit(const FieldDescriptor* field) { - // This predicate includes proto3 message fields only if they have "optional". - // Foo submsg1 = 1; // HasHasbit() == false - // optional Foo submsg2 = 2; // HasHasbit() == true - // This is slightly odd, as adding "optional" to a singular proto3 field does - // not change the semantics or API. However whenever any field in a message - // has a hasbit, it forces reflection to include hasbit offsets for *all* - // fields, even if almost all of them are set to -1 (no hasbit). So to avoid - // causing a sudden size regression for ~all proto3 messages, we give proto3 - // message fields a hasbit only if "optional" is present. If the user is - // explicitly writing "optional", it is likely they are writing it on - // primitive fields also. - return (field->has_optional_keyword() || field->is_required()) && - !field->options().weak(); -} - -// Returns true if 'enum' semantics are such that unknown values are preserved -// in the enum field itself, rather than going to the UnknownFieldSet. -inline bool HasPreservingUnknownEnumSemantics(const FieldDescriptor* field) { - return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3; -} - inline bool IsCrossFileMessage(const FieldDescriptor* field) { return field->type() == FieldDescriptor::TYPE_MESSAGE && field->message_type()->file() != field->file(); } inline TProtoStringType MakeDefaultName(const FieldDescriptor* field) { - return StrCat("_i_give_permission_to_break_this_code_default_", + return y_absl::StrCat("_i_give_permission_to_break_this_code_default_", FieldName(field), "_"); } @@ -498,11 +495,11 @@ inline TProtoStringType MakeDefaultName(const FieldDescriptor* field) { // exists at some nested level like: // internal_container_._i_give_permission_to_break_this_code_default_field_; inline TProtoStringType MakeDefaultFieldName(const FieldDescriptor* field) { - return StrCat("Impl_::", MakeDefaultName(field)); + return y_absl::StrCat("Impl_::", MakeDefaultName(field)); } inline TProtoStringType MakeVarintCachedSizeName(const FieldDescriptor* field) { - return StrCat("_", FieldName(field), "_cached_byte_size_"); + return y_absl::StrCat("_", FieldName(field), "_cached_byte_size_"); } // Semantically distinct from MakeVarintCachedSizeName in that it gives the C++ @@ -518,7 +515,7 @@ inline TProtoStringType MakeVarintCachedSizeName(const FieldDescriptor* field) { // internal_container_._field_cached_byte_size_; inline TProtoStringType MakeVarintCachedSizeFieldName(const FieldDescriptor* field, bool split) { - return StrCat("_impl_.", split ? "_split_->" : "", "_", + return y_absl::StrCat("_impl_.", split ? "_split_->" : "", "_", FieldName(field), "_cached_byte_size_"); } @@ -531,20 +528,34 @@ bool IsAnyMessage(const Descriptor* descriptor, const Options& options); bool IsWellKnownMessage(const FileDescriptor* descriptor); -inline TProtoStringType IncludeGuard(const FileDescriptor* file, bool pb_h, - bool deps, +enum class GeneratedFileType : int { kPbH, kProtoH, kProtoStaticReflectionH }; + +inline TProtoStringType IncludeGuard(const FileDescriptor* file, + GeneratedFileType file_type, const Options& options) { // If we are generating a .pb.h file and the proto_h option is enabled, then // the .pb.h gets an extra suffix. - TProtoStringType filename_identifier = FilenameIdentifier( - file->name() + (deps ? ".deps": "") + (pb_h && options.proto_h ? ".pb.h" : "")); + TProtoStringType extension; + switch (file_type) { + case GeneratedFileType::kPbH: + extension = ".pb.h"; + break; + case GeneratedFileType::kProtoH: + extension = ".proto.h"; + break; + case GeneratedFileType::kProtoStaticReflectionH: + extension = ".proto.static_reflection.h"; + } + TProtoStringType filename_identifier = + FilenameIdentifier(file->name() + extension); if (IsWellKnownMessage(file)) { // For well-known messages we need third_party/protobuf and net/proto2 to // have distinct include guards, because some source files include both and // both need to be defined (the third_party copies will be in the // google::protobuf_opensource namespace). - return MacroPrefix(options) + "_INCLUDED_" + filename_identifier; + return y_absl::StrCat(MacroPrefix(options), "_INCLUDED_", + filename_identifier); } else { // Ideally this case would use distinct include guards for opensource and // google3 protos also. (The behavior of "first #included wins" is not @@ -552,7 +563,7 @@ inline TProtoStringType IncludeGuard(const FileDescriptor* file, bool pb_h, // the identical include guards to avoid compile errors. // // We should clean this up so that this case can be removed. - return "GOOGLE_PROTOBUF_INCLUDED_" + filename_identifier; + return y_absl::StrCat("GOOGLE_PROTOBUF_INCLUDED_", filename_identifier); } } @@ -663,7 +674,7 @@ class PROTOC_EXPORT MessageSCCAnalyzer { }; SCCAnalyzer<DepsGenerator> analyzer_; Options options_; - std::map<const SCC*, MessageAnalysis> analysis_cache_; + y_absl::flat_hash_map<const SCC*, MessageAnalysis> analysis_cache_; }; void ListAllFields(const Descriptor* d, @@ -747,6 +758,8 @@ inline bool HasImplData(const Descriptor* desc, const Options& options) { return !HasSimpleBaseClass(desc, options); } +// DO NOT USE IN NEW CODE! Use io::Printer directly instead. See b/242326974. +// // Formatter is a functor class which acts as a closure around printer and // the variable map. It's much like printer->Print except it supports both named // variables that are substituted using a key value map and direct arguments. In @@ -789,15 +802,15 @@ class PROTOC_EXPORT Formatter { public: explicit Formatter(io::Printer* printer) : printer_(printer) {} Formatter(io::Printer* printer, - const std::map<TProtoStringType, TProtoStringType>& vars) + const y_absl::flat_hash_map<y_absl::string_view, TProtoStringType>& vars) : printer_(printer), vars_(vars) {} template <typename T> - void Set(const TProtoStringType& key, const T& value) { + void Set(y_absl::string_view key, const T& value) { vars_[key] = ToString(value); } - void AddMap(const std::map<TProtoStringType, TProtoStringType>& vars) { + void AddMap(const y_absl::flat_hash_map<y_absl::string_view, TProtoStringType>& vars) { for (const auto& keyval : vars) vars_[keyval.first] = keyval.second; } @@ -839,31 +852,69 @@ class PROTOC_EXPORT Formatter { private: Formatter* format_; - std::map<TProtoStringType, TProtoStringType> vars_; + y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> vars_; }; private: io::Printer* printer_; - std::map<TProtoStringType, TProtoStringType> vars_; + y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> vars_; // Convenience overloads to accept different types as arguments. - static TProtoStringType ToString(const TProtoStringType& s) { return s; } + static TProtoStringType ToString(y_absl::string_view s) { return TProtoStringType(s); } template <typename I, typename = typename std::enable_if< std::is_integral<I>::value>::type> static TProtoStringType ToString(I x) { - return StrCat(x); + return y_absl::StrCat(x); + } + static TProtoStringType ToString(y_absl::Hex x) { return y_absl::StrCat(x); } + static TProtoStringType ToString(const FieldDescriptor* d) { + return Payload(d, GeneratedCodeInfo::Annotation::NONE); + } + static TProtoStringType ToString(const Descriptor* d) { + return Payload(d, GeneratedCodeInfo::Annotation::NONE); + } + static TProtoStringType ToString(const EnumDescriptor* d) { + return Payload(d, GeneratedCodeInfo::Annotation::NONE); } - static TProtoStringType ToString(strings::Hex x) { return StrCat(x); } - static TProtoStringType ToString(const FieldDescriptor* d) { return Payload(d); } - static TProtoStringType ToString(const Descriptor* d) { return Payload(d); } - static TProtoStringType ToString(const EnumDescriptor* d) { return Payload(d); } static TProtoStringType ToString(const EnumValueDescriptor* d) { - return Payload(d); + return Payload(d, GeneratedCodeInfo::Annotation::NONE); + } + static TProtoStringType ToString(const OneofDescriptor* d) { + return Payload(d, GeneratedCodeInfo::Annotation::NONE); + } + + static TProtoStringType ToString( + std::tuple<const FieldDescriptor*, + GeneratedCodeInfo::Annotation::Semantic> + p) { + return Payload(std::get<0>(p), std::get<1>(p)); + } + static TProtoStringType ToString( + std::tuple<const Descriptor*, GeneratedCodeInfo::Annotation::Semantic> + p) { + return Payload(std::get<0>(p), std::get<1>(p)); + } + static TProtoStringType ToString( + std::tuple<const EnumDescriptor*, GeneratedCodeInfo::Annotation::Semantic> + p) { + return Payload(std::get<0>(p), std::get<1>(p)); + } + static TProtoStringType ToString( + std::tuple<const EnumValueDescriptor*, + GeneratedCodeInfo::Annotation::Semantic> + p) { + return Payload(std::get<0>(p), std::get<1>(p)); + } + static TProtoStringType ToString( + std::tuple<const OneofDescriptor*, + GeneratedCodeInfo::Annotation::Semantic> + p) { + return Payload(std::get<0>(p), std::get<1>(p)); } - static TProtoStringType ToString(const OneofDescriptor* d) { return Payload(d); } template <typename Descriptor> - static TProtoStringType Payload(const Descriptor* descriptor) { + static TProtoStringType Payload(const Descriptor* descriptor, + GeneratedCodeInfo::Annotation::Semantic semantic) { std::vector<int> path; descriptor->GetLocationPath(&path); GeneratedCodeInfo::Annotation annotation; @@ -871,119 +922,71 @@ class PROTOC_EXPORT Formatter { annotation.add_path(index); } annotation.set_source_file(descriptor->file()->name()); + annotation.set_semantic(semantic); return annotation.SerializeAsString(); } }; -template <class T> -void PrintFieldComment(const Formatter& format, const T* field) { +template <typename T> +TProtoStringType FieldComment(const T* field) { // Print the field's (or oneof's) proto-syntax definition as a comment. // We don't want to print group bodies so we cut off after the first // line. DebugStringOptions options; options.elide_group_body = true; options.elide_oneof_body = true; - TProtoStringType def = field->DebugStringWithOptions(options); - format("// $1$\n", def.substr(0, def.find_first_of('\n'))); + + for (y_absl::string_view chunk : + y_absl::StrSplit(field->DebugStringWithOptions(options), '\n')) { + return TProtoStringType(chunk); + } + + return "<unknown>"; +} + +template <class T> +void PrintFieldComment(const Formatter& format, const T* field) { + format("// $1$\n", FieldComment(field)); } class PROTOC_EXPORT NamespaceOpener { public: - explicit NamespaceOpener(const Formatter& format) - : printer_(format.printer()) {} - NamespaceOpener(const TProtoStringType& name, const Formatter& format) + explicit NamespaceOpener(io::Printer* p) : p_(p) {} + explicit NamespaceOpener(const Formatter& format) : p_(format.printer()) {} + NamespaceOpener(y_absl::string_view name, const Formatter& format) : NamespaceOpener(format) { ChangeTo(name); } + NamespaceOpener(y_absl::string_view name, io::Printer* p) : NamespaceOpener(p) { + ChangeTo(name); + } ~NamespaceOpener() { ChangeTo(""); } - void ChangeTo(const TProtoStringType& name) { - std::vector<TProtoStringType> new_stack_ = - Split(name, "::", true); - size_t len = std::min(name_stack_.size(), new_stack_.size()); - size_t common_idx = 0; - while (common_idx < len) { - if (name_stack_[common_idx] != new_stack_[common_idx]) break; - common_idx++; - } - for (auto it = name_stack_.crbegin(); - it != name_stack_.crend() - common_idx; ++it) { - if (*it == "PROTOBUF_NAMESPACE_ID") { - printer_->Print("PROTOBUF_NAMESPACE_CLOSE\n"); - } else { - printer_->Print("} // namespace $ns$\n", "ns", *it); - } - } - name_stack_.swap(new_stack_); - for (size_t i = common_idx; i < name_stack_.size(); ++i) { - if (name_stack_[i] == "PROTOBUF_NAMESPACE_ID") { - printer_->Print("PROTOBUF_NAMESPACE_OPEN\n"); - } else { - printer_->Print("namespace $ns$ {\n", "ns", name_stack_[i]); - } - } - } + void ChangeTo(y_absl::string_view name); private: - io::Printer* printer_; + io::Printer* p_; std::vector<TProtoStringType> name_stack_; }; -enum class Utf8CheckMode { - kStrict = 0, // Parsing will fail if non UTF-8 data is in string fields. - kVerify = 1, // Only log an error but parsing will succeed. - kNone = 2, // No UTF-8 check. -}; - -Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field, - const Options& options); - void GenerateUtf8CheckCodeForString(const FieldDescriptor* field, const Options& options, bool for_parse, - const char* parameters, + y_absl::string_view parameters, const Formatter& format); void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field, const Options& options, bool for_parse, - const char* parameters, + y_absl::string_view parameters, const Formatter& format); -template <typename T> -struct FieldRangeImpl { - struct Iterator { - using iterator_category = std::forward_iterator_tag; - using value_type = const FieldDescriptor*; - using difference_type = int; - - value_type operator*() { return descriptor->field(idx); } - - friend bool operator==(const Iterator& a, const Iterator& b) { - GOOGLE_DCHECK(a.descriptor == b.descriptor); - return a.idx == b.idx; - } - friend bool operator!=(const Iterator& a, const Iterator& b) { - return !(a == b); - } - - Iterator& operator++() { - idx++; - return *this; - } - - int idx; - const T* descriptor; - }; - - Iterator begin() const { return {0, descriptor}; } - Iterator end() const { return {descriptor->field_count(), descriptor}; } - - const T* descriptor; -}; +void GenerateUtf8CheckCodeForString(io::Printer* p, + const FieldDescriptor* field, + const Options& options, bool for_parse, + y_absl::string_view parameters); -template <typename T> -FieldRangeImpl<T> FieldRange(const T* desc) { - return {desc}; -} +void GenerateUtf8CheckCodeForCord(io::Printer* p, const FieldDescriptor* field, + const Options& options, bool for_parse, + y_absl::string_view parameters); struct OneOfRangeImpl { struct Iterator { @@ -994,7 +997,7 @@ struct OneOfRangeImpl { value_type operator*() { return descriptor->oneof_decl(idx); } friend bool operator==(const Iterator& a, const Iterator& b) { - GOOGLE_DCHECK(a.descriptor == b.descriptor); + Y_ABSL_DCHECK(a.descriptor == b.descriptor); return a.idx == b.idx; } friend bool operator!=(const Iterator& a, const Iterator& b) { @@ -1020,12 +1023,8 @@ struct OneOfRangeImpl { inline OneOfRangeImpl OneOfRange(const Descriptor* desc) { return {desc}; } -PROTOC_EXPORT TProtoStringType StripProto(const TProtoStringType& filename); - -bool EnableMessageOwnedArena(const Descriptor* desc, const Options& options); - -bool EnableMessageOwnedArenaTrial(const Descriptor* desc, - const Options& options); +// Strips ".proto" or ".protodevel" from the end of a filename. +PROTOC_EXPORT TProtoStringType StripProto(y_absl::string_view filename); bool ShouldVerify(const Descriptor* descriptor, const Options& options, MessageSCCAnalyzer* scc_analyzer); @@ -1055,11 +1054,21 @@ bool IsUtf8String(const FieldDescriptor* field); bool HasMessageFieldOrExtension(const Descriptor* desc); +// Generates a vector of substitutions for use with Printer::WithVars that +// contains annotated accessor names for a particular field. +// +// Each substitution will be named `y_absl::StrCat(prefix, "name")`, and will +// be annotated with `field`. +std::vector<io::Printer::Sub> AnnotatedAccessors( + const FieldDescriptor* field, y_absl::Span<const y_absl::string_view> prefixes, + y_absl::optional<google::protobuf::io::AnnotationCollector::Semantic> semantic = + y_absl::nullopt); + } // namespace cpp } // namespace compiler } // namespace protobuf } // namespace google -#include <google/protobuf/port_undef.inc> +#include "google/protobuf/port_undef.inc" #endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ |
