65 #include <google/protobuf/dynamic_message.h>
71 #include <unordered_map>
73 #include <google/protobuf/descriptor.pb.h>
74 #include <google/protobuf/descriptor.h>
75 #include <google/protobuf/generated_message_reflection.h>
76 #include <google/protobuf/generated_message_util.h>
77 #include <google/protobuf/unknown_field_set.h>
78 #include <google/protobuf/stubs/hash.h>
79 #include <google/protobuf/arenastring.h>
80 #include <google/protobuf/extension_set.h>
81 #include <google/protobuf/map_field.h>
82 #include <google/protobuf/map_field_inl.h>
83 #include <google/protobuf/map_type_handler.h>
84 #include <google/protobuf/reflection_ops.h>
85 #include <google/protobuf/repeated_field.h>
86 #include <google/protobuf/wire_format.h>
88 #include <google/protobuf/port_def.inc>
93 using internal::DynamicMapField;
94 using internal::ExtensionSet;
95 using internal::MapField;
98 using internal::ArenaStringPtr;
142 case FD::CPPTYPE_INT32:
144 case FD::CPPTYPE_INT64:
146 case FD::CPPTYPE_UINT32:
148 case FD::CPPTYPE_UINT64:
150 case FD::CPPTYPE_DOUBLE:
152 case FD::CPPTYPE_FLOAT:
154 case FD::CPPTYPE_BOOL:
156 case FD::CPPTYPE_ENUM:
158 case FD::CPPTYPE_MESSAGE:
159 if (IsMapFieldInApi(
field)) {
160 return sizeof(DynamicMapField);
162 return sizeof(RepeatedPtrField<Message>);
165 case FD::CPPTYPE_STRING:
169 return sizeof(RepeatedPtrField<std::string>);
175 case FD::CPPTYPE_INT32:
177 case FD::CPPTYPE_INT64:
179 case FD::CPPTYPE_UINT32:
181 case FD::CPPTYPE_UINT64:
183 case FD::CPPTYPE_DOUBLE:
184 return sizeof(double);
185 case FD::CPPTYPE_FLOAT:
186 return sizeof(float);
187 case FD::CPPTYPE_BOOL:
189 case FD::CPPTYPE_ENUM:
192 case FD::CPPTYPE_MESSAGE:
195 case FD::CPPTYPE_STRING:
199 return sizeof(ArenaStringPtr);
209 inline int DivideRoundingUp(
int i,
int j) {
return (i + (j - 1)) /
j; }
211 static const int kSafeAlignment =
sizeof(
uint64_t);
212 static const int kMaxOneofUnionSize =
sizeof(
uint64_t);
222 #define bitsizeof(T) (sizeof(T) * 8)
228 class DynamicMessage :
public Message {
230 explicit DynamicMessage(
const DynamicMessageFactory::TypeInfo* type_info);
233 DynamicMessage(DynamicMessageFactory::TypeInfo* type_info,
bool lock_factory);
256 #if defined(__cpp_lib_destroying_delete) && defined(__cpp_sized_deallocation)
265 static void operator delete(
void*
ptr) { ::operator
delete(
ptr); }
334 : type_info_(type_info), cached_byte_size_(0) {
340 :
Message(
arena), type_info_(type_info), cached_byte_size_(0) {
346 : type_info_(type_info), cached_byte_size_(0) {
373 f->containing_oneof()->index()],
390 for (
int i = 0;
i <
descriptor->oneof_decl_count(); ++
i) {
391 if (
descriptor->oneof_decl(i)->is_synthetic())
continue;
401 if (InRealOneof(
field)) {
404 switch (
field->cpp_type()) {
405 #define HANDLE_TYPE(CPPTYPE, TYPE) \
406 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
407 if (!field->is_repeated()) { \
408 new (field_ptr) TYPE(field->default_value_##TYPE()); \
410 new (field_ptr) RepeatedField<TYPE>(GetArenaForAllocation()); \
424 if (!
field->is_repeated()) {
425 new (field_ptr)
int{
field->default_value_enum()->number()};
432 switch (
field->options().ctype()) {
435 if (!
field->is_repeated()) {
437 field->default_value_string().empty()
440 ArenaStringPtr* asp =
new (field_ptr) ArenaStringPtr();
441 asp->UnsafeSetDefault(default_value);
451 if (!
field->is_repeated()) {
452 new (field_ptr)
Message*(
nullptr);
454 if (IsMapFieldInApi(
field)) {
460 new (field_ptr) DynamicMapField(
466 static_cast<DynamicMapField*
>(field_ptr));
469 new (field_ptr) DynamicMapField(
476 field->message_type()),
481 static_cast<DynamicMapField*
>(field_ptr));
486 field->message_type()));
506 #if defined(__cpp_lib_destroying_delete) && defined(__cpp_sized_deallocation)
507 void DynamicMessage::operator
delete(DynamicMessage*
msg,
508 std::destroying_delete_t) {
509 const size_t size =
msg->type_info_->size;
510 msg->~DynamicMessage();
534 if (InRealOneof(
field)) {
536 if (*(
reinterpret_cast<const int32_t*
>(field_ptr)) ==
field->number()) {
539 switch (
field->options().ctype()) {
547 reinterpret_cast<ArenaStringPtr*
>(field_ptr)->
Destroy(
548 default_value,
nullptr);
553 delete *
reinterpret_cast<Message**
>(field_ptr);
560 if (
field->is_repeated()) {
561 switch (
field->cpp_type()) {
562 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
563 case FieldDescriptor::CPPTYPE_##UPPERCASE: \
564 reinterpret_cast<RepeatedField<LOWERCASE>*>(field_ptr) \
565 ->~RepeatedField<LOWERCASE>(); \
579 switch (
field->options().ctype()) {
582 reinterpret_cast<RepeatedPtrField<std::string>*
>(field_ptr)
583 ->~RepeatedPtrField<std::string>();
589 if (IsMapFieldInApi(
field)) {
590 reinterpret_cast<DynamicMapField*
>(field_ptr)->~DynamicMapField();
592 reinterpret_cast<RepeatedPtrField<Message>*
>(field_ptr)
593 ->~RepeatedPtrField<Message>();
599 switch (
field->options().ctype()) {
603 reinterpret_cast<const ArenaStringPtr*
>(
607 reinterpret_cast<ArenaStringPtr*
>(field_ptr)->
Destroy(default_value,
634 !
field->options().weak() && !InRealOneof(
field) &&
635 !
field->is_repeated()) {
641 *
reinterpret_cast<const Message**
>(field_ptr) =
642 factory->GetPrototypeNoLock(
field->message_type());
648 if (
arena !=
nullptr) {
677 :
pool_(nullptr), delegate_to_generated_factory_(
false) {}
703 return (*target)->prototype;
710 type_info->pool = (
pool_ ==
nullptr) ?
type->file()->pool() :
pool_;
711 type_info->factory =
this;
720 int real_oneof_count = 0;
721 for (
int i = 0;
i <
type->oneof_decl_count();
i++) {
722 if (!
type->oneof_decl(i)->is_synthetic()) {
729 type_info->offsets.reset(offsets);
738 type_info->has_bits_offset = -1;
740 for (
int i = 0;
i <
type->field_count();
i++) {
742 if (type_info->has_bits_offset == -1) {
745 type_info->has_bits_offset =
size;
747 for (
int j = 0;
j <
type->field_count();
j++) {
749 has_bits_indices[
j] =
static_cast<uint32_t>(-1);
751 type_info->has_bits_indices.reset(has_bits_indices);
753 type_info->has_bits_indices[
i] = max_hasbit++;
757 if (max_hasbit > 0) {
764 if (real_oneof_count > 0) {
765 type_info->oneof_case_offset =
size;
771 if (
type->extension_range_count() > 0) {
772 type_info->extensions_offset =
size;
773 size +=
sizeof(ExtensionSet);
777 type_info->extensions_offset = -1;
783 for (
int i = 0;
i <
type->field_count();
i++) {
786 if (!InRealOneof(
type->field(i))) {
787 int field_size = FieldSpaceUsed(
type->field(i));
795 for (
int i = 0;
i <
type->oneof_decl_count();
i++) {
796 if (!
type->oneof_decl(i)->is_synthetic()) {
799 size += kMaxOneofUnionSize;
803 type_info->weak_field_map_offset = -1;
807 type_info->size =
size;
813 for (
int i = 0;
i <
type->oneof_decl_count();
i++) {
814 if (
type->oneof_decl(i)->is_synthetic())
continue;
815 for (
int j = 0;
j <
type->oneof_decl(i)->field_count();
j++) {
834 internal::ReflectionSchema schema = {
835 type_info->prototype,
836 type_info->offsets.get(),
837 type_info->has_bits_indices.get(),
838 type_info->has_bits_offset,
840 type_info->extensions_offset,
841 type_info->oneof_case_offset,
843 type_info->weak_field_map_offset,
847 type_info->reflection.reset(
848 new Reflection(type_info->
type, schema, type_info->pool,
this));
851 prototype->CrossLinkPrototypes();
859 #include <google/protobuf/port_undef.inc>