Home | History | Annotate | Download | only in java
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // https://developers.google.com/protocol-buffers/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are
      7 // met:
      8 //
      9 //     * Redistributions of source code must retain the above copyright
     10 // notice, this list of conditions and the following disclaimer.
     11 //     * Redistributions in binary form must reproduce the above
     12 // copyright notice, this list of conditions and the following disclaimer
     13 // in the documentation and/or other materials provided with the
     14 // distribution.
     15 //     * Neither the name of Google Inc. nor the names of its
     16 // contributors may be used to endorse or promote products derived from
     17 // this software without specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 // Author: kenton (at) google.com (Kenton Varda)
     32 //  Based on original Protocol Buffers design by
     33 //  Sanjay Ghemawat, Jeff Dean, and others.
     34 
     35 #include <algorithm>
     36 #include <google/protobuf/stubs/hash.h>
     37 #include <limits>
     38 #include <vector>
     39 
     40 #include <google/protobuf/compiler/java/java_helpers.h>
     41 #include <google/protobuf/compiler/java/java_name_resolver.h>
     42 #include <google/protobuf/descriptor.pb.h>
     43 #include <google/protobuf/wire_format.h>
     44 #include <google/protobuf/stubs/strutil.h>
     45 #include <google/protobuf/stubs/substitute.h>
     46 
     47 namespace google {
     48 namespace protobuf {
     49 namespace compiler {
     50 namespace java {
     51 
     52 using internal::WireFormat;
     53 using internal::WireFormatLite;
     54 
     55 const char kThickSeparator[] =
     56   "// ===================================================================\n";
     57 const char kThinSeparator[] =
     58   "// -------------------------------------------------------------------\n";
     59 
     60 namespace {
     61 
     62 const char* kDefaultPackage = "";
     63 
     64 // Names that should be avoided as field names.
     65 // Using them will cause the compiler to generate accessors whose names are
     66 // colliding with methods defined in base classes.
     67 const char* kForbiddenWordList[] = {
     68   // message base class:
     69   "cached_size", "serialized_size",
     70   // java.lang.Object:
     71   "class",
     72 };
     73 
     74 bool IsForbidden(const string& field_name) {
     75   for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) {
     76     if (field_name == kForbiddenWordList[i]) {
     77       return true;
     78     }
     79   }
     80   return false;
     81 }
     82 
     83 string FieldName(const FieldDescriptor* field) {
     84   string field_name;
     85   // Groups are hacky:  The name of the field is just the lower-cased name
     86   // of the group type.  In Java, though, we would like to retain the original
     87   // capitalization of the type name.
     88   if (GetType(field) == FieldDescriptor::TYPE_GROUP) {
     89     field_name = field->message_type()->name();
     90   } else {
     91     field_name = field->name();
     92   }
     93   if (IsForbidden(field_name)) {
     94     // Append a trailing "#" to indicate that the name should be decorated to
     95     // avoid collision with other names.
     96     field_name += "#";
     97   }
     98   return field_name;
     99 }
    100 
    101 
    102 }  // namespace
    103 
    104 string UnderscoresToCamelCase(const string& input, bool cap_next_letter) {
    105   string result;
    106   // Note:  I distrust ctype.h due to locales.
    107   for (int i = 0; i < input.size(); i++) {
    108     if ('a' <= input[i] && input[i] <= 'z') {
    109       if (cap_next_letter) {
    110         result += input[i] + ('A' - 'a');
    111       } else {
    112         result += input[i];
    113       }
    114       cap_next_letter = false;
    115     } else if ('A' <= input[i] && input[i] <= 'Z') {
    116       if (i == 0 && !cap_next_letter) {
    117         // Force first letter to lower-case unless explicitly told to
    118         // capitalize it.
    119         result += input[i] + ('a' - 'A');
    120       } else {
    121         // Capital letters after the first are left as-is.
    122         result += input[i];
    123       }
    124       cap_next_letter = false;
    125     } else if ('0' <= input[i] && input[i] <= '9') {
    126       result += input[i];
    127       cap_next_letter = true;
    128     } else {
    129       cap_next_letter = true;
    130     }
    131   }
    132   // Add a trailing "_" if the name should be altered.
    133   if (input[input.size() - 1] == '#') {
    134     result += '_';
    135   }
    136   return result;
    137 }
    138 
    139 string UnderscoresToCamelCase(const FieldDescriptor* field) {
    140   return UnderscoresToCamelCase(FieldName(field), false);
    141 }
    142 
    143 string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
    144   return UnderscoresToCamelCase(FieldName(field), true);
    145 }
    146 
    147 string UnderscoresToCamelCase(const MethodDescriptor* method) {
    148   return UnderscoresToCamelCase(method->name(), false);
    149 }
    150 
    151 string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
    152   return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
    153 }
    154 
    155 string StripProto(const string& filename) {
    156   if (HasSuffixString(filename, ".protodevel")) {
    157     return StripSuffixString(filename, ".protodevel");
    158   } else {
    159     return StripSuffixString(filename, ".proto");
    160   }
    161 }
    162 
    163 string FileClassName(const FileDescriptor* file, bool immutable) {
    164   ClassNameResolver name_resolver;
    165   return name_resolver.GetFileClassName(file, immutable);
    166 }
    167 
    168 string FileJavaPackage(const FileDescriptor* file, bool immutable) {
    169   string result;
    170 
    171   if (file->options().has_java_package()) {
    172     result = file->options().java_package();
    173   } else {
    174     result = kDefaultPackage;
    175     if (!file->package().empty()) {
    176       if (!result.empty()) result += '.';
    177       result += file->package();
    178     }
    179   }
    180 
    181   return result;
    182 }
    183 
    184 string JavaPackageToDir(string package_name) {
    185   string package_dir =
    186     StringReplace(package_name, ".", "/", true);
    187   if (!package_dir.empty()) package_dir += "/";
    188   return package_dir;
    189 }
    190 
    191 // TODO(xiaofeng): This function is only kept for it's publicly referenced.
    192 // It should be removed after mutable API up-integration.
    193 string ToJavaName(const string& full_name,
    194                   const FileDescriptor* file) {
    195   string result;
    196   if (file->options().java_multiple_files()) {
    197     result = FileJavaPackage(file);
    198   } else {
    199     result = ClassName(file);
    200   }
    201   if (!result.empty()) {
    202     result += '.';
    203   }
    204   if (file->package().empty()) {
    205     result += full_name;
    206   } else {
    207     // Strip the proto package from full_name since we've replaced it with
    208     // the Java package.
    209     result += full_name.substr(file->package().size() + 1);
    210   }
    211   return result;
    212 }
    213 
    214 string ClassName(const Descriptor* descriptor) {
    215   ClassNameResolver name_resolver;
    216   return name_resolver.GetClassName(descriptor, true);
    217 }
    218 
    219 string ClassName(const EnumDescriptor* descriptor) {
    220   ClassNameResolver name_resolver;
    221   return name_resolver.GetClassName(descriptor, true);
    222 }
    223 
    224 string ClassName(const ServiceDescriptor* descriptor) {
    225   ClassNameResolver name_resolver;
    226   return name_resolver.GetClassName(descriptor, true);
    227 }
    228 
    229 string ClassName(const FileDescriptor* descriptor) {
    230   ClassNameResolver name_resolver;
    231   return name_resolver.GetClassName(descriptor, true);
    232 }
    233 
    234 string ExtraMessageInterfaces(const Descriptor* descriptor) {
    235   string interfaces = "// @@protoc_insertion_point(message_implements:"
    236       + descriptor->full_name() + ")";
    237   return interfaces;
    238 }
    239 
    240 
    241 string ExtraBuilderInterfaces(const Descriptor* descriptor) {
    242   string interfaces = "// @@protoc_insertion_point(builder_implements:"
    243       + descriptor->full_name() + ")";
    244   return interfaces;
    245 }
    246 
    247 string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor) {
    248   string interfaces = "// @@protoc_insertion_point(interface_extends:"
    249       + descriptor->full_name() + ")";
    250   return interfaces;
    251 }
    252 
    253 string FieldConstantName(const FieldDescriptor *field) {
    254   string name = field->name() + "_FIELD_NUMBER";
    255   UpperString(&name);
    256   return name;
    257 }
    258 
    259 FieldDescriptor::Type GetType(const FieldDescriptor* field) {
    260   return field->type();
    261 }
    262 
    263 JavaType GetJavaType(const FieldDescriptor* field) {
    264   switch (GetType(field)) {
    265     case FieldDescriptor::TYPE_INT32:
    266     case FieldDescriptor::TYPE_UINT32:
    267     case FieldDescriptor::TYPE_SINT32:
    268     case FieldDescriptor::TYPE_FIXED32:
    269     case FieldDescriptor::TYPE_SFIXED32:
    270       return JAVATYPE_INT;
    271 
    272     case FieldDescriptor::TYPE_INT64:
    273     case FieldDescriptor::TYPE_UINT64:
    274     case FieldDescriptor::TYPE_SINT64:
    275     case FieldDescriptor::TYPE_FIXED64:
    276     case FieldDescriptor::TYPE_SFIXED64:
    277       return JAVATYPE_LONG;
    278 
    279     case FieldDescriptor::TYPE_FLOAT:
    280       return JAVATYPE_FLOAT;
    281 
    282     case FieldDescriptor::TYPE_DOUBLE:
    283       return JAVATYPE_DOUBLE;
    284 
    285     case FieldDescriptor::TYPE_BOOL:
    286       return JAVATYPE_BOOLEAN;
    287 
    288     case FieldDescriptor::TYPE_STRING:
    289       return JAVATYPE_STRING;
    290 
    291     case FieldDescriptor::TYPE_BYTES:
    292       return JAVATYPE_BYTES;
    293 
    294     case FieldDescriptor::TYPE_ENUM:
    295       return JAVATYPE_ENUM;
    296 
    297     case FieldDescriptor::TYPE_GROUP:
    298     case FieldDescriptor::TYPE_MESSAGE:
    299       return JAVATYPE_MESSAGE;
    300 
    301     // No default because we want the compiler to complain if any new
    302     // types are added.
    303   }
    304 
    305   GOOGLE_LOG(FATAL) << "Can't get here.";
    306   return JAVATYPE_INT;
    307 }
    308 
    309 const char* PrimitiveTypeName(JavaType type) {
    310   switch (type) {
    311     case JAVATYPE_INT    : return "int";
    312     case JAVATYPE_LONG   : return "long";
    313     case JAVATYPE_FLOAT  : return "float";
    314     case JAVATYPE_DOUBLE : return "double";
    315     case JAVATYPE_BOOLEAN: return "boolean";
    316     case JAVATYPE_STRING : return "java.lang.String";
    317     case JAVATYPE_BYTES  : return "com.google.protobuf.ByteString";
    318     case JAVATYPE_ENUM   : return NULL;
    319     case JAVATYPE_MESSAGE: return NULL;
    320 
    321     // No default because we want the compiler to complain if any new
    322     // JavaTypes are added.
    323   }
    324 
    325   GOOGLE_LOG(FATAL) << "Can't get here.";
    326   return NULL;
    327 }
    328 
    329 const char* BoxedPrimitiveTypeName(JavaType type) {
    330   switch (type) {
    331     case JAVATYPE_INT    : return "java.lang.Integer";
    332     case JAVATYPE_LONG   : return "java.lang.Long";
    333     case JAVATYPE_FLOAT  : return "java.lang.Float";
    334     case JAVATYPE_DOUBLE : return "java.lang.Double";
    335     case JAVATYPE_BOOLEAN: return "java.lang.Boolean";
    336     case JAVATYPE_STRING : return "java.lang.String";
    337     case JAVATYPE_BYTES  : return "com.google.protobuf.ByteString";
    338     case JAVATYPE_ENUM   : return NULL;
    339     case JAVATYPE_MESSAGE: return NULL;
    340 
    341     // No default because we want the compiler to complain if any new
    342     // JavaTypes are added.
    343   }
    344 
    345   GOOGLE_LOG(FATAL) << "Can't get here.";
    346   return NULL;
    347 }
    348 
    349 const char* FieldTypeName(FieldDescriptor::Type field_type) {
    350   switch (field_type) {
    351     case FieldDescriptor::TYPE_INT32   : return "INT32";
    352     case FieldDescriptor::TYPE_UINT32  : return "UINT32";
    353     case FieldDescriptor::TYPE_SINT32  : return "SINT32";
    354     case FieldDescriptor::TYPE_FIXED32 : return "FIXED32";
    355     case FieldDescriptor::TYPE_SFIXED32: return "SFIXED32";
    356     case FieldDescriptor::TYPE_INT64   : return "INT64";
    357     case FieldDescriptor::TYPE_UINT64  : return "UINT64";
    358     case FieldDescriptor::TYPE_SINT64  : return "SINT64";
    359     case FieldDescriptor::TYPE_FIXED64 : return "FIXED64";
    360     case FieldDescriptor::TYPE_SFIXED64: return "SFIXED64";
    361     case FieldDescriptor::TYPE_FLOAT   : return "FLOAT";
    362     case FieldDescriptor::TYPE_DOUBLE  : return "DOUBLE";
    363     case FieldDescriptor::TYPE_BOOL    : return "BOOL";
    364     case FieldDescriptor::TYPE_STRING  : return "STRING";
    365     case FieldDescriptor::TYPE_BYTES   : return "BYTES";
    366     case FieldDescriptor::TYPE_ENUM    : return "ENUM";
    367     case FieldDescriptor::TYPE_GROUP   : return "GROUP";
    368     case FieldDescriptor::TYPE_MESSAGE : return "MESSAGE";
    369 
    370     // No default because we want the compiler to complain if any new
    371     // types are added.
    372   }
    373 
    374   GOOGLE_LOG(FATAL) << "Can't get here.";
    375   return NULL;
    376 }
    377 
    378 bool AllAscii(const string& text) {
    379   for (int i = 0; i < text.size(); i++) {
    380     if ((text[i] & 0x80) != 0) {
    381       return false;
    382     }
    383   }
    384   return true;
    385 }
    386 
    387 string DefaultValue(const FieldDescriptor* field, bool immutable,
    388                     ClassNameResolver* name_resolver) {
    389   // Switch on CppType since we need to know which default_value_* method
    390   // of FieldDescriptor to call.
    391   switch (field->cpp_type()) {
    392     case FieldDescriptor::CPPTYPE_INT32:
    393       return SimpleItoa(field->default_value_int32());
    394     case FieldDescriptor::CPPTYPE_UINT32:
    395       // Need to print as a signed int since Java has no unsigned.
    396       return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
    397     case FieldDescriptor::CPPTYPE_INT64:
    398       return SimpleItoa(field->default_value_int64()) + "L";
    399     case FieldDescriptor::CPPTYPE_UINT64:
    400       return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
    401              "L";
    402     case FieldDescriptor::CPPTYPE_DOUBLE: {
    403       double value = field->default_value_double();
    404       if (value == numeric_limits<double>::infinity()) {
    405         return "Double.POSITIVE_INFINITY";
    406       } else if (value == -numeric_limits<double>::infinity()) {
    407         return "Double.NEGATIVE_INFINITY";
    408       } else if (value != value) {
    409         return "Double.NaN";
    410       } else {
    411         return SimpleDtoa(value) + "D";
    412       }
    413     }
    414     case FieldDescriptor::CPPTYPE_FLOAT: {
    415       float value = field->default_value_float();
    416       if (value == numeric_limits<float>::infinity()) {
    417         return "Float.POSITIVE_INFINITY";
    418       } else if (value == -numeric_limits<float>::infinity()) {
    419         return "Float.NEGATIVE_INFINITY";
    420       } else if (value != value) {
    421         return "Float.NaN";
    422       } else {
    423         return SimpleFtoa(value) + "F";
    424       }
    425     }
    426     case FieldDescriptor::CPPTYPE_BOOL:
    427       return field->default_value_bool() ? "true" : "false";
    428     case FieldDescriptor::CPPTYPE_STRING:
    429       if (GetType(field) == FieldDescriptor::TYPE_BYTES) {
    430         if (field->has_default_value()) {
    431           // See comments in Internal.java for gory details.
    432           return strings::Substitute(
    433             "com.google.protobuf.Internal.bytesDefaultValue(\"$0\")",
    434             CEscape(field->default_value_string()));
    435         } else {
    436           return "com.google.protobuf.ByteString.EMPTY";
    437         }
    438       } else {
    439         if (AllAscii(field->default_value_string())) {
    440           // All chars are ASCII.  In this case CEscape() works fine.
    441           return "\"" + CEscape(field->default_value_string()) + "\"";
    442         } else {
    443           // See comments in Internal.java for gory details.
    444           return strings::Substitute(
    445               "com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
    446               CEscape(field->default_value_string()));
    447         }
    448       }
    449 
    450     case FieldDescriptor::CPPTYPE_ENUM:
    451       return name_resolver->GetClassName(field->enum_type(), immutable) + "." +
    452           field->default_value_enum()->name();
    453 
    454     case FieldDescriptor::CPPTYPE_MESSAGE:
    455       return name_resolver->GetClassName(field->message_type(), immutable) +
    456           ".getDefaultInstance()";
    457 
    458     // No default because we want the compiler to complain if any new
    459     // types are added.
    460   }
    461 
    462   GOOGLE_LOG(FATAL) << "Can't get here.";
    463   return "";
    464 }
    465 
    466 bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
    467   // Switch on CppType since we need to know which default_value_* method
    468   // of FieldDescriptor to call.
    469   switch (field->cpp_type()) {
    470     case FieldDescriptor::CPPTYPE_INT32:
    471       return field->default_value_int32() == 0;
    472     case FieldDescriptor::CPPTYPE_UINT32:
    473       return field->default_value_uint32() == 0;
    474     case FieldDescriptor::CPPTYPE_INT64:
    475       return field->default_value_int64() == 0L;
    476     case FieldDescriptor::CPPTYPE_UINT64:
    477       return field->default_value_uint64() == 0L;
    478     case FieldDescriptor::CPPTYPE_DOUBLE:
    479       return field->default_value_double() == 0.0;
    480     case FieldDescriptor::CPPTYPE_FLOAT:
    481       return field->default_value_float() == 0.0;
    482     case FieldDescriptor::CPPTYPE_BOOL:
    483       return field->default_value_bool() == false;
    484 
    485     case FieldDescriptor::CPPTYPE_STRING:
    486     case FieldDescriptor::CPPTYPE_ENUM:
    487     case FieldDescriptor::CPPTYPE_MESSAGE:
    488       return false;
    489 
    490     // No default because we want the compiler to complain if any new
    491     // types are added.
    492   }
    493 
    494   GOOGLE_LOG(FATAL) << "Can't get here.";
    495   return false;
    496 }
    497 
    498 const char* bit_masks[] = {
    499   "0x00000001",
    500   "0x00000002",
    501   "0x00000004",
    502   "0x00000008",
    503   "0x00000010",
    504   "0x00000020",
    505   "0x00000040",
    506   "0x00000080",
    507 
    508   "0x00000100",
    509   "0x00000200",
    510   "0x00000400",
    511   "0x00000800",
    512   "0x00001000",
    513   "0x00002000",
    514   "0x00004000",
    515   "0x00008000",
    516 
    517   "0x00010000",
    518   "0x00020000",
    519   "0x00040000",
    520   "0x00080000",
    521   "0x00100000",
    522   "0x00200000",
    523   "0x00400000",
    524   "0x00800000",
    525 
    526   "0x01000000",
    527   "0x02000000",
    528   "0x04000000",
    529   "0x08000000",
    530   "0x10000000",
    531   "0x20000000",
    532   "0x40000000",
    533   "0x80000000",
    534 };
    535 
    536 string GetBitFieldName(int index) {
    537   string varName = "bitField";
    538   varName += SimpleItoa(index);
    539   varName += "_";
    540   return varName;
    541 }
    542 
    543 string GetBitFieldNameForBit(int bitIndex) {
    544   return GetBitFieldName(bitIndex / 32);
    545 }
    546 
    547 namespace {
    548 
    549 string GenerateGetBitInternal(const string& prefix, int bitIndex) {
    550   string varName = prefix + GetBitFieldNameForBit(bitIndex);
    551   int bitInVarIndex = bitIndex % 32;
    552 
    553   string mask = bit_masks[bitInVarIndex];
    554   string result = "((" + varName + " & " + mask + ") == " + mask + ")";
    555   return result;
    556 }
    557 
    558 string GenerateSetBitInternal(const string& prefix, int bitIndex) {
    559   string varName = prefix + GetBitFieldNameForBit(bitIndex);
    560   int bitInVarIndex = bitIndex % 32;
    561 
    562   string mask = bit_masks[bitInVarIndex];
    563   string result = varName + " |= " + mask;
    564   return result;
    565 }
    566 
    567 }  // namespace
    568 
    569 string GenerateGetBit(int bitIndex) {
    570   return GenerateGetBitInternal("", bitIndex);
    571 }
    572 
    573 string GenerateSetBit(int bitIndex) {
    574   return GenerateSetBitInternal("", bitIndex);
    575 }
    576 
    577 string GenerateClearBit(int bitIndex) {
    578   string varName = GetBitFieldNameForBit(bitIndex);
    579   int bitInVarIndex = bitIndex % 32;
    580 
    581   string mask = bit_masks[bitInVarIndex];
    582   string result = varName + " = (" + varName + " & ~" + mask + ")";
    583   return result;
    584 }
    585 
    586 string GenerateGetBitFromLocal(int bitIndex) {
    587   return GenerateGetBitInternal("from_", bitIndex);
    588 }
    589 
    590 string GenerateSetBitToLocal(int bitIndex) {
    591   return GenerateSetBitInternal("to_", bitIndex);
    592 }
    593 
    594 string GenerateGetBitMutableLocal(int bitIndex) {
    595   return GenerateGetBitInternal("mutable_", bitIndex);
    596 }
    597 
    598 string GenerateSetBitMutableLocal(int bitIndex) {
    599   return GenerateSetBitInternal("mutable_", bitIndex);
    600 }
    601 
    602 bool IsReferenceType(JavaType type) {
    603   switch (type) {
    604     case JAVATYPE_INT    : return false;
    605     case JAVATYPE_LONG   : return false;
    606     case JAVATYPE_FLOAT  : return false;
    607     case JAVATYPE_DOUBLE : return false;
    608     case JAVATYPE_BOOLEAN: return false;
    609     case JAVATYPE_STRING : return true;
    610     case JAVATYPE_BYTES  : return true;
    611     case JAVATYPE_ENUM   : return true;
    612     case JAVATYPE_MESSAGE: return true;
    613 
    614     // No default because we want the compiler to complain if any new
    615     // JavaTypes are added.
    616   }
    617 
    618   GOOGLE_LOG(FATAL) << "Can't get here.";
    619   return false;
    620 }
    621 
    622 const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable) {
    623   switch (GetType(field)) {
    624     case FieldDescriptor::TYPE_INT32   : return "Int32";
    625     case FieldDescriptor::TYPE_UINT32  : return "UInt32";
    626     case FieldDescriptor::TYPE_SINT32  : return "SInt32";
    627     case FieldDescriptor::TYPE_FIXED32 : return "Fixed32";
    628     case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
    629     case FieldDescriptor::TYPE_INT64   : return "Int64";
    630     case FieldDescriptor::TYPE_UINT64  : return "UInt64";
    631     case FieldDescriptor::TYPE_SINT64  : return "SInt64";
    632     case FieldDescriptor::TYPE_FIXED64 : return "Fixed64";
    633     case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
    634     case FieldDescriptor::TYPE_FLOAT   : return "Float";
    635     case FieldDescriptor::TYPE_DOUBLE  : return "Double";
    636     case FieldDescriptor::TYPE_BOOL    : return "Bool";
    637     case FieldDescriptor::TYPE_STRING  : return "String";
    638     case FieldDescriptor::TYPE_BYTES   : {
    639       return "Bytes";
    640     }
    641     case FieldDescriptor::TYPE_ENUM    : return "Enum";
    642     case FieldDescriptor::TYPE_GROUP   : return "Group";
    643     case FieldDescriptor::TYPE_MESSAGE : return "Message";
    644 
    645     // No default because we want the compiler to complain if any new
    646     // types are added.
    647   }
    648 
    649   GOOGLE_LOG(FATAL) << "Can't get here.";
    650   return NULL;
    651 }
    652 
    653 // For encodings with fixed sizes, returns that size in bytes.  Otherwise
    654 // returns -1.
    655 int FixedSize(FieldDescriptor::Type type) {
    656   switch (type) {
    657     case FieldDescriptor::TYPE_INT32   : return -1;
    658     case FieldDescriptor::TYPE_INT64   : return -1;
    659     case FieldDescriptor::TYPE_UINT32  : return -1;
    660     case FieldDescriptor::TYPE_UINT64  : return -1;
    661     case FieldDescriptor::TYPE_SINT32  : return -1;
    662     case FieldDescriptor::TYPE_SINT64  : return -1;
    663     case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
    664     case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
    665     case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
    666     case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
    667     case FieldDescriptor::TYPE_FLOAT   : return WireFormatLite::kFloatSize;
    668     case FieldDescriptor::TYPE_DOUBLE  : return WireFormatLite::kDoubleSize;
    669 
    670     case FieldDescriptor::TYPE_BOOL    : return WireFormatLite::kBoolSize;
    671     case FieldDescriptor::TYPE_ENUM    : return -1;
    672 
    673     case FieldDescriptor::TYPE_STRING  : return -1;
    674     case FieldDescriptor::TYPE_BYTES   : return -1;
    675     case FieldDescriptor::TYPE_GROUP   : return -1;
    676     case FieldDescriptor::TYPE_MESSAGE : return -1;
    677 
    678     // No default because we want the compiler to complain if any new
    679     // types are added.
    680   }
    681   GOOGLE_LOG(FATAL) << "Can't get here.";
    682   return -1;
    683 }
    684 
    685 // Sort the fields of the given Descriptor by number into a new[]'d array
    686 // and return it. The caller should delete the returned array.
    687 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
    688   const FieldDescriptor** fields =
    689     new const FieldDescriptor*[descriptor->field_count()];
    690   for (int i = 0; i < descriptor->field_count(); i++) {
    691     fields[i] = descriptor->field(i);
    692   }
    693   std::sort(fields, fields + descriptor->field_count(),
    694             FieldOrderingByNumber());
    695   return fields;
    696 }
    697 
    698 // Returns true if the message type has any required fields.  If it doesn't,
    699 // we can optimize out calls to its isInitialized() method.
    700 //
    701 // already_seen is used to avoid checking the same type multiple times
    702 // (and also to protect against recursion).
    703 bool HasRequiredFields(
    704     const Descriptor* type,
    705     hash_set<const Descriptor*>* already_seen) {
    706   if (already_seen->count(type) > 0) {
    707     // The type is already in cache.  This means that either:
    708     // a. The type has no required fields.
    709     // b. We are in the midst of checking if the type has required fields,
    710     //    somewhere up the stack.  In this case, we know that if the type
    711     //    has any required fields, they'll be found when we return to it,
    712     //    and the whole call to HasRequiredFields() will return true.
    713     //    Therefore, we don't have to check if this type has required fields
    714     //    here.
    715     return false;
    716   }
    717   already_seen->insert(type);
    718 
    719   // If the type has extensions, an extension with message type could contain
    720   // required fields, so we have to be conservative and assume such an
    721   // extension exists.
    722   if (type->extension_range_count() > 0) return true;
    723 
    724   for (int i = 0; i < type->field_count(); i++) {
    725     const FieldDescriptor* field = type->field(i);
    726     if (field->is_required()) {
    727       return true;
    728     }
    729     if (GetJavaType(field) == JAVATYPE_MESSAGE) {
    730       if (HasRequiredFields(field->message_type(), already_seen)) {
    731         return true;
    732       }
    733     }
    734   }
    735 
    736   return false;
    737 }
    738 
    739 bool HasRequiredFields(const Descriptor* type) {
    740   hash_set<const Descriptor*> already_seen;
    741   return HasRequiredFields(type, &already_seen);
    742 }
    743 
    744 bool HasRepeatedFields(const Descriptor* descriptor) {
    745   for (int i = 0; i < descriptor->field_count(); ++i) {
    746     const FieldDescriptor* field = descriptor->field(i);
    747     if (field->is_repeated()) {
    748       return true;
    749     }
    750   }
    751   return false;
    752 }
    753 
    754 }  // namespace java
    755 }  // namespace compiler
    756 }  // namespace protobuf
    757 }  // namespace google
    758