Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-19 09:23:42

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
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 // Must be included last.
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 // Microsoft compiler complains about non-virtual destructor,
0056 // even when the destructor is private.
0057 #ifdef _MSC_VER
0058 #pragma warning(push)
0059 #pragma warning(disable : 4265)
0060 #endif  // _MSC_VER
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 // MapKey is an union type for representing any possible map key. For strings,
0073 // map key does not own the underlying data. It is up to the caller to ensure
0074 // any supplied strings outlive any instance of this class.
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       // We could define a total order that handles this case, but
0143       // there currently no need.  So, for now, fail.
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       // To be consistent with operator<, we don't allow this either.
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   // type_ is 0 or a valid FieldDescriptor::CppType.
0268   // Use "CppType()" to indicate zero.
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 }  // namespace internal
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 // Return the prototype message for a Map entry.
0290 // REQUIRES: `default_entry` is a map entry message.
0291 // REQUIRES: mapped_type is of type message.
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 // This class provides access to map field using reflection, which is the same
0298 // as those provided for RepeatedPtrField<Message>. It is used for internal
0299 // reflection implementation only. Users should never use this directly.
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   // "protected" stops users from deleting a `MapFieldBase *`
0311   ~MapFieldBase();
0312 
0313  public:
0314   // Returns reference to internal repeated field. Data written using
0315   // Map's api prior to calling this function is guarantted to be
0316   // included in repeated field.
0317   const RepeatedPtrFieldBase& GetRepeatedField() const;
0318 
0319   // Like above. Returns mutable pointer to the internal repeated field.
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   // Returns whether changes to the map are reflected in the repeated field.
0334   bool IsRepeatedFieldValid() const;
0335   // Insures operations after won't get executed before calling this.
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   // Sync Map with repeated field and returns the size of map.
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   // Returns the number of bytes used by the repeated field, excluding
0356   // sizeof(*this)
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   // Synchronizes the content in Map to RepeatedPtrField if there is any change
0374   // to Map after last synchronization.
0375   const RepeatedPtrFieldBase& SyncRepeatedFieldWithMap(bool for_mutation) const;
0376   void SyncRepeatedFieldWithMapNoLock();
0377 
0378   // Synchronizes the content in RepeatedPtrField to Map if there is any change
0379   // to RepeatedPtrField after last synchronization.
0380   void SyncMapWithRepeatedField() const;
0381   void SyncMapWithRepeatedFieldNoLock();
0382 
0383   static void SwapPayload(MapFieldBase& lhs, MapFieldBase& rhs);
0384 
0385   // Tells MapFieldBase that there is new change to Map.
0386   void SetMapDirty() {
0387     MutableAccess();
0388     // These are called by (non-const) mutator functions. So by our API it's the
0389     // callers responsibility to have these calls properly ordered.
0390     if (auto* p = maybe_payload()) {
0391       // If we don't have a payload, it is already assumed `STATE_MODIFIED_MAP`.
0392       p->state.store(STATE_MODIFIED_MAP, std::memory_order_relaxed);
0393     }
0394   }
0395 
0396   // Tells MapFieldBase that there is new change to RepeatedPtrField.
0397   void SetRepeatedDirty();
0398 
0399   // Provides derived class the access to repeated field.
0400   void* MutableRepeatedPtrField() const;
0401 
0402   bool InsertOrLookupMapValueNoSync(const MapKey& map_key, MapValueRef* val);
0403 
0404   // Support thread sanitizer (tsan) by making const / mutable races
0405   // more apparent.  If one thread calls MutableAccess() while another
0406   // thread calls either ConstAccess() or MutableAccess(), on the same
0407   // MapFieldBase-derived object, and there is no synchronization going
0408   // on between them, tsan will alert.
0409 #if defined(ABSL_HAVE_THREAD_SANITIZER)
0410   // Using prototype_as_void_ as an arbitrary member that we can read/write.
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,       // map has newly added data that has not been
0426                                   // synchronized to repeated field
0427     STATE_MODIFIED_REPEATED = 1,  // repeated field has newly added data that
0428                                   // has not been synchronized to map
0429     CLEAN = 2,                    // data in map and repeated field are same
0430   };
0431 
0432   struct ReflectionPayload {
0433     explicit ReflectionPayload(Arena* arena) : repeated_field(arena) {}
0434     RepeatedPtrField<Message> repeated_field;
0435 
0436     absl::Mutex mutex;  // The thread to synchronize map and repeated
0437                         // field needs to get lock first;
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   // Returns the reflection payload. Returns null if it does not exist yet.
0448   ReflectionPayload* maybe_payload() const {
0449     auto p = payload_.load(std::memory_order_acquire);
0450     return IsPayload(p) ? ToPayload(p) : nullptr;
0451   }
0452   // Returns the reflection payload, and constructs one if does not exist yet.
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                         // The default
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   // Virtual helper methods for MapIterator. MapIterator doesn't have the
0489   // type helper for key and value. Call these help methods to deal with
0490   // different types. Real helper methods are implemented in
0491   // TypeDefinedMapFieldBase.
0492   template <bool>
0493   friend class google::protobuf::MapIteratorBase;
0494   friend class google::protobuf::MapIterator;
0495 
0496   // Copy the map<...>::iterator from other_iterator to
0497   // this_iterator.
0498   template <bool kIsMutable>
0499   void CopyIterator(MapIteratorBase<kIsMutable>* this_iter,
0500                     const MapIteratorBase<kIsMutable>& that_iter) const;
0501 
0502   // IncreaseIterator() is called by operator++() of MapIterator only.
0503   // It implements the ++ operator of MapIterator.
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 // This class provides common Map Reflection implementations for generated
0529 // message and dynamic message.
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     // This invariant is required by `GetMapRaw` to easily access the map
0536     // member without paying for dynamic dispatch.
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   // This overload is called from codegen, so we use templates for speed.
0566   // If there is no codegen (eg optimize_for=CODE_SIZE), then only the
0567   // reflection based one above will be used.
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   // map_ is inside an anonymous union so we can explicitly control its
0584   // destruction
0585   union {
0586     Map<Key, T> map_;
0587   };
0588 };
0589 
0590 // This class provides access to map field using generated api. It is used for
0591 // internal generated message implementation only. Users should never use this
0592 // directly.
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   // Provide utilities to parse/serialize key/value.  Provide utilities to
0598   // manipulate internal stored type.
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;  // For testing, it needs raw access to impl_
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 }  // namespace internal
0643 
0644 // MapValueConstRef points to a map value. Users can NOT modify
0645 // the map value.
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   // data_ point to a map value. MapValueConstRef does not
0711   // own this value.
0712   void* data_;
0713   // type_ is 0 or a valid FieldDescriptor::CppType.
0714   // Use "CppType()" to indicate zero.
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 // MapValueRef points to a map value. Users are able to modify
0741 // the map value.
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   // TODO - Checks that enum is member.
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   // Point to a MapField to call helper methods implemented in MapField.
0834   // MapIterator does not own this object.
0835   MapFieldBase* map_;
0836   MapKey key_;
0837   ValueRef value_;
0838 };
0839 
0840 extern template class MapIteratorBase</*kIsMutable=*/false>;
0841 extern template class MapIteratorBase</*kIsMutable=*/true>;
0842 
0843 class PROTOBUF_EXPORT ConstMapIterator final
0844     : public MapIteratorBase</*kIsMutable=*/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</*kIsMutable=*/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 }  // namespace internal
0886 
0887 }  // namespace protobuf
0888 }  // namespace google
0889 
0890 #ifdef _MSC_VER
0891 #pragma warning(pop)  // restore warning C4265
0892 #endif                // _MSC_VER
0893 
0894 #include "google/protobuf/port_undef.inc"
0895 
0896 #endif  // GOOGLE_PROTOBUF_MAP_FIELD_H__