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
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/java/java_helpers.h>
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.pb.h>
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h>
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/substitute.h>
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace compiler {
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace java {
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char kThickSeparator[] =
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "// ===================================================================\n";
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char kThinSeparator[] =
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "// -------------------------------------------------------------------\n";
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace {
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char* kDefaultPackage = "";
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst string& FieldName(const FieldDescriptor* field) {
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Groups are hacky:  The name of the field is just the lower-cased name
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // of the group type.  In Java, though, we would like to retain the original
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // capitalization of the type name.
61d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (GetType(field) == FieldDescriptor::TYPE_GROUP) {
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return field->message_type()->name();
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return field->name();
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) {
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string result;
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Note:  I distrust ctype.h due to locales.
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < input.size(); i++) {
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if ('a' <= input[i] && input[i] <= 'z') {
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (cap_next_letter) {
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        result += input[i] + ('A' - 'a');
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        result += input[i];
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      cap_next_letter = false;
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if ('A' <= input[i] && input[i] <= 'Z') {
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (i == 0 && !cap_next_letter) {
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // Force first letter to lower-case unless explicitly told to
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // capitalize it.
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        result += input[i] + ('a' - 'A');
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // Capital letters after the first are left as-is.
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        result += input[i];
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      cap_next_letter = false;
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if ('0' <= input[i] && input[i] <= '9') {
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      result += input[i];
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      cap_next_letter = true;
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      cap_next_letter = true;
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return result;
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring UnderscoresToCamelCase(const FieldDescriptor* field) {
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return UnderscoresToCamelCaseImpl(FieldName(field), false);
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return UnderscoresToCamelCaseImpl(FieldName(field), true);
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring UnderscoresToCamelCase(const MethodDescriptor* method) {
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return UnderscoresToCamelCaseImpl(method->name(), false);
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring StripProto(const string& filename) {
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasSuffixString(filename, ".protodevel")) {
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return StripSuffixString(filename, ".protodevel");
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return StripSuffixString(filename, ".proto");
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring FileClassName(const FileDescriptor* file) {
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (file->options().has_java_outer_classname()) {
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return file->options().java_outer_classname();
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    string basename;
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    string::size_type last_slash = file->name().find_last_of('/');
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (last_slash == string::npos) {
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      basename = file->name();
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      basename = file->name().substr(last_slash + 1);
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return UnderscoresToCamelCaseImpl(StripProto(basename), true);
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring FileJavaPackage(const FileDescriptor* file) {
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (file->options().has_java_package()) {
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return file->options().java_package();
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    string result = kDefaultPackage;
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!file->package().empty()) {
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (!result.empty()) result += '.';
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      result += file->package();
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return result;
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring ToJavaName(const string& full_name, const FileDescriptor* file) {
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string result;
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (file->options().java_multiple_files()) {
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    result = FileJavaPackage(file);
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    result = ClassName(file);
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!result.empty()) {
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    result += '.';
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (file->package().empty()) {
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    result += full_name;
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Strip the proto package from full_name since we've replaced it with
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // the Java package.
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    result += full_name.substr(file->package().size() + 1);
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return result;
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring ClassName(const FileDescriptor* descriptor) {
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string result = FileJavaPackage(descriptor);
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!result.empty()) result += '.';
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  result += FileClassName(descriptor);
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return result;
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring FieldConstantName(const FieldDescriptor *field) {
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string name = field->name() + "_FIELD_NUMBER";
178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UpperString(&name);
179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return name;
180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
182d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleFieldDescriptor::Type GetType(const FieldDescriptor* field) {
183d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  return field->type();
184d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
185d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
186d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleJavaType GetJavaType(const FieldDescriptor* field) {
187d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  switch (GetType(field)) {
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_INT32:
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_UINT32:
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_SINT32:
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_FIXED32:
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_SFIXED32:
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return JAVATYPE_INT;
194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_INT64:
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_UINT64:
197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_SINT64:
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_FIXED64:
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_SFIXED64:
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return JAVATYPE_LONG;
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_FLOAT:
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return JAVATYPE_FLOAT;
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_DOUBLE:
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return JAVATYPE_DOUBLE;
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_BOOL:
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return JAVATYPE_BOOLEAN;
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_STRING:
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return JAVATYPE_STRING;
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_BYTES:
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return JAVATYPE_BYTES;
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_ENUM:
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return JAVATYPE_ENUM;
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_GROUP:
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::TYPE_MESSAGE:
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return JAVATYPE_MESSAGE;
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // No default because we want the compiler to complain if any new
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // types are added.
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_LOG(FATAL) << "Can't get here.";
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return JAVATYPE_INT;
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char* BoxedPrimitiveTypeName(JavaType type) {
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  switch (type) {
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case JAVATYPE_INT    : return "java.lang.Integer";
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case JAVATYPE_LONG   : return "java.lang.Long";
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case JAVATYPE_FLOAT  : return "java.lang.Float";
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case JAVATYPE_DOUBLE : return "java.lang.Double";
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case JAVATYPE_BOOLEAN: return "java.lang.Boolean";
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case JAVATYPE_STRING : return "java.lang.String";
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case JAVATYPE_BYTES  : return "com.google.protobuf.ByteString";
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case JAVATYPE_ENUM   : return NULL;
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case JAVATYPE_MESSAGE: return NULL;
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // No default because we want the compiler to complain if any new
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // JavaTypes are added.
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_LOG(FATAL) << "Can't get here.";
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return NULL;
250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool AllAscii(const string& text) {
253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < text.size(); i++) {
254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if ((text[i] & 0x80) != 0) {
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return false;
256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring DefaultValue(const FieldDescriptor* field) {
262d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Switch on CppType since we need to know which default_value_* method
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // of FieldDescriptor to call.
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  switch (field->cpp_type()) {
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_INT32:
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field->default_value_int32());
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_UINT32:
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Need to print as a signed int since Java has no unsigned.
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_INT64:
271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field->default_value_int64()) + "L";
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_UINT64:
273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville             "L";
275d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    case FieldDescriptor::CPPTYPE_DOUBLE: {
276d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      double value = field->default_value_double();
277d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (value == numeric_limits<double>::infinity()) {
278d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "Double.POSITIVE_INFINITY";
279d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value == -numeric_limits<double>::infinity()) {
280d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "Double.NEGATIVE_INFINITY";
281d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value != value) {
282d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "Double.NaN";
283d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else {
284d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return SimpleDtoa(value) + "D";
285d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
286d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    }
287d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    case FieldDescriptor::CPPTYPE_FLOAT: {
288d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      float value = field->default_value_float();
289d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (value == numeric_limits<float>::infinity()) {
290d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "Float.POSITIVE_INFINITY";
291d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value == -numeric_limits<float>::infinity()) {
292d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "Float.NEGATIVE_INFINITY";
293d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value != value) {
294d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "Float.NaN";
295d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else {
296d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return SimpleFtoa(value) + "F";
297d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
298d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    }
299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_BOOL:
300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return field->default_value_bool() ? "true" : "false";
301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_STRING:
302d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (GetType(field) == FieldDescriptor::TYPE_BYTES) {
303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (field->has_default_value()) {
304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          // See comments in Internal.java for gory details.
305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          return strings::Substitute(
306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            "com.google.protobuf.Internal.bytesDefaultValue(\"$0\")",
307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            CEscape(field->default_value_string()));
308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        } else {
309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          return "com.google.protobuf.ByteString.EMPTY";
310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (AllAscii(field->default_value_string())) {
313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          // All chars are ASCII.  In this case CEscape() works fine.
314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          return "\"" + CEscape(field->default_value_string()) + "\"";
315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        } else {
316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          // See comments in Internal.java for gory details.
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          return strings::Substitute(
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            "com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            CEscape(field->default_value_string()));
320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_ENUM:
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return ClassName(field->enum_type()) + "." +
325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville             field->default_value_enum()->name();
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_MESSAGE:
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return ClassName(field->message_type()) + ".getDefaultInstance()";
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // No default because we want the compiler to complain if any new
331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // types are added.
332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_LOG(FATAL) << "Can't get here.";
335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return "";
336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace java
339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace compiler
340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
342