1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met:
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions of source code must retain the above copyright
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer.
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions in binary form must reproduce the above
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution.
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Neither the name of Google Inc. nor the names of its
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission.
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda)
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Based on original Protocol Buffers design by
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Sanjay Ghemawat, Jeff Dean, and others.
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
35d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <limits>
36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <vector>
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/hash.h>
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_helpers.h>
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h>
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h>
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/substitute.h>
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
44d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace compiler {
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace cpp {
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace {
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring DotsToUnderscores(const string& name) {
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return StringReplace(name, ".", "_", true);
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring DotsToColons(const string& name) {
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return StringReplace(name, ".", "::", true);
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char* const kKeywordList[] = {
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case",
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "catch", "char", "class", "compl", "const", "const_cast", "continue",
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "default", "delete", "do", "double", "dynamic_cast", "else", "enum",
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "explicit", "extern", "false", "float", "for", "friend", "goto", "if",
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "inline", "int", "long", "mutable", "namespace", "new", "not", "not_eq",
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "operator", "or", "or_eq", "private", "protected", "public", "register",
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "reinterpret_cast", "return", "short", "signed", "sizeof", "static",
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "static_cast", "struct", "switch", "template", "this", "throw", "true", "try",
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual",
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "void", "volatile", "wchar_t", "while", "xor", "xor_eq"
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville};
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillehash_set<string> MakeKeywordsMap() {
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  hash_set<string> result;
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < GOOGLE_ARRAYSIZE(kKeywordList); i++) {
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    result.insert(kKeywordList[i]);
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return result;
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillehash_set<string> kKeywords = MakeKeywordsMap();
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring UnderscoresToCamelCase(const string& input, bool cap_next_letter) {
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string result;
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Note:  I distrust ctype.h due to locales.
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < input.size(); i++) {
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if ('a' <= input[i] && input[i] <= 'z') {
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (cap_next_letter) {
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        result += input[i] + ('A' - 'a');
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        result += input[i];
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      cap_next_letter = false;
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if ('A' <= input[i] && input[i] <= 'Z') {
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Capital letters are left as-is.
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      result += input[i];
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      cap_next_letter = false;
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if ('0' <= input[i] && input[i] <= '9') {
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      result += input[i];
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      cap_next_letter = true;
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      cap_next_letter = true;
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return result;
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char kThickSeparator[] =
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "// ===================================================================\n";
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char kThinSeparator[] =
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "// -------------------------------------------------------------------\n";
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring ClassName(const Descriptor* descriptor, bool qualified) {
116d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Find "outer", the descriptor of the top-level message in which
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // "descriptor" is embedded.
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const Descriptor* outer = descriptor;
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (outer->containing_type() != NULL) outer = outer->containing_type();
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const string& outer_name = outer->full_name();
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string inner_name = descriptor->full_name().substr(outer_name.size());
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (qualified) {
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return "::" + DotsToColons(outer_name) + DotsToUnderscores(inner_name);
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return outer->name() + DotsToUnderscores(inner_name);
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring ClassName(const EnumDescriptor* enum_descriptor, bool qualified) {
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (enum_descriptor->containing_type() == NULL) {
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (qualified) {
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return DotsToColons(enum_descriptor->full_name());
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return enum_descriptor->name();
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    string result = ClassName(enum_descriptor->containing_type(), qualified);
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    result += '_';
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    result += enum_descriptor->name();
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return result;
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
147d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
148d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillestring SuperClassName(const Descriptor* descriptor) {
149d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  return HasDescriptorMethods(descriptor->file()) ?
150d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "::google::protobuf::Message" : "::google::protobuf::MessageLite";
151d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
152d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring FieldName(const FieldDescriptor* field) {
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string result = field->name();
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  LowerString(&result);
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (kKeywords.count(result) > 0) {
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    result.append("_");
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return result;
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring FieldConstantName(const FieldDescriptor *field) {
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string field_name = UnderscoresToCamelCase(field->name(), true);
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string result = "k" + field_name + "FieldNumber";
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!field->is_extension() &&
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field->containing_type()->FindFieldByCamelcaseName(
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        field->camelcase_name()) != field) {
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // This field's camelcase name is not unique.  As a hack, add the field
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // number to the constant name.  This makes the constant rather useless,
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // but what can we do?
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    result += "_" + SimpleItoa(field->number());
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return result;
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
178d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillestring FieldMessageTypeName(const FieldDescriptor* field) {
179d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Note:  The Google-internal version of Protocol Buffers uses this function
180d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  //   as a hook point for hacks to support legacy code.
181d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  return ClassName(field->message_type(), true);
182d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
183d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring StripProto(const string& filename) {
185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasSuffixString(filename, ".protodevel")) {
186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return StripSuffixString(filename, ".protodevel");
187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return StripSuffixString(filename, ".proto");
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char* PrimitiveTypeName(FieldDescriptor::CppType type) {
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  switch (type) {
194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_INT32  : return "::google::protobuf::int32";
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_INT64  : return "::google::protobuf::int64";
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_UINT32 : return "::google::protobuf::uint32";
197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_UINT64 : return "::google::protobuf::uint64";
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_DOUBLE : return "double";
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_FLOAT  : return "float";
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_BOOL   : return "bool";
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_ENUM   : return "int";
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_STRING : return "::std::string";
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_MESSAGE: return NULL;
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // No default because we want the compiler to complain if any new
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // CppTypes are added.
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_LOG(FATAL) << "Can't get here.";
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return NULL;
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char* DeclaredTypeMethodName(FieldDescriptor::Type type) {
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  switch (type) {
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_INT32   : return "Int32";
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_INT64   : return "Int64";
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_UINT32  : return "UInt32";
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_UINT64  : return "UInt64";
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_SINT32  : return "SInt32";
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_SINT64  : return "SInt64";
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_FIXED32 : return "Fixed32";
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_FIXED64 : return "Fixed64";
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_FLOAT   : return "Float";
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_DOUBLE  : return "Double";
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_BOOL    : return "Bool";
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_ENUM    : return "Enum";
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_STRING  : return "String";
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_BYTES   : return "Bytes";
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_GROUP   : return "Group";
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_MESSAGE : return "Message";
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // No default because we want the compiler to complain if any new
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // types are added.
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_LOG(FATAL) << "Can't get here.";
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return "";
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring DefaultValue(const FieldDescriptor* field) {
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  switch (field->cpp_type()) {
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_INT32:
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field->default_value_int32());
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_UINT32:
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field->default_value_uint32()) + "u";
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_INT64:
250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return "GOOGLE_LONGLONG(" + SimpleItoa(field->default_value_int64()) + ")";
251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_UINT64:
252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return "GOOGLE_ULONGLONG(" + SimpleItoa(field->default_value_uint64())+ ")";
253d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    case FieldDescriptor::CPPTYPE_DOUBLE: {
254d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      double value = field->default_value_double();
255d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (value == numeric_limits<double>::infinity()) {
256d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "::google::protobuf::internal::Infinity()";
257d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value == -numeric_limits<double>::infinity()) {
258d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "-::google::protobuf::internal::Infinity()";
259d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value != value) {
260d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "::google::protobuf::internal::NaN()";
261d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else {
262d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return SimpleDtoa(value);
263d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
264d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    }
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_FLOAT:
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      {
267d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        float value = field->default_value_float();
268d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        if (value == numeric_limits<float>::infinity()) {
269d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          return "static_cast<float>(::google::protobuf::internal::Infinity())";
270d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        } else if (value == -numeric_limits<float>::infinity()) {
271d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          return "static_cast<float>(-::google::protobuf::internal::Infinity())";
272d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        } else if (value != value) {
273d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          return "static_cast<float>(::google::protobuf::internal::NaN())";
274d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        } else {
275d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          string float_value = SimpleFtoa(value);
276d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          // If floating point value contains a period (.) or an exponent
277d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          // (either E or e), then append suffix 'f' to make it a float
278d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          // literal.
279d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          if (float_value.find_first_of(".eE") != string::npos) {
280d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville            float_value.push_back('f');
281d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          }
282d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          return float_value;
283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_BOOL:
286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return field->default_value_bool() ? "true" : "false";
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_ENUM:
288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Lazy:  Generate a static_cast because we don't have a helper function
289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      //   that constructs the full name of an enum value.
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return strings::Substitute(
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "static_cast< $0 >($1)",
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          ClassName(field->enum_type(), true),
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          field->default_value_enum()->number());
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_STRING:
295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return "\"" + CEscape(field->default_value_string()) + "\"";
296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_MESSAGE:
297d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      return FieldMessageTypeName(field) + "::default_instance()";
298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Can't actually get here; make compiler happy.  (We could add a default
300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // case above but then we wouldn't get the nice compiler warning when a
301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // new type is added.)
302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_LOG(FATAL) << "Can't get here.";
303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return "";
304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Convert a file name into a valid identifier.
307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring FilenameIdentifier(const string& filename) {
308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string result;
309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < filename.size(); i++) {
310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (ascii_isalnum(filename[i])) {
311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      result.push_back(filename[i]);
312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Not alphanumeric.  To avoid any possibility of name conflicts we
314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // use the hex code for the character.
315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      result.push_back('_');
316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      char buffer[kFastToBufferSize];
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      result.append(FastHexToBuffer(static_cast<uint8>(filename[i]), buffer));
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return result;
321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Return the name of the AddDescriptors() function for a given file.
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring GlobalAddDescriptorsName(const string& filename) {
325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return "protobuf_AddDesc_" + FilenameIdentifier(filename);
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Return the name of the AssignDescriptors() function for a given file.
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring GlobalAssignDescriptorsName(const string& filename) {
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return "protobuf_AssignDesc_" + FilenameIdentifier(filename);
331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Return the name of the ShutdownFile() function for a given file.
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring GlobalShutdownFileName(const string& filename) {
335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return "protobuf_ShutdownFile_" + FilenameIdentifier(filename);
336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace cpp
339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace compiler
340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
342