15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met: 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions of source code must retain the above copyright 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Based on original Protocol Buffers design by 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sanjay Ghemawat, Jeff Dean, and others. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.h> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.pb.h> 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace io { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Printer; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace compiler { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace cpp { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Commonly-used separator comments. Thick is a line of '=', thin is a line 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of '-'. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kThickSeparator[]; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kThinSeparator[]; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the non-nested type name for the given type. If "qualified" is 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true, prefix the type with the full namespace. For example, if you had: 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// package foo.bar; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message Baz { message Qux {} } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Then the qualified ClassName for Qux would be: 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ::foo::bar::Baz_Qux 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// While the non-qualified version would be: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Baz_Qux 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string ClassName(const Descriptor* descriptor, bool qualified); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string ClassName(const EnumDescriptor* enum_descriptor, bool qualified); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string SuperClassName(const Descriptor* descriptor); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get the (unqualified) name that should be used for this field in C++ code. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The name is coerced to lower-case to emulate proto1 behavior. People 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should be using lowercase-with-underscores style for proto field names 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// anyway, so normally this just returns field->name(). 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string FieldName(const FieldDescriptor* field); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get the unqualified name that should be used for a field's field 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// number constant. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string FieldConstantName(const FieldDescriptor *field); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the scope where the field was defined (for extensions, this is 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// different from the message type to which the field applies). 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline const Descriptor* FieldScope(const FieldDescriptor* field) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return field->is_extension() ? 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->extension_scope() : field->containing_type(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the fully-qualified type name field->message_type(). Usually this 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is just ClassName(field->message_type(), true); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string FieldMessageTypeName(const FieldDescriptor* field); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Strips ".proto" or ".protodevel" from the end of a filename. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string StripProto(const string& filename); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.). 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: non-built-in type names will be qualified, meaning they will start 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with a ::. If you are using the type as a template parameter, you will 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need to insure there is a space between the < and the ::, because the 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ridiculous C++ standard defines "<:" to be a synonym for "[". 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* PrimitiveTypeName(FieldDescriptor::CppType type); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get the declared type name in CamelCase format, as is used e.g. for the 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// methods of WireFormat. For example, TYPE_INT32 becomes "Int32". 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* DeclaredTypeMethodName(FieldDescriptor::Type type); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get code that evaluates to the field's default value. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string DefaultValue(const FieldDescriptor* field); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert a file name into a valid identifier. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string FilenameIdentifier(const string& filename); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return the name of the AddDescriptors() function for a given file. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GlobalAddDescriptorsName(const string& filename); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return the name of the AssignDescriptors() function for a given file. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GlobalAssignDescriptorsName(const string& filename); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return the name of the ShutdownFile() function for a given file. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GlobalShutdownFileName(const string& filename); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Escape C++ trigraphs by escaping question marks to \? 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string EscapeTrigraphs(const string& to_escape); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Do message classes in this file keep track of unknown fields? 1253d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochinline bool HasUnknownFields(const FileDescriptor* file) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file->options().optimize_for() != FileOptions::LITE_RUNTIME || 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file->options().retain_unknown_fields(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1303d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch// Does this file have any enum type definitions? 1313d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochbool HasEnumDefinitions(const FileDescriptor* file); 1323d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Does this file have generated parsing, serialization, and other 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// standard methods for which reflection-based fallback implementations exist? 1353d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochinline bool HasGeneratedMethods(const FileDescriptor* file) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file->options().optimize_for() != FileOptions::CODE_SIZE; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Do message classes in this file have descriptor and refelction methods? 1403d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochinline bool HasDescriptorMethods(const FileDescriptor* file) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file->options().optimize_for() != FileOptions::LITE_RUNTIME; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Should we generate generic services for this file? 1453d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochinline bool HasGenericServices(const FileDescriptor* file) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file->service_count() > 0 && 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file->options().optimize_for() != FileOptions::LITE_RUNTIME && 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file->options().cc_generic_services(); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Should string fields in this file verify that their contents are UTF-8? 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool HasUtf8Verification(const FileDescriptor* file) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file->options().optimize_for() != FileOptions::LITE_RUNTIME; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Should we generate a separate, super-optimized code path for serializing to 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// flat arrays? We don't do this in Lite mode because we'd rather reduce code 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// size. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool HasFastArraySerialization(const FileDescriptor* file) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file->options().optimize_for() == FileOptions::SPEED; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns whether we have to generate code with static initializers. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StaticInitializersForced(const FileDescriptor* file); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints 'with_static_init' if static initializers have to be used for the 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// provided file. Otherwise emits both 'with_static_init' and 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 'without_static_init' using #ifdef. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintHandlingOptionalStaticInitializers( 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptor* file, io::Printer* printer, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* with_static_init, const char* without_static_init, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* var1 = NULL, const string& val1 = "", 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* var2 = NULL, const string& val2 = ""); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintHandlingOptionalStaticInitializers( 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const map<string, string>& vars, const FileDescriptor* file, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::Printer* printer, const char* with_static_init, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* without_static_init); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1803d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace cpp 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace compiler 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protobuf 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace google 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ 187