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

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

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years 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>
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698