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: dweis@google.com (Daniel Weis) 32// Based on original Protocol Buffers design by 33// Sanjay Ghemawat, Jeff Dean, and others. 34 35#include <google/protobuf/compiler/java/java_message_lite.h> 36 37#include <algorithm> 38#include <google/protobuf/stubs/hash.h> 39#include <map> 40#include <memory> 41#ifndef _SHARED_PTR_H 42#include <google/protobuf/stubs/shared_ptr.h> 43#endif 44#include <vector> 45 46#include <google/protobuf/compiler/java/java_context.h> 47#include <google/protobuf/compiler/java/java_doc_comment.h> 48#include <google/protobuf/compiler/java/java_enum_lite.h> 49#include <google/protobuf/compiler/java/java_extension_lite.h> 50#include <google/protobuf/compiler/java/java_generator_factory.h> 51#include <google/protobuf/compiler/java/java_helpers.h> 52#include <google/protobuf/compiler/java/java_message_builder.h> 53#include <google/protobuf/compiler/java/java_message_builder_lite.h> 54#include <google/protobuf/compiler/java/java_name_resolver.h> 55#include <google/protobuf/io/coded_stream.h> 56#include <google/protobuf/io/printer.h> 57#include <google/protobuf/descriptor.pb.h> 58#include <google/protobuf/wire_format.h> 59#include <google/protobuf/stubs/strutil.h> 60#include <google/protobuf/stubs/substitute.h> 61 62namespace google { 63namespace protobuf { 64namespace compiler { 65namespace java { 66 67using internal::WireFormat; 68using internal::WireFormatLite; 69 70namespace { 71bool GenerateHasBits(const Descriptor* descriptor) { 72 return SupportFieldPresence(descriptor->file()) || 73 HasRepeatedFields(descriptor); 74} 75 76string MapValueImmutableClassdName(const Descriptor* descriptor, 77 ClassNameResolver* name_resolver) { 78 const FieldDescriptor* value_field = descriptor->FindFieldByName("value"); 79 GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type()); 80 return name_resolver->GetImmutableClassName(value_field->message_type()); 81} 82} // namespace 83 84// =================================================================== 85ImmutableMessageLiteGenerator::ImmutableMessageLiteGenerator( 86 const Descriptor* descriptor, Context* context) 87 : MessageGenerator(descriptor), context_(context), 88 name_resolver_(context->GetNameResolver()), 89 field_generators_(descriptor, context_) { 90 GOOGLE_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite())) 91 << "Generator factory error: A lite message generator is used to " 92 "generate non-lite messages."; 93} 94 95ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {} 96 97void ImmutableMessageLiteGenerator::GenerateStaticVariables( 98 io::Printer* printer, int* bytecode_estimate) { 99 // Generate static members for all nested types. 100 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 101 // TODO(kenton): Reuse MessageGenerator objects? 102 ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) 103 .GenerateStaticVariables(printer, bytecode_estimate); 104 } 105} 106 107int ImmutableMessageLiteGenerator::GenerateStaticVariableInitializers( 108 io::Printer* printer) { 109 int bytecode_estimate = 0; 110 // Generate static member initializers for all nested types. 111 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 112 // TODO(kenton): Reuse MessageGenerator objects? 113 bytecode_estimate += 114 ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) 115 .GenerateStaticVariableInitializers(printer); 116 } 117 return bytecode_estimate; 118} 119 120// =================================================================== 121 122void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { 123 if (descriptor_->extension_range_count() > 0) { 124 printer->Print( 125 "public interface $classname$OrBuilder extends \n" 126 " $extra_interfaces$\n" 127 " com.google.protobuf.GeneratedMessageLite.\n" 128 " ExtendableMessageOrBuilder<\n" 129 " $classname$, $classname$.Builder> {\n", 130 "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), 131 "classname", descriptor_->name()); 132 } else { 133 printer->Print( 134 "public interface $classname$OrBuilder extends\n" 135 " $extra_interfaces$\n" 136 " com.google.protobuf.MessageLiteOrBuilder {\n", 137 "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), 138 "classname", descriptor_->name()); 139 } 140 141 printer->Indent(); 142 for (int i = 0; i < descriptor_->field_count(); i++) { 143 printer->Print("\n"); 144 field_generators_.get(descriptor_->field(i)) 145 .GenerateInterfaceMembers(printer); 146 } 147 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 148 printer->Print( 149 "\n" 150 "public $classname$.$oneof_capitalized_name$Case " 151 "get$oneof_capitalized_name$Case();\n", 152 "oneof_capitalized_name", 153 context_->GetOneofGeneratorInfo( 154 descriptor_->oneof_decl(i))->capitalized_name, 155 "classname", 156 context_->GetNameResolver()->GetImmutableClassName(descriptor_)); 157 } 158 printer->Outdent(); 159 160 printer->Print("}\n"); 161} 162 163// =================================================================== 164 165void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { 166 bool is_own_file = 167 descriptor_->containing_type() == NULL && 168 MultipleJavaFiles(descriptor_->file(), /* immutable = */ true); 169 170 map<string, string> variables; 171 variables["static"] = is_own_file ? " " : " static "; 172 variables["classname"] = descriptor_->name(); 173 variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); 174 175 WriteMessageDocComment(printer, descriptor_); 176 177 // The builder_type stores the super type name of the nested Builder class. 178 string builder_type; 179 if (descriptor_->extension_range_count() > 0) { 180 printer->Print(variables, 181 "public $static$final class $classname$ extends\n" 182 " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n" 183 " $classname$, $classname$.Builder> implements\n" 184 " $extra_interfaces$\n" 185 " $classname$OrBuilder {\n"); 186 builder_type = strings::Substitute( 187 "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>", 188 name_resolver_->GetImmutableClassName(descriptor_)); 189 } else { 190 printer->Print(variables, 191 "public $static$final class $classname$ extends\n" 192 " com.google.protobuf.GeneratedMessageLite<\n" 193 " $classname$, $classname$.Builder> implements\n" 194 " $extra_interfaces$\n" 195 " $classname$OrBuilder {\n"); 196 197 builder_type = "com.google.protobuf.GeneratedMessageLite.Builder"; 198 } 199 printer->Indent(); 200 201 202 GenerateConstructor(printer); 203 204 // Nested types 205 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 206 EnumLiteGenerator(descriptor_->enum_type(i), true, context_) 207 .Generate(printer); 208 } 209 210 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 211 // Don't generate Java classes for map entry messages. 212 if (IsMapEntry(descriptor_->nested_type(i))) continue; 213 ImmutableMessageLiteGenerator messageGenerator( 214 descriptor_->nested_type(i), context_); 215 messageGenerator.GenerateInterface(printer); 216 messageGenerator.Generate(printer); 217 } 218 219 if (GenerateHasBits(descriptor_)) { 220 // Integers for bit fields. 221 int totalBits = 0; 222 for (int i = 0; i < descriptor_->field_count(); i++) { 223 totalBits += field_generators_.get(descriptor_->field(i)) 224 .GetNumBitsForMessage(); 225 } 226 int totalInts = (totalBits + 31) / 32; 227 for (int i = 0; i < totalInts; i++) { 228 printer->Print("private int $bit_field_name$;\n", 229 "bit_field_name", GetBitFieldName(i)); 230 } 231 } 232 233 // oneof 234 map<string, string> vars; 235 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 236 vars["oneof_name"] = context_->GetOneofGeneratorInfo( 237 descriptor_->oneof_decl(i))->name; 238 vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo( 239 descriptor_->oneof_decl(i))->capitalized_name; 240 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index()); 241 // oneofCase_ and oneof_ 242 printer->Print(vars, 243 "private int $oneof_name$Case_ = 0;\n" 244 "private java.lang.Object $oneof_name$_;\n"); 245 // OneofCase enum 246 printer->Print(vars, 247 "public enum $oneof_capitalized_name$Case\n" 248 " implements com.google.protobuf.Internal.EnumLite {\n"); 249 printer->Indent(); 250 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 251 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); 252 printer->Print( 253 "$field_name$($field_number$),\n", 254 "field_name", 255 ToUpper(field->name()), 256 "field_number", 257 SimpleItoa(field->number())); 258 } 259 printer->Print( 260 "$cap_oneof_name$_NOT_SET(0);\n", 261 "cap_oneof_name", 262 ToUpper(vars["oneof_name"])); 263 printer->Print(vars, 264 "private final int value;\n" 265 "private $oneof_capitalized_name$Case(int value) {\n" 266 " this.value = value;\n" 267 "}\n"); 268 printer->Print(vars, 269 "/**\n" 270 " * @deprecated Use {@link #forNumber(int)} instead.\n" 271 " */\n" 272 "@java.lang.Deprecated\n" 273 "public static $oneof_capitalized_name$Case valueOf(int value) {\n" 274 " return forNumber(value);\n" 275 "}\n" 276 "\n" 277 "public static $oneof_capitalized_name$Case forNumber(int value) {\n" 278 " switch (value) {\n"); 279 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 280 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); 281 printer->Print( 282 " case $field_number$: return $field_name$;\n", 283 "field_number", 284 SimpleItoa(field->number()), 285 "field_name", 286 ToUpper(field->name())); 287 } 288 printer->Print( 289 " case 0: return $cap_oneof_name$_NOT_SET;\n" 290 " default: return null;\n" 291 " }\n" 292 "}\n" 293 "public int getNumber() {\n" 294 " return this.value;\n" 295 "}\n", 296 "cap_oneof_name", ToUpper(vars["oneof_name"])); 297 printer->Outdent(); 298 printer->Print("};\n\n"); 299 // oneofCase() 300 printer->Print(vars, 301 "public $oneof_capitalized_name$Case\n" 302 "get$oneof_capitalized_name$Case() {\n" 303 " return $oneof_capitalized_name$Case.forNumber(\n" 304 " $oneof_name$Case_);\n" 305 "}\n" 306 "\n" 307 "private void clear$oneof_capitalized_name$() {\n" 308 " $oneof_name$Case_ = 0;\n" 309 " $oneof_name$_ = null;\n" 310 "}\n" 311 "\n"); 312 } 313 314 // Fields 315 for (int i = 0; i < descriptor_->field_count(); i++) { 316 printer->Print("public static final int $constant_name$ = $number$;\n", 317 "constant_name", FieldConstantName(descriptor_->field(i)), 318 "number", SimpleItoa(descriptor_->field(i)->number())); 319 field_generators_.get(descriptor_->field(i)).GenerateMembers(printer); 320 printer->Print("\n"); 321 } 322 323 GenerateMessageSerializationMethods(printer); 324 325 GenerateParseFromMethods(printer); 326 GenerateBuilder(printer); 327 328 if (HasRequiredFields(descriptor_)) { 329 // Memoizes whether the protocol buffer is fully initialized (has all 330 // required fields). -1 means not yet computed. 0 means false and 1 means 331 // true. 332 printer->Print( 333 "private byte memoizedIsInitialized = -1;\n"); 334 } 335 336 printer->Print( 337 "protected final Object dynamicMethod(\n" 338 " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n" 339 " Object arg0, Object arg1) {\n" 340 " switch (method) {\n" 341 " case NEW_MUTABLE_INSTANCE: {\n" 342 " return new $classname$();\n" 343 " }\n", 344 "classname", name_resolver_->GetImmutableClassName(descriptor_)); 345 346 printer->Indent(); 347 printer->Indent(); 348 349 printer->Print( 350 "case IS_INITIALIZED: {\n"); 351 printer->Indent(); 352 GenerateDynamicMethodIsInitialized(printer); 353 printer->Outdent(); 354 355 printer->Print( 356 "}\n" 357 "case MAKE_IMMUTABLE: {\n"); 358 359 printer->Indent(); 360 GenerateDynamicMethodMakeImmutable(printer); 361 printer->Outdent(); 362 363 printer->Print( 364 "}\n" 365 "case NEW_BUILDER: {\n"); 366 367 printer->Indent(); 368 GenerateDynamicMethodNewBuilder(printer); 369 printer->Outdent(); 370 371 printer->Print( 372 "}\n" 373 "case VISIT: {\n"); 374 375 printer->Indent(); 376 GenerateDynamicMethodVisit(printer); 377 printer->Outdent(); 378 379 printer->Print( 380 "}\n" 381 "case MERGE_FROM_STREAM: {\n"); 382 383 printer->Indent(); 384 GenerateDynamicMethodMergeFromStream(printer); 385 printer->Outdent(); 386 387 printer->Print( 388 "}\n" 389 "case GET_DEFAULT_INSTANCE: {\n" 390 " return DEFAULT_INSTANCE;\n" 391 "}\n" 392 "case GET_PARSER: {\n" 393 // Generally one would use the lazy initialization holder pattern for 394 // manipulating static fields but that has exceptional cost on Android as 395 // it will generate an extra class for every message. Instead, use the 396 // double-check locking pattern which works just as well. 397 " if (PARSER == null) {" 398 " synchronized ($classname$.class) {\n" 399 " if (PARSER == null) {\n" 400 " PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n" 401 " }\n" 402 " }\n" 403 " }\n" 404 " return PARSER;\n" 405 "}\n", 406 "classname", name_resolver_->GetImmutableClassName(descriptor_)); 407 408 printer->Outdent(); 409 printer->Outdent(); 410 411 printer->Print( 412 " }\n" 413 " throw new UnsupportedOperationException();\n" 414 "}\n" 415 "\n", 416 "classname", name_resolver_->GetImmutableClassName(descriptor_)); 417 418 printer->Print( 419 "\n" 420 "// @@protoc_insertion_point(class_scope:$full_name$)\n", 421 "full_name", descriptor_->full_name()); 422 423 424 // Carefully initialize the default instance in such a way that it doesn't 425 // conflict with other initialization. 426 printer->Print( 427 "private static final $classname$ DEFAULT_INSTANCE;\n", 428 "classname", name_resolver_->GetImmutableClassName(descriptor_)); 429 430 printer->Print( 431 "static {\n" 432 " DEFAULT_INSTANCE = new $classname$();\n" 433 " DEFAULT_INSTANCE.makeImmutable();\n" 434 "}\n" 435 "\n", 436 "classname", descriptor_->name()); 437 printer->Print( 438 "public static $classname$ getDefaultInstance() {\n" 439 " return DEFAULT_INSTANCE;\n" 440 "}\n" 441 "\n", 442 "classname", name_resolver_->GetImmutableClassName(descriptor_)); 443 444 GenerateParser(printer); 445 446 // Extensions must be declared after the DEFAULT_INSTANCE is initialized 447 // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve 448 // the outer class's FileDescriptor. 449 for (int i = 0; i < descriptor_->extension_count(); i++) { 450 ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_) 451 .Generate(printer); 452 } 453 454 printer->Outdent(); 455 printer->Print("}\n\n"); 456} 457 458// =================================================================== 459 460void ImmutableMessageLiteGenerator:: 461GenerateMessageSerializationMethods(io::Printer* printer) { 462 google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields( 463 SortFieldsByNumber(descriptor_)); 464 465 vector<const Descriptor::ExtensionRange*> sorted_extensions; 466 for (int i = 0; i < descriptor_->extension_range_count(); ++i) { 467 sorted_extensions.push_back(descriptor_->extension_range(i)); 468 } 469 std::sort(sorted_extensions.begin(), sorted_extensions.end(), 470 ExtensionRangeOrdering()); 471 472 printer->Print( 473 "public void writeTo(com.google.protobuf.CodedOutputStream output)\n" 474 " throws java.io.IOException {\n"); 475 printer->Indent(); 476 if (HasPackedFields(descriptor_)) { 477 // writeTo(CodedOutputStream output) might be invoked without 478 // getSerializedSize() ever being called, but we need the memoized 479 // sizes in case this message has packed fields. Rather than emit checks for 480 // each packed field, just call getSerializedSize() up front. 481 // In most cases, getSerializedSize() will have already been called anyway 482 // by one of the wrapper writeTo() methods, making this call cheap. 483 printer->Print( 484 "getSerializedSize();\n"); 485 } 486 487 if (descriptor_->extension_range_count() > 0) { 488 if (descriptor_->options().message_set_wire_format()) { 489 printer->Print( 490 "com.google.protobuf.GeneratedMessageLite\n" 491 " .ExtendableMessage<$classname$, $classname$.Builder>\n" 492 " .ExtensionWriter extensionWriter =\n" 493 " newMessageSetExtensionWriter();\n", 494 "classname", name_resolver_->GetImmutableClassName(descriptor_)); 495 } else { 496 printer->Print( 497 "com.google.protobuf.GeneratedMessageLite\n" 498 " .ExtendableMessage<$classname$, $classname$.Builder>\n" 499 " .ExtensionWriter extensionWriter =\n" 500 " newExtensionWriter();\n", 501 "classname", name_resolver_->GetImmutableClassName(descriptor_)); 502 } 503 } 504 505 // Merge the fields and the extension ranges, both sorted by field number. 506 for (int i = 0, j = 0; 507 i < descriptor_->field_count() || j < sorted_extensions.size(); 508 ) { 509 if (i == descriptor_->field_count()) { 510 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); 511 } else if (j == sorted_extensions.size()) { 512 GenerateSerializeOneField(printer, sorted_fields[i++]); 513 } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) { 514 GenerateSerializeOneField(printer, sorted_fields[i++]); 515 } else { 516 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); 517 } 518 } 519 520 if (PreserveUnknownFields(descriptor_)) { 521 printer->Print( 522 "unknownFields.writeTo(output);\n"); 523 } 524 525 printer->Outdent(); 526 printer->Print( 527 "}\n" 528 "\n" 529 "public int getSerializedSize() {\n" 530 " int size = memoizedSerializedSize;\n" 531 " if (size != -1) return size;\n" 532 "\n" 533 " size = 0;\n"); 534 printer->Indent(); 535 536 for (int i = 0; i < descriptor_->field_count(); i++) { 537 field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer); 538 } 539 540 if (descriptor_->extension_range_count() > 0) { 541 if (descriptor_->options().message_set_wire_format()) { 542 printer->Print( 543 "size += extensionsSerializedSizeAsMessageSet();\n"); 544 } else { 545 printer->Print( 546 "size += extensionsSerializedSize();\n"); 547 } 548 } 549 550 if (PreserveUnknownFields(descriptor_)) { 551 printer->Print( 552 "size += unknownFields.getSerializedSize();\n"); 553 } 554 555 printer->Outdent(); 556 printer->Print( 557 " memoizedSerializedSize = size;\n" 558 " return size;\n" 559 "}\n" 560 "\n"); 561} 562 563void ImmutableMessageLiteGenerator:: 564GenerateParseFromMethods(io::Printer* printer) { 565 // Note: These are separate from GenerateMessageSerializationMethods() 566 // because they need to be generated even for messages that are optimized 567 // for code size. 568 printer->Print( 569 "public static $classname$ parseFrom(\n" 570 " com.google.protobuf.ByteString data)\n" 571 " throws com.google.protobuf.InvalidProtocolBufferException {\n" 572 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" 573 " DEFAULT_INSTANCE, data);\n" 574 "}\n" 575 "public static $classname$ parseFrom(\n" 576 " com.google.protobuf.ByteString data,\n" 577 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" 578 " throws com.google.protobuf.InvalidProtocolBufferException {\n" 579 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" 580 " DEFAULT_INSTANCE, data, extensionRegistry);\n" 581 "}\n" 582 "public static $classname$ parseFrom(byte[] data)\n" 583 " throws com.google.protobuf.InvalidProtocolBufferException {\n" 584 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" 585 " DEFAULT_INSTANCE, data);\n" 586 "}\n" 587 "public static $classname$ parseFrom(\n" 588 " byte[] data,\n" 589 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" 590 " throws com.google.protobuf.InvalidProtocolBufferException {\n" 591 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" 592 " DEFAULT_INSTANCE, data, extensionRegistry);\n" 593 "}\n" 594 "public static $classname$ parseFrom(java.io.InputStream input)\n" 595 " throws java.io.IOException {\n" 596 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" 597 " DEFAULT_INSTANCE, input);\n" 598 "}\n" 599 "public static $classname$ parseFrom(\n" 600 " java.io.InputStream input,\n" 601 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" 602 " throws java.io.IOException {\n" 603 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" 604 " DEFAULT_INSTANCE, input, extensionRegistry);\n" 605 "}\n" 606 "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n" 607 " throws java.io.IOException {\n" 608 " return parseDelimitedFrom(DEFAULT_INSTANCE, input);\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 " return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n" 615 "}\n" 616 "public static $classname$ parseFrom(\n" 617 " com.google.protobuf.CodedInputStream input)\n" 618 " throws java.io.IOException {\n" 619 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" 620 " DEFAULT_INSTANCE, input);\n" 621 "}\n" 622 "public static $classname$ parseFrom(\n" 623 " com.google.protobuf.CodedInputStream input,\n" 624 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" 625 " throws java.io.IOException {\n" 626 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" 627 " DEFAULT_INSTANCE, input, extensionRegistry);\n" 628 "}\n" 629 "\n", 630 "classname", name_resolver_->GetImmutableClassName(descriptor_)); 631} 632 633void ImmutableMessageLiteGenerator::GenerateSerializeOneField( 634 io::Printer* printer, const FieldDescriptor* field) { 635 field_generators_.get(field).GenerateSerializationCode(printer); 636} 637 638void ImmutableMessageLiteGenerator::GenerateSerializeOneExtensionRange( 639 io::Printer* printer, const Descriptor::ExtensionRange* range) { 640 printer->Print( 641 "extensionWriter.writeUntil($end$, output);\n", 642 "end", SimpleItoa(range->end)); 643} 644 645// =================================================================== 646 647void ImmutableMessageLiteGenerator::GenerateBuilder(io::Printer* printer) { 648 printer->Print( 649 "public static Builder newBuilder() {\n" 650 " return DEFAULT_INSTANCE.toBuilder();\n" 651 "}\n" 652 "public static Builder newBuilder($classname$ prototype) {\n" 653 " return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n" 654 "}\n" 655 "\n", 656 "classname", name_resolver_->GetImmutableClassName(descriptor_)); 657 658 MessageBuilderLiteGenerator builderGenerator(descriptor_, context_); 659 builderGenerator.Generate(printer); 660} 661 662// =================================================================== 663 664void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized( 665 io::Printer* printer) { 666 // Returns null for false, DEFAULT_INSTANCE for true. 667 if (!HasRequiredFields(descriptor_)) { 668 printer->Print("return DEFAULT_INSTANCE;\n"); 669 return; 670 } 671 672 // Don't directly compare to -1 to avoid an Android x86 JIT bug. 673 printer->Print( 674 "byte isInitialized = memoizedIsInitialized;\n" 675 "if (isInitialized == 1) return DEFAULT_INSTANCE;\n" 676 "if (isInitialized == 0) return null;\n" 677 "\n" 678 "boolean shouldMemoize = ((Boolean) arg0).booleanValue();\n"); 679 680 // Check that all required fields in this message are set. 681 // TODO(kenton): We can optimize this when we switch to putting all the 682 // "has" fields into a single bitfield. 683 for (int i = 0; i < descriptor_->field_count(); i++) { 684 const FieldDescriptor* field = descriptor_->field(i); 685 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); 686 687 if (field->is_required()) { 688 printer->Print( 689 "if (!has$name$()) {\n" 690 " if (shouldMemoize) {\n" 691 " memoizedIsInitialized = 0;\n" 692 " }\n" 693 " return null;\n" 694 "}\n", 695 "name", info->capitalized_name); 696 } 697 } 698 699 // Now check that all embedded messages are initialized. 700 for (int i = 0; i < descriptor_->field_count(); i++) { 701 const FieldDescriptor* field = descriptor_->field(i); 702 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); 703 if (GetJavaType(field) == JAVATYPE_MESSAGE && 704 HasRequiredFields(field->message_type())) { 705 switch (field->label()) { 706 case FieldDescriptor::LABEL_REQUIRED: 707 printer->Print( 708 "if (!get$name$().isInitialized()) {\n" 709 " if (shouldMemoize) {\n" 710 " memoizedIsInitialized = 0;\n" 711 " }\n" 712 " return null;\n" 713 "}\n", 714 "type", name_resolver_->GetImmutableClassName( 715 field->message_type()), 716 "name", info->capitalized_name); 717 break; 718 case FieldDescriptor::LABEL_OPTIONAL: 719 if (!SupportFieldPresence(descriptor_->file()) && 720 field->containing_oneof() != NULL) { 721 const OneofDescriptor* oneof = field->containing_oneof(); 722 const OneofGeneratorInfo* oneof_info = 723 context_->GetOneofGeneratorInfo(oneof); 724 printer->Print( 725 "if ($oneof_name$Case_ == $field_number$) {\n", 726 "oneof_name", oneof_info->name, 727 "field_number", SimpleItoa(field->number())); 728 } else { 729 printer->Print( 730 "if (has$name$()) {\n", 731 "name", info->capitalized_name); 732 } 733 printer->Print( 734 " if (!get$name$().isInitialized()) {\n" 735 " if (shouldMemoize) {\n" 736 " memoizedIsInitialized = 0;\n" 737 " }\n" 738 " return null;\n" 739 " }\n" 740 "}\n", 741 "name", info->capitalized_name); 742 break; 743 case FieldDescriptor::LABEL_REPEATED: 744 if (IsMapEntry(field->message_type())) { 745 printer->Print( 746 "for ($type$ item : get$name$().values()) {\n" 747 " if (!item.isInitialized()) {\n" 748 " if (shouldMemoize) {\n" 749 " memoizedIsInitialized = 0;\n" 750 " }\n" 751 " return null;\n" 752 " }\n" 753 "}\n", 754 "type", MapValueImmutableClassdName(field->message_type(), 755 name_resolver_), 756 "name", info->capitalized_name); 757 } else { 758 printer->Print( 759 "for (int i = 0; i < get$name$Count(); i++) {\n" 760 " if (!get$name$(i).isInitialized()) {\n" 761 " if (shouldMemoize) {\n" 762 " memoizedIsInitialized = 0;\n" 763 " }\n" 764 " return null;\n" 765 " }\n" 766 "}\n", 767 "type", name_resolver_->GetImmutableClassName( 768 field->message_type()), 769 "name", info->capitalized_name); 770 } 771 break; 772 } 773 } 774 } 775 776 if (descriptor_->extension_range_count() > 0) { 777 printer->Print( 778 "if (!extensionsAreInitialized()) {\n" 779 " if (shouldMemoize) {\n" 780 " memoizedIsInitialized = 0;\n" 781 " }\n" 782 " return null;\n" 783 "}\n"); 784 } 785 786 printer->Print( 787 "if (shouldMemoize) memoizedIsInitialized = 1;\n"); 788 789 printer->Print( 790 "return DEFAULT_INSTANCE;\n" 791 "\n"); 792} 793 794// =================================================================== 795 796void ImmutableMessageLiteGenerator::GenerateDynamicMethodMakeImmutable( 797 io::Printer* printer) { 798 799 // Output generation code for each field. 800 for (int i = 0; i < descriptor_->field_count(); i++) { 801 field_generators_.get(descriptor_->field(i)) 802 .GenerateDynamicMethodMakeImmutableCode(printer); 803 } 804 805 printer->Print( 806 "return null;\n"); 807} 808 809// =================================================================== 810 811void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder( 812 io::Printer* printer) { 813 printer->Print( 814 "return new Builder();\n"); 815} 816 817// =================================================================== 818 819void ImmutableMessageLiteGenerator::GenerateDynamicMethodVisit( 820 io::Printer* printer) { 821 printer->Print( 822 "Visitor visitor = (Visitor) arg0;\n" 823 "$classname$ other = ($classname$) arg1;\n", 824 "classname", name_resolver_->GetImmutableClassName(descriptor_)); 825 826 for (int i = 0; i < descriptor_->field_count(); i++) { 827 if (!descriptor_->field(i)->containing_oneof()) { 828 field_generators_.get( 829 descriptor_->field(i)).GenerateVisitCode(printer); 830 } 831 } 832 833 // Merge oneof fields. 834 for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { 835 printer->Print( 836 "switch (other.get$oneof_capitalized_name$Case()) {\n", 837 "oneof_capitalized_name", 838 context_->GetOneofGeneratorInfo( 839 descriptor_->oneof_decl(i))->capitalized_name); 840 printer->Indent(); 841 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 842 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); 843 printer->Print( 844 "case $field_name$: {\n", 845 "field_name", 846 ToUpper(field->name())); 847 printer->Indent(); 848 field_generators_.get(field).GenerateVisitCode(printer); 849 printer->Print( 850 "break;\n"); 851 printer->Outdent(); 852 printer->Print( 853 "}\n"); 854 } 855 printer->Print( 856 "case $cap_oneof_name$_NOT_SET: {\n" 857 " visitor.visitOneofNotSet($oneof_name$Case_ != 0);\n" 858 " break;\n" 859 "}\n", 860 "cap_oneof_name", 861 ToUpper(context_->GetOneofGeneratorInfo( 862 descriptor_->oneof_decl(i))->name), 863 "oneof_name", 864 context_->GetOneofGeneratorInfo( 865 descriptor_->oneof_decl(i))->name); 866 printer->Outdent(); 867 printer->Print( 868 "}\n"); 869 } 870 871 printer->Print( 872 "if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n" 873 " .INSTANCE) {\n"); 874 printer->Indent(); 875 for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { 876 const OneofDescriptor* field = descriptor_->oneof_decl(i); 877 printer->Print( 878 "if (other.$oneof_name$Case_ != 0) {\n" 879 " $oneof_name$Case_ = other.$oneof_name$Case_;\n" 880 "}\n", 881 "oneof_name", context_->GetOneofGeneratorInfo(field)->name); 882 } 883 884 if (GenerateHasBits(descriptor_)) { 885 // Integers for bit fields. 886 int totalBits = 0; 887 for (int i = 0; i < descriptor_->field_count(); i++) { 888 totalBits += field_generators_.get(descriptor_->field(i)) 889 .GetNumBitsForMessage(); 890 } 891 int totalInts = (totalBits + 31) / 32; 892 893 for (int i = 0; i < totalInts; i++) { 894 printer->Print( 895 "$bit_field_name$ |= other.$bit_field_name$;\n", 896 "bit_field_name", GetBitFieldName(i)); 897 } 898 } 899 printer->Outdent(); 900 printer->Print( 901 "}\n"); 902 903 904 printer->Print( 905 "return this;\n"); 906} 907 908// =================================================================== 909 910void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFromStream( 911 io::Printer* printer) { 912 printer->Print( 913 "com.google.protobuf.CodedInputStream input =\n" 914 " (com.google.protobuf.CodedInputStream) arg0;\n" 915 "com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n" 916 " (com.google.protobuf.ExtensionRegistryLite) arg1;\n" 917 "try {\n"); 918 printer->Indent(); 919 920 printer->Print( 921 "boolean done = false;\n" 922 "while (!done) {\n"); 923 printer->Indent(); 924 925 printer->Print( 926 "int tag = input.readTag();\n" 927 "switch (tag) {\n"); 928 printer->Indent(); 929 930 printer->Print( 931 "case 0:\n" // zero signals EOF / limit reached 932 " done = true;\n" 933 " break;\n"); 934 935 if (PreserveUnknownFields(descriptor_)) { 936 if (descriptor_->extension_range_count() > 0) { 937 printer->Print( 938 "default: {\n" 939 " if (!parseUnknownField(getDefaultInstanceForType(),\n" 940 " input, extensionRegistry, tag)) {\n" 941 " done = true;\n" // it's an endgroup tag 942 " }\n" 943 " break;\n" 944 "}\n"); 945 } else { 946 printer->Print( 947 "default: {\n" 948 " if (!parseUnknownField(tag, input)) {\n" 949 " done = true;\n" // it's an endgroup tag 950 " }\n" 951 " break;\n" 952 "}\n"); 953 } 954 } else { 955 printer->Print( 956 "default: {\n" 957 " if (!input.skipField(tag)) {\n" 958 " done = true;\n" // it's an endgroup tag 959 " }\n" 960 " break;\n" 961 "}\n"); 962 } 963 964 google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields( 965 SortFieldsByNumber(descriptor_)); 966 for (int i = 0; i < descriptor_->field_count(); i++) { 967 const FieldDescriptor* field = sorted_fields[i]; 968 uint32 tag = WireFormatLite::MakeTag(field->number(), 969 WireFormat::WireTypeForFieldType(field->type())); 970 971 printer->Print( 972 "case $tag$: {\n", 973 "tag", SimpleItoa(tag)); 974 printer->Indent(); 975 976 field_generators_.get(field).GenerateParsingCode(printer); 977 978 printer->Outdent(); 979 printer->Print( 980 " break;\n" 981 "}\n"); 982 983 if (field->is_packable()) { 984 // To make packed = true wire compatible, we generate parsing code from a 985 // packed version of this field regardless of field->options().packed(). 986 uint32 packed_tag = WireFormatLite::MakeTag(field->number(), 987 WireFormatLite::WIRETYPE_LENGTH_DELIMITED); 988 printer->Print( 989 "case $tag$: {\n", 990 "tag", SimpleItoa(packed_tag)); 991 printer->Indent(); 992 993 field_generators_.get(field).GenerateParsingCodeFromPacked(printer); 994 995 printer->Outdent(); 996 printer->Print( 997 " break;\n" 998 "}\n"); 999 } 1000 } 1001 1002 printer->Outdent(); 1003 printer->Outdent(); 1004 printer->Print( 1005 " }\n" // switch (tag) 1006 "}\n"); // while (!done) 1007 1008 printer->Outdent(); 1009 printer->Print( 1010 "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" 1011 " throw new RuntimeException(e.setUnfinishedMessage(this));\n" 1012 "} catch (java.io.IOException e) {\n" 1013 " throw new RuntimeException(\n" 1014 " new com.google.protobuf.InvalidProtocolBufferException(\n" 1015 " e.getMessage()).setUnfinishedMessage(this));\n" 1016 "} finally {\n"); 1017 printer->Indent(); 1018 1019 printer->Outdent(); 1020 printer->Print( 1021 "}\n"); // finally 1022} 1023 1024// =================================================================== 1025 1026namespace { 1027bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) { 1028 if (field->is_repeated()) { 1029 return false; 1030 } 1031 if (SupportFieldPresence(field->file())) { 1032 return true; 1033 } 1034 return GetJavaType(field) == JAVATYPE_MESSAGE && 1035 field->containing_oneof() == NULL; 1036} 1037} // namespace 1038 1039// =================================================================== 1040 1041void ImmutableMessageLiteGenerator:: 1042GenerateExtensionRegistrationCode(io::Printer* printer) { 1043 for (int i = 0; i < descriptor_->extension_count(); i++) { 1044 ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_) 1045 .GenerateRegistrationCode(printer); 1046 } 1047 1048 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 1049 ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) 1050 .GenerateExtensionRegistrationCode(printer); 1051 } 1052} 1053 1054// =================================================================== 1055void ImmutableMessageLiteGenerator:: 1056GenerateConstructor(io::Printer* printer) { 1057 printer->Print( 1058 "private $classname$() {\n", 1059 "classname", descriptor_->name()); 1060 printer->Indent(); 1061 1062 // Initialize all fields to default. 1063 GenerateInitializers(printer); 1064 1065 printer->Outdent(); 1066 printer->Print( 1067 "}\n"); 1068} 1069 1070// =================================================================== 1071void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) { 1072 printer->Print( 1073 "private static volatile com.google.protobuf.Parser<$classname$> PARSER;\n" 1074 "\n" 1075 "public static com.google.protobuf.Parser<$classname$> parser() {\n" 1076 " return DEFAULT_INSTANCE.getParserForType();\n" 1077 "}\n", 1078 "classname", descriptor_->name()); 1079} 1080 1081// =================================================================== 1082void ImmutableMessageLiteGenerator::GenerateInitializers(io::Printer* printer) { 1083 for (int i = 0; i < descriptor_->field_count(); i++) { 1084 if (!descriptor_->field(i)->containing_oneof()) { 1085 field_generators_.get(descriptor_->field(i)) 1086 .GenerateInitializationCode(printer); 1087 } 1088 } 1089} 1090 1091} // namespace java 1092} // namespace compiler 1093} // namespace protobuf 1094} // namespace google 1095