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