Line data Source code
1 : // Protocol Buffers - Google's data interchange format
2 : // Copyright 2008 Google Inc. All rights reserved.
3 : // https://developers.google.com/protocol-buffers/
4 : //
5 : // Redistribution and use in source and binary forms, with or without
6 : // modification, are permitted provided that the following conditions are
7 : // met:
8 : //
9 : // * Redistributions of source code must retain the above copyright
10 : // notice, this list of conditions and the following disclaimer.
11 : // * Redistributions in binary form must reproduce the above
12 : // copyright notice, this list of conditions and the following disclaimer
13 : // in the documentation and/or other materials provided with the
14 : // distribution.
15 : // * Neither the name of Google Inc. nor the names of its
16 : // contributors may be used to endorse or promote products derived from
17 : // this software without specific prior written permission.
18 : //
19 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 :
31 : // Author: kenton@google.com (Kenton Varda)
32 : // Based on original Protocol Buffers design by
33 : // Sanjay Ghemawat, Jeff Dean, and others.
34 :
35 : #include <algorithm>
36 : #include <google/protobuf/stubs/hash.h>
37 : #include <limits>
38 : #include <vector>
39 :
40 : #include <google/protobuf/compiler/java/java_helpers.h>
41 : #include <google/protobuf/compiler/java/java_name_resolver.h>
42 : #include <google/protobuf/descriptor.pb.h>
43 : #include <google/protobuf/wire_format.h>
44 : #include <google/protobuf/stubs/strutil.h>
45 : #include <google/protobuf/stubs/substitute.h>
46 :
47 : namespace google {
48 : namespace protobuf {
49 : namespace compiler {
50 : namespace java {
51 :
52 : using internal::WireFormat;
53 : using internal::WireFormatLite;
54 :
55 : const char kThickSeparator[] =
56 : "// ===================================================================\n";
57 : const char kThinSeparator[] =
58 : "// -------------------------------------------------------------------\n";
59 :
60 : namespace {
61 :
62 : const char* kDefaultPackage = "";
63 :
64 : // Names that should be avoided as field names.
65 : // Using them will cause the compiler to generate accessors whose names are
66 : // colliding with methods defined in base classes.
67 : const char* kForbiddenWordList[] = {
68 : // message base class:
69 : "cached_size", "serialized_size",
70 : // java.lang.Object:
71 : "class",
72 : };
73 :
74 0 : bool IsForbidden(const string& field_name) {
75 0 : for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) {
76 0 : if (field_name == kForbiddenWordList[i]) {
77 : return true;
78 : }
79 : }
80 : return false;
81 : }
82 :
83 0 : string FieldName(const FieldDescriptor* field) {
84 : string field_name;
85 : // Groups are hacky: The name of the field is just the lower-cased name
86 : // of the group type. In Java, though, we would like to retain the original
87 : // capitalization of the type name.
88 0 : if (GetType(field) == FieldDescriptor::TYPE_GROUP) {
89 0 : field_name = field->message_type()->name();
90 : } else {
91 0 : field_name = field->name();
92 : }
93 0 : if (IsForbidden(field_name)) {
94 : // Append a trailing "#" to indicate that the name should be decorated to
95 : // avoid collision with other names.
96 : field_name += "#";
97 : }
98 0 : return field_name;
99 : }
100 :
101 :
102 : } // namespace
103 :
104 0 : string UnderscoresToCamelCase(const string& input, bool cap_next_letter) {
105 : string result;
106 : // Note: I distrust ctype.h due to locales.
107 0 : for (int i = 0; i < input.size(); i++) {
108 0 : if ('a' <= input[i] && input[i] <= 'z') {
109 0 : if (cap_next_letter) {
110 0 : result += input[i] + ('A' - 'a');
111 : } else {
112 0 : result += input[i];
113 : }
114 : cap_next_letter = false;
115 0 : } else if ('A' <= input[i] && input[i] <= 'Z') {
116 0 : if (i == 0 && !cap_next_letter) {
117 : // Force first letter to lower-case unless explicitly told to
118 : // capitalize it.
119 0 : result += input[i] + ('a' - 'A');
120 : } else {
121 : // Capital letters after the first are left as-is.
122 0 : result += input[i];
123 : }
124 : cap_next_letter = false;
125 0 : } else if ('0' <= input[i] && input[i] <= '9') {
126 0 : result += input[i];
127 : cap_next_letter = true;
128 : } else {
129 : cap_next_letter = true;
130 : }
131 : }
132 : // Add a trailing "_" if the name should be altered.
133 0 : if (input[input.size() - 1] == '#') {
134 : result += '_';
135 : }
136 0 : return result;
137 : }
138 :
139 0 : string UnderscoresToCamelCase(const FieldDescriptor* field) {
140 0 : return UnderscoresToCamelCase(FieldName(field), false);
141 : }
142 :
143 0 : string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
144 0 : return UnderscoresToCamelCase(FieldName(field), true);
145 : }
146 :
147 0 : string UnderscoresToCamelCase(const MethodDescriptor* method) {
148 0 : return UnderscoresToCamelCase(method->name(), false);
149 : }
150 :
151 0 : string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
152 0 : return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
153 : }
154 :
155 0 : string StripProto(const string& filename) {
156 0 : if (HasSuffixString(filename, ".protodevel")) {
157 0 : return StripSuffixString(filename, ".protodevel");
158 : } else {
159 0 : return StripSuffixString(filename, ".proto");
160 : }
161 : }
162 :
163 0 : string FileClassName(const FileDescriptor* file, bool immutable) {
164 0 : ClassNameResolver name_resolver;
165 0 : return name_resolver.GetFileClassName(file, immutable);
166 : }
167 :
168 0 : string FileJavaPackage(const FileDescriptor* file, bool immutable) {
169 : string result;
170 :
171 0 : if (file->options().has_java_package()) {
172 0 : result = file->options().java_package();
173 : } else {
174 0 : result = kDefaultPackage;
175 0 : if (!file->package().empty()) {
176 0 : if (!result.empty()) result += '.';
177 0 : result += file->package();
178 : }
179 : }
180 :
181 0 : return result;
182 : }
183 :
184 0 : string JavaPackageToDir(string package_name) {
185 : string package_dir =
186 0 : StringReplace(package_name, ".", "/", true);
187 0 : if (!package_dir.empty()) package_dir += "/";
188 0 : return package_dir;
189 : }
190 :
191 : // TODO(xiaofeng): This function is only kept for it's publicly referenced.
192 : // It should be removed after mutable API up-integration.
193 0 : string ToJavaName(const string& full_name,
194 0 : const FileDescriptor* file) {
195 : string result;
196 0 : if (file->options().java_multiple_files()) {
197 0 : result = FileJavaPackage(file);
198 : } else {
199 0 : result = ClassName(file);
200 : }
201 0 : if (!result.empty()) {
202 : result += '.';
203 : }
204 0 : if (file->package().empty()) {
205 : result += full_name;
206 : } else {
207 : // Strip the proto package from full_name since we've replaced it with
208 : // the Java package.
209 0 : result += full_name.substr(file->package().size() + 1);
210 : }
211 0 : return result;
212 : }
213 :
214 0 : string ClassName(const Descriptor* descriptor) {
215 0 : ClassNameResolver name_resolver;
216 0 : return name_resolver.GetClassName(descriptor, true);
217 : }
218 :
219 0 : string ClassName(const EnumDescriptor* descriptor) {
220 0 : ClassNameResolver name_resolver;
221 0 : return name_resolver.GetClassName(descriptor, true);
222 : }
223 :
224 0 : string ClassName(const ServiceDescriptor* descriptor) {
225 0 : ClassNameResolver name_resolver;
226 0 : return name_resolver.GetClassName(descriptor, true);
227 : }
228 :
229 0 : string ClassName(const FileDescriptor* descriptor) {
230 0 : ClassNameResolver name_resolver;
231 0 : return name_resolver.GetClassName(descriptor, true);
232 : }
233 :
234 0 : string ExtraMessageInterfaces(const Descriptor* descriptor) {
235 : string interfaces = "// @@protoc_insertion_point(message_implements:"
236 0 : + descriptor->full_name() + ")";
237 0 : return interfaces;
238 : }
239 :
240 :
241 0 : string ExtraBuilderInterfaces(const Descriptor* descriptor) {
242 : string interfaces = "// @@protoc_insertion_point(builder_implements:"
243 0 : + descriptor->full_name() + ")";
244 0 : return interfaces;
245 : }
246 :
247 0 : string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor) {
248 : string interfaces = "// @@protoc_insertion_point(interface_extends:"
249 0 : + descriptor->full_name() + ")";
250 0 : return interfaces;
251 : }
252 :
253 0 : string FieldConstantName(const FieldDescriptor *field) {
254 0 : string name = field->name() + "_FIELD_NUMBER";
255 0 : UpperString(&name);
256 0 : return name;
257 : }
258 :
259 0 : FieldDescriptor::Type GetType(const FieldDescriptor* field) {
260 0 : return field->type();
261 : }
262 :
263 0 : JavaType GetJavaType(const FieldDescriptor* field) {
264 0 : switch (GetType(field)) {
265 : case FieldDescriptor::TYPE_INT32:
266 : case FieldDescriptor::TYPE_UINT32:
267 : case FieldDescriptor::TYPE_SINT32:
268 : case FieldDescriptor::TYPE_FIXED32:
269 : case FieldDescriptor::TYPE_SFIXED32:
270 : return JAVATYPE_INT;
271 :
272 : case FieldDescriptor::TYPE_INT64:
273 : case FieldDescriptor::TYPE_UINT64:
274 : case FieldDescriptor::TYPE_SINT64:
275 : case FieldDescriptor::TYPE_FIXED64:
276 : case FieldDescriptor::TYPE_SFIXED64:
277 0 : return JAVATYPE_LONG;
278 :
279 : case FieldDescriptor::TYPE_FLOAT:
280 0 : return JAVATYPE_FLOAT;
281 :
282 : case FieldDescriptor::TYPE_DOUBLE:
283 0 : return JAVATYPE_DOUBLE;
284 :
285 : case FieldDescriptor::TYPE_BOOL:
286 0 : return JAVATYPE_BOOLEAN;
287 :
288 : case FieldDescriptor::TYPE_STRING:
289 0 : return JAVATYPE_STRING;
290 :
291 : case FieldDescriptor::TYPE_BYTES:
292 0 : return JAVATYPE_BYTES;
293 :
294 : case FieldDescriptor::TYPE_ENUM:
295 0 : return JAVATYPE_ENUM;
296 :
297 : case FieldDescriptor::TYPE_GROUP:
298 : case FieldDescriptor::TYPE_MESSAGE:
299 0 : return JAVATYPE_MESSAGE;
300 :
301 : // No default because we want the compiler to complain if any new
302 : // types are added.
303 : }
304 :
305 0 : GOOGLE_LOG(FATAL) << "Can't get here.";
306 0 : return JAVATYPE_INT;
307 : }
308 :
309 0 : const char* PrimitiveTypeName(JavaType type) {
310 0 : switch (type) {
311 : case JAVATYPE_INT : return "int";
312 0 : case JAVATYPE_LONG : return "long";
313 0 : case JAVATYPE_FLOAT : return "float";
314 0 : case JAVATYPE_DOUBLE : return "double";
315 0 : case JAVATYPE_BOOLEAN: return "boolean";
316 0 : case JAVATYPE_STRING : return "java.lang.String";
317 0 : case JAVATYPE_BYTES : return "com.google.protobuf.ByteString";
318 0 : case JAVATYPE_ENUM : return NULL;
319 0 : case JAVATYPE_MESSAGE: return NULL;
320 :
321 : // No default because we want the compiler to complain if any new
322 : // JavaTypes are added.
323 : }
324 :
325 0 : GOOGLE_LOG(FATAL) << "Can't get here.";
326 0 : return NULL;
327 : }
328 :
329 0 : const char* BoxedPrimitiveTypeName(JavaType type) {
330 0 : switch (type) {
331 : case JAVATYPE_INT : return "java.lang.Integer";
332 0 : case JAVATYPE_LONG : return "java.lang.Long";
333 0 : case JAVATYPE_FLOAT : return "java.lang.Float";
334 0 : case JAVATYPE_DOUBLE : return "java.lang.Double";
335 0 : case JAVATYPE_BOOLEAN: return "java.lang.Boolean";
336 0 : case JAVATYPE_STRING : return "java.lang.String";
337 0 : case JAVATYPE_BYTES : return "com.google.protobuf.ByteString";
338 0 : case JAVATYPE_ENUM : return NULL;
339 0 : case JAVATYPE_MESSAGE: return NULL;
340 :
341 : // No default because we want the compiler to complain if any new
342 : // JavaTypes are added.
343 : }
344 :
345 0 : GOOGLE_LOG(FATAL) << "Can't get here.";
346 0 : return NULL;
347 : }
348 :
349 0 : const char* FieldTypeName(FieldDescriptor::Type field_type) {
350 0 : switch (field_type) {
351 : case FieldDescriptor::TYPE_INT32 : return "INT32";
352 0 : case FieldDescriptor::TYPE_UINT32 : return "UINT32";
353 0 : case FieldDescriptor::TYPE_SINT32 : return "SINT32";
354 0 : case FieldDescriptor::TYPE_FIXED32 : return "FIXED32";
355 0 : case FieldDescriptor::TYPE_SFIXED32: return "SFIXED32";
356 0 : case FieldDescriptor::TYPE_INT64 : return "INT64";
357 0 : case FieldDescriptor::TYPE_UINT64 : return "UINT64";
358 0 : case FieldDescriptor::TYPE_SINT64 : return "SINT64";
359 0 : case FieldDescriptor::TYPE_FIXED64 : return "FIXED64";
360 0 : case FieldDescriptor::TYPE_SFIXED64: return "SFIXED64";
361 0 : case FieldDescriptor::TYPE_FLOAT : return "FLOAT";
362 0 : case FieldDescriptor::TYPE_DOUBLE : return "DOUBLE";
363 0 : case FieldDescriptor::TYPE_BOOL : return "BOOL";
364 0 : case FieldDescriptor::TYPE_STRING : return "STRING";
365 0 : case FieldDescriptor::TYPE_BYTES : return "BYTES";
366 0 : case FieldDescriptor::TYPE_ENUM : return "ENUM";
367 0 : case FieldDescriptor::TYPE_GROUP : return "GROUP";
368 0 : case FieldDescriptor::TYPE_MESSAGE : return "MESSAGE";
369 :
370 : // No default because we want the compiler to complain if any new
371 : // types are added.
372 : }
373 :
374 0 : GOOGLE_LOG(FATAL) << "Can't get here.";
375 0 : return NULL;
376 : }
377 :
378 0 : bool AllAscii(const string& text) {
379 0 : for (int i = 0; i < text.size(); i++) {
380 0 : if ((text[i] & 0x80) != 0) {
381 : return false;
382 : }
383 : }
384 : return true;
385 : }
386 :
387 0 : string DefaultValue(const FieldDescriptor* field, bool immutable,
388 : ClassNameResolver* name_resolver) {
389 : // Switch on CppType since we need to know which default_value_* method
390 : // of FieldDescriptor to call.
391 0 : switch (field->cpp_type()) {
392 : case FieldDescriptor::CPPTYPE_INT32:
393 0 : return SimpleItoa(field->default_value_int32());
394 : case FieldDescriptor::CPPTYPE_UINT32:
395 : // Need to print as a signed int since Java has no unsigned.
396 0 : return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
397 : case FieldDescriptor::CPPTYPE_INT64:
398 0 : return SimpleItoa(field->default_value_int64()) + "L";
399 : case FieldDescriptor::CPPTYPE_UINT64:
400 0 : return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
401 0 : "L";
402 : case FieldDescriptor::CPPTYPE_DOUBLE: {
403 0 : double value = field->default_value_double();
404 0 : if (value == numeric_limits<double>::infinity()) {
405 0 : return "Double.POSITIVE_INFINITY";
406 0 : } else if (value == -numeric_limits<double>::infinity()) {
407 0 : return "Double.NEGATIVE_INFINITY";
408 0 : } else if (value != value) {
409 0 : return "Double.NaN";
410 : } else {
411 0 : return SimpleDtoa(value) + "D";
412 : }
413 : }
414 : case FieldDescriptor::CPPTYPE_FLOAT: {
415 0 : float value = field->default_value_float();
416 0 : if (value == numeric_limits<float>::infinity()) {
417 0 : return "Float.POSITIVE_INFINITY";
418 0 : } else if (value == -numeric_limits<float>::infinity()) {
419 0 : return "Float.NEGATIVE_INFINITY";
420 0 : } else if (value != value) {
421 0 : return "Float.NaN";
422 : } else {
423 0 : return SimpleFtoa(value) + "F";
424 : }
425 : }
426 : case FieldDescriptor::CPPTYPE_BOOL:
427 0 : return field->default_value_bool() ? "true" : "false";
428 : case FieldDescriptor::CPPTYPE_STRING:
429 0 : if (GetType(field) == FieldDescriptor::TYPE_BYTES) {
430 0 : if (field->has_default_value()) {
431 : // See comments in Internal.java for gory details.
432 : return strings::Substitute(
433 : "com.google.protobuf.Internal.bytesDefaultValue(\"$0\")",
434 0 : CEscape(field->default_value_string()));
435 : } else {
436 0 : return "com.google.protobuf.ByteString.EMPTY";
437 : }
438 : } else {
439 0 : if (AllAscii(field->default_value_string())) {
440 : // All chars are ASCII. In this case CEscape() works fine.
441 0 : return "\"" + CEscape(field->default_value_string()) + "\"";
442 : } else {
443 : // See comments in Internal.java for gory details.
444 : return strings::Substitute(
445 : "com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
446 0 : CEscape(field->default_value_string()));
447 : }
448 : }
449 :
450 : case FieldDescriptor::CPPTYPE_ENUM:
451 0 : return name_resolver->GetClassName(field->enum_type(), immutable) + "." +
452 0 : field->default_value_enum()->name();
453 :
454 : case FieldDescriptor::CPPTYPE_MESSAGE:
455 : return name_resolver->GetClassName(field->message_type(), immutable) +
456 0 : ".getDefaultInstance()";
457 :
458 : // No default because we want the compiler to complain if any new
459 : // types are added.
460 : }
461 :
462 0 : GOOGLE_LOG(FATAL) << "Can't get here.";
463 0 : return "";
464 : }
465 :
466 0 : bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
467 : // Switch on CppType since we need to know which default_value_* method
468 : // of FieldDescriptor to call.
469 0 : switch (field->cpp_type()) {
470 : case FieldDescriptor::CPPTYPE_INT32:
471 0 : return field->default_value_int32() == 0;
472 : case FieldDescriptor::CPPTYPE_UINT32:
473 0 : return field->default_value_uint32() == 0;
474 : case FieldDescriptor::CPPTYPE_INT64:
475 0 : return field->default_value_int64() == 0L;
476 : case FieldDescriptor::CPPTYPE_UINT64:
477 0 : return field->default_value_uint64() == 0L;
478 : case FieldDescriptor::CPPTYPE_DOUBLE:
479 0 : return field->default_value_double() == 0.0;
480 : case FieldDescriptor::CPPTYPE_FLOAT:
481 0 : return field->default_value_float() == 0.0;
482 : case FieldDescriptor::CPPTYPE_BOOL:
483 0 : return field->default_value_bool() == false;
484 :
485 : case FieldDescriptor::CPPTYPE_STRING:
486 : case FieldDescriptor::CPPTYPE_ENUM:
487 : case FieldDescriptor::CPPTYPE_MESSAGE:
488 : return false;
489 :
490 : // No default because we want the compiler to complain if any new
491 : // types are added.
492 : }
493 :
494 0 : GOOGLE_LOG(FATAL) << "Can't get here.";
495 0 : return false;
496 : }
497 :
498 : const char* bit_masks[] = {
499 : "0x00000001",
500 : "0x00000002",
501 : "0x00000004",
502 : "0x00000008",
503 : "0x00000010",
504 : "0x00000020",
505 : "0x00000040",
506 : "0x00000080",
507 :
508 : "0x00000100",
509 : "0x00000200",
510 : "0x00000400",
511 : "0x00000800",
512 : "0x00001000",
513 : "0x00002000",
514 : "0x00004000",
515 : "0x00008000",
516 :
517 : "0x00010000",
518 : "0x00020000",
519 : "0x00040000",
520 : "0x00080000",
521 : "0x00100000",
522 : "0x00200000",
523 : "0x00400000",
524 : "0x00800000",
525 :
526 : "0x01000000",
527 : "0x02000000",
528 : "0x04000000",
529 : "0x08000000",
530 : "0x10000000",
531 : "0x20000000",
532 : "0x40000000",
533 : "0x80000000",
534 : };
535 :
536 0 : string GetBitFieldName(int index) {
537 0 : string varName = "bitField";
538 0 : varName += SimpleItoa(index);
539 : varName += "_";
540 0 : return varName;
541 : }
542 :
543 0 : string GetBitFieldNameForBit(int bitIndex) {
544 0 : return GetBitFieldName(bitIndex / 32);
545 : }
546 :
547 : namespace {
548 :
549 0 : string GenerateGetBitInternal(const string& prefix, int bitIndex) {
550 0 : string varName = prefix + GetBitFieldNameForBit(bitIndex);
551 0 : int bitInVarIndex = bitIndex % 32;
552 :
553 0 : string mask = bit_masks[bitInVarIndex];
554 0 : string result = "((" + varName + " & " + mask + ") == " + mask + ")";
555 0 : return result;
556 : }
557 :
558 0 : string GenerateSetBitInternal(const string& prefix, int bitIndex) {
559 0 : string varName = prefix + GetBitFieldNameForBit(bitIndex);
560 0 : int bitInVarIndex = bitIndex % 32;
561 :
562 0 : string mask = bit_masks[bitInVarIndex];
563 0 : string result = varName + " |= " + mask;
564 0 : return result;
565 : }
566 :
567 : } // namespace
568 :
569 0 : string GenerateGetBit(int bitIndex) {
570 0 : return GenerateGetBitInternal("", bitIndex);
571 : }
572 :
573 0 : string GenerateSetBit(int bitIndex) {
574 0 : return GenerateSetBitInternal("", bitIndex);
575 : }
576 :
577 0 : string GenerateClearBit(int bitIndex) {
578 0 : string varName = GetBitFieldNameForBit(bitIndex);
579 0 : int bitInVarIndex = bitIndex % 32;
580 :
581 0 : string mask = bit_masks[bitInVarIndex];
582 0 : string result = varName + " = (" + varName + " & ~" + mask + ")";
583 0 : return result;
584 : }
585 :
586 0 : string GenerateGetBitFromLocal(int bitIndex) {
587 0 : return GenerateGetBitInternal("from_", bitIndex);
588 : }
589 :
590 0 : string GenerateSetBitToLocal(int bitIndex) {
591 0 : return GenerateSetBitInternal("to_", bitIndex);
592 : }
593 :
594 0 : string GenerateGetBitMutableLocal(int bitIndex) {
595 0 : return GenerateGetBitInternal("mutable_", bitIndex);
596 : }
597 :
598 0 : string GenerateSetBitMutableLocal(int bitIndex) {
599 0 : return GenerateSetBitInternal("mutable_", bitIndex);
600 : }
601 :
602 0 : bool IsReferenceType(JavaType type) {
603 0 : switch (type) {
604 : case JAVATYPE_INT : return false;
605 : case JAVATYPE_LONG : return false;
606 : case JAVATYPE_FLOAT : return false;
607 : case JAVATYPE_DOUBLE : return false;
608 : case JAVATYPE_BOOLEAN: return false;
609 0 : case JAVATYPE_STRING : return true;
610 0 : case JAVATYPE_BYTES : return true;
611 0 : case JAVATYPE_ENUM : return true;
612 0 : case JAVATYPE_MESSAGE: return true;
613 :
614 : // No default because we want the compiler to complain if any new
615 : // JavaTypes are added.
616 : }
617 :
618 0 : GOOGLE_LOG(FATAL) << "Can't get here.";
619 0 : return false;
620 : }
621 :
622 0 : const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable) {
623 0 : switch (GetType(field)) {
624 : case FieldDescriptor::TYPE_INT32 : return "Int32";
625 0 : case FieldDescriptor::TYPE_UINT32 : return "UInt32";
626 0 : case FieldDescriptor::TYPE_SINT32 : return "SInt32";
627 0 : case FieldDescriptor::TYPE_FIXED32 : return "Fixed32";
628 0 : case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
629 0 : case FieldDescriptor::TYPE_INT64 : return "Int64";
630 0 : case FieldDescriptor::TYPE_UINT64 : return "UInt64";
631 0 : case FieldDescriptor::TYPE_SINT64 : return "SInt64";
632 0 : case FieldDescriptor::TYPE_FIXED64 : return "Fixed64";
633 0 : case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
634 0 : case FieldDescriptor::TYPE_FLOAT : return "Float";
635 0 : case FieldDescriptor::TYPE_DOUBLE : return "Double";
636 0 : case FieldDescriptor::TYPE_BOOL : return "Bool";
637 0 : case FieldDescriptor::TYPE_STRING : return "String";
638 : case FieldDescriptor::TYPE_BYTES : {
639 0 : return "Bytes";
640 : }
641 0 : case FieldDescriptor::TYPE_ENUM : return "Enum";
642 0 : case FieldDescriptor::TYPE_GROUP : return "Group";
643 0 : case FieldDescriptor::TYPE_MESSAGE : return "Message";
644 :
645 : // No default because we want the compiler to complain if any new
646 : // types are added.
647 : }
648 :
649 0 : GOOGLE_LOG(FATAL) << "Can't get here.";
650 0 : return NULL;
651 : }
652 :
653 : // For encodings with fixed sizes, returns that size in bytes. Otherwise
654 : // returns -1.
655 0 : int FixedSize(FieldDescriptor::Type type) {
656 0 : switch (type) {
657 : case FieldDescriptor::TYPE_INT32 : return -1;
658 : case FieldDescriptor::TYPE_INT64 : return -1;
659 : case FieldDescriptor::TYPE_UINT32 : return -1;
660 : case FieldDescriptor::TYPE_UINT64 : return -1;
661 : case FieldDescriptor::TYPE_SINT32 : return -1;
662 : case FieldDescriptor::TYPE_SINT64 : return -1;
663 0 : case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
664 0 : case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
665 0 : case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
666 0 : case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
667 0 : case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize;
668 0 : case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize;
669 :
670 0 : case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize;
671 : case FieldDescriptor::TYPE_ENUM : return -1;
672 :
673 : case FieldDescriptor::TYPE_STRING : return -1;
674 : case FieldDescriptor::TYPE_BYTES : return -1;
675 : case FieldDescriptor::TYPE_GROUP : return -1;
676 : case FieldDescriptor::TYPE_MESSAGE : return -1;
677 :
678 : // No default because we want the compiler to complain if any new
679 : // types are added.
680 : }
681 0 : GOOGLE_LOG(FATAL) << "Can't get here.";
682 0 : return -1;
683 : }
684 :
685 : // Sort the fields of the given Descriptor by number into a new[]'d array
686 : // and return it. The caller should delete the returned array.
687 0 : const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
688 : const FieldDescriptor** fields =
689 0 : new const FieldDescriptor*[descriptor->field_count()];
690 0 : for (int i = 0; i < descriptor->field_count(); i++) {
691 0 : fields[i] = descriptor->field(i);
692 : }
693 0 : std::sort(fields, fields + descriptor->field_count(),
694 0 : FieldOrderingByNumber());
695 0 : return fields;
696 : }
697 :
698 : // Returns true if the message type has any required fields. If it doesn't,
699 : // we can optimize out calls to its isInitialized() method.
700 : //
701 : // already_seen is used to avoid checking the same type multiple times
702 : // (and also to protect against recursion).
703 0 : bool HasRequiredFields(
704 : const Descriptor* type,
705 : hash_set<const Descriptor*>* already_seen) {
706 0 : if (already_seen->count(type) > 0) {
707 : // The type is already in cache. This means that either:
708 : // a. The type has no required fields.
709 : // b. We are in the midst of checking if the type has required fields,
710 : // somewhere up the stack. In this case, we know that if the type
711 : // has any required fields, they'll be found when we return to it,
712 : // and the whole call to HasRequiredFields() will return true.
713 : // Therefore, we don't have to check if this type has required fields
714 : // here.
715 : return false;
716 : }
717 0 : already_seen->insert(type);
718 :
719 : // If the type has extensions, an extension with message type could contain
720 : // required fields, so we have to be conservative and assume such an
721 : // extension exists.
722 0 : if (type->extension_range_count() > 0) return true;
723 :
724 0 : for (int i = 0; i < type->field_count(); i++) {
725 0 : const FieldDescriptor* field = type->field(i);
726 0 : if (field->is_required()) {
727 : return true;
728 : }
729 0 : if (GetJavaType(field) == JAVATYPE_MESSAGE) {
730 0 : if (HasRequiredFields(field->message_type(), already_seen)) {
731 : return true;
732 : }
733 : }
734 : }
735 :
736 : return false;
737 : }
738 :
739 0 : bool HasRequiredFields(const Descriptor* type) {
740 : hash_set<const Descriptor*> already_seen;
741 0 : return HasRequiredFields(type, &already_seen);
742 : }
743 :
744 0 : bool HasRepeatedFields(const Descriptor* descriptor) {
745 0 : for (int i = 0; i < descriptor->field_count(); ++i) {
746 0 : const FieldDescriptor* field = descriptor->field(i);
747 0 : if (field->is_repeated()) {
748 : return true;
749 : }
750 : }
751 : return false;
752 : }
753 :
754 : } // namespace java
755 : } // namespace compiler
756 : } // namespace protobuf
757 : } // namespace google
|