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 (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 <google/protobuf/compiler/javanano/javanano_message.h> 38 #include <google/protobuf/compiler/javanano/javanano_enum.h> 39 #include <google/protobuf/compiler/javanano/javanano_extension.h> 40 #include <google/protobuf/compiler/javanano/javanano_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 47 namespace google { 48 namespace protobuf { 49 namespace compiler { 50 namespace javanano { 51 52 using internal::WireFormat; 53 using internal::WireFormatLite; 54 55 namespace { 56 57 struct FieldOrderingByNumber { 58 inline bool operator()(const FieldDescriptor* a, 59 const FieldDescriptor* b) const { 60 return a->number() < b->number(); 61 } 62 }; 63 64 // Sort the fields of the given Descriptor by number into a new[]'d array 65 // and return it. 66 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { 67 const FieldDescriptor** fields = 68 new const FieldDescriptor*[descriptor->field_count()]; 69 for (int i = 0; i < descriptor->field_count(); i++) { 70 fields[i] = descriptor->field(i); 71 } 72 sort(fields, fields + descriptor->field_count(), 73 FieldOrderingByNumber()); 74 return fields; 75 } 76 77 } // namespace 78 79 // =================================================================== 80 81 MessageGenerator::MessageGenerator(const Descriptor* descriptor, const Params& params) 82 : params_(params), 83 descriptor_(descriptor), 84 field_generators_(descriptor, params) { 85 } 86 87 MessageGenerator::~MessageGenerator() {} 88 89 void MessageGenerator::GenerateStaticVariables(io::Printer* printer) { 90 // Generate static members for all nested types. 91 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 92 // TODO(kenton): Reuse MessageGenerator objects? 93 MessageGenerator(descriptor_->nested_type(i), params_) 94 .GenerateStaticVariables(printer); 95 } 96 } 97 98 void MessageGenerator::GenerateStaticVariableInitializers( 99 io::Printer* printer) { 100 // Generate static member initializers for all nested types. 101 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 102 // TODO(kenton): Reuse MessageGenerator objects? 103 MessageGenerator(descriptor_->nested_type(i), params_) 104 .GenerateStaticVariableInitializers(printer); 105 } 106 } 107 108 void MessageGenerator::Generate(io::Printer* printer) { 109 if (!params_.store_unknown_fields() && 110 (descriptor_->extension_count() != 0 || descriptor_->extension_range_count() != 0)) { 111 GOOGLE_LOG(FATAL) << "Extensions are only supported in NANO_RUNTIME if the " 112 "'store_unknown_fields' generator option is 'true'\n"; 113 } 114 115 const string& file_name = descriptor_->file()->name(); 116 bool is_own_file = 117 params_.java_multiple_files(file_name) 118 && descriptor_->containing_type() == NULL; 119 120 if (is_own_file) { 121 // Note: constants (from enums and fields requiring stored defaults, emitted in the loop below) 122 // may have the same names as constants in the nested classes. This causes Java warnings, but 123 // is not fatal, so we suppress those warnings here in the top-most class declaration. 124 printer->Print( 125 "\n" 126 "@SuppressWarnings(\"hiding\")\n" 127 "public final class $classname$ extends\n", 128 "classname", descriptor_->name()); 129 } else { 130 printer->Print( 131 "\n" 132 "public static final class $classname$ extends\n", 133 "classname", descriptor_->name()); 134 } 135 if (params_.store_unknown_fields() && params_.parcelable_messages()) { 136 printer->Print( 137 " com.google.protobuf.nano.android.ParcelableExtendableMessageNano<$classname$> {\n", 138 "classname", descriptor_->name()); 139 } else if (params_.store_unknown_fields()) { 140 printer->Print( 141 " com.google.protobuf.nano.ExtendableMessageNano<$classname$> {\n", 142 "classname", descriptor_->name()); 143 } else if (params_.parcelable_messages()) { 144 printer->Print( 145 " com.google.protobuf.nano.android.ParcelableMessageNano {\n"); 146 } else { 147 printer->Print( 148 " com.google.protobuf.nano.MessageNano {\n"); 149 } 150 printer->Indent(); 151 152 // Nested types and extensions 153 for (int i = 0; i < descriptor_->extension_count(); i++) { 154 ExtensionGenerator(descriptor_->extension(i), params_).Generate(printer); 155 } 156 157 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 158 EnumGenerator(descriptor_->enum_type(i), params_).Generate(printer); 159 } 160 161 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 162 MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer); 163 } 164 165 // Lazy initialization of otherwise static final fields can help prevent the 166 // class initializer from being generated. We want to prevent it because it 167 // stops ProGuard from inlining any methods in this class into call sites and 168 // therefore reducing the method count. However, extensions are best kept as 169 // public static final fields with initializers, so with their existence we 170 // won't bother with lazy initialization. 171 bool lazy_init = descriptor_->extension_count() == 0; 172 173 // Empty array 174 if (lazy_init) { 175 printer->Print( 176 "\n" 177 "private static volatile $classname$[] _emptyArray;\n" 178 "public static $classname$[] emptyArray() {\n" 179 " // Lazily initializes the empty array\n" 180 " if (_emptyArray == null) {\n" 181 " synchronized (\n" 182 " com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n" 183 " if (_emptyArray == null) {\n" 184 " _emptyArray = new $classname$[0];\n" 185 " }\n" 186 " }\n" 187 " }\n" 188 " return _emptyArray;\n" 189 "}\n", 190 "classname", descriptor_->name()); 191 } else { 192 printer->Print( 193 "\n" 194 "private static final $classname$[] EMPTY_ARRAY = {};\n" 195 "public static $classname$[] emptyArray() {\n" 196 " return EMPTY_ARRAY;\n" 197 "}\n", 198 "classname", descriptor_->name()); 199 } 200 201 // Integers for bit fields 202 int totalInts = (field_generators_.total_bits() + 31) / 32; 203 if (totalInts > 0) { 204 printer->Print("\n"); 205 for (int i = 0; i < totalInts; i++) { 206 printer->Print("private int $bit_field_name$;\n", 207 "bit_field_name", GetBitFieldName(i)); 208 } 209 } 210 211 // Fields and maybe their default values 212 for (int i = 0; i < descriptor_->field_count(); i++) { 213 printer->Print("\n"); 214 PrintFieldComment(printer, descriptor_->field(i)); 215 field_generators_.get(descriptor_->field(i)).GenerateMembers( 216 printer, lazy_init); 217 } 218 219 // Constructor, with lazy init code if needed 220 if (lazy_init && field_generators_.saved_defaults_needed()) { 221 printer->Print( 222 "\n" 223 "private static volatile boolean _classInitialized;\n" 224 "\n" 225 "public $classname$() {\n" 226 " // Lazily initializes the field defaults\n" 227 " if (!_classInitialized) {\n" 228 " synchronized (\n" 229 " com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n" 230 " if (!_classInitialized) {\n", 231 "classname", descriptor_->name()); 232 printer->Indent(); 233 printer->Indent(); 234 printer->Indent(); 235 printer->Indent(); 236 for (int i = 0; i < descriptor_->field_count(); i++) { 237 field_generators_.get(descriptor_->field(i)) 238 .GenerateInitSavedDefaultCode(printer); 239 } 240 printer->Outdent(); 241 printer->Outdent(); 242 printer->Outdent(); 243 printer->Outdent(); 244 printer->Print( 245 " _classInitialized = true;\n" 246 " }\n" 247 " }\n" 248 " }\n" 249 " clear();\n" 250 "}\n"); 251 } else { 252 printer->Print( 253 "\n" 254 "public $classname$() {\n" 255 " clear();\n" 256 "}\n", 257 "classname", descriptor_->name()); 258 } 259 260 // Other methods in this class 261 262 GenerateClear(printer); 263 264 if (params_.generate_equals()) { 265 GenerateEquals(printer); 266 GenerateHashCode(printer); 267 } 268 269 GenerateMessageSerializationMethods(printer); 270 GenerateMergeFromMethods(printer); 271 GenerateParseFromMethods(printer); 272 273 printer->Outdent(); 274 printer->Print("}\n"); 275 } 276 277 // =================================================================== 278 279 void MessageGenerator:: 280 GenerateMessageSerializationMethods(io::Printer* printer) { 281 // Rely on the parent implementations of writeTo() and getSerializedSize() 282 // if there are no fields to serialize in this message. 283 if (descriptor_->field_count() == 0) { 284 return; 285 } 286 287 scoped_array<const FieldDescriptor*> sorted_fields( 288 SortFieldsByNumber(descriptor_)); 289 290 printer->Print( 291 "\n" 292 "@Override\n" 293 "public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output)\n" 294 " throws java.io.IOException {\n"); 295 printer->Indent(); 296 297 // Output the fields in sorted order 298 for (int i = 0; i < descriptor_->field_count(); i++) { 299 GenerateSerializeOneField(printer, sorted_fields[i]); 300 } 301 302 // The parent implementation will write any unknown fields if necessary. 303 printer->Print( 304 "super.writeTo(output);\n"); 305 306 printer->Outdent(); 307 printer->Print("}\n"); 308 309 // The parent implementation will get the serialized size for unknown 310 // fields if necessary. 311 printer->Print( 312 "\n" 313 "@Override\n" 314 "protected int computeSerializedSize() {\n" 315 " int size = super.computeSerializedSize();\n"); 316 printer->Indent(); 317 318 for (int i = 0; i < descriptor_->field_count(); i++) { 319 field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer); 320 } 321 322 printer->Outdent(); 323 printer->Print( 324 " return size;\n" 325 "}\n"); 326 } 327 328 void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) { 329 scoped_array<const FieldDescriptor*> sorted_fields( 330 SortFieldsByNumber(descriptor_)); 331 332 printer->Print( 333 "\n" 334 "@Override\n" 335 "public $classname$ mergeFrom(\n" 336 " com.google.protobuf.nano.CodedInputByteBufferNano input)\n" 337 " throws java.io.IOException {\n", 338 "classname", descriptor_->name()); 339 340 printer->Indent(); 341 342 printer->Print( 343 "while (true) {\n"); 344 printer->Indent(); 345 346 printer->Print( 347 "int tag = input.readTag();\n" 348 "switch (tag) {\n"); 349 printer->Indent(); 350 351 printer->Print( 352 "case 0:\n" // zero signals EOF / limit reached 353 " return this;\n" 354 "default: {\n"); 355 356 printer->Indent(); 357 if (params_.store_unknown_fields()) { 358 printer->Print( 359 "if (!storeUnknownField(input, tag)) {\n" 360 " return this;\n" 361 "}\n"); 362 } else { 363 printer->Print( 364 "if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) {\n" 365 " return this;\n" // it's an endgroup tag 366 "}\n"); 367 } 368 printer->Print("break;\n"); 369 printer->Outdent(); 370 printer->Print("}\n"); 371 372 for (int i = 0; i < descriptor_->field_count(); i++) { 373 const FieldDescriptor* field = sorted_fields[i]; 374 uint32 tag = WireFormatLite::MakeTag(field->number(), 375 WireFormat::WireTypeForFieldType(field->type())); 376 377 printer->Print( 378 "case $tag$: {\n", 379 "tag", SimpleItoa(tag)); 380 printer->Indent(); 381 382 field_generators_.get(field).GenerateMergingCode(printer); 383 384 printer->Outdent(); 385 printer->Print( 386 " break;\n" 387 "}\n"); 388 389 if (field->is_packable()) { 390 // To make packed = true wire compatible, we generate parsing code from a 391 // packed version of this field regardless of field->options().packed(). 392 uint32 packed_tag = WireFormatLite::MakeTag(field->number(), 393 WireFormatLite::WIRETYPE_LENGTH_DELIMITED); 394 printer->Print( 395 "case $tag$: {\n", 396 "tag", SimpleItoa(packed_tag)); 397 printer->Indent(); 398 399 field_generators_.get(field).GenerateMergingCodeFromPacked(printer); 400 401 printer->Outdent(); 402 printer->Print( 403 " break;\n" 404 "}\n"); 405 } 406 } 407 408 printer->Outdent(); 409 printer->Outdent(); 410 printer->Outdent(); 411 printer->Print( 412 " }\n" // switch (tag) 413 " }\n" // while (true) 414 "}\n"); 415 } 416 417 void MessageGenerator:: 418 GenerateParseFromMethods(io::Printer* printer) { 419 // Note: These are separate from GenerateMessageSerializationMethods() 420 // because they need to be generated even for messages that are optimized 421 // for code size. 422 printer->Print( 423 "\n" 424 "public static $classname$ parseFrom(byte[] data)\n" 425 " throws com.google.protobuf.nano.InvalidProtocolBufferNanoException {\n" 426 " return com.google.protobuf.nano.MessageNano.mergeFrom(new $classname$(), data);\n" 427 "}\n" 428 "\n" 429 "public static $classname$ parseFrom(\n" 430 " com.google.protobuf.nano.CodedInputByteBufferNano input)\n" 431 " throws java.io.IOException {\n" 432 " return new $classname$().mergeFrom(input);\n" 433 "}\n", 434 "classname", descriptor_->name()); 435 } 436 437 void MessageGenerator::GenerateSerializeOneField( 438 io::Printer* printer, const FieldDescriptor* field) { 439 field_generators_.get(field).GenerateSerializationCode(printer); 440 } 441 442 void MessageGenerator::GenerateClear(io::Printer* printer) { 443 printer->Print( 444 "\n" 445 "public $classname$ clear() {\n", 446 "classname", descriptor_->name()); 447 printer->Indent(); 448 449 // Clear bit fields. 450 int totalInts = (field_generators_.total_bits() + 31) / 32; 451 for (int i = 0; i < totalInts; i++) { 452 printer->Print("$bit_field_name$ = 0;\n", 453 "bit_field_name", GetBitFieldName(i)); 454 } 455 456 // Call clear for all of the fields. 457 for (int i = 0; i < descriptor_->field_count(); i++) { 458 const FieldDescriptor* field = descriptor_->field(i); 459 field_generators_.get(field).GenerateClearCode(printer); 460 } 461 462 // Clear unknown fields. 463 if (params_.store_unknown_fields()) { 464 printer->Print("unknownFieldData = null;\n"); 465 } 466 467 printer->Outdent(); 468 printer->Print( 469 " cachedSize = -1;\n" 470 " return this;\n" 471 "}\n"); 472 } 473 474 void MessageGenerator::GenerateEquals(io::Printer* printer) { 475 // Don't override if there are no fields. We could generate an 476 // equals method that compares types, but often empty messages 477 // are used as namespaces. 478 if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) { 479 return; 480 } 481 482 printer->Print( 483 "\n" 484 "@Override\n" 485 "public boolean equals(Object o) {\n"); 486 printer->Indent(); 487 printer->Print( 488 "if (o == this) {\n" 489 " return true;\n" 490 "}\n" 491 "if (!(o instanceof $classname$)) {\n" 492 " return false;\n" 493 "}\n" 494 "$classname$ other = ($classname$) o;\n", 495 "classname", descriptor_->name()); 496 497 for (int i = 0; i < descriptor_->field_count(); i++) { 498 const FieldDescriptor* field = descriptor_->field(i); 499 field_generators_.get(field).GenerateEqualsCode(printer); 500 } 501 502 if (params_.store_unknown_fields()) { 503 printer->Print( 504 "return unknownFieldDataEquals(other);\n"); 505 } else { 506 printer->Print( 507 "return true;\n"); 508 } 509 510 printer->Outdent(); 511 printer->Print("}\n"); 512 } 513 514 void MessageGenerator::GenerateHashCode(io::Printer* printer) { 515 if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) { 516 return; 517 } 518 519 printer->Print( 520 "\n" 521 "@Override\n" 522 "public int hashCode() {\n"); 523 printer->Indent(); 524 525 printer->Print("int result = 17;\n"); 526 for (int i = 0; i < descriptor_->field_count(); i++) { 527 const FieldDescriptor* field = descriptor_->field(i); 528 field_generators_.get(field).GenerateHashCodeCode(printer); 529 } 530 531 if (params_.store_unknown_fields()) { 532 printer->Print( 533 "result = 31 * result + unknownFieldDataHashCode();\n"); 534 } 535 536 printer->Print("return result;\n"); 537 538 printer->Outdent(); 539 printer->Print("}\n"); 540 } 541 542 // =================================================================== 543 544 } // namespace javanano 545 } // namespace compiler 546 } // namespace protobuf 547 } // namespace google 548