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