| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
| 2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
| 3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 // I don't have the book on me right now so I'm not sure. | 63 // I don't have the book on me right now so I'm not sure. |
| 64 | 64 |
| 65 #include <algorithm> | 65 #include <algorithm> |
| 66 #include <google/protobuf/stubs/hash.h> | 66 #include <google/protobuf/stubs/hash.h> |
| 67 #include <memory> | 67 #include <memory> |
| 68 #ifndef _SHARED_PTR_H | 68 #ifndef _SHARED_PTR_H |
| 69 #include <google/protobuf/stubs/shared_ptr.h> | 69 #include <google/protobuf/stubs/shared_ptr.h> |
| 70 #endif | 70 #endif |
| 71 | 71 |
| 72 #include <google/protobuf/stubs/common.h> | 72 #include <google/protobuf/stubs/common.h> |
| 73 #include <google/protobuf/stubs/scoped_ptr.h> |
| 73 | 74 |
| 74 #include <google/protobuf/dynamic_message.h> | 75 #include <google/protobuf/dynamic_message.h> |
| 75 #include <google/protobuf/descriptor.h> | 76 #include <google/protobuf/descriptor.h> |
| 76 #include <google/protobuf/descriptor.pb.h> | 77 #include <google/protobuf/descriptor.pb.h> |
| 77 #include <google/protobuf/generated_message_util.h> | 78 #include <google/protobuf/generated_message_util.h> |
| 78 #include <google/protobuf/generated_message_reflection.h> | 79 #include <google/protobuf/generated_message_reflection.h> |
| 79 #include <google/protobuf/arenastring.h> | 80 #include <google/protobuf/arenastring.h> |
| 80 #include <google/protobuf/map_field_inl.h> | 81 #include <google/protobuf/map_field_inl.h> |
| 81 #include <google/protobuf/reflection_ops.h> | 82 #include <google/protobuf/reflection_ops.h> |
| 82 #include <google/protobuf/repeated_field.h> | 83 #include <google/protobuf/repeated_field.h> |
| 83 #include <google/protobuf/map_type_handler.h> | 84 #include <google/protobuf/map_type_handler.h> |
| 84 #include <google/protobuf/extension_set.h> | 85 #include <google/protobuf/extension_set.h> |
| 85 #include <google/protobuf/wire_format.h> | 86 #include <google/protobuf/wire_format.h> |
| 86 #include <google/protobuf/map_field.h> | 87 #include <google/protobuf/map_field.h> |
| 87 | 88 |
| 88 namespace google { | 89 namespace google { |
| 89 namespace protobuf { | 90 namespace protobuf { |
| 90 | 91 |
| 91 using internal::DynamicMapField; | 92 using internal::WireFormat; |
| 92 using internal::ExtensionSet; | 93 using internal::ExtensionSet; |
| 93 using internal::GeneratedMessageReflection; | 94 using internal::GeneratedMessageReflection; |
| 94 using internal::InternalMetadataWithArena; | |
| 95 using internal::MapField; | 95 using internal::MapField; |
| 96 using internal::DynamicMapField; |
| 96 | 97 |
| 97 | 98 |
| 98 using internal::ArenaStringPtr; | 99 using internal::ArenaStringPtr; |
| 99 | 100 |
| 100 // =================================================================== | 101 // =================================================================== |
| 101 // Some helper tables and functions... | 102 // Some helper tables and functions... |
| 102 | 103 |
| 103 namespace { | 104 namespace { |
| 104 | 105 |
| 105 bool IsMapFieldInApi(const FieldDescriptor* field) { | 106 bool IsMapFieldInApi(const FieldDescriptor* field) { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 } // namespace | 215 } // namespace |
| 215 | 216 |
| 216 // =================================================================== | 217 // =================================================================== |
| 217 | 218 |
| 218 class DynamicMessage : public Message { | 219 class DynamicMessage : public Message { |
| 219 public: | 220 public: |
| 220 struct TypeInfo { | 221 struct TypeInfo { |
| 221 int size; | 222 int size; |
| 222 int has_bits_offset; | 223 int has_bits_offset; |
| 223 int oneof_case_offset; | 224 int oneof_case_offset; |
| 224 int internal_metadata_offset; | 225 int unknown_fields_offset; |
| 225 int extensions_offset; | 226 int extensions_offset; |
| 227 int is_default_instance_offset; |
| 226 | 228 |
| 227 // Not owned by the TypeInfo. | 229 // Not owned by the TypeInfo. |
| 228 DynamicMessageFactory* factory; // The factory that created this object. | 230 DynamicMessageFactory* factory; // The factory that created this object. |
| 229 const DescriptorPool* pool; // The factory's DescriptorPool. | 231 const DescriptorPool* pool; // The factory's DescriptorPool. |
| 230 const Descriptor* type; // Type of this DynamicMessage. | 232 const Descriptor* type; // Type of this DynamicMessage. |
| 231 | 233 |
| 232 // Warning: The order in which the following pointers are defined is | 234 // Warning: The order in which the following pointers are defined is |
| 233 // important (the prototype must be deleted *before* the offsets). | 235 // important (the prototype must be deleted *before* the offsets). |
| 234 google::protobuf::scoped_array<uint32> offsets; | 236 google::protobuf::scoped_array<int> offsets; |
| 235 google::protobuf::scoped_array<uint32> has_bits_indices; | |
| 236 google::protobuf::scoped_ptr<const GeneratedMessageReflection> reflection; | 237 google::protobuf::scoped_ptr<const GeneratedMessageReflection> reflection; |
| 237 // Don't use a scoped_ptr to hold the prototype: the destructor for | 238 // Don't use a scoped_ptr to hold the prototype: the destructor for |
| 238 // DynamicMessage needs to know whether it is the prototype, and does so by | 239 // DynamicMessage needs to know whether it is the prototype, and does so by |
| 239 // looking back at this field. This would assume details about the | 240 // looking back at this field. This would assume details about the |
| 240 // implementation of scoped_ptr. | 241 // implementation of scoped_ptr. |
| 241 const DynamicMessage* prototype; | 242 const DynamicMessage* prototype; |
| 242 void* default_oneof_instance; | 243 void* default_oneof_instance; |
| 243 | 244 |
| 244 TypeInfo() : prototype(NULL), default_oneof_instance(NULL) {} | 245 TypeInfo() : prototype(NULL), default_oneof_instance(NULL) {} |
| 245 | 246 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 // it now. We use placement new even for primitive types that don't have | 322 // it now. We use placement new even for primitive types that don't have |
| 322 // constructors for consistency. (In theory, placement new should be used | 323 // constructors for consistency. (In theory, placement new should be used |
| 323 // any time you are trying to convert untyped memory to typed memory, though | 324 // any time you are trying to convert untyped memory to typed memory, though |
| 324 // in practice that's not strictly necessary for types that don't have a | 325 // in practice that's not strictly necessary for types that don't have a |
| 325 // constructor.) | 326 // constructor.) |
| 326 | 327 |
| 327 const Descriptor* descriptor = type_info_->type; | 328 const Descriptor* descriptor = type_info_->type; |
| 328 | 329 |
| 329 // Initialize oneof cases. | 330 // Initialize oneof cases. |
| 330 for (int i = 0 ; i < descriptor->oneof_decl_count(); ++i) { | 331 for (int i = 0 ; i < descriptor->oneof_decl_count(); ++i) { |
| 331 new (OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i)) | 332 new(OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i)) |
| 332 uint32(0); | 333 uint32(0); |
| 333 } | 334 } |
| 334 | 335 |
| 335 new (OffsetToPointer(type_info_->internal_metadata_offset)) | 336 if (type_info_->is_default_instance_offset != -1) { |
| 336 InternalMetadataWithArena; | 337 *reinterpret_cast<bool*>( |
| 338 OffsetToPointer(type_info_->is_default_instance_offset)) = false; |
| 339 } |
| 340 |
| 341 new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet; |
| 337 | 342 |
| 338 if (type_info_->extensions_offset != -1) { | 343 if (type_info_->extensions_offset != -1) { |
| 339 new (OffsetToPointer(type_info_->extensions_offset)) ExtensionSet; | 344 new(OffsetToPointer(type_info_->extensions_offset)) ExtensionSet; |
| 340 } | 345 } |
| 341 | 346 |
| 342 for (int i = 0; i < descriptor->field_count(); i++) { | 347 for (int i = 0; i < descriptor->field_count(); i++) { |
| 343 const FieldDescriptor* field = descriptor->field(i); | 348 const FieldDescriptor* field = descriptor->field(i); |
| 344 void* field_ptr = OffsetToPointer(type_info_->offsets[i]); | 349 void* field_ptr = OffsetToPointer(type_info_->offsets[i]); |
| 345 if (field->containing_oneof()) { | 350 if (field->containing_oneof()) { |
| 346 continue; | 351 continue; |
| 347 } | 352 } |
| 348 switch (field->cpp_type()) { | 353 switch (field->cpp_type()) { |
| 349 #define HANDLE_TYPE(CPPTYPE, TYPE) \ | 354 #define HANDLE_TYPE(CPPTYPE, TYPE) \ |
| (...skipping 24 matching lines...) Expand all Loading... |
| 374 | 379 |
| 375 case FieldDescriptor::CPPTYPE_STRING: | 380 case FieldDescriptor::CPPTYPE_STRING: |
| 376 switch (field->options().ctype()) { | 381 switch (field->options().ctype()) { |
| 377 default: // TODO(kenton): Support other string reps. | 382 default: // TODO(kenton): Support other string reps. |
| 378 case FieldOptions::STRING: | 383 case FieldOptions::STRING: |
| 379 if (!field->is_repeated()) { | 384 if (!field->is_repeated()) { |
| 380 const string* default_value; | 385 const string* default_value; |
| 381 if (is_prototype()) { | 386 if (is_prototype()) { |
| 382 default_value = &field->default_value_string(); | 387 default_value = &field->default_value_string(); |
| 383 } else { | 388 } else { |
| 384 default_value = &(reinterpret_cast<const ArenaStringPtr*>( | 389 default_value = |
| 385 type_info_->prototype->OffsetToPointer( | 390 &(reinterpret_cast<const ArenaStringPtr*>( |
| 386 type_info_->offsets[i])) | 391 type_info_->prototype->OffsetToPointer( |
| 387 ->Get()); | 392 type_info_->offsets[i]))->Get(NULL)); |
| 388 } | 393 } |
| 389 ArenaStringPtr* asp = new(field_ptr) ArenaStringPtr(); | 394 ArenaStringPtr* asp = new(field_ptr) ArenaStringPtr(); |
| 390 asp->UnsafeSetDefault(default_value); | 395 asp->UnsafeSetDefault(default_value); |
| 391 } else { | 396 } else { |
| 392 new(field_ptr) RepeatedPtrField<string>(); | 397 new(field_ptr) RepeatedPtrField<string>(); |
| 393 } | 398 } |
| 394 break; | 399 break; |
| 395 } | 400 } |
| 396 break; | 401 break; |
| 397 | 402 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 408 } | 413 } |
| 409 break; | 414 break; |
| 410 } | 415 } |
| 411 } | 416 } |
| 412 } | 417 } |
| 413 } | 418 } |
| 414 | 419 |
| 415 DynamicMessage::~DynamicMessage() { | 420 DynamicMessage::~DynamicMessage() { |
| 416 const Descriptor* descriptor = type_info_->type; | 421 const Descriptor* descriptor = type_info_->type; |
| 417 | 422 |
| 418 reinterpret_cast<InternalMetadataWithArena*>( | 423 reinterpret_cast<UnknownFieldSet*>( |
| 419 OffsetToPointer(type_info_->internal_metadata_offset)) | 424 OffsetToPointer(type_info_->unknown_fields_offset))->~UnknownFieldSet(); |
| 420 ->~InternalMetadataWithArena(); | |
| 421 | 425 |
| 422 if (type_info_->extensions_offset != -1) { | 426 if (type_info_->extensions_offset != -1) { |
| 423 reinterpret_cast<ExtensionSet*>( | 427 reinterpret_cast<ExtensionSet*>( |
| 424 OffsetToPointer(type_info_->extensions_offset))->~ExtensionSet(); | 428 OffsetToPointer(type_info_->extensions_offset))->~ExtensionSet(); |
| 425 } | 429 } |
| 426 | 430 |
| 427 // We need to manually run the destructors for repeated fields and strings, | 431 // We need to manually run the destructors for repeated fields and strings, |
| 428 // just as we ran their constructors in the DynamicMessage constructor. | 432 // just as we ran their constructors in the DynamicMessage constructor. |
| 429 // We also need to manually delete oneof fields if it is set and is string | 433 // We also need to manually delete oneof fields if it is set and is string |
| 430 // or message. | 434 // or message. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 441 if (*(reinterpret_cast<const uint32*>(field_ptr)) == | 445 if (*(reinterpret_cast<const uint32*>(field_ptr)) == |
| 442 field->number()) { | 446 field->number()) { |
| 443 field_ptr = OffsetToPointer(type_info_->offsets[ | 447 field_ptr = OffsetToPointer(type_info_->offsets[ |
| 444 descriptor->field_count() + field->containing_oneof()->index()]); | 448 descriptor->field_count() + field->containing_oneof()->index()]); |
| 445 if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { | 449 if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { |
| 446 switch (field->options().ctype()) { | 450 switch (field->options().ctype()) { |
| 447 default: | 451 default: |
| 448 case FieldOptions::STRING: { | 452 case FieldOptions::STRING: { |
| 449 const ::std::string* default_value = | 453 const ::std::string* default_value = |
| 450 &(reinterpret_cast<const ArenaStringPtr*>( | 454 &(reinterpret_cast<const ArenaStringPtr*>( |
| 451 reinterpret_cast<uint8*>( | 455 reinterpret_cast<uint8*>( |
| 452 type_info_->default_oneof_instance) + | 456 type_info_->default_oneof_instance) |
| 453 type_info_->offsets[i]) | 457 + type_info_->offsets[i]) |
| 454 ->Get()); | 458 ->Get(NULL)); |
| 455 reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( | 459 reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( |
| 456 default_value, NULL); | 460 default_value, NULL); |
| 457 break; | 461 break; |
| 458 } | 462 } |
| 459 } | 463 } |
| 460 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { | 464 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
| 461 delete *reinterpret_cast<Message**>(field_ptr); | 465 delete *reinterpret_cast<Message**>(field_ptr); |
| 462 } | 466 } |
| 463 } | 467 } |
| 464 continue; | 468 continue; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 } | 506 } |
| 503 break; | 507 break; |
| 504 } | 508 } |
| 505 | 509 |
| 506 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { | 510 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { |
| 507 switch (field->options().ctype()) { | 511 switch (field->options().ctype()) { |
| 508 default: // TODO(kenton): Support other string reps. | 512 default: // TODO(kenton): Support other string reps. |
| 509 case FieldOptions::STRING: { | 513 case FieldOptions::STRING: { |
| 510 const ::std::string* default_value = | 514 const ::std::string* default_value = |
| 511 &(reinterpret_cast<const ArenaStringPtr*>( | 515 &(reinterpret_cast<const ArenaStringPtr*>( |
| 512 type_info_->prototype->OffsetToPointer( | 516 type_info_->prototype->OffsetToPointer( |
| 513 type_info_->offsets[i])) | 517 type_info_->offsets[i]))->Get(NULL)); |
| 514 ->Get()); | |
| 515 reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( | 518 reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( |
| 516 default_value, NULL); | 519 default_value, NULL); |
| 517 break; | 520 break; |
| 518 } | 521 } |
| 519 } | 522 } |
| 520 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { | 523 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
| 521 if (!is_prototype()) { | 524 if (!is_prototype()) { |
| 522 Message* message = *reinterpret_cast<Message**>(field_ptr); | 525 Message* message = *reinterpret_cast<Message**>(field_ptr); |
| 523 if (message != NULL) { | 526 if (message != NULL) { |
| 524 delete message; | 527 delete message; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 547 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && | 550 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && |
| 548 !field->is_repeated()) { | 551 !field->is_repeated()) { |
| 549 // For fields with message types, we need to cross-link with the | 552 // For fields with message types, we need to cross-link with the |
| 550 // prototype for the field's type. | 553 // prototype for the field's type. |
| 551 // For singular fields, the field is just a pointer which should | 554 // For singular fields, the field is just a pointer which should |
| 552 // point to the prototype. | 555 // point to the prototype. |
| 553 *reinterpret_cast<const Message**>(field_ptr) = | 556 *reinterpret_cast<const Message**>(field_ptr) = |
| 554 factory->GetPrototypeNoLock(field->message_type()); | 557 factory->GetPrototypeNoLock(field->message_type()); |
| 555 } | 558 } |
| 556 } | 559 } |
| 560 |
| 561 // Set as the default instance -- this affects field-presence semantics for |
| 562 // proto3. |
| 563 if (type_info_->is_default_instance_offset != -1) { |
| 564 void* is_default_instance_ptr = |
| 565 OffsetToPointer(type_info_->is_default_instance_offset); |
| 566 *reinterpret_cast<bool*>(is_default_instance_ptr) = true; |
| 567 } |
| 557 } | 568 } |
| 558 | 569 |
| 559 Message* DynamicMessage::New() const { | 570 Message* DynamicMessage::New() const { |
| 560 void* new_base = operator new(type_info_->size); | 571 void* new_base = operator new(type_info_->size); |
| 561 memset(new_base, 0, type_info_->size); | 572 memset(new_base, 0, type_info_->size); |
| 562 return new(new_base) DynamicMessage(type_info_); | 573 return new(new_base) DynamicMessage(type_info_); |
| 563 } | 574 } |
| 564 | 575 |
| 565 Message* DynamicMessage::New(::google::protobuf::Arena* arena) const { | 576 Message* DynamicMessage::New(::google::protobuf::Arena* arena) const { |
| 566 if (arena != NULL) { | 577 if (arena != NULL) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 | 657 |
| 647 // We need to construct all the structures passed to | 658 // We need to construct all the structures passed to |
| 648 // GeneratedMessageReflection's constructor. This includes: | 659 // GeneratedMessageReflection's constructor. This includes: |
| 649 // - A block of memory that contains space for all the message's fields. | 660 // - A block of memory that contains space for all the message's fields. |
| 650 // - An array of integers indicating the byte offset of each field within | 661 // - An array of integers indicating the byte offset of each field within |
| 651 // this block. | 662 // this block. |
| 652 // - A big bitfield containing a bit for each field indicating whether | 663 // - A big bitfield containing a bit for each field indicating whether |
| 653 // or not that field is set. | 664 // or not that field is set. |
| 654 | 665 |
| 655 // Compute size and offsets. | 666 // Compute size and offsets. |
| 656 uint32* offsets = | 667 int* offsets = new int[type->field_count() + type->oneof_decl_count()]; |
| 657 new uint32[type->field_count() + type->oneof_decl_count()]; | |
| 658 type_info->offsets.reset(offsets); | 668 type_info->offsets.reset(offsets); |
| 659 | 669 |
| 660 // Decide all field offsets by packing in order. | 670 // Decide all field offsets by packing in order. |
| 661 // We place the DynamicMessage object itself at the beginning of the allocated | 671 // We place the DynamicMessage object itself at the beginning of the allocated |
| 662 // space. | 672 // space. |
| 663 int size = sizeof(DynamicMessage); | 673 int size = sizeof(DynamicMessage); |
| 664 size = AlignOffset(size); | 674 size = AlignOffset(size); |
| 665 | 675 |
| 666 // Next the has_bits, which is an array of uint32s. | 676 // Next the has_bits, which is an array of uint32s. |
| 667 if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { | 677 if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { |
| 668 type_info->has_bits_offset = -1; | 678 type_info->has_bits_offset = -1; |
| 669 } else { | 679 } else { |
| 670 type_info->has_bits_offset = size; | 680 type_info->has_bits_offset = size; |
| 671 int has_bits_array_size = | 681 int has_bits_array_size = |
| 672 DivideRoundingUp(type->field_count(), bitsizeof(uint32)); | 682 DivideRoundingUp(type->field_count(), bitsizeof(uint32)); |
| 673 size += has_bits_array_size * sizeof(uint32); | 683 size += has_bits_array_size * sizeof(uint32); |
| 674 size = AlignOffset(size); | 684 size = AlignOffset(size); |
| 685 } |
| 675 | 686 |
| 676 uint32* has_bits_indices = new uint32[type->field_count()]; | 687 // The is_default_instance member, if any. |
| 677 for (int i = 0; i < type->field_count(); i++) { | 688 if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { |
| 678 has_bits_indices[i] = i; | 689 type_info->is_default_instance_offset = size; |
| 679 } | 690 size += sizeof(bool); |
| 680 type_info->has_bits_indices.reset(has_bits_indices); | 691 size = AlignOffset(size); |
| 692 } else { |
| 693 type_info->is_default_instance_offset = -1; |
| 681 } | 694 } |
| 682 | 695 |
| 683 // The oneof_case, if any. It is an array of uint32s. | 696 // The oneof_case, if any. It is an array of uint32s. |
| 684 if (type->oneof_decl_count() > 0) { | 697 if (type->oneof_decl_count() > 0) { |
| 685 type_info->oneof_case_offset = size; | 698 type_info->oneof_case_offset = size; |
| 686 size += type->oneof_decl_count() * sizeof(uint32); | 699 size += type->oneof_decl_count() * sizeof(uint32); |
| 687 size = AlignOffset(size); | 700 size = AlignOffset(size); |
| 688 } | 701 } |
| 689 | 702 |
| 690 // The ExtensionSet, if any. | 703 // The ExtensionSet, if any. |
| 691 if (type->extension_range_count() > 0) { | 704 if (type->extension_range_count() > 0) { |
| 692 type_info->extensions_offset = size; | 705 type_info->extensions_offset = size; |
| 693 size += sizeof(ExtensionSet); | 706 size += sizeof(ExtensionSet); |
| 694 size = AlignOffset(size); | 707 size = AlignOffset(size); |
| 695 } else { | 708 } else { |
| 696 // No extensions. | 709 // No extensions. |
| 697 type_info->extensions_offset = -1; | 710 type_info->extensions_offset = -1; |
| 698 } | 711 } |
| 699 | 712 |
| 700 // All the fields. | 713 // All the fields. |
| 701 // | |
| 702 // TODO(b/31226269): Optimize the order of fields to minimize padding. | |
| 703 for (int i = 0; i < type->field_count(); i++) { | 714 for (int i = 0; i < type->field_count(); i++) { |
| 704 // Make sure field is aligned to avoid bus errors. | 715 // Make sure field is aligned to avoid bus errors. |
| 705 // Oneof fields do not use any space. | 716 // Oneof fields do not use any space. |
| 706 if (!type->field(i)->containing_oneof()) { | 717 if (!type->field(i)->containing_oneof()) { |
| 707 int field_size = FieldSpaceUsed(type->field(i)); | 718 int field_size = FieldSpaceUsed(type->field(i)); |
| 708 size = AlignTo(size, std::min(kSafeAlignment, field_size)); | 719 size = AlignTo(size, std::min(kSafeAlignment, field_size)); |
| 709 offsets[i] = size; | 720 offsets[i] = size; |
| 710 size += field_size; | 721 size += field_size; |
| 711 } | 722 } |
| 712 } | 723 } |
| 713 | 724 |
| 714 // The oneofs. | 725 // The oneofs. |
| 715 for (int i = 0; i < type->oneof_decl_count(); i++) { | 726 for (int i = 0; i < type->oneof_decl_count(); i++) { |
| 716 size = AlignTo(size, kSafeAlignment); | 727 size = AlignTo(size, kSafeAlignment); |
| 717 offsets[type->field_count() + i] = size; | 728 offsets[type->field_count() + i] = size; |
| 718 size += kMaxOneofUnionSize; | 729 size += kMaxOneofUnionSize; |
| 719 } | 730 } |
| 720 | 731 |
| 721 // Add the InternalMetadataWithArena to the end. | 732 // Add the UnknownFieldSet to the end. |
| 722 size = AlignOffset(size); | 733 size = AlignOffset(size); |
| 723 type_info->internal_metadata_offset = size; | 734 type_info->unknown_fields_offset = size; |
| 724 size += sizeof(InternalMetadataWithArena); | 735 size += sizeof(UnknownFieldSet); |
| 725 | 736 |
| 726 // Align the final size to make sure no clever allocators think that | 737 // Align the final size to make sure no clever allocators think that |
| 727 // alignment is not necessary. | 738 // alignment is not necessary. |
| 728 size = AlignOffset(size); | 739 size = AlignOffset(size); |
| 729 type_info->size = size; | 740 type_info->size = size; |
| 730 | 741 |
| 731 // Allocate the prototype. | 742 // Allocate the prototype. |
| 732 void* base = operator new(size); | 743 void* base = operator new(size); |
| 733 memset(base, 0, size); | 744 memset(base, 0, size); |
| 734 // The prototype in type_info has to be set before creating the prototype | 745 // The prototype in type_info has to be set before creating the prototype |
| 735 // instance on memory. e.g., message Foo { map<int32, Foo> a = 1; }. When | 746 // instance on memory. e.g., message Foo { map<int32, Foo> a = 1; }. When |
| 736 // creating prototype for Foo, prototype of the map entry will also be | 747 // creating prototype for Foo, prototype of the map entry will also be |
| 737 // created, which needs the address of the prototype of Foo (the value in | 748 // created, which needs the address of the prototype of Foo (the value in |
| 738 // map). To break the cyclic dependency, we have to assgin the address of | 749 // map). To break the cyclic dependency, we have to assgin the address of |
| 739 // prototype into type_info first. | 750 // prototype into type_info first. |
| 740 type_info->prototype = static_cast<DynamicMessage*>(base); | 751 type_info->prototype = static_cast<DynamicMessage*>(base); |
| 741 DynamicMessage* prototype = new(base) DynamicMessage(type_info); | 752 DynamicMessage* prototype = new(base) DynamicMessage(type_info); |
| 742 | 753 |
| 743 // Construct the reflection object. | 754 // Construct the reflection object. |
| 744 | |
| 745 void* default_oneof_instance = NULL; | |
| 746 int oneof_case_offset = -1; | |
| 747 | |
| 748 if (type->oneof_decl_count() > 0) { | 755 if (type->oneof_decl_count() > 0) { |
| 749 // Compute the size of default oneof instance and offsets of default | 756 // Compute the size of default oneof instance and offsets of default |
| 750 // oneof fields. | 757 // oneof fields. |
| 751 int oneof_size = 0; | 758 int oneof_size = 0; |
| 752 for (int i = 0; i < type->oneof_decl_count(); i++) { | 759 for (int i = 0; i < type->oneof_decl_count(); i++) { |
| 753 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { | 760 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { |
| 754 const FieldDescriptor* field = type->oneof_decl(i)->field(j); | 761 const FieldDescriptor* field = type->oneof_decl(i)->field(j); |
| 755 int field_size = OneofFieldSpaceUsed(field); | 762 int field_size = OneofFieldSpaceUsed(field); |
| 756 oneof_size = AlignTo(oneof_size, std::min(kSafeAlignment, field_size)); | 763 oneof_size = AlignTo(oneof_size, std::min(kSafeAlignment, field_size)); |
| 757 offsets[field->index()] = oneof_size; | 764 offsets[field->index()] = oneof_size; |
| 758 oneof_size += field_size; | 765 oneof_size += field_size; |
| 759 } | 766 } |
| 760 } | 767 } |
| 761 // Construct default oneof instance. | 768 // Construct default oneof instance. |
| 762 type_info->default_oneof_instance = ::operator new(oneof_size); | 769 type_info->default_oneof_instance = ::operator new(oneof_size); |
| 763 ConstructDefaultOneofInstance(type_info->type, | 770 ConstructDefaultOneofInstance(type_info->type, |
| 764 type_info->offsets.get(), | 771 type_info->offsets.get(), |
| 765 type_info->default_oneof_instance); | 772 type_info->default_oneof_instance); |
| 766 default_oneof_instance = type_info->default_oneof_instance; | 773 type_info->reflection.reset( |
| 767 oneof_case_offset = type_info->oneof_case_offset; | 774 new GeneratedMessageReflection( |
| 775 type_info->type, |
| 776 type_info->prototype, |
| 777 type_info->offsets.get(), |
| 778 type_info->has_bits_offset, |
| 779 type_info->unknown_fields_offset, |
| 780 type_info->extensions_offset, |
| 781 type_info->default_oneof_instance, |
| 782 type_info->oneof_case_offset, |
| 783 type_info->pool, |
| 784 this, |
| 785 type_info->size, |
| 786 -1 /* arena_offset */, |
| 787 type_info->is_default_instance_offset)); |
| 788 } else { |
| 789 type_info->reflection.reset( |
| 790 new GeneratedMessageReflection( |
| 791 type_info->type, |
| 792 type_info->prototype, |
| 793 type_info->offsets.get(), |
| 794 type_info->has_bits_offset, |
| 795 type_info->unknown_fields_offset, |
| 796 type_info->extensions_offset, |
| 797 type_info->pool, |
| 798 this, |
| 799 type_info->size, |
| 800 -1 /* arena_offset */, |
| 801 type_info->is_default_instance_offset)); |
| 768 } | 802 } |
| 769 | |
| 770 internal::ReflectionSchema schema = { | |
| 771 type_info->prototype, | |
| 772 type_info->offsets.get(), | |
| 773 type_info->has_bits_indices.get(), | |
| 774 type_info->has_bits_offset, | |
| 775 type_info->internal_metadata_offset, | |
| 776 type_info->extensions_offset, | |
| 777 default_oneof_instance, | |
| 778 oneof_case_offset, | |
| 779 type_info->size}; | |
| 780 | |
| 781 type_info->reflection.reset(new GeneratedMessageReflection( | |
| 782 type_info->type, schema, type_info->pool, this)); | |
| 783 | |
| 784 // Cross link prototypes. | 803 // Cross link prototypes. |
| 785 prototype->CrossLinkPrototypes(); | 804 prototype->CrossLinkPrototypes(); |
| 786 | 805 |
| 787 return prototype; | 806 return prototype; |
| 788 } | 807 } |
| 789 | 808 |
| 790 void DynamicMessageFactory::ConstructDefaultOneofInstance( | 809 void DynamicMessageFactory::ConstructDefaultOneofInstance( |
| 791 const Descriptor* type, | 810 const Descriptor* type, |
| 792 const uint32 offsets[], | 811 const int offsets[], |
| 793 void* default_oneof_instance) { | 812 void* default_oneof_instance) { |
| 794 for (int i = 0; i < type->oneof_decl_count(); i++) { | 813 for (int i = 0; i < type->oneof_decl_count(); i++) { |
| 795 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { | 814 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { |
| 796 const FieldDescriptor* field = type->oneof_decl(i)->field(j); | 815 const FieldDescriptor* field = type->oneof_decl(i)->field(j); |
| 797 void* field_ptr = reinterpret_cast<uint8*>( | 816 void* field_ptr = reinterpret_cast<uint8*>( |
| 798 default_oneof_instance) + offsets[field->index()]; | 817 default_oneof_instance) + offsets[field->index()]; |
| 799 switch (field->cpp_type()) { | 818 switch (field->cpp_type()) { |
| 800 #define HANDLE_TYPE(CPPTYPE, TYPE) \ | 819 #define HANDLE_TYPE(CPPTYPE, TYPE) \ |
| 801 case FieldDescriptor::CPPTYPE_##CPPTYPE: \ | 820 case FieldDescriptor::CPPTYPE_##CPPTYPE: \ |
| 802 new(field_ptr) TYPE(field->default_value_##TYPE()); \ | 821 new(field_ptr) TYPE(field->default_value_##TYPE()); \ |
| (...skipping 25 matching lines...) Expand all Loading... |
| 828 new(field_ptr) Message*(NULL); | 847 new(field_ptr) Message*(NULL); |
| 829 break; | 848 break; |
| 830 } | 849 } |
| 831 } | 850 } |
| 832 } | 851 } |
| 833 } | 852 } |
| 834 } | 853 } |
| 835 | 854 |
| 836 void DynamicMessageFactory::DeleteDefaultOneofInstance( | 855 void DynamicMessageFactory::DeleteDefaultOneofInstance( |
| 837 const Descriptor* type, | 856 const Descriptor* type, |
| 838 const uint32 offsets[], | 857 const int offsets[], |
| 839 void* default_oneof_instance) { | 858 void* default_oneof_instance) { |
| 840 for (int i = 0; i < type->oneof_decl_count(); i++) { | 859 for (int i = 0; i < type->oneof_decl_count(); i++) { |
| 841 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { | 860 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { |
| 842 const FieldDescriptor* field = type->oneof_decl(i)->field(j); | 861 const FieldDescriptor* field = type->oneof_decl(i)->field(j); |
| 843 if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { | 862 if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { |
| 844 switch (field->options().ctype()) { | 863 switch (field->options().ctype()) { |
| 845 default: | 864 default: |
| 846 case FieldOptions::STRING: | 865 case FieldOptions::STRING: |
| 847 break; | 866 break; |
| 848 } | 867 } |
| 849 } | 868 } |
| 850 } | 869 } |
| 851 } | 870 } |
| 852 } | 871 } |
| 853 | 872 |
| 854 } // namespace protobuf | 873 } // namespace protobuf |
| 855 } // namespace google | 874 } // namespace google |
| OLD | NEW |