cpp_helpers.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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/descriptor.pb.h>
  39. #include <google/protobuf/descriptor.h>
  40. namespace google {
  41. namespace protobuf {
  42. namespace io {
  43. class Printer;
  44. }
  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. // Returns the non-nested type name for the given type. If "qualified" is
  52. // true, prefix the type with the full namespace. For example, if you had:
  53. // package foo.bar;
  54. // message Baz { message Qux {} }
  55. // Then the qualified ClassName for Qux would be:
  56. // ::foo::bar::Baz_Qux
  57. // While the non-qualified version would be:
  58. // Baz_Qux
  59. string ClassName(const Descriptor* descriptor, bool qualified);
  60. string ClassName(const EnumDescriptor* enum_descriptor, bool qualified);
  61. // Name of the CRTP class template (for use with proto_h).
  62. // This is a class name, like "ProtoName_InternalBase".
  63. string DependentBaseClassTemplateName(const Descriptor* descriptor);
  64. // Name of the base class: either the dependent base class (for use with
  65. // proto_h) or google::protobuf::Message.
  66. string SuperClassName(const Descriptor* descriptor, const Options& options);
  67. // Returns a string that down-casts from the dependent base class to the
  68. // derived class.
  69. string DependentBaseDownCast();
  70. string DependentBaseConstDownCast();
  71. // Get the (unqualified) name that should be used for this field in C++ code.
  72. // The name is coerced to lower-case to emulate proto1 behavior. People
  73. // should be using lowercase-with-underscores style for proto field names
  74. // anyway, so normally this just returns field->name().
  75. string FieldName(const FieldDescriptor* field);
  76. // Get the sanitized name that should be used for the given enum in C++ code.
  77. string EnumValueName(const EnumValueDescriptor* enum_value);
  78. // Get the unqualified name that should be used for a field's field
  79. // number constant.
  80. string FieldConstantName(const FieldDescriptor *field);
  81. // Returns the scope where the field was defined (for extensions, this is
  82. // different from the message type to which the field applies).
  83. inline const Descriptor* FieldScope(const FieldDescriptor* field) {
  84. return field->is_extension() ?
  85. field->extension_scope() : field->containing_type();
  86. }
  87. // Returns true if the given 'field_descriptor' has a message type that is
  88. // a dependency of the file where the field is defined (i.e., the field
  89. // type is defined in a different file than the message holding the field).
  90. //
  91. // This only applies to Message-typed fields. Enum-typed fields may refer
  92. // to an enum in a dependency; however, enums are specified and
  93. // forward-declared with an enum-base, so the definition is not required to
  94. // manipulate the field value.
  95. bool IsFieldDependent(const FieldDescriptor* field_descriptor);
  96. // Returns the name that should be used for forcing dependent lookup from a
  97. // dependent base class.
  98. string DependentTypeName(const FieldDescriptor* field);
  99. // Returns the fully-qualified type name field->message_type(). Usually this
  100. // is just ClassName(field->message_type(), true);
  101. string FieldMessageTypeName(const FieldDescriptor* field);
  102. // Strips ".proto" or ".protodevel" from the end of a filename.
  103. LIBPROTOC_EXPORT string StripProto(const string& filename);
  104. // Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
  105. // Note: non-built-in type names will be qualified, meaning they will start
  106. // with a ::. If you are using the type as a template parameter, you will
  107. // need to insure there is a space between the < and the ::, because the
  108. // ridiculous C++ standard defines "<:" to be a synonym for "[".
  109. const char* PrimitiveTypeName(FieldDescriptor::CppType type);
  110. // Get the declared type name in CamelCase format, as is used e.g. for the
  111. // methods of WireFormat. For example, TYPE_INT32 becomes "Int32".
  112. const char* DeclaredTypeMethodName(FieldDescriptor::Type type);
  113. // Return the code that evaluates to the number when compiled.
  114. string Int32ToString(int number);
  115. // Return the code that evaluates to the number when compiled.
  116. string Int64ToString(int64 number);
  117. // Get code that evaluates to the field's default value.
  118. string DefaultValue(const FieldDescriptor* field);
  119. // Convert a file name into a valid identifier.
  120. string FilenameIdentifier(const string& filename);
  121. // For each .proto file generates a unique namespace. In this namespace global
  122. // definitions are put to prevent collisions.
  123. string FileLevelNamespace(const string& filename);
  124. // Return the qualified C++ name for a file level symbol.
  125. string QualifiedFileLevelSymbol(const string& package, const string& name);
  126. // Escape C++ trigraphs by escaping question marks to \?
  127. string EscapeTrigraphs(const string& to_escape);
  128. // Escaped function name to eliminate naming conflict.
  129. string SafeFunctionName(const Descriptor* descriptor,
  130. const FieldDescriptor* field,
  131. const string& prefix);
  132. // Returns true if unknown fields are preseved after parsing.
  133. inline bool PreserveUnknownFields(const Descriptor* message) {
  134. return message->file()->syntax() != FileDescriptor::SYNTAX_PROTO3;
  135. }
  136. // Returns the optimize mode for <file>, respecting <options.enforce_lite>.
  137. ::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor(
  138. const FileDescriptor* file, const Options& options);
  139. // If PreserveUnknownFields() is true, determines whether unknown
  140. // fields will be stored in an UnknownFieldSet or a string.
  141. // If PreserveUnknownFields() is false, this method will not be
  142. // used.
  143. inline bool UseUnknownFieldSet(const FileDescriptor* file,
  144. const Options& options) {
  145. return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
  146. }
  147. // Does the file have any map fields, necessitating the file to include
  148. // map_field_inl.h and map.h.
  149. bool HasMapFields(const FileDescriptor* file);
  150. // Does this file have any enum type definitions?
  151. bool HasEnumDefinitions(const FileDescriptor* file);
  152. // Does this file have generated parsing, serialization, and other
  153. // standard methods for which reflection-based fallback implementations exist?
  154. inline bool HasGeneratedMethods(const FileDescriptor* file,
  155. const Options& options) {
  156. return GetOptimizeFor(file, options) != FileOptions::CODE_SIZE;
  157. }
  158. // Do message classes in this file have descriptor and reflection methods?
  159. inline bool HasDescriptorMethods(const FileDescriptor* file,
  160. const Options& options) {
  161. return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
  162. }
  163. // Should we generate generic services for this file?
  164. inline bool HasGenericServices(const FileDescriptor* file,
  165. const Options& options) {
  166. return file->service_count() > 0 &&
  167. GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME &&
  168. file->options().cc_generic_services();
  169. }
  170. // Should we generate a separate, super-optimized code path for serializing to
  171. // flat arrays? We don't do this in Lite mode because we'd rather reduce code
  172. // size.
  173. inline bool HasFastArraySerialization(const FileDescriptor* file,
  174. const Options& options) {
  175. return GetOptimizeFor(file, options) == FileOptions::SPEED;
  176. }
  177. // Returns whether we have to generate code with static initializers.
  178. bool StaticInitializersForced(const FileDescriptor* file,
  179. const Options& options);
  180. inline bool IsMapEntryMessage(const Descriptor* descriptor) {
  181. return descriptor->options().map_entry();
  182. }
  183. // Returns true if the field's CPPTYPE is string or message.
  184. bool IsStringOrMessage(const FieldDescriptor* field);
  185. // For a string field, returns the effective ctype. If the actual ctype is
  186. // not supported, returns the default of STRING.
  187. FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field);
  188. string UnderscoresToCamelCase(const string& input, bool cap_next_letter);
  189. inline bool HasFieldPresence(const FileDescriptor* file) {
  190. return file->syntax() != FileDescriptor::SYNTAX_PROTO3;
  191. }
  192. // Returns true if 'enum' semantics are such that unknown values are preserved
  193. // in the enum field itself, rather than going to the UnknownFieldSet.
  194. inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) {
  195. return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
  196. }
  197. inline bool SupportsArenas(const FileDescriptor* file) {
  198. return file->options().cc_enable_arenas();
  199. }
  200. inline bool SupportsArenas(const Descriptor* desc) {
  201. return SupportsArenas(desc->file());
  202. }
  203. inline bool SupportsArenas(const FieldDescriptor* field) {
  204. return SupportsArenas(field->file());
  205. }
  206. bool IsAnyMessage(const FileDescriptor* descriptor);
  207. bool IsAnyMessage(const Descriptor* descriptor);
  208. bool IsWellKnownMessage(const FileDescriptor* descriptor);
  209. void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
  210. const Options& options, bool for_parse,
  211. const std::map<string, string>& variables,
  212. const char* parameters,
  213. io::Printer* printer);
  214. void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
  215. const Options& options, bool for_parse,
  216. const std::map<string, string>& variables,
  217. const char* parameters, io::Printer* printer);
  218. inline ::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor(
  219. const FileDescriptor* file, const Options& options) {
  220. return options.enforce_lite
  221. ? FileOptions::LITE_RUNTIME
  222. : file->options().optimize_for();
  223. }
  224. } // namespace cpp
  225. } // namespace compiler
  226. } // namespace protobuf
  227. } // namespace google
  228. #endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__