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