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 (at) 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 bool IsForbidden(const string& field_name) { 75 for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) { 76 if (field_name == kForbiddenWordList[i]) { 77 return true; 78 } 79 } 80 return false; 81 } 82 83 string FieldName(const FieldDescriptor* field) { 84 string field_name; 85 // Groups are hacky: The name of the field is just the lower-cased name 86 // of the group type. In Java, though, we would like to retain the original 87 // capitalization of the type name. 88 if (GetType(field) == FieldDescriptor::TYPE_GROUP) { 89 field_name = field->message_type()->name(); 90 } else { 91 field_name = field->name(); 92 } 93 if (IsForbidden(field_name)) { 94 // Append a trailing "#" to indicate that the name should be decorated to 95 // avoid collision with other names. 96 field_name += "#"; 97 } 98 return field_name; 99 } 100 101 102 } // namespace 103 104 string UnderscoresToCamelCase(const string& input, bool cap_next_letter) { 105 string result; 106 // Note: I distrust ctype.h due to locales. 107 for (int i = 0; i < input.size(); i++) { 108 if ('a' <= input[i] && input[i] <= 'z') { 109 if (cap_next_letter) { 110 result += input[i] + ('A' - 'a'); 111 } else { 112 result += input[i]; 113 } 114 cap_next_letter = false; 115 } else if ('A' <= input[i] && input[i] <= 'Z') { 116 if (i == 0 && !cap_next_letter) { 117 // Force first letter to lower-case unless explicitly told to 118 // capitalize it. 119 result += input[i] + ('a' - 'A'); 120 } else { 121 // Capital letters after the first are left as-is. 122 result += input[i]; 123 } 124 cap_next_letter = false; 125 } else if ('0' <= input[i] && input[i] <= '9') { 126 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 if (input[input.size() - 1] == '#') { 134 result += '_'; 135 } 136 return result; 137 } 138 139 string UnderscoresToCamelCase(const FieldDescriptor* field) { 140 return UnderscoresToCamelCase(FieldName(field), false); 141 } 142 143 string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) { 144 return UnderscoresToCamelCase(FieldName(field), true); 145 } 146 147 string UnderscoresToCamelCase(const MethodDescriptor* method) { 148 return UnderscoresToCamelCase(method->name(), false); 149 } 150 151 string UniqueFileScopeIdentifier(const Descriptor* descriptor) { 152 return "static_" + StringReplace(descriptor->full_name(), ".", "_", true); 153 } 154 155 string StripProto(const string& filename) { 156 if (HasSuffixString(filename, ".protodevel")) { 157 return StripSuffixString(filename, ".protodevel"); 158 } else { 159 return StripSuffixString(filename, ".proto"); 160 } 161 } 162 163 string FileClassName(const FileDescriptor* file, bool immutable) { 164 ClassNameResolver name_resolver; 165 return name_resolver.GetFileClassName(file, immutable); 166 } 167 168 string FileJavaPackage(const FileDescriptor* file, bool immutable) { 169 string result; 170 171 if (file->options().has_java_package()) { 172 result = file->options().java_package(); 173 } else { 174 result = kDefaultPackage; 175 if (!file->package().empty()) { 176 if (!result.empty()) result += '.'; 177 result += file->package(); 178 } 179 } 180 181 return result; 182 } 183 184 string JavaPackageToDir(string package_name) { 185 string package_dir = 186 StringReplace(package_name, ".", "/", true); 187 if (!package_dir.empty()) package_dir += "/"; 188 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 string ToJavaName(const string& full_name, 194 const FileDescriptor* file) { 195 string result; 196 if (file->options().java_multiple_files()) { 197 result = FileJavaPackage(file); 198 } else { 199 result = ClassName(file); 200 } 201 if (!result.empty()) { 202 result += '.'; 203 } 204 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 result += full_name.substr(file->package().size() + 1); 210 } 211 return result; 212 } 213 214 string ClassName(const Descriptor* descriptor) { 215 ClassNameResolver name_resolver; 216 return name_resolver.GetClassName(descriptor, true); 217 } 218 219 string ClassName(const EnumDescriptor* descriptor) { 220 ClassNameResolver name_resolver; 221 return name_resolver.GetClassName(descriptor, true); 222 } 223 224 string ClassName(const ServiceDescriptor* descriptor) { 225 ClassNameResolver name_resolver; 226 return name_resolver.GetClassName(descriptor, true); 227 } 228 229 string ClassName(const FileDescriptor* descriptor) { 230 ClassNameResolver name_resolver; 231 return name_resolver.GetClassName(descriptor, true); 232 } 233 234 string ExtraMessageInterfaces(const Descriptor* descriptor) { 235 string interfaces = "// @@protoc_insertion_point(message_implements:" 236 + descriptor->full_name() + ")"; 237 return interfaces; 238 } 239 240 241 string ExtraBuilderInterfaces(const Descriptor* descriptor) { 242 string interfaces = "// @@protoc_insertion_point(builder_implements:" 243 + descriptor->full_name() + ")"; 244 return interfaces; 245 } 246 247 string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor) { 248 string interfaces = "// @@protoc_insertion_point(interface_extends:" 249 + descriptor->full_name() + ")"; 250 return interfaces; 251 } 252 253 string FieldConstantName(const FieldDescriptor *field) { 254 string name = field->name() + "_FIELD_NUMBER"; 255 UpperString(&name); 256 return name; 257 } 258 259 FieldDescriptor::Type GetType(const FieldDescriptor* field) { 260 return field->type(); 261 } 262 263 JavaType GetJavaType(const FieldDescriptor* field) { 264 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 return JAVATYPE_LONG; 278 279 case FieldDescriptor::TYPE_FLOAT: 280 return JAVATYPE_FLOAT; 281 282 case FieldDescriptor::TYPE_DOUBLE: 283 return JAVATYPE_DOUBLE; 284 285 case FieldDescriptor::TYPE_BOOL: 286 return JAVATYPE_BOOLEAN; 287 288 case FieldDescriptor::TYPE_STRING: 289 return JAVATYPE_STRING; 290 291 case FieldDescriptor::TYPE_BYTES: 292 return JAVATYPE_BYTES; 293 294 case FieldDescriptor::TYPE_ENUM: 295 return JAVATYPE_ENUM; 296 297 case FieldDescriptor::TYPE_GROUP: 298 case FieldDescriptor::TYPE_MESSAGE: 299 return JAVATYPE_MESSAGE; 300 301 // No default because we want the compiler to complain if any new 302 // types are added. 303 } 304 305 GOOGLE_LOG(FATAL) << "Can't get here."; 306 return JAVATYPE_INT; 307 } 308 309 const char* PrimitiveTypeName(JavaType type) { 310 switch (type) { 311 case JAVATYPE_INT : return "int"; 312 case JAVATYPE_LONG : return "long"; 313 case JAVATYPE_FLOAT : return "float"; 314 case JAVATYPE_DOUBLE : return "double"; 315 case JAVATYPE_BOOLEAN: return "boolean"; 316 case JAVATYPE_STRING : return "java.lang.String"; 317 case JAVATYPE_BYTES : return "com.google.protobuf.ByteString"; 318 case JAVATYPE_ENUM : return NULL; 319 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 GOOGLE_LOG(FATAL) << "Can't get here."; 326 return NULL; 327 } 328 329 const char* BoxedPrimitiveTypeName(JavaType type) { 330 switch (type) { 331 case JAVATYPE_INT : return "java.lang.Integer"; 332 case JAVATYPE_LONG : return "java.lang.Long"; 333 case JAVATYPE_FLOAT : return "java.lang.Float"; 334 case JAVATYPE_DOUBLE : return "java.lang.Double"; 335 case JAVATYPE_BOOLEAN: return "java.lang.Boolean"; 336 case JAVATYPE_STRING : return "java.lang.String"; 337 case JAVATYPE_BYTES : return "com.google.protobuf.ByteString"; 338 case JAVATYPE_ENUM : return NULL; 339 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 GOOGLE_LOG(FATAL) << "Can't get here."; 346 return NULL; 347 } 348 349 const char* FieldTypeName(FieldDescriptor::Type field_type) { 350 switch (field_type) { 351 case FieldDescriptor::TYPE_INT32 : return "INT32"; 352 case FieldDescriptor::TYPE_UINT32 : return "UINT32"; 353 case FieldDescriptor::TYPE_SINT32 : return "SINT32"; 354 case FieldDescriptor::TYPE_FIXED32 : return "FIXED32"; 355 case FieldDescriptor::TYPE_SFIXED32: return "SFIXED32"; 356 case FieldDescriptor::TYPE_INT64 : return "INT64"; 357 case FieldDescriptor::TYPE_UINT64 : return "UINT64"; 358 case FieldDescriptor::TYPE_SINT64 : return "SINT64"; 359 case FieldDescriptor::TYPE_FIXED64 : return "FIXED64"; 360 case FieldDescriptor::TYPE_SFIXED64: return "SFIXED64"; 361 case FieldDescriptor::TYPE_FLOAT : return "FLOAT"; 362 case FieldDescriptor::TYPE_DOUBLE : return "DOUBLE"; 363 case FieldDescriptor::TYPE_BOOL : return "BOOL"; 364 case FieldDescriptor::TYPE_STRING : return "STRING"; 365 case FieldDescriptor::TYPE_BYTES : return "BYTES"; 366 case FieldDescriptor::TYPE_ENUM : return "ENUM"; 367 case FieldDescriptor::TYPE_GROUP : return "GROUP"; 368 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 GOOGLE_LOG(FATAL) << "Can't get here."; 375 return NULL; 376 } 377 378 bool AllAscii(const string& text) { 379 for (int i = 0; i < text.size(); i++) { 380 if ((text[i] & 0x80) != 0) { 381 return false; 382 } 383 } 384 return true; 385 } 386 387 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 switch (field->cpp_type()) { 392 case FieldDescriptor::CPPTYPE_INT32: 393 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 return SimpleItoa(static_cast<int32>(field->default_value_uint32())); 397 case FieldDescriptor::CPPTYPE_INT64: 398 return SimpleItoa(field->default_value_int64()) + "L"; 399 case FieldDescriptor::CPPTYPE_UINT64: 400 return SimpleItoa(static_cast<int64>(field->default_value_uint64())) + 401 "L"; 402 case FieldDescriptor::CPPTYPE_DOUBLE: { 403 double value = field->default_value_double(); 404 if (value == numeric_limits<double>::infinity()) { 405 return "Double.POSITIVE_INFINITY"; 406 } else if (value == -numeric_limits<double>::infinity()) { 407 return "Double.NEGATIVE_INFINITY"; 408 } else if (value != value) { 409 return "Double.NaN"; 410 } else { 411 return SimpleDtoa(value) + "D"; 412 } 413 } 414 case FieldDescriptor::CPPTYPE_FLOAT: { 415 float value = field->default_value_float(); 416 if (value == numeric_limits<float>::infinity()) { 417 return "Float.POSITIVE_INFINITY"; 418 } else if (value == -numeric_limits<float>::infinity()) { 419 return "Float.NEGATIVE_INFINITY"; 420 } else if (value != value) { 421 return "Float.NaN"; 422 } else { 423 return SimpleFtoa(value) + "F"; 424 } 425 } 426 case FieldDescriptor::CPPTYPE_BOOL: 427 return field->default_value_bool() ? "true" : "false"; 428 case FieldDescriptor::CPPTYPE_STRING: 429 if (GetType(field) == FieldDescriptor::TYPE_BYTES) { 430 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 CEscape(field->default_value_string())); 435 } else { 436 return "com.google.protobuf.ByteString.EMPTY"; 437 } 438 } else { 439 if (AllAscii(field->default_value_string())) { 440 // All chars are ASCII. In this case CEscape() works fine. 441 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 CEscape(field->default_value_string())); 447 } 448 } 449 450 case FieldDescriptor::CPPTYPE_ENUM: 451 return name_resolver->GetClassName(field->enum_type(), immutable) + "." + 452 field->default_value_enum()->name(); 453 454 case FieldDescriptor::CPPTYPE_MESSAGE: 455 return name_resolver->GetClassName(field->message_type(), immutable) + 456 ".getDefaultInstance()"; 457 458 // No default because we want the compiler to complain if any new 459 // types are added. 460 } 461 462 GOOGLE_LOG(FATAL) << "Can't get here."; 463 return ""; 464 } 465 466 bool IsDefaultValueJavaDefault(const FieldDescriptor* field) { 467 // Switch on CppType since we need to know which default_value_* method 468 // of FieldDescriptor to call. 469 switch (field->cpp_type()) { 470 case FieldDescriptor::CPPTYPE_INT32: 471 return field->default_value_int32() == 0; 472 case FieldDescriptor::CPPTYPE_UINT32: 473 return field->default_value_uint32() == 0; 474 case FieldDescriptor::CPPTYPE_INT64: 475 return field->default_value_int64() == 0L; 476 case FieldDescriptor::CPPTYPE_UINT64: 477 return field->default_value_uint64() == 0L; 478 case FieldDescriptor::CPPTYPE_DOUBLE: 479 return field->default_value_double() == 0.0; 480 case FieldDescriptor::CPPTYPE_FLOAT: 481 return field->default_value_float() == 0.0; 482 case FieldDescriptor::CPPTYPE_BOOL: 483 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 GOOGLE_LOG(FATAL) << "Can't get here."; 495 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 string GetBitFieldName(int index) { 537 string varName = "bitField"; 538 varName += SimpleItoa(index); 539 varName += "_"; 540 return varName; 541 } 542 543 string GetBitFieldNameForBit(int bitIndex) { 544 return GetBitFieldName(bitIndex / 32); 545 } 546 547 namespace { 548 549 string GenerateGetBitInternal(const string& prefix, int bitIndex) { 550 string varName = prefix + GetBitFieldNameForBit(bitIndex); 551 int bitInVarIndex = bitIndex % 32; 552 553 string mask = bit_masks[bitInVarIndex]; 554 string result = "((" + varName + " & " + mask + ") == " + mask + ")"; 555 return result; 556 } 557 558 string GenerateSetBitInternal(const string& prefix, int bitIndex) { 559 string varName = prefix + GetBitFieldNameForBit(bitIndex); 560 int bitInVarIndex = bitIndex % 32; 561 562 string mask = bit_masks[bitInVarIndex]; 563 string result = varName + " |= " + mask; 564 return result; 565 } 566 567 } // namespace 568 569 string GenerateGetBit(int bitIndex) { 570 return GenerateGetBitInternal("", bitIndex); 571 } 572 573 string GenerateSetBit(int bitIndex) { 574 return GenerateSetBitInternal("", bitIndex); 575 } 576 577 string GenerateClearBit(int bitIndex) { 578 string varName = GetBitFieldNameForBit(bitIndex); 579 int bitInVarIndex = bitIndex % 32; 580 581 string mask = bit_masks[bitInVarIndex]; 582 string result = varName + " = (" + varName + " & ~" + mask + ")"; 583 return result; 584 } 585 586 string GenerateGetBitFromLocal(int bitIndex) { 587 return GenerateGetBitInternal("from_", bitIndex); 588 } 589 590 string GenerateSetBitToLocal(int bitIndex) { 591 return GenerateSetBitInternal("to_", bitIndex); 592 } 593 594 string GenerateGetBitMutableLocal(int bitIndex) { 595 return GenerateGetBitInternal("mutable_", bitIndex); 596 } 597 598 string GenerateSetBitMutableLocal(int bitIndex) { 599 return GenerateSetBitInternal("mutable_", bitIndex); 600 } 601 602 bool IsReferenceType(JavaType type) { 603 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 case JAVATYPE_STRING : return true; 610 case JAVATYPE_BYTES : return true; 611 case JAVATYPE_ENUM : return true; 612 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 GOOGLE_LOG(FATAL) << "Can't get here."; 619 return false; 620 } 621 622 const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable) { 623 switch (GetType(field)) { 624 case FieldDescriptor::TYPE_INT32 : return "Int32"; 625 case FieldDescriptor::TYPE_UINT32 : return "UInt32"; 626 case FieldDescriptor::TYPE_SINT32 : return "SInt32"; 627 case FieldDescriptor::TYPE_FIXED32 : return "Fixed32"; 628 case FieldDescriptor::TYPE_SFIXED32: return "SFixed32"; 629 case FieldDescriptor::TYPE_INT64 : return "Int64"; 630 case FieldDescriptor::TYPE_UINT64 : return "UInt64"; 631 case FieldDescriptor::TYPE_SINT64 : return "SInt64"; 632 case FieldDescriptor::TYPE_FIXED64 : return "Fixed64"; 633 case FieldDescriptor::TYPE_SFIXED64: return "SFixed64"; 634 case FieldDescriptor::TYPE_FLOAT : return "Float"; 635 case FieldDescriptor::TYPE_DOUBLE : return "Double"; 636 case FieldDescriptor::TYPE_BOOL : return "Bool"; 637 case FieldDescriptor::TYPE_STRING : return "String"; 638 case FieldDescriptor::TYPE_BYTES : { 639 return "Bytes"; 640 } 641 case FieldDescriptor::TYPE_ENUM : return "Enum"; 642 case FieldDescriptor::TYPE_GROUP : return "Group"; 643 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 GOOGLE_LOG(FATAL) << "Can't get here."; 650 return NULL; 651 } 652 653 // For encodings with fixed sizes, returns that size in bytes. Otherwise 654 // returns -1. 655 int FixedSize(FieldDescriptor::Type type) { 656 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 case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size; 664 case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size; 665 case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size; 666 case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size; 667 case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize; 668 case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize; 669 670 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 GOOGLE_LOG(FATAL) << "Can't get here."; 682 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 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { 688 const FieldDescriptor** fields = 689 new const FieldDescriptor*[descriptor->field_count()]; 690 for (int i = 0; i < descriptor->field_count(); i++) { 691 fields[i] = descriptor->field(i); 692 } 693 std::sort(fields, fields + descriptor->field_count(), 694 FieldOrderingByNumber()); 695 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 bool HasRequiredFields( 704 const Descriptor* type, 705 hash_set<const Descriptor*>* already_seen) { 706 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 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 if (type->extension_range_count() > 0) return true; 723 724 for (int i = 0; i < type->field_count(); i++) { 725 const FieldDescriptor* field = type->field(i); 726 if (field->is_required()) { 727 return true; 728 } 729 if (GetJavaType(field) == JAVATYPE_MESSAGE) { 730 if (HasRequiredFields(field->message_type(), already_seen)) { 731 return true; 732 } 733 } 734 } 735 736 return false; 737 } 738 739 bool HasRequiredFields(const Descriptor* type) { 740 hash_set<const Descriptor*> already_seen; 741 return HasRequiredFields(type, &already_seen); 742 } 743 744 bool HasRepeatedFields(const Descriptor* descriptor) { 745 for (int i = 0; i < descriptor->field_count(); ++i) { 746 const FieldDescriptor* field = descriptor->field(i); 747 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 758