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