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* BoxedPrimitiveTypeName(JavaType type) {
    310   switch (type) {
    311     case JAVATYPE_INT    : return "java.lang.Integer";
    312     case JAVATYPE_LONG   : return "java.lang.Long";
    313     case JAVATYPE_FLOAT  : return "java.lang.Float";
    314     case JAVATYPE_DOUBLE : return "java.lang.Double";
    315     case JAVATYPE_BOOLEAN: return "java.lang.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* FieldTypeName(FieldDescriptor::Type field_type) {
    330   switch (field_type) {
    331     case FieldDescriptor::TYPE_INT32   : return "INT32";
    332     case FieldDescriptor::TYPE_UINT32  : return "UINT32";
    333     case FieldDescriptor::TYPE_SINT32  : return "SINT32";
    334     case FieldDescriptor::TYPE_FIXED32 : return "FIXED32";
    335     case FieldDescriptor::TYPE_SFIXED32: return "SFIXED32";
    336     case FieldDescriptor::TYPE_INT64   : return "INT64";
    337     case FieldDescriptor::TYPE_UINT64  : return "UINT64";
    338     case FieldDescriptor::TYPE_SINT64  : return "SINT64";
    339     case FieldDescriptor::TYPE_FIXED64 : return "FIXED64";
    340     case FieldDescriptor::TYPE_SFIXED64: return "SFIXED64";
    341     case FieldDescriptor::TYPE_FLOAT   : return "FLOAT";
    342     case FieldDescriptor::TYPE_DOUBLE  : return "DOUBLE";
    343     case FieldDescriptor::TYPE_BOOL    : return "BOOL";
    344     case FieldDescriptor::TYPE_STRING  : return "STRING";
    345     case FieldDescriptor::TYPE_BYTES   : return "BYTES";
    346     case FieldDescriptor::TYPE_ENUM    : return "ENUM";
    347     case FieldDescriptor::TYPE_GROUP   : return "GROUP";
    348     case FieldDescriptor::TYPE_MESSAGE : return "MESSAGE";
    349 
    350     // No default because we want the compiler to complain if any new
    351     // types are added.
    352   }
    353 
    354   GOOGLE_LOG(FATAL) << "Can't get here.";
    355   return NULL;
    356 }
    357 
    358 bool AllAscii(const string& text) {
    359   for (int i = 0; i < text.size(); i++) {
    360     if ((text[i] & 0x80) != 0) {
    361       return false;
    362     }
    363   }
    364   return true;
    365 }
    366 
    367 string DefaultValue(const FieldDescriptor* field, bool immutable,
    368                     ClassNameResolver* name_resolver) {
    369   // Switch on CppType since we need to know which default_value_* method
    370   // of FieldDescriptor to call.
    371   switch (field->cpp_type()) {
    372     case FieldDescriptor::CPPTYPE_INT32:
    373       return SimpleItoa(field->default_value_int32());
    374     case FieldDescriptor::CPPTYPE_UINT32:
    375       // Need to print as a signed int since Java has no unsigned.
    376       return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
    377     case FieldDescriptor::CPPTYPE_INT64:
    378       return SimpleItoa(field->default_value_int64()) + "L";
    379     case FieldDescriptor::CPPTYPE_UINT64:
    380       return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
    381              "L";
    382     case FieldDescriptor::CPPTYPE_DOUBLE: {
    383       double value = field->default_value_double();
    384       if (value == numeric_limits<double>::infinity()) {
    385         return "Double.POSITIVE_INFINITY";
    386       } else if (value == -numeric_limits<double>::infinity()) {
    387         return "Double.NEGATIVE_INFINITY";
    388       } else if (value != value) {
    389         return "Double.NaN";
    390       } else {
    391         return SimpleDtoa(value) + "D";
    392       }
    393     }
    394     case FieldDescriptor::CPPTYPE_FLOAT: {
    395       float value = field->default_value_float();
    396       if (value == numeric_limits<float>::infinity()) {
    397         return "Float.POSITIVE_INFINITY";
    398       } else if (value == -numeric_limits<float>::infinity()) {
    399         return "Float.NEGATIVE_INFINITY";
    400       } else if (value != value) {
    401         return "Float.NaN";
    402       } else {
    403         return SimpleFtoa(value) + "F";
    404       }
    405     }
    406     case FieldDescriptor::CPPTYPE_BOOL:
    407       return field->default_value_bool() ? "true" : "false";
    408     case FieldDescriptor::CPPTYPE_STRING:
    409       if (GetType(field) == FieldDescriptor::TYPE_BYTES) {
    410         if (field->has_default_value()) {
    411           // See comments in Internal.java for gory details.
    412           return strings::Substitute(
    413             "com.google.protobuf.Internal.bytesDefaultValue(\"$0\")",
    414             CEscape(field->default_value_string()));
    415         } else {
    416           return "com.google.protobuf.ByteString.EMPTY";
    417         }
    418       } else {
    419         if (AllAscii(field->default_value_string())) {
    420           // All chars are ASCII.  In this case CEscape() works fine.
    421           return "\"" + CEscape(field->default_value_string()) + "\"";
    422         } else {
    423           // See comments in Internal.java for gory details.
    424           return strings::Substitute(
    425               "com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
    426               CEscape(field->default_value_string()));
    427         }
    428       }
    429 
    430     case FieldDescriptor::CPPTYPE_ENUM:
    431       return name_resolver->GetClassName(field->enum_type(), immutable) + "." +
    432           field->default_value_enum()->name();
    433 
    434     case FieldDescriptor::CPPTYPE_MESSAGE:
    435       return name_resolver->GetClassName(field->message_type(), immutable) +
    436           ".getDefaultInstance()";
    437 
    438     // No default because we want the compiler to complain if any new
    439     // types are added.
    440   }
    441 
    442   GOOGLE_LOG(FATAL) << "Can't get here.";
    443   return "";
    444 }
    445 
    446 bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
    447   // Switch on CppType since we need to know which default_value_* method
    448   // of FieldDescriptor to call.
    449   switch (field->cpp_type()) {
    450     case FieldDescriptor::CPPTYPE_INT32:
    451       return field->default_value_int32() == 0;
    452     case FieldDescriptor::CPPTYPE_UINT32:
    453       return field->default_value_uint32() == 0;
    454     case FieldDescriptor::CPPTYPE_INT64:
    455       return field->default_value_int64() == 0L;
    456     case FieldDescriptor::CPPTYPE_UINT64:
    457       return field->default_value_uint64() == 0L;
    458     case FieldDescriptor::CPPTYPE_DOUBLE:
    459       return field->default_value_double() == 0.0;
    460     case FieldDescriptor::CPPTYPE_FLOAT:
    461       return field->default_value_float() == 0.0;
    462     case FieldDescriptor::CPPTYPE_BOOL:
    463       return field->default_value_bool() == false;
    464 
    465     case FieldDescriptor::CPPTYPE_STRING:
    466     case FieldDescriptor::CPPTYPE_ENUM:
    467     case FieldDescriptor::CPPTYPE_MESSAGE:
    468       return false;
    469 
    470     // No default because we want the compiler to complain if any new
    471     // types are added.
    472   }
    473 
    474   GOOGLE_LOG(FATAL) << "Can't get here.";
    475   return false;
    476 }
    477 
    478 const char* bit_masks[] = {
    479   "0x00000001",
    480   "0x00000002",
    481   "0x00000004",
    482   "0x00000008",
    483   "0x00000010",
    484   "0x00000020",
    485   "0x00000040",
    486   "0x00000080",
    487 
    488   "0x00000100",
    489   "0x00000200",
    490   "0x00000400",
    491   "0x00000800",
    492   "0x00001000",
    493   "0x00002000",
    494   "0x00004000",
    495   "0x00008000",
    496 
    497   "0x00010000",
    498   "0x00020000",
    499   "0x00040000",
    500   "0x00080000",
    501   "0x00100000",
    502   "0x00200000",
    503   "0x00400000",
    504   "0x00800000",
    505 
    506   "0x01000000",
    507   "0x02000000",
    508   "0x04000000",
    509   "0x08000000",
    510   "0x10000000",
    511   "0x20000000",
    512   "0x40000000",
    513   "0x80000000",
    514 };
    515 
    516 string GetBitFieldName(int index) {
    517   string varName = "bitField";
    518   varName += SimpleItoa(index);
    519   varName += "_";
    520   return varName;
    521 }
    522 
    523 string GetBitFieldNameForBit(int bitIndex) {
    524   return GetBitFieldName(bitIndex / 32);
    525 }
    526 
    527 namespace {
    528 
    529 string GenerateGetBitInternal(const string& prefix, int bitIndex) {
    530   string varName = prefix + GetBitFieldNameForBit(bitIndex);
    531   int bitInVarIndex = bitIndex % 32;
    532 
    533   string mask = bit_masks[bitInVarIndex];
    534   string result = "((" + varName + " & " + mask + ") == " + mask + ")";
    535   return result;
    536 }
    537 
    538 string GenerateSetBitInternal(const string& prefix, int bitIndex) {
    539   string varName = prefix + GetBitFieldNameForBit(bitIndex);
    540   int bitInVarIndex = bitIndex % 32;
    541 
    542   string mask = bit_masks[bitInVarIndex];
    543   string result = varName + " |= " + mask;
    544   return result;
    545 }
    546 
    547 }  // namespace
    548 
    549 string GenerateGetBit(int bitIndex) {
    550   return GenerateGetBitInternal("", bitIndex);
    551 }
    552 
    553 string GenerateSetBit(int bitIndex) {
    554   return GenerateSetBitInternal("", bitIndex);
    555 }
    556 
    557 string GenerateClearBit(int bitIndex) {
    558   string varName = GetBitFieldNameForBit(bitIndex);
    559   int bitInVarIndex = bitIndex % 32;
    560 
    561   string mask = bit_masks[bitInVarIndex];
    562   string result = varName + " = (" + varName + " & ~" + mask + ")";
    563   return result;
    564 }
    565 
    566 string GenerateGetBitFromLocal(int bitIndex) {
    567   return GenerateGetBitInternal("from_", bitIndex);
    568 }
    569 
    570 string GenerateSetBitToLocal(int bitIndex) {
    571   return GenerateSetBitInternal("to_", bitIndex);
    572 }
    573 
    574 string GenerateGetBitMutableLocal(int bitIndex) {
    575   return GenerateGetBitInternal("mutable_", bitIndex);
    576 }
    577 
    578 string GenerateSetBitMutableLocal(int bitIndex) {
    579   return GenerateSetBitInternal("mutable_", bitIndex);
    580 }
    581 
    582 bool IsReferenceType(JavaType type) {
    583   switch (type) {
    584     case JAVATYPE_INT    : return false;
    585     case JAVATYPE_LONG   : return false;
    586     case JAVATYPE_FLOAT  : return false;
    587     case JAVATYPE_DOUBLE : return false;
    588     case JAVATYPE_BOOLEAN: return false;
    589     case JAVATYPE_STRING : return true;
    590     case JAVATYPE_BYTES  : return true;
    591     case JAVATYPE_ENUM   : return true;
    592     case JAVATYPE_MESSAGE: return true;
    593 
    594     // No default because we want the compiler to complain if any new
    595     // JavaTypes are added.
    596   }
    597 
    598   GOOGLE_LOG(FATAL) << "Can't get here.";
    599   return false;
    600 }
    601 
    602 const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable) {
    603   switch (GetType(field)) {
    604     case FieldDescriptor::TYPE_INT32   : return "Int32";
    605     case FieldDescriptor::TYPE_UINT32  : return "UInt32";
    606     case FieldDescriptor::TYPE_SINT32  : return "SInt32";
    607     case FieldDescriptor::TYPE_FIXED32 : return "Fixed32";
    608     case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
    609     case FieldDescriptor::TYPE_INT64   : return "Int64";
    610     case FieldDescriptor::TYPE_UINT64  : return "UInt64";
    611     case FieldDescriptor::TYPE_SINT64  : return "SInt64";
    612     case FieldDescriptor::TYPE_FIXED64 : return "Fixed64";
    613     case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
    614     case FieldDescriptor::TYPE_FLOAT   : return "Float";
    615     case FieldDescriptor::TYPE_DOUBLE  : return "Double";
    616     case FieldDescriptor::TYPE_BOOL    : return "Bool";
    617     case FieldDescriptor::TYPE_STRING  : return "String";
    618     case FieldDescriptor::TYPE_BYTES   : {
    619       return "Bytes";
    620     }
    621     case FieldDescriptor::TYPE_ENUM    : return "Enum";
    622     case FieldDescriptor::TYPE_GROUP   : return "Group";
    623     case FieldDescriptor::TYPE_MESSAGE : return "Message";
    624 
    625     // No default because we want the compiler to complain if any new
    626     // types are added.
    627   }
    628 
    629   GOOGLE_LOG(FATAL) << "Can't get here.";
    630   return NULL;
    631 }
    632 
    633 // For encodings with fixed sizes, returns that size in bytes.  Otherwise
    634 // returns -1.
    635 int FixedSize(FieldDescriptor::Type type) {
    636   switch (type) {
    637     case FieldDescriptor::TYPE_INT32   : return -1;
    638     case FieldDescriptor::TYPE_INT64   : return -1;
    639     case FieldDescriptor::TYPE_UINT32  : return -1;
    640     case FieldDescriptor::TYPE_UINT64  : return -1;
    641     case FieldDescriptor::TYPE_SINT32  : return -1;
    642     case FieldDescriptor::TYPE_SINT64  : return -1;
    643     case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
    644     case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
    645     case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
    646     case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
    647     case FieldDescriptor::TYPE_FLOAT   : return WireFormatLite::kFloatSize;
    648     case FieldDescriptor::TYPE_DOUBLE  : return WireFormatLite::kDoubleSize;
    649 
    650     case FieldDescriptor::TYPE_BOOL    : return WireFormatLite::kBoolSize;
    651     case FieldDescriptor::TYPE_ENUM    : return -1;
    652 
    653     case FieldDescriptor::TYPE_STRING  : return -1;
    654     case FieldDescriptor::TYPE_BYTES   : return -1;
    655     case FieldDescriptor::TYPE_GROUP   : return -1;
    656     case FieldDescriptor::TYPE_MESSAGE : return -1;
    657 
    658     // No default because we want the compiler to complain if any new
    659     // types are added.
    660   }
    661   GOOGLE_LOG(FATAL) << "Can't get here.";
    662   return -1;
    663 }
    664 
    665 // Sort the fields of the given Descriptor by number into a new[]'d array
    666 // and return it. The caller should delete the returned array.
    667 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
    668   const FieldDescriptor** fields =
    669     new const FieldDescriptor*[descriptor->field_count()];
    670   for (int i = 0; i < descriptor->field_count(); i++) {
    671     fields[i] = descriptor->field(i);
    672   }
    673   sort(fields, fields + descriptor->field_count(),
    674        FieldOrderingByNumber());
    675   return fields;
    676 }
    677 
    678 // Returns true if the message type has any required fields.  If it doesn't,
    679 // we can optimize out calls to its isInitialized() method.
    680 //
    681 // already_seen is used to avoid checking the same type multiple times
    682 // (and also to protect against recursion).
    683 bool HasRequiredFields(
    684     const Descriptor* type,
    685     hash_set<const Descriptor*>* already_seen) {
    686   if (already_seen->count(type) > 0) {
    687     // The type is already in cache.  This means that either:
    688     // a. The type has no required fields.
    689     // b. We are in the midst of checking if the type has required fields,
    690     //    somewhere up the stack.  In this case, we know that if the type
    691     //    has any required fields, they'll be found when we return to it,
    692     //    and the whole call to HasRequiredFields() will return true.
    693     //    Therefore, we don't have to check if this type has required fields
    694     //    here.
    695     return false;
    696   }
    697   already_seen->insert(type);
    698 
    699   // If the type has extensions, an extension with message type could contain
    700   // required fields, so we have to be conservative and assume such an
    701   // extension exists.
    702   if (type->extension_range_count() > 0) return true;
    703 
    704   for (int i = 0; i < type->field_count(); i++) {
    705     const FieldDescriptor* field = type->field(i);
    706     if (field->is_required()) {
    707       return true;
    708     }
    709     if (GetJavaType(field) == JAVATYPE_MESSAGE) {
    710       if (HasRequiredFields(field->message_type(), already_seen)) {
    711         return true;
    712       }
    713     }
    714   }
    715 
    716   return false;
    717 }
    718 
    719 bool HasRequiredFields(const Descriptor* type) {
    720   hash_set<const Descriptor*> already_seen;
    721   return HasRequiredFields(type, &already_seen);
    722 }
    723 
    724 bool HasRepeatedFields(const Descriptor* descriptor) {
    725   for (int i = 0; i < descriptor->field_count(); ++i) {
    726     const FieldDescriptor* field = descriptor->field(i);
    727     if (field->is_repeated()) {
    728       return true;
    729     }
    730   }
    731   return false;
    732 }
    733 
    734 }  // namespace java
    735 }  // namespace compiler
    736 }  // namespace protobuf
    737 }  // namespace google
    738