javanano_helpers.cc revision 64d8d8f89050c5ada85341f967af391f4716a7cb
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
3564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <vector>
3664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
3764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_helpers.h>
3864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_params.h>
3964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/descriptor.pb.h>
4064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/stubs/strutil.h>
4164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/stubs/substitute.h>
4264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
4364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace google {
4464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace protobuf {
4564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace compiler {
4664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace javanano {
4764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
4864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciconst char kThickSeparator[] =
4964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  "// ===================================================================\n";
5064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciconst char kThinSeparator[] =
5164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  "// -------------------------------------------------------------------\n";
5264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
5364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace {
5464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
5564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciconst char* kDefaultPackage = "";
5664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
5764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciconst string& FieldName(const FieldDescriptor* field) {
5864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // Groups are hacky:  The name of the field is just the lower-cased name
5964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // of the group type.  In Java, though, we would like to retain the original
6064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // capitalization of the type name.
6164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (field->type() == FieldDescriptor::TYPE_GROUP) {
6264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return field->message_type()->name();
6364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
6464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return field->name();
6564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
6664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
6764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
6864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) {
6964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  string result;
7064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // Note:  I distrust ctype.h due to locales.
7164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  for (int i = 0; i < input.size(); i++) {
7264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    if ('a' <= input[i] && input[i] <= 'z') {
7364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      if (cap_next_letter) {
7464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        result += input[i] + ('A' - 'a');
7564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      } else {
7664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        result += input[i];
7764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      }
7864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      cap_next_letter = false;
7964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    } else if ('A' <= input[i] && input[i] <= 'Z') {
8064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      if (i == 0 && !cap_next_letter) {
8164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        // Force first letter to lower-case unless explicitly told to
8264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        // capitalize it.
8364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        result += input[i] + ('a' - 'A');
8464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      } else {
8564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        // Capital letters after the first are left as-is.
8664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        result += input[i];
8764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      }
8864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      cap_next_letter = false;
8964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    } else if ('0' <= input[i] && input[i] <= '9') {
9064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      result += input[i];
9164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      cap_next_letter = true;
9264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    } else {
9364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      cap_next_letter = true;
9464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
9564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
9664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return result;
9764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
9864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
9964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace
10064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
10164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring UnderscoresToCamelCase(const FieldDescriptor* field) {
10264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return UnderscoresToCamelCaseImpl(FieldName(field), false);
10364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
10464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
10564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
10664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return UnderscoresToCamelCaseImpl(FieldName(field), true);
10764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
10864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
10964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring UnderscoresToCamelCase(const MethodDescriptor* method) {
11064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return UnderscoresToCamelCaseImpl(method->name(), false);
11164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
11264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
11364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring StripProto(const string& filename) {
11464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (HasSuffixString(filename, ".protodevel")) {
11564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return StripSuffixString(filename, ".protodevel");
11664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
11764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return StripSuffixString(filename, ".proto");
11864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
11964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
12064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
12164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring FileClassName(const Params& params, const FileDescriptor* file) {
12264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  string name;
12364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
12464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (params.has_java_outer_classname(file->name())) {
12564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      name = params.java_outer_classname(file->name());
12664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
12764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    if ((file->message_type_count() == 1)
12864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        || (file->enum_type_count() == 0)) {
12964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      // If no outer calls and only one message then
13064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      // use the message name as the file name
13164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      name = file->message_type(0)->name();
13264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    } else {
13364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      // Use the filename it self with underscores removed
13464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      // and a CamelCase style name.
13564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      string basename;
13664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      string::size_type last_slash = file->name().find_last_of('/');
13764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      if (last_slash == string::npos) {
13864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        basename = file->name();
13964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      } else {
14064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        basename = file->name().substr(last_slash + 1);
14164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      }
14264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      name = UnderscoresToCamelCaseImpl(StripProto(basename), true);
14364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
14464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
14564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
14664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return name;
14764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
14864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
14964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring FileJavaPackage(const Params& params, const FileDescriptor* file) {
15064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (params.has_java_package(file->name())) {
15164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return params.java_package(file->name());
15264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
15364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    string result = kDefaultPackage;
15464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    if (!file->package().empty()) {
15564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      if (!result.empty()) result += '.';
15664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      result += file->package();
15764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
15864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return result;
15964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
16064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
16164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
16264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring ToJavaName(const Params& params, const string& full_name,
16364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    const FileDescriptor* file) {
16464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  string result;
16564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (params.java_multiple_files()) {
16664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    result = FileJavaPackage(params, file);
16764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
16864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    result = ClassName(params, file);
16964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
17064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (file->package().empty()) {
17164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    result += '.';
17264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    result += full_name;
17364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
17464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // Strip the proto package from full_name since we've replaced it with
17564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // the Java package. If there isn't an outer classname then strip it too.
17664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    int sizeToSkipPackageName = file->package().size();
17764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    int sizeToSkipOutClassName;
17864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    if (params.has_java_outer_classname(file->name())) {
17964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      sizeToSkipOutClassName = 0;
18064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    } else {
18164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      sizeToSkipOutClassName =
18264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci                full_name.find_first_of('.', sizeToSkipPackageName + 1);
18364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
18464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    int sizeToSkip = sizeToSkipOutClassName > 0 ?
18564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci            sizeToSkipOutClassName : sizeToSkipPackageName;
18664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    string class_name = full_name.substr(sizeToSkip + 1);
18764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    if (class_name == FileClassName(params, file)) {
18864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      // Done class_name is already present.
18964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    } else {
19064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      result += '.';
19164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      result += class_name;
19264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
19364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
19464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return result;
19564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
19664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
19764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring ClassName(const Params& params, const FileDescriptor* descriptor) {
19864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  string result = FileJavaPackage(params, descriptor);
19964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (!result.empty()) result += '.';
20064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  result += FileClassName(params, descriptor);
20164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return result;
20264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
20364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
20464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring ClassName(const Params& params, const EnumDescriptor* descriptor) {
20564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  string result;
20664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  const FileDescriptor* file = descriptor->file();
20764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  const string file_name = file->name();
20864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  const string full_name = descriptor->full_name();
20964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
21064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // Remove enum class name as we use int's for enums
21164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  string base_name = full_name.substr(0, full_name.find_last_of('.'));
21264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
21364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (!file->package().empty()) {
21464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    if (file->package() == base_name.substr(0, file->package().size())) {
21564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      // Remove package name leaving just the parent class of the enum
21664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      int offset = file->package().size();
21764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      if (base_name.size() > offset) {
21864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        // Remove period between package and class name if there is a classname
21964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        offset += 1;
22064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      }
22164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      base_name = base_name.substr(offset);
22264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    } else {
22364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      GOOGLE_LOG(FATAL) << "Expected package name to start an enum";
22464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
22564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
22664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
22764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // Construct the path name from the package and outer class
22864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
22964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // Add the java package name if it exsits
23064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (params.has_java_package(file_name)) {
23164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    result += params.java_package(file_name);
23264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
23364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
23464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // Add the outer classname if it exists
23564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (params.has_java_outer_classname(file_name)) {
23664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    if (!result.empty()) {
23764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      result += ".";
23864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
23964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    result += params.java_outer_classname(file_name);
24064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
24164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
24264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // Create the full class name from the base and path
24364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (!base_name.empty()) {
24464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    if (!result.empty()) {
24564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      result += ".";
24664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
24764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    result += base_name;
24864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
24964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return result;
25064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
25164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
25264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring FieldConstantName(const FieldDescriptor *field) {
25364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  string name = field->name() + "_FIELD_NUMBER";
25464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  UpperString(&name);
25564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return name;
25664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
25764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
25864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring FieldDefaultConstantName(const FieldDescriptor *field) {
25964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  string name = field->name() + "_DEFAULT";
26064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  UpperString(&name);
26164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return name;
26264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
26364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
26464d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciJavaType GetJavaType(FieldDescriptor::Type field_type) {
26564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (field_type) {
26664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_INT32:
26764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_UINT32:
26864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SINT32:
26964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_FIXED32:
27064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SFIXED32:
27164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_INT;
27264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
27364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_INT64:
27464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_UINT64:
27564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SINT64:
27664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_FIXED64:
27764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SFIXED64:
27864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_LONG;
27964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
28064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_FLOAT:
28164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_FLOAT;
28264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
28364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_DOUBLE:
28464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_DOUBLE;
28564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
28664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_BOOL:
28764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_BOOLEAN;
28864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
28964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_STRING:
29064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_STRING;
29164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
29264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_BYTES:
29364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_BYTES;
29464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
29564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_ENUM:
29664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_ENUM;
29764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
29864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_GROUP:
29964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_MESSAGE:
30064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return JAVATYPE_MESSAGE;
30164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
30264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
30364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // types are added.
30464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
30564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
30664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
30764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return JAVATYPE_INT;
30864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
30964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
31064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciconst char* BoxedPrimitiveTypeName(JavaType type) {
31164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (type) {
31264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_INT    : return "java.lang.Integer";
31364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_LONG   : return "java.lang.Long";
31464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_FLOAT  : return "java.lang.Float";
31564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_DOUBLE : return "java.lang.Double";
31664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BOOLEAN: return "java.lang.Boolean";
31764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_STRING : return "java.lang.String";
31864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BYTES  : return "byte[]";
31964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_ENUM   : return "java.lang.Integer";
32064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_MESSAGE: return NULL;
32164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
32264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
32364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // JavaTypes are added.
32464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
32564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
32664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
32764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return NULL;
32864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
32964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
33064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring EmptyArrayName(const Params& params, const FieldDescriptor* field) {
33164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (GetJavaType(field)) {
33264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_INT    : return "com.google.protobuf.nano.WireFormatNano.EMPTY_INT_ARRAY";
33364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_LONG   : return "com.google.protobuf.nano.WireFormatNano.EMPTY_LONG_ARRAY";
33464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_FLOAT  : return "com.google.protobuf.nano.WireFormatNano.EMPTY_FLOAT_ARRAY";
33564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_DOUBLE : return "com.google.protobuf.nano.WireFormatNano.EMPTY_DOUBLE_ARRAY";
33664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BOOLEAN: return "com.google.protobuf.nano.WireFormatNano.EMPTY_BOOLEAN_ARRAY";
33764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_STRING : return "com.google.protobuf.nano.WireFormatNano.EMPTY_STRING_ARRAY";
33864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BYTES  : return "com.google.protobuf.nano.WireFormatNano.EMPTY_BYTES_ARRAY";
33964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_ENUM   : return "com.google.protobuf.nano.WireFormatNano.EMPTY_INT_ARRAY";
34064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_MESSAGE: return ClassName(params, field->message_type()) + ".EMPTY_ARRAY";
34164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
34264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
34364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // JavaTypes are added.
34464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
34564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
34664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
34764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return "";
34864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
34964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
35064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring DefaultValue(const Params& params, const FieldDescriptor* field) {
35164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (field->label() == FieldDescriptor::LABEL_REPEATED) {
35264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    return EmptyArrayName(params, field);
35364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
35464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
35564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // Switch on cpp_type since we need to know which default_value_* method
35664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // of FieldDescriptor to call.
35764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (field->cpp_type()) {
35864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_INT32:
35964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return SimpleItoa(field->default_value_int32());
36064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_UINT32:
36164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      // Need to print as a signed int since Java has no unsigned.
36264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
36364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_INT64:
36464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return SimpleItoa(field->default_value_int64()) + "L";
36564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_UINT64:
36664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
36764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci             "L";
36864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_DOUBLE:
36964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return SimpleDtoa(field->default_value_double()) + "D";
37064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_FLOAT:
37164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return SimpleFtoa(field->default_value_float()) + "F";
37264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_BOOL:
37364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return field->default_value_bool() ? "true" : "false";
37464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_STRING:
37564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      if (!field->default_value_string().empty()) {
37664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        // Point it to the static final in the generated code.
37764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        return FieldDefaultConstantName(field);
37864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      } else {
37964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        if (field->type() == FieldDescriptor::TYPE_BYTES) {
38064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci          return "com.google.protobuf.nano.WireFormatNano.EMPTY_BYTES";
38164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        } else {
38264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci          return "\"\"";
38364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        }
38464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      }
38564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
38664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_ENUM:
38764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return ClassName(params, field->enum_type()) + "." +
38864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci             field->default_value_enum()->name();
38964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
39064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::CPPTYPE_MESSAGE:
39164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return "null";
39264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
39364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
39464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // types are added.
39564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
39664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
39764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
39864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return "";
39964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
40064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
40164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace javanano
40264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace compiler
40364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace protobuf
40464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace google
405