• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 #ifndef GOOGLE_PROTOBUF_MAP_FIELD_H__
32 #define GOOGLE_PROTOBUF_MAP_FIELD_H__
33 
34 #include <atomic>
35 #include <functional>
36 
37 #include <google/protobuf/arena.h>
38 #include <google/protobuf/descriptor.h>
39 #include <google/protobuf/generated_message_reflection.h>
40 #include <google/protobuf/generated_message_util.h>
41 #include <google/protobuf/map_entry.h>
42 #include <google/protobuf/map_field_lite.h>
43 #include <google/protobuf/map_type_handler.h>
44 #include <google/protobuf/message.h>
45 #include <google/protobuf/stubs/mutex.h>
46 #include <google/protobuf/port.h>
47 #include <google/protobuf/repeated_field.h>
48 #include <google/protobuf/unknown_field_set.h>
49 
50 
51 #include <google/protobuf/port_def.inc>
52 
53 #ifdef SWIG
54 #error "You cannot SWIG proto headers"
55 #endif
56 
57 namespace google {
58 namespace protobuf {
59 class DynamicMessage;
60 class MapIterator;
61 
62 #define TYPE_CHECK(EXPECTEDTYPE, METHOD)                                   \
63   if (type() != EXPECTEDTYPE) {                                            \
64     GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n"                     \
65                << METHOD << " type does not match\n"                       \
66                << "  Expected : "                                          \
67                << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n"       \
68                << "  Actual   : " << FieldDescriptor::CppTypeName(type()); \
69   }
70 
71 // MapKey is an union type for representing any possible
72 // map key.
73 class PROTOBUF_EXPORT MapKey {
74  public:
MapKey()75   MapKey() : type_(0) {}
MapKey(const MapKey & other)76   MapKey(const MapKey& other) : type_(0) { CopyFrom(other); }
77 
78   MapKey& operator=(const MapKey& other) {
79     CopyFrom(other);
80     return *this;
81   }
82 
~MapKey()83   ~MapKey() {
84     if (type_ == FieldDescriptor::CPPTYPE_STRING) {
85       val_.string_value_.Destruct();
86     }
87   }
88 
type()89   FieldDescriptor::CppType type() const {
90     if (type_ == 0) {
91       GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n"
92                  << "MapKey::type MapKey is not initialized. "
93                  << "Call set methods to initialize MapKey.";
94     }
95     return (FieldDescriptor::CppType)type_;
96   }
97 
SetInt64Value(int64 value)98   void SetInt64Value(int64 value) {
99     SetType(FieldDescriptor::CPPTYPE_INT64);
100     val_.int64_value_ = value;
101   }
SetUInt64Value(uint64 value)102   void SetUInt64Value(uint64 value) {
103     SetType(FieldDescriptor::CPPTYPE_UINT64);
104     val_.uint64_value_ = value;
105   }
SetInt32Value(int32 value)106   void SetInt32Value(int32 value) {
107     SetType(FieldDescriptor::CPPTYPE_INT32);
108     val_.int32_value_ = value;
109   }
SetUInt32Value(uint32 value)110   void SetUInt32Value(uint32 value) {
111     SetType(FieldDescriptor::CPPTYPE_UINT32);
112     val_.uint32_value_ = value;
113   }
SetBoolValue(bool value)114   void SetBoolValue(bool value) {
115     SetType(FieldDescriptor::CPPTYPE_BOOL);
116     val_.bool_value_ = value;
117   }
SetStringValue(std::string val)118   void SetStringValue(std::string val) {
119     SetType(FieldDescriptor::CPPTYPE_STRING);
120     *val_.string_value_.get_mutable() = std::move(val);
121   }
122 
GetInt64Value()123   int64 GetInt64Value() const {
124     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapKey::GetInt64Value");
125     return val_.int64_value_;
126   }
GetUInt64Value()127   uint64 GetUInt64Value() const {
128     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapKey::GetUInt64Value");
129     return val_.uint64_value_;
130   }
GetInt32Value()131   int32 GetInt32Value() const {
132     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapKey::GetInt32Value");
133     return val_.int32_value_;
134   }
GetUInt32Value()135   uint32 GetUInt32Value() const {
136     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapKey::GetUInt32Value");
137     return val_.uint32_value_;
138   }
GetBoolValue()139   bool GetBoolValue() const {
140     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapKey::GetBoolValue");
141     return val_.bool_value_;
142   }
GetStringValue()143   const std::string& GetStringValue() const {
144     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapKey::GetStringValue");
145     return val_.string_value_.get();
146   }
147 
148   bool operator<(const MapKey& other) const {
149     if (type_ != other.type_) {
150       // We could define a total order that handles this case, but
151       // there currently no need.  So, for now, fail.
152       GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
153     }
154     switch (type()) {
155       case FieldDescriptor::CPPTYPE_DOUBLE:
156       case FieldDescriptor::CPPTYPE_FLOAT:
157       case FieldDescriptor::CPPTYPE_ENUM:
158       case FieldDescriptor::CPPTYPE_MESSAGE:
159         GOOGLE_LOG(FATAL) << "Unsupported";
160         return false;
161       case FieldDescriptor::CPPTYPE_STRING:
162         return val_.string_value_.get() < other.val_.string_value_.get();
163       case FieldDescriptor::CPPTYPE_INT64:
164         return val_.int64_value_ < other.val_.int64_value_;
165       case FieldDescriptor::CPPTYPE_INT32:
166         return val_.int32_value_ < other.val_.int32_value_;
167       case FieldDescriptor::CPPTYPE_UINT64:
168         return val_.uint64_value_ < other.val_.uint64_value_;
169       case FieldDescriptor::CPPTYPE_UINT32:
170         return val_.uint32_value_ < other.val_.uint32_value_;
171       case FieldDescriptor::CPPTYPE_BOOL:
172         return val_.bool_value_ < other.val_.bool_value_;
173     }
174     return false;
175   }
176 
177   bool operator==(const MapKey& other) const {
178     if (type_ != other.type_) {
179       // To be consistent with operator<, we don't allow this either.
180       GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
181     }
182     switch (type()) {
183       case FieldDescriptor::CPPTYPE_DOUBLE:
184       case FieldDescriptor::CPPTYPE_FLOAT:
185       case FieldDescriptor::CPPTYPE_ENUM:
186       case FieldDescriptor::CPPTYPE_MESSAGE:
187         GOOGLE_LOG(FATAL) << "Unsupported";
188         break;
189       case FieldDescriptor::CPPTYPE_STRING:
190         return val_.string_value_.get() == other.val_.string_value_.get();
191       case FieldDescriptor::CPPTYPE_INT64:
192         return val_.int64_value_ == other.val_.int64_value_;
193       case FieldDescriptor::CPPTYPE_INT32:
194         return val_.int32_value_ == other.val_.int32_value_;
195       case FieldDescriptor::CPPTYPE_UINT64:
196         return val_.uint64_value_ == other.val_.uint64_value_;
197       case FieldDescriptor::CPPTYPE_UINT32:
198         return val_.uint32_value_ == other.val_.uint32_value_;
199       case FieldDescriptor::CPPTYPE_BOOL:
200         return val_.bool_value_ == other.val_.bool_value_;
201     }
202     GOOGLE_LOG(FATAL) << "Can't get here.";
203     return false;
204   }
205 
CopyFrom(const MapKey & other)206   void CopyFrom(const MapKey& other) {
207     SetType(other.type());
208     switch (type_) {
209       case FieldDescriptor::CPPTYPE_DOUBLE:
210       case FieldDescriptor::CPPTYPE_FLOAT:
211       case FieldDescriptor::CPPTYPE_ENUM:
212       case FieldDescriptor::CPPTYPE_MESSAGE:
213         GOOGLE_LOG(FATAL) << "Unsupported";
214         break;
215       case FieldDescriptor::CPPTYPE_STRING:
216         *val_.string_value_.get_mutable() = other.val_.string_value_.get();
217         break;
218       case FieldDescriptor::CPPTYPE_INT64:
219         val_.int64_value_ = other.val_.int64_value_;
220         break;
221       case FieldDescriptor::CPPTYPE_INT32:
222         val_.int32_value_ = other.val_.int32_value_;
223         break;
224       case FieldDescriptor::CPPTYPE_UINT64:
225         val_.uint64_value_ = other.val_.uint64_value_;
226         break;
227       case FieldDescriptor::CPPTYPE_UINT32:
228         val_.uint32_value_ = other.val_.uint32_value_;
229         break;
230       case FieldDescriptor::CPPTYPE_BOOL:
231         val_.bool_value_ = other.val_.bool_value_;
232         break;
233     }
234   }
235 
236  private:
237   template <typename K, typename V>
238   friend class internal::TypeDefinedMapFieldBase;
239   friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
240   friend class internal::DynamicMapField;
241 
242   union KeyValue {
KeyValue()243     KeyValue() {}
244     internal::ExplicitlyConstructed<std::string> string_value_;
245     int64 int64_value_;
246     int32 int32_value_;
247     uint64 uint64_value_;
248     uint32 uint32_value_;
249     bool bool_value_;
250   } val_;
251 
SetType(FieldDescriptor::CppType type)252   void SetType(FieldDescriptor::CppType type) {
253     if (type_ == type) return;
254     if (type_ == FieldDescriptor::CPPTYPE_STRING) {
255       val_.string_value_.Destruct();
256     }
257     type_ = type;
258     if (type_ == FieldDescriptor::CPPTYPE_STRING) {
259       val_.string_value_.DefaultConstruct();
260     }
261   }
262 
263   // type_ is 0 or a valid FieldDescriptor::CppType.
264   int type_;
265 };
266 
267 }  // namespace protobuf
268 }  // namespace google
269 namespace std {
270 template <>
271 struct hash<::PROTOBUF_NAMESPACE_ID::MapKey> {
272   size_t operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key) const {
273     switch (map_key.type()) {
274       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_DOUBLE:
275       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_FLOAT:
276       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_ENUM:
277       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_MESSAGE:
278         GOOGLE_LOG(FATAL) << "Unsupported";
279         break;
280       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_STRING:
281         return hash<std::string>()(map_key.GetStringValue());
282       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT64: {
283         auto value = map_key.GetInt64Value();
284         return hash<decltype(value)>()(value);
285       }
286       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT32: {
287         auto value = map_key.GetInt32Value();
288         return hash<decltype(value)>()(map_key.GetInt32Value());
289       }
290       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT64: {
291         auto value = map_key.GetUInt64Value();
292         return hash<decltype(value)>()(map_key.GetUInt64Value());
293       }
294       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT32: {
295         auto value = map_key.GetUInt32Value();
296         return hash<decltype(value)>()(map_key.GetUInt32Value());
297       }
298       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_BOOL: {
299         return hash<bool>()(map_key.GetBoolValue());
300       }
301     }
302     GOOGLE_LOG(FATAL) << "Can't get here.";
303     return 0;
304   }
305   bool operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key1,
306                   const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key2) const {
307     return map_key1 < map_key2;
308   }
309 };
310 }  // namespace std
311 
312 namespace google {
313 namespace protobuf {
314 namespace internal {
315 
316 class ContendedMapCleanTest;
317 class GeneratedMessageReflection;
318 class MapFieldAccessor;
319 
320 // This class provides access to map field using reflection, which is the same
321 // as those provided for RepeatedPtrField<Message>. It is used for internal
322 // reflection implementation only. Users should never use this directly.
323 class PROTOBUF_EXPORT MapFieldBase {
324  public:
325   MapFieldBase()
326       : arena_(NULL), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {}
327 
328   // This constructor is for constant initialized global instances.
329   // It uses a linker initialized mutex, so it is not compatible with regular
330   // runtime instances.
331   // Except in MSVC, where we can't have a constinit mutex.
332   explicit PROTOBUF_MAYBE_CONSTEXPR MapFieldBase(ConstantInitialized)
333       : arena_(nullptr),
334         repeated_field_(nullptr),
335         mutex_(GOOGLE_PROTOBUF_LINKER_INITIALIZED),
336         state_(STATE_MODIFIED_MAP) {}
337   explicit MapFieldBase(Arena* arena)
338       : arena_(arena), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {
339     // Mutex's destructor needs to be called explicitly to release resources
340     // acquired in its constructor.
341     if (arena) {
342       arena->OwnDestructor(&mutex_);
343     }
344   }
345   virtual ~MapFieldBase();
346 
347   // Returns reference to internal repeated field. Data written using
348   // Map's api prior to calling this function is guarantted to be
349   // included in repeated field.
350   const RepeatedPtrFieldBase& GetRepeatedField() const;
351 
352   // Like above. Returns mutable pointer to the internal repeated field.
353   RepeatedPtrFieldBase* MutableRepeatedField();
354 
355   // Pure virtual map APIs for Map Reflection.
356   virtual bool ContainsMapKey(const MapKey& map_key) const = 0;
357   virtual bool InsertOrLookupMapValue(const MapKey& map_key,
358                                       MapValueRef* val) = 0;
359   virtual bool LookupMapValue(const MapKey& map_key,
360                               MapValueConstRef* val) const = 0;
361   bool LookupMapValue(const MapKey&, MapValueRef*) const = delete;
362 
363   // Returns whether changes to the map are reflected in the repeated field.
364   bool IsRepeatedFieldValid() const;
365   // Insures operations after won't get executed before calling this.
366   bool IsMapValid() const;
367   virtual bool DeleteMapValue(const MapKey& map_key) = 0;
368   virtual bool EqualIterator(const MapIterator& a,
369                              const MapIterator& b) const = 0;
370   virtual void MapBegin(MapIterator* map_iter) const = 0;
371   virtual void MapEnd(MapIterator* map_iter) const = 0;
372   virtual void MergeFrom(const MapFieldBase& other) = 0;
373   virtual void Swap(MapFieldBase* other) = 0;
374   // Sync Map with repeated field and returns the size of map.
375   virtual int size() const = 0;
376   virtual void Clear() = 0;
377 
378   // Returns the number of bytes used by the repeated field, excluding
379   // sizeof(*this)
380   size_t SpaceUsedExcludingSelfLong() const;
381 
382   int SpaceUsedExcludingSelf() const {
383     return internal::ToIntSize(SpaceUsedExcludingSelfLong());
384   }
385 
386  protected:
387   // Gets the size of space used by map field.
388   virtual size_t SpaceUsedExcludingSelfNoLock() const;
389 
390   // Synchronizes the content in Map to RepeatedPtrField if there is any change
391   // to Map after last synchronization.
392   void SyncRepeatedFieldWithMap() const;
393   virtual void SyncRepeatedFieldWithMapNoLock() const;
394 
395   // Synchronizes the content in RepeatedPtrField to Map if there is any change
396   // to RepeatedPtrField after last synchronization.
397   void SyncMapWithRepeatedField() const;
398   virtual void SyncMapWithRepeatedFieldNoLock() const {}
399 
400   // Tells MapFieldBase that there is new change to Map.
401   void SetMapDirty();
402 
403   // Tells MapFieldBase that there is new change to RepeatedPtrField.
404   void SetRepeatedDirty();
405 
406   // Provides derived class the access to repeated field.
407   void* MutableRepeatedPtrField() const;
408 
409   // Support thread sanitizer (tsan) by making const / mutable races
410   // more apparent.  If one thread calls MutableAccess() while another
411   // thread calls either ConstAccess() or MutableAccess(), on the same
412   // MapFieldBase-derived object, and there is no synchronization going
413   // on between them, tsan will alert.
414 #if defined(__SANITIZE_THREAD__) || defined(THREAD_SANITIZER)
415   void ConstAccess() const { GOOGLE_CHECK_EQ(seq1_, seq2_); }
416   void MutableAccess() {
417     if (seq1_ & 1) {
418       seq2_ = ++seq1_;
419     } else {
420       seq1_ = ++seq2_;
421     }
422   }
423   unsigned int seq1_ = 0, seq2_ = 0;
424 #else
425   void ConstAccess() const {}
426   void MutableAccess() {}
427 #endif
428   enum State {
429     STATE_MODIFIED_MAP = 0,       // map has newly added data that has not been
430                                   // synchronized to repeated field
431     STATE_MODIFIED_REPEATED = 1,  // repeated field has newly added data that
432                                   // has not been synchronized to map
433     CLEAN = 2,                    // data in map and repeated field are same
434   };
435 
436   Arena* arena_;
437   mutable RepeatedPtrField<Message>* repeated_field_;
438 
439   mutable internal::WrappedMutex
440       mutex_;  // The thread to synchronize map and repeated field
441                // needs to get lock first;
442   mutable std::atomic<State> state_;
443 
444  private:
445   friend class ContendedMapCleanTest;
446   friend class GeneratedMessageReflection;
447   friend class MapFieldAccessor;
448   friend class ::PROTOBUF_NAMESPACE_ID::DynamicMessage;
449 
450   // Virtual helper methods for MapIterator. MapIterator doesn't have the
451   // type helper for key and value. Call these help methods to deal with
452   // different types. Real helper methods are implemented in
453   // TypeDefinedMapFieldBase.
454   friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
455   // Allocate map<...>::iterator for MapIterator.
456   virtual void InitializeIterator(MapIterator* map_iter) const = 0;
457 
458   // DeleteIterator() is called by the destructor of MapIterator only.
459   // It deletes map<...>::iterator for MapIterator.
460   virtual void DeleteIterator(MapIterator* map_iter) const = 0;
461 
462   // Copy the map<...>::iterator from other_iterator to
463   // this_iterator.
464   virtual void CopyIterator(MapIterator* this_iterator,
465                             const MapIterator& other_iterator) const = 0;
466 
467   // IncreaseIterator() is called by operator++() of MapIterator only.
468   // It implements the ++ operator of MapIterator.
469   virtual void IncreaseIterator(MapIterator* map_iter) const = 0;
470   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldBase);
471 };
472 
473 // This class provides common Map Reflection implementations for generated
474 // message and dynamic message.
475 template <typename Key, typename T>
476 class TypeDefinedMapFieldBase : public MapFieldBase {
477  public:
478   TypeDefinedMapFieldBase() {}
479 
480   // This constructor is for constant initialized global instances.
481   // It uses a linker initialized mutex, so it is not compatible with regular
482   // runtime instances.
483   explicit constexpr TypeDefinedMapFieldBase(ConstantInitialized tag)
484       : MapFieldBase(tag) {}
485   explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
486   ~TypeDefinedMapFieldBase() override {}
487   void MapBegin(MapIterator* map_iter) const override;
488   void MapEnd(MapIterator* map_iter) const override;
489   bool EqualIterator(const MapIterator& a, const MapIterator& b) const override;
490 
491   virtual const Map<Key, T>& GetMap() const = 0;
492   virtual Map<Key, T>* MutableMap() = 0;
493 
494  protected:
495   typename Map<Key, T>::const_iterator& InternalGetIterator(
496       const MapIterator* map_iter) const;
497 
498  private:
499   void InitializeIterator(MapIterator* map_iter) const override;
500   void DeleteIterator(MapIterator* map_iter) const override;
501   void CopyIterator(MapIterator* this_iteratorm,
502                     const MapIterator& that_iterator) const override;
503   void IncreaseIterator(MapIterator* map_iter) const override;
504 
505   virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0;
506   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeDefinedMapFieldBase);
507 };
508 
509 // This class provides access to map field using generated api. It is used for
510 // internal generated message implementation only. Users should never use this
511 // directly.
512 template <typename Derived, typename Key, typename T,
513           WireFormatLite::FieldType kKeyFieldType,
514           WireFormatLite::FieldType kValueFieldType>
515 class MapField : public TypeDefinedMapFieldBase<Key, T> {
516   // Provide utilities to parse/serialize key/value.  Provide utilities to
517   // manipulate internal stored type.
518   typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
519   typedef MapTypeHandler<kValueFieldType, T> ValueTypeHandler;
520 
521   // Define message type for internal repeated field.
522   typedef Derived EntryType;
523 
524   // Define abbreviation for parent MapFieldLite
525   typedef MapFieldLite<Derived, Key, T, kKeyFieldType, kValueFieldType>
526       MapFieldLiteType;
527 
528   // Enum needs to be handled differently from other types because it has
529   // different exposed type in Map's api and repeated field's api. For
530   // details see the comment in the implementation of
531   // SyncMapWithRepeatedFieldNoLock.
532   static constexpr bool kIsValueEnum = ValueTypeHandler::kIsEnum;
533   typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType;
534 
535  public:
536   typedef typename Derived::SuperType EntryTypeTrait;
537   typedef Map<Key, T> MapType;
538 
539   MapField() {}
540 
541   // This constructor is for constant initialized global instances.
542   // It uses a linker initialized mutex, so it is not compatible with regular
543   // runtime instances.
544   explicit constexpr MapField(ConstantInitialized tag)
545       : TypeDefinedMapFieldBase<Key, T>(tag), impl_() {}
546   explicit MapField(Arena* arena)
547       : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {}
548 
549   // Implement MapFieldBase
550   bool ContainsMapKey(const MapKey& map_key) const override;
551   bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
552   bool LookupMapValue(const MapKey& map_key,
553                       MapValueConstRef* val) const override;
554   bool LookupMapValue(const MapKey&, MapValueRef*) const = delete;
555   bool DeleteMapValue(const MapKey& map_key) override;
556 
557   const Map<Key, T>& GetMap() const override {
558     MapFieldBase::SyncMapWithRepeatedField();
559     return impl_.GetMap();
560   }
561 
562   Map<Key, T>* MutableMap() override {
563     MapFieldBase::SyncMapWithRepeatedField();
564     Map<Key, T>* result = impl_.MutableMap();
565     MapFieldBase::SetMapDirty();
566     return result;
567   }
568 
569   int size() const override;
570   void Clear() override;
571   void MergeFrom(const MapFieldBase& other) override;
572   void Swap(MapFieldBase* other) override;
573 
574   // Used in the implementation of parsing. Caller should take the ownership iff
575   // arena_ is NULL.
576   EntryType* NewEntry() const { return impl_.NewEntry(); }
577   // Used in the implementation of serializing enum value type. Caller should
578   // take the ownership iff arena_ is NULL.
579   EntryType* NewEnumEntryWrapper(const Key& key, const T t) const {
580     return impl_.NewEnumEntryWrapper(key, t);
581   }
582   // Used in the implementation of serializing other value types. Caller should
583   // take the ownership iff arena_ is NULL.
584   EntryType* NewEntryWrapper(const Key& key, const T& t) const {
585     return impl_.NewEntryWrapper(key, t);
586   }
587 
588   const char* _InternalParse(const char* ptr, ParseContext* ctx) {
589     return impl_._InternalParse(ptr, ctx);
590   }
591   template <typename UnknownType>
592   const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx,
593                                       bool (*is_valid)(int), uint32 field_num,
594                                       InternalMetadata* metadata) {
595     return impl_.template ParseWithEnumValidation<UnknownType>(
596         ptr, ctx, is_valid, field_num, metadata);
597   }
598 
599  private:
600   MapFieldLiteType impl_;
601 
602   typedef void InternalArenaConstructable_;
603   typedef void DestructorSkippable_;
604 
605   // Implements MapFieldBase
606   void SyncRepeatedFieldWithMapNoLock() const override;
607   void SyncMapWithRepeatedFieldNoLock() const override;
608   size_t SpaceUsedExcludingSelfNoLock() const override;
609 
610   void SetMapIteratorValue(MapIterator* map_iter) const override;
611 
612   friend class ::PROTOBUF_NAMESPACE_ID::Arena;
613   friend class MapFieldStateTest;  // For testing, it needs raw access to impl_
614   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapField);
615 };
616 
617 template <typename Derived, typename Key, typename T,
618           WireFormatLite::FieldType key_wire_type,
619           WireFormatLite::FieldType value_wire_type>
620 bool AllAreInitialized(
621     const MapField<Derived, Key, T, key_wire_type, value_wire_type>& field) {
622   const auto& t = field.GetMap();
623   for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end();
624        ++it) {
625     if (!it->second.IsInitialized()) return false;
626   }
627   return true;
628 }
629 
630 template <typename T, typename Key, typename Value,
631           WireFormatLite::FieldType kKeyFieldType,
632           WireFormatLite::FieldType kValueFieldType>
633 struct MapEntryToMapField<
634     MapEntry<T, Key, Value, kKeyFieldType, kValueFieldType>> {
635   typedef MapField<T, Key, Value, kKeyFieldType, kValueFieldType> MapFieldType;
636 };
637 
638 class PROTOBUF_EXPORT DynamicMapField
639     : public TypeDefinedMapFieldBase<MapKey, MapValueRef> {
640  public:
641   explicit DynamicMapField(const Message* default_entry);
642   DynamicMapField(const Message* default_entry, Arena* arena);
643   ~DynamicMapField() override;
644 
645   // Implement MapFieldBase
646   bool ContainsMapKey(const MapKey& map_key) const override;
647   bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
648   bool LookupMapValue(const MapKey& map_key,
649                       MapValueConstRef* val) const override;
650   bool LookupMapValue(const MapKey&, MapValueRef*) const = delete;
651   bool DeleteMapValue(const MapKey& map_key) override;
652   void MergeFrom(const MapFieldBase& other) override;
653   void Swap(MapFieldBase* other) override;
654 
655   const Map<MapKey, MapValueRef>& GetMap() const override;
656   Map<MapKey, MapValueRef>* MutableMap() override;
657 
658   int size() const override;
659   void Clear() override;
660 
661  private:
662   Map<MapKey, MapValueRef> map_;
663   const Message* default_entry_;
664 
665   void AllocateMapValue(MapValueRef* map_val);
666 
667   // Implements MapFieldBase
668   void SyncRepeatedFieldWithMapNoLock() const override;
669   void SyncMapWithRepeatedFieldNoLock() const override;
670   size_t SpaceUsedExcludingSelfNoLock() const override;
671   void SetMapIteratorValue(MapIterator* map_iter) const override;
672   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMapField);
673 };
674 
675 }  // namespace internal
676 
677 // MapValueConstRef points to a map value. Users can NOT modify
678 // the map value.
679 class PROTOBUF_EXPORT MapValueConstRef {
680  public:
681   MapValueConstRef() : data_(nullptr), type_(0) {}
682 
683   int64 GetInt64Value() const {
684     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
685                "MapValueConstRef::GetInt64Value");
686     return *reinterpret_cast<int64*>(data_);
687   }
688   uint64 GetUInt64Value() const {
689     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
690                "MapValueConstRef::GetUInt64Value");
691     return *reinterpret_cast<uint64*>(data_);
692   }
693   int32 GetInt32Value() const {
694     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
695                "MapValueConstRef::GetInt32Value");
696     return *reinterpret_cast<int32*>(data_);
697   }
698   uint32 GetUInt32Value() const {
699     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
700                "MapValueConstRef::GetUInt32Value");
701     return *reinterpret_cast<uint32*>(data_);
702   }
703   bool GetBoolValue() const {
704     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueConstRef::GetBoolValue");
705     return *reinterpret_cast<bool*>(data_);
706   }
707   int GetEnumValue() const {
708     TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueConstRef::GetEnumValue");
709     return *reinterpret_cast<int*>(data_);
710   }
711   const std::string& GetStringValue() const {
712     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
713                "MapValueConstRef::GetStringValue");
714     return *reinterpret_cast<std::string*>(data_);
715   }
716   float GetFloatValue() const {
717     TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
718                "MapValueConstRef::GetFloatValue");
719     return *reinterpret_cast<float*>(data_);
720   }
721   double GetDoubleValue() const {
722     TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
723                "MapValueConstRef::GetDoubleValue");
724     return *reinterpret_cast<double*>(data_);
725   }
726 
727   const Message& GetMessageValue() const {
728     TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
729                "MapValueConstRef::GetMessageValue");
730     return *reinterpret_cast<Message*>(data_);
731   }
732 
733  protected:
734   // data_ point to a map value. MapValueConstRef does not
735   // own this value.
736   void* data_;
737   // type_ is 0 or a valid FieldDescriptor::CppType.
738   int type_;
739 
740   FieldDescriptor::CppType type() const {
741     if (type_ == 0 || data_ == nullptr) {
742       GOOGLE_LOG(FATAL)
743           << "Protocol Buffer map usage error:\n"
744           << "MapValueConstRef::type MapValueConstRef is not initialized.";
745     }
746     return static_cast<FieldDescriptor::CppType>(type_);
747   }
748 
749  private:
750   template <typename Derived, typename K, typename V,
751             internal::WireFormatLite::FieldType key_wire_type,
752             internal::WireFormatLite::FieldType value_wire_type>
753   friend class internal::MapField;
754   template <typename K, typename V>
755   friend class internal::TypeDefinedMapFieldBase;
756   friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
757   friend class Reflection;
758   friend class internal::DynamicMapField;
759 
760   void SetType(FieldDescriptor::CppType type) { type_ = type; }
761   void SetValue(const void* val) { data_ = const_cast<void*>(val); }
762   void CopyFrom(const MapValueConstRef& other) {
763     type_ = other.type_;
764     data_ = other.data_;
765   }
766 };
767 
768 // MapValueRef points to a map value. Users are able to modify
769 // the map value.
770 class PROTOBUF_EXPORT MapValueRef final : public MapValueConstRef {
771  public:
772   MapValueRef() {}
773 
774   void SetInt64Value(int64 value) {
775     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::SetInt64Value");
776     *reinterpret_cast<int64*>(data_) = value;
777   }
778   void SetUInt64Value(uint64 value) {
779     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::SetUInt64Value");
780     *reinterpret_cast<uint64*>(data_) = value;
781   }
782   void SetInt32Value(int32 value) {
783     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::SetInt32Value");
784     *reinterpret_cast<int32*>(data_) = value;
785   }
786   void SetUInt32Value(uint32 value) {
787     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::SetUInt32Value");
788     *reinterpret_cast<uint32*>(data_) = value;
789   }
790   void SetBoolValue(bool value) {
791     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::SetBoolValue");
792     *reinterpret_cast<bool*>(data_) = value;
793   }
794   // TODO(jieluo) - Checks that enum is member.
795   void SetEnumValue(int value) {
796     TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueRef::SetEnumValue");
797     *reinterpret_cast<int*>(data_) = value;
798   }
799   void SetStringValue(const std::string& value) {
800     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapValueRef::SetStringValue");
801     *reinterpret_cast<std::string*>(data_) = value;
802   }
803   void SetFloatValue(float value) {
804     TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, "MapValueRef::SetFloatValue");
805     *reinterpret_cast<float*>(data_) = value;
806   }
807   void SetDoubleValue(double value) {
808     TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, "MapValueRef::SetDoubleValue");
809     *reinterpret_cast<double*>(data_) = value;
810   }
811 
812   Message* MutableMessageValue() {
813     TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
814                "MapValueRef::MutableMessageValue");
815     return reinterpret_cast<Message*>(data_);
816   }
817 
818  private:
819   friend class internal::DynamicMapField;
820 
821   // Only used in DynamicMapField
822   void DeleteData() {
823     switch (type_) {
824 #define HANDLE_TYPE(CPPTYPE, TYPE)           \
825   case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
826     delete reinterpret_cast<TYPE*>(data_);   \
827     break;                                   \
828   }
829       HANDLE_TYPE(INT32, int32);
830       HANDLE_TYPE(INT64, int64);
831       HANDLE_TYPE(UINT32, uint32);
832       HANDLE_TYPE(UINT64, uint64);
833       HANDLE_TYPE(DOUBLE, double);
834       HANDLE_TYPE(FLOAT, float);
835       HANDLE_TYPE(BOOL, bool);
836       HANDLE_TYPE(STRING, std::string);
837       HANDLE_TYPE(ENUM, int32);
838       HANDLE_TYPE(MESSAGE, Message);
839 #undef HANDLE_TYPE
840     }
841   }
842 };
843 
844 #undef TYPE_CHECK
845 
846 class PROTOBUF_EXPORT MapIterator {
847  public:
848   MapIterator(Message* message, const FieldDescriptor* field) {
849     const Reflection* reflection = message->GetReflection();
850     map_ = reflection->MutableMapData(message, field);
851     key_.SetType(field->message_type()->FindFieldByName("key")->cpp_type());
852     value_.SetType(field->message_type()->FindFieldByName("value")->cpp_type());
853     map_->InitializeIterator(this);
854   }
855   MapIterator(const MapIterator& other) {
856     map_ = other.map_;
857     map_->InitializeIterator(this);
858     map_->CopyIterator(this, other);
859   }
860   ~MapIterator() { map_->DeleteIterator(this); }
861   MapIterator& operator=(const MapIterator& other) {
862     map_ = other.map_;
863     map_->CopyIterator(this, other);
864     return *this;
865   }
866   friend bool operator==(const MapIterator& a, const MapIterator& b) {
867     return a.map_->EqualIterator(a, b);
868   }
869   friend bool operator!=(const MapIterator& a, const MapIterator& b) {
870     return !a.map_->EqualIterator(a, b);
871   }
872   MapIterator& operator++() {
873     map_->IncreaseIterator(this);
874     return *this;
875   }
876   MapIterator operator++(int) {
877     // iter_ is copied from Map<...>::iterator, no need to
878     // copy from its self again. Use the same implementation
879     // with operator++()
880     map_->IncreaseIterator(this);
881     return *this;
882   }
883   const MapKey& GetKey() { return key_; }
884   const MapValueRef& GetValueRef() { return value_; }
885   MapValueRef* MutableValueRef() {
886     map_->SetMapDirty();
887     return &value_;
888   }
889 
890  private:
891   template <typename Key, typename T>
892   friend class internal::TypeDefinedMapFieldBase;
893   friend class internal::DynamicMapField;
894   template <typename Derived, typename Key, typename T,
895             internal::WireFormatLite::FieldType kKeyFieldType,
896             internal::WireFormatLite::FieldType kValueFieldType>
897   friend class internal::MapField;
898 
899   // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns
900   // the iterator. It is allocated by MapField<...>::InitializeIterator() called
901   // in constructor and deleted by MapField<...>::DeleteIterator() called in
902   // destructor.
903   void* iter_;
904   // Point to a MapField to call helper methods implemented in MapField.
905   // MapIterator does not own this object.
906   internal::MapFieldBase* map_;
907   MapKey key_;
908   MapValueRef value_;
909 };
910 
911 }  // namespace protobuf
912 }  // namespace google
913 
914 #include <google/protobuf/port_undef.inc>
915 
916 #endif  // GOOGLE_PROTOBUF_MAP_FIELD_H__
917