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