Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:11:56

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 // Author: kenton@google.com (Kenton Varda)
0009 //  Based on original Protocol Buffers design by
0010 //  Sanjay Ghemawat, Jeff Dean, and others.
0011 
0012 #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
0013 #define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
0014 
0015 #include <iterator>
0016 #include <string>
0017 #include <tuple>
0018 #include <vector>
0019 
0020 #include "absl/container/flat_hash_map.h"
0021 #include "absl/log/absl_check.h"
0022 #include "absl/strings/str_cat.h"
0023 #include "absl/strings/str_split.h"
0024 #include "absl/strings/string_view.h"
0025 #include "absl/types/optional.h"
0026 #include "google/protobuf/compiler/code_generator.h"
0027 #include "google/protobuf/compiler/cpp/names.h"
0028 #include "google/protobuf/compiler/cpp/options.h"
0029 #include "google/protobuf/compiler/scc.h"
0030 #include "google/protobuf/descriptor.h"
0031 #include "google/protobuf/descriptor.pb.h"
0032 #include "google/protobuf/io/printer.h"
0033 #include "google/protobuf/port.h"
0034 
0035 
0036 // Must be included last.
0037 #include "google/protobuf/port_def.inc"
0038 
0039 namespace google {
0040 namespace protobuf {
0041 namespace compiler {
0042 namespace cpp {
0043 enum class ArenaDtorNeeds { kNone = 0, kOnDemand = 1, kRequired = 2 };
0044 
0045 inline absl::string_view ProtobufNamespace(const Options& opts) {
0046   // This won't be transformed by copybara, since copybara looks for google::protobuf::.
0047   constexpr absl::string_view kGoogle3Ns = "proto2";
0048   constexpr absl::string_view kOssNs = "google::protobuf";
0049 
0050   return opts.opensource_runtime ? kOssNs : kGoogle3Ns;
0051 }
0052 
0053 inline std::string MacroPrefix(const Options& options) {
0054   // Constants are different in the internal and external version.
0055   return options.opensource_runtime ? "GOOGLE_PROTOBUF" : "GOOGLE_PROTOBUF";
0056 }
0057 
0058 inline std::string DeprecatedAttribute(const Options&,
0059                                        const FieldDescriptor* d) {
0060   return d->options().deprecated() ? "[[deprecated]] " : "";
0061 }
0062 
0063 inline std::string DeprecatedAttribute(const Options&,
0064                                        const EnumValueDescriptor* d) {
0065   return d->options().deprecated() ? "[[deprecated]] " : "";
0066 }
0067 
0068 // Commonly-used separator comments.  Thick is a line of '=', thin is a line
0069 // of '-'.
0070 extern const char kThickSeparator[];
0071 extern const char kThinSeparator[];
0072 
0073 absl::flat_hash_map<absl::string_view, std::string> MessageVars(
0074     const Descriptor* desc);
0075 
0076 // Variables to access message data from the message scope.
0077 void SetCommonMessageDataVariables(
0078     const Descriptor* descriptor,
0079     absl::flat_hash_map<absl::string_view, std::string>* variables);
0080 
0081 absl::flat_hash_map<absl::string_view, std::string> UnknownFieldsVars(
0082     const Descriptor* desc, const Options& opts);
0083 
0084 void SetUnknownFieldsVariable(
0085     const Descriptor* descriptor, const Options& options,
0086     absl::flat_hash_map<absl::string_view, std::string>* variables);
0087 
0088 bool GetBootstrapBasename(const Options& options, absl::string_view basename,
0089                           std::string* bootstrap_basename);
0090 bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context,
0091                     bool bootstrap_flag, std::string* basename);
0092 bool IsBootstrapProto(const Options& options, const FileDescriptor* file);
0093 
0094 // Name space of the proto file. This namespace is such that the string
0095 // "<namespace>::some_name" is the correct fully qualified namespace.
0096 // This means if the package is empty the namespace is "", and otherwise
0097 // the namespace is "::foo::bar::...::baz" without trailing semi-colons.
0098 std::string Namespace(const FileDescriptor* d, const Options& options);
0099 std::string Namespace(const Descriptor* d, const Options& options);
0100 std::string Namespace(const FieldDescriptor* d, const Options& options);
0101 std::string Namespace(const EnumDescriptor* d, const Options& options);
0102 PROTOC_EXPORT std::string Namespace(const FileDescriptor* d);
0103 PROTOC_EXPORT std::string Namespace(const Descriptor* d);
0104 PROTOC_EXPORT std::string Namespace(const FieldDescriptor* d);
0105 PROTOC_EXPORT std::string Namespace(const EnumDescriptor* d);
0106 
0107 class MessageSCCAnalyzer;
0108 
0109 // Returns true if it's safe to init "field" to zero.
0110 bool CanInitializeByZeroing(const FieldDescriptor* field,
0111                             const Options& options,
0112                             MessageSCCAnalyzer* scc_analyzer);
0113 // Returns true if it's safe to reset "field" to zero.
0114 bool CanClearByZeroing(const FieldDescriptor* field);
0115 // Determines if swap can be implemented via memcpy.
0116 bool HasTrivialSwap(const FieldDescriptor* field, const Options& options,
0117                     MessageSCCAnalyzer* scc_analyzer);
0118 
0119 PROTOC_EXPORT std::string ClassName(const Descriptor* descriptor);
0120 PROTOC_EXPORT std::string ClassName(const EnumDescriptor* enum_descriptor);
0121 
0122 std::string QualifiedClassName(const Descriptor* d, const Options& options);
0123 std::string QualifiedClassName(const EnumDescriptor* d, const Options& options);
0124 
0125 PROTOC_EXPORT std::string QualifiedClassName(const Descriptor* d);
0126 PROTOC_EXPORT std::string QualifiedClassName(const EnumDescriptor* d);
0127 
0128 // DEPRECATED just use ClassName or QualifiedClassName, a boolean is very
0129 // unreadable at the callsite.
0130 // Returns the non-nested type name for the given type.  If "qualified" is
0131 // true, prefix the type with the full namespace.  For example, if you had:
0132 //   package foo.bar;
0133 //   message Baz { message Moo {} }
0134 // Then the qualified ClassName for Moo would be:
0135 //   ::foo::bar::Baz_Moo
0136 // While the non-qualified version would be:
0137 //   Baz_Moo
0138 inline std::string ClassName(const Descriptor* descriptor, bool qualified) {
0139   return qualified ? QualifiedClassName(descriptor, Options())
0140                    : ClassName(descriptor);
0141 }
0142 
0143 inline std::string ClassName(const EnumDescriptor* descriptor, bool qualified) {
0144   return qualified ? QualifiedClassName(descriptor, Options())
0145                    : ClassName(descriptor);
0146 }
0147 
0148 // Returns the extension name prefixed with the class name if nested but without
0149 // the package name.
0150 std::string ExtensionName(const FieldDescriptor* d);
0151 
0152 std::string QualifiedExtensionName(const FieldDescriptor* d,
0153                                    const Options& options);
0154 std::string QualifiedExtensionName(const FieldDescriptor* d);
0155 
0156 // Type name of default instance.
0157 std::string DefaultInstanceType(const Descriptor* descriptor,
0158                                 const Options& options, bool split = false);
0159 
0160 // Non-qualified name of the default_instance of this message.
0161 std::string DefaultInstanceName(const Descriptor* descriptor,
0162                                 const Options& options, bool split = false);
0163 
0164 // Non-qualified name of the default instance pointer. This is used only for
0165 // implicit weak fields, where we need an extra indirection.
0166 std::string DefaultInstancePtr(const Descriptor* descriptor,
0167                                const Options& options, bool split = false);
0168 
0169 // Fully qualified name of the default_instance of this message.
0170 std::string QualifiedDefaultInstanceName(const Descriptor* descriptor,
0171                                          const Options& options,
0172                                          bool split = false);
0173 
0174 // Fully qualified name of the default instance pointer.
0175 std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor,
0176                                         const Options& options,
0177                                         bool split = false);
0178 
0179 // DescriptorTable variable name.
0180 std::string DescriptorTableName(const FileDescriptor* file,
0181                                 const Options& options);
0182 
0183 // When declaring symbol externs from another file, this macro will supply the
0184 // dllexport needed for the target file, if any.
0185 std::string FileDllExport(const FileDescriptor* file, const Options& options);
0186 
0187 // Name of the base class: google::protobuf::Message or google::protobuf::MessageLite.
0188 std::string SuperClassName(const Descriptor* descriptor,
0189                            const Options& options);
0190 
0191 // Adds an underscore if necessary to prevent conflicting with a keyword.
0192 std::string ResolveKeyword(absl::string_view name);
0193 
0194 // Get the (unqualified) name that should be used for this field in C++ code.
0195 // The name is coerced to lower-case to emulate proto1 behavior.  People
0196 // should be using lowercase-with-underscores style for proto field names
0197 // anyway, so normally this just returns field->name().
0198 PROTOC_EXPORT std::string FieldName(const FieldDescriptor* field);
0199 
0200 // Returns the (unqualified) private member name for this field in C++ code.
0201 std::string FieldMemberName(const FieldDescriptor* field, bool split);
0202 
0203 // Returns an estimate of the compiler's alignment for the field.  This
0204 // can't guarantee to be correct because the generated code could be compiled on
0205 // different systems with different alignment rules.  The estimates below assume
0206 // 64-bit pointers.
0207 int EstimateAlignmentSize(const FieldDescriptor* field);
0208 
0209 // Returns an estimate of the size of the field.  This
0210 // can't guarantee to be correct because the generated code could be compiled on
0211 // different systems with different alignment rules.  The estimates below assume
0212 // 64-bit pointers.
0213 int EstimateSize(const FieldDescriptor* field);
0214 
0215 // Get the unqualified name that should be used for a field's field
0216 // number constant.
0217 std::string FieldConstantName(const FieldDescriptor* field);
0218 
0219 // Returns the scope where the field was defined (for extensions, this is
0220 // different from the message type to which the field applies).
0221 inline const Descriptor* FieldScope(const FieldDescriptor* field) {
0222   return field->is_extension() ? field->extension_scope()
0223                                : field->containing_type();
0224 }
0225 
0226 // Returns the fully-qualified type name field->message_type().  Usually this
0227 // is just ClassName(field->message_type(), true);
0228 std::string FieldMessageTypeName(const FieldDescriptor* field,
0229                                  const Options& options);
0230 
0231 // Get the C++ type name for a primitive type (e.g. "double", "::int32", etc.).
0232 const char* PrimitiveTypeName(FieldDescriptor::CppType type);
0233 std::string PrimitiveTypeName(const Options& options,
0234                               FieldDescriptor::CppType type);
0235 
0236 // Get the declared type name in CamelCase format, as is used e.g. for the
0237 // methods of WireFormat.  For example, TYPE_INT32 becomes "Int32".
0238 const char* DeclaredTypeMethodName(FieldDescriptor::Type type);
0239 
0240 // Return the code that evaluates to the number when compiled.
0241 std::string Int32ToString(int number);
0242 
0243 // Get code that evaluates to the field's default value.
0244 std::string DefaultValue(const Options& options, const FieldDescriptor* field);
0245 
0246 // Compatibility function for callers outside proto2.
0247 std::string DefaultValue(const FieldDescriptor* field);
0248 
0249 // Convert a file name into a valid identifier.
0250 std::string FilenameIdentifier(absl::string_view filename);
0251 
0252 // For each .proto file generates a unique name. To prevent collisions of
0253 // symbols in the global namespace
0254 std::string UniqueName(absl::string_view name, absl::string_view filename,
0255                        const Options& options);
0256 inline std::string UniqueName(absl::string_view name, const FileDescriptor* d,
0257                               const Options& options) {
0258   return UniqueName(name, d->name(), options);
0259 }
0260 inline std::string UniqueName(absl::string_view name, const Descriptor* d,
0261                               const Options& options) {
0262   return UniqueName(name, d->file(), options);
0263 }
0264 inline std::string UniqueName(absl::string_view name, const EnumDescriptor* d,
0265                               const Options& options) {
0266   return UniqueName(name, d->file(), options);
0267 }
0268 inline std::string UniqueName(absl::string_view name,
0269                               const ServiceDescriptor* d,
0270                               const Options& options) {
0271   return UniqueName(name, d->file(), options);
0272 }
0273 
0274 // Versions for call sites that only support the internal runtime (like proto1
0275 // support).
0276 inline Options InternalRuntimeOptions() {
0277   Options options;
0278   options.opensource_runtime = false;
0279   return options;
0280 }
0281 inline std::string UniqueName(absl::string_view name,
0282                               absl::string_view filename) {
0283   return UniqueName(name, filename, InternalRuntimeOptions());
0284 }
0285 inline std::string UniqueName(absl::string_view name, const FileDescriptor* d) {
0286   return UniqueName(name, d->name(), InternalRuntimeOptions());
0287 }
0288 inline std::string UniqueName(absl::string_view name, const Descriptor* d) {
0289   return UniqueName(name, d->file(), InternalRuntimeOptions());
0290 }
0291 inline std::string UniqueName(absl::string_view name, const EnumDescriptor* d) {
0292   return UniqueName(name, d->file(), InternalRuntimeOptions());
0293 }
0294 inline std::string UniqueName(absl::string_view name,
0295                               const ServiceDescriptor* d) {
0296   return UniqueName(name, d->file(), InternalRuntimeOptions());
0297 }
0298 
0299 // Return the qualified C++ name for a file level symbol.
0300 std::string QualifiedFileLevelSymbol(const FileDescriptor* file,
0301                                      absl::string_view name,
0302                                      const Options& options);
0303 
0304 // Escape C++ trigraphs by escaping question marks to \?
0305 std::string EscapeTrigraphs(absl::string_view to_escape);
0306 
0307 // Escaped function name to eliminate naming conflict.
0308 std::string SafeFunctionName(const Descriptor* descriptor,
0309                              const FieldDescriptor* field,
0310                              absl::string_view prefix);
0311 
0312 // Returns the optimize mode for <file>, respecting <options.enforce_lite>.
0313 FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
0314                                         const Options& options);
0315 
0316 // Determines whether unknown fields will be stored in an UnknownFieldSet or
0317 // a string.
0318 inline bool UseUnknownFieldSet(const FileDescriptor* file,
0319                                const Options& options) {
0320   return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
0321 }
0322 
0323 inline bool IsWeak(const FieldDescriptor* field, const Options& options) {
0324   if (field->options().weak()) {
0325     ABSL_CHECK(!options.opensource_runtime);
0326     return true;
0327   }
0328   return false;
0329 }
0330 
0331 inline bool IsCord(const FieldDescriptor* field) {
0332   return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
0333          internal::cpp::EffectiveStringCType(field) == FieldOptions::CORD;
0334 }
0335 
0336 inline bool IsString(const FieldDescriptor* field) {
0337   return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
0338          internal::cpp::EffectiveStringCType(field) == FieldOptions::STRING;
0339 }
0340 
0341 inline bool IsStringPiece(const FieldDescriptor* field) {
0342   return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
0343          internal::cpp::EffectiveStringCType(field) ==
0344              FieldOptions::STRING_PIECE;
0345 }
0346 
0347 bool IsProfileDriven(const Options& options);
0348 
0349 // Returns true if `field` is unlikely to be present based on PDProto profile.
0350 bool IsRarelyPresent(const FieldDescriptor* field, const Options& options);
0351 
0352 // Returns true if `field` is likely to be present based on PDProto profile.
0353 bool IsLikelyPresent(const FieldDescriptor* field, const Options& options);
0354 
0355 float GetPresenceProbability(const FieldDescriptor* field,
0356                              const Options& options);
0357 
0358 bool IsStringInliningEnabled(const Options& options);
0359 
0360 // Returns true if the provided field is a singular string and can be inlined.
0361 bool CanStringBeInlined(const FieldDescriptor* field);
0362 
0363 // Returns true if `field` is a string field that can and should be inlined
0364 // based on PDProto profile.
0365 bool IsStringInlined(const FieldDescriptor* field, const Options& options);
0366 
0367 // Returns true if `field` should be inlined based on PDProto profile.
0368 // Currently we only enable inlining for string fields backed by a std::string
0369 // instance, but in the future we may expand this to message types.
0370 inline bool IsFieldInlined(const FieldDescriptor* field,
0371                            const Options& options) {
0372   return IsStringInlined(field, options);
0373 }
0374 
0375 // Does the given FileDescriptor use lazy fields?
0376 bool HasLazyFields(const FileDescriptor* file, const Options& options,
0377                    MessageSCCAnalyzer* scc_analyzer);
0378 
0379 // Is the given field a supported lazy field?
0380 bool IsLazy(const FieldDescriptor* field, const Options& options,
0381             MessageSCCAnalyzer* scc_analyzer);
0382 
0383 // Is this an explicit (non-profile driven) lazy field, as denoted by
0384 // lazy/unverified_lazy in the descriptor?
0385 inline bool IsExplicitLazy(const FieldDescriptor* field) {
0386   if (field->is_map() || field->is_repeated()) {
0387     return false;
0388   }
0389 
0390   if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
0391     return false;
0392   }
0393 
0394   return field->options().lazy() || field->options().unverified_lazy();
0395 }
0396 
0397 internal::field_layout::TransformValidation GetLazyStyle(
0398     const FieldDescriptor* field, const Options& options,
0399     MessageSCCAnalyzer* scc_analyzer);
0400 
0401 bool IsEagerlyVerifiedLazy(const FieldDescriptor* field, const Options& options,
0402                            MessageSCCAnalyzer* scc_analyzer);
0403 
0404 bool IsLazilyVerifiedLazy(const FieldDescriptor* field, const Options& options);
0405 
0406 bool ShouldVerify(const Descriptor* descriptor, const Options& options,
0407                   MessageSCCAnalyzer* scc_analyzer);
0408 bool ShouldVerify(const FileDescriptor* file, const Options& options,
0409                   MessageSCCAnalyzer* scc_analyzer);
0410 bool ShouldVerifyRecursively(const FieldDescriptor* field);
0411 
0412 // Indicates whether to use predefined verify methods for a given message. If a
0413 // message is "simple" and needs no special verification per field (e.g. message
0414 // field, repeated packed, UTF8 string, etc.), we can use either VerifySimple or
0415 // VerifySimpleAlwaysCheckInt32 methods as all verification can be done based on
0416 // the wire type.
0417 //
0418 // Otherwise, we need "custom" verify methods tailored to a message to pass
0419 // which field needs a special verification; i.e. InternalVerify.
0420 enum class VerifySimpleType {
0421   kSimpleInt32Never,   // Use VerifySimple
0422   kSimpleInt32Always,  // Use VerifySimpleAlwaysCheckInt32
0423   kCustom,             // Use InternalVerify and check only for int32
0424   kCustomInt32Never,   // Use InternalVerify but never check for int32
0425   kCustomInt32Always,  // Use InternalVerify and always check for int32
0426 };
0427 
0428 // Returns VerifySimpleType if messages can be verified by predefined methods.
0429 VerifySimpleType ShouldVerifySimple(const Descriptor* descriptor);
0430 
0431 
0432 // Is the given message being split (go/pdsplit)?
0433 bool ShouldSplit(const Descriptor* desc, const Options& options);
0434 
0435 // Is the given field being split out?
0436 bool ShouldSplit(const FieldDescriptor* field, const Options& options);
0437 
0438 // Should we generate code that force creating an allocation in the constructor
0439 // of the given message?
0440 bool ShouldForceAllocationOnConstruction(const Descriptor* desc,
0441                                          const Options& options);
0442 
0443 // Returns true if the message is present based on PDProto profile.
0444 bool IsPresentMessage(const Descriptor* descriptor, const Options& options);
0445 
0446 // Returns the most likely present field. Returns nullptr if not profile driven.
0447 const FieldDescriptor* FindHottestField(
0448     const std::vector<const FieldDescriptor*>& fields, const Options& options);
0449 
0450 // Does the file contain any definitions that need extension_set.h?
0451 bool HasExtensionsOrExtendableMessage(const FileDescriptor* file);
0452 
0453 // Does the file have any repeated fields, necessitating the file to include
0454 // repeated_field.h? This does not include repeated extensions, since those are
0455 // all stored internally in an ExtensionSet, not a separate RepeatedField*.
0456 bool HasRepeatedFields(const FileDescriptor* file);
0457 
0458 // Does the file have any string/bytes fields with ctype=STRING_PIECE? This
0459 // does not include extensions, since ctype is ignored for extensions.
0460 bool HasStringPieceFields(const FileDescriptor* file, const Options& options);
0461 
0462 // Does the file have any string/bytes fields with ctype=CORD? This does not
0463 // include extensions, since ctype is ignored for extensions.
0464 bool HasCordFields(const FileDescriptor* file, const Options& options);
0465 
0466 // Does the file have any map fields, necessitating the file to include
0467 // map_field_inl.h and map.h.
0468 bool HasMapFields(const FileDescriptor* file);
0469 
0470 // Does this file have any enum type definitions?
0471 bool HasEnumDefinitions(const FileDescriptor* file);
0472 
0473 // Does this file have generated parsing, serialization, and other
0474 // standard methods for which reflection-based fallback implementations exist?
0475 inline bool HasGeneratedMethods(const FileDescriptor* file,
0476                                 const Options& options) {
0477   return GetOptimizeFor(file, options) != FileOptions::CODE_SIZE;
0478 }
0479 
0480 // Do message classes in this file have descriptor and reflection methods?
0481 inline bool HasDescriptorMethods(const FileDescriptor* file,
0482                                  const Options& options) {
0483   return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
0484 }
0485 
0486 // Should we generate generic services for this file?
0487 inline bool HasGenericServices(const FileDescriptor* file,
0488                                const Options& options) {
0489   return file->service_count() > 0 &&
0490          GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME &&
0491          file->options().cc_generic_services();
0492 }
0493 
0494 inline bool IsProto2MessageSet(const Descriptor* descriptor,
0495                                const Options& options) {
0496   return !options.opensource_runtime &&
0497          options.enforce_mode != EnforceOptimizeMode::kLiteRuntime &&
0498          !options.lite_implicit_weak_fields &&
0499          descriptor->options().message_set_wire_format() &&
0500          descriptor->full_name() == "google.protobuf.bridge.MessageSet";
0501 }
0502 
0503 inline bool IsMapEntryMessage(const Descriptor* descriptor) {
0504   return descriptor->options().map_entry();
0505 }
0506 
0507 // Returns true if the field's CPPTYPE is string or message.
0508 bool IsStringOrMessage(const FieldDescriptor* field);
0509 
0510 std::string UnderscoresToCamelCase(absl::string_view input,
0511                                    bool cap_next_letter);
0512 
0513 inline bool IsCrossFileMessage(const FieldDescriptor* field) {
0514   return field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
0515          field->message_type()->file() != field->file();
0516 }
0517 
0518 inline std::string MakeDefaultName(const FieldDescriptor* field) {
0519   return absl::StrCat("_i_give_permission_to_break_this_code_default_",
0520                       FieldName(field), "_");
0521 }
0522 
0523 // Semantically distinct from MakeDefaultName in that it gives the C++ code
0524 // referencing a default field from the message scope, rather than just the
0525 // variable name.
0526 // For example, declarations of default variables should always use just
0527 // MakeDefaultName to produce code like:
0528 //   Type _i_give_permission_to_break_this_code_default_field_;
0529 //
0530 // Code that references these should use MakeDefaultFieldName, in case the field
0531 // exists at some nested level like:
0532 //   internal_container_._i_give_permission_to_break_this_code_default_field_;
0533 inline std::string MakeDefaultFieldName(const FieldDescriptor* field) {
0534   return absl::StrCat("Impl_::", MakeDefaultName(field));
0535 }
0536 
0537 inline std::string MakeVarintCachedSizeName(const FieldDescriptor* field) {
0538   return absl::StrCat("_", FieldName(field), "_cached_byte_size_");
0539 }
0540 
0541 // Semantically distinct from MakeVarintCachedSizeName in that it gives the C++
0542 // code referencing the object from the message scope, rather than just the
0543 // variable name.
0544 // For example, declarations of default variables should always use just
0545 // MakeVarintCachedSizeName to produce code like:
0546 //   Type _field_cached_byte_size_;
0547 //
0548 // Code that references these variables should use
0549 // MakeVarintCachedSizeFieldName, in case the field exists at some nested level
0550 // like:
0551 //   internal_container_._field_cached_byte_size_;
0552 inline std::string MakeVarintCachedSizeFieldName(const FieldDescriptor* field,
0553                                                  bool split) {
0554   return absl::StrCat("_impl_.", split ? "_split_->" : "", "_",
0555                       FieldName(field), "_cached_byte_size_");
0556 }
0557 
0558 // Note: A lot of libraries detect Any protos based on Descriptor::full_name()
0559 // while the two functions below use FileDescriptor::name(). In a sane world the
0560 // two approaches should be equivalent. But if you are dealing with descriptors
0561 // from untrusted sources, you might need to match semantics across libraries.
0562 bool IsAnyMessage(const FileDescriptor* descriptor);
0563 bool IsAnyMessage(const Descriptor* descriptor);
0564 
0565 bool IsWellKnownMessage(const FileDescriptor* descriptor);
0566 
0567 enum class GeneratedFileType : int { kPbH, kProtoH, kProtoStaticReflectionH };
0568 
0569 inline std::string IncludeGuard(const FileDescriptor* file,
0570                                 GeneratedFileType file_type,
0571                                 const Options& options) {
0572   // If we are generating a .pb.h file and the proto_h option is enabled, then
0573   // the .pb.h gets an extra suffix.
0574   std::string extension;
0575   switch (file_type) {
0576     case GeneratedFileType::kPbH:
0577       extension = ".pb.h";
0578       break;
0579     case GeneratedFileType::kProtoH:
0580       extension = ".proto.h";
0581       break;
0582     case GeneratedFileType::kProtoStaticReflectionH:
0583       extension = ".proto.static_reflection.h";
0584   }
0585   std::string filename_identifier =
0586       FilenameIdentifier(absl::StrCat(file->name(), extension));
0587 
0588   if (IsWellKnownMessage(file)) {
0589     // For well-known messages we need third_party/protobuf and net/proto2 to
0590     // have distinct include guards, because some source files include both and
0591     // both need to be defined (the third_party copies will be in the
0592     // google::protobuf_opensource namespace).
0593     return absl::StrCat(MacroPrefix(options), "_INCLUDED_",
0594                         filename_identifier);
0595   } else {
0596     // Ideally this case would use distinct include guards for opensource and
0597     // google3 protos also.  (The behavior of "first #included wins" is not
0598     // ideal).  But unfortunately some legacy code includes both and depends on
0599     // the identical include guards to avoid compile errors.
0600     //
0601     // We should clean this up so that this case can be removed.
0602     return absl::StrCat("GOOGLE_PROTOBUF_INCLUDED_", filename_identifier);
0603   }
0604 }
0605 
0606 // Returns the OptimizeMode for this file, furthermore it updates a status
0607 // bool if has_opt_codesize_extension is non-null. If this status bool is true
0608 // it means this file contains an extension that itself is defined as
0609 // optimized_for = CODE_SIZE.
0610 FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
0611                                         const Options& options,
0612                                         bool* has_opt_codesize_extension);
0613 inline FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
0614                                                const Options& options) {
0615   return GetOptimizeFor(file, options, nullptr);
0616 }
0617 inline bool NeedsEagerDescriptorAssignment(const FileDescriptor* file,
0618                                            const Options& options) {
0619   bool has_opt_codesize_extension;
0620   if (GetOptimizeFor(file, options, &has_opt_codesize_extension) ==
0621           FileOptions::CODE_SIZE &&
0622       has_opt_codesize_extension) {
0623     // If this filedescriptor contains an extension from another file which
0624     // is optimized_for = CODE_SIZE. We need to be careful in the ordering so
0625     // we eagerly build the descriptors in the dependencies before building
0626     // the descriptors of this file.
0627     return true;
0628   } else {
0629     // If we have a generated code based parser we never need eager
0630     // initialization of descriptors of our deps.
0631     return false;
0632   }
0633 }
0634 
0635 // This orders the messages in a .pb.cc as it's outputted by file.cc
0636 void FlattenMessagesInFile(const FileDescriptor* file,
0637                            std::vector<const Descriptor*>* result);
0638 inline std::vector<const Descriptor*> FlattenMessagesInFile(
0639     const FileDescriptor* file) {
0640   std::vector<const Descriptor*> result;
0641   FlattenMessagesInFile(file, &result);
0642   return result;
0643 }
0644 
0645 std::vector<const Descriptor*> TopologicalSortMessagesInFile(
0646     const FileDescriptor* file, MessageSCCAnalyzer& scc_analyzer);
0647 
0648 bool HasWeakFields(const Descriptor* desc, const Options& options);
0649 bool HasWeakFields(const FileDescriptor* desc, const Options& options);
0650 
0651 // Returns true if the "required" restriction check should be ignored for the
0652 // given field.
0653 inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field,
0654                                                   const Options& options) {
0655   // Do not check "required" for lazily verified lazy fields.
0656   return IsLazilyVerifiedLazy(field, options);
0657 }
0658 
0659 struct MessageAnalysis {
0660   bool is_recursive = false;
0661   bool contains_cord = false;
0662   bool contains_extension = false;
0663   bool contains_required = false;
0664   bool contains_weak = false;  // Implicit weak as well.
0665 };
0666 
0667 // This class is used in FileGenerator, to ensure linear instead of
0668 // quadratic performance, if we do this per message we would get O(V*(V+E)).
0669 // Logically this is just only used in message.cc, but in the header for
0670 // FileGenerator to help share it.
0671 class PROTOC_EXPORT MessageSCCAnalyzer {
0672  public:
0673   explicit MessageSCCAnalyzer(const Options& options) : options_(options) {}
0674 
0675   MessageAnalysis GetSCCAnalysis(const SCC* scc);
0676 
0677   bool HasRequiredFields(const Descriptor* descriptor) {
0678     MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor));
0679     return result.contains_required || result.contains_extension;
0680   }
0681   bool HasWeakField(const Descriptor* descriptor) {
0682     MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor));
0683     return result.contains_weak;
0684   }
0685   const SCC* GetSCC(const Descriptor* descriptor) {
0686     return analyzer_.GetSCC(descriptor);
0687   }
0688 
0689  private:
0690   struct DepsGenerator {
0691     std::vector<const Descriptor*> operator()(const Descriptor* desc) const {
0692       std::vector<const Descriptor*> deps;
0693       for (int i = 0; i < desc->field_count(); i++) {
0694         if (desc->field(i)->message_type()) {
0695           deps.push_back(desc->field(i)->message_type());
0696         }
0697       }
0698       return deps;
0699     }
0700   };
0701   SCCAnalyzer<DepsGenerator> analyzer_;
0702   Options options_;
0703   absl::flat_hash_map<const SCC*, MessageAnalysis> analysis_cache_;
0704 };
0705 
0706 void ListAllFields(const Descriptor* d,
0707                    std::vector<const FieldDescriptor*>* fields);
0708 void ListAllFields(const FileDescriptor* d,
0709                    std::vector<const FieldDescriptor*>* fields);
0710 
0711 template <bool do_nested_types, class T>
0712 void ForEachField(const Descriptor* d, T&& func) {
0713   if (do_nested_types) {
0714     for (int i = 0; i < d->nested_type_count(); i++) {
0715       ForEachField<true>(d->nested_type(i), std::forward<T&&>(func));
0716     }
0717   }
0718   for (int i = 0; i < d->extension_count(); i++) {
0719     func(d->extension(i));
0720   }
0721   for (int i = 0; i < d->field_count(); i++) {
0722     func(d->field(i));
0723   }
0724 }
0725 
0726 template <class T>
0727 void ForEachField(const FileDescriptor* d, T&& func) {
0728   for (int i = 0; i < d->message_type_count(); i++) {
0729     ForEachField<true>(d->message_type(i), std::forward<T&&>(func));
0730   }
0731   for (int i = 0; i < d->extension_count(); i++) {
0732     func(d->extension(i));
0733   }
0734 }
0735 
0736 void ListAllTypesForServices(const FileDescriptor* fd,
0737                              std::vector<const Descriptor*>* types);
0738 
0739 // Whether this type should use the implicit weak feature for descriptor based
0740 // objects.
0741 //
0742 // This feature allows tree shaking within a single translation unit by
0743 // decoupling the messages from the TU-wide `file_default_instances` array.
0744 // This way there are no static initializers in the TU pointing to any part of
0745 // the generated classes and they can be GC'd by the linker.
0746 // Instead of direct use, we have two ways to weakly refer to the default
0747 // instances:
0748 //  - Each default instance is located on its own section, and we use a
0749 //    `&__start_section_name` pointer to access it. This is a reference that
0750 //    allows GC to happen. This step is used with dynamic linking.
0751 //  - We also allow merging all these sections at link time into the
0752 //    `pb_defaults` section. All surviving messages will be injected back into
0753 //    the `file_default_instances` when the runtime is initialized. This is
0754 //    useful when doing static linking and you want to avoid having an unbounded
0755 //    number of sections.
0756 //
0757 // Any object that gets GC'd will have a `nullptr` in the respective slot in the
0758 // `file_default_instances` array. The runtime will recognize this and will
0759 // dynamically generate the object if needed. This logic is in the
0760 // `GeneratedMessageFactory::GetPrototype`.  It will fall back to a
0761 // `DynamicMessage` for the missing objects.
0762 // This allows all of reflection to keep working normally, even for types that
0763 // were dropped. Note that dropping the _classes_ will not drop the descriptor
0764 // information. The messages are still going to be registered in the generated
0765 // `DescriptorPool` and will be available via normal `FindMessageTypeByName` and
0766 // friends.
0767 //
0768 // A "pin" is adding dependency edge in the graph for the GC.
0769 // The default instance and vtable of a message pin each other. If any one
0770 // lives, they both do. This is important. The default instance of the message
0771 // pins the vtable trivially by using it. The vtable pins the default instance
0772 // by having a StrongPointer into it from any of the virtual functions.
0773 //
0774 // All parent messages pin their children.
0775 // SPEED messages do this implicitly via the TcParseTable, which contain
0776 // pointers to the submessages.
0777 // CODE_SIZE messages explicitly add a pin via `StrongPointer` somewhere in
0778 // their codegen.
0779 // LITE messages do not participate at all in this feature.
0780 //
0781 // For extensions, the identifiers currently pin the extendee. The extended is
0782 // assumed to by pinned elsewhere since we already have an instance of it when
0783 // we call `.GetExtension` et al. The extension identifier itself is not
0784 // automatically pinned, so it has to be used to participate in the graph.
0785 // Registration of the extensions do not pin the extended or the extendee. At
0786 // registration time we will eagerly create a prototype object if one is
0787 // missing to insert in the extension table in ExtensionSet.
0788 //
0789 // For services, the TU unconditionally pins the request/response objects.
0790 // This is the status quo for simplicitly to avoid modifying the RPC layer. It
0791 // might be improved in the future.
0792 bool UsingImplicitWeakDescriptor(const FileDescriptor* file,
0793                                  const Options& options);
0794 
0795 // Generates a strong reference to the message in `desc`, as a statement.
0796 std::string StrongReferenceToType(const Descriptor* desc,
0797                                   const Options& options);
0798 
0799 // Generates the section name to be used for a data object when using implicit
0800 // weak descriptors. The prefix determines the kind of object and the section it
0801 // will be merged into afterwards.
0802 // See `UsingImplicitWeakDescriptor` above.
0803 std::string WeakDescriptorDataSection(absl::string_view prefix,
0804                                       const Descriptor* descriptor,
0805                                       int index_in_file_messages,
0806                                       const Options& options);
0807 
0808 // Section name to be used for the default instance for implicit weak descriptor
0809 // objects. See `UsingImplicitWeakDescriptor` above.
0810 inline std::string WeakDefaultInstanceSection(const Descriptor* descriptor,
0811                                               int index_in_file_messages,
0812                                               const Options& options) {
0813   return WeakDescriptorDataSection("def", descriptor, index_in_file_messages,
0814                                    options);
0815 }
0816 
0817 // Indicates whether we should use implicit weak fields for this file.
0818 bool UsingImplicitWeakFields(const FileDescriptor* file,
0819                              const Options& options);
0820 
0821 // Indicates whether to treat this field as implicitly weak.
0822 bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
0823                          MessageSCCAnalyzer* scc_analyzer);
0824 
0825 inline std::string SimpleBaseClass(const Descriptor* desc,
0826                                    const Options& options) {
0827   // The only base class we have derived from `Message`.
0828   if (!HasDescriptorMethods(desc->file(), options)) return "";
0829   // We don't use the base class to be able to inject the weak descriptor pins.
0830   if (UsingImplicitWeakDescriptor(desc->file(), options)) return "";
0831   if (desc->extension_range_count() != 0) return "";
0832   // Don't use a simple base class if the field tracking is enabled. This
0833   // ensures generating all methods to track.
0834   if (options.field_listener_options.inject_field_listener_events) return "";
0835   if (desc->field_count() == 0) {
0836     return "ZeroFieldsBase";
0837   }
0838   // TODO: Support additional common message types with only one
0839   // or two fields
0840   return "";
0841 }
0842 
0843 inline bool HasSimpleBaseClass(const Descriptor* desc, const Options& options) {
0844   return !SimpleBaseClass(desc, options).empty();
0845 }
0846 
0847 inline bool HasSimpleBaseClasses(const FileDescriptor* file,
0848                                  const Options& options) {
0849   return internal::cpp::VisitDescriptorsInFileOrder(
0850       file, [&](const Descriptor* desc) {
0851         return HasSimpleBaseClass(desc, options);
0852       });
0853 }
0854 
0855 // Returns true if this message has a _tracker_ field.
0856 inline bool HasTracker(const Descriptor* desc, const Options& options) {
0857   return options.field_listener_options.inject_field_listener_events &&
0858          desc->file()->options().optimize_for() !=
0859              google::protobuf::FileOptions::LITE_RUNTIME &&
0860          !IsMapEntryMessage(desc);
0861 }
0862 
0863 // Returns true if this message needs an Impl_ struct for it's data.
0864 inline bool HasImplData(const Descriptor* desc, const Options& options) {
0865   return !HasSimpleBaseClass(desc, options);
0866 }
0867 
0868 // DO NOT USE IN NEW CODE! Use io::Printer directly instead. See b/242326974.
0869 //
0870 // Formatter is a functor class which acts as a closure around printer and
0871 // the variable map. It's much like printer->Print except it supports both named
0872 // variables that are substituted using a key value map and direct arguments. In
0873 // the format string $1$, $2$, etc... are substituted for the first, second, ...
0874 // direct argument respectively in the format call, it accepts both strings and
0875 // integers. The implementation verifies all arguments are used and are "first"
0876 // used in order of appearance in the argument list. For example,
0877 //
0878 // Format("return array[$1$];", 3) -> "return array[3];"
0879 // Format("array[$2$] = $1$;", "Bla", 3) -> FATAL error (wrong order)
0880 // Format("array[$1$] = $2$;", 3, "Bla") -> "array[3] = Bla;"
0881 //
0882 // The arguments can be used more than once like
0883 //
0884 // Format("array[$1$] = $2$;  // Index = $1$", 3, "Bla") ->
0885 //        "array[3] = Bla;  // Index = 3"
0886 //
0887 // If you use more arguments use the following style to help the reader,
0888 //
0889 // Format("int $1$() {\n"
0890 //        "  array[$2$] = $3$;\n"
0891 //        "  return $4$;"
0892 //        "}\n",
0893 //        funname, // 1
0894 //        idx,  // 2
0895 //        varname,  // 3
0896 //        retval);  // 4
0897 //
0898 // but consider using named variables. Named variables like $foo$, with some
0899 // identifier foo, are looked up in the map. One additional feature is that
0900 // spaces are accepted between the '$' delimiters, $ foo$ will
0901 // substitute to " bar" if foo stands for "bar", but in case it's empty
0902 // will substitute to "". Hence, for example,
0903 //
0904 // Format(vars, "$dllexport $void fun();") -> "void fun();"
0905 //                                            "__declspec(export) void fun();"
0906 //
0907 // which is convenient to prevent double, leading or trailing spaces.
0908 class PROTOC_EXPORT Formatter {
0909  public:
0910   explicit Formatter(io::Printer* printer) : printer_(printer) {}
0911   Formatter(io::Printer* printer,
0912             const absl::flat_hash_map<absl::string_view, std::string>& vars)
0913       : printer_(printer), vars_(vars) {}
0914 
0915   template <typename T>
0916   void Set(absl::string_view key, const T& value) {
0917     vars_[key] = ToString(value);
0918   }
0919 
0920   template <typename... Args>
0921   void operator()(const char* format, const Args&... args) const {
0922     printer_->FormatInternal({ToString(args)...}, vars_, format);
0923   }
0924 
0925   void Indent() const { printer_->Indent(); }
0926   void Outdent() const { printer_->Outdent(); }
0927   io::Printer* printer() const { return printer_; }
0928 
0929   class PROTOC_EXPORT ScopedIndenter {
0930    public:
0931     explicit ScopedIndenter(Formatter* format) : format_(format) {
0932       format_->Indent();
0933     }
0934     ~ScopedIndenter() { format_->Outdent(); }
0935 
0936    private:
0937     Formatter* format_;
0938   };
0939 
0940   PROTOBUF_NODISCARD ScopedIndenter ScopedIndent() {
0941     return ScopedIndenter(this);
0942   }
0943   template <typename... Args>
0944   PROTOBUF_NODISCARD ScopedIndenter ScopedIndent(const char* format,
0945                                                  const Args&&... args) {
0946     (*this)(format, static_cast<Args&&>(args)...);
0947     return ScopedIndenter(this);
0948   }
0949 
0950  private:
0951   io::Printer* printer_;
0952   absl::flat_hash_map<absl::string_view, std::string> vars_;
0953 
0954   // Convenience overloads to accept different types as arguments.
0955   static std::string ToString(absl::string_view s) { return std::string(s); }
0956   template <typename I, typename = typename std::enable_if<
0957                             std::is_integral<I>::value>::type>
0958   static std::string ToString(I x) {
0959     return absl::StrCat(x);
0960   }
0961   static std::string ToString(absl::Hex x) { return absl::StrCat(x); }
0962   static std::string ToString(const FieldDescriptor* d) {
0963     return Payload(d, GeneratedCodeInfo::Annotation::NONE);
0964   }
0965   static std::string ToString(const Descriptor* d) {
0966     return Payload(d, GeneratedCodeInfo::Annotation::NONE);
0967   }
0968   static std::string ToString(const EnumDescriptor* d) {
0969     return Payload(d, GeneratedCodeInfo::Annotation::NONE);
0970   }
0971   static std::string ToString(const EnumValueDescriptor* d) {
0972     return Payload(d, GeneratedCodeInfo::Annotation::NONE);
0973   }
0974   static std::string ToString(const OneofDescriptor* d) {
0975     return Payload(d, GeneratedCodeInfo::Annotation::NONE);
0976   }
0977 
0978   static std::string ToString(
0979       std::tuple<const FieldDescriptor*,
0980                  GeneratedCodeInfo::Annotation::Semantic>
0981           p) {
0982     return Payload(std::get<0>(p), std::get<1>(p));
0983   }
0984   static std::string ToString(
0985       std::tuple<const Descriptor*, GeneratedCodeInfo::Annotation::Semantic>
0986           p) {
0987     return Payload(std::get<0>(p), std::get<1>(p));
0988   }
0989   static std::string ToString(
0990       std::tuple<const EnumDescriptor*, GeneratedCodeInfo::Annotation::Semantic>
0991           p) {
0992     return Payload(std::get<0>(p), std::get<1>(p));
0993   }
0994   static std::string ToString(
0995       std::tuple<const EnumValueDescriptor*,
0996                  GeneratedCodeInfo::Annotation::Semantic>
0997           p) {
0998     return Payload(std::get<0>(p), std::get<1>(p));
0999   }
1000   static std::string ToString(
1001       std::tuple<const OneofDescriptor*,
1002                  GeneratedCodeInfo::Annotation::Semantic>
1003           p) {
1004     return Payload(std::get<0>(p), std::get<1>(p));
1005   }
1006 
1007   template <typename Descriptor>
1008   static std::string Payload(const Descriptor* descriptor,
1009                              GeneratedCodeInfo::Annotation::Semantic semantic) {
1010     std::vector<int> path;
1011     descriptor->GetLocationPath(&path);
1012     GeneratedCodeInfo::Annotation annotation;
1013     for (int index : path) {
1014       annotation.add_path(index);
1015     }
1016     annotation.set_source_file(descriptor->file()->name());
1017     annotation.set_semantic(semantic);
1018     return annotation.SerializeAsString();
1019   }
1020 };
1021 
1022 template <typename T>
1023 std::string FieldComment(const T* field, const Options& options) {
1024   if (options.strip_nonfunctional_codegen) {
1025     return std::string(field->name());
1026   }
1027   // Print the field's (or oneof's) proto-syntax definition as a comment.
1028   // We don't want to print group bodies so we cut off after the first
1029   // line.
1030   DebugStringOptions debug_options;
1031   debug_options.elide_group_body = true;
1032   debug_options.elide_oneof_body = true;
1033 
1034   for (absl::string_view chunk :
1035        absl::StrSplit(field->DebugStringWithOptions(debug_options), '\n')) {
1036     return std::string(chunk);
1037   }
1038 
1039   return "<unknown>";
1040 }
1041 
1042 template <class T>
1043 void PrintFieldComment(const Formatter& format, const T* field,
1044                        const Options& options) {
1045   format("// $1$\n", FieldComment(field, options));
1046 }
1047 
1048 class PROTOC_EXPORT NamespaceOpener {
1049  public:
1050   explicit NamespaceOpener(
1051       io::Printer* p,
1052       io::Printer::SourceLocation loc = io::Printer::SourceLocation::current())
1053       : p_(p), loc_(loc) {}
1054 
1055   explicit NamespaceOpener(
1056       const Formatter& format,
1057       io::Printer::SourceLocation loc = io::Printer::SourceLocation::current())
1058       : NamespaceOpener(format.printer(), loc) {}
1059 
1060   NamespaceOpener(
1061       absl::string_view name, const Formatter& format,
1062       io::Printer::SourceLocation loc = io::Printer::SourceLocation::current())
1063       : NamespaceOpener(name, format.printer(), loc) {}
1064 
1065   NamespaceOpener(
1066       absl::string_view name, io::Printer* p,
1067       io::Printer::SourceLocation loc = io::Printer::SourceLocation::current())
1068       : NamespaceOpener(p, loc) {
1069     ChangeTo(name, loc);
1070   }
1071 
1072   ~NamespaceOpener() { ChangeTo("", loc_); }
1073 
1074   void ChangeTo(
1075       absl::string_view name,
1076       io::Printer::SourceLocation loc = io::Printer::SourceLocation::current());
1077 
1078  private:
1079   io::Printer* p_;
1080   io::Printer::SourceLocation loc_;
1081   std::vector<std::string> name_stack_;
1082 };
1083 
1084 void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
1085                                     const Options& options, bool for_parse,
1086                                     absl::string_view parameters,
1087                                     const Formatter& format);
1088 
1089 void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
1090                                   const Options& options, bool for_parse,
1091                                   absl::string_view parameters,
1092                                   const Formatter& format);
1093 
1094 void GenerateUtf8CheckCodeForString(io::Printer* p,
1095                                     const FieldDescriptor* field,
1096                                     const Options& options, bool for_parse,
1097                                     absl::string_view parameters);
1098 
1099 void GenerateUtf8CheckCodeForCord(io::Printer* p, const FieldDescriptor* field,
1100                                   const Options& options, bool for_parse,
1101                                   absl::string_view parameters);
1102 
1103 inline bool ShouldGenerateExternSpecializations(const Options& options) {
1104   // For OSS we omit the specializations to reduce codegen size.
1105   // Some compilers can't handle that much input in a single translation unit.
1106   // These specializations are just a link size optimization and do not affect
1107   // correctness or performance, so it is ok to omit them.
1108   return !options.opensource_runtime;
1109 }
1110 
1111 struct OneOfRangeImpl {
1112   struct Iterator {
1113     using iterator_category = std::forward_iterator_tag;
1114     using value_type = const OneofDescriptor*;
1115     using difference_type = int;
1116 
1117     value_type operator*() { return descriptor->oneof_decl(idx); }
1118 
1119     friend bool operator==(const Iterator& a, const Iterator& b) {
1120       ABSL_DCHECK(a.descriptor == b.descriptor);
1121       return a.idx == b.idx;
1122     }
1123     friend bool operator!=(const Iterator& a, const Iterator& b) {
1124       return !(a == b);
1125     }
1126 
1127     Iterator& operator++() {
1128       idx++;
1129       return *this;
1130     }
1131 
1132     int idx;
1133     const Descriptor* descriptor;
1134   };
1135 
1136   Iterator begin() const { return {0, descriptor}; }
1137   Iterator end() const {
1138     return {descriptor->real_oneof_decl_count(), descriptor};
1139   }
1140 
1141   const Descriptor* descriptor;
1142 };
1143 
1144 inline OneOfRangeImpl OneOfRange(const Descriptor* desc) { return {desc}; }
1145 
1146 // Strips ".proto" or ".protodevel" from the end of a filename.
1147 PROTOC_EXPORT std::string StripProto(absl::string_view filename);
1148 
1149 bool HasMessageFieldOrExtension(const Descriptor* desc);
1150 
1151 // Generates a vector of substitutions for use with Printer::WithVars that
1152 // contains annotated accessor names for a particular field.
1153 //
1154 // Each substitution will be named `absl::StrCat(prefix, "name")`, and will
1155 // be annotated with `field`.
1156 std::vector<io::Printer::Sub> AnnotatedAccessors(
1157     const FieldDescriptor* field, absl::Span<const absl::string_view> prefixes,
1158     absl::optional<google::protobuf::io::AnnotationCollector::Semantic> semantic =
1159         absl::nullopt);
1160 
1161 // Check whether `file` represents the .proto file FileDescriptorProto and
1162 // friends. This file needs special handling because it must be usable during
1163 // dynamic initialization.
1164 bool IsFileDescriptorProto(const FileDescriptor* file, const Options& options);
1165 
1166 // Determine if we should generate a class for the descriptor.
1167 // Some descriptors, like some map entries, are not represented as a generated
1168 // class.
1169 bool ShouldGenerateClass(const Descriptor* descriptor, const Options& options);
1170 
1171 
1172 // Determine if we are going to generate a tracker call for OnDeserialize.
1173 // This one is handled specially because we generate the PostLoopHandler for it.
1174 // We don't want to generate a handler if it is going to end up empty.
1175 bool HasOnDeserializeTracker(const Descriptor* descriptor,
1176                              const Options& options);
1177 
1178 // Determine if we need a PostLoopHandler function to inject into TcParseTable's
1179 // ParseLoop.
1180 // If this returns true, the parse table generation will use
1181 // `&ClassName::PostLoopHandler` which should be a static function of the right
1182 // signature.
1183 bool NeedsPostLoopHandler(const Descriptor* descriptor, const Options& options);
1184 
1185 // Priority used for static initializers.
1186 enum InitPriority {
1187   kInitPriority101,
1188   kInitPriority102,
1189 };
1190 
1191 }  // namespace cpp
1192 }  // namespace compiler
1193 }  // namespace protobuf
1194 }  // namespace google
1195 
1196 #include "google/protobuf/port_undef.inc"
1197 
1198 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__