1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc.
3
// http://code.google.com/p/protobuf/
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
9
// http://www.apache.org/licenses/LICENSE-2.0
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
17
// Author: kenton@google.com (Kenton Varda)
18
// Based on original Protocol Buffers design by
19
// Sanjay Ghemawat, Jeff Dean, and others.
22
#include <google/protobuf/stubs/hash.h>
24
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
25
#include <google/protobuf/stubs/common.h>
26
#include <google/protobuf/stubs/strutil.h>
35
string DotsToUnderscores(const string& name) {
36
return StringReplace(name, ".", "_", true);
39
string DotsToColons(const string& name) {
40
return StringReplace(name, ".", "::", true);
43
const char* const kKeywordList[] = {
44
"and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case",
45
"catch", "char", "class", "compl", "const", "const_cast", "continue",
46
"default", "delete", "do", "double", "dynamic_cast", "else", "enum",
47
"explicit", "extern", "false", "float", "for", "friend", "goto", "if",
48
"inline", "int", "long", "mutable", "namespace", "new", "not", "not_eq",
49
"operator", "or", "or_eq", "private", "protected", "public", "register",
50
"reinterpret_cast", "return", "short", "signed", "sizeof", "static",
51
"static_cast", "struct", "switch", "template", "this", "throw", "true", "try",
52
"typedef", "typeid", "typename", "union", "unsigned", "using", "virtual",
53
"void", "volatile", "wchar_t", "while", "xor", "xor_eq"
56
hash_set<string> MakeKeywordsMap() {
57
hash_set<string> result;
58
for (int i = 0; i < GOOGLE_ARRAYSIZE(kKeywordList); i++) {
59
result.insert(kKeywordList[i]);
64
hash_set<string> kKeywords = MakeKeywordsMap();
68
const char kThickSeparator[] =
69
"// ===================================================================\n";
70
const char kThinSeparator[] =
71
"// -------------------------------------------------------------------\n";
73
string ClassName(const Descriptor* descriptor, bool qualified) {
74
// Find "outer", the descriptor of the top-level message in which
75
// "descriptor" is embedded.
76
const Descriptor* outer = descriptor;
77
while (outer->containing_type() != NULL) outer = outer->containing_type();
79
const string& outer_name = outer->full_name();
80
string inner_name = descriptor->full_name().substr(outer_name.size());
83
return "::" + DotsToColons(outer_name) + DotsToUnderscores(inner_name);
85
return outer->name() + DotsToUnderscores(inner_name);
89
string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) {
90
if (enum_descriptor->containing_type() == NULL) {
92
return DotsToColons(enum_descriptor->full_name());
94
return enum_descriptor->name();
97
string result = ClassName(enum_descriptor->containing_type(), qualified);
99
result += enum_descriptor->name();
104
string FieldName(const FieldDescriptor* field) {
105
string result = field->name();
106
LowerString(&result);
107
if (kKeywords.count(result) > 0) {
113
string StripProto(const string& filename) {
114
if (HasSuffixString(filename, ".protodevel")) {
115
return StripSuffixString(filename, ".protodevel");
117
return StripSuffixString(filename, ".proto");
121
const char* PrimitiveTypeName(FieldDescriptor::CppType type) {
123
case FieldDescriptor::CPPTYPE_INT32 : return "::google::protobuf::int32";
124
case FieldDescriptor::CPPTYPE_INT64 : return "::google::protobuf::int64";
125
case FieldDescriptor::CPPTYPE_UINT32 : return "::google::protobuf::uint32";
126
case FieldDescriptor::CPPTYPE_UINT64 : return "::google::protobuf::uint64";
127
case FieldDescriptor::CPPTYPE_DOUBLE : return "double";
128
case FieldDescriptor::CPPTYPE_FLOAT : return "float";
129
case FieldDescriptor::CPPTYPE_BOOL : return "bool";
130
case FieldDescriptor::CPPTYPE_ENUM : return "int";
131
case FieldDescriptor::CPPTYPE_STRING : return "::std::string";
132
case FieldDescriptor::CPPTYPE_MESSAGE: return NULL;
134
// No default because we want the compiler to complain if any new
135
// CppTypes are added.
138
GOOGLE_LOG(FATAL) << "Can't get here.";
142
const char* DeclaredTypeMethodName(FieldDescriptor::Type type) {
144
case FieldDescriptor::TYPE_INT32 : return "Int32";
145
case FieldDescriptor::TYPE_INT64 : return "Int64";
146
case FieldDescriptor::TYPE_UINT32 : return "UInt32";
147
case FieldDescriptor::TYPE_UINT64 : return "UInt64";
148
case FieldDescriptor::TYPE_SINT32 : return "SInt32";
149
case FieldDescriptor::TYPE_SINT64 : return "SInt64";
150
case FieldDescriptor::TYPE_FIXED32 : return "Fixed32";
151
case FieldDescriptor::TYPE_FIXED64 : return "Fixed64";
152
case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
153
case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
154
case FieldDescriptor::TYPE_FLOAT : return "Float";
155
case FieldDescriptor::TYPE_DOUBLE : return "Double";
157
case FieldDescriptor::TYPE_BOOL : return "Bool";
158
case FieldDescriptor::TYPE_ENUM : return "Enum";
160
case FieldDescriptor::TYPE_STRING : return "String";
161
case FieldDescriptor::TYPE_BYTES : return "Bytes";
162
case FieldDescriptor::TYPE_GROUP : return "Group";
163
case FieldDescriptor::TYPE_MESSAGE : return "Message";
165
// No default because we want the compiler to complain if any new
168
GOOGLE_LOG(FATAL) << "Can't get here.";
172
// Convert a file name into a valid identifier.
173
string FilenameIdentifier(const string& filename) {
175
for (int i = 0; i < filename.size(); i++) {
176
if (ascii_isalnum(filename[i])) {
177
result.push_back(filename[i]);
179
// Not alphanumeric. To avoid any possibility of name conflicts we
180
// use the hex code for the character.
181
result.push_back('_');
182
char buffer[kFastToBufferSize];
183
result.append(FastHexToBuffer(static_cast<uint8>(filename[i]), buffer));
189
// Return the name of the BuildDescriptors() function for a given file.
190
string GlobalBuildDescriptorsName(const string& filename) {
191
return "proto_BuildDescriptors_" + FilenameIdentifier(filename);
195
} // namespace compiler
196
} // namespace protobuf
197
} // namespace google