Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: third_party/protobuf/src/google/protobuf/dynamic_message.cc

Issue 2600753002: Reverts third_party/protobuf: Update to HEAD (f52e188fe4) (Closed)
Patch Set: Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698