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