temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 1 | // Protocol Buffers - Google's data interchange format |
kenton@google.com | 24bf56f | 2008-09-24 20:31:01 +0000 | [diff] [blame] | 2 | // Copyright 2008 Google Inc. All rights reserved. |
Feng Xiao | e428862 | 2014-10-01 16:26:23 -0700 | [diff] [blame] | 3 | // https://developers.google.com/protocol-buffers/ |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 4 | // |
kenton@google.com | 24bf56f | 2008-09-24 20:31:01 +0000 | [diff] [blame] | 5 | // Redistribution and use in source and binary forms, with or without |
| 6 | // modification, are permitted provided that the following conditions are |
| 7 | // met: |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 8 | // |
kenton@google.com | 24bf56f | 2008-09-24 20:31:01 +0000 | [diff] [blame] | 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. |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 18 | // |
kenton@google.com | 24bf56f | 2008-09-24 20:31:01 +0000 | [diff] [blame] | 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. |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 30 | |
| 31 | // Author: kenton@google.com (Kenton Varda) |
| 32 | // Based on original Protocol Buffers design by |
| 33 | // Sanjay Ghemawat, Jeff Dean, and others. |
| 34 | |
| 35 | #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ |
| 36 | #define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ |
| 37 | |
pliard@google.com | 6103d4e | 2012-05-04 11:16:09 +0000 | [diff] [blame] | 38 | #include <map> |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 39 | #include <string> |
| 40 | #include <google/protobuf/descriptor.h> |
kenton@google.com | 80b1d62 | 2009-07-29 01:13:20 +0000 | [diff] [blame] | 41 | #include <google/protobuf/descriptor.pb.h> |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 42 | |
| 43 | namespace google { |
| 44 | namespace protobuf { |
pliard@google.com | 6103d4e | 2012-05-04 11:16:09 +0000 | [diff] [blame] | 45 | |
| 46 | namespace io { |
| 47 | class Printer; |
| 48 | } |
| 49 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 50 | namespace compiler { |
| 51 | namespace cpp { |
| 52 | |
| 53 | // Commonly-used separator comments. Thick is a line of '=', thin is a line |
| 54 | // of '-'. |
| 55 | extern const char kThickSeparator[]; |
| 56 | extern const char kThinSeparator[]; |
| 57 | |
| 58 | // Returns the non-nested type name for the given type. If "qualified" is |
| 59 | // true, prefix the type with the full namespace. For example, if you had: |
| 60 | // package foo.bar; |
| 61 | // message Baz { message Qux {} } |
| 62 | // Then the qualified ClassName for Qux would be: |
| 63 | // ::foo::bar::Baz_Qux |
| 64 | // While the non-qualified version would be: |
| 65 | // Baz_Qux |
| 66 | string ClassName(const Descriptor* descriptor, bool qualified); |
| 67 | string ClassName(const EnumDescriptor* enum_descriptor, bool qualified); |
| 68 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 69 | string SuperClassName(const Descriptor* descriptor); |
| 70 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 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 | |
kenton@google.com | cfa2d8a | 2009-04-18 00:02:12 +0000 | [diff] [blame] | 77 | // Get the unqualified name that should be used for a field's field |
| 78 | // number constant. |
| 79 | string FieldConstantName(const FieldDescriptor *field); |
| 80 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 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 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 88 | // Returns the fully-qualified type name field->message_type(). Usually this |
| 89 | // is just ClassName(field->message_type(), true); |
| 90 | string FieldMessageTypeName(const FieldDescriptor* field); |
| 91 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 92 | // Strips ".proto" or ".protodevel" from the end of a filename. |
| 93 | string StripProto(const string& filename); |
| 94 | |
| 95 | // Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.). |
| 96 | // Note: non-built-in type names will be qualified, meaning they will start |
| 97 | // with a ::. If you are using the type as a template parameter, you will |
| 98 | // need to insure there is a space between the < and the ::, because the |
| 99 | // ridiculous C++ standard defines "<:" to be a synonym for "[". |
| 100 | const char* PrimitiveTypeName(FieldDescriptor::CppType type); |
| 101 | |
| 102 | // Get the declared type name in CamelCase format, as is used e.g. for the |
| 103 | // methods of WireFormat. For example, TYPE_INT32 becomes "Int32". |
| 104 | const char* DeclaredTypeMethodName(FieldDescriptor::Type type); |
| 105 | |
jieluo@google.com | 4de8f55 | 2014-07-18 00:47:59 +0000 | [diff] [blame] | 106 | // Return the code that evaluates to the number when compiled. |
| 107 | string Int32ToString(int number); |
| 108 | |
| 109 | // Return the code that evaluates to the number when compiled. |
| 110 | string Int64ToString(int64 number); |
| 111 | |
kenton@google.com | d37d46d | 2009-04-25 02:53:47 +0000 | [diff] [blame] | 112 | // Get code that evaluates to the field's default value. |
| 113 | string DefaultValue(const FieldDescriptor* field); |
| 114 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 115 | // Convert a file name into a valid identifier. |
| 116 | string FilenameIdentifier(const string& filename); |
| 117 | |
kenton@google.com | d37d46d | 2009-04-25 02:53:47 +0000 | [diff] [blame] | 118 | // Return the name of the AddDescriptors() function for a given file. |
| 119 | string GlobalAddDescriptorsName(const string& filename); |
| 120 | |
| 121 | // Return the name of the AssignDescriptors() function for a given file. |
| 122 | string GlobalAssignDescriptorsName(const string& filename); |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 123 | |
jieluo@google.com | 4de8f55 | 2014-07-18 00:47:59 +0000 | [diff] [blame] | 124 | // Return the qualified C++ name for a file level symbol. |
| 125 | string QualifiedFileLevelSymbol(const string& package, const string& name); |
| 126 | |
kenton@google.com | 63e646b | 2009-05-06 19:27:03 +0000 | [diff] [blame] | 127 | // Return the name of the ShutdownFile() function for a given file. |
| 128 | string GlobalShutdownFileName(const string& filename); |
| 129 | |
liujisi@google.com | 5c20ca1 | 2010-12-21 05:33:13 +0000 | [diff] [blame] | 130 | // Escape C++ trigraphs by escaping question marks to \? |
| 131 | string EscapeTrigraphs(const string& to_escape); |
| 132 | |
jieluo@google.com | 4de8f55 | 2014-07-18 00:47:59 +0000 | [diff] [blame] | 133 | // Escaped function name to eliminate naming conflict. |
| 134 | string SafeFunctionName(const Descriptor* descriptor, |
| 135 | const FieldDescriptor* field, |
| 136 | const string& prefix); |
| 137 | |
Feng Xiao | 6ef984a | 2014-11-10 17:34:54 -0800 | [diff] [blame] | 138 | // Returns true if unknown fields are preseved after parsing. |
| 139 | inline bool PreserveUnknownFields(const Descriptor* message) { |
| 140 | return message->file()->syntax() != FileDescriptor::SYNTAX_PROTO3; |
| 141 | } |
| 142 | |
| 143 | // If PreserveUnknownFields() is true, determines whether unknown |
| 144 | // fields will be stored in an UnknownFieldSet or a string. |
| 145 | // If PreserveUnknownFields() is false, this method will not be |
| 146 | // used. |
jieluo@google.com | 4de8f55 | 2014-07-18 00:47:59 +0000 | [diff] [blame] | 147 | inline bool UseUnknownFieldSet(const FileDescriptor* file) { |
kenton@google.com | 80b1d62 | 2009-07-29 01:13:20 +0000 | [diff] [blame] | 148 | return file->options().optimize_for() != FileOptions::LITE_RUNTIME; |
| 149 | } |
| 150 | |
xiaofeng@google.com | b55a20f | 2012-09-22 02:40:50 +0000 | [diff] [blame] | 151 | |
Feng Xiao | f157a56 | 2014-11-14 11:50:31 -0800 | [diff] [blame] | 152 | // Does the file have any map fields, necessitating the file to include |
| 153 | // map_field_inl.h and map.h. |
| 154 | bool HasMapFields(const FileDescriptor* file); |
| 155 | |
xiaofeng@google.com | b55a20f | 2012-09-22 02:40:50 +0000 | [diff] [blame] | 156 | // Does this file have any enum type definitions? |
| 157 | bool HasEnumDefinitions(const FileDescriptor* file); |
| 158 | |
kenton@google.com | 80b1d62 | 2009-07-29 01:13:20 +0000 | [diff] [blame] | 159 | // Does this file have generated parsing, serialization, and other |
| 160 | // standard methods for which reflection-based fallback implementations exist? |
xiaofeng@google.com | b55a20f | 2012-09-22 02:40:50 +0000 | [diff] [blame] | 161 | inline bool HasGeneratedMethods(const FileDescriptor* file) { |
kenton@google.com | 80b1d62 | 2009-07-29 01:13:20 +0000 | [diff] [blame] | 162 | return file->options().optimize_for() != FileOptions::CODE_SIZE; |
| 163 | } |
| 164 | |
xiaofeng@google.com | b55a20f | 2012-09-22 02:40:50 +0000 | [diff] [blame] | 165 | // Do message classes in this file have descriptor and reflection methods? |
| 166 | inline bool HasDescriptorMethods(const FileDescriptor* file) { |
kenton@google.com | 80b1d62 | 2009-07-29 01:13:20 +0000 | [diff] [blame] | 167 | return file->options().optimize_for() != FileOptions::LITE_RUNTIME; |
| 168 | } |
| 169 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 170 | // Should we generate generic services for this file? |
xiaofeng@google.com | b55a20f | 2012-09-22 02:40:50 +0000 | [diff] [blame] | 171 | inline bool HasGenericServices(const FileDescriptor* file) { |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 172 | return file->service_count() > 0 && |
| 173 | file->options().optimize_for() != FileOptions::LITE_RUNTIME && |
| 174 | file->options().cc_generic_services(); |
| 175 | } |
| 176 | |
kenton@google.com | 80b1d62 | 2009-07-29 01:13:20 +0000 | [diff] [blame] | 177 | // Should string fields in this file verify that their contents are UTF-8? |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 178 | inline bool HasUtf8Verification(const FileDescriptor* file) { |
kenton@google.com | 80b1d62 | 2009-07-29 01:13:20 +0000 | [diff] [blame] | 179 | return file->options().optimize_for() != FileOptions::LITE_RUNTIME; |
| 180 | } |
| 181 | |
| 182 | // Should we generate a separate, super-optimized code path for serializing to |
| 183 | // flat arrays? We don't do this in Lite mode because we'd rather reduce code |
| 184 | // size. |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 185 | inline bool HasFastArraySerialization(const FileDescriptor* file) { |
kenton@google.com | 80b1d62 | 2009-07-29 01:13:20 +0000 | [diff] [blame] | 186 | return file->options().optimize_for() == FileOptions::SPEED; |
| 187 | } |
| 188 | |
pliard@google.com | 6103d4e | 2012-05-04 11:16:09 +0000 | [diff] [blame] | 189 | // Returns whether we have to generate code with static initializers. |
| 190 | bool StaticInitializersForced(const FileDescriptor* file); |
| 191 | |
| 192 | // Prints 'with_static_init' if static initializers have to be used for the |
| 193 | // provided file. Otherwise emits both 'with_static_init' and |
| 194 | // 'without_static_init' using #ifdef. |
| 195 | void PrintHandlingOptionalStaticInitializers( |
| 196 | const FileDescriptor* file, io::Printer* printer, |
| 197 | const char* with_static_init, const char* without_static_init, |
| 198 | const char* var1 = NULL, const string& val1 = "", |
| 199 | const char* var2 = NULL, const string& val2 = ""); |
| 200 | |
| 201 | void PrintHandlingOptionalStaticInitializers( |
| 202 | const map<string, string>& vars, const FileDescriptor* file, |
| 203 | io::Printer* printer, const char* with_static_init, |
| 204 | const char* without_static_init); |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 205 | |
xiaofeng@google.com | b55a20f | 2012-09-22 02:40:50 +0000 | [diff] [blame] | 206 | |
Feng Xiao | f157a56 | 2014-11-14 11:50:31 -0800 | [diff] [blame] | 207 | inline bool IsMapEntryMessage(const Descriptor* descriptor) { |
| 208 | return descriptor->options().map_entry(); |
| 209 | } |
| 210 | |
jieluo@google.com | 4de8f55 | 2014-07-18 00:47:59 +0000 | [diff] [blame] | 211 | // Returns true if the field's CPPTYPE is string or message. |
| 212 | bool IsStringOrMessage(const FieldDescriptor* field); |
| 213 | |
Jisi Liu | 885b612 | 2015-02-28 14:51:22 -0800 | [diff] [blame^] | 214 | // For a string field, returns the effective ctype. If the actual ctype is |
| 215 | // not supported, returns the default of STRING. |
| 216 | FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field); |
| 217 | |
jieluo@google.com | 4de8f55 | 2014-07-18 00:47:59 +0000 | [diff] [blame] | 218 | string UnderscoresToCamelCase(const string& input, bool cap_next_letter); |
| 219 | |
Feng Xiao | 6ef984a | 2014-11-10 17:34:54 -0800 | [diff] [blame] | 220 | inline bool HasFieldPresence(const FileDescriptor* file) { |
| 221 | return file->syntax() != FileDescriptor::SYNTAX_PROTO3; |
| 222 | } |
| 223 | |
| 224 | // Returns true if 'enum' semantics are such that unknown values are preserved |
| 225 | // in the enum field itself, rather than going to the UnknownFieldSet. |
| 226 | inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) { |
| 227 | return file->syntax() == FileDescriptor::SYNTAX_PROTO3; |
| 228 | } |
| 229 | |
| 230 | inline bool SupportsArenas(const FileDescriptor* file) { |
Feng Xiao | f157a56 | 2014-11-14 11:50:31 -0800 | [diff] [blame] | 231 | return file->options().cc_enable_arenas(); |
Feng Xiao | 6ef984a | 2014-11-10 17:34:54 -0800 | [diff] [blame] | 232 | } |
| 233 | |
| 234 | inline bool SupportsArenas(const Descriptor* desc) { |
| 235 | return SupportsArenas(desc->file()); |
| 236 | } |
| 237 | |
| 238 | inline bool SupportsArenas(const FieldDescriptor* field) { |
| 239 | return SupportsArenas(field->file()); |
| 240 | } |
| 241 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 242 | } // namespace cpp |
| 243 | } // namespace compiler |
| 244 | } // namespace protobuf |
| 245 | |
| 246 | } // namespace google |
| 247 | #endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ |