• 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 
36 #include <google/protobuf/arena.h>
37 #include <google/protobuf/descriptor.h>
38 #include <google/protobuf/generated_message_reflection.h>
39 #include <google/protobuf/map_entry.h>
40 #include <google/protobuf/map_field_lite.h>
41 #include <google/protobuf/map_type_handler.h>
42 #include <google/protobuf/message.h>
43 #include <google/protobuf/stubs/mutex.h>
44 #include <google/protobuf/port.h>
45 #include <google/protobuf/repeated_field.h>
46 #include <google/protobuf/unknown_field_set.h>
47 
48 
49 #include <google/protobuf/port_def.inc>
50 
51 #ifdef SWIG
52 #error "You cannot SWIG proto headers"
53 #endif
54 
55 namespace google {
56 namespace protobuf {
57 class DynamicMessage;
58 class MapKey;
59 class MapIterator;
60 namespace internal {
61 
62 class ContendedMapCleanTest;
63 class GeneratedMessageReflection;
64 class MapFieldAccessor;
65 
66 // This class provides access to map field using reflection, which is the same
67 // as those provided for RepeatedPtrField<Message>. It is used for internal
68 // reflection implentation only. Users should never use this directly.
69 class PROTOBUF_EXPORT MapFieldBase {
70  public:
MapFieldBase()71   MapFieldBase()
72       : arena_(NULL), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {}
MapFieldBase(Arena * arena)73   explicit MapFieldBase(Arena* arena)
74       : arena_(arena), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {
75     // Mutex's destructor needs to be called explicitly to release resources
76     // acquired in its constructor.
77     arena->OwnDestructor(&mutex_);
78   }
79   virtual ~MapFieldBase();
80 
81   // Returns reference to internal repeated field. Data written using
82   // Map's api prior to calling this function is guarantted to be
83   // included in repeated field.
84   const RepeatedPtrFieldBase& GetRepeatedField() const;
85 
86   // Like above. Returns mutable pointer to the internal repeated field.
87   RepeatedPtrFieldBase* MutableRepeatedField();
88 
89   // Pure virtual map APIs for Map Reflection.
90   virtual bool ContainsMapKey(const MapKey& map_key) const = 0;
91   virtual bool InsertOrLookupMapValue(const MapKey& map_key,
92                                       MapValueRef* val) = 0;
93   // Returns whether changes to the map are reflected in the repeated field.
94   bool IsRepeatedFieldValid() const;
95   // Insures operations after won't get executed before calling this.
96   bool IsMapValid() const;
97   virtual bool DeleteMapValue(const MapKey& map_key) = 0;
98   virtual bool EqualIterator(const MapIterator& a,
99                              const MapIterator& b) const = 0;
100   virtual void MapBegin(MapIterator* map_iter) const = 0;
101   virtual void MapEnd(MapIterator* map_iter) const = 0;
102   virtual void MergeFrom(const MapFieldBase& other) = 0;
103   virtual void Swap(MapFieldBase* other) = 0;
104   // Sync Map with repeated field and returns the size of map.
105   virtual int size() const = 0;
106   virtual void Clear() = 0;
107 
108   // Returns the number of bytes used by the repeated field, excluding
109   // sizeof(*this)
110   size_t SpaceUsedExcludingSelfLong() const;
111 
SpaceUsedExcludingSelf()112   int SpaceUsedExcludingSelf() const {
113     return internal::ToIntSize(SpaceUsedExcludingSelfLong());
114   }
115 
116  protected:
117   // Gets the size of space used by map field.
118   virtual size_t SpaceUsedExcludingSelfNoLock() const;
119 
120   // Synchronizes the content in Map to RepeatedPtrField if there is any change
121   // to Map after last synchronization.
122   void SyncRepeatedFieldWithMap() const;
123   virtual void SyncRepeatedFieldWithMapNoLock() const;
124 
125   // Synchronizes the content in RepeatedPtrField to Map if there is any change
126   // to RepeatedPtrField after last synchronization.
127   void SyncMapWithRepeatedField() const;
SyncMapWithRepeatedFieldNoLock()128   virtual void SyncMapWithRepeatedFieldNoLock() const {}
129 
130   // Tells MapFieldBase that there is new change to Map.
131   void SetMapDirty();
132 
133   // Tells MapFieldBase that there is new change to RepeatedPTrField.
134   void SetRepeatedDirty();
135 
136   // Provides derived class the access to repeated field.
137   void* MutableRepeatedPtrField() const;
138 
139   enum State {
140     STATE_MODIFIED_MAP = 0,       // map has newly added data that has not been
141                                   // synchronized to repeated field
142     STATE_MODIFIED_REPEATED = 1,  // repeated field has newly added data that
143                                   // has not been synchronized to map
144     CLEAN = 2,                    // data in map and repeated field are same
145   };
146 
147   Arena* arena_;
148   mutable RepeatedPtrField<Message>* repeated_field_;
149 
150   mutable internal::WrappedMutex
151       mutex_;  // The thread to synchronize map and repeated field
152                // needs to get lock first;
153   mutable std::atomic<State> state_;
154 
155  private:
156   friend class ContendedMapCleanTest;
157   friend class GeneratedMessageReflection;
158   friend class MapFieldAccessor;
159   friend class DynamicMessage;
160 
161   // Virtual helper methods for MapIterator. MapIterator doesn't have the
162   // type helper for key and value. Call these help methods to deal with
163   // different types. Real helper methods are implemented in
164   // TypeDefinedMapFieldBase.
165   friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
166   // Allocate map<...>::iterator for MapIterator.
167   virtual void InitializeIterator(MapIterator* map_iter) const = 0;
168 
169   // DeleteIterator() is called by the destructor of MapIterator only.
170   // It deletes map<...>::iterator for MapIterator.
171   virtual void DeleteIterator(MapIterator* map_iter) const = 0;
172 
173   // Copy the map<...>::iterator from other_iterator to
174   // this_iterator.
175   virtual void CopyIterator(MapIterator* this_iterator,
176                             const MapIterator& other_iterator) const = 0;
177 
178   // IncreaseIterator() is called by operator++() of MapIterator only.
179   // It implements the ++ operator of MapIterator.
180   virtual void IncreaseIterator(MapIterator* map_iter) const = 0;
181   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldBase);
182 };
183 
184 // This class provides common Map Reflection implementations for generated
185 // message and dynamic message.
186 template <typename Key, typename T>
187 class TypeDefinedMapFieldBase : public MapFieldBase {
188  public:
TypeDefinedMapFieldBase()189   TypeDefinedMapFieldBase() {}
TypeDefinedMapFieldBase(Arena * arena)190   explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
~TypeDefinedMapFieldBase()191   ~TypeDefinedMapFieldBase() override {}
192   void MapBegin(MapIterator* map_iter) const override;
193   void MapEnd(MapIterator* map_iter) const override;
194   bool EqualIterator(const MapIterator& a, const MapIterator& b) const override;
195 
196   virtual const Map<Key, T>& GetMap() const = 0;
197   virtual Map<Key, T>* MutableMap() = 0;
198 
199  protected:
200   typename Map<Key, T>::const_iterator& InternalGetIterator(
201       const MapIterator* map_iter) const;
202 
203  private:
204   void InitializeIterator(MapIterator* map_iter) const override;
205   void DeleteIterator(MapIterator* map_iter) const override;
206   void CopyIterator(MapIterator* this_iteratorm,
207                     const MapIterator& that_iterator) const override;
208   void IncreaseIterator(MapIterator* map_iter) const override;
209 
210   virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0;
211   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeDefinedMapFieldBase);
212 };
213 
214 // This class provides access to map field using generated api. It is used for
215 // internal generated message implentation only. Users should never use this
216 // directly.
217 template <typename Derived, typename Key, typename T,
218           WireFormatLite::FieldType kKeyFieldType,
219           WireFormatLite::FieldType kValueFieldType, int default_enum_value = 0>
220 class MapField : public TypeDefinedMapFieldBase<Key, T> {
221   // Provide utilities to parse/serialize key/value.  Provide utilities to
222   // manipulate internal stored type.
223   typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
224   typedef MapTypeHandler<kValueFieldType, T> ValueTypeHandler;
225 
226   // Define message type for internal repeated field.
227   typedef Derived EntryType;
228 
229   // Define abbreviation for parent MapFieldLite
230   typedef MapFieldLite<Derived, Key, T, kKeyFieldType, kValueFieldType,
231                        default_enum_value>
232       MapFieldLiteType;
233 
234   // Enum needs to be handled differently from other types because it has
235   // different exposed type in Map's api and repeated field's api. For
236   // details see the comment in the implementation of
237   // SyncMapWithRepeatedFieldNoLock.
238   static const bool kIsValueEnum = ValueTypeHandler::kIsEnum;
239   typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType;
240 
241  public:
242   typedef typename Derived::SuperType EntryTypeTrait;
243   typedef Map<Key, T> MapType;
244 
MapField()245   MapField() {}
MapField(Arena * arena)246   explicit MapField(Arena* arena)
247       : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {}
248 
249   // Implement MapFieldBase
250   bool ContainsMapKey(const MapKey& map_key) const override;
251   bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
252   bool DeleteMapValue(const MapKey& map_key) override;
253 
GetMap()254   const Map<Key, T>& GetMap() const override {
255     MapFieldBase::SyncMapWithRepeatedField();
256     return impl_.GetMap();
257   }
258 
MutableMap()259   Map<Key, T>* MutableMap() override {
260     MapFieldBase::SyncMapWithRepeatedField();
261     Map<Key, T>* result = impl_.MutableMap();
262     MapFieldBase::SetMapDirty();
263     return result;
264   }
265 
266   int size() const override;
267   void Clear() override;
268   void MergeFrom(const MapFieldBase& other) override;
269   void Swap(MapFieldBase* other) override;
270 
271   // Used in the implementation of parsing. Caller should take the ownership iff
272   // arena_ is NULL.
NewEntry()273   EntryType* NewEntry() const { return impl_.NewEntry(); }
274   // Used in the implementation of serializing enum value type. Caller should
275   // take the ownership iff arena_ is NULL.
NewEnumEntryWrapper(const Key & key,const T t)276   EntryType* NewEnumEntryWrapper(const Key& key, const T t) const {
277     return impl_.NewEnumEntryWrapper(key, t);
278   }
279   // Used in the implementation of serializing other value types. Caller should
280   // take the ownership iff arena_ is NULL.
NewEntryWrapper(const Key & key,const T & t)281   EntryType* NewEntryWrapper(const Key& key, const T& t) const {
282     return impl_.NewEntryWrapper(key, t);
283   }
284 
_InternalParse(const char * ptr,ParseContext * ctx)285   const char* _InternalParse(const char* ptr, ParseContext* ctx) {
286     return impl_._InternalParse(ptr, ctx);
287   }
288   template <typename Metadata>
ParseWithEnumValidation(const char * ptr,ParseContext * ctx,bool (* is_valid)(int),uint32 field_num,Metadata * metadata)289   const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx,
290                                       bool (*is_valid)(int), uint32 field_num,
291                                       Metadata* metadata) {
292     return impl_.ParseWithEnumValidation(ptr, ctx, is_valid, field_num,
293                                          metadata);
294   }
295 
296  private:
297   MapFieldLiteType impl_;
298 
299   typedef void InternalArenaConstructable_;
300   typedef void DestructorSkippable_;
301 
302   // Implements MapFieldBase
303   void SyncRepeatedFieldWithMapNoLock() const override;
304   void SyncMapWithRepeatedFieldNoLock() const override;
305   size_t SpaceUsedExcludingSelfNoLock() const override;
306 
307   void SetMapIteratorValue(MapIterator* map_iter) const override;
308 
309   friend class ::PROTOBUF_NAMESPACE_ID::Arena;
310   friend class MapFieldStateTest;  // For testing, it needs raw access to impl_
311   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapField);
312 };
313 
314 template <typename T, typename Key, typename Value,
315           WireFormatLite::FieldType kKeyFieldType,
316           WireFormatLite::FieldType kValueFieldType, int default_enum_value>
317 struct MapEntryToMapField<MapEntry<T, Key, Value, kKeyFieldType,
318                                    kValueFieldType, default_enum_value>> {
319   typedef MapField<T, Key, Value, kKeyFieldType, kValueFieldType,
320                    default_enum_value>
321       MapFieldType;
322 };
323 
324 class PROTOBUF_EXPORT DynamicMapField
325     : public TypeDefinedMapFieldBase<MapKey, MapValueRef> {
326  public:
327   explicit DynamicMapField(const Message* default_entry);
328   DynamicMapField(const Message* default_entry, Arena* arena);
329   ~DynamicMapField() override;
330 
331   // Implement MapFieldBase
332   bool ContainsMapKey(const MapKey& map_key) const override;
333   bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
334   bool DeleteMapValue(const MapKey& map_key) override;
335   void MergeFrom(const MapFieldBase& other) override;
336   void Swap(MapFieldBase* other) override;
337 
338   const Map<MapKey, MapValueRef>& GetMap() const override;
339   Map<MapKey, MapValueRef>* MutableMap() override;
340 
341   int size() const override;
342   void Clear() override;
343 
344  private:
345   Map<MapKey, MapValueRef> map_;
346   const Message* default_entry_;
347 
348   void AllocateMapValue(MapValueRef* map_val);
349 
350   // Implements MapFieldBase
351   void SyncRepeatedFieldWithMapNoLock() const override;
352   void SyncMapWithRepeatedFieldNoLock() const override;
353   size_t SpaceUsedExcludingSelfNoLock() const override;
354   void SetMapIteratorValue(MapIterator* map_iter) const override;
355   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMapField);
356 };
357 
358 }  // namespace internal
359 
360 #define TYPE_CHECK(EXPECTEDTYPE, METHOD)                                   \
361   if (type() != EXPECTEDTYPE) {                                            \
362     GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n"                     \
363                << METHOD << " type does not match\n"                       \
364                << "  Expected : "                                          \
365                << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n"       \
366                << "  Actual   : " << FieldDescriptor::CppTypeName(type()); \
367   }
368 
369 // MapKey is an union type for representing any possible
370 // map key.
371 class PROTOBUF_EXPORT MapKey {
372  public:
373   MapKey() : type_(0) {}
374   MapKey(const MapKey& other) : type_(0) { CopyFrom(other); }
375   MapKey& operator=(const MapKey& other) {
376     CopyFrom(other);
377     return *this;
378   }
379 
380   ~MapKey() {
381     if (type_ == FieldDescriptor::CPPTYPE_STRING) {
382       delete val_.string_value_;
383     }
384   }
385 
386   FieldDescriptor::CppType type() const {
387     if (type_ == 0) {
388       GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n"
389                  << "MapKey::type MapKey is not initialized. "
390                  << "Call set methods to initialize MapKey.";
391     }
392     return (FieldDescriptor::CppType)type_;
393   }
394 
395   void SetInt64Value(int64 value) {
396     SetType(FieldDescriptor::CPPTYPE_INT64);
397     val_.int64_value_ = value;
398   }
399   void SetUInt64Value(uint64 value) {
400     SetType(FieldDescriptor::CPPTYPE_UINT64);
401     val_.uint64_value_ = value;
402   }
403   void SetInt32Value(int32 value) {
404     SetType(FieldDescriptor::CPPTYPE_INT32);
405     val_.int32_value_ = value;
406   }
407   void SetUInt32Value(uint32 value) {
408     SetType(FieldDescriptor::CPPTYPE_UINT32);
409     val_.uint32_value_ = value;
410   }
411   void SetBoolValue(bool value) {
412     SetType(FieldDescriptor::CPPTYPE_BOOL);
413     val_.bool_value_ = value;
414   }
415   void SetStringValue(const std::string& val) {
416     SetType(FieldDescriptor::CPPTYPE_STRING);
417     *val_.string_value_ = val;
418   }
419 
420   int64 GetInt64Value() const {
421     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapKey::GetInt64Value");
422     return val_.int64_value_;
423   }
424   uint64 GetUInt64Value() const {
425     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapKey::GetUInt64Value");
426     return val_.uint64_value_;
427   }
428   int32 GetInt32Value() const {
429     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapKey::GetInt32Value");
430     return val_.int32_value_;
431   }
432   uint32 GetUInt32Value() const {
433     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapKey::GetUInt32Value");
434     return val_.uint32_value_;
435   }
436   bool GetBoolValue() const {
437     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapKey::GetBoolValue");
438     return val_.bool_value_;
439   }
440   const std::string& GetStringValue() const {
441     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapKey::GetStringValue");
442     return *val_.string_value_;
443   }
444 
445   bool operator<(const MapKey& other) const {
446     if (type_ != other.type_) {
447       // We could define a total order that handles this case, but
448       // there currently no need.  So, for now, fail.
449       GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
450     }
451     switch (type()) {
452       case FieldDescriptor::CPPTYPE_DOUBLE:
453       case FieldDescriptor::CPPTYPE_FLOAT:
454       case FieldDescriptor::CPPTYPE_ENUM:
455       case FieldDescriptor::CPPTYPE_MESSAGE:
456         GOOGLE_LOG(FATAL) << "Unsupported";
457         return false;
458       case FieldDescriptor::CPPTYPE_STRING:
459         return *val_.string_value_ < *other.val_.string_value_;
460       case FieldDescriptor::CPPTYPE_INT64:
461         return val_.int64_value_ < other.val_.int64_value_;
462       case FieldDescriptor::CPPTYPE_INT32:
463         return val_.int32_value_ < other.val_.int32_value_;
464       case FieldDescriptor::CPPTYPE_UINT64:
465         return val_.uint64_value_ < other.val_.uint64_value_;
466       case FieldDescriptor::CPPTYPE_UINT32:
467         return val_.uint32_value_ < other.val_.uint32_value_;
468       case FieldDescriptor::CPPTYPE_BOOL:
469         return val_.bool_value_ < other.val_.bool_value_;
470     }
471     return false;
472   }
473 
474   bool operator==(const MapKey& other) const {
475     if (type_ != other.type_) {
476       // To be consistent with operator<, we don't allow this either.
477       GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
478     }
479     switch (type()) {
480       case FieldDescriptor::CPPTYPE_DOUBLE:
481       case FieldDescriptor::CPPTYPE_FLOAT:
482       case FieldDescriptor::CPPTYPE_ENUM:
483       case FieldDescriptor::CPPTYPE_MESSAGE:
484         GOOGLE_LOG(FATAL) << "Unsupported";
485         break;
486       case FieldDescriptor::CPPTYPE_STRING:
487         return *val_.string_value_ == *other.val_.string_value_;
488       case FieldDescriptor::CPPTYPE_INT64:
489         return val_.int64_value_ == other.val_.int64_value_;
490       case FieldDescriptor::CPPTYPE_INT32:
491         return val_.int32_value_ == other.val_.int32_value_;
492       case FieldDescriptor::CPPTYPE_UINT64:
493         return val_.uint64_value_ == other.val_.uint64_value_;
494       case FieldDescriptor::CPPTYPE_UINT32:
495         return val_.uint32_value_ == other.val_.uint32_value_;
496       case FieldDescriptor::CPPTYPE_BOOL:
497         return val_.bool_value_ == other.val_.bool_value_;
498     }
499     GOOGLE_LOG(FATAL) << "Can't get here.";
500     return false;
501   }
502 
503   void CopyFrom(const MapKey& other) {
504     SetType(other.type());
505     switch (type_) {
506       case FieldDescriptor::CPPTYPE_DOUBLE:
507       case FieldDescriptor::CPPTYPE_FLOAT:
508       case FieldDescriptor::CPPTYPE_ENUM:
509       case FieldDescriptor::CPPTYPE_MESSAGE:
510         GOOGLE_LOG(FATAL) << "Unsupported";
511         break;
512       case FieldDescriptor::CPPTYPE_STRING:
513         *val_.string_value_ = *other.val_.string_value_;
514         break;
515       case FieldDescriptor::CPPTYPE_INT64:
516         val_.int64_value_ = other.val_.int64_value_;
517         break;
518       case FieldDescriptor::CPPTYPE_INT32:
519         val_.int32_value_ = other.val_.int32_value_;
520         break;
521       case FieldDescriptor::CPPTYPE_UINT64:
522         val_.uint64_value_ = other.val_.uint64_value_;
523         break;
524       case FieldDescriptor::CPPTYPE_UINT32:
525         val_.uint32_value_ = other.val_.uint32_value_;
526         break;
527       case FieldDescriptor::CPPTYPE_BOOL:
528         val_.bool_value_ = other.val_.bool_value_;
529         break;
530     }
531   }
532 
533  private:
534   template <typename K, typename V>
535   friend class internal::TypeDefinedMapFieldBase;
536   friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
537   friend class internal::DynamicMapField;
538 
539   union KeyValue {
540     KeyValue() {}
541     std::string* string_value_;
542     int64 int64_value_;
543     int32 int32_value_;
544     uint64 uint64_value_;
545     uint32 uint32_value_;
546     bool bool_value_;
547   } val_;
548 
549   void SetType(FieldDescriptor::CppType type) {
550     if (type_ == type) return;
551     if (type_ == FieldDescriptor::CPPTYPE_STRING) {
552       delete val_.string_value_;
553     }
554     type_ = type;
555     if (type_ == FieldDescriptor::CPPTYPE_STRING) {
556       val_.string_value_ = new std::string;
557     }
558   }
559 
560   // type_ is 0 or a valid FieldDescriptor::CppType.
561   int type_;
562 };
563 
564 // MapValueRef points to a map value.
565 class PROTOBUF_EXPORT MapValueRef {
566  public:
567   MapValueRef() : data_(NULL), type_(0) {}
568 
569   void SetInt64Value(int64 value) {
570     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::SetInt64Value");
571     *reinterpret_cast<int64*>(data_) = value;
572   }
573   void SetUInt64Value(uint64 value) {
574     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::SetUInt64Value");
575     *reinterpret_cast<uint64*>(data_) = value;
576   }
577   void SetInt32Value(int32 value) {
578     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::SetInt32Value");
579     *reinterpret_cast<int32*>(data_) = value;
580   }
581   void SetUInt32Value(uint32 value) {
582     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::SetUInt32Value");
583     *reinterpret_cast<uint32*>(data_) = value;
584   }
585   void SetBoolValue(bool value) {
586     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::SetBoolValue");
587     *reinterpret_cast<bool*>(data_) = value;
588   }
589   // TODO(jieluo) - Checks that enum is member.
590   void SetEnumValue(int value) {
591     TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueRef::SetEnumValue");
592     *reinterpret_cast<int*>(data_) = value;
593   }
594   void SetStringValue(const std::string& value) {
595     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapValueRef::SetStringValue");
596     *reinterpret_cast<std::string*>(data_) = value;
597   }
598   void SetFloatValue(float value) {
599     TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, "MapValueRef::SetFloatValue");
600     *reinterpret_cast<float*>(data_) = value;
601   }
602   void SetDoubleValue(double value) {
603     TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, "MapValueRef::SetDoubleValue");
604     *reinterpret_cast<double*>(data_) = value;
605   }
606 
607   int64 GetInt64Value() const {
608     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::GetInt64Value");
609     return *reinterpret_cast<int64*>(data_);
610   }
611   uint64 GetUInt64Value() const {
612     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::GetUInt64Value");
613     return *reinterpret_cast<uint64*>(data_);
614   }
615   int32 GetInt32Value() const {
616     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::GetInt32Value");
617     return *reinterpret_cast<int32*>(data_);
618   }
619   uint32 GetUInt32Value() const {
620     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::GetUInt32Value");
621     return *reinterpret_cast<uint32*>(data_);
622   }
623   bool GetBoolValue() const {
624     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::GetBoolValue");
625     return *reinterpret_cast<bool*>(data_);
626   }
627   int GetEnumValue() const {
628     TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueRef::GetEnumValue");
629     return *reinterpret_cast<int*>(data_);
630   }
631   const std::string& GetStringValue() const {
632     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapValueRef::GetStringValue");
633     return *reinterpret_cast<std::string*>(data_);
634   }
635   float GetFloatValue() const {
636     TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, "MapValueRef::GetFloatValue");
637     return *reinterpret_cast<float*>(data_);
638   }
639   double GetDoubleValue() const {
640     TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, "MapValueRef::GetDoubleValue");
641     return *reinterpret_cast<double*>(data_);
642   }
643 
644   const Message& GetMessageValue() const {
645     TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
646                "MapValueRef::GetMessageValue");
647     return *reinterpret_cast<Message*>(data_);
648   }
649 
650   Message* MutableMessageValue() {
651     TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
652                "MapValueRef::MutableMessageValue");
653     return reinterpret_cast<Message*>(data_);
654   }
655 
656  private:
657   template <typename Derived, typename K, typename V,
658             internal::WireFormatLite::FieldType key_wire_type,
659             internal::WireFormatLite::FieldType value_wire_type,
660             int default_enum_value>
661   friend class internal::MapField;
662   template <typename K, typename V>
663   friend class internal::TypeDefinedMapFieldBase;
664   friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
665   friend class Reflection;
666   friend class internal::DynamicMapField;
667 
668   void SetType(FieldDescriptor::CppType type) { type_ = type; }
669 
670   FieldDescriptor::CppType type() const {
671     if (type_ == 0 || data_ == NULL) {
672       GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n"
673                  << "MapValueRef::type MapValueRef is not initialized.";
674     }
675     return (FieldDescriptor::CppType)type_;
676   }
677   void SetValue(const void* val) { data_ = const_cast<void*>(val); }
678   void CopyFrom(const MapValueRef& other) {
679     type_ = other.type_;
680     data_ = other.data_;
681   }
682   // Only used in DynamicMapField
683   void DeleteData() {
684     switch (type_) {
685 #define HANDLE_TYPE(CPPTYPE, TYPE)           \
686   case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
687     delete reinterpret_cast<TYPE*>(data_);   \
688     break;                                   \
689   }
690       HANDLE_TYPE(INT32, int32);
691       HANDLE_TYPE(INT64, int64);
692       HANDLE_TYPE(UINT32, uint32);
693       HANDLE_TYPE(UINT64, uint64);
694       HANDLE_TYPE(DOUBLE, double);
695       HANDLE_TYPE(FLOAT, float);
696       HANDLE_TYPE(BOOL, bool);
697       HANDLE_TYPE(STRING, std::string);
698       HANDLE_TYPE(ENUM, int32);
699       HANDLE_TYPE(MESSAGE, Message);
700 #undef HANDLE_TYPE
701     }
702   }
703   // data_ point to a map value. MapValueRef does not
704   // own this value.
705   void* data_;
706   // type_ is 0 or a valid FieldDescriptor::CppType.
707   int type_;
708 };
709 
710 #undef TYPE_CHECK
711 
712 class PROTOBUF_EXPORT MapIterator {
713  public:
714   MapIterator(Message* message, const FieldDescriptor* field) {
715     const Reflection* reflection = message->GetReflection();
716     map_ = reflection->MutableMapData(message, field);
717     key_.SetType(field->message_type()->FindFieldByName("key")->cpp_type());
718     value_.SetType(field->message_type()->FindFieldByName("value")->cpp_type());
719     map_->InitializeIterator(this);
720   }
721   MapIterator(const MapIterator& other) {
722     map_ = other.map_;
723     map_->InitializeIterator(this);
724     map_->CopyIterator(this, other);
725   }
726   ~MapIterator() { map_->DeleteIterator(this); }
727   MapIterator& operator=(const MapIterator& other) {
728     map_ = other.map_;
729     map_->CopyIterator(this, other);
730     return *this;
731   }
732   friend bool operator==(const MapIterator& a, const MapIterator& b) {
733     return a.map_->EqualIterator(a, b);
734   }
735   friend bool operator!=(const MapIterator& a, const MapIterator& b) {
736     return !a.map_->EqualIterator(a, b);
737   }
738   MapIterator& operator++() {
739     map_->IncreaseIterator(this);
740     return *this;
741   }
742   MapIterator operator++(int) {
743     // iter_ is copied from Map<...>::iterator, no need to
744     // copy from its self again. Use the same implementation
745     // with operator++()
746     map_->IncreaseIterator(this);
747     return *this;
748   }
749   const MapKey& GetKey() { return key_; }
750   const MapValueRef& GetValueRef() { return value_; }
751   MapValueRef* MutableValueRef() {
752     map_->SetMapDirty();
753     return &value_;
754   }
755 
756  private:
757   template <typename Key, typename T>
758   friend class internal::TypeDefinedMapFieldBase;
759   friend class internal::DynamicMapField;
760   template <typename Derived, typename Key, typename T,
761             internal::WireFormatLite::FieldType kKeyFieldType,
762             internal::WireFormatLite::FieldType kValueFieldType,
763             int default_enum_value>
764   friend class internal::MapField;
765 
766   // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns
767   // the iterator. It is allocated by MapField<...>::InitializeIterator() called
768   // in constructor and deleted by MapField<...>::DeleteIterator() called in
769   // destructor.
770   void* iter_;
771   // Point to a MapField to call helper methods implemented in MapField.
772   // MapIterator does not own this object.
773   internal::MapFieldBase* map_;
774   MapKey key_;
775   MapValueRef value_;
776 };
777 
778 }  // namespace protobuf
779 }  // namespace google
780 
781 GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START
782 template <>
783 struct hash<::PROTOBUF_NAMESPACE_ID::MapKey> {
784   size_t operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key) const {
785     switch (map_key.type()) {
786       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_DOUBLE:
787       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_FLOAT:
788       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_ENUM:
789       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_MESSAGE:
790         GOOGLE_LOG(FATAL) << "Unsupported";
791         break;
792       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_STRING:
793         return hash<std::string>()(map_key.GetStringValue());
794       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT64:
795         return hash<int64>()(map_key.GetInt64Value());
796       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT32:
797         return hash<int32>()(map_key.GetInt32Value());
798       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT64:
799         return hash<uint64>()(map_key.GetUInt64Value());
800       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT32:
801         return hash<uint32>()(map_key.GetUInt32Value());
802       case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_BOOL:
803         return hash<bool>()(map_key.GetBoolValue());
804     }
805     GOOGLE_LOG(FATAL) << "Can't get here.";
806     return 0;
807   }
808   bool operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key1,
809                   const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key2) const {
810     return map_key1 < map_key2;
811   }
812 };
813 GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END
814 
815 #include <google/protobuf/port_undef.inc>
816 
817 #endif  // GOOGLE_PROTOBUF_MAP_FIELD_H__
818