File indexing completed on 2025-01-31 10:12:22
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef GOOGLE_PROTOBUF_MAP_FIELD_H__
0009 #define GOOGLE_PROTOBUF_MAP_FIELD_H__
0010
0011 #include <atomic>
0012 #include <cstddef>
0013 #include <cstdint>
0014 #include <functional>
0015 #include <string>
0016 #include <type_traits>
0017 #include <utility>
0018
0019 #include "absl/log/absl_check.h"
0020 #include "absl/log/absl_log.h"
0021 #include "absl/synchronization/mutex.h"
0022 #include "google/protobuf/arena.h"
0023 #include "google/protobuf/descriptor.h"
0024 #include "google/protobuf/explicitly_constructed.h"
0025 #include "google/protobuf/generated_message_reflection.h"
0026 #include "google/protobuf/generated_message_util.h"
0027 #include "google/protobuf/internal_visibility.h"
0028 #include "google/protobuf/map.h"
0029 #include "google/protobuf/map_entry.h"
0030 #include "google/protobuf/map_field_lite.h"
0031 #include "google/protobuf/map_type_handler.h"
0032 #include "google/protobuf/message.h"
0033 #include "google/protobuf/message_lite.h"
0034 #include "google/protobuf/port.h"
0035 #include "google/protobuf/repeated_field.h"
0036 #include "google/protobuf/unknown_field_set.h"
0037
0038
0039
0040 #include "google/protobuf/port_def.inc"
0041
0042 #ifdef SWIG
0043 #error "You cannot SWIG proto headers"
0044 #endif
0045
0046 namespace google {
0047 namespace protobuf {
0048 class DynamicMessage;
0049 class MapIterator;
0050
0051
0052
0053 #ifdef _MSC_VER
0054 #pragma warning(push)
0055 #pragma warning(disable : 4265)
0056 #endif
0057
0058 #define TYPE_CHECK(EXPECTEDTYPE, METHOD) \
0059 if (type() != EXPECTEDTYPE) { \
0060 ABSL_LOG(FATAL) << "Protocol Buffer map usage error:\n" \
0061 << METHOD << " type does not match\n" \
0062 << " Expected : " \
0063 << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n" \
0064 << " Actual : " \
0065 << FieldDescriptor::CppTypeName(type()); \
0066 }
0067
0068
0069
0070 class PROTOBUF_EXPORT MapKey {
0071 public:
0072 MapKey() : type_() {}
0073 MapKey(const MapKey& other) : type_() { CopyFrom(other); }
0074
0075 MapKey& operator=(const MapKey& other) {
0076 CopyFrom(other);
0077 return *this;
0078 }
0079
0080 ~MapKey() {
0081 if (type_ == FieldDescriptor::CPPTYPE_STRING) {
0082 val_.string_value.Destruct();
0083 }
0084 }
0085
0086 FieldDescriptor::CppType type() const {
0087 if (type_ == FieldDescriptor::CppType()) {
0088 ABSL_LOG(FATAL) << "Protocol Buffer map usage error:\n"
0089 << "MapKey::type MapKey is not initialized. "
0090 << "Call set methods to initialize MapKey.";
0091 }
0092 return type_;
0093 }
0094
0095 void SetInt64Value(int64_t value) {
0096 SetType(FieldDescriptor::CPPTYPE_INT64);
0097 val_.int64_value = value;
0098 }
0099 void SetUInt64Value(uint64_t value) {
0100 SetType(FieldDescriptor::CPPTYPE_UINT64);
0101 val_.uint64_value = value;
0102 }
0103 void SetInt32Value(int32_t value) {
0104 SetType(FieldDescriptor::CPPTYPE_INT32);
0105 val_.int32_value = value;
0106 }
0107 void SetUInt32Value(uint32_t value) {
0108 SetType(FieldDescriptor::CPPTYPE_UINT32);
0109 val_.uint32_value = value;
0110 }
0111 void SetBoolValue(bool value) {
0112 SetType(FieldDescriptor::CPPTYPE_BOOL);
0113 val_.bool_value = value;
0114 }
0115 void SetStringValue(std::string val) {
0116 SetType(FieldDescriptor::CPPTYPE_STRING);
0117 *val_.string_value.get_mutable() = std::move(val);
0118 }
0119
0120 int64_t GetInt64Value() const {
0121 TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapKey::GetInt64Value");
0122 return val_.int64_value;
0123 }
0124 uint64_t GetUInt64Value() const {
0125 TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapKey::GetUInt64Value");
0126 return val_.uint64_value;
0127 }
0128 int32_t GetInt32Value() const {
0129 TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapKey::GetInt32Value");
0130 return val_.int32_value;
0131 }
0132 uint32_t GetUInt32Value() const {
0133 TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapKey::GetUInt32Value");
0134 return val_.uint32_value;
0135 }
0136 bool GetBoolValue() const {
0137 TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapKey::GetBoolValue");
0138 return val_.bool_value;
0139 }
0140 const std::string& GetStringValue() const {
0141 TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapKey::GetStringValue");
0142 return val_.string_value.get();
0143 }
0144
0145 bool operator<(const MapKey& other) const {
0146 if (type_ != other.type_) {
0147
0148
0149 ABSL_LOG(FATAL) << "Unsupported: type mismatch";
0150 }
0151 switch (type()) {
0152 case FieldDescriptor::CPPTYPE_DOUBLE:
0153 case FieldDescriptor::CPPTYPE_FLOAT:
0154 case FieldDescriptor::CPPTYPE_ENUM:
0155 case FieldDescriptor::CPPTYPE_MESSAGE:
0156 ABSL_LOG(FATAL) << "Unsupported";
0157 return false;
0158 case FieldDescriptor::CPPTYPE_STRING:
0159 return val_.string_value.get() < other.val_.string_value.get();
0160 case FieldDescriptor::CPPTYPE_INT64:
0161 return val_.int64_value < other.val_.int64_value;
0162 case FieldDescriptor::CPPTYPE_INT32:
0163 return val_.int32_value < other.val_.int32_value;
0164 case FieldDescriptor::CPPTYPE_UINT64:
0165 return val_.uint64_value < other.val_.uint64_value;
0166 case FieldDescriptor::CPPTYPE_UINT32:
0167 return val_.uint32_value < other.val_.uint32_value;
0168 case FieldDescriptor::CPPTYPE_BOOL:
0169 return val_.bool_value < other.val_.bool_value;
0170 }
0171 return false;
0172 }
0173
0174 bool operator==(const MapKey& other) const {
0175 if (type_ != other.type_) {
0176
0177 ABSL_LOG(FATAL) << "Unsupported: type mismatch";
0178 }
0179 switch (type()) {
0180 case FieldDescriptor::CPPTYPE_DOUBLE:
0181 case FieldDescriptor::CPPTYPE_FLOAT:
0182 case FieldDescriptor::CPPTYPE_ENUM:
0183 case FieldDescriptor::CPPTYPE_MESSAGE:
0184 ABSL_LOG(FATAL) << "Unsupported";
0185 break;
0186 case FieldDescriptor::CPPTYPE_STRING:
0187 return val_.string_value.get() == other.val_.string_value.get();
0188 case FieldDescriptor::CPPTYPE_INT64:
0189 return val_.int64_value == other.val_.int64_value;
0190 case FieldDescriptor::CPPTYPE_INT32:
0191 return val_.int32_value == other.val_.int32_value;
0192 case FieldDescriptor::CPPTYPE_UINT64:
0193 return val_.uint64_value == other.val_.uint64_value;
0194 case FieldDescriptor::CPPTYPE_UINT32:
0195 return val_.uint32_value == other.val_.uint32_value;
0196 case FieldDescriptor::CPPTYPE_BOOL:
0197 return val_.bool_value == other.val_.bool_value;
0198 }
0199 ABSL_LOG(FATAL) << "Can't get here.";
0200 return false;
0201 }
0202
0203 void CopyFrom(const MapKey& other) {
0204 SetType(other.type());
0205 switch (type_) {
0206 case FieldDescriptor::CPPTYPE_DOUBLE:
0207 case FieldDescriptor::CPPTYPE_FLOAT:
0208 case FieldDescriptor::CPPTYPE_ENUM:
0209 case FieldDescriptor::CPPTYPE_MESSAGE:
0210 ABSL_LOG(FATAL) << "Unsupported";
0211 break;
0212 case FieldDescriptor::CPPTYPE_STRING:
0213 *val_.string_value.get_mutable() = other.val_.string_value.get();
0214 break;
0215 case FieldDescriptor::CPPTYPE_INT64:
0216 val_.int64_value = other.val_.int64_value;
0217 break;
0218 case FieldDescriptor::CPPTYPE_INT32:
0219 val_.int32_value = other.val_.int32_value;
0220 break;
0221 case FieldDescriptor::CPPTYPE_UINT64:
0222 val_.uint64_value = other.val_.uint64_value;
0223 break;
0224 case FieldDescriptor::CPPTYPE_UINT32:
0225 val_.uint32_value = other.val_.uint32_value;
0226 break;
0227 case FieldDescriptor::CPPTYPE_BOOL:
0228 val_.bool_value = other.val_.bool_value;
0229 break;
0230 }
0231 }
0232
0233 private:
0234 template <typename K, typename V>
0235 friend class internal::TypeDefinedMapFieldBase;
0236 friend class internal::MapFieldBase;
0237 friend class MapIterator;
0238 friend class internal::DynamicMapField;
0239
0240 union KeyValue {
0241 KeyValue() {}
0242 internal::ExplicitlyConstructed<std::string> string_value;
0243 int64_t int64_value;
0244 int32_t int32_value;
0245 uint64_t uint64_value;
0246 uint32_t uint32_value;
0247 bool bool_value;
0248 } val_;
0249
0250 void SetType(FieldDescriptor::CppType type) {
0251 if (type_ == type) return;
0252 if (type_ == FieldDescriptor::CPPTYPE_STRING) {
0253 val_.string_value.Destruct();
0254 }
0255 type_ = type;
0256 if (type_ == FieldDescriptor::CPPTYPE_STRING) {
0257 val_.string_value.DefaultConstruct();
0258 }
0259 }
0260
0261
0262
0263 FieldDescriptor::CppType type_;
0264 };
0265
0266 namespace internal {
0267
0268 template <>
0269 struct is_internal_map_key_type<MapKey> : std::true_type {};
0270
0271 template <>
0272 struct RealKeyToVariantKey<MapKey> {
0273 VariantKey operator()(const MapKey& value) const;
0274 };
0275
0276 }
0277
0278 }
0279 }
0280 namespace std {
0281 template <>
0282 struct hash<google::protobuf::MapKey> {
0283 size_t operator()(const google::protobuf::MapKey& map_key) const {
0284 return ::google::protobuf::internal::RealKeyToVariantKey<::google::protobuf::MapKey>{}(map_key)
0285 .Hash();
0286 }
0287 bool operator()(const google::protobuf::MapKey& map_key1,
0288 const google::protobuf::MapKey& map_key2) const {
0289 return map_key1 < map_key2;
0290 }
0291 };
0292 }
0293
0294 namespace google {
0295 namespace protobuf {
0296 namespace internal {
0297
0298 class ContendedMapCleanTest;
0299 class GeneratedMessageReflection;
0300 class MapFieldAccessor;
0301
0302 template <typename MessageT>
0303 struct MapDynamicFieldInfo;
0304 struct MapFieldTestPeer;
0305
0306
0307
0308
0309 class PROTOBUF_EXPORT MapFieldBase : public MapFieldBaseForParse {
0310 public:
0311 explicit constexpr MapFieldBase(const VTable* vtable)
0312 : MapFieldBaseForParse(vtable) {}
0313 explicit MapFieldBase(const VTable* vtable, Arena* arena)
0314 : MapFieldBaseForParse(vtable), payload_{ToTaggedPtr(arena)} {}
0315 MapFieldBase(const MapFieldBase&) = delete;
0316 MapFieldBase& operator=(const MapFieldBase&) = delete;
0317
0318 protected:
0319
0320 ~MapFieldBase();
0321
0322 struct VTable : MapFieldBaseForParse::VTable {
0323 bool (*lookup_map_value)(const MapFieldBase& map, const MapKey& map_key,
0324 MapValueConstRef* val);
0325 bool (*delete_map_value)(MapFieldBase& map, const MapKey& map_key);
0326 void (*set_map_iterator_value)(MapIterator* map_iter);
0327 bool (*insert_or_lookup_no_sync)(MapFieldBase& map, const MapKey& map_key,
0328 MapValueRef* val);
0329
0330 void (*clear_map_no_sync)(MapFieldBase& map);
0331 void (*merge_from)(MapFieldBase& map, const MapFieldBase& other);
0332 void (*swap)(MapFieldBase& lhs, MapFieldBase& rhs);
0333 void (*unsafe_shallow_swap)(MapFieldBase& lhs, MapFieldBase& rhs);
0334 size_t (*space_used_excluding_self_nolock)(const MapFieldBase& map);
0335
0336 const Message* (*get_prototype)(const MapFieldBase& map);
0337 };
0338 template <typename T>
0339 static constexpr VTable MakeVTable() {
0340 VTable out{};
0341 out.get_map = &T::GetMapImpl;
0342 out.lookup_map_value = &T::LookupMapValueImpl;
0343 out.delete_map_value = &T::DeleteMapValueImpl;
0344 out.set_map_iterator_value = &T::SetMapIteratorValueImpl;
0345 out.insert_or_lookup_no_sync = &T::InsertOrLookupMapValueNoSyncImpl;
0346 out.clear_map_no_sync = &T::ClearMapNoSyncImpl;
0347 out.merge_from = &T::MergeFromImpl;
0348 out.swap = &T::SwapImpl;
0349 out.unsafe_shallow_swap = &T::UnsafeShallowSwapImpl;
0350 out.space_used_excluding_self_nolock = &T::SpaceUsedExcludingSelfNoLockImpl;
0351 out.get_prototype = &T::GetPrototypeImpl;
0352 return out;
0353 }
0354
0355 public:
0356
0357
0358
0359 const RepeatedPtrFieldBase& GetRepeatedField() const;
0360
0361
0362 RepeatedPtrFieldBase* MutableRepeatedField();
0363
0364 const VTable* vtable() const { return static_cast<const VTable*>(vtable_); }
0365
0366 bool ContainsMapKey(const MapKey& map_key) const {
0367 return LookupMapValue(map_key, static_cast<MapValueConstRef*>(nullptr));
0368 }
0369 bool LookupMapValue(const MapKey& map_key, MapValueConstRef* val) const {
0370 return vtable()->lookup_map_value(*this, map_key, val);
0371 }
0372 bool LookupMapValue(const MapKey&, MapValueRef*) const = delete;
0373
0374 bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val);
0375
0376
0377 bool IsRepeatedFieldValid() const;
0378
0379 bool IsMapValid() const;
0380 bool DeleteMapValue(const MapKey& map_key) {
0381 return vtable()->delete_map_value(*this, map_key);
0382 }
0383 void MergeFrom(const MapFieldBase& other) {
0384 vtable()->merge_from(*this, other);
0385 }
0386 void Swap(MapFieldBase* other) { vtable()->swap(*this, *other); }
0387 void UnsafeShallowSwap(MapFieldBase* other) {
0388 vtable()->unsafe_shallow_swap(*this, *other);
0389 }
0390
0391 int size() const;
0392 void Clear();
0393 void SetMapIteratorValue(MapIterator* map_iter) const {
0394 return vtable()->set_map_iterator_value(map_iter);
0395 }
0396
0397 void MapBegin(MapIterator* map_iter) const;
0398 void MapEnd(MapIterator* map_iter) const;
0399 bool EqualIterator(const MapIterator& a, const MapIterator& b) const;
0400
0401
0402
0403 size_t SpaceUsedExcludingSelfLong() const;
0404
0405 int SpaceUsedExcludingSelf() const {
0406 return internal::ToIntSize(SpaceUsedExcludingSelfLong());
0407 }
0408
0409 protected:
0410
0411 size_t SpaceUsedExcludingSelfNoLock() const {
0412 return vtable()->space_used_excluding_self_nolock(*this);
0413 }
0414
0415 const Message* GetPrototype() const { return vtable()->get_prototype(*this); }
0416 void ClearMapNoSync() { return vtable()->clear_map_no_sync(*this); }
0417
0418
0419
0420 const RepeatedPtrFieldBase& SyncRepeatedFieldWithMap(bool for_mutation) const;
0421 void SyncRepeatedFieldWithMapNoLock();
0422
0423
0424
0425 void SyncMapWithRepeatedField() const;
0426 void SyncMapWithRepeatedFieldNoLock();
0427
0428 static void SwapImpl(MapFieldBase& lhs, MapFieldBase& rhs);
0429 static void UnsafeShallowSwapImpl(MapFieldBase& lhs, MapFieldBase& rhs);
0430
0431
0432 void SetMapDirty();
0433
0434
0435 void SetRepeatedDirty();
0436
0437
0438 void* MutableRepeatedPtrField() const;
0439
0440 bool InsertOrLookupMapValueNoSync(const MapKey& map_key, MapValueRef* val) {
0441 return vtable()->insert_or_lookup_no_sync(*this, map_key, val);
0442 }
0443
0444 void InternalSwap(MapFieldBase* other);
0445
0446
0447
0448
0449
0450
0451 #if defined(PROTOBUF_TSAN)
0452 void ConstAccess() const { ABSL_CHECK_EQ(seq1_, seq2_); }
0453 void MutableAccess() {
0454 if (seq1_ & 1) {
0455 seq2_ = ++seq1_;
0456 } else {
0457 seq1_ = ++seq2_;
0458 }
0459 }
0460 unsigned int seq1_ = 0, seq2_ = 0;
0461 #else
0462 void ConstAccess() const {}
0463 void MutableAccess() {}
0464 #endif
0465 enum State {
0466 STATE_MODIFIED_MAP = 0,
0467
0468 STATE_MODIFIED_REPEATED = 1,
0469
0470 CLEAN = 2,
0471 };
0472
0473 struct ReflectionPayload {
0474 explicit ReflectionPayload(Arena* arena) : repeated_field(arena) {}
0475 RepeatedPtrField<Message> repeated_field;
0476
0477 absl::Mutex mutex;
0478
0479 std::atomic<State> state{STATE_MODIFIED_MAP};
0480 };
0481
0482 Arena* arena() const {
0483 auto p = payload_.load(std::memory_order_acquire);
0484 if (IsPayload(p)) return ToPayload(p)->repeated_field.GetArena();
0485 return ToArena(p);
0486 }
0487
0488
0489 ReflectionPayload* maybe_payload() const {
0490 auto p = payload_.load(std::memory_order_acquire);
0491 return IsPayload(p) ? ToPayload(p) : nullptr;
0492 }
0493
0494 ReflectionPayload& payload() const {
0495 auto* p = maybe_payload();
0496 return p != nullptr ? *p : PayloadSlow();
0497 }
0498 ReflectionPayload& PayloadSlow() const;
0499
0500 State state() const {
0501 auto* p = maybe_payload();
0502 return p != nullptr ? p->state.load(std::memory_order_acquire)
0503
0504 : STATE_MODIFIED_MAP;
0505 }
0506
0507 static const UntypedMapBase& GetMapImpl(const MapFieldBaseForParse& map,
0508 bool is_mutable);
0509
0510 private:
0511 friend class ContendedMapCleanTest;
0512 friend class GeneratedMessageReflection;
0513 friend class MapFieldAccessor;
0514 friend class google::protobuf::Reflection;
0515 friend class google::protobuf::DynamicMessage;
0516
0517
0518 const UntypedMapBase& GetMapRaw() const {
0519 return *reinterpret_cast<const UntypedMapBase*>(this + 1);
0520 }
0521 UntypedMapBase& GetMapRaw() {
0522 return *reinterpret_cast<UntypedMapBase*>(this + 1);
0523 }
0524
0525
0526
0527
0528
0529 friend class google::protobuf::MapIterator;
0530
0531
0532
0533 void CopyIterator(MapIterator* this_iter, const MapIterator& that_iter) const;
0534
0535
0536
0537 void IncreaseIterator(MapIterator* map_iter) const;
0538
0539 enum class TaggedPtr : uintptr_t {};
0540 static constexpr uintptr_t kHasPayloadBit = 1;
0541
0542 static ReflectionPayload* ToPayload(TaggedPtr p) {
0543 ABSL_DCHECK(IsPayload(p));
0544 auto* res = reinterpret_cast<ReflectionPayload*>(static_cast<uintptr_t>(p) -
0545 kHasPayloadBit);
0546 PROTOBUF_ASSUME(res != nullptr);
0547 return res;
0548 }
0549 static Arena* ToArena(TaggedPtr p) {
0550 ABSL_DCHECK(!IsPayload(p));
0551 return reinterpret_cast<Arena*>(p);
0552 }
0553 static TaggedPtr ToTaggedPtr(ReflectionPayload* p) {
0554 return static_cast<TaggedPtr>(reinterpret_cast<uintptr_t>(p) +
0555 kHasPayloadBit);
0556 }
0557 static TaggedPtr ToTaggedPtr(Arena* p) {
0558 return static_cast<TaggedPtr>(reinterpret_cast<uintptr_t>(p));
0559 }
0560 static bool IsPayload(TaggedPtr p) {
0561 return static_cast<uintptr_t>(p) & kHasPayloadBit;
0562 }
0563
0564 mutable std::atomic<TaggedPtr> payload_{};
0565 };
0566
0567
0568
0569 template <typename Key, typename T>
0570 class TypeDefinedMapFieldBase : public MapFieldBase {
0571 public:
0572 explicit constexpr TypeDefinedMapFieldBase(const VTable* vtable)
0573 : MapFieldBase(vtable), map_() {
0574
0575
0576 static_assert(PROTOBUF_FIELD_OFFSET(TypeDefinedMapFieldBase, map_) ==
0577 sizeof(MapFieldBase),
0578 "");
0579 }
0580 TypeDefinedMapFieldBase(const TypeDefinedMapFieldBase&) = delete;
0581 TypeDefinedMapFieldBase& operator=(const TypeDefinedMapFieldBase&) = delete;
0582
0583 TypeDefinedMapFieldBase(const VTable* vtable, Arena* arena)
0584 : MapFieldBase(vtable, arena), map_(arena) {}
0585
0586 protected:
0587 ~TypeDefinedMapFieldBase() { map_.~Map(); }
0588
0589
0590
0591
0592
0593 public:
0594 const Map<Key, T>& GetMap() const {
0595 SyncMapWithRepeatedField();
0596 return map_;
0597 }
0598
0599 Map<Key, T>* MutableMap() {
0600 SyncMapWithRepeatedField();
0601 SetMapDirty();
0602 return &map_;
0603 }
0604
0605 static void ClearMapNoSyncImpl(MapFieldBase& map) {
0606 static_cast<TypeDefinedMapFieldBase&>(map).map_.clear();
0607 }
0608
0609 void InternalSwap(TypeDefinedMapFieldBase* other);
0610
0611 protected:
0612 friend struct MapFieldTestPeer;
0613
0614 using Iter = typename Map<Key, T>::const_iterator;
0615
0616 static bool DeleteMapValueImpl(MapFieldBase& map, const MapKey& map_key);
0617 static bool LookupMapValueImpl(const MapFieldBase& self,
0618 const MapKey& map_key, MapValueConstRef* val);
0619 static void SetMapIteratorValueImpl(MapIterator* map_iter);
0620 static bool InsertOrLookupMapValueNoSyncImpl(MapFieldBase& map,
0621 const MapKey& map_key,
0622 MapValueRef* val);
0623
0624 static void MergeFromImpl(MapFieldBase& base, const MapFieldBase& other);
0625 static void SwapImpl(MapFieldBase& lhs, MapFieldBase& rhs);
0626 static void UnsafeShallowSwapImpl(MapFieldBase& lhs, MapFieldBase& rhs);
0627
0628 static size_t SpaceUsedExcludingSelfNoLockImpl(const MapFieldBase& map);
0629
0630
0631
0632 union {
0633 Map<Key, T> map_;
0634 };
0635 };
0636
0637
0638
0639
0640 template <typename Derived, typename Key, typename T,
0641 WireFormatLite::FieldType kKeyFieldType_,
0642 WireFormatLite::FieldType kValueFieldType_>
0643 class MapField final : public TypeDefinedMapFieldBase<Key, T> {
0644
0645
0646 typedef MapTypeHandler<kKeyFieldType_, Key> KeyTypeHandler;
0647 typedef MapTypeHandler<kValueFieldType_, T> ValueTypeHandler;
0648
0649
0650 typedef Derived EntryType;
0651
0652 public:
0653 typedef Map<Key, T> MapType;
0654 static constexpr WireFormatLite::FieldType kKeyFieldType = kKeyFieldType_;
0655 static constexpr WireFormatLite::FieldType kValueFieldType = kValueFieldType_;
0656
0657 constexpr MapField() : MapField::TypeDefinedMapFieldBase(&kVTable) {}
0658 MapField(const MapField&) = delete;
0659 MapField& operator=(const MapField&) = delete;
0660 ~MapField() = default;
0661
0662 explicit MapField(Arena* arena)
0663 : TypeDefinedMapFieldBase<Key, T>(&kVTable, arena) {}
0664 MapField(ArenaInitialized, Arena* arena) : MapField(arena) {}
0665 MapField(InternalVisibility, Arena* arena) : MapField(arena) {}
0666 MapField(InternalVisibility, Arena* arena, const MapField& from)
0667 : MapField(arena) {
0668 this->MergeFromImpl(*this, from);
0669 }
0670
0671
0672
0673 EntryType* NewEntry() const {
0674 return Arena::Create<EntryType>(this->arena());
0675 }
0676
0677 private:
0678 typedef void InternalArenaConstructable_;
0679 typedef void DestructorSkippable_;
0680
0681 static const Message* GetPrototypeImpl(const MapFieldBase& map);
0682
0683 static const MapFieldBase::VTable kVTable;
0684
0685 friend class google::protobuf::Arena;
0686 friend class MapFieldBase;
0687 friend class MapFieldStateTest;
0688 };
0689
0690 template <typename Derived, typename Key, typename T,
0691 WireFormatLite::FieldType kKeyFieldType_,
0692 WireFormatLite::FieldType kValueFieldType_>
0693 PROTOBUF_CONSTINIT const MapFieldBase::VTable
0694 MapField<Derived, Key, T, kKeyFieldType_, kValueFieldType_>::kVTable =
0695 MapField::template MakeVTable<MapField>();
0696
0697 template <typename Key, typename T>
0698 bool AllAreInitialized(const TypeDefinedMapFieldBase<Key, T>& field) {
0699 for (const auto& p : field.GetMap()) {
0700 if (!p.second.IsInitialized()) return false;
0701 }
0702 return true;
0703 }
0704
0705 template <typename T, typename Key, typename Value,
0706 WireFormatLite::FieldType kKeyFieldType,
0707 WireFormatLite::FieldType kValueFieldType>
0708 struct MapEntryToMapField<
0709 MapEntry<T, Key, Value, kKeyFieldType, kValueFieldType>> {
0710 typedef MapField<T, Key, Value, kKeyFieldType, kValueFieldType> MapFieldType;
0711 };
0712
0713 class PROTOBUF_EXPORT DynamicMapField final
0714 : public TypeDefinedMapFieldBase<MapKey, MapValueRef> {
0715 public:
0716 explicit DynamicMapField(const Message* default_entry);
0717 DynamicMapField(const Message* default_entry, Arena* arena);
0718 DynamicMapField(const DynamicMapField&) = delete;
0719 DynamicMapField& operator=(const DynamicMapField&) = delete;
0720 ~DynamicMapField();
0721
0722 private:
0723 friend class MapFieldBase;
0724
0725 const Message* default_entry_;
0726
0727 static const VTable kVTable;
0728
0729 void AllocateMapValue(MapValueRef* map_val);
0730
0731 static void MergeFromImpl(MapFieldBase& base, const MapFieldBase& other);
0732 static bool InsertOrLookupMapValueNoSyncImpl(MapFieldBase& base,
0733 const MapKey& map_key,
0734 MapValueRef* val);
0735 static void ClearMapNoSyncImpl(MapFieldBase& base);
0736
0737 static void UnsafeShallowSwapImpl(MapFieldBase& lhs, MapFieldBase& rhs) {
0738 static_cast<DynamicMapField&>(lhs).Swap(
0739 static_cast<DynamicMapField*>(&rhs));
0740 }
0741
0742 static size_t SpaceUsedExcludingSelfNoLockImpl(const MapFieldBase& map);
0743
0744 static const Message* GetPrototypeImpl(const MapFieldBase& map);
0745 };
0746
0747 }
0748
0749
0750
0751 class PROTOBUF_EXPORT MapValueConstRef {
0752 public:
0753 MapValueConstRef() : data_(nullptr), type_() {}
0754
0755 int64_t GetInt64Value() const {
0756 TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
0757 "MapValueConstRef::GetInt64Value");
0758 return *reinterpret_cast<int64_t*>(data_);
0759 }
0760 uint64_t GetUInt64Value() const {
0761 TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
0762 "MapValueConstRef::GetUInt64Value");
0763 return *reinterpret_cast<uint64_t*>(data_);
0764 }
0765 int32_t GetInt32Value() const {
0766 TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
0767 "MapValueConstRef::GetInt32Value");
0768 return *reinterpret_cast<int32_t*>(data_);
0769 }
0770 uint32_t GetUInt32Value() const {
0771 TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
0772 "MapValueConstRef::GetUInt32Value");
0773 return *reinterpret_cast<uint32_t*>(data_);
0774 }
0775 bool GetBoolValue() const {
0776 TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueConstRef::GetBoolValue");
0777 return *reinterpret_cast<bool*>(data_);
0778 }
0779 int GetEnumValue() const {
0780 TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueConstRef::GetEnumValue");
0781 return *reinterpret_cast<int*>(data_);
0782 }
0783 const std::string& GetStringValue() const {
0784 TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
0785 "MapValueConstRef::GetStringValue");
0786 return *reinterpret_cast<std::string*>(data_);
0787 }
0788 float GetFloatValue() const {
0789 TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
0790 "MapValueConstRef::GetFloatValue");
0791 return *reinterpret_cast<float*>(data_);
0792 }
0793 double GetDoubleValue() const {
0794 TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
0795 "MapValueConstRef::GetDoubleValue");
0796 return *reinterpret_cast<double*>(data_);
0797 }
0798
0799 const Message& GetMessageValue() const {
0800 TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
0801 "MapValueConstRef::GetMessageValue");
0802 return *reinterpret_cast<Message*>(data_);
0803 }
0804
0805 FieldDescriptor::CppType type() const {
0806 if (type_ == FieldDescriptor::CppType() || data_ == nullptr) {
0807 ABSL_LOG(FATAL)
0808 << "Protocol Buffer map usage error:\n"
0809 << "MapValueConstRef::type MapValueConstRef is not initialized.";
0810 }
0811 return type_;
0812 }
0813
0814 protected:
0815
0816
0817 void* data_;
0818
0819
0820 FieldDescriptor::CppType type_;
0821
0822 private:
0823 template <typename Derived, typename K, typename V,
0824 internal::WireFormatLite::FieldType key_wire_type,
0825 internal::WireFormatLite::FieldType value_wire_type>
0826 friend class internal::MapField;
0827 template <typename K, typename V>
0828 friend class internal::TypeDefinedMapFieldBase;
0829 friend class google::protobuf::MapIterator;
0830 friend class Reflection;
0831 friend class internal::DynamicMapField;
0832 friend class internal::MapFieldBase;
0833
0834 void SetValueOrCopy(const void* val) { SetValue(val); }
0835 void SetValueOrCopy(const MapValueConstRef* val) { CopyFrom(*val); }
0836
0837 void SetType(FieldDescriptor::CppType type) { type_ = type; }
0838 void SetValue(const void* val) { data_ = const_cast<void*>(val); }
0839 void CopyFrom(const MapValueConstRef& other) {
0840 type_ = other.type_;
0841 data_ = other.data_;
0842 }
0843 };
0844
0845
0846
0847 class PROTOBUF_EXPORT MapValueRef final : public MapValueConstRef {
0848 public:
0849 MapValueRef() = default;
0850
0851 void SetInt64Value(int64_t value) {
0852 TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::SetInt64Value");
0853 *reinterpret_cast<int64_t*>(data_) = value;
0854 }
0855 void SetUInt64Value(uint64_t value) {
0856 TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::SetUInt64Value");
0857 *reinterpret_cast<uint64_t*>(data_) = value;
0858 }
0859 void SetInt32Value(int32_t value) {
0860 TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::SetInt32Value");
0861 *reinterpret_cast<int32_t*>(data_) = value;
0862 }
0863 void SetUInt32Value(uint32_t value) {
0864 TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::SetUInt32Value");
0865 *reinterpret_cast<uint32_t*>(data_) = value;
0866 }
0867 void SetBoolValue(bool value) {
0868 TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::SetBoolValue");
0869 *reinterpret_cast<bool*>(data_) = value;
0870 }
0871
0872 void SetEnumValue(int value) {
0873 TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueRef::SetEnumValue");
0874 *reinterpret_cast<int*>(data_) = value;
0875 }
0876 void SetStringValue(const std::string& value) {
0877 TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapValueRef::SetStringValue");
0878 *reinterpret_cast<std::string*>(data_) = value;
0879 }
0880 void SetFloatValue(float value) {
0881 TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, "MapValueRef::SetFloatValue");
0882 *reinterpret_cast<float*>(data_) = value;
0883 }
0884 void SetDoubleValue(double value) {
0885 TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, "MapValueRef::SetDoubleValue");
0886 *reinterpret_cast<double*>(data_) = value;
0887 }
0888
0889 Message* MutableMessageValue() {
0890 TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
0891 "MapValueRef::MutableMessageValue");
0892 return reinterpret_cast<Message*>(data_);
0893 }
0894
0895 private:
0896 friend class internal::DynamicMapField;
0897
0898
0899 void DeleteData() {
0900 switch (type_) {
0901 #define HANDLE_TYPE(CPPTYPE, TYPE) \
0902 case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
0903 delete reinterpret_cast<TYPE*>(data_); \
0904 break; \
0905 }
0906 HANDLE_TYPE(INT32, int32_t);
0907 HANDLE_TYPE(INT64, int64_t);
0908 HANDLE_TYPE(UINT32, uint32_t);
0909 HANDLE_TYPE(UINT64, uint64_t);
0910 HANDLE_TYPE(DOUBLE, double);
0911 HANDLE_TYPE(FLOAT, float);
0912 HANDLE_TYPE(BOOL, bool);
0913 HANDLE_TYPE(STRING, std::string);
0914 HANDLE_TYPE(ENUM, int32_t);
0915 HANDLE_TYPE(MESSAGE, Message);
0916 #undef HANDLE_TYPE
0917 }
0918 }
0919 };
0920
0921 #undef TYPE_CHECK
0922
0923 class PROTOBUF_EXPORT MapIterator {
0924 public:
0925 MapIterator(Message* message, const FieldDescriptor* field) {
0926 const Reflection* reflection = message->GetReflection();
0927 map_ = reflection->MutableMapData(message, field);
0928 key_.SetType(field->message_type()->map_key()->cpp_type());
0929 value_.SetType(field->message_type()->map_value()->cpp_type());
0930 }
0931 MapIterator(const MapIterator& other) { *this = other; }
0932 MapIterator& operator=(const MapIterator& other) {
0933 map_ = other.map_;
0934 map_->CopyIterator(this, other);
0935 return *this;
0936 }
0937 friend bool operator==(const MapIterator& a, const MapIterator& b) {
0938 return a.map_->EqualIterator(a, b);
0939 }
0940 friend bool operator!=(const MapIterator& a, const MapIterator& b) {
0941 return !a.map_->EqualIterator(a, b);
0942 }
0943 MapIterator& operator++() {
0944 map_->IncreaseIterator(this);
0945 return *this;
0946 }
0947 MapIterator operator++(int) {
0948
0949
0950
0951 map_->IncreaseIterator(this);
0952 return *this;
0953 }
0954 const MapKey& GetKey() { return key_; }
0955 const MapValueRef& GetValueRef() { return value_; }
0956 MapValueRef* MutableValueRef() {
0957 map_->SetMapDirty();
0958 return &value_;
0959 }
0960
0961 private:
0962 template <typename Key, typename T>
0963 friend class internal::TypeDefinedMapFieldBase;
0964 friend class internal::DynamicMapField;
0965 template <typename Derived, typename Key, typename T,
0966 internal::WireFormatLite::FieldType kKeyFieldType,
0967 internal::WireFormatLite::FieldType kValueFieldType>
0968 friend class internal::MapField;
0969 friend class internal::MapFieldBase;
0970 template <typename MessageT>
0971 friend struct internal::MapDynamicFieldInfo;
0972
0973 MapIterator(internal::MapFieldBase* map, const Descriptor* descriptor) {
0974 map_ = map;
0975 key_.SetType(descriptor->map_key()->cpp_type());
0976 value_.SetType(descriptor->map_value()->cpp_type());
0977 }
0978
0979 internal::UntypedMapIterator iter_;
0980
0981
0982 internal::MapFieldBase* map_;
0983 MapKey key_;
0984 MapValueRef value_;
0985 };
0986
0987 namespace internal {
0988 template <>
0989 struct is_internal_map_value_type<class MapValueConstRef> : std::true_type {};
0990 template <>
0991 struct is_internal_map_value_type<class MapValueRef> : std::true_type {};
0992 }
0993
0994 }
0995 }
0996
0997 #ifdef _MSC_VER
0998 #pragma warning(pop)
0999 #endif
1000
1001 #include "google/protobuf/port_undef.inc"
1002
1003 #endif