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 
PrintGeneratedAnnotation(io::Printer * printer,char delimiter,const string & annotation_file)104 void PrintGeneratedAnnotation(io::Printer* printer, char delimiter,
105                               const string& annotation_file) {
106   if (annotation_file.empty()) {
107     return;
108   }
109   string ptemplate =
110       "@javax.annotation.Generated(value=\"protoc\", comments=\"annotations:";
111   ptemplate.push_back(delimiter);
112   ptemplate.append("annotation_file");
113   ptemplate.push_back(delimiter);
114   ptemplate.append("\")\n");
115   printer->Print(ptemplate.c_str(), "annotation_file", annotation_file);
116 }
117 
UnderscoresToCamelCase(const string & input,bool cap_next_letter)118 string UnderscoresToCamelCase(const string& input, bool cap_next_letter) {
119   string result;
120   // Note:  I distrust ctype.h due to locales.
121   for (int i = 0; i < input.size(); i++) {
122     if ('a' <= input[i] && input[i] <= 'z') {
123       if (cap_next_letter) {
124         result += input[i] + ('A' - 'a');
125       } else {
126         result += input[i];
127       }
128       cap_next_letter = false;
129     } else if ('A' <= input[i] && input[i] <= 'Z') {
130       if (i == 0 && !cap_next_letter) {
131         // Force first letter to lower-case unless explicitly told to
132         // capitalize it.
133         result += input[i] + ('a' - 'A');
134       } else {
135         // Capital letters after the first are left as-is.
136         result += input[i];
137       }
138       cap_next_letter = false;
139     } else if ('0' <= input[i] && input[i] <= '9') {
140       result += input[i];
141       cap_next_letter = true;
142     } else {
143       cap_next_letter = true;
144     }
145   }
146   // Add a trailing "_" if the name should be altered.
147   if (input[input.size() - 1] == '#') {
148     result += '_';
149   }
150   return result;
151 }
152 
UnderscoresToCamelCase(const FieldDescriptor * field)153 string UnderscoresToCamelCase(const FieldDescriptor* field) {
154   return UnderscoresToCamelCase(FieldName(field), false);
155 }
156 
UnderscoresToCapitalizedCamelCase(const FieldDescriptor * field)157 string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
158   return UnderscoresToCamelCase(FieldName(field), true);
159 }
160 
UnderscoresToCamelCase(const MethodDescriptor * method)161 string UnderscoresToCamelCase(const MethodDescriptor* method) {
162   return UnderscoresToCamelCase(method->name(), false);
163 }
164 
UniqueFileScopeIdentifier(const Descriptor * descriptor)165 string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
166   return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
167 }
168 
StripProto(const string & filename)169 string StripProto(const string& filename) {
170   if (HasSuffixString(filename, ".protodevel")) {
171     return StripSuffixString(filename, ".protodevel");
172   } else {
173     return StripSuffixString(filename, ".proto");
174   }
175 }
176 
FileClassName(const FileDescriptor * file,bool immutable)177 string FileClassName(const FileDescriptor* file, bool immutable) {
178   ClassNameResolver name_resolver;
179   return name_resolver.GetFileClassName(file, immutable);
180 }
181 
FileJavaPackage(const FileDescriptor * file,bool immutable)182 string FileJavaPackage(const FileDescriptor* file, bool immutable) {
183   string result;
184 
185   if (file->options().has_java_package()) {
186     result = file->options().java_package();
187   } else {
188     result = kDefaultPackage;
189     if (!file->package().empty()) {
190       if (!result.empty()) result += '.';
191       result += file->package();
192     }
193   }
194 
195   return result;
196 }
197 
JavaPackageToDir(string package_name)198 string JavaPackageToDir(string package_name) {
199   string package_dir =
200     StringReplace(package_name, ".", "/", true);
201   if (!package_dir.empty()) package_dir += "/";
202   return package_dir;
203 }
204 
205 // TODO(xiaofeng): This function is only kept for it's publicly referenced.
206 // It should be removed after mutable API up-integration.
ToJavaName(const string & full_name,const FileDescriptor * file)207 string ToJavaName(const string& full_name,
208                   const FileDescriptor* file) {
209   string result;
210   if (file->options().java_multiple_files()) {
211     result = FileJavaPackage(file);
212   } else {
213     result = ClassName(file);
214   }
215   if (!result.empty()) {
216     result += '.';
217   }
218   if (file->package().empty()) {
219     result += full_name;
220   } else {
221     // Strip the proto package from full_name since we've replaced it with
222     // the Java package.
223     result += full_name.substr(file->package().size() + 1);
224   }
225   return result;
226 }
227 
ClassName(const Descriptor * descriptor)228 string ClassName(const Descriptor* descriptor) {
229   ClassNameResolver name_resolver;
230   return name_resolver.GetClassName(descriptor, true);
231 }
232 
ClassName(const EnumDescriptor * descriptor)233 string ClassName(const EnumDescriptor* descriptor) {
234   ClassNameResolver name_resolver;
235   return name_resolver.GetClassName(descriptor, true);
236 }
237 
ClassName(const ServiceDescriptor * descriptor)238 string ClassName(const ServiceDescriptor* descriptor) {
239   ClassNameResolver name_resolver;
240   return name_resolver.GetClassName(descriptor, true);
241 }
242 
ClassName(const FileDescriptor * descriptor)243 string ClassName(const FileDescriptor* descriptor) {
244   ClassNameResolver name_resolver;
245   return name_resolver.GetClassName(descriptor, true);
246 }
247 
ExtraMessageInterfaces(const Descriptor * descriptor)248 string ExtraMessageInterfaces(const Descriptor* descriptor) {
249   string interfaces = "// @@protoc_insertion_point(message_implements:"
250       + descriptor->full_name() + ")";
251   return interfaces;
252 }
253 
254 
ExtraBuilderInterfaces(const Descriptor * descriptor)255 string ExtraBuilderInterfaces(const Descriptor* descriptor) {
256   string interfaces = "// @@protoc_insertion_point(builder_implements:"
257       + descriptor->full_name() + ")";
258   return interfaces;
259 }
260 
ExtraMessageOrBuilderInterfaces(const Descriptor * descriptor)261 string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor) {
262   string interfaces = "// @@protoc_insertion_point(interface_extends:"
263       + descriptor->full_name() + ")";
264   return interfaces;
265 }
266 
FieldConstantName(const FieldDescriptor * field)267 string FieldConstantName(const FieldDescriptor *field) {
268   string name = field->name() + "_FIELD_NUMBER";
269   UpperString(&name);
270   return name;
271 }
272 
GetType(const FieldDescriptor * field)273 FieldDescriptor::Type GetType(const FieldDescriptor* field) {
274   return field->type();
275 }
276 
GetJavaType(const FieldDescriptor * field)277 JavaType GetJavaType(const FieldDescriptor* field) {
278   switch (GetType(field)) {
279     case FieldDescriptor::TYPE_INT32:
280     case FieldDescriptor::TYPE_UINT32:
281     case FieldDescriptor::TYPE_SINT32:
282     case FieldDescriptor::TYPE_FIXED32:
283     case FieldDescriptor::TYPE_SFIXED32:
284       return JAVATYPE_INT;
285 
286     case FieldDescriptor::TYPE_INT64:
287     case FieldDescriptor::TYPE_UINT64:
288     case FieldDescriptor::TYPE_SINT64:
289     case FieldDescriptor::TYPE_FIXED64:
290     case FieldDescriptor::TYPE_SFIXED64:
291       return JAVATYPE_LONG;
292 
293     case FieldDescriptor::TYPE_FLOAT:
294       return JAVATYPE_FLOAT;
295 
296     case FieldDescriptor::TYPE_DOUBLE:
297       return JAVATYPE_DOUBLE;
298 
299     case FieldDescriptor::TYPE_BOOL:
300       return JAVATYPE_BOOLEAN;
301 
302     case FieldDescriptor::TYPE_STRING:
303       return JAVATYPE_STRING;
304 
305     case FieldDescriptor::TYPE_BYTES:
306       return JAVATYPE_BYTES;
307 
308     case FieldDescriptor::TYPE_ENUM:
309       return JAVATYPE_ENUM;
310 
311     case FieldDescriptor::TYPE_GROUP:
312     case FieldDescriptor::TYPE_MESSAGE:
313       return JAVATYPE_MESSAGE;
314 
315     // No default because we want the compiler to complain if any new
316     // types are added.
317   }
318 
319   GOOGLE_LOG(FATAL) << "Can't get here.";
320   return JAVATYPE_INT;
321 }
322 
PrimitiveTypeName(JavaType type)323 const char* PrimitiveTypeName(JavaType type) {
324   switch (type) {
325     case JAVATYPE_INT    : return "int";
326     case JAVATYPE_LONG   : return "long";
327     case JAVATYPE_FLOAT  : return "float";
328     case JAVATYPE_DOUBLE : return "double";
329     case JAVATYPE_BOOLEAN: return "boolean";
330     case JAVATYPE_STRING : return "java.lang.String";
331     case JAVATYPE_BYTES  : return "com.google.protobuf.ByteString";
332     case JAVATYPE_ENUM   : return NULL;
333     case JAVATYPE_MESSAGE: return NULL;
334 
335     // No default because we want the compiler to complain if any new
336     // JavaTypes are added.
337   }
338 
339   GOOGLE_LOG(FATAL) << "Can't get here.";
340   return NULL;
341 }
342 
BoxedPrimitiveTypeName(JavaType type)343 const char* BoxedPrimitiveTypeName(JavaType type) {
344   switch (type) {
345     case JAVATYPE_INT    : return "java.lang.Integer";
346     case JAVATYPE_LONG   : return "java.lang.Long";
347     case JAVATYPE_FLOAT  : return "java.lang.Float";
348     case JAVATYPE_DOUBLE : return "java.lang.Double";
349     case JAVATYPE_BOOLEAN: return "java.lang.Boolean";
350     case JAVATYPE_STRING : return "java.lang.String";
351     case JAVATYPE_BYTES  : return "com.google.protobuf.ByteString";
352     case JAVATYPE_ENUM   : return NULL;
353     case JAVATYPE_MESSAGE: return NULL;
354 
355     // No default because we want the compiler to complain if any new
356     // JavaTypes are added.
357   }
358 
359   GOOGLE_LOG(FATAL) << "Can't get here.";
360   return NULL;
361 }
362 
FieldTypeName(FieldDescriptor::Type field_type)363 const char* FieldTypeName(FieldDescriptor::Type field_type) {
364   switch (field_type) {
365     case FieldDescriptor::TYPE_INT32   : return "INT32";
366     case FieldDescriptor::TYPE_UINT32  : return "UINT32";
367     case FieldDescriptor::TYPE_SINT32  : return "SINT32";
368     case FieldDescriptor::TYPE_FIXED32 : return "FIXED32";
369     case FieldDescriptor::TYPE_SFIXED32: return "SFIXED32";
370     case FieldDescriptor::TYPE_INT64   : return "INT64";
371     case FieldDescriptor::TYPE_UINT64  : return "UINT64";
372     case FieldDescriptor::TYPE_SINT64  : return "SINT64";
373     case FieldDescriptor::TYPE_FIXED64 : return "FIXED64";
374     case FieldDescriptor::TYPE_SFIXED64: return "SFIXED64";
375     case FieldDescriptor::TYPE_FLOAT   : return "FLOAT";
376     case FieldDescriptor::TYPE_DOUBLE  : return "DOUBLE";
377     case FieldDescriptor::TYPE_BOOL    : return "BOOL";
378     case FieldDescriptor::TYPE_STRING  : return "STRING";
379     case FieldDescriptor::TYPE_BYTES   : return "BYTES";
380     case FieldDescriptor::TYPE_ENUM    : return "ENUM";
381     case FieldDescriptor::TYPE_GROUP   : return "GROUP";
382     case FieldDescriptor::TYPE_MESSAGE : return "MESSAGE";
383 
384     // No default because we want the compiler to complain if any new
385     // types are added.
386   }
387 
388   GOOGLE_LOG(FATAL) << "Can't get here.";
389   return NULL;
390 }
391 
AllAscii(const string & text)392 bool AllAscii(const string& text) {
393   for (int i = 0; i < text.size(); i++) {
394     if ((text[i] & 0x80) != 0) {
395       return false;
396     }
397   }
398   return true;
399 }
400 
DefaultValue(const FieldDescriptor * field,bool immutable,ClassNameResolver * name_resolver)401 string DefaultValue(const FieldDescriptor* field, bool immutable,
402                     ClassNameResolver* name_resolver) {
403   // Switch on CppType since we need to know which default_value_* method
404   // of FieldDescriptor to call.
405   switch (field->cpp_type()) {
406     case FieldDescriptor::CPPTYPE_INT32:
407       return SimpleItoa(field->default_value_int32());
408     case FieldDescriptor::CPPTYPE_UINT32:
409       // Need to print as a signed int since Java has no unsigned.
410       return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
411     case FieldDescriptor::CPPTYPE_INT64:
412       return SimpleItoa(field->default_value_int64()) + "L";
413     case FieldDescriptor::CPPTYPE_UINT64:
414       return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
415              "L";
416     case FieldDescriptor::CPPTYPE_DOUBLE: {
417       double value = field->default_value_double();
418       if (value == numeric_limits<double>::infinity()) {
419         return "Double.POSITIVE_INFINITY";
420       } else if (value == -numeric_limits<double>::infinity()) {
421         return "Double.NEGATIVE_INFINITY";
422       } else if (value != value) {
423         return "Double.NaN";
424       } else {
425         return SimpleDtoa(value) + "D";
426       }
427     }
428     case FieldDescriptor::CPPTYPE_FLOAT: {
429       float value = field->default_value_float();
430       if (value == numeric_limits<float>::infinity()) {
431         return "Float.POSITIVE_INFINITY";
432       } else if (value == -numeric_limits<float>::infinity()) {
433         return "Float.NEGATIVE_INFINITY";
434       } else if (value != value) {
435         return "Float.NaN";
436       } else {
437         return SimpleFtoa(value) + "F";
438       }
439     }
440     case FieldDescriptor::CPPTYPE_BOOL:
441       return field->default_value_bool() ? "true" : "false";
442     case FieldDescriptor::CPPTYPE_STRING:
443       if (GetType(field) == FieldDescriptor::TYPE_BYTES) {
444         if (field->has_default_value()) {
445           // See comments in Internal.java for gory details.
446           return strings::Substitute(
447             "com.google.protobuf.Internal.bytesDefaultValue(\"$0\")",
448             CEscape(field->default_value_string()));
449         } else {
450           return "com.google.protobuf.ByteString.EMPTY";
451         }
452       } else {
453         if (AllAscii(field->default_value_string())) {
454           // All chars are ASCII.  In this case CEscape() works fine.
455           return "\"" + CEscape(field->default_value_string()) + "\"";
456         } else {
457           // See comments in Internal.java for gory details.
458           return strings::Substitute(
459               "com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
460               CEscape(field->default_value_string()));
461         }
462       }
463 
464     case FieldDescriptor::CPPTYPE_ENUM:
465       return name_resolver->GetClassName(field->enum_type(), immutable) + "." +
466           field->default_value_enum()->name();
467 
468     case FieldDescriptor::CPPTYPE_MESSAGE:
469       return name_resolver->GetClassName(field->message_type(), immutable) +
470           ".getDefaultInstance()";
471 
472     // No default because we want the compiler to complain if any new
473     // types are added.
474   }
475 
476   GOOGLE_LOG(FATAL) << "Can't get here.";
477   return "";
478 }
479 
IsDefaultValueJavaDefault(const FieldDescriptor * field)480 bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
481   // Switch on CppType since we need to know which default_value_* method
482   // of FieldDescriptor to call.
483   switch (field->cpp_type()) {
484     case FieldDescriptor::CPPTYPE_INT32:
485       return field->default_value_int32() == 0;
486     case FieldDescriptor::CPPTYPE_UINT32:
487       return field->default_value_uint32() == 0;
488     case FieldDescriptor::CPPTYPE_INT64:
489       return field->default_value_int64() == 0L;
490     case FieldDescriptor::CPPTYPE_UINT64:
491       return field->default_value_uint64() == 0L;
492     case FieldDescriptor::CPPTYPE_DOUBLE:
493       return field->default_value_double() == 0.0;
494     case FieldDescriptor::CPPTYPE_FLOAT:
495       return field->default_value_float() == 0.0;
496     case FieldDescriptor::CPPTYPE_BOOL:
497       return field->default_value_bool() == false;
498     case FieldDescriptor::CPPTYPE_ENUM:
499       return field->default_value_enum()->number() == 0;
500     case FieldDescriptor::CPPTYPE_STRING:
501     case FieldDescriptor::CPPTYPE_MESSAGE:
502       return false;
503 
504     // No default because we want the compiler to complain if any new
505     // types are added.
506   }
507 
508   GOOGLE_LOG(FATAL) << "Can't get here.";
509   return false;
510 }
511 
IsByteStringWithCustomDefaultValue(const FieldDescriptor * field)512 bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field) {
513   return GetJavaType(field) == JAVATYPE_BYTES &&
514          field->default_value_string() != "";
515 }
516 
517 const char* bit_masks[] = {
518   "0x00000001",
519   "0x00000002",
520   "0x00000004",
521   "0x00000008",
522   "0x00000010",
523   "0x00000020",
524   "0x00000040",
525   "0x00000080",
526 
527   "0x00000100",
528   "0x00000200",
529   "0x00000400",
530   "0x00000800",
531   "0x00001000",
532   "0x00002000",
533   "0x00004000",
534   "0x00008000",
535 
536   "0x00010000",
537   "0x00020000",
538   "0x00040000",
539   "0x00080000",
540   "0x00100000",
541   "0x00200000",
542   "0x00400000",
543   "0x00800000",
544 
545   "0x01000000",
546   "0x02000000",
547   "0x04000000",
548   "0x08000000",
549   "0x10000000",
550   "0x20000000",
551   "0x40000000",
552   "0x80000000",
553 };
554 
GetBitFieldName(int index)555 string GetBitFieldName(int index) {
556   string varName = "bitField";
557   varName += SimpleItoa(index);
558   varName += "_";
559   return varName;
560 }
561 
GetBitFieldNameForBit(int bitIndex)562 string GetBitFieldNameForBit(int bitIndex) {
563   return GetBitFieldName(bitIndex / 32);
564 }
565 
566 namespace {
567 
GenerateGetBitInternal(const string & prefix,int bitIndex)568 string GenerateGetBitInternal(const string& prefix, int bitIndex) {
569   string varName = prefix + GetBitFieldNameForBit(bitIndex);
570   int bitInVarIndex = bitIndex % 32;
571 
572   string mask = bit_masks[bitInVarIndex];
573   string result = "((" + varName + " & " + mask + ") == " + mask + ")";
574   return result;
575 }
576 
GenerateSetBitInternal(const string & prefix,int bitIndex)577 string GenerateSetBitInternal(const string& prefix, int bitIndex) {
578   string varName = prefix + GetBitFieldNameForBit(bitIndex);
579   int bitInVarIndex = bitIndex % 32;
580 
581   string mask = bit_masks[bitInVarIndex];
582   string result = varName + " |= " + mask;
583   return result;
584 }
585 
586 }  // namespace
587 
GenerateGetBit(int bitIndex)588 string GenerateGetBit(int bitIndex) {
589   return GenerateGetBitInternal("", bitIndex);
590 }
591 
GenerateSetBit(int bitIndex)592 string GenerateSetBit(int bitIndex) {
593   return GenerateSetBitInternal("", bitIndex);
594 }
595 
GenerateClearBit(int bitIndex)596 string GenerateClearBit(int bitIndex) {
597   string varName = GetBitFieldNameForBit(bitIndex);
598   int bitInVarIndex = bitIndex % 32;
599 
600   string mask = bit_masks[bitInVarIndex];
601   string result = varName + " = (" + varName + " & ~" + mask + ")";
602   return result;
603 }
604 
GenerateGetBitFromLocal(int bitIndex)605 string GenerateGetBitFromLocal(int bitIndex) {
606   return GenerateGetBitInternal("from_", bitIndex);
607 }
608 
GenerateSetBitToLocal(int bitIndex)609 string GenerateSetBitToLocal(int bitIndex) {
610   return GenerateSetBitInternal("to_", bitIndex);
611 }
612 
GenerateGetBitMutableLocal(int bitIndex)613 string GenerateGetBitMutableLocal(int bitIndex) {
614   return GenerateGetBitInternal("mutable_", bitIndex);
615 }
616 
GenerateSetBitMutableLocal(int bitIndex)617 string GenerateSetBitMutableLocal(int bitIndex) {
618   return GenerateSetBitInternal("mutable_", bitIndex);
619 }
620 
IsReferenceType(JavaType type)621 bool IsReferenceType(JavaType type) {
622   switch (type) {
623     case JAVATYPE_INT    : return false;
624     case JAVATYPE_LONG   : return false;
625     case JAVATYPE_FLOAT  : return false;
626     case JAVATYPE_DOUBLE : return false;
627     case JAVATYPE_BOOLEAN: return false;
628     case JAVATYPE_STRING : return true;
629     case JAVATYPE_BYTES  : return true;
630     case JAVATYPE_ENUM   : return true;
631     case JAVATYPE_MESSAGE: return true;
632 
633     // No default because we want the compiler to complain if any new
634     // JavaTypes are added.
635   }
636 
637   GOOGLE_LOG(FATAL) << "Can't get here.";
638   return false;
639 }
640 
GetCapitalizedType(const FieldDescriptor * field,bool immutable)641 const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable) {
642   switch (GetType(field)) {
643     case FieldDescriptor::TYPE_INT32   : return "Int32";
644     case FieldDescriptor::TYPE_UINT32  : return "UInt32";
645     case FieldDescriptor::TYPE_SINT32  : return "SInt32";
646     case FieldDescriptor::TYPE_FIXED32 : return "Fixed32";
647     case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
648     case FieldDescriptor::TYPE_INT64   : return "Int64";
649     case FieldDescriptor::TYPE_UINT64  : return "UInt64";
650     case FieldDescriptor::TYPE_SINT64  : return "SInt64";
651     case FieldDescriptor::TYPE_FIXED64 : return "Fixed64";
652     case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
653     case FieldDescriptor::TYPE_FLOAT   : return "Float";
654     case FieldDescriptor::TYPE_DOUBLE  : return "Double";
655     case FieldDescriptor::TYPE_BOOL    : return "Bool";
656     case FieldDescriptor::TYPE_STRING  : return "String";
657     case FieldDescriptor::TYPE_BYTES   : {
658       return "Bytes";
659     }
660     case FieldDescriptor::TYPE_ENUM    : return "Enum";
661     case FieldDescriptor::TYPE_GROUP   : return "Group";
662     case FieldDescriptor::TYPE_MESSAGE : return "Message";
663 
664     // No default because we want the compiler to complain if any new
665     // types are added.
666   }
667 
668   GOOGLE_LOG(FATAL) << "Can't get here.";
669   return NULL;
670 }
671 
672 // For encodings with fixed sizes, returns that size in bytes.  Otherwise
673 // returns -1.
FixedSize(FieldDescriptor::Type type)674 int FixedSize(FieldDescriptor::Type type) {
675   switch (type) {
676     case FieldDescriptor::TYPE_INT32   : return -1;
677     case FieldDescriptor::TYPE_INT64   : return -1;
678     case FieldDescriptor::TYPE_UINT32  : return -1;
679     case FieldDescriptor::TYPE_UINT64  : return -1;
680     case FieldDescriptor::TYPE_SINT32  : return -1;
681     case FieldDescriptor::TYPE_SINT64  : return -1;
682     case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
683     case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
684     case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
685     case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
686     case FieldDescriptor::TYPE_FLOAT   : return WireFormatLite::kFloatSize;
687     case FieldDescriptor::TYPE_DOUBLE  : return WireFormatLite::kDoubleSize;
688 
689     case FieldDescriptor::TYPE_BOOL    : return WireFormatLite::kBoolSize;
690     case FieldDescriptor::TYPE_ENUM    : return -1;
691 
692     case FieldDescriptor::TYPE_STRING  : return -1;
693     case FieldDescriptor::TYPE_BYTES   : return -1;
694     case FieldDescriptor::TYPE_GROUP   : return -1;
695     case FieldDescriptor::TYPE_MESSAGE : return -1;
696 
697     // No default because we want the compiler to complain if any new
698     // types are added.
699   }
700   GOOGLE_LOG(FATAL) << "Can't get here.";
701   return -1;
702 }
703 
704 // Sort the fields of the given Descriptor by number into a new[]'d array
705 // and return it. The caller should delete the returned array.
SortFieldsByNumber(const Descriptor * descriptor)706 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
707   const FieldDescriptor** fields =
708     new const FieldDescriptor*[descriptor->field_count()];
709   for (int i = 0; i < descriptor->field_count(); i++) {
710     fields[i] = descriptor->field(i);
711   }
712   std::sort(fields, fields + descriptor->field_count(),
713             FieldOrderingByNumber());
714   return fields;
715 }
716 
717 // Returns true if the message type has any required fields.  If it doesn't,
718 // we can optimize out calls to its isInitialized() method.
719 //
720 // already_seen is used to avoid checking the same type multiple times
721 // (and also to protect against recursion).
HasRequiredFields(const Descriptor * type,hash_set<const Descriptor * > * already_seen)722 bool HasRequiredFields(
723     const Descriptor* type,
724     hash_set<const Descriptor*>* already_seen) {
725   if (already_seen->count(type) > 0) {
726     // The type is already in cache.  This means that either:
727     // a. The type has no required fields.
728     // b. We are in the midst of checking if the type has required fields,
729     //    somewhere up the stack.  In this case, we know that if the type
730     //    has any required fields, they'll be found when we return to it,
731     //    and the whole call to HasRequiredFields() will return true.
732     //    Therefore, we don't have to check if this type has required fields
733     //    here.
734     return false;
735   }
736   already_seen->insert(type);
737 
738   // If the type has extensions, an extension with message type could contain
739   // required fields, so we have to be conservative and assume such an
740   // extension exists.
741   if (type->extension_range_count() > 0) return true;
742 
743   for (int i = 0; i < type->field_count(); i++) {
744     const FieldDescriptor* field = type->field(i);
745     if (field->is_required()) {
746       return true;
747     }
748     if (GetJavaType(field) == JAVATYPE_MESSAGE) {
749       if (HasRequiredFields(field->message_type(), already_seen)) {
750         return true;
751       }
752     }
753   }
754 
755   return false;
756 }
757 
HasRequiredFields(const Descriptor * type)758 bool HasRequiredFields(const Descriptor* type) {
759   hash_set<const Descriptor*> already_seen;
760   return HasRequiredFields(type, &already_seen);
761 }
762 
HasRepeatedFields(const Descriptor * descriptor)763 bool HasRepeatedFields(const Descriptor* descriptor) {
764   for (int i = 0; i < descriptor->field_count(); ++i) {
765     const FieldDescriptor* field = descriptor->field(i);
766     if (field->is_repeated()) {
767       return true;
768     }
769   }
770   return false;
771 }
772 
773 }  // namespace java
774 }  // namespace compiler
775 }  // namespace protobuf
776 }  // namespace google
777