cpp_helpers.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  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 <map>
  36. #include <string>
  37. #include <google/protobuf/compiler/cpp/cpp_options.h>
  38. #include <google/protobuf/compiler/code_generator.h>
  39. #include <google/protobuf/descriptor.pb.h>
  40. #include <google/protobuf/io/printer.h>
  41. #include <google/protobuf/descriptor.h>
  42. #include <google/protobuf/stubs/strutil.h>
  43. namespace google {
  44. namespace protobuf {
  45. namespace compiler {
  46. namespace cpp {
  47. // Commonly-used separator comments. Thick is a line of '=', thin is a line
  48. // of '-'.
  49. extern const char kThickSeparator[];
  50. extern const char kThinSeparator[];
  51. // Name space of the proto file. This namespace is such that the string
  52. // "<namespace>::some_name" is the correct fully qualified namespace.
  53. // This means if the package is empty the namespace is "", and otherwise
  54. // the namespace is "::foo::bar::...::baz" without trailing semi-colons.
  55. string Namespace(const string& package);
  56. inline string Namespace(const FileDescriptor* d) {
  57. return Namespace(d->package());
  58. }
  59. template <typename Desc>
  60. string Namespace(const Desc* d) {
  61. return Namespace(d->file());
  62. }
  63. // Returns true if it's safe to reset "field" to zero.
  64. bool CanInitializeByZeroing(const FieldDescriptor* field);
  65. string ClassName(const Descriptor* descriptor);
  66. string ClassName(const EnumDescriptor* enum_descriptor);
  67. template <typename Desc>
  68. string QualifiedClassName(const Desc* d) {
  69. return Namespace(d) + "::" + ClassName(d);
  70. }
  71. // DEPRECATED just use ClassName or QualifiedClassName, a boolean is very
  72. // unreadable at the callsite.
  73. // Returns the non-nested type name for the given type. If "qualified" is
  74. // true, prefix the type with the full namespace. For example, if you had:
  75. // package foo.bar;
  76. // message Baz { message Qux {} }
  77. // Then the qualified ClassName for Qux would be:
  78. // ::foo::bar::Baz_Qux
  79. // While the non-qualified version would be:
  80. // Baz_Qux
  81. inline string ClassName(const Descriptor* descriptor, bool qualified) {
  82. return qualified ? QualifiedClassName(descriptor) : ClassName(descriptor);
  83. }
  84. inline string ClassName(const EnumDescriptor* descriptor, bool qualified) {
  85. return qualified ? QualifiedClassName(descriptor) : ClassName(descriptor);
  86. }
  87. // Fully qualified name of the default_instance of this message.
  88. string DefaultInstanceName(const Descriptor* descriptor);
  89. // Returns the name of a no-op function that we can call to introduce a linker
  90. // dependency on the given message type. This is used to implement implicit weak
  91. // fields.
  92. string ReferenceFunctionName(const Descriptor* descriptor);
  93. // Name of the base class: google::protobuf::Message or google::protobuf::MessageLite.
  94. string SuperClassName(const Descriptor* descriptor, const Options& options);
  95. // Get the (unqualified) name that should be used for this field in C++ code.
  96. // The name is coerced to lower-case to emulate proto1 behavior. People
  97. // should be using lowercase-with-underscores style for proto field names
  98. // anyway, so normally this just returns field->name().
  99. string FieldName(const FieldDescriptor* field);
  100. // Get the sanitized name that should be used for the given enum in C++ code.
  101. string EnumValueName(const EnumValueDescriptor* enum_value);
  102. // Returns an estimate of the compiler's alignment for the field. This
  103. // can't guarantee to be correct because the generated code could be compiled on
  104. // different systems with different alignment rules. The estimates below assume
  105. // 64-bit pointers.
  106. int EstimateAlignmentSize(const FieldDescriptor* field);
  107. // Get the unqualified name that should be used for a field's field
  108. // number constant.
  109. string FieldConstantName(const FieldDescriptor *field);
  110. // Returns the scope where the field was defined (for extensions, this is
  111. // different from the message type to which the field applies).
  112. inline const Descriptor* FieldScope(const FieldDescriptor* field) {
  113. return field->is_extension() ?
  114. field->extension_scope() : field->containing_type();
  115. }
  116. // Returns the fully-qualified type name field->message_type(). Usually this
  117. // is just ClassName(field->message_type(), true);
  118. string FieldMessageTypeName(const FieldDescriptor* field);
  119. // Strips ".proto" or ".protodevel" from the end of a filename.
  120. LIBPROTOC_EXPORT string StripProto(const string& filename);
  121. // Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
  122. // Note: non-built-in type names will be qualified, meaning they will start
  123. // with a ::. If you are using the type as a template parameter, you will
  124. // need to insure there is a space between the < and the ::, because the
  125. // ridiculous C++ standard defines "<:" to be a synonym for "[".
  126. const char* PrimitiveTypeName(FieldDescriptor::CppType type);
  127. // Get the declared type name in CamelCase format, as is used e.g. for the
  128. // methods of WireFormat. For example, TYPE_INT32 becomes "Int32".
  129. const char* DeclaredTypeMethodName(FieldDescriptor::Type type);
  130. // Return the code that evaluates to the number when compiled.
  131. string Int32ToString(int number);
  132. // Return the code that evaluates to the number when compiled.
  133. string Int64ToString(int64 number);
  134. // Get code that evaluates to the field's default value.
  135. string DefaultValue(const FieldDescriptor* field);
  136. // Convert a file name into a valid identifier.
  137. string FilenameIdentifier(const string& filename);
  138. // For each .proto file generates a unique namespace. In this namespace global
  139. // definitions are put to prevent collisions.
  140. string FileLevelNamespace(const string& filename);
  141. inline string FileLevelNamespace(const FileDescriptor* file) {
  142. return FileLevelNamespace(file->name());
  143. }
  144. inline string FileLevelNamespace(const Descriptor* d) {
  145. return FileLevelNamespace(d->file());
  146. }
  147. // Return the qualified C++ name for a file level symbol.
  148. string QualifiedFileLevelSymbol(const string& package, const string& name);
  149. // Escape C++ trigraphs by escaping question marks to \?
  150. string EscapeTrigraphs(const string& to_escape);
  151. // Escaped function name to eliminate naming conflict.
  152. string SafeFunctionName(const Descriptor* descriptor,
  153. const FieldDescriptor* field,
  154. const string& prefix);
  155. // Returns true if unknown fields are always preserved after parsing.
  156. inline bool AlwaysPreserveUnknownFields(const FileDescriptor* file) {
  157. return file->syntax() != FileDescriptor::SYNTAX_PROTO3;
  158. }
  159. // Returns true if unknown fields are preserved after parsing.
  160. inline bool AlwaysPreserveUnknownFields(const Descriptor* message) {
  161. return AlwaysPreserveUnknownFields(message->file());
  162. }
  163. // Returns true if generated messages have public unknown fields accessors
  164. inline bool PublicUnknownFieldsAccessors(const Descriptor* message) {
  165. return message->file()->syntax() != FileDescriptor::SYNTAX_PROTO3;
  166. }
  167. // Returns the optimize mode for <file>, respecting <options.enforce_lite>.
  168. ::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor(
  169. const FileDescriptor* file, const Options& options);
  170. // Determines whether unknown fields will be stored in an UnknownFieldSet or
  171. // a string.
  172. inline bool UseUnknownFieldSet(const FileDescriptor* file,
  173. const Options& options) {
  174. return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
  175. }
  176. // Does the file have any map fields, necessitating the file to include
  177. // map_field_inl.h and map.h.
  178. bool HasMapFields(const FileDescriptor* file);
  179. // Does this file have any enum type definitions?
  180. bool HasEnumDefinitions(const FileDescriptor* file);
  181. // Does this file have generated parsing, serialization, and other
  182. // standard methods for which reflection-based fallback implementations exist?
  183. inline bool HasGeneratedMethods(const FileDescriptor* file,
  184. const Options& options) {
  185. return GetOptimizeFor(file, options) != FileOptions::CODE_SIZE;
  186. }
  187. // Do message classes in this file have descriptor and reflection methods?
  188. inline bool HasDescriptorMethods(const FileDescriptor* file,
  189. const Options& options) {
  190. return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
  191. }
  192. // Should we generate generic services for this file?
  193. inline bool HasGenericServices(const FileDescriptor* file,
  194. const Options& options) {
  195. return file->service_count() > 0 &&
  196. GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME &&
  197. file->options().cc_generic_services();
  198. }
  199. // Should we generate a separate, super-optimized code path for serializing to
  200. // flat arrays? We don't do this in Lite mode because we'd rather reduce code
  201. // size.
  202. inline bool HasFastArraySerialization(const FileDescriptor* file,
  203. const Options& options) {
  204. return GetOptimizeFor(file, options) == FileOptions::SPEED;
  205. }
  206. inline bool IsMapEntryMessage(const Descriptor* descriptor) {
  207. return descriptor->options().map_entry();
  208. }
  209. // Returns true if the field's CPPTYPE is string or message.
  210. bool IsStringOrMessage(const FieldDescriptor* field);
  211. // For a string field, returns the effective ctype. If the actual ctype is
  212. // not supported, returns the default of STRING.
  213. FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field);
  214. string UnderscoresToCamelCase(const string& input, bool cap_next_letter);
  215. inline bool HasFieldPresence(const FileDescriptor* file) {
  216. return file->syntax() != FileDescriptor::SYNTAX_PROTO3;
  217. }
  218. // Returns true if 'enum' semantics are such that unknown values are preserved
  219. // in the enum field itself, rather than going to the UnknownFieldSet.
  220. inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) {
  221. return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
  222. }
  223. inline bool SupportsArenas(const FileDescriptor* file) {
  224. return file->options().cc_enable_arenas();
  225. }
  226. inline bool SupportsArenas(const Descriptor* desc) {
  227. return SupportsArenas(desc->file());
  228. }
  229. inline bool SupportsArenas(const FieldDescriptor* field) {
  230. return SupportsArenas(field->file());
  231. }
  232. inline bool IsCrossFileMessage(const FieldDescriptor* field) {
  233. return field->type() == FieldDescriptor::TYPE_MESSAGE &&
  234. field->message_type()->file() != field->file();
  235. }
  236. inline string MessageCreateFunction(const Descriptor* d) {
  237. return SupportsArenas(d) ? "CreateMessage" : "Create";
  238. }
  239. inline string MakeDefaultName(const FieldDescriptor* field) {
  240. return "_i_give_permission_to_break_this_code_default_" + FieldName(field) +
  241. "_";
  242. }
  243. bool IsAnyMessage(const FileDescriptor* descriptor);
  244. bool IsAnyMessage(const Descriptor* descriptor);
  245. bool IsWellKnownMessage(const FileDescriptor* descriptor);
  246. void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
  247. const Options& options, bool for_parse,
  248. const std::map<string, string>& variables,
  249. const char* parameters,
  250. io::Printer* printer);
  251. void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
  252. const Options& options, bool for_parse,
  253. const std::map<string, string>& variables,
  254. const char* parameters, io::Printer* printer);
  255. inline ::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor(
  256. const FileDescriptor* file, const Options& options) {
  257. return options.enforce_lite
  258. ? FileOptions::LITE_RUNTIME
  259. : file->options().optimize_for();
  260. }
  261. // This orders the messages in a .pb.cc as it's outputted by file.cc
  262. void FlattenMessagesInFile(const FileDescriptor* file,
  263. std::vector<const Descriptor*>* result);
  264. inline std::vector<const Descriptor*> FlattenMessagesInFile(
  265. const FileDescriptor* file) {
  266. std::vector<const Descriptor*> result;
  267. FlattenMessagesInFile(file, &result);
  268. return result;
  269. }
  270. bool HasWeakFields(const Descriptor* desc);
  271. bool HasWeakFields(const FileDescriptor* desc);
  272. // Returns true if the "required" restriction check should be ignored for the
  273. // given field.
  274. inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field,
  275. const Options& options) {
  276. return false;
  277. }
  278. class LIBPROTOC_EXPORT NamespaceOpener {
  279. public:
  280. explicit NamespaceOpener(io::Printer* printer) : printer_(printer) {}
  281. NamespaceOpener(const string& name, io::Printer* printer)
  282. : printer_(printer) {
  283. ChangeTo(name);
  284. }
  285. ~NamespaceOpener() { ChangeTo(""); }
  286. void ChangeTo(const string& name) {
  287. std::vector<string> new_stack_ =
  288. Split(name, "::", true);
  289. int len = std::min(name_stack_.size(), new_stack_.size());
  290. int common_idx = 0;
  291. while (common_idx < len) {
  292. if (name_stack_[common_idx] != new_stack_[common_idx]) break;
  293. common_idx++;
  294. }
  295. for (int i = name_stack_.size() - 1; i >= common_idx; i--) {
  296. printer_->Print("} // namespace $ns$\n", "ns", name_stack_[i]);
  297. }
  298. name_stack_.swap(new_stack_);
  299. for (int i = common_idx; i < name_stack_.size(); i++) {
  300. printer_->Print("namespace $ns$ {\n", "ns", name_stack_[i]);
  301. }
  302. }
  303. private:
  304. io::Printer* printer_;
  305. std::vector<string> name_stack_;
  306. };
  307. // Description of each strongly connected component. Note that the order
  308. // of both the descriptors in this SCC and the order of children is
  309. // deterministic.
  310. struct SCC {
  311. std::vector<const Descriptor*> descriptors;
  312. std::vector<const SCC*> children;
  313. const Descriptor* GetRepresentative() const { return descriptors[0]; }
  314. };
  315. struct MessageAnalysis {
  316. bool is_recursive;
  317. bool contains_cord;
  318. bool contains_extension;
  319. bool contains_required;
  320. };
  321. // This class is used in FileGenerator, to ensure linear instead of
  322. // quadratic performance, if we do this per message we would get O(V*(V+E)).
  323. // Logically this is just only used in message.cc, but in the header for
  324. // FileGenerator to help share it.
  325. class LIBPROTOC_EXPORT SCCAnalyzer {
  326. public:
  327. explicit SCCAnalyzer(const Options& options) : options_(options), index_(0) {}
  328. ~SCCAnalyzer() {
  329. for (int i = 0; i < garbage_bin_.size(); i++) delete garbage_bin_[i];
  330. }
  331. const SCC* GetSCC(const Descriptor* descriptor) {
  332. if (cache_.count(descriptor)) return cache_[descriptor].scc;
  333. return DFS(descriptor).scc;
  334. }
  335. MessageAnalysis GetSCCAnalysis(const SCC* scc);
  336. bool HasRequiredFields(const Descriptor* descriptor) {
  337. MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor));
  338. return result.contains_required || result.contains_extension;
  339. }
  340. private:
  341. struct NodeData {
  342. const SCC* scc; // if null it means its still on the stack
  343. int index;
  344. int lowlink;
  345. };
  346. Options options_;
  347. std::map<const Descriptor*, NodeData> cache_;
  348. std::map<const SCC*, MessageAnalysis> analysis_cache_;
  349. std::vector<const Descriptor*> stack_;
  350. int index_;
  351. std::vector<SCC*> garbage_bin_;
  352. SCC* CreateSCC() {
  353. garbage_bin_.push_back(new SCC());
  354. return garbage_bin_.back();
  355. }
  356. // Tarjan's Strongly Connected Components algo
  357. NodeData DFS(const Descriptor* descriptor);
  358. // Add the SCC's that are children of this SCC to its children.
  359. void AddChildren(SCC* scc);
  360. };
  361. void ListAllFields(const Descriptor* d,
  362. std::vector<const FieldDescriptor*>* fields);
  363. void ListAllFields(const FileDescriptor* d,
  364. std::vector<const FieldDescriptor*>* fields);
  365. void ListAllTypesForServices(const FileDescriptor* fd,
  366. std::vector<const Descriptor*>* types);
  367. // Indicates whether we should use implicit weak fields for this file.
  368. bool UsingImplicitWeakFields(const FileDescriptor* file,
  369. const Options& options);
  370. // Indicates whether to treat this field as implicitly weak.
  371. bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
  372. SCCAnalyzer* scc_analyzer);
  373. } // namespace cpp
  374. } // namespace compiler
  375. } // namespace protobuf
  376. } // namespace google
  377. #endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__