This source file includes following definitions.
- FieldName
- UnderscoresToCamelCaseImpl
- UnderscoresToCamelCase
- UnderscoresToCapitalizedCamelCase
- UnderscoresToCamelCase
- StripProto
- FileClassName
- FileJavaPackage
- JavaPackageToDir
- ToJavaName
- ClassName
- ClassName
- ClassName
- ClassName
- FieldConstantName
- GetType
- GetJavaType
- BoxedPrimitiveTypeName
- AllAscii
- DefaultValue
- IsDefaultValueJavaDefault
- GetBitFieldName
- GetBitFieldNameForBit
- GenerateGetBitInternal
- GenerateSetBitInternal
- GenerateGetBit
- GenerateSetBit
- GenerateClearBit
- GenerateGetBitFromLocal
- GenerateSetBitToLocal
- GenerateGetBitMutableLocal
- GenerateSetBitMutableLocal
#include <limits>
#include <vector>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace java {
const char kThickSeparator[] =
"// ===================================================================\n";
const char kThinSeparator[] =
"// -------------------------------------------------------------------\n";
namespace {
const char* kDefaultPackage = "";
const string& FieldName(const FieldDescriptor* field) {
if (GetType(field) == FieldDescriptor::TYPE_GROUP) {
return field->message_type()->name();
} else {
return field->name();
}
}
string UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) {
string result;
for (int i = 0; i < input.size(); i++) {
if ('a' <= input[i] && input[i] <= 'z') {
if (cap_next_letter) {
result += input[i] + ('A' - 'a');
} else {
result += input[i];
}
cap_next_letter = false;
} else if ('A' <= input[i] && input[i] <= 'Z') {
if (i == 0 && !cap_next_letter) {
result += input[i] + ('a' - 'A');
} else {
result += input[i];
}
cap_next_letter = false;
} else if ('0' <= input[i] && input[i] <= '9') {
result += input[i];
cap_next_letter = true;
} else {
cap_next_letter = true;
}
}
return result;
}
}
string UnderscoresToCamelCase(const FieldDescriptor* field) {
return UnderscoresToCamelCaseImpl(FieldName(field), false);
}
string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
return UnderscoresToCamelCaseImpl(FieldName(field), true);
}
string UnderscoresToCamelCase(const MethodDescriptor* method) {
return UnderscoresToCamelCaseImpl(method->name(), false);
}
string StripProto(const string& filename) {
if (HasSuffixString(filename, ".protodevel")) {
return StripSuffixString(filename, ".protodevel");
} else {
return StripSuffixString(filename, ".proto");
}
}
string FileClassName(const FileDescriptor* file) {
if (file->options().has_java_outer_classname()) {
return file->options().java_outer_classname();
} else {
string basename;
string::size_type last_slash = file->name().find_last_of('/');
if (last_slash == string::npos) {
basename = file->name();
} else {
basename = file->name().substr(last_slash + 1);
}
return UnderscoresToCamelCaseImpl(StripProto(basename), true);
}
}
string FileJavaPackage(const FileDescriptor* file) {
string result;
if (file->options().has_java_package()) {
result = file->options().java_package();
} else {
result = kDefaultPackage;
if (!file->package().empty()) {
if (!result.empty()) result += '.';
result += file->package();
}
}
return result;
}
string JavaPackageToDir(string package_name) {
string package_dir =
StringReplace(package_name, ".", "/", true);
if (!package_dir.empty()) package_dir += "/";
return package_dir;
}
string ToJavaName(const string& full_name, const FileDescriptor* file) {
string result;
if (file->options().java_multiple_files()) {
result = FileJavaPackage(file);
} else {
result = ClassName(file);
}
if (!result.empty()) {
result += '.';
}
if (file->package().empty()) {
result += full_name;
} else {
result += full_name.substr(file->package().size() + 1);
}
return result;
}
string ClassName(const Descriptor* descriptor) {
return ToJavaName(descriptor->full_name(), descriptor->file());
}
string ClassName(const EnumDescriptor* descriptor) {
return ToJavaName(descriptor->full_name(), descriptor->file());
}
string ClassName(const ServiceDescriptor* descriptor) {
return ToJavaName(descriptor->full_name(), descriptor->file());
}
string ClassName(const FileDescriptor* descriptor) {
string result = FileJavaPackage(descriptor);
if (!result.empty()) result += '.';
result += FileClassName(descriptor);
return result;
}
string FieldConstantName(const FieldDescriptor *field) {
string name = field->name() + "_FIELD_NUMBER";
UpperString(&name);
return name;
}
FieldDescriptor::Type GetType(const FieldDescriptor* field) {
return field->type();
}
JavaType GetJavaType(const FieldDescriptor* field) {
switch (GetType(field)) {
case FieldDescriptor::TYPE_INT32:
case FieldDescriptor::TYPE_UINT32:
case FieldDescriptor::TYPE_SINT32:
case FieldDescriptor::TYPE_FIXED32:
case FieldDescriptor::TYPE_SFIXED32:
return JAVATYPE_INT;
case FieldDescriptor::TYPE_INT64:
case FieldDescriptor::TYPE_UINT64:
case FieldDescriptor::TYPE_SINT64:
case FieldDescriptor::TYPE_FIXED64:
case FieldDescriptor::TYPE_SFIXED64:
return JAVATYPE_LONG;
case FieldDescriptor::TYPE_FLOAT:
return JAVATYPE_FLOAT;
case FieldDescriptor::TYPE_DOUBLE:
return JAVATYPE_DOUBLE;
case FieldDescriptor::TYPE_BOOL:
return JAVATYPE_BOOLEAN;
case FieldDescriptor::TYPE_STRING:
return JAVATYPE_STRING;
case FieldDescriptor::TYPE_BYTES:
return JAVATYPE_BYTES;
case FieldDescriptor::TYPE_ENUM:
return JAVATYPE_ENUM;
case FieldDescriptor::TYPE_GROUP:
case FieldDescriptor::TYPE_MESSAGE:
return JAVATYPE_MESSAGE;
}
GOOGLE_LOG(FATAL) << "Can't get here.";
return JAVATYPE_INT;
}
const char* BoxedPrimitiveTypeName(JavaType type) {
switch (type) {
case JAVATYPE_INT : return "java.lang.Integer";
case JAVATYPE_LONG : return "java.lang.Long";
case JAVATYPE_FLOAT : return "java.lang.Float";
case JAVATYPE_DOUBLE : return "java.lang.Double";
case JAVATYPE_BOOLEAN: return "java.lang.Boolean";
case JAVATYPE_STRING : return "java.lang.String";
case JAVATYPE_BYTES : return "com.google.protobuf.ByteString";
case JAVATYPE_ENUM : return NULL;
case JAVATYPE_MESSAGE: return NULL;
}
GOOGLE_LOG(FATAL) << "Can't get here.";
return NULL;
}
bool AllAscii(const string& text) {
for (int i = 0; i < text.size(); i++) {
if ((text[i] & 0x80) != 0) {
return false;
}
}
return true;
}
string DefaultValue(const FieldDescriptor* field) {
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32:
return SimpleItoa(field->default_value_int32());
case FieldDescriptor::CPPTYPE_UINT32:
return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
case FieldDescriptor::CPPTYPE_INT64:
return SimpleItoa(field->default_value_int64()) + "L";
case FieldDescriptor::CPPTYPE_UINT64:
return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
"L";
case FieldDescriptor::CPPTYPE_DOUBLE: {
double value = field->default_value_double();
if (value == numeric_limits<double>::infinity()) {
return "Double.POSITIVE_INFINITY";
} else if (value == -numeric_limits<double>::infinity()) {
return "Double.NEGATIVE_INFINITY";
} else if (value != value) {
return "Double.NaN";
} else {
return SimpleDtoa(value) + "D";
}
}
case FieldDescriptor::CPPTYPE_FLOAT: {
float value = field->default_value_float();
if (value == numeric_limits<float>::infinity()) {
return "Float.POSITIVE_INFINITY";
} else if (value == -numeric_limits<float>::infinity()) {
return "Float.NEGATIVE_INFINITY";
} else if (value != value) {
return "Float.NaN";
} else {
return SimpleFtoa(value) + "F";
}
}
case FieldDescriptor::CPPTYPE_BOOL:
return field->default_value_bool() ? "true" : "false";
case FieldDescriptor::CPPTYPE_STRING:
if (GetType(field) == FieldDescriptor::TYPE_BYTES) {
if (field->has_default_value()) {
return strings::Substitute(
"com.google.protobuf.Internal.bytesDefaultValue(\"$0\")",
CEscape(field->default_value_string()));
} else {
return "com.google.protobuf.ByteString.EMPTY";
}
} else {
if (AllAscii(field->default_value_string())) {
return "\"" + CEscape(field->default_value_string()) + "\"";
} else {
return strings::Substitute(
"com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
CEscape(field->default_value_string()));
}
}
case FieldDescriptor::CPPTYPE_ENUM:
return ClassName(field->enum_type()) + "." +
field->default_value_enum()->name();
case FieldDescriptor::CPPTYPE_MESSAGE:
return ClassName(field->message_type()) + ".getDefaultInstance()";
}
GOOGLE_LOG(FATAL) << "Can't get here.";
return "";
}
bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32:
return field->default_value_int32() == 0;
case FieldDescriptor::CPPTYPE_UINT32:
return field->default_value_uint32() == 0;
case FieldDescriptor::CPPTYPE_INT64:
return field->default_value_int64() == 0L;
case FieldDescriptor::CPPTYPE_UINT64:
return field->default_value_uint64() == 0L;
case FieldDescriptor::CPPTYPE_DOUBLE:
return field->default_value_double() == 0.0;
case FieldDescriptor::CPPTYPE_FLOAT:
return field->default_value_float() == 0.0;
case FieldDescriptor::CPPTYPE_BOOL:
return field->default_value_bool() == false;
case FieldDescriptor::CPPTYPE_STRING:
case FieldDescriptor::CPPTYPE_ENUM:
case FieldDescriptor::CPPTYPE_MESSAGE:
return false;
}
GOOGLE_LOG(FATAL) << "Can't get here.";
return false;
}
const char* bit_masks[] = {
"0x00000001",
"0x00000002",
"0x00000004",
"0x00000008",
"0x00000010",
"0x00000020",
"0x00000040",
"0x00000080",
"0x00000100",
"0x00000200",
"0x00000400",
"0x00000800",
"0x00001000",
"0x00002000",
"0x00004000",
"0x00008000",
"0x00010000",
"0x00020000",
"0x00040000",
"0x00080000",
"0x00100000",
"0x00200000",
"0x00400000",
"0x00800000",
"0x01000000",
"0x02000000",
"0x04000000",
"0x08000000",
"0x10000000",
"0x20000000",
"0x40000000",
"0x80000000",
};
string GetBitFieldName(int index) {
string varName = "bitField";
varName += SimpleItoa(index);
varName += "_";
return varName;
}
string GetBitFieldNameForBit(int bitIndex) {
return GetBitFieldName(bitIndex / 32);
}
namespace {
string GenerateGetBitInternal(const string& prefix, int bitIndex) {
string varName = prefix + GetBitFieldNameForBit(bitIndex);
int bitInVarIndex = bitIndex % 32;
string mask = bit_masks[bitInVarIndex];
string result = "((" + varName + " & " + mask + ") == " + mask + ")";
return result;
}
string GenerateSetBitInternal(const string& prefix, int bitIndex) {
string varName = prefix + GetBitFieldNameForBit(bitIndex);
int bitInVarIndex = bitIndex % 32;
string mask = bit_masks[bitInVarIndex];
string result = varName + " |= " + mask;
return result;
}
}
string GenerateGetBit(int bitIndex) {
return GenerateGetBitInternal("", bitIndex);
}
string GenerateSetBit(int bitIndex) {
return GenerateSetBitInternal("", bitIndex);
}
string GenerateClearBit(int bitIndex) {
string varName = GetBitFieldNameForBit(bitIndex);
int bitInVarIndex = bitIndex % 32;
string mask = bit_masks[bitInVarIndex];
string result = varName + " = (" + varName + " & ~" + mask + ")";
return result;
}
string GenerateGetBitFromLocal(int bitIndex) {
return GenerateGetBitInternal("from_", bitIndex);
}
string GenerateSetBitToLocal(int bitIndex) {
return GenerateSetBitInternal("to_", bitIndex);
}
string GenerateGetBitMutableLocal(int bitIndex) {
return GenerateGetBitInternal("mutable_", bitIndex);
}
string GenerateSetBitMutableLocal(int bitIndex) {
return GenerateSetBitInternal("mutable_", bitIndex);
}
}
}
}
}