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