• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <google/protobuf/compiler/java/java_helpers.h>
36 
37 #include <algorithm>
38 #include <limits>
39 #include <unordered_set>
40 #include <vector>
41 
42 #include <google/protobuf/stubs/stringprintf.h>
43 #include <google/protobuf/compiler/java/java_name_resolver.h>
44 #include <google/protobuf/descriptor.pb.h>
45 #include <google/protobuf/wire_format.h>
46 #include <google/protobuf/stubs/strutil.h>
47 #include <google/protobuf/stubs/substitute.h>
48 #include <google/protobuf/stubs/hash.h>  // for hash<T *>
49 
50 namespace google {
51 namespace protobuf {
52 namespace compiler {
53 namespace java {
54 
55 using internal::WireFormat;
56 using internal::WireFormatLite;
57 
58 const char kThickSeparator[] =
59     "// ===================================================================\n";
60 const char kThinSeparator[] =
61     "// -------------------------------------------------------------------\n";
62 
63 namespace {
64 
65 const char* kDefaultPackage = "";
66 
67 // Names that should be avoided as field names.
68 // Using them will cause the compiler to generate accessors whose names are
69 // colliding with methods defined in base classes.
70 const char* kForbiddenWordList[] = {
71     // message base class:
72     "cached_size",
73     "serialized_size",
74     // java.lang.Object:
75     "class",
76 };
77 
78 const std::unordered_set<std::string>* kReservedNames =
79     new std::unordered_set<std::string>({
80         "abstract",   "assert",       "boolean",   "break",      "byte",
81         "case",       "catch",        "char",      "class",      "const",
82         "continue",   "default",      "do",        "double",     "else",
83         "enum",       "extends",      "final",     "finally",    "float",
84         "for",        "goto",         "if",        "implements", "import",
85         "instanceof", "int",          "interface", "long",       "native",
86         "new",        "package",      "private",   "protected",  "public",
87         "return",     "short",        "static",    "strictfp",   "super",
88         "switch",     "synchronized", "this",      "throw",      "throws",
89         "transient",  "try",          "void",      "volatile",   "while",
90     });
91 
IsForbidden(const std::string & field_name)92 bool IsForbidden(const std::string& field_name) {
93   for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) {
94     if (field_name == kForbiddenWordList[i]) {
95       return true;
96     }
97   }
98   return false;
99 }
100 
FieldName(const FieldDescriptor * field)101 std::string FieldName(const FieldDescriptor* field) {
102   std::string field_name;
103   // Groups are hacky:  The name of the field is just the lower-cased name
104   // of the group type.  In Java, though, we would like to retain the original
105   // capitalization of the type name.
106   if (GetType(field) == FieldDescriptor::TYPE_GROUP) {
107     field_name = field->message_type()->name();
108   } else {
109     field_name = field->name();
110   }
111   if (IsForbidden(field_name)) {
112     // Append a trailing "#" to indicate that the name should be decorated to
113     // avoid collision with other names.
114     field_name += "#";
115   }
116   return field_name;
117 }
118 
119 
120 }  // namespace
121 
PrintGeneratedAnnotation(io::Printer * printer,char delimiter,const std::string & annotation_file)122 void PrintGeneratedAnnotation(io::Printer* printer, char delimiter,
123                               const std::string& annotation_file) {
124   if (annotation_file.empty()) {
125     return;
126   }
127   std::string ptemplate =
128       "@javax.annotation.Generated(value=\"protoc\", comments=\"annotations:";
129   ptemplate.push_back(delimiter);
130   ptemplate.append("annotation_file");
131   ptemplate.push_back(delimiter);
132   ptemplate.append("\")\n");
133   printer->Print(ptemplate.c_str(), "annotation_file", annotation_file);
134 }
135 
PrintEnumVerifierLogic(io::Printer * printer,const FieldDescriptor * descriptor,const std::map<std::string,std::string> & variables,const char * var_name,const char * terminating_string,bool enforce_lite)136 void PrintEnumVerifierLogic(io::Printer* printer,
137                             const FieldDescriptor* descriptor,
138                             const std::map<std::string, std::string>& variables,
139                             const char* var_name,
140                             const char* terminating_string, bool enforce_lite) {
141   std::string enum_verifier_string =
142       enforce_lite ? StrCat(var_name, ".internalGetVerifier()")
143                    : StrCat(
144                          "new com.google.protobuf.Internal.EnumVerifier() {\n"
145                          "        @java.lang.Override\n"
146                          "        public boolean isInRange(int number) {\n"
147                          "          return ",
148                          var_name,
149                          ".forNumber(number) != null;\n"
150                          "        }\n"
151                          "      }");
152   printer->Print(
153       variables,
154       StrCat(enum_verifier_string, terminating_string).c_str());
155 }
156 
UnderscoresToCamelCase(const std::string & input,bool cap_next_letter)157 std::string UnderscoresToCamelCase(const std::string& input,
158                                    bool cap_next_letter) {
159   GOOGLE_CHECK(!input.empty());
160   std::string result;
161   // Note:  I distrust ctype.h due to locales.
162   for (int i = 0; i < input.size(); i++) {
163     if ('a' <= input[i] && input[i] <= 'z') {
164       if (cap_next_letter) {
165         result += input[i] + ('A' - 'a');
166       } else {
167         result += input[i];
168       }
169       cap_next_letter = false;
170     } else if ('A' <= input[i] && input[i] <= 'Z') {
171       if (i == 0 && !cap_next_letter) {
172         // Force first letter to lower-case unless explicitly told to
173         // capitalize it.
174         result += input[i] + ('a' - 'A');
175       } else {
176         // Capital letters after the first are left as-is.
177         result += input[i];
178       }
179       cap_next_letter = false;
180     } else if ('0' <= input[i] && input[i] <= '9') {
181       result += input[i];
182       cap_next_letter = true;
183     } else {
184       cap_next_letter = true;
185     }
186   }
187   // Add a trailing "_" if the name should be altered.
188   if (input[input.size() - 1] == '#') {
189     result += '_';
190   }
191   return result;
192 }
193 
UnderscoresToCamelCase(const FieldDescriptor * field)194 std::string UnderscoresToCamelCase(const FieldDescriptor* field) {
195   return UnderscoresToCamelCase(FieldName(field), false);
196 }
197 
UnderscoresToCapitalizedCamelCase(const FieldDescriptor * field)198 std::string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
199   return UnderscoresToCamelCase(FieldName(field), true);
200 }
201 
CapitalizedFieldName(const FieldDescriptor * field)202 std::string CapitalizedFieldName(const FieldDescriptor* field) {
203   return UnderscoresToCapitalizedCamelCase(field);
204 }
205 
UnderscoresToCamelCase(const MethodDescriptor * method)206 std::string UnderscoresToCamelCase(const MethodDescriptor* method) {
207   return UnderscoresToCamelCase(method->name(), false);
208 }
209 
UnderscoresToCamelCaseCheckReserved(const FieldDescriptor * field)210 std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field) {
211   std::string name = UnderscoresToCamelCase(field);
212   if (kReservedNames->find(name) != kReservedNames->end()) {
213     return name + "_";
214   }
215   return name;
216 }
217 
UniqueFileScopeIdentifier(const Descriptor * descriptor)218 std::string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
219   return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
220 }
221 
CamelCaseFieldName(const FieldDescriptor * field)222 std::string CamelCaseFieldName(const FieldDescriptor* field) {
223   std::string fieldName = UnderscoresToCamelCase(field);
224   if ('0' <= fieldName[0] && fieldName[0] <= '9') {
225     return '_' + fieldName;
226   }
227   return fieldName;
228 }
229 
StripProto(const std::string & filename)230 std::string StripProto(const std::string& filename) {
231   if (HasSuffixString(filename, ".protodevel")) {
232     return StripSuffixString(filename, ".protodevel");
233   } else {
234     return StripSuffixString(filename, ".proto");
235   }
236 }
237 
FileClassName(const FileDescriptor * file,bool immutable)238 std::string FileClassName(const FileDescriptor* file, bool immutable) {
239   ClassNameResolver name_resolver;
240   return name_resolver.GetFileClassName(file, immutable);
241 }
242 
FileJavaPackage(const FileDescriptor * file,bool immutable)243 std::string FileJavaPackage(const FileDescriptor* file, bool immutable) {
244   std::string result;
245 
246   if (file->options().has_java_package()) {
247     result = file->options().java_package();
248   } else {
249     result = kDefaultPackage;
250     if (!file->package().empty()) {
251       if (!result.empty()) result += '.';
252       result += file->package();
253     }
254   }
255 
256   return result;
257 }
258 
FileJavaPackage(const FileDescriptor * file)259 std::string FileJavaPackage(const FileDescriptor* file) {
260   return FileJavaPackage(file, true /* immutable */);
261 }
262 
JavaPackageToDir(std::string package_name)263 std::string JavaPackageToDir(std::string package_name) {
264   std::string package_dir = StringReplace(package_name, ".", "/", true);
265   if (!package_dir.empty()) package_dir += "/";
266   return package_dir;
267 }
268 
ClassName(const Descriptor * descriptor)269 std::string ClassName(const Descriptor* descriptor) {
270   ClassNameResolver name_resolver;
271   return name_resolver.GetClassName(descriptor, true);
272 }
273 
ClassName(const EnumDescriptor * descriptor)274 std::string ClassName(const EnumDescriptor* descriptor) {
275   ClassNameResolver name_resolver;
276   return name_resolver.GetClassName(descriptor, true);
277 }
278 
ClassName(const ServiceDescriptor * descriptor)279 std::string ClassName(const ServiceDescriptor* descriptor) {
280   ClassNameResolver name_resolver;
281   return name_resolver.GetClassName(descriptor, true);
282 }
283 
ClassName(const FileDescriptor * descriptor)284 std::string ClassName(const FileDescriptor* descriptor) {
285   ClassNameResolver name_resolver;
286   return name_resolver.GetClassName(descriptor, true);
287 }
288 
289 
ExtraMessageInterfaces(const Descriptor * descriptor)290 std::string ExtraMessageInterfaces(const Descriptor* descriptor) {
291   std::string interfaces = "// @@protoc_insertion_point(message_implements:" +
292                            descriptor->full_name() + ")";
293   return interfaces;
294 }
295 
296 
ExtraBuilderInterfaces(const Descriptor * descriptor)297 std::string ExtraBuilderInterfaces(const Descriptor* descriptor) {
298   std::string interfaces = "// @@protoc_insertion_point(builder_implements:" +
299                            descriptor->full_name() + ")";
300   return interfaces;
301 }
302 
ExtraMessageOrBuilderInterfaces(const Descriptor * descriptor)303 std::string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor) {
304   std::string interfaces = "// @@protoc_insertion_point(interface_extends:" +
305                            descriptor->full_name() + ")";
306   return interfaces;
307 }
308 
FieldConstantName(const FieldDescriptor * field)309 std::string FieldConstantName(const FieldDescriptor* field) {
310   std::string name = field->name() + "_FIELD_NUMBER";
311   ToUpper(&name);
312   return name;
313 }
314 
GetType(const FieldDescriptor * field)315 FieldDescriptor::Type GetType(const FieldDescriptor* field) {
316   return field->type();
317 }
318 
GetJavaType(const FieldDescriptor * field)319 JavaType GetJavaType(const FieldDescriptor* field) {
320   switch (GetType(field)) {
321     case FieldDescriptor::TYPE_INT32:
322     case FieldDescriptor::TYPE_UINT32:
323     case FieldDescriptor::TYPE_SINT32:
324     case FieldDescriptor::TYPE_FIXED32:
325     case FieldDescriptor::TYPE_SFIXED32:
326       return JAVATYPE_INT;
327 
328     case FieldDescriptor::TYPE_INT64:
329     case FieldDescriptor::TYPE_UINT64:
330     case FieldDescriptor::TYPE_SINT64:
331     case FieldDescriptor::TYPE_FIXED64:
332     case FieldDescriptor::TYPE_SFIXED64:
333       return JAVATYPE_LONG;
334 
335     case FieldDescriptor::TYPE_FLOAT:
336       return JAVATYPE_FLOAT;
337 
338     case FieldDescriptor::TYPE_DOUBLE:
339       return JAVATYPE_DOUBLE;
340 
341     case FieldDescriptor::TYPE_BOOL:
342       return JAVATYPE_BOOLEAN;
343 
344     case FieldDescriptor::TYPE_STRING:
345       return JAVATYPE_STRING;
346 
347     case FieldDescriptor::TYPE_BYTES:
348       return JAVATYPE_BYTES;
349 
350     case FieldDescriptor::TYPE_ENUM:
351       return JAVATYPE_ENUM;
352 
353     case FieldDescriptor::TYPE_GROUP:
354     case FieldDescriptor::TYPE_MESSAGE:
355       return JAVATYPE_MESSAGE;
356 
357       // No default because we want the compiler to complain if any new
358       // types are added.
359   }
360 
361   GOOGLE_LOG(FATAL) << "Can't get here.";
362   return JAVATYPE_INT;
363 }
364 
PrimitiveTypeName(JavaType type)365 const char* PrimitiveTypeName(JavaType type) {
366   switch (type) {
367     case JAVATYPE_INT:
368       return "int";
369     case JAVATYPE_LONG:
370       return "long";
371     case JAVATYPE_FLOAT:
372       return "float";
373     case JAVATYPE_DOUBLE:
374       return "double";
375     case JAVATYPE_BOOLEAN:
376       return "boolean";
377     case JAVATYPE_STRING:
378       return "java.lang.String";
379     case JAVATYPE_BYTES:
380       return "com.google.protobuf.ByteString";
381     case JAVATYPE_ENUM:
382       return NULL;
383     case JAVATYPE_MESSAGE:
384       return NULL;
385 
386       // No default because we want the compiler to complain if any new
387       // JavaTypes are added.
388   }
389 
390   GOOGLE_LOG(FATAL) << "Can't get here.";
391   return NULL;
392 }
393 
PrimitiveTypeName(const FieldDescriptor * descriptor)394 const char* PrimitiveTypeName(const FieldDescriptor* descriptor) {
395   return PrimitiveTypeName(GetJavaType(descriptor));
396 }
397 
BoxedPrimitiveTypeName(JavaType type)398 const char* BoxedPrimitiveTypeName(JavaType type) {
399   switch (type) {
400     case JAVATYPE_INT:
401       return "java.lang.Integer";
402     case JAVATYPE_LONG:
403       return "java.lang.Long";
404     case JAVATYPE_FLOAT:
405       return "java.lang.Float";
406     case JAVATYPE_DOUBLE:
407       return "java.lang.Double";
408     case JAVATYPE_BOOLEAN:
409       return "java.lang.Boolean";
410     case JAVATYPE_STRING:
411       return "java.lang.String";
412     case JAVATYPE_BYTES:
413       return "com.google.protobuf.ByteString";
414     case JAVATYPE_ENUM:
415       return NULL;
416     case JAVATYPE_MESSAGE:
417       return NULL;
418 
419       // No default because we want the compiler to complain if any new
420       // JavaTypes are added.
421   }
422 
423   GOOGLE_LOG(FATAL) << "Can't get here.";
424   return NULL;
425 }
426 
BoxedPrimitiveTypeName(const FieldDescriptor * descriptor)427 const char* BoxedPrimitiveTypeName(const FieldDescriptor* descriptor) {
428   return BoxedPrimitiveTypeName(GetJavaType(descriptor));
429 }
430 
431 
GetOneofStoredType(const FieldDescriptor * field)432 std::string GetOneofStoredType(const FieldDescriptor* field) {
433   const JavaType javaType = GetJavaType(field);
434   switch (javaType) {
435     case JAVATYPE_ENUM:
436       return "java.lang.Integer";
437     case JAVATYPE_MESSAGE:
438       return ClassName(field->message_type());
439     default:
440       return BoxedPrimitiveTypeName(javaType);
441   }
442 }
443 
FieldTypeName(FieldDescriptor::Type field_type)444 const char* FieldTypeName(FieldDescriptor::Type field_type) {
445   switch (field_type) {
446     case FieldDescriptor::TYPE_INT32:
447       return "INT32";
448     case FieldDescriptor::TYPE_UINT32:
449       return "UINT32";
450     case FieldDescriptor::TYPE_SINT32:
451       return "SINT32";
452     case FieldDescriptor::TYPE_FIXED32:
453       return "FIXED32";
454     case FieldDescriptor::TYPE_SFIXED32:
455       return "SFIXED32";
456     case FieldDescriptor::TYPE_INT64:
457       return "INT64";
458     case FieldDescriptor::TYPE_UINT64:
459       return "UINT64";
460     case FieldDescriptor::TYPE_SINT64:
461       return "SINT64";
462     case FieldDescriptor::TYPE_FIXED64:
463       return "FIXED64";
464     case FieldDescriptor::TYPE_SFIXED64:
465       return "SFIXED64";
466     case FieldDescriptor::TYPE_FLOAT:
467       return "FLOAT";
468     case FieldDescriptor::TYPE_DOUBLE:
469       return "DOUBLE";
470     case FieldDescriptor::TYPE_BOOL:
471       return "BOOL";
472     case FieldDescriptor::TYPE_STRING:
473       return "STRING";
474     case FieldDescriptor::TYPE_BYTES:
475       return "BYTES";
476     case FieldDescriptor::TYPE_ENUM:
477       return "ENUM";
478     case FieldDescriptor::TYPE_GROUP:
479       return "GROUP";
480     case FieldDescriptor::TYPE_MESSAGE:
481       return "MESSAGE";
482 
483       // No default because we want the compiler to complain if any new
484       // types are added.
485   }
486 
487   GOOGLE_LOG(FATAL) << "Can't get here.";
488   return NULL;
489 }
490 
AllAscii(const std::string & text)491 bool AllAscii(const std::string& text) {
492   for (int i = 0; i < text.size(); i++) {
493     if ((text[i] & 0x80) != 0) {
494       return false;
495     }
496   }
497   return true;
498 }
499 
DefaultValue(const FieldDescriptor * field,bool immutable,ClassNameResolver * name_resolver)500 std::string DefaultValue(const FieldDescriptor* field, bool immutable,
501                          ClassNameResolver* name_resolver) {
502   // Switch on CppType since we need to know which default_value_* method
503   // of FieldDescriptor to call.
504   switch (field->cpp_type()) {
505     case FieldDescriptor::CPPTYPE_INT32:
506       return StrCat(field->default_value_int32());
507     case FieldDescriptor::CPPTYPE_UINT32:
508       // Need to print as a signed int since Java has no unsigned.
509       return StrCat(static_cast<int32>(field->default_value_uint32()));
510     case FieldDescriptor::CPPTYPE_INT64:
511       return StrCat(field->default_value_int64()) + "L";
512     case FieldDescriptor::CPPTYPE_UINT64:
513       return StrCat(static_cast<int64>(field->default_value_uint64())) +
514              "L";
515     case FieldDescriptor::CPPTYPE_DOUBLE: {
516       double value = field->default_value_double();
517       if (value == std::numeric_limits<double>::infinity()) {
518         return "Double.POSITIVE_INFINITY";
519       } else if (value == -std::numeric_limits<double>::infinity()) {
520         return "Double.NEGATIVE_INFINITY";
521       } else if (value != value) {
522         return "Double.NaN";
523       } else {
524         return SimpleDtoa(value) + "D";
525       }
526     }
527     case FieldDescriptor::CPPTYPE_FLOAT: {
528       float value = field->default_value_float();
529       if (value == std::numeric_limits<float>::infinity()) {
530         return "Float.POSITIVE_INFINITY";
531       } else if (value == -std::numeric_limits<float>::infinity()) {
532         return "Float.NEGATIVE_INFINITY";
533       } else if (value != value) {
534         return "Float.NaN";
535       } else {
536         return SimpleFtoa(value) + "F";
537       }
538     }
539     case FieldDescriptor::CPPTYPE_BOOL:
540       return field->default_value_bool() ? "true" : "false";
541     case FieldDescriptor::CPPTYPE_STRING:
542       if (GetType(field) == FieldDescriptor::TYPE_BYTES) {
543         if (field->has_default_value()) {
544           // See comments in Internal.java for gory details.
545           return strings::Substitute(
546               "com.google.protobuf.Internal.bytesDefaultValue(\"$0\")",
547               CEscape(field->default_value_string()));
548         } else {
549           return "com.google.protobuf.ByteString.EMPTY";
550         }
551       } else {
552         if (AllAscii(field->default_value_string())) {
553           // All chars are ASCII.  In this case CEscape() works fine.
554           return "\"" + CEscape(field->default_value_string()) + "\"";
555         } else {
556           // See comments in Internal.java for gory details.
557           return strings::Substitute(
558               "com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
559               CEscape(field->default_value_string()));
560         }
561       }
562 
563     case FieldDescriptor::CPPTYPE_ENUM:
564       return name_resolver->GetClassName(field->enum_type(), immutable) + "." +
565              field->default_value_enum()->name();
566 
567     case FieldDescriptor::CPPTYPE_MESSAGE:
568       return name_resolver->GetClassName(field->message_type(), immutable) +
569              ".getDefaultInstance()";
570 
571       // No default because we want the compiler to complain if any new
572       // types are added.
573   }
574 
575   GOOGLE_LOG(FATAL) << "Can't get here.";
576   return "";
577 }
578 
IsDefaultValueJavaDefault(const FieldDescriptor * field)579 bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
580   // Switch on CppType since we need to know which default_value_* method
581   // of FieldDescriptor to call.
582   switch (field->cpp_type()) {
583     case FieldDescriptor::CPPTYPE_INT32:
584       return field->default_value_int32() == 0;
585     case FieldDescriptor::CPPTYPE_UINT32:
586       return field->default_value_uint32() == 0;
587     case FieldDescriptor::CPPTYPE_INT64:
588       return field->default_value_int64() == 0L;
589     case FieldDescriptor::CPPTYPE_UINT64:
590       return field->default_value_uint64() == 0L;
591     case FieldDescriptor::CPPTYPE_DOUBLE:
592       return field->default_value_double() == 0.0;
593     case FieldDescriptor::CPPTYPE_FLOAT:
594       return field->default_value_float() == 0.0;
595     case FieldDescriptor::CPPTYPE_BOOL:
596       return field->default_value_bool() == false;
597     case FieldDescriptor::CPPTYPE_ENUM:
598       return field->default_value_enum()->number() == 0;
599     case FieldDescriptor::CPPTYPE_STRING:
600     case FieldDescriptor::CPPTYPE_MESSAGE:
601       return false;
602 
603       // No default because we want the compiler to complain if any new
604       // types are added.
605   }
606 
607   GOOGLE_LOG(FATAL) << "Can't get here.";
608   return false;
609 }
610 
IsByteStringWithCustomDefaultValue(const FieldDescriptor * field)611 bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field) {
612   return GetJavaType(field) == JAVATYPE_BYTES &&
613          field->default_value_string() != "";
614 }
615 
616 const char* bit_masks[] = {
617     "0x00000001", "0x00000002", "0x00000004", "0x00000008",
618     "0x00000010", "0x00000020", "0x00000040", "0x00000080",
619 
620     "0x00000100", "0x00000200", "0x00000400", "0x00000800",
621     "0x00001000", "0x00002000", "0x00004000", "0x00008000",
622 
623     "0x00010000", "0x00020000", "0x00040000", "0x00080000",
624     "0x00100000", "0x00200000", "0x00400000", "0x00800000",
625 
626     "0x01000000", "0x02000000", "0x04000000", "0x08000000",
627     "0x10000000", "0x20000000", "0x40000000", "0x80000000",
628 };
629 
GetBitFieldName(int index)630 std::string GetBitFieldName(int index) {
631   std::string varName = "bitField";
632   varName += StrCat(index);
633   varName += "_";
634   return varName;
635 }
636 
GetBitFieldNameForBit(int bitIndex)637 std::string GetBitFieldNameForBit(int bitIndex) {
638   return GetBitFieldName(bitIndex / 32);
639 }
640 
641 namespace {
642 
GenerateGetBitInternal(const std::string & prefix,int bitIndex)643 std::string GenerateGetBitInternal(const std::string& prefix, int bitIndex) {
644   std::string varName = prefix + GetBitFieldNameForBit(bitIndex);
645   int bitInVarIndex = bitIndex % 32;
646 
647   std::string mask = bit_masks[bitInVarIndex];
648   std::string result = "((" + varName + " & " + mask + ") != 0)";
649   return result;
650 }
651 
GenerateSetBitInternal(const std::string & prefix,int bitIndex)652 std::string GenerateSetBitInternal(const std::string& prefix, int bitIndex) {
653   std::string varName = prefix + GetBitFieldNameForBit(bitIndex);
654   int bitInVarIndex = bitIndex % 32;
655 
656   std::string mask = bit_masks[bitInVarIndex];
657   std::string result = varName + " |= " + mask;
658   return result;
659 }
660 
661 }  // namespace
662 
GenerateGetBit(int bitIndex)663 std::string GenerateGetBit(int bitIndex) {
664   return GenerateGetBitInternal("", bitIndex);
665 }
666 
GenerateSetBit(int bitIndex)667 std::string GenerateSetBit(int bitIndex) {
668   return GenerateSetBitInternal("", bitIndex);
669 }
670 
GenerateClearBit(int bitIndex)671 std::string GenerateClearBit(int bitIndex) {
672   std::string varName = GetBitFieldNameForBit(bitIndex);
673   int bitInVarIndex = bitIndex % 32;
674 
675   std::string mask = bit_masks[bitInVarIndex];
676   std::string result = varName + " = (" + varName + " & ~" + mask + ")";
677   return result;
678 }
679 
GenerateGetBitFromLocal(int bitIndex)680 std::string GenerateGetBitFromLocal(int bitIndex) {
681   return GenerateGetBitInternal("from_", bitIndex);
682 }
683 
GenerateSetBitToLocal(int bitIndex)684 std::string GenerateSetBitToLocal(int bitIndex) {
685   return GenerateSetBitInternal("to_", bitIndex);
686 }
687 
GenerateGetBitMutableLocal(int bitIndex)688 std::string GenerateGetBitMutableLocal(int bitIndex) {
689   return GenerateGetBitInternal("mutable_", bitIndex);
690 }
691 
GenerateSetBitMutableLocal(int bitIndex)692 std::string GenerateSetBitMutableLocal(int bitIndex) {
693   return GenerateSetBitInternal("mutable_", bitIndex);
694 }
695 
IsReferenceType(JavaType type)696 bool IsReferenceType(JavaType type) {
697   switch (type) {
698     case JAVATYPE_INT:
699       return false;
700     case JAVATYPE_LONG:
701       return false;
702     case JAVATYPE_FLOAT:
703       return false;
704     case JAVATYPE_DOUBLE:
705       return false;
706     case JAVATYPE_BOOLEAN:
707       return false;
708     case JAVATYPE_STRING:
709       return true;
710     case JAVATYPE_BYTES:
711       return true;
712     case JAVATYPE_ENUM:
713       return true;
714     case JAVATYPE_MESSAGE:
715       return true;
716 
717       // No default because we want the compiler to complain if any new
718       // JavaTypes are added.
719   }
720 
721   GOOGLE_LOG(FATAL) << "Can't get here.";
722   return false;
723 }
724 
GetCapitalizedType(const FieldDescriptor * field,bool immutable)725 const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable) {
726   switch (GetType(field)) {
727     case FieldDescriptor::TYPE_INT32:
728       return "Int32";
729     case FieldDescriptor::TYPE_UINT32:
730       return "UInt32";
731     case FieldDescriptor::TYPE_SINT32:
732       return "SInt32";
733     case FieldDescriptor::TYPE_FIXED32:
734       return "Fixed32";
735     case FieldDescriptor::TYPE_SFIXED32:
736       return "SFixed32";
737     case FieldDescriptor::TYPE_INT64:
738       return "Int64";
739     case FieldDescriptor::TYPE_UINT64:
740       return "UInt64";
741     case FieldDescriptor::TYPE_SINT64:
742       return "SInt64";
743     case FieldDescriptor::TYPE_FIXED64:
744       return "Fixed64";
745     case FieldDescriptor::TYPE_SFIXED64:
746       return "SFixed64";
747     case FieldDescriptor::TYPE_FLOAT:
748       return "Float";
749     case FieldDescriptor::TYPE_DOUBLE:
750       return "Double";
751     case FieldDescriptor::TYPE_BOOL:
752       return "Bool";
753     case FieldDescriptor::TYPE_STRING:
754       return "String";
755     case FieldDescriptor::TYPE_BYTES: {
756       return "Bytes";
757     }
758     case FieldDescriptor::TYPE_ENUM:
759       return "Enum";
760     case FieldDescriptor::TYPE_GROUP:
761       return "Group";
762     case FieldDescriptor::TYPE_MESSAGE:
763       return "Message";
764 
765       // No default because we want the compiler to complain if any new
766       // types are added.
767   }
768 
769   GOOGLE_LOG(FATAL) << "Can't get here.";
770   return NULL;
771 }
772 
773 // For encodings with fixed sizes, returns that size in bytes.  Otherwise
774 // returns -1.
FixedSize(FieldDescriptor::Type type)775 int FixedSize(FieldDescriptor::Type type) {
776   switch (type) {
777     case FieldDescriptor::TYPE_INT32:
778       return -1;
779     case FieldDescriptor::TYPE_INT64:
780       return -1;
781     case FieldDescriptor::TYPE_UINT32:
782       return -1;
783     case FieldDescriptor::TYPE_UINT64:
784       return -1;
785     case FieldDescriptor::TYPE_SINT32:
786       return -1;
787     case FieldDescriptor::TYPE_SINT64:
788       return -1;
789     case FieldDescriptor::TYPE_FIXED32:
790       return WireFormatLite::kFixed32Size;
791     case FieldDescriptor::TYPE_FIXED64:
792       return WireFormatLite::kFixed64Size;
793     case FieldDescriptor::TYPE_SFIXED32:
794       return WireFormatLite::kSFixed32Size;
795     case FieldDescriptor::TYPE_SFIXED64:
796       return WireFormatLite::kSFixed64Size;
797     case FieldDescriptor::TYPE_FLOAT:
798       return WireFormatLite::kFloatSize;
799     case FieldDescriptor::TYPE_DOUBLE:
800       return WireFormatLite::kDoubleSize;
801 
802     case FieldDescriptor::TYPE_BOOL:
803       return WireFormatLite::kBoolSize;
804     case FieldDescriptor::TYPE_ENUM:
805       return -1;
806 
807     case FieldDescriptor::TYPE_STRING:
808       return -1;
809     case FieldDescriptor::TYPE_BYTES:
810       return -1;
811     case FieldDescriptor::TYPE_GROUP:
812       return -1;
813     case FieldDescriptor::TYPE_MESSAGE:
814       return -1;
815 
816       // No default because we want the compiler to complain if any new
817       // types are added.
818   }
819   GOOGLE_LOG(FATAL) << "Can't get here.";
820   return -1;
821 }
822 
823 // Sort the fields of the given Descriptor by number into a new[]'d array
824 // and return it. The caller should delete the returned array.
SortFieldsByNumber(const Descriptor * descriptor)825 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
826   const FieldDescriptor** fields =
827       new const FieldDescriptor*[descriptor->field_count()];
828   for (int i = 0; i < descriptor->field_count(); i++) {
829     fields[i] = descriptor->field(i);
830   }
831   std::sort(fields, fields + descriptor->field_count(),
832             FieldOrderingByNumber());
833   return fields;
834 }
835 
836 // Returns true if the message type has any required fields.  If it doesn't,
837 // we can optimize out calls to its isInitialized() method.
838 //
839 // already_seen is used to avoid checking the same type multiple times
840 // (and also to protect against recursion).
HasRequiredFields(const Descriptor * type,std::unordered_set<const Descriptor * > * already_seen)841 bool HasRequiredFields(const Descriptor* type,
842                        std::unordered_set<const Descriptor*>* already_seen) {
843   if (already_seen->count(type) > 0) {
844     // The type is already in cache.  This means that either:
845     // a. The type has no required fields.
846     // b. We are in the midst of checking if the type has required fields,
847     //    somewhere up the stack.  In this case, we know that if the type
848     //    has any required fields, they'll be found when we return to it,
849     //    and the whole call to HasRequiredFields() will return true.
850     //    Therefore, we don't have to check if this type has required fields
851     //    here.
852     return false;
853   }
854   already_seen->insert(type);
855 
856   // If the type has extensions, an extension with message type could contain
857   // required fields, so we have to be conservative and assume such an
858   // extension exists.
859   if (type->extension_range_count() > 0) return true;
860 
861   for (int i = 0; i < type->field_count(); i++) {
862     const FieldDescriptor* field = type->field(i);
863     if (field->is_required()) {
864       return true;
865     }
866     if (GetJavaType(field) == JAVATYPE_MESSAGE) {
867       if (HasRequiredFields(field->message_type(), already_seen)) {
868         return true;
869       }
870     }
871   }
872 
873   return false;
874 }
875 
HasRequiredFields(const Descriptor * type)876 bool HasRequiredFields(const Descriptor* type) {
877   std::unordered_set<const Descriptor*> already_seen;
878   return HasRequiredFields(type, &already_seen);
879 }
880 
HasRepeatedFields(const Descriptor * descriptor)881 bool HasRepeatedFields(const Descriptor* descriptor) {
882   for (int i = 0; i < descriptor->field_count(); ++i) {
883     const FieldDescriptor* field = descriptor->field(i);
884     if (field->is_repeated()) {
885       return true;
886     }
887   }
888   return false;
889 }
890 
891 // Encode an unsigned 32-bit value into a sequence of UTF-16 characters.
892 //
893 // If the value is in [0x0000, 0xD7FF], we encode it with a single character
894 // with the same numeric value.
895 //
896 // If the value is larger than 0xD7FF, we encode its lowest 13 bits into a
897 // character in the range [0xE000, 0xFFFF] by combining these 13 bits with
898 // 0xE000 using logic-or. Then we shift the value to the right by 13 bits, and
899 // encode the remaining value by repeating this same process until we get to
900 // a value in [0x0000, 0xD7FF] where we will encode it using a character with
901 // the same numeric value.
902 //
903 // Note that we only use code points in [0x0000, 0xD7FF] and [0xE000, 0xFFFF].
904 // There will be no surrogate pairs in the encoded character sequence.
WriteUInt32ToUtf16CharSequence(uint32 number,std::vector<uint16> * output)905 void WriteUInt32ToUtf16CharSequence(uint32 number,
906                                     std::vector<uint16>* output) {
907   // For values in [0x0000, 0xD7FF], only use one char to encode it.
908   if (number < 0xD800) {
909     output->push_back(static_cast<uint16>(number));
910     return;
911   }
912   // Encode into multiple chars. All except the last char will be in the range
913   // [0xE000, 0xFFFF], and the last char will be in the range [0x0000, 0xD7FF].
914   // Note that we don't use any value in range [0xD800, 0xDFFF] because they
915   // have to come in pairs and the encoding is just more space-efficient w/o
916   // them.
917   while (number >= 0xD800) {
918     // [0xE000, 0xFFFF] can represent 13 bits of info.
919     output->push_back(static_cast<uint16>(0xE000 | (number & 0x1FFF)));
920     number >>= 13;
921   }
922   output->push_back(static_cast<uint16>(number));
923 }
924 
GetExperimentalJavaFieldTypeForSingular(const FieldDescriptor * field)925 int GetExperimentalJavaFieldTypeForSingular(const FieldDescriptor* field) {
926   // j/c/g/protobuf/FieldType.java lists field types in a slightly different
927   // order from FieldDescriptor::Type so we can't do a simple cast.
928   //
929   // TODO(xiaofeng): Make j/c/g/protobuf/FieldType.java follow the same order.
930   int result = field->type();
931   if (result == FieldDescriptor::TYPE_GROUP) {
932     return 17;
933   } else if (result < FieldDescriptor::TYPE_GROUP) {
934     return result - 1;
935   } else {
936     return result - 2;
937   }
938 }
939 
GetExperimentalJavaFieldTypeForRepeated(const FieldDescriptor * field)940 int GetExperimentalJavaFieldTypeForRepeated(const FieldDescriptor* field) {
941   if (field->type() == FieldDescriptor::TYPE_GROUP) {
942     return 49;
943   } else {
944     return GetExperimentalJavaFieldTypeForSingular(field) + 18;
945   }
946 }
947 
GetExperimentalJavaFieldTypeForPacked(const FieldDescriptor * field)948 int GetExperimentalJavaFieldTypeForPacked(const FieldDescriptor* field) {
949   int result = field->type();
950   if (result < FieldDescriptor::TYPE_STRING) {
951     return result + 34;
952   } else if (result > FieldDescriptor::TYPE_BYTES) {
953     return result + 30;
954   } else {
955     GOOGLE_LOG(FATAL) << field->full_name() << " can't be packed.";
956     return 0;
957   }
958 }
959 
GetExperimentalJavaFieldType(const FieldDescriptor * field)960 int GetExperimentalJavaFieldType(const FieldDescriptor* field) {
961   static const int kMapFieldType = 50;
962   static const int kOneofFieldTypeOffset = 51;
963   static const int kRequiredBit = 0x100;
964   static const int kUtf8CheckBit = 0x200;
965   static const int kCheckInitialized = 0x400;
966   static const int kMapWithProto2EnumValue = 0x800;
967   static const int kHasHasBit = 0x1000;
968   int extra_bits = field->is_required() ? kRequiredBit : 0;
969   if (field->type() == FieldDescriptor::TYPE_STRING && CheckUtf8(field)) {
970     extra_bits |= kUtf8CheckBit;
971   }
972   if (field->is_required() || (GetJavaType(field) == JAVATYPE_MESSAGE &&
973                                HasRequiredFields(field->message_type()))) {
974     extra_bits |= kCheckInitialized;
975   }
976   if (HasHasbit(field)) {
977     extra_bits |= kHasHasBit;
978   }
979 
980   if (field->is_map()) {
981     if (!SupportUnknownEnumValue(field)) {
982       const FieldDescriptor* value =
983           field->message_type()->FindFieldByName("value");
984       if (GetJavaType(value) == JAVATYPE_ENUM) {
985         extra_bits |= kMapWithProto2EnumValue;
986       }
987     }
988     return kMapFieldType | extra_bits;
989   } else if (field->is_packed()) {
990     return GetExperimentalJavaFieldTypeForPacked(field);
991   } else if (field->is_repeated()) {
992     return GetExperimentalJavaFieldTypeForRepeated(field) | extra_bits;
993   } else if (IsRealOneof(field)) {
994     return (GetExperimentalJavaFieldTypeForSingular(field) +
995             kOneofFieldTypeOffset) |
996            extra_bits;
997   } else {
998     return GetExperimentalJavaFieldTypeForSingular(field) | extra_bits;
999   }
1000 }
1001 
1002 // Escape a UTF-16 character to be embedded in a Java string.
EscapeUtf16ToString(uint16 code,std::string * output)1003 void EscapeUtf16ToString(uint16 code, std::string* output) {
1004   if (code == '\t') {
1005     output->append("\\t");
1006   } else if (code == '\b') {
1007     output->append("\\b");
1008   } else if (code == '\n') {
1009     output->append("\\n");
1010   } else if (code == '\r') {
1011     output->append("\\r");
1012   } else if (code == '\f') {
1013     output->append("\\f");
1014   } else if (code == '\'') {
1015     output->append("\\'");
1016   } else if (code == '\"') {
1017     output->append("\\\"");
1018   } else if (code == '\\') {
1019     output->append("\\\\");
1020   } else if (code >= 0x20 && code <= 0x7f) {
1021     output->push_back(static_cast<char>(code));
1022   } else {
1023     output->append(StringPrintf("\\u%04x", code));
1024   }
1025 }
1026 
1027 }  // namespace java
1028 }  // namespace compiler
1029 }  // namespace protobuf
1030 }  // namespace google
1031