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