• 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 internal {
268 
269 class ContendedMapCleanTest;
270 class GeneratedMessageReflection;
271 class MapFieldAccessor;
272 
273 // This class provides access to map field using reflection, which is the same
274 // as those provided for RepeatedPtrField<Message>. It is used for internal
275 // reflection implentation only. Users should never use this directly.
276 class PROTOBUF_EXPORT MapFieldBase {
277  public:
MapFieldBase()278   MapFieldBase()
279       : arena_(NULL), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {}
MapFieldBase(Arena * arena)280   explicit MapFieldBase(Arena* arena)
281       : arena_(arena), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {
282     // Mutex's destructor needs to be called explicitly to release resources
283     // acquired in its constructor.
284     if (arena) {
285       arena->OwnDestructor(&mutex_);
286     }
287   }
288   virtual ~MapFieldBase();
289 
290   // Returns reference to internal repeated field. Data written using
291   // Map's api prior to calling this function is guarantted to be
292   // included in repeated field.
293   const RepeatedPtrFieldBase& GetRepeatedField() const;
294 
295   // Like above. Returns mutable pointer to the internal repeated field.
296   RepeatedPtrFieldBase* MutableRepeatedField();
297 
298   // Pure virtual map APIs for Map Reflection.
299   virtual bool ContainsMapKey(const MapKey& map_key) const = 0;
300   virtual bool InsertOrLookupMapValue(const MapKey& map_key,
301                                       MapValueRef* val) = 0;
302   // Returns whether changes to the map are reflected in the repeated field.
303   bool IsRepeatedFieldValid() const;
304   // Insures operations after won't get executed before calling this.
305   bool IsMapValid() const;
306   virtual bool DeleteMapValue(const MapKey& map_key) = 0;
307   virtual bool EqualIterator(const MapIterator& a,
308                              const MapIterator& b) const = 0;
309   virtual void MapBegin(MapIterator* map_iter) const = 0;
310   virtual void MapEnd(MapIterator* map_iter) const = 0;
311   virtual void MergeFrom(const MapFieldBase& other) = 0;
312   virtual void Swap(MapFieldBase* other) = 0;
313   // Sync Map with repeated field and returns the size of map.
314   virtual int size() const = 0;
315   virtual void Clear() = 0;
316 
317   // Returns the number of bytes used by the repeated field, excluding
318   // sizeof(*this)
319   size_t SpaceUsedExcludingSelfLong() const;
320 
SpaceUsedExcludingSelf()321   int SpaceUsedExcludingSelf() const {
322     return internal::ToIntSize(SpaceUsedExcludingSelfLong());
323   }
324 
325  protected:
326   // Gets the size of space used by map field.
327   virtual size_t SpaceUsedExcludingSelfNoLock() const;
328 
329   // Synchronizes the content in Map to RepeatedPtrField if there is any change
330   // to Map after last synchronization.
331   void SyncRepeatedFieldWithMap() const;
332   virtual void SyncRepeatedFieldWithMapNoLock() const;
333 
334   // Synchronizes the content in RepeatedPtrField to Map if there is any change
335   // to RepeatedPtrField after last synchronization.
336   void SyncMapWithRepeatedField() const;
SyncMapWithRepeatedFieldNoLock()337   virtual void SyncMapWithRepeatedFieldNoLock() const {}
338 
339   // Tells MapFieldBase that there is new change to Map.
340   void SetMapDirty();
341 
342   // Tells MapFieldBase that there is new change to RepeatedPTrField.
343   void SetRepeatedDirty();
344 
345   // Provides derived class the access to repeated field.
346   void* MutableRepeatedPtrField() const;
347 
348   enum State {
349     STATE_MODIFIED_MAP = 0,       // map has newly added data that has not been
350                                   // synchronized to repeated field
351     STATE_MODIFIED_REPEATED = 1,  // repeated field has newly added data that
352                                   // has not been synchronized to map
353     CLEAN = 2,                    // data in map and repeated field are same
354   };
355 
356   Arena* arena_;
357   mutable RepeatedPtrField<Message>* repeated_field_;
358 
359   mutable internal::WrappedMutex
360       mutex_;  // The thread to synchronize map and repeated field
361                // needs to get lock first;
362   mutable std::atomic<State> state_;
363 
364  private:
365   friend class ContendedMapCleanTest;
366   friend class GeneratedMessageReflection;
367   friend class MapFieldAccessor;
368   friend class ::PROTOBUF_NAMESPACE_ID::DynamicMessage;
369 
370   // Virtual helper methods for MapIterator. MapIterator doesn't have the
371   // type helper for key and value. Call these help methods to deal with
372   // different types. Real helper methods are implemented in
373   // TypeDefinedMapFieldBase.
374   friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
375   // Allocate map<...>::iterator for MapIterator.
376   virtual void InitializeIterator(MapIterator* map_iter) const = 0;
377 
378   // DeleteIterator() is called by the destructor of MapIterator only.
379   // It deletes map<...>::iterator for MapIterator.
380   virtual void DeleteIterator(MapIterator* map_iter) const = 0;
381 
382   // Copy the map<...>::iterator from other_iterator to
383   // this_iterator.
384   virtual void CopyIterator(MapIterator* this_iterator,
385                             const MapIterator& other_iterator) const = 0;
386 
387   // IncreaseIterator() is called by operator++() of MapIterator only.
388   // It implements the ++ operator of MapIterator.
389   virtual void IncreaseIterator(MapIterator* map_iter) const = 0;
390   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldBase);
391 };
392 
393 // This class provides common Map Reflection implementations for generated
394 // message and dynamic message.
395 template <typename Key, typename T>
396 class TypeDefinedMapFieldBase : public MapFieldBase {
397  public:
TypeDefinedMapFieldBase()398   TypeDefinedMapFieldBase() {}
TypeDefinedMapFieldBase(Arena * arena)399   explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
~TypeDefinedMapFieldBase()400   ~TypeDefinedMapFieldBase() override {}
401   void MapBegin(MapIterator* map_iter) const override;
402   void MapEnd(MapIterator* map_iter) const override;
403   bool EqualIterator(const MapIterator& a, const MapIterator& b) const override;
404 
405   virtual const Map<Key, T>& GetMap() const = 0;
406   virtual Map<Key, T>* MutableMap() = 0;
407 
408  protected:
409   typename Map<Key, T>::const_iterator& InternalGetIterator(
410       const MapIterator* map_iter) const;
411 
412  private:
413   void InitializeIterator(MapIterator* map_iter) const override;
414   void DeleteIterator(MapIterator* map_iter) const override;
415   void CopyIterator(MapIterator* this_iteratorm,
416                     const MapIterator& that_iterator) const override;
417   void IncreaseIterator(MapIterator* map_iter) const override;
418 
419   virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0;
420   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeDefinedMapFieldBase);
421 };
422 
423 // This class provides access to map field using generated api. It is used for
424 // internal generated message implentation only. Users should never use this
425 // directly.
426 template <typename Derived, typename Key, typename T,
427           WireFormatLite::FieldType kKeyFieldType,
428           WireFormatLite::FieldType kValueFieldType, int default_enum_value = 0>
429 class MapField : public TypeDefinedMapFieldBase<Key, T> {
430   // Provide utilities to parse/serialize key/value.  Provide utilities to
431   // manipulate internal stored type.
432   typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
433   typedef MapTypeHandler<kValueFieldType, T> ValueTypeHandler;
434 
435   // Define message type for internal repeated field.
436   typedef Derived EntryType;
437 
438   // Define abbreviation for parent MapFieldLite
439   typedef MapFieldLite<Derived, Key, T, kKeyFieldType, kValueFieldType,
440                        default_enum_value>
441       MapFieldLiteType;
442 
443   // Enum needs to be handled differently from other types because it has
444   // different exposed type in Map's api and repeated field's api. For
445   // details see the comment in the implementation of
446   // SyncMapWithRepeatedFieldNoLock.
447   static constexpr bool kIsValueEnum = ValueTypeHandler::kIsEnum;
448   typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType;
449 
450  public:
451   typedef typename Derived::SuperType EntryTypeTrait;
452   typedef Map<Key, T> MapType;
453 
MapField()454   MapField() {}
MapField(Arena * arena)455   explicit MapField(Arena* arena)
456       : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {}
457 
458   // Implement MapFieldBase
459   bool ContainsMapKey(const MapKey& map_key) const override;
460   bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
461   bool DeleteMapValue(const MapKey& map_key) override;
462 
GetMap()463   const Map<Key, T>& GetMap() const override {
464     MapFieldBase::SyncMapWithRepeatedField();
465     return impl_.GetMap();
466   }
467 
MutableMap()468   Map<Key, T>* MutableMap() override {
469     MapFieldBase::SyncMapWithRepeatedField();
470     Map<Key, T>* result = impl_.MutableMap();
471     MapFieldBase::SetMapDirty();
472     return result;
473   }
474 
475   int size() const override;
476   void Clear() override;
477   void MergeFrom(const MapFieldBase& other) override;
478   void Swap(MapFieldBase* other) override;
479 
480   // Used in the implementation of parsing. Caller should take the ownership iff
481   // arena_ is NULL.
NewEntry()482   EntryType* NewEntry() const { return impl_.NewEntry(); }
483   // Used in the implementation of serializing enum value type. Caller should
484   // take the ownership iff arena_ is NULL.
NewEnumEntryWrapper(const Key & key,const T t)485   EntryType* NewEnumEntryWrapper(const Key& key, const T t) const {
486     return impl_.NewEnumEntryWrapper(key, t);
487   }
488   // Used in the implementation of serializing other value types. Caller should
489   // take the ownership iff arena_ is NULL.
NewEntryWrapper(const Key & key,const T & t)490   EntryType* NewEntryWrapper(const Key& key, const T& t) const {
491     return impl_.NewEntryWrapper(key, t);
492   }
493 
_InternalParse(const char * ptr,ParseContext * ctx)494   const char* _InternalParse(const char* ptr, ParseContext* ctx) {
495     return impl_._InternalParse(ptr, ctx);
496   }
497   template <typename UnknownType>
ParseWithEnumValidation(const char * ptr,ParseContext * ctx,bool (* is_valid)(int),uint32 field_num,InternalMetadata * metadata)498   const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx,
499                                       bool (*is_valid)(int), uint32 field_num,
500                                       InternalMetadata* metadata) {
501     return impl_.template ParseWithEnumValidation<UnknownType>(
502         ptr, ctx, is_valid, field_num, metadata);
503   }
504 
505  private:
506   MapFieldLiteType impl_;
507 
508   typedef void InternalArenaConstructable_;
509   typedef void DestructorSkippable_;
510 
511   // Implements MapFieldBase
512   void SyncRepeatedFieldWithMapNoLock() const override;
513   void SyncMapWithRepeatedFieldNoLock() const override;
514   size_t SpaceUsedExcludingSelfNoLock() const override;
515 
516   void SetMapIteratorValue(MapIterator* map_iter) const override;
517 
518   friend class ::PROTOBUF_NAMESPACE_ID::Arena;
519   friend class MapFieldStateTest;  // For testing, it needs raw access to impl_
520   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapField);
521 };
522 
523 template <typename Derived, typename Key, typename T,
524           WireFormatLite::FieldType key_wire_type,
525           WireFormatLite::FieldType value_wire_type, int default_enum_value>
AllAreInitialized(const MapField<Derived,Key,T,key_wire_type,value_wire_type,default_enum_value> & field)526 bool AllAreInitialized(
527     const MapField<Derived, Key, T, key_wire_type, value_wire_type,
528                    default_enum_value>& field) {
529   const auto& t = field.GetMap();
530   for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end();
531        ++it) {
532     if (!it->second.IsInitialized()) return false;
533   }
534   return true;
535 }
536 
537 template <typename T, typename Key, typename Value,
538           WireFormatLite::FieldType kKeyFieldType,
539           WireFormatLite::FieldType kValueFieldType, int default_enum_value>
540 struct MapEntryToMapField<MapEntry<T, Key, Value, kKeyFieldType,
541                                    kValueFieldType, default_enum_value>> {
542   typedef MapField<T, Key, Value, kKeyFieldType, kValueFieldType,
543                    default_enum_value>
544       MapFieldType;
545 };
546 
547 class PROTOBUF_EXPORT DynamicMapField
548     : public TypeDefinedMapFieldBase<MapKey, MapValueRef> {
549  public:
550   explicit DynamicMapField(const Message* default_entry);
551   DynamicMapField(const Message* default_entry, Arena* arena);
552   ~DynamicMapField() override;
553 
554   // Implement MapFieldBase
555   bool ContainsMapKey(const MapKey& map_key) const override;
556   bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
557   bool DeleteMapValue(const MapKey& map_key) override;
558   void MergeFrom(const MapFieldBase& other) override;
559   void Swap(MapFieldBase* other) override;
560 
561   const Map<MapKey, MapValueRef>& GetMap() const override;
562   Map<MapKey, MapValueRef>* MutableMap() override;
563 
564   int size() const override;
565   void Clear() override;
566 
567  private:
568   Map<MapKey, MapValueRef> map_;
569   const Message* default_entry_;
570 
571   void AllocateMapValue(MapValueRef* map_val);
572 
573   // Implements MapFieldBase
574   void SyncRepeatedFieldWithMapNoLock() const override;
575   void SyncMapWithRepeatedFieldNoLock() const override;
576   size_t SpaceUsedExcludingSelfNoLock() const override;
577   void SetMapIteratorValue(MapIterator* map_iter) const override;
578   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMapField);
579 };
580 
581 }  // namespace internal
582 
583 // MapValueRef points to a map value.
584 class PROTOBUF_EXPORT MapValueRef {
585  public:
586   MapValueRef() : data_(NULL), type_(0) {}
587 
588   void SetInt64Value(int64 value) {
589     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::SetInt64Value");
590     *reinterpret_cast<int64*>(data_) = value;
591   }
592   void SetUInt64Value(uint64 value) {
593     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::SetUInt64Value");
594     *reinterpret_cast<uint64*>(data_) = value;
595   }
596   void SetInt32Value(int32 value) {
597     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::SetInt32Value");
598     *reinterpret_cast<int32*>(data_) = value;
599   }
600   void SetUInt32Value(uint32 value) {
601     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::SetUInt32Value");
602     *reinterpret_cast<uint32*>(data_) = value;
603   }
604   void SetBoolValue(bool value) {
605     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::SetBoolValue");
606     *reinterpret_cast<bool*>(data_) = value;
607   }
608   // TODO(jieluo) - Checks that enum is member.
609   void SetEnumValue(int value) {
610     TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueRef::SetEnumValue");
611     *reinterpret_cast<int*>(data_) = value;
612   }
613   void SetStringValue(const std::string& value) {
614     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapValueRef::SetStringValue");
615     *reinterpret_cast<std::string*>(data_) = value;
616   }
617   void SetFloatValue(float value) {
618     TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, "MapValueRef::SetFloatValue");
619     *reinterpret_cast<float*>(data_) = value;
620   }
621   void SetDoubleValue(double value) {
622     TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, "MapValueRef::SetDoubleValue");
623     *reinterpret_cast<double*>(data_) = value;
624   }
625 
626   int64 GetInt64Value() const {
627     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::GetInt64Value");
628     return *reinterpret_cast<int64*>(data_);
629   }
630   uint64 GetUInt64Value() const {
631     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::GetUInt64Value");
632     return *reinterpret_cast<uint64*>(data_);
633   }
634   int32 GetInt32Value() const {
635     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::GetInt32Value");
636     return *reinterpret_cast<int32*>(data_);
637   }
638   uint32 GetUInt32Value() const {
639     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::GetUInt32Value");
640     return *reinterpret_cast<uint32*>(data_);
641   }
642   bool GetBoolValue() const {
643     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::GetBoolValue");
644     return *reinterpret_cast<bool*>(data_);
645   }
646   int GetEnumValue() const {
647     TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueRef::GetEnumValue");
648     return *reinterpret_cast<int*>(data_);
649   }
650   const std::string& GetStringValue() const {
651     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapValueRef::GetStringValue");
652     return *reinterpret_cast<std::string*>(data_);
653   }
654   float GetFloatValue() const {
655     TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, "MapValueRef::GetFloatValue");
656     return *reinterpret_cast<float*>(data_);
657   }
658   double GetDoubleValue() const {
659     TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, "MapValueRef::GetDoubleValue");
660     return *reinterpret_cast<double*>(data_);
661   }
662 
663   const Message& GetMessageValue() const {
664     TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
665                "MapValueRef::GetMessageValue");
666     return *reinterpret_cast<Message*>(data_);
667   }
668 
669   Message* MutableMessageValue() {
670     TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
671                "MapValueRef::MutableMessageValue");
672     return reinterpret_cast<Message*>(data_);
673   }
674 
675  private:
676   template <typename Derived, typename K, typename V,
677             internal::WireFormatLite::FieldType key_wire_type,
678             internal::WireFormatLite::FieldType value_wire_type,
679             int default_enum_value>
680   friend class internal::MapField;
681   template <typename K, typename V>
682   friend class internal::TypeDefinedMapFieldBase;
683   friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
684   friend class Reflection;
685   friend class internal::DynamicMapField;
686 
687   void SetType(FieldDescriptor::CppType type) { type_ = type; }
688 
689   FieldDescriptor::CppType type() const {
690     if (type_ == 0 || data_ == NULL) {
691       GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n"
692                  << "MapValueRef::type MapValueRef is not initialized.";
693     }
694     return (FieldDescriptor::CppType)type_;
695   }
696   void SetValue(const void* val) { data_ = const_cast<void*>(val); }
697   void CopyFrom(const MapValueRef& other) {
698     type_ = other.type_;
699     data_ = other.data_;
700   }
701   // Only used in DynamicMapField
702   void DeleteData() {
703     switch (type_) {
704 #define HANDLE_TYPE(CPPTYPE, TYPE)           \
705   case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
706     delete reinterpret_cast<TYPE*>(data_);   \
707     break;                                   \
708   }
709       HANDLE_TYPE(INT32, int32);
710       HANDLE_TYPE(INT64, int64);
711       HANDLE_TYPE(UINT32, uint32);
712       HANDLE_TYPE(UINT64, uint64);
713       HANDLE_TYPE(DOUBLE, double);
714       HANDLE_TYPE(FLOAT, float);
715       HANDLE_TYPE(BOOL, bool);
716       HANDLE_TYPE(STRING, std::string);
717       HANDLE_TYPE(ENUM, int32);
718       HANDLE_TYPE(MESSAGE, Message);
719 #undef HANDLE_TYPE
720     }
721   }
722   // data_ point to a map value. MapValueRef does not
723   // own this value.
724   void* data_;
725   // type_ is 0 or a valid FieldDescriptor::CppType.
726   int type_;
727 };
728 
729 #undef TYPE_CHECK
730 
731 class PROTOBUF_EXPORT MapIterator {
732  public:
733   MapIterator(Message* message, const FieldDescriptor* field) {
734     const Reflection* reflection = message->GetReflection();
735     map_ = reflection->MutableMapData(message, field);
736     key_.SetType(field->message_type()->FindFieldByName("key")->cpp_type());
737     value_.SetType(field->message_type()->FindFieldByName("value")->cpp_type());
738     map_->InitializeIterator(this);
739   }
740   MapIterator(const MapIterator& other) {
741     map_ = other.map_;
742     map_->InitializeIterator(this);
743     map_->CopyIterator(this, other);
744   }
745   ~MapIterator() { map_->DeleteIterator(this); }
746   MapIterator& operator=(const MapIterator& other) {
747     map_ = other.map_;
748     map_->CopyIterator(this, other);
749     return *this;
750   }
751   friend bool operator==(const MapIterator& a, const MapIterator& b) {
752     return a.map_->EqualIterator(a, b);
753   }
754   friend bool operator!=(const MapIterator& a, const MapIterator& b) {
755     return !a.map_->EqualIterator(a, b);
756   }
757   MapIterator& operator++() {
758     map_->IncreaseIterator(this);
759     return *this;
760   }
761   MapIterator operator++(int) {
762     // iter_ is copied from Map<...>::iterator, no need to
763     // copy from its self again. Use the same implementation
764     // with operator++()
765     map_->IncreaseIterator(this);
766     return *this;
767   }
768   const MapKey& GetKey() { return key_; }
769   const MapValueRef& GetValueRef() { return value_; }
770   MapValueRef* MutableValueRef() {
771     map_->SetMapDirty();
772     return &value_;
773   }
774 
775  private:
776   template <typename Key, typename T>
777   friend class internal::TypeDefinedMapFieldBase;
778   friend class internal::DynamicMapField;
779   template <typename Derived, typename Key, typename T,
780             internal::WireFormatLite::FieldType kKeyFieldType,
781             internal::WireFormatLite::FieldType kValueFieldType,
782             int default_enum_value>
783   friend class internal::MapField;
784 
785   // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns
786   // the iterator. It is allocated by MapField<...>::InitializeIterator() called
787   // in constructor and deleted by MapField<...>::DeleteIterator() called in
788   // destructor.
789   void* iter_;
790   // Point to a MapField to call helper methods implemented in MapField.
791   // MapIterator does not own this object.
792   internal::MapFieldBase* map_;
793   MapKey key_;
794   MapValueRef value_;
795 };
796 
797 }  // namespace protobuf
798 }  // namespace google
799 
800 namespace std {
801 template <>
802 struct hash<::PROTOBUF_NAMESPACE_ID::MapKey> {
803   size_t operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key) const {
804     switch (map_key.type()) {
805       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_DOUBLE:
806       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_FLOAT:
807       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_ENUM:
808       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_MESSAGE:
809         GOOGLE_LOG(FATAL) << "Unsupported";
810         break;
811       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_STRING:
812         return hash<std::string>()(map_key.GetStringValue());
813       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT64: {
814         auto value = map_key.GetInt64Value();
815         return hash<decltype(value)>()(value);
816       }
817       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT32: {
818         auto value = map_key.GetInt32Value();
819         return hash<decltype(value)>()(map_key.GetInt32Value());
820       }
821       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT64: {
822         auto value = map_key.GetUInt64Value();
823         return hash<decltype(value)>()(map_key.GetUInt64Value());
824       }
825       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT32: {
826         auto value = map_key.GetUInt32Value();
827         return hash<decltype(value)>()(map_key.GetUInt32Value());
828       }
829       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_BOOL: {
830         return hash<bool>()(map_key.GetBoolValue());
831       }
832     }
833     GOOGLE_LOG(FATAL) << "Can't get here.";
834     return 0;
835   }
836   bool operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key1,
837                   const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key2) const {
838     return map_key1 < map_key2;
839   }
840 };
841 }  // namespace std
842 #include <google/protobuf/port_undef.inc>
843 
844 #endif  // GOOGLE_PROTOBUF_MAP_FIELD_H__
845