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