164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Protocol Buffers - Google's data interchange format
264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Copyright 2008 Google Inc.  All rights reserved.
364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// http://code.google.com/p/protobuf/
464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//
564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Redistribution and use in source and binary forms, with or without
664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// modification, are permitted provided that the following conditions are
764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// met:
864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//
964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//     * Redistributions of source code must retain the above copyright
1064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// notice, this list of conditions and the following disclaimer.
1164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//     * Redistributions in binary form must reproduce the above
1264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// copyright notice, this list of conditions and the following disclaimer
1364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// in the documentation and/or other materials provided with the
1464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// distribution.
1564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//     * Neither the name of Google Inc. nor the names of its
1664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// contributors may be used to endorse or promote products derived from
1764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// this software without specific prior written permission.
1864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//
1964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
3164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Author: kenton@google.com (Kenton Varda)
3264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//  Based on original Protocol Buffers design by
3364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//  Sanjay Ghemawat, Jeff Dean, and others.
3464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
350f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith#include <limits>
3664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <vector>
3764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
3864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_helpers.h>
3964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_params.h>
4064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/descriptor.pb.h>
41f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao#include <google/protobuf/stubs/hash.h>
4264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/stubs/strutil.h>
4364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/stubs/substitute.h>
4464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
4564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace google {
4664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace protobuf {
4764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace compiler {
4864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace javanano {
4964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
5064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciconst char kThickSeparator[] =
5164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  "// ===================================================================\n";
5264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciconst char kThinSeparator[] =
5364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  "// -------------------------------------------------------------------\n";
5464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
55f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chaoclass RenameKeywords {
56f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao private:
57f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao  hash_set<string> java_keywords_set_;
58f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao
59f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao public:
60f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao  RenameKeywords() {
61f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao    static const char* kJavaKeywordsList[] = {
62f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao      // Reserved Java Keywords
63f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao      "abstract", "assert", "boolean", "break", "byte", "case", "catch",
64f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao      "char", "class", "const", "continue", "default", "do", "double", "else",
65f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao      "enum", "extends", "final", "finally", "float", "for", "goto", "if",
66f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao      "implements", "import", "instanceof", "int", "interface", "long",
67f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao      "native", "new", "package", "private", "protected", "public", "return",
68f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao      "short", "static", "strictfp", "super", "switch", "synchronized",
69f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao      "this", "throw", "throws", "transient", "try", "void", "volatile", "while",
70f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao
71f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao      // Reserved Keywords for Literals
72f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao      "false", "null", "true"
73f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao    };
74f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao
75f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao    for (int i = 0; i < GOOGLE_ARRAYSIZE(kJavaKeywordsList); i++) {
76f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao      java_keywords_set_.insert(kJavaKeywordsList[i]);
77f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao    }
78f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao  }
79f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao
80f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao  // Used to rename the a field name if it's a java keyword.  Specifically
81f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao  // this is used to rename the ["name"] or ["capitalized_name"] field params.
82f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao  // (http://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html)
83f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao  string RenameJavaKeywordsImpl(const string& input) {
84f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao    string result = input;
85f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao
86f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao    if (java_keywords_set_.find(result) != java_keywords_set_.end()) {
87f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao      result += "_";
88f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao    }
89f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao
90f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao    return result;
91f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao  }
92f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao
93f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao};
94f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao
95f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chaostatic RenameKeywords sRenameKeywords;
96f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao
9764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace {
9864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
9964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciconst char* kDefaultPackage = "";
10064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
10164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciconst string& FieldName(const FieldDescriptor* field) {
10264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // Groups are hacky:  The name of the field is just the lower-cased name
10364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // of the group type.  In Java, though, we would like to retain the original
10464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // capitalization of the type name.
10564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (field->type() == FieldDescriptor::TYPE_GROUP) {
10664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return field->message_type()->name();
10764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
10864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return field->name();
10964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
11064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
11164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
11264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) {
11364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  string result;
11464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // Note:  I distrust ctype.h due to locales.
11564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  for (int i = 0; i < input.size(); i++) {
11664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    if ('a' <= input[i] && input[i] <= 'z') {
11764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      if (cap_next_letter) {
11864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        result += input[i] + ('A' - 'a');
11964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      } else {
12064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        result += input[i];
12164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      }
12264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      cap_next_letter = false;
12364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    } else if ('A' <= input[i] && input[i] <= 'Z') {
12464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      if (i == 0 && !cap_next_letter) {
12564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        // Force first letter to lower-case unless explicitly told to
12664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        // capitalize it.
12764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        result += input[i] + ('a' - 'A');
12864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      } else {
12964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        // Capital letters after the first are left as-is.
13064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        result += input[i];
13164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      }
13264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      cap_next_letter = false;
13364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    } else if ('0' <= input[i] && input[i] <= '9') {
13464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      result += input[i];
13564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      cap_next_letter = true;
13664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    } else {
13764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      cap_next_letter = true;
13864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
13964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
14064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return result;
14164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
14264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
14364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace
14464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
14564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring UnderscoresToCamelCase(const FieldDescriptor* field) {
14664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return UnderscoresToCamelCaseImpl(FieldName(field), false);
14764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
14864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
14964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
15064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return UnderscoresToCamelCaseImpl(FieldName(field), true);
15164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
15264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
15364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring UnderscoresToCamelCase(const MethodDescriptor* method) {
15464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return UnderscoresToCamelCaseImpl(method->name(), false);
15564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
15664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
157f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chaostring RenameJavaKeywords(const string& input) {
158f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao  return sRenameKeywords.RenameJavaKeywordsImpl(input);
159f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao}
160f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao
16164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring StripProto(const string& filename) {
16264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (HasSuffixString(filename, ".protodevel")) {
16364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return StripSuffixString(filename, ".protodevel");
16464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
16564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return StripSuffixString(filename, ".proto");
16664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
16764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
16864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
16964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring FileClassName(const Params& params, const FileDescriptor* file) {
17064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (params.has_java_outer_classname(file->name())) {
171624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    return params.java_outer_classname(file->name());
17264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
173624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    // Use the filename itself with underscores removed
174624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    // and a CamelCase style name.
175624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    string basename;
176624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    string::size_type last_slash = file->name().find_last_of('/');
177624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    if (last_slash == string::npos) {
178624c448fbef20a1a2fad2289f622b468c25763d1Max Cai      basename = file->name();
17964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    } else {
180624c448fbef20a1a2fad2289f622b468c25763d1Max Cai      basename = file->name().substr(last_slash + 1);
18164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
182624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    return UnderscoresToCamelCaseImpl(StripProto(basename), true);
18364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
18464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
18564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
18664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring FileJavaPackage(const Params& params, const FileDescriptor* file) {
18764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (params.has_java_package(file->name())) {
18864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return params.java_package(file->name());
18964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
19064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    string result = kDefaultPackage;
19164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    if (!file->package().empty()) {
19264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      if (!result.empty()) result += '.';
19364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      result += file->package();
19464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
19564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return result;
19664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
19764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
19864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
199624c448fbef20a1a2fad2289f622b468c25763d1Max Caibool IsOuterClassNeeded(const Params& params, const FileDescriptor* file) {
20026266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  // If java_multiple_files is false, the outer class is always needed.
20126266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  if (!params.java_multiple_files(file->name())) {
202624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    return true;
20364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
20426266cd4660ffe1f3d6015b715713ee654c5b936Max Cai
20526266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  // File-scope extensions need the outer class as the scope.
20626266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  if (file->extension_count() != 0) {
20726266cd4660ffe1f3d6015b715713ee654c5b936Max Cai    return true;
20826266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  }
20926266cd4660ffe1f3d6015b715713ee654c5b936Max Cai
21026266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  // If container interfaces are not generated, file-scope enums need the
21126266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  // outer class as the scope.
21226266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  if (file->enum_type_count() != 0 && !params.java_enum_style()) {
21326266cd4660ffe1f3d6015b715713ee654c5b936Max Cai    return true;
21426266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  }
21526266cd4660ffe1f3d6015b715713ee654c5b936Max Cai
21626266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  return false;
217624c448fbef20a1a2fad2289f622b468c25763d1Max Cai}
218624c448fbef20a1a2fad2289f622b468c25763d1Max Cai
219624c448fbef20a1a2fad2289f622b468c25763d1Max Caistring ToJavaName(const Params& params, const string& name, bool is_class,
220624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    const Descriptor* parent, const FileDescriptor* file) {
221624c448fbef20a1a2fad2289f622b468c25763d1Max Cai  string result;
222624c448fbef20a1a2fad2289f622b468c25763d1Max Cai  if (parent != NULL) {
223624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    result.append(ClassName(params, parent));
224624c448fbef20a1a2fad2289f622b468c25763d1Max Cai  } else if (is_class && params.java_multiple_files(file->name())) {
225624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    result.append(FileJavaPackage(params, file));
22664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
227624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    result.append(ClassName(params, file));
22864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
229624c448fbef20a1a2fad2289f622b468c25763d1Max Cai  if (!result.empty()) result.append(1, '.');
230624c448fbef20a1a2fad2289f622b468c25763d1Max Cai  result.append(RenameJavaKeywords(name));
23164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return result;
23264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
23364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
23464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring ClassName(const Params& params, const FileDescriptor* descriptor) {
23564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  string result = FileJavaPackage(params, descriptor);
23664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (!result.empty()) result += '.';
23764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  result += FileClassName(params, descriptor);
23864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return result;
23964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
24064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
24164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring ClassName(const Params& params, const EnumDescriptor* descriptor) {
242624c448fbef20a1a2fad2289f622b468c25763d1Max Cai  const Descriptor* parent = descriptor->containing_type();
24326266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  // When using Java enum style, an enum's class name contains the enum name.
24426266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  // Use the standard ToJavaName translation.
24526266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  if (params.java_enum_style()) {
24626266cd4660ffe1f3d6015b715713ee654c5b936Max Cai    return ToJavaName(params, descriptor->name(), true, parent,
24726266cd4660ffe1f3d6015b715713ee654c5b936Max Cai                      descriptor->file());
24826266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  }
24926266cd4660ffe1f3d6015b715713ee654c5b936Max Cai  // Otherwise the enum members are accessed from the enclosing class.
250624c448fbef20a1a2fad2289f622b468c25763d1Max Cai  if (parent != NULL) {
251624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    return ClassName(params, parent);
252624c448fbef20a1a2fad2289f622b468c25763d1Max Cai  } else {
253624c448fbef20a1a2fad2289f622b468c25763d1Max Cai    return ClassName(params, descriptor->file());
25464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
25564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
25664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
25764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring FieldConstantName(const FieldDescriptor *field) {
25864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  string name = field->name() + "_FIELD_NUMBER";
25964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  UpperString(&name);
26064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return name;
26164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
26264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
26364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring FieldDefaultConstantName(const FieldDescriptor *field) {
2645cc242074f189837b38e7768b57ccfb0bca258dfMax Cai  return "_" + RenameJavaKeywords(UnderscoresToCamelCase(field)) + "Default";
26564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
26664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
267382ddccb550e1c822ef26a0e65988998f7446624Max Caivoid PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
268382ddccb550e1c822ef26a0e65988998f7446624Max Cai  // We don't want to print group bodies so we cut off after the first line
269382ddccb550e1c822ef26a0e65988998f7446624Max Cai  // (the second line for extensions).
270382ddccb550e1c822ef26a0e65988998f7446624Max Cai  string def = field->DebugString();
271382ddccb550e1c822ef26a0e65988998f7446624Max Cai  string::size_type first_line_end = def.find_first_of('\n');
272382ddccb550e1c822ef26a0e65988998f7446624Max Cai  printer->Print("// $def$\n",
273382ddccb550e1c822ef26a0e65988998f7446624Max Cai    "def", def.substr(0, first_line_end));
274382ddccb550e1c822ef26a0e65988998f7446624Max Cai  if (field->is_extension()) {
275382ddccb550e1c822ef26a0e65988998f7446624Max Cai    string::size_type second_line_start = first_line_end + 1;
276382ddccb550e1c822ef26a0e65988998f7446624Max Cai    string::size_type second_line_length =
277382ddccb550e1c822ef26a0e65988998f7446624Max Cai        def.find('\n', second_line_start) - second_line_start;
278382ddccb550e1c822ef26a0e65988998f7446624Max Cai    printer->Print("// $def$\n",
279382ddccb550e1c822ef26a0e65988998f7446624Max Cai      "def", def.substr(second_line_start, second_line_length));
280382ddccb550e1c822ef26a0e65988998f7446624Max Cai  }
281382ddccb550e1c822ef26a0e65988998f7446624Max Cai}
282382ddccb550e1c822ef26a0e65988998f7446624Max Cai
28364d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciJavaType GetJavaType(FieldDescriptor::Type field_type) {
28464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (field_type) {
28564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_INT32:
28664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_UINT32:
28764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SINT32:
28864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_FIXED32:
28964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SFIXED32:
29064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_INT;
29164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
29264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_INT64:
29364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_UINT64:
29464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SINT64:
29564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_FIXED64:
29664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SFIXED64:
29764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_LONG;
29864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
29964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_FLOAT:
30064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_FLOAT;
30164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
30264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_DOUBLE:
30364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_DOUBLE;
30464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
30564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_BOOL:
30664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_BOOLEAN;
30764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
30864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_STRING:
30964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_STRING;
31064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
31164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_BYTES:
31264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_BYTES;
31364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
31464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_ENUM:
31564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_ENUM;
31664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
31764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_GROUP:
31864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_MESSAGE:
31964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_MESSAGE;
32064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
32164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
32264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // types are added.
32364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
32464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
32564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
32664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return JAVATYPE_INT;
32764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
32864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
329382ddccb550e1c822ef26a0e65988998f7446624Max Caistring PrimitiveTypeName(JavaType type) {
330382ddccb550e1c822ef26a0e65988998f7446624Max Cai  switch (type) {
331382ddccb550e1c822ef26a0e65988998f7446624Max Cai    case JAVATYPE_INT    : return "int";
332382ddccb550e1c822ef26a0e65988998f7446624Max Cai    case JAVATYPE_LONG   : return "long";
333382ddccb550e1c822ef26a0e65988998f7446624Max Cai    case JAVATYPE_FLOAT  : return "float";
334382ddccb550e1c822ef26a0e65988998f7446624Max Cai    case JAVATYPE_DOUBLE : return "double";
335382ddccb550e1c822ef26a0e65988998f7446624Max Cai    case JAVATYPE_BOOLEAN: return "boolean";
336382ddccb550e1c822ef26a0e65988998f7446624Max Cai    case JAVATYPE_STRING : return "java.lang.String";
337382ddccb550e1c822ef26a0e65988998f7446624Max Cai    case JAVATYPE_BYTES  : return "byte[]";
338382ddccb550e1c822ef26a0e65988998f7446624Max Cai    case JAVATYPE_ENUM   : return "int";
339382ddccb550e1c822ef26a0e65988998f7446624Max Cai    case JAVATYPE_MESSAGE: return NULL;
340382ddccb550e1c822ef26a0e65988998f7446624Max Cai
341382ddccb550e1c822ef26a0e65988998f7446624Max Cai    // No default because we want the compiler to complain if any new
342382ddccb550e1c822ef26a0e65988998f7446624Max Cai    // JavaTypes are added.
343382ddccb550e1c822ef26a0e65988998f7446624Max Cai  }
344382ddccb550e1c822ef26a0e65988998f7446624Max Cai
345382ddccb550e1c822ef26a0e65988998f7446624Max Cai  GOOGLE_LOG(FATAL) << "Can't get here.";
346382ddccb550e1c822ef26a0e65988998f7446624Max Cai  return NULL;
347382ddccb550e1c822ef26a0e65988998f7446624Max Cai}
348382ddccb550e1c822ef26a0e65988998f7446624Max Cai
349382ddccb550e1c822ef26a0e65988998f7446624Max Caistring BoxedPrimitiveTypeName(JavaType type) {
35064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (type) {
35164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_INT    : return "java.lang.Integer";
35264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_LONG   : return "java.lang.Long";
35364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_FLOAT  : return "java.lang.Float";
35464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_DOUBLE : return "java.lang.Double";
35564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BOOLEAN: return "java.lang.Boolean";
35664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_STRING : return "java.lang.String";
35764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BYTES  : return "byte[]";
35864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_ENUM   : return "java.lang.Integer";
35964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_MESSAGE: return NULL;
36064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
36164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
36264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // JavaTypes are added.
36364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
36464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
36564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
36664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return NULL;
36764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
36864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
36964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring EmptyArrayName(const Params& params, const FieldDescriptor* field) {
37064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (GetJavaType(field)) {
37164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_INT    : return "com.google.protobuf.nano.WireFormatNano.EMPTY_INT_ARRAY";
37264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_LONG   : return "com.google.protobuf.nano.WireFormatNano.EMPTY_LONG_ARRAY";
37364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_FLOAT  : return "com.google.protobuf.nano.WireFormatNano.EMPTY_FLOAT_ARRAY";
37464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_DOUBLE : return "com.google.protobuf.nano.WireFormatNano.EMPTY_DOUBLE_ARRAY";
37564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BOOLEAN: return "com.google.protobuf.nano.WireFormatNano.EMPTY_BOOLEAN_ARRAY";
37664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_STRING : return "com.google.protobuf.nano.WireFormatNano.EMPTY_STRING_ARRAY";
37764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BYTES  : return "com.google.protobuf.nano.WireFormatNano.EMPTY_BYTES_ARRAY";
37864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_ENUM   : return "com.google.protobuf.nano.WireFormatNano.EMPTY_INT_ARRAY";
37964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_MESSAGE: return ClassName(params, field->message_type()) + ".EMPTY_ARRAY";
38064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
38164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
38264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // JavaTypes are added.
38364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
38464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
38564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
38664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return "";
38764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
38864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
38964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring DefaultValue(const Params& params, const FieldDescriptor* field) {
39064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (field->label() == FieldDescriptor::LABEL_REPEATED) {
39164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return EmptyArrayName(params, field);
39264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
39364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
3940b8579237336f221711a0aac42400eb31a58fed3Brian Duff  if (params.use_reference_types_for_primitives()) {
3950b8579237336f221711a0aac42400eb31a58fed3Brian Duff    return "null";
3960b8579237336f221711a0aac42400eb31a58fed3Brian Duff  }
3970b8579237336f221711a0aac42400eb31a58fed3Brian Duff
39864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // Switch on cpp_type since we need to know which default_value_* method
39964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // of FieldDescriptor to call.
40064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (field->cpp_type()) {
40164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_INT32:
40264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return SimpleItoa(field->default_value_int32());
40364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_UINT32:
40464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      // Need to print as a signed int since Java has no unsigned.
40564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
40664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_INT64:
40764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return SimpleItoa(field->default_value_int64()) + "L";
40864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_UINT64:
40964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
41064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci             "L";
4110f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::CPPTYPE_DOUBLE: {
4120f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      double value = field->default_value_double();
4130f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      if (value == numeric_limits<double>::infinity()) {
4140f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith        return "Double.POSITIVE_INFINITY";
4150f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      } else if (value == -numeric_limits<double>::infinity()) {
4160f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith        return "Double.NEGATIVE_INFINITY";
4170f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      } else if (value != value) {
4180f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith        return "Double.NaN";
4190f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      } else {
4200f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith        return SimpleDtoa(value) + "D";
4210f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      }
4220f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    }
4230f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::CPPTYPE_FLOAT: {
4240f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      float value = field->default_value_float();
4250f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      if (value == numeric_limits<float>::infinity()) {
4260f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith        return "Float.POSITIVE_INFINITY";
4270f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      } else if (value == -numeric_limits<float>::infinity()) {
4280f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith        return "Float.NEGATIVE_INFINITY";
4290f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      } else if (value != value) {
4300f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith        return "Float.NaN";
4310f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      } else {
4320f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith        return SimpleFtoa(value) + "F";
4330f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      }
4340f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    }
43564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_BOOL:
43664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return field->default_value_bool() ? "true" : "false";
43764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_STRING:
43864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      if (!field->default_value_string().empty()) {
43964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        // Point it to the static final in the generated code.
44064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        return FieldDefaultConstantName(field);
44164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      } else {
44264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        if (field->type() == FieldDescriptor::TYPE_BYTES) {
44364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci          return "com.google.protobuf.nano.WireFormatNano.EMPTY_BYTES";
44464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        } else {
44564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci          return "\"\"";
44664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        }
44764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      }
44864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
44964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_ENUM:
45064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return ClassName(params, field->enum_type()) + "." +
451d888895a3b5cf764856d3a94ed526bf9994c1800Max Cai             RenameJavaKeywords(field->default_value_enum()->name());
45264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
45364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_MESSAGE:
45464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return "null";
45564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
45664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
45764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // types are added.
45864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
45964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
46064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
46164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return "";
46264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
46364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
46447dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai
46547dee56155c7bdb9855e51ff08c99db306d11a2dMax Caistatic const char* kBitMasks[] = {
46647dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00000001",
46747dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00000002",
46847dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00000004",
46947dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00000008",
47047dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00000010",
47147dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00000020",
47247dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00000040",
47347dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00000080",
47447dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai
47547dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00000100",
47647dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00000200",
47747dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00000400",
47847dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00000800",
47947dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00001000",
48047dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00002000",
48147dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00004000",
48247dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00008000",
48347dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai
48447dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00010000",
48547dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00020000",
48647dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00040000",
48747dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00080000",
48847dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00100000",
48947dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00200000",
49047dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00400000",
49147dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x00800000",
49247dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai
49347dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x01000000",
49447dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x02000000",
49547dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x04000000",
49647dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x08000000",
49747dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x10000000",
49847dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x20000000",
49947dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x40000000",
50047dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  "0x80000000",
50147dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai};
50247dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai
50347dee56155c7bdb9855e51ff08c99db306d11a2dMax Caistring GetBitFieldName(int index) {
50447dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  string var_name = "bitField";
50547dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  var_name += SimpleItoa(index);
50647dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  var_name += "_";
50747dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  return var_name;
50847dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai}
50947dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai
51047dee56155c7bdb9855e51ff08c99db306d11a2dMax Caistring GetBitFieldNameForBit(int bit_index) {
51147dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  return GetBitFieldName(bit_index / 32);
51247dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai}
51347dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai
51447dee56155c7bdb9855e51ff08c99db306d11a2dMax Caistring GenerateGetBit(int bit_index) {
51547dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  string var_name = GetBitFieldNameForBit(bit_index);
51647dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  int bit_in_var_index = bit_index % 32;
51747dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai
51847dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  string mask = kBitMasks[bit_in_var_index];
519ccc48faf20dbf3b3cddcffe78d198876d543529bBrian Duff  string result = "((" + var_name + " & " + mask + ") != 0)";
52047dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  return result;
52147dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai}
52247dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai
52347dee56155c7bdb9855e51ff08c99db306d11a2dMax Caistring GenerateSetBit(int bit_index) {
52447dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  string var_name = GetBitFieldNameForBit(bit_index);
52547dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  int bit_in_var_index = bit_index % 32;
52647dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai
52747dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  string mask = kBitMasks[bit_in_var_index];
52847dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  string result = var_name + " |= " + mask;
52947dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  return result;
53047dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai}
53147dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai
53247dee56155c7bdb9855e51ff08c99db306d11a2dMax Caistring GenerateClearBit(int bit_index) {
53347dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  string var_name = GetBitFieldNameForBit(bit_index);
53447dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  int bit_in_var_index = bit_index % 32;
53547dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai
53647dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  string mask = kBitMasks[bit_in_var_index];
53747dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  string result = var_name + " = (" + var_name + " & ~" + mask + ")";
53847dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai  return result;
53947dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai}
54047dee56155c7bdb9855e51ff08c99db306d11a2dMax Cai
541ccc48faf20dbf3b3cddcffe78d198876d543529bBrian Duffstring GenerateDifferentBit(int bit_index) {
542ccc48faf20dbf3b3cddcffe78d198876d543529bBrian Duff  string var_name = GetBitFieldNameForBit(bit_index);
543ccc48faf20dbf3b3cddcffe78d198876d543529bBrian Duff  int bit_in_var_index = bit_index % 32;
544ccc48faf20dbf3b3cddcffe78d198876d543529bBrian Duff
545ccc48faf20dbf3b3cddcffe78d198876d543529bBrian Duff  string mask = kBitMasks[bit_in_var_index];
546ccc48faf20dbf3b3cddcffe78d198876d543529bBrian Duff  string result = "((" + var_name + " & " + mask
547ccc48faf20dbf3b3cddcffe78d198876d543529bBrian Duff      + ") != (other." + var_name + " & " + mask + "))";
548ccc48faf20dbf3b3cddcffe78d198876d543529bBrian Duff  return result;
549ccc48faf20dbf3b3cddcffe78d198876d543529bBrian Duff}
550ccc48faf20dbf3b3cddcffe78d198876d543529bBrian Duff
551e74fe623e115237968a3de1143d7cdb4df710858Max Caivoid SetBitOperationVariables(const string name,
552e74fe623e115237968a3de1143d7cdb4df710858Max Cai    int bitIndex, map<string, string>* variables) {
553e74fe623e115237968a3de1143d7cdb4df710858Max Cai  (*variables)["get_" + name] = GenerateGetBit(bitIndex);
554e74fe623e115237968a3de1143d7cdb4df710858Max Cai  (*variables)["set_" + name] = GenerateSetBit(bitIndex);
555e74fe623e115237968a3de1143d7cdb4df710858Max Cai  (*variables)["clear_" + name] = GenerateClearBit(bitIndex);
556ccc48faf20dbf3b3cddcffe78d198876d543529bBrian Duff  (*variables)["different_" + name] = GenerateDifferentBit(bitIndex);
557e74fe623e115237968a3de1143d7cdb4df710858Max Cai}
558e74fe623e115237968a3de1143d7cdb4df710858Max Cai
55964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace javanano
56064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace compiler
56164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace protobuf
56264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace google
563