javanano_message.cc revision 382ddccb550e1c822ef26a0e65988998f7446624
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 "public int getSerializedSize() {\n" 308 " int size = super.getSerializedSize();\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 " cachedSize = size;\n" 318 " return size;\n" 319 "}\n"); 320} 321 322void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) { 323 scoped_array<const FieldDescriptor*> sorted_fields( 324 SortFieldsByNumber(descriptor_)); 325 326 printer->Print( 327 "\n" 328 "@Override\n" 329 "public $classname$ mergeFrom(\n" 330 " com.google.protobuf.nano.CodedInputByteBufferNano input)\n" 331 " throws java.io.IOException {\n", 332 "classname", descriptor_->name()); 333 334 printer->Indent(); 335 336 printer->Print( 337 "while (true) {\n"); 338 printer->Indent(); 339 340 printer->Print( 341 "int tag = input.readTag();\n" 342 "switch (tag) {\n"); 343 printer->Indent(); 344 345 printer->Print( 346 "case 0:\n" // zero signals EOF / limit reached 347 " return this;\n" 348 "default: {\n"); 349 350 printer->Indent(); 351 if (params_.store_unknown_fields()) { 352 printer->Print( 353 "if (!storeUnknownField(input, tag)) {\n" 354 " return this;\n" 355 "}\n"); 356 } else { 357 printer->Print( 358 "if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) {\n" 359 " return this;\n" // it's an endgroup tag 360 "}\n"); 361 } 362 printer->Print("break;\n"); 363 printer->Outdent(); 364 printer->Print("}\n"); 365 366 for (int i = 0; i < descriptor_->field_count(); i++) { 367 const FieldDescriptor* field = sorted_fields[i]; 368 uint32 tag = WireFormatLite::MakeTag(field->number(), 369 WireFormat::WireTypeForFieldType(field->type())); 370 371 printer->Print( 372 "case $tag$: {\n", 373 "tag", SimpleItoa(tag)); 374 printer->Indent(); 375 376 field_generators_.get(field).GenerateMergingCode(printer); 377 378 printer->Outdent(); 379 printer->Print( 380 " break;\n" 381 "}\n"); 382 383 if (field->is_packable()) { 384 // To make packed = true wire compatible, we generate parsing code from a 385 // packed version of this field regardless of field->options().packed(). 386 uint32 packed_tag = WireFormatLite::MakeTag(field->number(), 387 WireFormatLite::WIRETYPE_LENGTH_DELIMITED); 388 printer->Print( 389 "case $tag$: {\n", 390 "tag", SimpleItoa(packed_tag)); 391 printer->Indent(); 392 393 field_generators_.get(field).GenerateMergingCodeFromPacked(printer); 394 395 printer->Outdent(); 396 printer->Print( 397 " break;\n" 398 "}\n"); 399 } 400 } 401 402 printer->Outdent(); 403 printer->Outdent(); 404 printer->Outdent(); 405 printer->Print( 406 " }\n" // switch (tag) 407 " }\n" // while (true) 408 "}\n"); 409} 410 411void MessageGenerator:: 412GenerateParseFromMethods(io::Printer* printer) { 413 // Note: These are separate from GenerateMessageSerializationMethods() 414 // because they need to be generated even for messages that are optimized 415 // for code size. 416 printer->Print( 417 "\n" 418 "public static $classname$ parseFrom(byte[] data)\n" 419 " throws com.google.protobuf.nano.InvalidProtocolBufferNanoException {\n" 420 " return com.google.protobuf.nano.MessageNano.mergeFrom(new $classname$(), data);\n" 421 "}\n" 422 "\n" 423 "public static $classname$ parseFrom(\n" 424 " com.google.protobuf.nano.CodedInputByteBufferNano input)\n" 425 " throws java.io.IOException {\n" 426 " return new $classname$().mergeFrom(input);\n" 427 "}\n", 428 "classname", descriptor_->name()); 429} 430 431void MessageGenerator::GenerateSerializeOneField( 432 io::Printer* printer, const FieldDescriptor* field) { 433 field_generators_.get(field).GenerateSerializationCode(printer); 434} 435 436void MessageGenerator::GenerateClear(io::Printer* printer) { 437 printer->Print( 438 "\n" 439 "public $classname$ clear() {\n", 440 "classname", descriptor_->name()); 441 printer->Indent(); 442 443 // Clear bit fields. 444 int totalInts = (field_generators_.total_bits() + 31) / 32; 445 for (int i = 0; i < totalInts; i++) { 446 printer->Print("$bit_field_name$ = 0;\n", 447 "bit_field_name", GetBitFieldName(i)); 448 } 449 450 // Call clear for all of the fields. 451 for (int i = 0; i < descriptor_->field_count(); i++) { 452 const FieldDescriptor* field = descriptor_->field(i); 453 field_generators_.get(field).GenerateClearCode(printer); 454 } 455 456 // Clear unknown fields. 457 if (params_.store_unknown_fields()) { 458 printer->Print("unknownFieldData = null;\n"); 459 } 460 461 printer->Outdent(); 462 printer->Print( 463 " cachedSize = -1;\n" 464 " return this;\n" 465 "}\n"); 466} 467 468void MessageGenerator::GenerateEquals(io::Printer* printer) { 469 // Don't override if there are no fields. We could generate an 470 // equals method that compares types, but often empty messages 471 // are used as namespaces. 472 if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) { 473 return; 474 } 475 476 printer->Print( 477 "\n" 478 "@Override\n" 479 "public boolean equals(Object o) {\n"); 480 printer->Indent(); 481 printer->Print( 482 "if (o == this) {\n" 483 " return true;\n" 484 "}\n" 485 "if (!(o instanceof $classname$)) {\n" 486 " return false;\n" 487 "}\n" 488 "$classname$ other = ($classname$) o;\n", 489 "classname", descriptor_->name()); 490 491 for (int i = 0; i < descriptor_->field_count(); i++) { 492 const FieldDescriptor* field = descriptor_->field(i); 493 field_generators_.get(field).GenerateEqualsCode(printer); 494 } 495 496 if (params_.store_unknown_fields()) { 497 printer->Print( 498 "if (unknownFieldData == null || unknownFieldData.isEmpty()) {\n" 499 " return other.unknownFieldData == null || other.unknownFieldData.isEmpty();" 500 "} else {\n" 501 " return unknownFieldData.equals(other.unknownFieldData);\n" 502 "}\n"); 503 } else { 504 printer->Print( 505 "return true;\n"); 506 } 507 508 printer->Outdent(); 509 printer->Print("}\n"); 510} 511 512void MessageGenerator::GenerateHashCode(io::Printer* printer) { 513 if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) { 514 return; 515 } 516 517 printer->Print( 518 "\n" 519 "@Override\n" 520 "public int hashCode() {\n"); 521 printer->Indent(); 522 523 printer->Print("int result = 17;\n"); 524 for (int i = 0; i < descriptor_->field_count(); i++) { 525 const FieldDescriptor* field = descriptor_->field(i); 526 field_generators_.get(field).GenerateHashCodeCode(printer); 527 } 528 529 if (params_.store_unknown_fields()) { 530 printer->Print( 531 "result = 31 * result + (unknownFieldData == null || unknownFieldData.isEmpty()\n" 532 " ? 0 : unknownFieldData.hashCode());\n"); 533 } 534 535 printer->Print("return result;\n"); 536 537 printer->Outdent(); 538 printer->Print("}\n"); 539} 540 541// =================================================================== 542 543} // namespace javanano 544} // namespace compiler 545} // namespace protobuf 546} // namespace google 547