cpp_helpers.h 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
  34. #define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
  35. #include <algorithm>
  36. #include <cstdint>
  37. #include <iterator>
  38. #include <map>
  39. #include <string>
  40. #include <google/protobuf/compiler/cpp/cpp_options.h>
  41. #include <google/protobuf/compiler/cpp/cpp_names.h>
  42. #include <google/protobuf/compiler/scc.h>
  43. #include <google/protobuf/compiler/code_generator.h>
  44. #include <google/protobuf/descriptor.pb.h>
  45. #include <google/protobuf/io/printer.h>
  46. #include <google/protobuf/descriptor.h>
  47. #include <google/protobuf/port.h>
  48. #include <google/protobuf/stubs/strutil.h>
  49. // Must be included last.
  50. #include <google/protobuf/port_def.inc>
  51. namespace google {
  52. namespace protobuf {
  53. namespace compiler {
  54. namespace cpp {
  55. inline std::string ProtobufNamespace(const Options& /* options */) {
  56. return "PROTOBUF_NAMESPACE_ID";
  57. }
  58. inline std::string MacroPrefix(const Options& /* options */) {
  59. return "GOOGLE_PROTOBUF";
  60. }
  61. inline std::string DeprecatedAttribute(const Options& /* options */,
  62. const FieldDescriptor* d) {
  63. return d->options().deprecated() ? "PROTOBUF_DEPRECATED " : "";
  64. }
  65. inline std::string DeprecatedAttribute(const Options& /* options */,
  66. const EnumValueDescriptor* d) {
  67. return d->options().deprecated() ? "PROTOBUF_DEPRECATED_ENUM " : "";
  68. }
  69. // Commonly-used separator comments. Thick is a line of '=', thin is a line
  70. // of '-'.
  71. extern const char kThickSeparator[];
  72. extern const char kThinSeparator[];
  73. void SetCommonVars(const Options& options,
  74. std::map<std::string, std::string>* variables);
  75. void SetUnknownFieldsVariable(const Descriptor* descriptor,
  76. const Options& options,
  77. std::map<std::string, std::string>* variables);
  78. bool GetBootstrapBasename(const Options& options, const std::string& basename,
  79. std::string* bootstrap_basename);
  80. bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context,
  81. bool bootstrap_flag, std::string* basename);
  82. bool IsBootstrapProto(const Options& options, const FileDescriptor* file);
  83. // Name space of the proto file. This namespace is such that the string
  84. // "<namespace>::some_name" is the correct fully qualified namespace.
  85. // This means if the package is empty the namespace is "", and otherwise
  86. // the namespace is "::foo::bar::...::baz" without trailing semi-colons.
  87. std::string Namespace(const FileDescriptor* d, const Options& options);
  88. std::string Namespace(const Descriptor* d, const Options& options);
  89. std::string Namespace(const FieldDescriptor* d, const Options& options);
  90. std::string Namespace(const EnumDescriptor* d, const Options& options);
  91. // Returns true if it's safe to reset "field" to zero.
  92. bool CanInitializeByZeroing(const FieldDescriptor* field);
  93. std::string ClassName(const Descriptor* descriptor);
  94. std::string ClassName(const EnumDescriptor* enum_descriptor);
  95. std::string QualifiedClassName(const Descriptor* d, const Options& options);
  96. std::string QualifiedClassName(const EnumDescriptor* d, const Options& options);
  97. std::string QualifiedClassName(const Descriptor* d);
  98. std::string QualifiedClassName(const EnumDescriptor* d);
  99. // DEPRECATED just use ClassName or QualifiedClassName, a boolean is very
  100. // unreadable at the callsite.
  101. // Returns the non-nested type name for the given type. If "qualified" is
  102. // true, prefix the type with the full namespace. For example, if you had:
  103. // package foo.bar;
  104. // message Baz { message Qux {} }
  105. // Then the qualified ClassName for Qux would be:
  106. // ::foo::bar::Baz_Qux
  107. // While the non-qualified version would be:
  108. // Baz_Qux
  109. inline std::string ClassName(const Descriptor* descriptor, bool qualified) {
  110. return qualified ? QualifiedClassName(descriptor, Options())
  111. : ClassName(descriptor);
  112. }
  113. inline std::string ClassName(const EnumDescriptor* descriptor, bool qualified) {
  114. return qualified ? QualifiedClassName(descriptor, Options())
  115. : ClassName(descriptor);
  116. }
  117. // Returns the extension name prefixed with the class name if nested but without
  118. // the package name.
  119. std::string ExtensionName(const FieldDescriptor* d);
  120. std::string QualifiedExtensionName(const FieldDescriptor* d,
  121. const Options& options);
  122. std::string QualifiedExtensionName(const FieldDescriptor* d);
  123. // Type name of default instance.
  124. std::string DefaultInstanceType(const Descriptor* descriptor,
  125. const Options& options);
  126. // Non-qualified name of the default_instance of this message.
  127. std::string DefaultInstanceName(const Descriptor* descriptor,
  128. const Options& options);
  129. // Non-qualified name of the default instance pointer. This is used only for
  130. // implicit weak fields, where we need an extra indirection.
  131. std::string DefaultInstancePtr(const Descriptor* descriptor,
  132. const Options& options);
  133. // Fully qualified name of the default_instance of this message.
  134. std::string QualifiedDefaultInstanceName(const Descriptor* descriptor,
  135. const Options& options);
  136. // Fully qualified name of the default instance pointer.
  137. std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor,
  138. const Options& options);
  139. // DescriptorTable variable name.
  140. std::string DescriptorTableName(const FileDescriptor* file,
  141. const Options& options);
  142. // When declaring symbol externs from another file, this macro will supply the
  143. // dllexport needed for the target file, if any.
  144. std::string FileDllExport(const FileDescriptor* file, const Options& options);
  145. // Name of the base class: google::protobuf::Message or google::protobuf::MessageLite.
  146. std::string SuperClassName(const Descriptor* descriptor,
  147. const Options& options);
  148. // Adds an underscore if necessary to prevent conflicting with a keyword.
  149. std::string ResolveKeyword(const std::string& name);
  150. // Get the (unqualified) name that should be used for this field in C++ code.
  151. // The name is coerced to lower-case to emulate proto1 behavior. People
  152. // should be using lowercase-with-underscores style for proto field names
  153. // anyway, so normally this just returns field->name().
  154. std::string FieldName(const FieldDescriptor* field);
  155. // Returns an estimate of the compiler's alignment for the field. This
  156. // can't guarantee to be correct because the generated code could be compiled on
  157. // different systems with different alignment rules. The estimates below assume
  158. // 64-bit pointers.
  159. int EstimateAlignmentSize(const FieldDescriptor* field);
  160. // Get the unqualified name that should be used for a field's field
  161. // number constant.
  162. std::string FieldConstantName(const FieldDescriptor* field);
  163. // Returns the scope where the field was defined (for extensions, this is
  164. // different from the message type to which the field applies).
  165. inline const Descriptor* FieldScope(const FieldDescriptor* field) {
  166. return field->is_extension() ? field->extension_scope()
  167. : field->containing_type();
  168. }
  169. // Returns the fully-qualified type name field->message_type(). Usually this
  170. // is just ClassName(field->message_type(), true);
  171. std::string FieldMessageTypeName(const FieldDescriptor* field,
  172. const Options& options);
  173. // Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
  174. const char* PrimitiveTypeName(FieldDescriptor::CppType type);
  175. std::string PrimitiveTypeName(const Options& options,
  176. FieldDescriptor::CppType type);
  177. // Get the declared type name in CamelCase format, as is used e.g. for the
  178. // methods of WireFormat. For example, TYPE_INT32 becomes "Int32".
  179. const char* DeclaredTypeMethodName(FieldDescriptor::Type type);
  180. // Return the code that evaluates to the number when compiled.
  181. std::string Int32ToString(int number);
  182. // Get code that evaluates to the field's default value.
  183. std::string DefaultValue(const Options& options, const FieldDescriptor* field);
  184. // Compatibility function for callers outside proto2.
  185. std::string DefaultValue(const FieldDescriptor* field);
  186. // Convert a file name into a valid identifier.
  187. std::string FilenameIdentifier(const std::string& filename);
  188. // For each .proto file generates a unique name. To prevent collisions of
  189. // symbols in the global namespace
  190. std::string UniqueName(const std::string& name, const std::string& filename,
  191. const Options& options);
  192. inline std::string UniqueName(const std::string& name, const FileDescriptor* d,
  193. const Options& options) {
  194. return UniqueName(name, d->name(), options);
  195. }
  196. inline std::string UniqueName(const std::string& name, const Descriptor* d,
  197. const Options& options) {
  198. return UniqueName(name, d->file(), options);
  199. }
  200. inline std::string UniqueName(const std::string& name, const EnumDescriptor* d,
  201. const Options& options) {
  202. return UniqueName(name, d->file(), options);
  203. }
  204. inline std::string UniqueName(const std::string& name,
  205. const ServiceDescriptor* d,
  206. const Options& options) {
  207. return UniqueName(name, d->file(), options);
  208. }
  209. // Versions for call sites that only support the internal runtime (like proto1
  210. // support).
  211. inline Options InternalRuntimeOptions() {
  212. Options options;
  213. options.opensource_runtime = false;
  214. return options;
  215. }
  216. inline std::string UniqueName(const std::string& name,
  217. const std::string& filename) {
  218. return UniqueName(name, filename, InternalRuntimeOptions());
  219. }
  220. inline std::string UniqueName(const std::string& name,
  221. const FileDescriptor* d) {
  222. return UniqueName(name, d->name(), InternalRuntimeOptions());
  223. }
  224. inline std::string UniqueName(const std::string& name, const Descriptor* d) {
  225. return UniqueName(name, d->file(), InternalRuntimeOptions());
  226. }
  227. inline std::string UniqueName(const std::string& name,
  228. const EnumDescriptor* d) {
  229. return UniqueName(name, d->file(), InternalRuntimeOptions());
  230. }
  231. inline std::string UniqueName(const std::string& name,
  232. const ServiceDescriptor* d) {
  233. return UniqueName(name, d->file(), InternalRuntimeOptions());
  234. }
  235. // Return the qualified C++ name for a file level symbol.
  236. std::string QualifiedFileLevelSymbol(const FileDescriptor* file,
  237. const std::string& name,
  238. const Options& options);
  239. // Escape C++ trigraphs by escaping question marks to \?
  240. std::string EscapeTrigraphs(const std::string& to_escape);
  241. // Escaped function name to eliminate naming conflict.
  242. std::string SafeFunctionName(const Descriptor* descriptor,
  243. const FieldDescriptor* field,
  244. const std::string& prefix);
  245. // Returns true if generated messages have public unknown fields accessors
  246. inline bool PublicUnknownFieldsAccessors(const Descriptor* message) {
  247. return message->file()->syntax() != FileDescriptor::SYNTAX_PROTO3;
  248. }
  249. // Returns the optimize mode for <file>, respecting <options.enforce_lite>.
  250. FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
  251. const Options& options);
  252. // Determines whether unknown fields will be stored in an UnknownFieldSet or
  253. // a string.
  254. inline bool UseUnknownFieldSet(const FileDescriptor* file,
  255. const Options& options) {
  256. return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
  257. }
  258. inline bool IsWeak(const FieldDescriptor* field, const Options& options) {
  259. if (field->options().weak()) {
  260. GOOGLE_CHECK(!options.opensource_runtime);
  261. return true;
  262. }
  263. return false;
  264. }
  265. bool IsStringInlined(const FieldDescriptor* descriptor, const Options& options);
  266. // For a string field, returns the effective ctype. If the actual ctype is
  267. // not supported, returns the default of STRING.
  268. FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field,
  269. const Options& options);
  270. inline bool IsCord(const FieldDescriptor* field, const Options& options) {
  271. return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
  272. EffectiveStringCType(field, options) == FieldOptions::CORD;
  273. }
  274. inline bool IsString(const FieldDescriptor* field, const Options& options) {
  275. return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
  276. EffectiveStringCType(field, options) == FieldOptions::STRING;
  277. }
  278. inline bool IsStringPiece(const FieldDescriptor* field,
  279. const Options& options) {
  280. return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
  281. EffectiveStringCType(field, options) == FieldOptions::STRING_PIECE;
  282. }
  283. class MessageSCCAnalyzer;
  284. // Does the given FileDescriptor use lazy fields?
  285. bool HasLazyFields(const FileDescriptor* file, const Options& options,
  286. MessageSCCAnalyzer* scc_analyzer);
  287. // Is the given field a supported lazy field?
  288. bool IsLazy(const FieldDescriptor* field, const Options& options,
  289. MessageSCCAnalyzer* scc_analyzer);
  290. inline bool IsLazilyVerifiedLazy(const FieldDescriptor* field,
  291. const Options& options) {
  292. return field->options().lazy() && !field->is_repeated() &&
  293. field->type() == FieldDescriptor::TYPE_MESSAGE &&
  294. GetOptimizeFor(field->file(), options) != FileOptions::LITE_RUNTIME &&
  295. !options.opensource_runtime;
  296. }
  297. inline bool IsEagerlyVerifiedLazy(const FieldDescriptor* field,
  298. const Options& options,
  299. MessageSCCAnalyzer* scc_analyzer) {
  300. return IsLazy(field, options, scc_analyzer) && !field->options().lazy();
  301. }
  302. inline bool IsFieldUsed(const FieldDescriptor* /* field */,
  303. const Options& /* options */) {
  304. return true;
  305. }
  306. // Returns true if "field" is stripped.
  307. inline bool IsFieldStripped(const FieldDescriptor* /*field*/,
  308. const Options& /*options*/) {
  309. return false;
  310. }
  311. // Does the file contain any definitions that need extension_set.h?
  312. bool HasExtensionsOrExtendableMessage(const FileDescriptor* file);
  313. // Does the file have any repeated fields, necessitating the file to include
  314. // repeated_field.h? This does not include repeated extensions, since those are
  315. // all stored internally in an ExtensionSet, not a separate RepeatedField*.
  316. bool HasRepeatedFields(const FileDescriptor* file);
  317. // Does the file have any string/bytes fields with ctype=STRING_PIECE? This
  318. // does not include extensions, since ctype is ignored for extensions.
  319. bool HasStringPieceFields(const FileDescriptor* file, const Options& options);
  320. // Does the file have any string/bytes fields with ctype=CORD? This does not
  321. // include extensions, since ctype is ignored for extensions.
  322. bool HasCordFields(const FileDescriptor* file, const Options& options);
  323. // Does the file have any map fields, necessitating the file to include
  324. // map_field_inl.h and map.h.
  325. bool HasMapFields(const FileDescriptor* file);
  326. // Does this file have any enum type definitions?
  327. bool HasEnumDefinitions(const FileDescriptor* file);
  328. // Does this file have generated parsing, serialization, and other
  329. // standard methods for which reflection-based fallback implementations exist?
  330. inline bool HasGeneratedMethods(const FileDescriptor* file,
  331. const Options& options) {
  332. return GetOptimizeFor(file, options) != FileOptions::CODE_SIZE;
  333. }
  334. // Do message classes in this file have descriptor and reflection methods?
  335. inline bool HasDescriptorMethods(const FileDescriptor* file,
  336. const Options& options) {
  337. return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
  338. }
  339. // Should we generate generic services for this file?
  340. inline bool HasGenericServices(const FileDescriptor* file,
  341. const Options& options) {
  342. return file->service_count() > 0 &&
  343. GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME &&
  344. file->options().cc_generic_services();
  345. }
  346. inline bool IsProto2MessageSet(const Descriptor* descriptor,
  347. const Options& options) {
  348. return !options.opensource_runtime &&
  349. options.enforce_mode != EnforceOptimizeMode::kLiteRuntime &&
  350. !options.lite_implicit_weak_fields &&
  351. descriptor->options().message_set_wire_format() &&
  352. descriptor->full_name() == "google.protobuf.bridge.MessageSet";
  353. }
  354. inline bool IsMapEntryMessage(const Descriptor* descriptor) {
  355. return descriptor->options().map_entry();
  356. }
  357. // Returns true if the field's CPPTYPE is string or message.
  358. bool IsStringOrMessage(const FieldDescriptor* field);
  359. std::string UnderscoresToCamelCase(const std::string& input,
  360. bool cap_next_letter);
  361. inline bool IsProto3(const FileDescriptor* file) {
  362. return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
  363. }
  364. inline bool HasHasbit(const FieldDescriptor* field) {
  365. // This predicate includes proto3 message fields only if they have "optional".
  366. // Foo submsg1 = 1; // HasHasbit() == false
  367. // optional Foo submsg2 = 2; // HasHasbit() == true
  368. // This is slightly odd, as adding "optional" to a singular proto3 field does
  369. // not change the semantics or API. However whenever any field in a message
  370. // has a hasbit, it forces reflection to include hasbit offsets for *all*
  371. // fields, even if almost all of them are set to -1 (no hasbit). So to avoid
  372. // causing a sudden size regression for ~all proto3 messages, we give proto3
  373. // message fields a hasbit only if "optional" is present. If the user is
  374. // explicitly writing "optional", it is likely they are writing it on
  375. // primitive fields also.
  376. return (field->has_optional_keyword() || field->is_required()) &&
  377. !field->options().weak();
  378. }
  379. // Returns true if 'enum' semantics are such that unknown values are preserved
  380. // in the enum field itself, rather than going to the UnknownFieldSet.
  381. inline bool HasPreservingUnknownEnumSemantics(const FieldDescriptor* field) {
  382. return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
  383. }
  384. inline bool IsCrossFileMessage(const FieldDescriptor* field) {
  385. return field->type() == FieldDescriptor::TYPE_MESSAGE &&
  386. field->message_type()->file() != field->file();
  387. }
  388. inline std::string MakeDefaultName(const FieldDescriptor* field) {
  389. return "_i_give_permission_to_break_this_code_default_" + FieldName(field) +
  390. "_";
  391. }
  392. bool IsAnyMessage(const FileDescriptor* descriptor, const Options& options);
  393. bool IsAnyMessage(const Descriptor* descriptor, const Options& options);
  394. bool IsWellKnownMessage(const FileDescriptor* descriptor);
  395. inline std::string IncludeGuard(const FileDescriptor* file, bool pb_h,
  396. const Options& options) {
  397. // If we are generating a .pb.h file and the proto_h option is enabled, then
  398. // the .pb.h gets an extra suffix.
  399. std::string filename_identifier = FilenameIdentifier(
  400. file->name() + (pb_h && options.proto_h ? ".pb.h" : ""));
  401. if (IsWellKnownMessage(file)) {
  402. // For well-known messages we need third_party/protobuf and net/proto2 to
  403. // have distinct include guards, because some source files include both and
  404. // both need to be defined (the third_party copies will be in the
  405. // google::protobuf_opensource namespace).
  406. return MacroPrefix(options) + "_INCLUDED_" + filename_identifier;
  407. } else {
  408. // Ideally this case would use distinct include guards for opensource and
  409. // google3 protos also. (The behavior of "first #included wins" is not
  410. // ideal). But unfortunately some legacy code includes both and depends on
  411. // the identical include guards to avoid compile errors.
  412. //
  413. // We should clean this up so that this case can be removed.
  414. return "GOOGLE_PROTOBUF_INCLUDED_" + filename_identifier;
  415. }
  416. }
  417. // Returns the OptimizeMode for this file, furthermore it updates a status
  418. // bool if has_opt_codesize_extension is non-null. If this status bool is true
  419. // it means this file contains an extension that itself is defined as
  420. // optimized_for = CODE_SIZE.
  421. FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
  422. const Options& options,
  423. bool* has_opt_codesize_extension);
  424. inline FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
  425. const Options& options) {
  426. return GetOptimizeFor(file, options, nullptr);
  427. }
  428. inline bool NeedsEagerDescriptorAssignment(const FileDescriptor* file,
  429. const Options& options) {
  430. bool has_opt_codesize_extension;
  431. if (GetOptimizeFor(file, options, &has_opt_codesize_extension) ==
  432. FileOptions::CODE_SIZE &&
  433. has_opt_codesize_extension) {
  434. // If this filedescriptor contains an extension from another file which
  435. // is optimized_for = CODE_SIZE. We need to be careful in the ordering so
  436. // we eagerly build the descriptors in the dependencies before building
  437. // the descriptors of this file.
  438. return true;
  439. } else {
  440. // If we have a generated code based parser we never need eager
  441. // initialization of descriptors of our deps.
  442. return false;
  443. }
  444. }
  445. // This orders the messages in a .pb.cc as it's outputted by file.cc
  446. void FlattenMessagesInFile(const FileDescriptor* file,
  447. std::vector<const Descriptor*>* result);
  448. inline std::vector<const Descriptor*> FlattenMessagesInFile(
  449. const FileDescriptor* file) {
  450. std::vector<const Descriptor*> result;
  451. FlattenMessagesInFile(file, &result);
  452. return result;
  453. }
  454. template <typename F>
  455. void ForEachMessage(const Descriptor* descriptor, F&& func) {
  456. for (int i = 0; i < descriptor->nested_type_count(); i++)
  457. ForEachMessage(descriptor->nested_type(i), std::forward<F&&>(func));
  458. func(descriptor);
  459. }
  460. template <typename F>
  461. void ForEachMessage(const FileDescriptor* descriptor, F&& func) {
  462. for (int i = 0; i < descriptor->message_type_count(); i++)
  463. ForEachMessage(descriptor->message_type(i), std::forward<F&&>(func));
  464. }
  465. bool HasWeakFields(const Descriptor* desc, const Options& options);
  466. bool HasWeakFields(const FileDescriptor* desc, const Options& options);
  467. // Returns true if the "required" restriction check should be ignored for the
  468. // given field.
  469. inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field,
  470. const Options& options) {
  471. // Do not check "required" for lazily verified lazy fields.
  472. return IsLazilyVerifiedLazy(field, options);
  473. }
  474. struct MessageAnalysis {
  475. bool is_recursive = false;
  476. bool contains_cord = false;
  477. bool contains_extension = false;
  478. bool contains_required = false;
  479. bool contains_weak = false; // Implicit weak as well.
  480. };
  481. // This class is used in FileGenerator, to ensure linear instead of
  482. // quadratic performance, if we do this per message we would get O(V*(V+E)).
  483. // Logically this is just only used in message.cc, but in the header for
  484. // FileGenerator to help share it.
  485. class PROTOC_EXPORT MessageSCCAnalyzer {
  486. public:
  487. explicit MessageSCCAnalyzer(const Options& options) : options_(options) {}
  488. MessageAnalysis GetSCCAnalysis(const SCC* scc);
  489. bool HasRequiredFields(const Descriptor* descriptor) {
  490. MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor));
  491. return result.contains_required || result.contains_extension;
  492. }
  493. bool HasWeakField(const Descriptor* descriptor) {
  494. MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor));
  495. return result.contains_weak;
  496. }
  497. const SCC* GetSCC(const Descriptor* descriptor) {
  498. return analyzer_.GetSCC(descriptor);
  499. }
  500. private:
  501. struct DepsGenerator {
  502. std::vector<const Descriptor*> operator()(const Descriptor* desc) const {
  503. std::vector<const Descriptor*> deps;
  504. for (int i = 0; i < desc->field_count(); i++) {
  505. if (desc->field(i)->message_type()) {
  506. deps.push_back(desc->field(i)->message_type());
  507. }
  508. }
  509. return deps;
  510. }
  511. };
  512. SCCAnalyzer<DepsGenerator> analyzer_;
  513. Options options_;
  514. std::map<const SCC*, MessageAnalysis> analysis_cache_;
  515. };
  516. void ListAllFields(const Descriptor* d,
  517. std::vector<const FieldDescriptor*>* fields);
  518. void ListAllFields(const FileDescriptor* d,
  519. std::vector<const FieldDescriptor*>* fields);
  520. template <class T>
  521. void ForEachField(const Descriptor* d, T&& func) {
  522. for (int i = 0; i < d->nested_type_count(); i++) {
  523. ForEachField(d->nested_type(i), std::forward<T&&>(func));
  524. }
  525. for (int i = 0; i < d->extension_count(); i++) {
  526. func(d->extension(i));
  527. }
  528. for (int i = 0; i < d->field_count(); i++) {
  529. func(d->field(i));
  530. }
  531. }
  532. template <class T>
  533. void ForEachField(const FileDescriptor* d, T&& func) {
  534. for (int i = 0; i < d->message_type_count(); i++) {
  535. ForEachField(d->message_type(i), std::forward<T&&>(func));
  536. }
  537. for (int i = 0; i < d->extension_count(); i++) {
  538. func(d->extension(i));
  539. }
  540. }
  541. void ListAllTypesForServices(const FileDescriptor* fd,
  542. std::vector<const Descriptor*>* types);
  543. // Indicates whether we should use implicit weak fields for this file.
  544. bool UsingImplicitWeakFields(const FileDescriptor* file,
  545. const Options& options);
  546. // Indicates whether to treat this field as implicitly weak.
  547. bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
  548. MessageSCCAnalyzer* scc_analyzer);
  549. inline bool HasSimpleBaseClass(const Descriptor* desc, const Options& options) {
  550. if (!HasDescriptorMethods(desc->file(), options)) return false;
  551. if (desc->extension_range_count() != 0) return false;
  552. if (desc->field_count() == 0) return true;
  553. // TODO(jorg): Support additional common message types with only one
  554. // or two fields
  555. return false;
  556. }
  557. inline bool HasSimpleBaseClasses(const FileDescriptor* file,
  558. const Options& options) {
  559. bool v = false;
  560. ForEachMessage(file, [&v, &options](const Descriptor* desc) {
  561. v |= HasSimpleBaseClass(desc, options);
  562. });
  563. return v;
  564. }
  565. inline std::string SimpleBaseClass(const Descriptor* desc,
  566. const Options& options) {
  567. if (!HasDescriptorMethods(desc->file(), options)) return "";
  568. if (desc->extension_range_count() != 0) return "";
  569. if (desc->field_count() == 0) {
  570. return "ZeroFieldsBase";
  571. }
  572. // TODO(jorg): Support additional common message types with only one
  573. // or two fields
  574. return "";
  575. }
  576. // Formatter is a functor class which acts as a closure around printer and
  577. // the variable map. It's much like printer->Print except it supports both named
  578. // variables that are substituted using a key value map and direct arguments. In
  579. // the format string $1$, $2$, etc... are substituted for the first, second, ...
  580. // direct argument respectively in the format call, it accepts both strings and
  581. // integers. The implementation verifies all arguments are used and are "first"
  582. // used in order of appearance in the argument list. For example,
  583. //
  584. // Format("return array[$1$];", 3) -> "return array[3];"
  585. // Format("array[$2$] = $1$;", "Bla", 3) -> FATAL error (wrong order)
  586. // Format("array[$1$] = $2$;", 3, "Bla") -> "array[3] = Bla;"
  587. //
  588. // The arguments can be used more than once like
  589. //
  590. // Format("array[$1$] = $2$; // Index = $1$", 3, "Bla") ->
  591. // "array[3] = Bla; // Index = 3"
  592. //
  593. // If you use more arguments use the following style to help the reader,
  594. //
  595. // Format("int $1$() {\n"
  596. // " array[$2$] = $3$;\n"
  597. // " return $4$;"
  598. // "}\n",
  599. // funname, // 1
  600. // idx, // 2
  601. // varname, // 3
  602. // retval); // 4
  603. //
  604. // but consider using named variables. Named variables like $foo$, with some
  605. // identifier foo, are looked up in the map. One additional feature is that
  606. // spaces are accepted between the '$' delimiters, $ foo$ will
  607. // substiture to " bar" if foo stands for "bar", but in case it's empty
  608. // will substitute to "". Hence, for example,
  609. //
  610. // Format(vars, "$dllexport $void fun();") -> "void fun();"
  611. // "__declspec(export) void fun();"
  612. //
  613. // which is convenient to prevent double, leading or trailing spaces.
  614. class PROTOC_EXPORT Formatter {
  615. public:
  616. explicit Formatter(io::Printer* printer) : printer_(printer) {}
  617. Formatter(io::Printer* printer,
  618. const std::map<std::string, std::string>& vars)
  619. : printer_(printer), vars_(vars) {}
  620. template <typename T>
  621. void Set(const std::string& key, const T& value) {
  622. vars_[key] = ToString(value);
  623. }
  624. void AddMap(const std::map<std::string, std::string>& vars) {
  625. for (const auto& keyval : vars) vars_[keyval.first] = keyval.second;
  626. }
  627. template <typename... Args>
  628. void operator()(const char* format, const Args&... args) const {
  629. printer_->FormatInternal({ToString(args)...}, vars_, format);
  630. }
  631. void Indent() const { printer_->Indent(); }
  632. void Outdent() const { printer_->Outdent(); }
  633. io::Printer* printer() const { return printer_; }
  634. class PROTOC_EXPORT ScopedIndenter {
  635. public:
  636. explicit ScopedIndenter(Formatter* format) : format_(format) {
  637. format_->Indent();
  638. }
  639. ~ScopedIndenter() { format_->Outdent(); }
  640. private:
  641. Formatter* format_;
  642. };
  643. PROTOBUF_NODISCARD ScopedIndenter ScopedIndent() {
  644. return ScopedIndenter(this);
  645. }
  646. template <typename... Args>
  647. PROTOBUF_NODISCARD ScopedIndenter ScopedIndent(const char* format,
  648. const Args&&... args) {
  649. (*this)(format, static_cast<Args&&>(args)...);
  650. return ScopedIndenter(this);
  651. }
  652. class PROTOC_EXPORT SaveState {
  653. public:
  654. explicit SaveState(Formatter* format)
  655. : format_(format), vars_(format->vars_) {}
  656. ~SaveState() { format_->vars_.swap(vars_); }
  657. private:
  658. Formatter* format_;
  659. std::map<std::string, std::string> vars_;
  660. };
  661. private:
  662. io::Printer* printer_;
  663. std::map<std::string, std::string> vars_;
  664. // Convenience overloads to accept different types as arguments.
  665. static std::string ToString(const std::string& s) { return s; }
  666. template <typename I, typename = typename std::enable_if<
  667. std::is_integral<I>::value>::type>
  668. static std::string ToString(I x) {
  669. return StrCat(x);
  670. }
  671. static std::string ToString(strings::Hex x) { return StrCat(x); }
  672. static std::string ToString(const FieldDescriptor* d) { return Payload(d); }
  673. static std::string ToString(const Descriptor* d) { return Payload(d); }
  674. static std::string ToString(const EnumDescriptor* d) { return Payload(d); }
  675. static std::string ToString(const EnumValueDescriptor* d) {
  676. return Payload(d);
  677. }
  678. static std::string ToString(const OneofDescriptor* d) { return Payload(d); }
  679. template <typename Descriptor>
  680. static std::string Payload(const Descriptor* descriptor) {
  681. std::vector<int> path;
  682. descriptor->GetLocationPath(&path);
  683. GeneratedCodeInfo::Annotation annotation;
  684. for (int index : path) {
  685. annotation.add_path(index);
  686. }
  687. annotation.set_source_file(descriptor->file()->name());
  688. return annotation.SerializeAsString();
  689. }
  690. };
  691. template <class T>
  692. void PrintFieldComment(const Formatter& format, const T* field) {
  693. // Print the field's (or oneof's) proto-syntax definition as a comment.
  694. // We don't want to print group bodies so we cut off after the first
  695. // line.
  696. DebugStringOptions options;
  697. options.elide_group_body = true;
  698. options.elide_oneof_body = true;
  699. std::string def = field->DebugStringWithOptions(options);
  700. format("// $1$\n", def.substr(0, def.find_first_of('\n')));
  701. }
  702. class PROTOC_EXPORT NamespaceOpener {
  703. public:
  704. explicit NamespaceOpener(const Formatter& format)
  705. : printer_(format.printer()) {}
  706. NamespaceOpener(const std::string& name, const Formatter& format)
  707. : NamespaceOpener(format) {
  708. ChangeTo(name);
  709. }
  710. ~NamespaceOpener() { ChangeTo(""); }
  711. void ChangeTo(const std::string& name) {
  712. std::vector<std::string> new_stack_ =
  713. Split(name, "::", true);
  714. size_t len = std::min(name_stack_.size(), new_stack_.size());
  715. size_t common_idx = 0;
  716. while (common_idx < len) {
  717. if (name_stack_[common_idx] != new_stack_[common_idx]) break;
  718. common_idx++;
  719. }
  720. for (auto it = name_stack_.crbegin();
  721. it != name_stack_.crend() - common_idx; ++it) {
  722. if (*it == "PROTOBUF_NAMESPACE_ID") {
  723. printer_->Print("PROTOBUF_NAMESPACE_CLOSE\n");
  724. } else {
  725. printer_->Print("} // namespace $ns$\n", "ns", *it);
  726. }
  727. }
  728. name_stack_.swap(new_stack_);
  729. for (size_t i = common_idx; i < name_stack_.size(); ++i) {
  730. if (name_stack_[i] == "PROTOBUF_NAMESPACE_ID") {
  731. printer_->Print("PROTOBUF_NAMESPACE_OPEN\n");
  732. } else {
  733. printer_->Print("namespace $ns$ {\n", "ns", name_stack_[i]);
  734. }
  735. }
  736. }
  737. private:
  738. io::Printer* printer_;
  739. std::vector<std::string> name_stack_;
  740. };
  741. enum class Utf8CheckMode {
  742. kStrict = 0, // Parsing will fail if non UTF-8 data is in string fields.
  743. kVerify = 1, // Only log an error but parsing will succeed.
  744. kNone = 2, // No UTF-8 check.
  745. };
  746. Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
  747. const Options& options);
  748. void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
  749. const Options& options, bool for_parse,
  750. const char* parameters,
  751. const Formatter& format);
  752. void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
  753. const Options& options, bool for_parse,
  754. const char* parameters,
  755. const Formatter& format);
  756. template <typename T>
  757. struct FieldRangeImpl {
  758. struct Iterator {
  759. using iterator_category = std::forward_iterator_tag;
  760. using value_type = const FieldDescriptor*;
  761. using difference_type = int;
  762. value_type operator*() { return descriptor->field(idx); }
  763. friend bool operator==(const Iterator& a, const Iterator& b) {
  764. GOOGLE_DCHECK(a.descriptor == b.descriptor);
  765. return a.idx == b.idx;
  766. }
  767. friend bool operator!=(const Iterator& a, const Iterator& b) {
  768. return !(a == b);
  769. }
  770. Iterator& operator++() {
  771. idx++;
  772. return *this;
  773. }
  774. int idx;
  775. const T* descriptor;
  776. };
  777. Iterator begin() const { return {0, descriptor}; }
  778. Iterator end() const { return {descriptor->field_count(), descriptor}; }
  779. const T* descriptor;
  780. };
  781. template <typename T>
  782. FieldRangeImpl<T> FieldRange(const T* desc) {
  783. return {desc};
  784. }
  785. struct OneOfRangeImpl {
  786. struct Iterator {
  787. using iterator_category = std::forward_iterator_tag;
  788. using value_type = const OneofDescriptor*;
  789. using difference_type = int;
  790. value_type operator*() { return descriptor->oneof_decl(idx); }
  791. friend bool operator==(const Iterator& a, const Iterator& b) {
  792. GOOGLE_DCHECK(a.descriptor == b.descriptor);
  793. return a.idx == b.idx;
  794. }
  795. friend bool operator!=(const Iterator& a, const Iterator& b) {
  796. return !(a == b);
  797. }
  798. Iterator& operator++() {
  799. idx++;
  800. return *this;
  801. }
  802. int idx;
  803. const Descriptor* descriptor;
  804. };
  805. Iterator begin() const { return {0, descriptor}; }
  806. Iterator end() const {
  807. return {descriptor->real_oneof_decl_count(), descriptor};
  808. }
  809. const Descriptor* descriptor;
  810. };
  811. inline OneOfRangeImpl OneOfRange(const Descriptor* desc) { return {desc}; }
  812. PROTOC_EXPORT std::string StripProto(const std::string& filename);
  813. bool EnableMessageOwnedArena(const Descriptor* desc);
  814. bool ShouldVerify(const Descriptor* descriptor, const Options& options,
  815. MessageSCCAnalyzer* scc_analyzer);
  816. bool ShouldVerify(const FileDescriptor* file, const Options& options,
  817. MessageSCCAnalyzer* scc_analyzer);
  818. } // namespace cpp
  819. } // namespace compiler
  820. } // namespace protobuf
  821. } // namespace google
  822. #include <google/protobuf/port_undef.inc>
  823. #endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__