/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/compiler/java/java_message.cc
C++ | 1287 lines | 1022 code | 139 blank | 126 comment | 126 complexity | 66c1ad7ab600afc5545fff4e67637ce1 MD5 | raw file
1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// http://code.google.com/p/protobuf/ 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 <google/protobuf/compiler/java/java_message.h> 38#include <google/protobuf/compiler/java/java_enum.h> 39#include <google/protobuf/compiler/java/java_extension.h> 40#include <google/protobuf/compiler/java/java_helpers.h> 41#include <google/protobuf/stubs/strutil.h> 42#include <google/protobuf/io/printer.h> 43#include <google/protobuf/io/coded_stream.h> 44#include <google/protobuf/wire_format.h> 45#include <google/protobuf/descriptor.pb.h> 46 47namespace google { 48namespace protobuf { 49namespace compiler { 50namespace java { 51 52using internal::WireFormat; 53using internal::WireFormatLite; 54 55namespace { 56 57void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) { 58 // Print the field's proto-syntax definition as a comment. We don't want to 59 // print group bodies so we cut off after the first line. 60 string def = field->DebugString(); 61 printer->Print("// $def$\n", 62 "def", def.substr(0, def.find_first_of('\n'))); 63} 64 65struct FieldOrderingByNumber { 66 inline bool operator()(const FieldDescriptor* a, 67 const FieldDescriptor* b) const { 68 return a->number() < b->number(); 69 } 70}; 71 72struct ExtensionRangeOrdering { 73 bool operator()(const Descriptor::ExtensionRange* a, 74 const Descriptor::ExtensionRange* b) const { 75 return a->start < b->start; 76 } 77}; 78 79// Sort the fields of the given Descriptor by number into a new[]'d array 80// and return it. 81const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { 82 const FieldDescriptor** fields = 83 new const FieldDescriptor*[descriptor->field_count()]; 84 for (int i = 0; i < descriptor->field_count(); i++) { 85 fields[i] = descriptor->field(i); 86 } 87 sort(fields, fields + descriptor->field_count(), 88 FieldOrderingByNumber()); 89 return fields; 90} 91 92// Get an identifier that uniquely identifies this type within the file. 93// This is used to declare static variables related to this type at the 94// outermost file scope. 95string UniqueFileScopeIdentifier(const Descriptor* descriptor) { 96 return "static_" + StringReplace(descriptor->full_name(), ".", "_", true); 97} 98 99// Returns true if the message type has any required fields. If it doesn't, 100// we can optimize out calls to its isInitialized() method. 101// 102// already_seen is used to avoid checking the same type multiple times 103// (and also to protect against recursion). 104static bool HasRequiredFields( 105 const Descriptor* type, 106 hash_set<const Descriptor*>* already_seen) { 107 if (already_seen->count(type) > 0) { 108 // The type is already in cache. This means that either: 109 // a. The type has no required fields. 110 // b. We are in the midst of checking if the type has required fields, 111 // somewhere up the stack. In this case, we know that if the type 112 // has any required fields, they'll be found when we return to it, 113 // and the whole call to HasRequiredFields() will return true. 114 // Therefore, we don't have to check if this type has required fields 115 // here. 116 return false; 117 } 118 already_seen->insert(type); 119 120 // If the type has extensions, an extension with message type could contain 121 // required fields, so we have to be conservative and assume such an 122 // extension exists. 123 if (type->extension_range_count() > 0) return true; 124 125 for (int i = 0; i < type->field_count(); i++) { 126 const FieldDescriptor* field = type->field(i); 127 if (field->is_required()) { 128 return true; 129 } 130 if (GetJavaType(field) == JAVATYPE_MESSAGE) { 131 if (HasRequiredFields(field->message_type(), already_seen)) { 132 return true; 133 } 134 } 135 } 136 137 return false; 138} 139 140static bool HasRequiredFields(const Descriptor* type) { 141 hash_set<const Descriptor*> already_seen; 142 return HasRequiredFields(type, &already_seen); 143} 144 145} // namespace 146 147// =================================================================== 148 149MessageGenerator::MessageGenerator(const Descriptor* descriptor) 150 : descriptor_(descriptor), 151 field_generators_(descriptor) { 152} 153 154MessageGenerator::~MessageGenerator() {} 155 156void MessageGenerator::GenerateStaticVariables(io::Printer* printer) { 157 if (HasDescriptorMethods(descriptor_)) { 158 // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is 159 // used in the construction of descriptors, we have a tricky bootstrapping 160 // problem. To help control static initialization order, we make sure all 161 // descriptors and other static data that depends on them are members of 162 // the outermost class in the file. This way, they will be initialized in 163 // a deterministic order. 164 165 map<string, string> vars; 166 vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); 167 vars["index"] = SimpleItoa(descriptor_->index()); 168 vars["classname"] = ClassName(descriptor_); 169 if (descriptor_->containing_type() != NULL) { 170 vars["parent"] = UniqueFileScopeIdentifier( 171 descriptor_->containing_type()); 172 } 173 if (descriptor_->file()->options().java_multiple_files()) { 174 // We can only make these package-private since the classes that use them 175 // are in separate files. 176 vars["private"] = ""; 177 } else { 178 vars["private"] = "private "; 179 } 180 181 // The descriptor for this type. 182 printer->Print(vars, 183 "$private$static com.google.protobuf.Descriptors.Descriptor\n" 184 " internal_$identifier$_descriptor;\n"); 185 186 // And the FieldAccessorTable. 187 printer->Print(vars, 188 "$private$static\n" 189 " com.google.protobuf.GeneratedMessage.FieldAccessorTable\n" 190 " internal_$identifier$_fieldAccessorTable;\n"); 191 } 192 193 // Generate static members for all nested types. 194 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 195 // TODO(kenton): Reuse MessageGenerator objects? 196 MessageGenerator(descriptor_->nested_type(i)) 197 .GenerateStaticVariables(printer); 198 } 199} 200 201void MessageGenerator::GenerateStaticVariableInitializers( 202 io::Printer* printer) { 203 if (HasDescriptorMethods(descriptor_)) { 204 map<string, string> vars; 205 vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); 206 vars["index"] = SimpleItoa(descriptor_->index()); 207 vars["classname"] = ClassName(descriptor_); 208 if (descriptor_->containing_type() != NULL) { 209 vars["parent"] = UniqueFileScopeIdentifier( 210 descriptor_->containing_type()); 211 } 212 213 // The descriptor for this type. 214 if (descriptor_->containing_type() == NULL) { 215 printer->Print(vars, 216 "internal_$identifier$_descriptor =\n" 217 " getDescriptor().getMessageTypes().get($index$);\n"); 218 } else { 219 printer->Print(vars, 220 "internal_$identifier$_descriptor =\n" 221 " internal_$parent$_descriptor.getNestedTypes().get($index$);\n"); 222 } 223 224 // And the FieldAccessorTable. 225 printer->Print(vars, 226 "internal_$identifier$_fieldAccessorTable = new\n" 227 " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n" 228 " internal_$identifier$_descriptor,\n" 229 " new java.lang.String[] { "); 230 for (int i = 0; i < descriptor_->field_count(); i++) { 231 printer->Print( 232 "\"$field_name$\", ", 233 "field_name", 234 UnderscoresToCapitalizedCamelCase(descriptor_->field(i))); 235 } 236 printer->Print("},\n" 237 " $classname$.class,\n" 238 " $classname$.Builder.class);\n", 239 "classname", ClassName(descriptor_)); 240 } 241 242 // Generate static member initializers for all nested types. 243 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 244 // TODO(kenton): Reuse MessageGenerator objects? 245 MessageGenerator(descriptor_->nested_type(i)) 246 .GenerateStaticVariableInitializers(printer); 247 } 248} 249 250// =================================================================== 251 252void MessageGenerator::GenerateInterface(io::Printer* printer) { 253 254 if (descriptor_->extension_range_count() > 0) { 255 if (HasDescriptorMethods(descriptor_)) { 256 printer->Print( 257 "public interface $classname$OrBuilder extends\n" 258 " com.google.protobuf.GeneratedMessage.\n" 259 " ExtendableMessageOrBuilder<$classname$> {\n", 260 "classname", descriptor_->name()); 261 } else { 262 printer->Print( 263 "public interface $classname$OrBuilder extends \n" 264 " com.google.protobuf.GeneratedMessageLite.\n" 265 " ExtendableMessageOrBuilder<$classname$> {\n", 266 "classname", descriptor_->name()); 267 } 268 } else { 269 if (HasDescriptorMethods(descriptor_)) { 270 printer->Print( 271 "public interface $classname$OrBuilder\n" 272 " extends com.google.protobuf.MessageOrBuilder {\n", 273 "classname", descriptor_->name()); 274 } else { 275 printer->Print( 276 "public interface $classname$OrBuilder\n" 277 " extends com.google.protobuf.MessageLiteOrBuilder {\n", 278 "classname", descriptor_->name()); 279 } 280 } 281 282 printer->Indent(); 283 for (int i = 0; i < descriptor_->field_count(); i++) { 284 printer->Print("\n"); 285 PrintFieldComment(printer, descriptor_->field(i)); 286 field_generators_.get(descriptor_->field(i)) 287 .GenerateInterfaceMembers(printer); 288 } 289 printer->Outdent(); 290 291 printer->Print("}\n"); 292} 293 294// =================================================================== 295 296void MessageGenerator::Generate(io::Printer* printer) { 297 bool is_own_file = 298 descriptor_->containing_type() == NULL && 299 descriptor_->file()->options().java_multiple_files(); 300 301 if (descriptor_->extension_range_count() > 0) { 302 if (HasDescriptorMethods(descriptor_)) { 303 printer->Print( 304 "public $static$ final class $classname$ extends\n" 305 " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n" 306 " $classname$> implements $classname$OrBuilder {\n", 307 "static", is_own_file ? "" : "static", 308 "classname", descriptor_->name()); 309 } else { 310 printer->Print( 311 "public $static$ final class $classname$ extends\n" 312 " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n" 313 " $classname$> implements $classname$OrBuilder {\n", 314 "static", is_own_file ? "" : "static", 315 "classname", descriptor_->name()); 316 } 317 } else { 318 if (HasDescriptorMethods(descriptor_)) { 319 printer->Print( 320 "public $static$ final class $classname$ extends\n" 321 " com.google.protobuf.GeneratedMessage\n" 322 " implements $classname$OrBuilder {\n", 323 "static", is_own_file ? "" : "static", 324 "classname", descriptor_->name()); 325 } else { 326 printer->Print( 327 "public $static$ final class $classname$ extends\n" 328 " com.google.protobuf.GeneratedMessageLite\n" 329 " implements $classname$OrBuilder {\n", 330 "static", is_own_file ? "" : "static", 331 "classname", descriptor_->name()); 332 } 333 } 334 printer->Indent(); 335 printer->Print( 336 "// Use $classname$.newBuilder() to construct.\n" 337 "private $classname$(Builder builder) {\n" 338 " super(builder);\n" 339 "}\n" 340 // Used when constructing the default instance, which cannot be initialized 341 // immediately because it may cyclically refer to other default instances. 342 "private $classname$(boolean noInit) {}\n" 343 "\n" 344 "private static final $classname$ defaultInstance;\n" 345 "public static $classname$ getDefaultInstance() {\n" 346 " return defaultInstance;\n" 347 "}\n" 348 "\n" 349 "public $classname$ getDefaultInstanceForType() {\n" 350 " return defaultInstance;\n" 351 "}\n" 352 "\n", 353 "classname", descriptor_->name()); 354 355 GenerateDescriptorMethods(printer); 356 357 // Nested types 358 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 359 EnumGenerator(descriptor_->enum_type(i)).Generate(printer); 360 } 361 362 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 363 MessageGenerator messageGenerator(descriptor_->nested_type(i)); 364 messageGenerator.GenerateInterface(printer); 365 messageGenerator.Generate(printer); 366 } 367 368 // Integers for bit fields. 369 int totalBits = 0; 370 for (int i = 0; i < descriptor_->field_count(); i++) { 371 totalBits += field_generators_.get(descriptor_->field(i)) 372 .GetNumBitsForMessage(); 373 } 374 int totalInts = (totalBits + 31) / 32; 375 for (int i = 0; i < totalInts; i++) { 376 printer->Print("private int $bit_field_name$;\n", 377 "bit_field_name", GetBitFieldName(i)); 378 } 379 380 // Fields 381 for (int i = 0; i < descriptor_->field_count(); i++) { 382 PrintFieldComment(printer, descriptor_->field(i)); 383 printer->Print("public static final int $constant_name$ = $number$;\n", 384 "constant_name", FieldConstantName(descriptor_->field(i)), 385 "number", SimpleItoa(descriptor_->field(i)->number())); 386 field_generators_.get(descriptor_->field(i)).GenerateMembers(printer); 387 printer->Print("\n"); 388 } 389 390 // Called by the constructor, except in the case of the default instance, 391 // in which case this is called by static init code later on. 392 printer->Print("private void initFields() {\n"); 393 printer->Indent(); 394 for (int i = 0; i < descriptor_->field_count(); i++) { 395 field_generators_.get(descriptor_->field(i)) 396 .GenerateInitializationCode(printer); 397 } 398 printer->Outdent(); 399 printer->Print("}\n"); 400 401 if (HasGeneratedMethods(descriptor_)) { 402 GenerateIsInitialized(printer, MEMOIZE); 403 GenerateMessageSerializationMethods(printer); 404 } 405 406 if (HasEqualsAndHashCode(descriptor_)) { 407 GenerateEqualsAndHashCode(printer); 408 } 409 410 GenerateParseFromMethods(printer); 411 GenerateBuilder(printer); 412 413 // Carefully initialize the default instance in such a way that it doesn't 414 // conflict with other initialization. 415 printer->Print( 416 "\n" 417 "static {\n" 418 " defaultInstance = new $classname$(true);\n" 419 " defaultInstance.initFields();\n" 420 "}\n" 421 "\n" 422 "// @@protoc_insertion_point(class_scope:$full_name$)\n", 423 "classname", descriptor_->name(), 424 "full_name", descriptor_->full_name()); 425 426 // Extensions must be declared after the defaultInstance is initialized 427 // because the defaultInstance is used by the extension to lazily retrieve 428 // the outer class's FileDescriptor. 429 for (int i = 0; i < descriptor_->extension_count(); i++) { 430 ExtensionGenerator(descriptor_->extension(i)).Generate(printer); 431 } 432 433 printer->Outdent(); 434 printer->Print("}\n\n"); 435} 436 437 438// =================================================================== 439 440void MessageGenerator:: 441GenerateMessageSerializationMethods(io::Printer* printer) { 442 scoped_array<const FieldDescriptor*> sorted_fields( 443 SortFieldsByNumber(descriptor_)); 444 445 vector<const Descriptor::ExtensionRange*> sorted_extensions; 446 for (int i = 0; i < descriptor_->extension_range_count(); ++i) { 447 sorted_extensions.push_back(descriptor_->extension_range(i)); 448 } 449 sort(sorted_extensions.begin(), sorted_extensions.end(), 450 ExtensionRangeOrdering()); 451 452 printer->Print( 453 "public void writeTo(com.google.protobuf.CodedOutputStream output)\n" 454 " throws java.io.IOException {\n"); 455 printer->Indent(); 456 // writeTo(CodedOutputStream output) might be invoked without 457 // getSerializedSize() ever being called, but we need the memoized 458 // sizes in case this message has packed fields. Rather than emit checks for 459 // each packed field, just call getSerializedSize() up front for all messages. 460 // In most cases, getSerializedSize() will have already been called anyway by 461 // one of the wrapper writeTo() methods, making this call cheap. 462 printer->Print( 463 "getSerializedSize();\n"); 464 465 if (descriptor_->extension_range_count() > 0) { 466 if (descriptor_->options().message_set_wire_format()) { 467 printer->Print( 468 "com.google.protobuf.GeneratedMessage$lite$\n" 469 " .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n" 470 " newMessageSetExtensionWriter();\n", 471 "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite", 472 "classname", ClassName(descriptor_)); 473 } else { 474 printer->Print( 475 "com.google.protobuf.GeneratedMessage$lite$\n" 476 " .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n" 477 " newExtensionWriter();\n", 478 "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite", 479 "classname", ClassName(descriptor_)); 480 } 481 } 482 483 // Merge the fields and the extension ranges, both sorted by field number. 484 for (int i = 0, j = 0; 485 i < descriptor_->field_count() || j < sorted_extensions.size(); 486 ) { 487 if (i == descriptor_->field_count()) { 488 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); 489 } else if (j == sorted_extensions.size()) { 490 GenerateSerializeOneField(printer, sorted_fields[i++]); 491 } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) { 492 GenerateSerializeOneField(printer, sorted_fields[i++]); 493 } else { 494 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); 495 } 496 } 497 498 if (HasUnknownFields(descriptor_)) { 499 if (descriptor_->options().message_set_wire_format()) { 500 printer->Print( 501 "getUnknownFields().writeAsMessageSetTo(output);\n"); 502 } else { 503 printer->Print( 504 "getUnknownFields().writeTo(output);\n"); 505 } 506 } 507 508 printer->Outdent(); 509 printer->Print( 510 "}\n" 511 "\n" 512 "private int memoizedSerializedSize = -1;\n" 513 "public int getSerializedSize() {\n" 514 " int size = memoizedSerializedSize;\n" 515 " if (size != -1) return size;\n" 516 "\n" 517 " size = 0;\n"); 518 printer->Indent(); 519 520 for (int i = 0; i < descriptor_->field_count(); i++) { 521 field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer); 522 } 523 524 if (descriptor_->extension_range_count() > 0) { 525 if (descriptor_->options().message_set_wire_format()) { 526 printer->Print( 527 "size += extensionsSerializedSizeAsMessageSet();\n"); 528 } else { 529 printer->Print( 530 "size += extensionsSerializedSize();\n"); 531 } 532 } 533 534 if (HasUnknownFields(descriptor_)) { 535 if (descriptor_->options().message_set_wire_format()) { 536 printer->Print( 537 "size += getUnknownFields().getSerializedSizeAsMessageSet();\n"); 538 } else { 539 printer->Print( 540 "size += getUnknownFields().getSerializedSize();\n"); 541 } 542 } 543 544 printer->Outdent(); 545 printer->Print( 546 " memoizedSerializedSize = size;\n" 547 " return size;\n" 548 "}\n" 549 "\n"); 550 551 printer->Print( 552 "private static final long serialVersionUID = 0L;\n" 553 "@java.lang.Override\n" 554 "protected java.lang.Object writeReplace()\n" 555 " throws java.io.ObjectStreamException {\n" 556 " return super.writeReplace();\n" 557 "}\n" 558 "\n"); 559} 560 561void MessageGenerator:: 562GenerateParseFromMethods(io::Printer* printer) { 563 // Note: These are separate from GenerateMessageSerializationMethods() 564 // because they need to be generated even for messages that are optimized 565 // for code size. 566 printer->Print( 567 "public static $classname$ parseFrom(\n" 568 " com.google.protobuf.ByteString data)\n" 569 " throws com.google.protobuf.InvalidProtocolBufferException {\n" 570 " return newBuilder().mergeFrom(data).buildParsed();\n" 571 "}\n" 572 "public static $classname$ parseFrom(\n" 573 " com.google.protobuf.ByteString data,\n" 574 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" 575 " throws com.google.protobuf.InvalidProtocolBufferException {\n" 576 " return newBuilder().mergeFrom(data, extensionRegistry)\n" 577 " .buildParsed();\n" 578 "}\n" 579 "public static $classname$ parseFrom(byte[] data)\n" 580 " throws com.google.protobuf.InvalidProtocolBufferException {\n" 581 " return newBuilder().mergeFrom(data).buildParsed();\n" 582 "}\n" 583 "public static $classname$ parseFrom(\n" 584 " byte[] data,\n" 585 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" 586 " throws com.google.protobuf.InvalidProtocolBufferException {\n" 587 " return newBuilder().mergeFrom(data, extensionRegistry)\n" 588 " .buildParsed();\n" 589 "}\n" 590 "public static $classname$ parseFrom(java.io.InputStream input)\n" 591 " throws java.io.IOException {\n" 592 " return newBuilder().mergeFrom(input).buildParsed();\n" 593 "}\n" 594 "public static $classname$ parseFrom(\n" 595 " java.io.InputStream input,\n" 596 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" 597 " throws java.io.IOException {\n" 598 " return newBuilder().mergeFrom(input, extensionRegistry)\n" 599 " .buildParsed();\n" 600 "}\n" 601 "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n" 602 " throws java.io.IOException {\n" 603 " Builder builder = newBuilder();\n" 604 " if (builder.mergeDelimitedFrom(input)) {\n" 605 " return builder.buildParsed();\n" 606 " } else {\n" 607 " return null;\n" 608 " }\n" 609 "}\n" 610 "public static $classname$ parseDelimitedFrom(\n" 611 " java.io.InputStream input,\n" 612 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" 613 " throws java.io.IOException {\n" 614 " Builder builder = newBuilder();\n" 615 " if (builder.mergeDelimitedFrom(input, extensionRegistry)) {\n" 616 " return builder.buildParsed();\n" 617 " } else {\n" 618 " return null;\n" 619 " }\n" 620 "}\n" 621 "public static $classname$ parseFrom(\n" 622 " com.google.protobuf.CodedInputStream input)\n" 623 " throws java.io.IOException {\n" 624 " return newBuilder().mergeFrom(input).buildParsed();\n" 625 "}\n" 626 "public static $classname$ parseFrom(\n" 627 " com.google.protobuf.CodedInputStream input,\n" 628 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" 629 " throws java.io.IOException {\n" 630 " return newBuilder().mergeFrom(input, extensionRegistry)\n" 631 " .buildParsed();\n" 632 "}\n" 633 "\n", 634 "classname", ClassName(descriptor_)); 635} 636 637void MessageGenerator::GenerateSerializeOneField( 638 io::Printer* printer, const FieldDescriptor* field) { 639 field_generators_.get(field).GenerateSerializationCode(printer); 640} 641 642void MessageGenerator::GenerateSerializeOneExtensionRange( 643 io::Printer* printer, const Descriptor::ExtensionRange* range) { 644 printer->Print( 645 "extensionWriter.writeUntil($end$, output);\n", 646 "end", SimpleItoa(range->end)); 647} 648 649// =================================================================== 650 651void MessageGenerator::GenerateBuilder(io::Printer* printer) { 652 printer->Print( 653 "public static Builder newBuilder() { return Builder.create(); }\n" 654 "public Builder newBuilderForType() { return newBuilder(); }\n" 655 "public static Builder newBuilder($classname$ prototype) {\n" 656 " return newBuilder().mergeFrom(prototype);\n" 657 "}\n" 658 "public Builder toBuilder() { return newBuilder(this); }\n" 659 "\n", 660 "classname", ClassName(descriptor_)); 661 662 if (HasNestedBuilders(descriptor_)) { 663 printer->Print( 664 "@java.lang.Override\n" 665 "protected Builder newBuilderForType(\n" 666 " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n" 667 " Builder builder = new Builder(parent);\n" 668 " return builder;\n" 669 "}\n"); 670 } 671 672 if (descriptor_->extension_range_count() > 0) { 673 if (HasDescriptorMethods(descriptor_)) { 674 printer->Print( 675 "public static final class Builder extends\n" 676 " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n" 677 " $classname$, Builder> implements $classname$OrBuilder {\n", 678 "classname", ClassName(descriptor_)); 679 } else { 680 printer->Print( 681 "public static final class Builder extends\n" 682 " com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<\n" 683 " $classname$, Builder> implements $classname$OrBuilder {\n", 684 "classname", ClassName(descriptor_)); 685 } 686 } else { 687 if (HasDescriptorMethods(descriptor_)) { 688 printer->Print( 689 "public static final class Builder extends\n" 690 " com.google.protobuf.GeneratedMessage.Builder<Builder>\n" 691 " implements $classname$OrBuilder {\n", 692 "classname", ClassName(descriptor_)); 693 } else { 694 printer->Print( 695 "public static final class Builder extends\n" 696 " com.google.protobuf.GeneratedMessageLite.Builder<\n" 697 " $classname$, Builder>\n" 698 " implements $classname$OrBuilder {\n", 699 "classname", ClassName(descriptor_)); 700 } 701 } 702 printer->Indent(); 703 704 GenerateDescriptorMethods(printer); 705 GenerateCommonBuilderMethods(printer); 706 707 if (HasGeneratedMethods(descriptor_)) { 708 GenerateIsInitialized(printer, DONT_MEMOIZE); 709 GenerateBuilderParsingMethods(printer); 710 } 711 712 // Integers for bit fields. 713 int totalBits = 0; 714 for (int i = 0; i < descriptor_->field_count(); i++) { 715 totalBits += field_generators_.get(descriptor_->field(i)) 716 .GetNumBitsForBuilder(); 717 } 718 int totalInts = (totalBits + 31) / 32; 719 for (int i = 0; i < totalInts; i++) { 720 printer->Print("private int $bit_field_name$;\n", 721 "bit_field_name", GetBitFieldName(i)); 722 } 723 724 for (int i = 0; i < descriptor_->field_count(); i++) { 725 printer->Print("\n"); 726 PrintFieldComment(printer, descriptor_->field(i)); 727 field_generators_.get(descriptor_->field(i)) 728 .GenerateBuilderMembers(printer); 729 } 730 731 printer->Print( 732 "\n" 733 "// @@protoc_insertion_point(builder_scope:$full_name$)\n", 734 "full_name", descriptor_->full_name()); 735 736 printer->Outdent(); 737 printer->Print("}\n"); 738} 739 740void MessageGenerator::GenerateDescriptorMethods(io::Printer* printer) { 741 if (HasDescriptorMethods(descriptor_)) { 742 printer->Print( 743 "public static final com.google.protobuf.Descriptors.Descriptor\n" 744 " getDescriptor() {\n" 745 " return $fileclass$.internal_$identifier$_descriptor;\n" 746 "}\n" 747 "\n" 748 "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n" 749 " internalGetFieldAccessorTable() {\n" 750 " return $fileclass$.internal_$identifier$_fieldAccessorTable;\n" 751 "}\n" 752 "\n", 753 "fileclass", ClassName(descriptor_->file()), 754 "identifier", UniqueFileScopeIdentifier(descriptor_)); 755 } 756} 757 758// =================================================================== 759 760void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) { 761 printer->Print( 762 "// Construct using $classname$.newBuilder()\n" 763 "private Builder() {\n" 764 " maybeForceBuilderInitialization();\n" 765 "}\n" 766 "\n", 767 "classname", ClassName(descriptor_)); 768 769 if (HasDescriptorMethods(descriptor_)) { 770 printer->Print( 771 "private Builder(BuilderParent parent) {\n" 772 " super(parent);\n" 773 " maybeForceBuilderInitialization();\n" 774 "}\n", 775 "classname", ClassName(descriptor_)); 776 } 777 778 779 if (HasNestedBuilders(descriptor_)) { 780 printer->Print( 781 "private void maybeForceBuilderInitialization() {\n" 782 " if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {\n"); 783 784 printer->Indent(); 785 printer->Indent(); 786 for (int i = 0; i < descriptor_->field_count(); i++) { 787 field_generators_.get(descriptor_->field(i)) 788 .GenerateFieldBuilderInitializationCode(printer); 789 } 790 printer->Outdent(); 791 printer->Outdent(); 792 793 printer->Print( 794 " }\n" 795 "}\n"); 796 } else { 797 printer->Print( 798 "private void maybeForceBuilderInitialization() {\n" 799 "}\n"); 800 } 801 802 printer->Print( 803 "private static Builder create() {\n" 804 " return new Builder();\n" 805 "}\n" 806 "\n" 807 "public Builder clear() {\n" 808 " super.clear();\n", 809 "classname", ClassName(descriptor_)); 810 811 printer->Indent(); 812 813 for (int i = 0; i < descriptor_->field_count(); i++) { 814 field_generators_.get(descriptor_->field(i)) 815 .GenerateBuilderClearCode(printer); 816 } 817 818 printer->Outdent(); 819 820 printer->Print( 821 " return this;\n" 822 "}\n" 823 "\n" 824 "public Builder clone() {\n" 825 " return create().mergeFrom(buildPartial());\n" 826 "}\n" 827 "\n", 828 "classname", ClassName(descriptor_)); 829 if (HasDescriptorMethods(descriptor_)) { 830 printer->Print( 831 "public com.google.protobuf.Descriptors.Descriptor\n" 832 " getDescriptorForType() {\n" 833 " return $classname$.getDescriptor();\n" 834 "}\n" 835 "\n", 836 "classname", ClassName(descriptor_)); 837 } 838 printer->Print( 839 "public $classname$ getDefaultInstanceForType() {\n" 840 " return $classname$.getDefaultInstance();\n" 841 "}\n" 842 "\n", 843 "classname", ClassName(descriptor_)); 844 845 // ----------------------------------------------------------------- 846 847 printer->Print( 848 "public $classname$ build() {\n" 849 " $classname$ result = buildPartial();\n" 850 " if (!result.isInitialized()) {\n" 851 " throw newUninitializedMessageException(result);\n" 852 " }\n" 853 " return result;\n" 854 "}\n" 855 "\n" 856 "private $classname$ buildParsed()\n" 857 " throws com.google.protobuf.InvalidProtocolBufferException {\n" 858 " $classname$ result = buildPartial();\n" 859 " if (!result.isInitialized()) {\n" 860 " throw newUninitializedMessageException(\n" 861 " result).asInvalidProtocolBufferException();\n" 862 " }\n" 863 " return result;\n" 864 "}\n" 865 "\n" 866 "public $classname$ buildPartial() {\n" 867 " $classname$ result = new $classname$(this);\n", 868 "classname", ClassName(descriptor_)); 869 870 printer->Indent(); 871 872 // Local vars for from and to bit fields to avoid accessing the builder and 873 // message over and over for these fields. Seems to provide a slight 874 // perforamance improvement in micro benchmark and this is also what proto1 875 // code does. 876 int totalBuilderBits = 0; 877 int totalMessageBits = 0; 878 for (int i = 0; i < descriptor_->field_count(); i++) { 879 const FieldGenerator& field = field_generators_.get(descriptor_->field(i)); 880 totalBuilderBits += field.GetNumBitsForBuilder(); 881 totalMessageBits += field.GetNumBitsForMessage(); 882 } 883 int totalBuilderInts = (totalBuilderBits + 31) / 32; 884 int totalMessageInts = (totalMessageBits + 31) / 32; 885 for (int i = 0; i < totalBuilderInts; i++) { 886 printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n", 887 "bit_field_name", GetBitFieldName(i)); 888 } 889 for (int i = 0; i < totalMessageInts; i++) { 890 printer->Print("int to_$bit_field_name$ = 0;\n", 891 "bit_field_name", GetBitFieldName(i)); 892 } 893 894 // Output generation code for each field. 895 for (int i = 0; i < descriptor_->field_count(); i++) { 896 field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer); 897 } 898 899 // Copy the bit field results to the generated message 900 for (int i = 0; i < totalMessageInts; i++) { 901 printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n", 902 "bit_field_name", GetBitFieldName(i)); 903 } 904 905 printer->Outdent(); 906 907 if (HasDescriptorMethods(descriptor_)) { 908 printer->Print( 909 " onBuilt();\n"); 910 } 911 912 printer->Print( 913 " return result;\n" 914 "}\n" 915 "\n", 916 "classname", ClassName(descriptor_)); 917 918 // ----------------------------------------------------------------- 919 920 if (HasGeneratedMethods(descriptor_)) { 921 // MergeFrom(Message other) requires the ability to distinguish the other 922 // messages type by its descriptor. 923 if (HasDescriptorMethods(descriptor_)) { 924 printer->Print( 925 "public Builder mergeFrom(com.google.protobuf.Message other) {\n" 926 " if (other instanceof $classname$) {\n" 927 " return mergeFrom(($classname$)other);\n" 928 " } else {\n" 929 " super.mergeFrom(other);\n" 930 " return this;\n" 931 " }\n" 932 "}\n" 933 "\n", 934 "classname", ClassName(descriptor_)); 935 } 936 937 printer->Print( 938 "public Builder mergeFrom($classname$ other) {\n" 939 // Optimization: If other is the default instance, we know none of its 940 // fields are set so we can skip the merge. 941 " if (other == $classname$.getDefaultInstance()) return this;\n", 942 "classname", ClassName(descriptor_)); 943 printer->Indent(); 944 945 for (int i = 0; i < descriptor_->field_count(); i++) { 946 field_generators_.get(descriptor_->field(i)).GenerateMergingCode(printer); 947 } 948 949 printer->Outdent(); 950 951 // if message type has extensions 952 if (descriptor_->extension_range_count() > 0) { 953 printer->Print( 954 " this.mergeExtensionFields(other);\n"); 955 } 956 957 if (HasUnknownFields(descriptor_)) { 958 printer->Print( 959 " this.mergeUnknownFields(other.getUnknownFields());\n"); 960 } 961 962 printer->Print( 963 " return this;\n" 964 "}\n" 965 "\n"); 966 } 967} 968 969// =================================================================== 970 971void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { 972 scoped_array<const FieldDescriptor*> sorted_fields( 973 SortFieldsByNumber(descriptor_)); 974 975 printer->Print( 976 "public Builder mergeFrom(\n" 977 " com.google.protobuf.CodedInputStream input,\n" 978 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" 979 " throws java.io.IOException {\n"); 980 printer->Indent(); 981 982 if (HasUnknownFields(descriptor_)) { 983 printer->Print( 984 "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n" 985 " com.google.protobuf.UnknownFieldSet.newBuilder(\n" 986 " this.getUnknownFields());\n"); 987 } 988 989 printer->Print( 990 "while (true) {\n"); 991 printer->Indent(); 992 993 printer->Print( 994 "int tag = input.readTag();\n" 995 "switch (tag) {\n"); 996 printer->Indent(); 997 998 if (HasUnknownFields(descriptor_)) { 999 printer->Print( 1000 "case 0:\n" // zero signals EOF / limit reached 1001 " this.setUnknownFields(unknownFields.build());\n" 1002 " $on_changed$\n" 1003 " return this;\n" 1004 "default: {\n" 1005 " if (!parseUnknownField(input, unknownFields,\n" 1006 " extensionRegistry, tag)) {\n" 1007 " this.setUnknownFields(unknownFields.build());\n" 1008 " $on_changed$\n" 1009 " return this;\n" // it's an endgroup tag 1010 " }\n" 1011 " break;\n" 1012 "}\n", 1013 "on_changed", HasDescriptorMethods(descriptor_) ? "onChanged();" : ""); 1014 } else { 1015 printer->Print( 1016 "case 0:\n" // zero signals EOF / limit reached 1017 " $on_changed$\n" 1018 " return this;\n" 1019 "default: {\n" 1020 " if (!parseUnknownField(input, extensionRegistry, tag)) {\n" 1021 " $on_changed$\n" 1022 " return this;\n" // it's an endgroup tag 1023 " }\n" 1024 " break;\n" 1025 "}\n", 1026 "on_changed", HasDescriptorMethods(descriptor_) ? "onChanged();" : ""); 1027 } 1028 1029 for (int i = 0; i < descriptor_->field_count(); i++) { 1030 const FieldDescriptor* field = sorted_fields[i]; 1031 uint32 tag = WireFormatLite::MakeTag(field->number(), 1032 WireFormat::WireTypeForFieldType(field->type())); 1033 1034 printer->Print( 1035 "case $tag$: {\n", 1036 "tag", SimpleItoa(tag)); 1037 printer->Indent(); 1038 1039 field_generators_.get(field).GenerateParsingCode(printer); 1040 1041 printer->Outdent(); 1042 printer->Print( 1043 " break;\n" 1044 "}\n"); 1045 1046 if (field->is_packable()) { 1047 // To make packed = true wire compatible, we generate parsing code from a 1048 // packed version of this field regardless of field->options().packed(). 1049 uint32 packed_tag = WireFormatLite::MakeTag(field->number(), 1050 WireFormatLite::WIRETYPE_LENGTH_DELIMITED); 1051 printer->Print( 1052 "case $tag$: {\n", 1053 "tag", SimpleItoa(packed_tag)); 1054 printer->Indent(); 1055 1056 field_generators_.get(field).GenerateParsingCodeFromPacked(printer); 1057 1058 printer->Outdent(); 1059 printer->Print( 1060 " break;\n" 1061 "}\n"); 1062 } 1063 } 1064 1065 printer->Outdent(); 1066 printer->Outdent(); 1067 printer->Outdent(); 1068 printer->Print( 1069 " }\n" // switch (tag) 1070 " }\n" // while (true) 1071 "}\n" 1072 1073 "\n"); 1074} 1075 1076// =================================================================== 1077 1078void MessageGenerator::GenerateIsInitialized( 1079 io::Printer* printer, UseMemoization useMemoization) { 1080 bool memoization = useMemoization == MEMOIZE; 1081 if (memoization) { 1082 // Memoizes whether the protocol buffer is fully initialized (has all 1083 // required fields). -1 means not yet computed. 0 means false and 1 means 1084 // true. 1085 printer->Print( 1086 "private byte memoizedIsInitialized = -1;\n"); 1087 } 1088 printer->Print( 1089 "public final boolean isInitialized() {\n"); 1090 printer->Indent(); 1091 1092 if (memoization) { 1093 printer->Print( 1094 "byte isInitialized = memoizedIsInitialized;\n" 1095 "if (isInitialized != -1) return isInitialized == 1;\n" 1096 "\n"); 1097 } 1098 1099 // Check that all required fields in this message are set. 1100 // TODO(kenton): We can optimize this when we switch to putting all the 1101 // "has" fields into a single bitfield. 1102 for (int i = 0; i < descriptor_->field_count(); i++) { 1103 const FieldDescriptor* field = descriptor_->field(i); 1104 1105 if (field->is_required()) { 1106 printer->Print( 1107 "if (!has$name$()) {\n" 1108 " $memoize$\n" 1109 " return false;\n" 1110 "}\n", 1111 "name", UnderscoresToCapitalizedCamelCase(field), 1112 "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); 1113 } 1114 } 1115 1116 // Now check that all embedded messages are initialized. 1117 for (int i = 0; i < descriptor_->field_count(); i++) { 1118 const FieldDescriptor* field = descriptor_->field(i); 1119 if (GetJavaType(field) == JAVATYPE_MESSAGE && 1120 HasRequiredFields(field->message_type())) { 1121 switch (field->label()) { 1122 case FieldDescriptor::LABEL_REQUIRED: 1123 printer->Print( 1124 "if (!get$name$().isInitialized()) {\n" 1125 " $memoize$\n" 1126 " return false;\n" 1127 "}\n", 1128 "type", ClassName(field->message_type()), 1129 "name", UnderscoresToCapitalizedCamelCase(field), 1130 "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); 1131 break; 1132 case FieldDescriptor::LABEL_OPTIONAL: 1133 printer->Print( 1134 "if (has$name$()) {\n" 1135 " if (!get$name$().isInitialized()) {\n" 1136 " $memoize$\n" 1137 " return false;\n" 1138 " }\n" 1139 "}\n", 1140 "type", ClassName(field->message_type()), 1141 "name", UnderscoresToCapitalizedCamelCase(field), 1142 "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); 1143 break; 1144 case FieldDescriptor::LABEL_REPEATED: 1145 printer->Print( 1146 "for (int i = 0; i < get$name$Count(); i++) {\n" 1147 " if (!get$name$(i).isInitialized()) {\n" 1148 " $memoize$\n" 1149 " return false;\n" 1150 " }\n" 1151 "}\n", 1152 "type", ClassName(field->message_type()), 1153 "name", UnderscoresToCapitalizedCamelCase(field), 1154 "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); 1155 break; 1156 } 1157 } 1158 } 1159 1160 if (descriptor_->extension_range_count() > 0) { 1161 printer->Print( 1162 "if (!extensionsAreInitialized()) {\n" 1163 " $memoize$\n" 1164 " return false;\n" 1165 "}\n", 1166 "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); 1167 } 1168 1169 printer->Outdent(); 1170 1171 if (memoization) { 1172 printer->Print( 1173 " memoizedIsInitialized = 1;\n"); 1174 } 1175 1176 printer->Print( 1177 " return true;\n" 1178 "}\n" 1179 "\n"); 1180} 1181 1182// =================================================================== 1183 1184void MessageGenerator::GenerateEqualsAndHashCode(io::Printer* printer) { 1185 printer->Print( 1186 "@java.lang.Override\n" 1187 "public boolean equals(final java.lang.Object obj) {\n"); 1188 printer->Indent(); 1189 printer->Print( 1190 "if (obj == this) {\n" 1191 " return true;\n" 1192 "}\n" 1193 "if (!(obj instanceof $classname$)) {\n" 1194 " return super.equals(obj);\n" 1195 "}\n" 1196 "$classname$ other = ($classname$) obj;\n" 1197 "\n", 1198 "classname", ClassName(descriptor_)); 1199 1200 printer->Print("boolean result = true;\n"); 1201 for (int i = 0; i < descriptor_->field_count(); i++) { 1202 const FieldDescriptor* field = descriptor_->field(i); 1203 if (!field->is_repeated()) { 1204 printer->Print( 1205 "result = result && (has$name$() == other.has$name$());\n" 1206 "if (has$name$()) {\n", 1207 "name", UnderscoresToCapitalizedCamelCase(field)); 1208 printer->Indent(); 1209 } 1210 field_generators_.get(field).GenerateEqualsCode(printer); 1211 if (!field->is_repeated()) { 1212 printer->Outdent(); 1213 printer->Print( 1214 "}\n"); 1215 } 1216 } 1217 if (HasDescriptorMethods(descriptor_)) { 1218 printer->Print( 1219 "result = result &&\n" 1220 " getUnknownFields().equals(other.getUnknownFields());\n"); 1221 if (descriptor_->extension_range_count() > 0) { 1222 printer->Print( 1223 "result = result &&\n" 1224 " getExtensionFields().equals(other.getExtensionFields());\n"); 1225 } 1226 } 1227 printer->Print( 1228 "return result;\n"); 1229 printer->Outdent(); 1230 printer->Print( 1231 "}\n" 1232 "\n"); 1233 1234 printer->Print( 1235 "@java.lang.Override\n" 1236 "public int hashCode() {\n"); 1237 printer->Indent(); 1238 printer->Print( 1239 "int hash = 41;\n" 1240 "hash = (19 * hash) + getDescriptorForType().hashCode();\n"); 1241 for (int i = 0; i < descriptor_->field_count(); i++) { 1242 const FieldDescriptor* field = descriptor_->field(i); 1243 if (!field->is_repeated()) { 1244 printer->Print( 1245 "if (has$name$()) {\n", 1246 "name", UnderscoresToCapitalizedCamelCase(field)); 1247 printer->Indent(); 1248 } 1249 field_generators_.get(field).GenerateHashCode(printer); 1250 if (!field->is_repeated()) { 1251 printer->Outdent(); 1252 printer->Print("}\n"); 1253 } 1254 } 1255 if (HasDescriptorMethods(descriptor_)) { 1256 if (descriptor_->extension_range_count() > 0) { 1257 printer->Print( 1258 "hash = hashFields(hash, getExtensionFields());\n"); 1259 } 1260 } 1261 printer->Print( 1262 "hash = (29 * hash) + getUnknownFields().hashCode();\n" 1263 "return hash;\n"); 1264 printer->Outdent(); 1265 printer->Print( 1266 "}\n" 1267 "\n"); 1268} 1269 1270// =================================================================== 1271 1272void MessageGenerator::GenerateExtensionRegistrationCode(io::Printer* printer) { 1273 for (int i = 0; i < descriptor_->extension_count(); i++) { 1274 ExtensionGenerator(descriptor_->extension(i)) 1275 .GenerateRegistrationCode(printer); 1276 } 1277 1278 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 1279 MessageGenerator(descriptor_->nested_type(i)) 1280 .GenerateExtensionRegistrationCode(printer); 1281 } 1282} 1283 1284} // namespace java 1285} // namespace compiler 1286} // namespace protobuf 1287} // namespace google