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 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 38#include <map> 39#include <string> 40#include <google/protobuf/descriptor.h> 41#include <google/protobuf/descriptor.pb.h> 42 43namespace google { 44namespace protobuf { 45 46namespace io { 47class Printer; 48} 49 50namespace compiler { 51namespace cpp { 52 53// Commonly-used separator comments. Thick is a line of '=', thin is a line 54// of '-'. 55extern const char kThickSeparator[]; 56extern 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 66string ClassName(const Descriptor* descriptor, bool qualified); 67string ClassName(const EnumDescriptor* enum_descriptor, bool qualified); 68 69string SuperClassName(const Descriptor* descriptor); 70 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(). 75string FieldName(const FieldDescriptor* field); 76 77// Get the unqualified name that should be used for a field's field 78// number constant. 79string FieldConstantName(const FieldDescriptor *field); 80 81// Returns the scope where the field was defined (for extensions, this is 82// different from the message type to which the field applies). 83inline const Descriptor* FieldScope(const FieldDescriptor* field) { 84 return field->is_extension() ? 85 field->extension_scope() : field->containing_type(); 86} 87 88// Returns the fully-qualified type name field->message_type(). Usually this 89// is just ClassName(field->message_type(), true); 90string FieldMessageTypeName(const FieldDescriptor* field); 91 92// Strips ".proto" or ".protodevel" from the end of a filename. 93string 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 "[". 100const 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". 104const char* DeclaredTypeMethodName(FieldDescriptor::Type type); 105 106// Return the code that evaluates to the number when compiled. 107string Int32ToString(int number); 108 109// Return the code that evaluates to the number when compiled. 110string Int64ToString(int64 number); 111 112// Get code that evaluates to the field's default value. 113string DefaultValue(const FieldDescriptor* field); 114 115// Convert a file name into a valid identifier. 116string FilenameIdentifier(const string& filename); 117 118// Return the name of the AddDescriptors() function for a given file. 119string GlobalAddDescriptorsName(const string& filename); 120 121// Return the name of the AssignDescriptors() function for a given file. 122string GlobalAssignDescriptorsName(const string& filename); 123 124// Return the qualified C++ name for a file level symbol. 125string QualifiedFileLevelSymbol(const string& package, const string& name); 126 127// Return the name of the ShutdownFile() function for a given file. 128string GlobalShutdownFileName(const string& filename); 129 130// Escape C++ trigraphs by escaping question marks to \? 131string EscapeTrigraphs(const string& to_escape); 132 133// Escaped function name to eliminate naming conflict. 134string SafeFunctionName(const Descriptor* descriptor, 135 const FieldDescriptor* field, 136 const string& prefix); 137 138// Do message classes in this file use UnknownFieldSet? 139// Otherwise, messages will store unknown fields in a string 140inline bool UseUnknownFieldSet(const FileDescriptor* file) { 141 return file->options().optimize_for() != FileOptions::LITE_RUNTIME; 142} 143 144 145// Does this file have any enum type definitions? 146bool HasEnumDefinitions(const FileDescriptor* file); 147 148// Does this file have generated parsing, serialization, and other 149// standard methods for which reflection-based fallback implementations exist? 150inline bool HasGeneratedMethods(const FileDescriptor* file) { 151 return file->options().optimize_for() != FileOptions::CODE_SIZE; 152} 153 154// Do message classes in this file have descriptor and reflection methods? 155inline bool HasDescriptorMethods(const FileDescriptor* file) { 156 return file->options().optimize_for() != FileOptions::LITE_RUNTIME; 157} 158 159// Should we generate generic services for this file? 160inline bool HasGenericServices(const FileDescriptor* file) { 161 return file->service_count() > 0 && 162 file->options().optimize_for() != FileOptions::LITE_RUNTIME && 163 file->options().cc_generic_services(); 164} 165 166// Should string fields in this file verify that their contents are UTF-8? 167inline bool HasUtf8Verification(const FileDescriptor* file) { 168 return file->options().optimize_for() != FileOptions::LITE_RUNTIME; 169} 170 171// Should we generate a separate, super-optimized code path for serializing to 172// flat arrays? We don't do this in Lite mode because we'd rather reduce code 173// size. 174inline bool HasFastArraySerialization(const FileDescriptor* file) { 175 return file->options().optimize_for() == FileOptions::SPEED; 176} 177 178// Returns whether we have to generate code with static initializers. 179bool StaticInitializersForced(const FileDescriptor* file); 180 181// Prints 'with_static_init' if static initializers have to be used for the 182// provided file. Otherwise emits both 'with_static_init' and 183// 'without_static_init' using #ifdef. 184void PrintHandlingOptionalStaticInitializers( 185 const FileDescriptor* file, io::Printer* printer, 186 const char* with_static_init, const char* without_static_init, 187 const char* var1 = NULL, const string& val1 = "", 188 const char* var2 = NULL, const string& val2 = ""); 189 190void PrintHandlingOptionalStaticInitializers( 191 const map<string, string>& vars, const FileDescriptor* file, 192 io::Printer* printer, const char* with_static_init, 193 const char* without_static_init); 194 195 196// Returns true if the field's CPPTYPE is string or message. 197bool IsStringOrMessage(const FieldDescriptor* field); 198 199string UnderscoresToCamelCase(const string& input, bool cap_next_letter); 200 201} // namespace cpp 202} // namespace compiler 203} // namespace protobuf 204 205} // namespace google 206#endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ 207