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