1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// http://code.google.com/p/protobuf/ 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// Get code that evaluates to the field's default value. 107string DefaultValue(const FieldDescriptor* field); 108 109// Convert a file name into a valid identifier. 110string FilenameIdentifier(const string& filename); 111 112// Return the name of the AddDescriptors() function for a given file. 113string GlobalAddDescriptorsName(const string& filename); 114 115// Return the name of the AssignDescriptors() function for a given file. 116string GlobalAssignDescriptorsName(const string& filename); 117 118// Return the name of the ShutdownFile() function for a given file. 119string GlobalShutdownFileName(const string& filename); 120 121// Escape C++ trigraphs by escaping question marks to \? 122string EscapeTrigraphs(const string& to_escape); 123 124// Do message classes in this file keep track of unknown fields? 125inline bool HasUnknownFields(const FileDescriptor* file) { 126 return file->options().optimize_for() != FileOptions::LITE_RUNTIME || 127 file->options().retain_unknown_fields(); 128} 129 130// Does this file have any enum type definitions? 131bool HasEnumDefinitions(const FileDescriptor* file); 132 133// Does this file have generated parsing, serialization, and other 134// standard methods for which reflection-based fallback implementations exist? 135inline bool HasGeneratedMethods(const FileDescriptor* file) { 136 return file->options().optimize_for() != FileOptions::CODE_SIZE; 137} 138 139// Do message classes in this file have descriptor and refelction methods? 140inline bool HasDescriptorMethods(const FileDescriptor* file) { 141 return file->options().optimize_for() != FileOptions::LITE_RUNTIME; 142} 143 144// Should we generate generic services for this file? 145inline bool HasGenericServices(const FileDescriptor* file) { 146 return file->service_count() > 0 && 147 file->options().optimize_for() != FileOptions::LITE_RUNTIME && 148 file->options().cc_generic_services(); 149} 150 151// Should string fields in this file verify that their contents are UTF-8? 152inline bool HasUtf8Verification(const FileDescriptor* file) { 153 return file->options().optimize_for() != FileOptions::LITE_RUNTIME; 154} 155 156// Should we generate a separate, super-optimized code path for serializing to 157// flat arrays? We don't do this in Lite mode because we'd rather reduce code 158// size. 159inline bool HasFastArraySerialization(const FileDescriptor* file) { 160 return file->options().optimize_for() == FileOptions::SPEED; 161} 162 163// Returns whether we have to generate code with static initializers. 164bool StaticInitializersForced(const FileDescriptor* file); 165 166// Prints 'with_static_init' if static initializers have to be used for the 167// provided file. Otherwise emits both 'with_static_init' and 168// 'without_static_init' using #ifdef. 169void PrintHandlingOptionalStaticInitializers( 170 const FileDescriptor* file, io::Printer* printer, 171 const char* with_static_init, const char* without_static_init, 172 const char* var1 = NULL, const string& val1 = "", 173 const char* var2 = NULL, const string& val2 = ""); 174 175void PrintHandlingOptionalStaticInitializers( 176 const map<string, string>& vars, const FileDescriptor* file, 177 io::Printer* printer, const char* with_static_init, 178 const char* without_static_init); 179 180 181} // namespace cpp 182} // namespace compiler 183} // namespace protobuf 184 185} // namespace google 186#endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ 187