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@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 
IsForbidden(const string & field_name)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 
FieldName(const FieldDescriptor * field)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 
UnderscoresToCamelCase(const string & input,bool cap_next_letter)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 
UnderscoresToCamelCase(const FieldDescriptor * field)139 string UnderscoresToCamelCase(const FieldDescriptor* field) {
140   return UnderscoresToCamelCase(FieldName(field), false);
141 }
142 
UnderscoresToCapitalizedCamelCase(const FieldDescriptor * field)143 string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
144   return UnderscoresToCamelCase(FieldName(field), true);
145 }
146 
UnderscoresToCamelCase(const MethodDescriptor * method)147 string UnderscoresToCamelCase(const MethodDescriptor* method) {
148   return UnderscoresToCamelCase(method->name(), false);
149 }
150 
UniqueFileScopeIdentifier(const Descriptor * descriptor)151 string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
152   return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
153 }
154 
StripProto(const string & filename)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 
FileClassName(const FileDescriptor * file,bool immutable)163 string FileClassName(const FileDescriptor* file, bool immutable) {
164   ClassNameResolver name_resolver;
165   return name_resolver.GetFileClassName(file, immutable);
166 }
167 
FileJavaPackage(const FileDescriptor * file,bool immutable)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 
JavaPackageToDir(string package_name)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.
ToJavaName(const string & full_name,const FileDescriptor * file)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 
ClassName(const Descriptor * descriptor)214 string ClassName(const Descriptor* descriptor) {
215   ClassNameResolver name_resolver;
216   return name_resolver.GetClassName(descriptor, true);
217 }
218 
ClassName(const EnumDescriptor * descriptor)219 string ClassName(const EnumDescriptor* descriptor) {
220   ClassNameResolver name_resolver;
221   return name_resolver.GetClassName(descriptor, true);
222 }
223 
ClassName(const ServiceDescriptor * descriptor)224 string ClassName(const ServiceDescriptor* descriptor) {
225   ClassNameResolver name_resolver;
226   return name_resolver.GetClassName(descriptor, true);
227 }
228 
ClassName(const FileDescriptor * descriptor)229 string ClassName(const FileDescriptor* descriptor) {
230   ClassNameResolver name_resolver;
231   return name_resolver.GetClassName(descriptor, true);
232 }
233 
ExtraMessageInterfaces(const Descriptor * descriptor)234 string ExtraMessageInterfaces(const Descriptor* descriptor) {
235   string interfaces = "// @@protoc_insertion_point(message_implements:"
236       + descriptor->full_name() + ")";
237   return interfaces;
238 }
239 
240 
ExtraBuilderInterfaces(const Descriptor * descriptor)241 string ExtraBuilderInterfaces(const Descriptor* descriptor) {
242   string interfaces = "// @@protoc_insertion_point(builder_implements:"
243       + descriptor->full_name() + ")";
244   return interfaces;
245 }
246 
ExtraMessageOrBuilderInterfaces(const Descriptor * descriptor)247 string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor) {
248   string interfaces = "// @@protoc_insertion_point(interface_extends:"
249       + descriptor->full_name() + ")";
250   return interfaces;
251 }
252 
FieldConstantName(const FieldDescriptor * field)253 string FieldConstantName(const FieldDescriptor *field) {
254   string name = field->name() + "_FIELD_NUMBER";
255   UpperString(&name);
256   return name;
257 }
258 
GetType(const FieldDescriptor * field)259 FieldDescriptor::Type GetType(const FieldDescriptor* field) {
260   return field->type();
261 }
262 
GetJavaType(const FieldDescriptor * field)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 
BoxedPrimitiveTypeName(JavaType type)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 
FieldTypeName(FieldDescriptor::Type field_type)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 
AllAscii(const string & text)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 
DefaultValue(const FieldDescriptor * field,bool immutable,ClassNameResolver * name_resolver)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 
IsDefaultValueJavaDefault(const FieldDescriptor * field)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 
GetBitFieldName(int index)516 string GetBitFieldName(int index) {
517   string varName = "bitField";
518   varName += SimpleItoa(index);
519   varName += "_";
520   return varName;
521 }
522 
GetBitFieldNameForBit(int bitIndex)523 string GetBitFieldNameForBit(int bitIndex) {
524   return GetBitFieldName(bitIndex / 32);
525 }
526 
527 namespace {
528 
GenerateGetBitInternal(const string & prefix,int bitIndex)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 
GenerateSetBitInternal(const string & prefix,int bitIndex)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 
GenerateGetBit(int bitIndex)549 string GenerateGetBit(int bitIndex) {
550   return GenerateGetBitInternal("", bitIndex);
551 }
552 
GenerateSetBit(int bitIndex)553 string GenerateSetBit(int bitIndex) {
554   return GenerateSetBitInternal("", bitIndex);
555 }
556 
GenerateClearBit(int bitIndex)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 
GenerateGetBitFromLocal(int bitIndex)566 string GenerateGetBitFromLocal(int bitIndex) {
567   return GenerateGetBitInternal("from_", bitIndex);
568 }
569 
GenerateSetBitToLocal(int bitIndex)570 string GenerateSetBitToLocal(int bitIndex) {
571   return GenerateSetBitInternal("to_", bitIndex);
572 }
573 
GenerateGetBitMutableLocal(int bitIndex)574 string GenerateGetBitMutableLocal(int bitIndex) {
575   return GenerateGetBitInternal("mutable_", bitIndex);
576 }
577 
GenerateSetBitMutableLocal(int bitIndex)578 string GenerateSetBitMutableLocal(int bitIndex) {
579   return GenerateSetBitInternal("mutable_", bitIndex);
580 }
581 
IsReferenceType(JavaType type)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 
GetCapitalizedType(const FieldDescriptor * field,bool immutable)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.
FixedSize(FieldDescriptor::Type type)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.
SortFieldsByNumber(const Descriptor * descriptor)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).
HasRequiredFields(const Descriptor * type,hash_set<const Descriptor * > * already_seen)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 
HasRequiredFields(const Descriptor * type)719 bool HasRequiredFields(const Descriptor* type) {
720   hash_set<const Descriptor*> already_seen;
721   return HasRequiredFields(type, &already_seen);
722 }
723 
HasRepeatedFields(const Descriptor * descriptor)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