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 #include <google/protobuf/map_field.h>
32
33 #include <vector>
34
35 #include <google/protobuf/map_field_inl.h>
36
37 // Must be included last.
38 #include <google/protobuf/port_def.inc>
39
40 namespace google {
41 namespace protobuf {
42 namespace internal {
43
Destruct()44 void MapFieldBase::Destruct() {
45 if (arena_ == nullptr) {
46 delete repeated_field_;
47 }
48 repeated_field_ = nullptr;
49 }
50
GetRepeatedField() const51 const RepeatedPtrFieldBase& MapFieldBase::GetRepeatedField() const {
52 ConstAccess();
53 SyncRepeatedFieldWithMap();
54 return *reinterpret_cast<RepeatedPtrFieldBase*>(repeated_field_);
55 }
56
MutableRepeatedField()57 RepeatedPtrFieldBase* MapFieldBase::MutableRepeatedField() {
58 MutableAccess();
59 SyncRepeatedFieldWithMap();
60 SetRepeatedDirty();
61 return reinterpret_cast<RepeatedPtrFieldBase*>(repeated_field_);
62 }
63
SwapState(MapFieldBase * other)64 void MapFieldBase::SwapState(MapFieldBase* other) {
65 // a relaxed swap of the atomic
66 auto other_state = other->state_.load(std::memory_order_relaxed);
67 auto this_state = state_.load(std::memory_order_relaxed);
68 other->state_.store(this_state, std::memory_order_relaxed);
69 state_.store(other_state, std::memory_order_relaxed);
70 }
71
SwapRepeatedPtrToNull(RepeatedPtrField<Message> ** from,RepeatedPtrField<Message> ** to,Arena * from_arena,Arena * to_arena)72 void SwapRepeatedPtrToNull(RepeatedPtrField<Message>** from,
73 RepeatedPtrField<Message>** to, Arena* from_arena,
74 Arena* to_arena) {
75 GOOGLE_DCHECK(*from != nullptr);
76 GOOGLE_DCHECK(*to == nullptr);
77 *to = Arena::CreateMessage<RepeatedPtrField<Message> >(to_arena);
78 **to = std::move(**from);
79 if (from_arena == nullptr) {
80 delete *from;
81 }
82 *from = nullptr;
83 }
84
Swap(MapFieldBase * other)85 void MapFieldBase::Swap(MapFieldBase* other) {
86 if (arena_ == other->arena_) {
87 InternalSwap(other);
88 return;
89 }
90 if (repeated_field_ != nullptr || other->repeated_field_ != nullptr) {
91 if (repeated_field_ == nullptr) {
92 SwapRepeatedPtrToNull(&other->repeated_field_, &repeated_field_,
93 other->arena_, arena_);
94 } else if (other->repeated_field_ == nullptr) {
95 SwapRepeatedPtrToNull(&repeated_field_, &other->repeated_field_, arena_,
96 other->arena_);
97 } else {
98 repeated_field_->Swap(other->repeated_field_);
99 }
100 }
101 SwapState(other);
102 }
103
UnsafeShallowSwap(MapFieldBase * other)104 void MapFieldBase::UnsafeShallowSwap(MapFieldBase* other) {
105 GOOGLE_DCHECK_EQ(arena_, other->arena_);
106 InternalSwap(other);
107 }
108
InternalSwap(MapFieldBase * other)109 void MapFieldBase::InternalSwap(MapFieldBase* other) {
110 std::swap(arena_, other->arena_);
111 std::swap(repeated_field_, other->repeated_field_);
112 SwapState(other);
113 }
114
SpaceUsedExcludingSelfLong() const115 size_t MapFieldBase::SpaceUsedExcludingSelfLong() const {
116 ConstAccess();
117 mutex_.Lock();
118 size_t size = SpaceUsedExcludingSelfNoLock();
119 mutex_.Unlock();
120 ConstAccess();
121 return size;
122 }
123
SpaceUsedExcludingSelfNoLock() const124 size_t MapFieldBase::SpaceUsedExcludingSelfNoLock() const {
125 if (repeated_field_ != nullptr) {
126 return repeated_field_->SpaceUsedExcludingSelfLong();
127 } else {
128 return 0;
129 }
130 }
131
IsMapValid() const132 bool MapFieldBase::IsMapValid() const {
133 ConstAccess();
134 // "Acquire" insures the operation after SyncRepeatedFieldWithMap won't get
135 // executed before state_ is checked.
136 int state = state_.load(std::memory_order_acquire);
137 return state != STATE_MODIFIED_REPEATED;
138 }
139
IsRepeatedFieldValid() const140 bool MapFieldBase::IsRepeatedFieldValid() const {
141 ConstAccess();
142 int state = state_.load(std::memory_order_acquire);
143 return state != STATE_MODIFIED_MAP;
144 }
145
SetMapDirty()146 void MapFieldBase::SetMapDirty() {
147 MutableAccess();
148 // These are called by (non-const) mutator functions. So by our API it's the
149 // callers responsibility to have these calls properly ordered.
150 state_.store(STATE_MODIFIED_MAP, std::memory_order_relaxed);
151 }
152
SetRepeatedDirty()153 void MapFieldBase::SetRepeatedDirty() {
154 MutableAccess();
155 // These are called by (non-const) mutator functions. So by our API it's the
156 // callers responsibility to have these calls properly ordered.
157 state_.store(STATE_MODIFIED_REPEATED, std::memory_order_relaxed);
158 }
159
SyncRepeatedFieldWithMap() const160 void MapFieldBase::SyncRepeatedFieldWithMap() const {
161 ConstAccess();
162 // acquire here matches with release below to ensure that we can only see a
163 // value of CLEAN after all previous changes have been synced.
164 switch (state_.load(std::memory_order_acquire)) {
165 case STATE_MODIFIED_MAP:
166 mutex_.Lock();
167 // Double check state, because another thread may have seen the same
168 // state and done the synchronization before the current thread.
169 if (state_.load(std::memory_order_relaxed) == STATE_MODIFIED_MAP) {
170 SyncRepeatedFieldWithMapNoLock();
171 state_.store(CLEAN, std::memory_order_release);
172 }
173 mutex_.Unlock();
174 ConstAccess();
175 break;
176 case CLEAN:
177 mutex_.Lock();
178 // Double check state
179 if (state_.load(std::memory_order_relaxed) == CLEAN) {
180 if (repeated_field_ == nullptr) {
181 repeated_field_ =
182 Arena::CreateMessage<RepeatedPtrField<Message> >(arena_);
183 }
184 state_.store(CLEAN, std::memory_order_release);
185 }
186 mutex_.Unlock();
187 ConstAccess();
188 break;
189 default:
190 break;
191 }
192 }
193
SyncRepeatedFieldWithMapNoLock() const194 void MapFieldBase::SyncRepeatedFieldWithMapNoLock() const {
195 if (repeated_field_ == nullptr) {
196 repeated_field_ = Arena::CreateMessage<RepeatedPtrField<Message> >(arena_);
197 }
198 }
199
SyncMapWithRepeatedField() const200 void MapFieldBase::SyncMapWithRepeatedField() const {
201 ConstAccess();
202 // acquire here matches with release below to ensure that we can only see a
203 // value of CLEAN after all previous changes have been synced.
204 if (state_.load(std::memory_order_acquire) == STATE_MODIFIED_REPEATED) {
205 mutex_.Lock();
206 // Double check state, because another thread may have seen the same state
207 // and done the synchronization before the current thread.
208 if (state_.load(std::memory_order_relaxed) == STATE_MODIFIED_REPEATED) {
209 SyncMapWithRepeatedFieldNoLock();
210 state_.store(CLEAN, std::memory_order_release);
211 }
212 mutex_.Unlock();
213 ConstAccess();
214 }
215 }
216
217 // ------------------DynamicMapField------------------
DynamicMapField(const Message * default_entry)218 DynamicMapField::DynamicMapField(const Message* default_entry)
219 : default_entry_(default_entry) {}
220
DynamicMapField(const Message * default_entry,Arena * arena)221 DynamicMapField::DynamicMapField(const Message* default_entry, Arena* arena)
222 : TypeDefinedMapFieldBase<MapKey, MapValueRef>(arena),
223 map_(arena),
224 default_entry_(default_entry) {}
225
~DynamicMapField()226 DynamicMapField::~DynamicMapField() {
227 if (arena_ == nullptr) {
228 // DynamicMapField owns map values. Need to delete them before clearing the
229 // map.
230 for (auto& kv : map_) {
231 kv.second.DeleteData();
232 }
233 map_.clear();
234 }
235 Destruct();
236 }
237
size() const238 int DynamicMapField::size() const { return GetMap().size(); }
239
Clear()240 void DynamicMapField::Clear() {
241 Map<MapKey, MapValueRef>* map = &const_cast<DynamicMapField*>(this)->map_;
242 if (MapFieldBase::arena_ == nullptr) {
243 for (Map<MapKey, MapValueRef>::iterator iter = map->begin();
244 iter != map->end(); ++iter) {
245 iter->second.DeleteData();
246 }
247 }
248
249 map->clear();
250
251 if (MapFieldBase::repeated_field_ != nullptr) {
252 MapFieldBase::repeated_field_->Clear();
253 }
254 // Data in map and repeated field are both empty, but we can't set status
255 // CLEAN which will invalidate previous reference to map.
256 MapFieldBase::SetMapDirty();
257 }
258
ContainsMapKey(const MapKey & map_key) const259 bool DynamicMapField::ContainsMapKey(const MapKey& map_key) const {
260 const Map<MapKey, MapValueRef>& map = GetMap();
261 Map<MapKey, MapValueRef>::const_iterator iter = map.find(map_key);
262 return iter != map.end();
263 }
264
AllocateMapValue(MapValueRef * map_val)265 void DynamicMapField::AllocateMapValue(MapValueRef* map_val) {
266 const FieldDescriptor* val_des = default_entry_->GetDescriptor()->map_value();
267 map_val->SetType(val_des->cpp_type());
268 // Allocate memory for the MapValueRef, and initialize to
269 // default value.
270 switch (val_des->cpp_type()) {
271 #define HANDLE_TYPE(CPPTYPE, TYPE) \
272 case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
273 TYPE* value = Arena::Create<TYPE>(MapFieldBase::arena_); \
274 map_val->SetValue(value); \
275 break; \
276 }
277 HANDLE_TYPE(INT32, int32_t);
278 HANDLE_TYPE(INT64, int64_t);
279 HANDLE_TYPE(UINT32, uint32_t);
280 HANDLE_TYPE(UINT64, uint64_t);
281 HANDLE_TYPE(DOUBLE, double);
282 HANDLE_TYPE(FLOAT, float);
283 HANDLE_TYPE(BOOL, bool);
284 HANDLE_TYPE(STRING, std::string);
285 HANDLE_TYPE(ENUM, int32_t);
286 #undef HANDLE_TYPE
287 case FieldDescriptor::CPPTYPE_MESSAGE: {
288 const Message& message =
289 default_entry_->GetReflection()->GetMessage(*default_entry_, val_des);
290 Message* value = message.New(MapFieldBase::arena_);
291 map_val->SetValue(value);
292 break;
293 }
294 }
295 }
296
InsertOrLookupMapValue(const MapKey & map_key,MapValueRef * val)297 bool DynamicMapField::InsertOrLookupMapValue(const MapKey& map_key,
298 MapValueRef* val) {
299 // Always use mutable map because users may change the map value by
300 // MapValueRef.
301 Map<MapKey, MapValueRef>* map = MutableMap();
302 Map<MapKey, MapValueRef>::iterator iter = map->find(map_key);
303 if (iter == map->end()) {
304 MapValueRef& map_val = map_[map_key];
305 AllocateMapValue(&map_val);
306 val->CopyFrom(map_val);
307 return true;
308 }
309 // map_key is already in the map. Make sure (*map)[map_key] is not called.
310 // [] may reorder the map and iterators.
311 val->CopyFrom(iter->second);
312 return false;
313 }
314
LookupMapValue(const MapKey & map_key,MapValueConstRef * val) const315 bool DynamicMapField::LookupMapValue(const MapKey& map_key,
316 MapValueConstRef* val) const {
317 const Map<MapKey, MapValueRef>& map = GetMap();
318 Map<MapKey, MapValueRef>::const_iterator iter = map.find(map_key);
319 if (iter == map.end()) {
320 return false;
321 }
322 // map_key is already in the map. Make sure (*map)[map_key] is not called.
323 // [] may reorder the map and iterators.
324 val->CopyFrom(iter->second);
325 return true;
326 }
327
DeleteMapValue(const MapKey & map_key)328 bool DynamicMapField::DeleteMapValue(const MapKey& map_key) {
329 MapFieldBase::SyncMapWithRepeatedField();
330 Map<MapKey, MapValueRef>::iterator iter = map_.find(map_key);
331 if (iter == map_.end()) {
332 return false;
333 }
334 // Set map dirty only if the delete is successful.
335 MapFieldBase::SetMapDirty();
336 if (MapFieldBase::arena_ == nullptr) {
337 iter->second.DeleteData();
338 }
339 map_.erase(iter);
340 return true;
341 }
342
GetMap() const343 const Map<MapKey, MapValueRef>& DynamicMapField::GetMap() const {
344 MapFieldBase::SyncMapWithRepeatedField();
345 return map_;
346 }
347
MutableMap()348 Map<MapKey, MapValueRef>* DynamicMapField::MutableMap() {
349 MapFieldBase::SyncMapWithRepeatedField();
350 MapFieldBase::SetMapDirty();
351 return &map_;
352 }
353
SetMapIteratorValue(MapIterator * map_iter) const354 void DynamicMapField::SetMapIteratorValue(MapIterator* map_iter) const {
355 Map<MapKey, MapValueRef>::const_iterator iter =
356 TypeDefinedMapFieldBase<MapKey, MapValueRef>::InternalGetIterator(
357 map_iter);
358 if (iter == map_.end()) return;
359 map_iter->key_.CopyFrom(iter->first);
360 map_iter->value_.CopyFrom(iter->second);
361 }
362
MergeFrom(const MapFieldBase & other)363 void DynamicMapField::MergeFrom(const MapFieldBase& other) {
364 GOOGLE_DCHECK(IsMapValid() && other.IsMapValid());
365 Map<MapKey, MapValueRef>* map = MutableMap();
366 const DynamicMapField& other_field =
367 reinterpret_cast<const DynamicMapField&>(other);
368 for (Map<MapKey, MapValueRef>::const_iterator other_it =
369 other_field.map_.begin();
370 other_it != other_field.map_.end(); ++other_it) {
371 Map<MapKey, MapValueRef>::iterator iter = map->find(other_it->first);
372 MapValueRef* map_val;
373 if (iter == map->end()) {
374 map_val = &map_[other_it->first];
375 AllocateMapValue(map_val);
376 } else {
377 map_val = &iter->second;
378 }
379
380 // Copy map value
381 const FieldDescriptor* field_descriptor =
382 default_entry_->GetDescriptor()->map_value();
383 switch (field_descriptor->cpp_type()) {
384 case FieldDescriptor::CPPTYPE_INT32: {
385 map_val->SetInt32Value(other_it->second.GetInt32Value());
386 break;
387 }
388 case FieldDescriptor::CPPTYPE_INT64: {
389 map_val->SetInt64Value(other_it->second.GetInt64Value());
390 break;
391 }
392 case FieldDescriptor::CPPTYPE_UINT32: {
393 map_val->SetUInt32Value(other_it->second.GetUInt32Value());
394 break;
395 }
396 case FieldDescriptor::CPPTYPE_UINT64: {
397 map_val->SetUInt64Value(other_it->second.GetUInt64Value());
398 break;
399 }
400 case FieldDescriptor::CPPTYPE_FLOAT: {
401 map_val->SetFloatValue(other_it->second.GetFloatValue());
402 break;
403 }
404 case FieldDescriptor::CPPTYPE_DOUBLE: {
405 map_val->SetDoubleValue(other_it->second.GetDoubleValue());
406 break;
407 }
408 case FieldDescriptor::CPPTYPE_BOOL: {
409 map_val->SetBoolValue(other_it->second.GetBoolValue());
410 break;
411 }
412 case FieldDescriptor::CPPTYPE_STRING: {
413 map_val->SetStringValue(other_it->second.GetStringValue());
414 break;
415 }
416 case FieldDescriptor::CPPTYPE_ENUM: {
417 map_val->SetEnumValue(other_it->second.GetEnumValue());
418 break;
419 }
420 case FieldDescriptor::CPPTYPE_MESSAGE: {
421 map_val->MutableMessageValue()->CopyFrom(
422 other_it->second.GetMessageValue());
423 break;
424 }
425 }
426 }
427 }
428
Swap(MapFieldBase * other)429 void DynamicMapField::Swap(MapFieldBase* other) {
430 DynamicMapField* other_field = down_cast<DynamicMapField*>(other);
431 std::swap(this->MapFieldBase::repeated_field_, other_field->repeated_field_);
432 map_.swap(other_field->map_);
433 // a relaxed swap of the atomic
434 auto other_state = other_field->state_.load(std::memory_order_relaxed);
435 auto this_state = this->MapFieldBase::state_.load(std::memory_order_relaxed);
436 other_field->state_.store(this_state, std::memory_order_relaxed);
437 this->MapFieldBase::state_.store(other_state, std::memory_order_relaxed);
438 }
439
SyncRepeatedFieldWithMapNoLock() const440 void DynamicMapField::SyncRepeatedFieldWithMapNoLock() const {
441 const Reflection* reflection = default_entry_->GetReflection();
442 const FieldDescriptor* key_des = default_entry_->GetDescriptor()->map_key();
443 const FieldDescriptor* val_des = default_entry_->GetDescriptor()->map_value();
444 if (MapFieldBase::repeated_field_ == nullptr) {
445 MapFieldBase::repeated_field_ =
446 Arena::CreateMessage<RepeatedPtrField<Message> >(MapFieldBase::arena_);
447 }
448
449 MapFieldBase::repeated_field_->Clear();
450
451 for (Map<MapKey, MapValueRef>::const_iterator it = map_.begin();
452 it != map_.end(); ++it) {
453 Message* new_entry = default_entry_->New(MapFieldBase::arena_);
454 MapFieldBase::repeated_field_->AddAllocated(new_entry);
455 const MapKey& map_key = it->first;
456 switch (key_des->cpp_type()) {
457 case FieldDescriptor::CPPTYPE_STRING:
458 reflection->SetString(new_entry, key_des, map_key.GetStringValue());
459 break;
460 case FieldDescriptor::CPPTYPE_INT64:
461 reflection->SetInt64(new_entry, key_des, map_key.GetInt64Value());
462 break;
463 case FieldDescriptor::CPPTYPE_INT32:
464 reflection->SetInt32(new_entry, key_des, map_key.GetInt32Value());
465 break;
466 case FieldDescriptor::CPPTYPE_UINT64:
467 reflection->SetUInt64(new_entry, key_des, map_key.GetUInt64Value());
468 break;
469 case FieldDescriptor::CPPTYPE_UINT32:
470 reflection->SetUInt32(new_entry, key_des, map_key.GetUInt32Value());
471 break;
472 case FieldDescriptor::CPPTYPE_BOOL:
473 reflection->SetBool(new_entry, key_des, map_key.GetBoolValue());
474 break;
475 case FieldDescriptor::CPPTYPE_DOUBLE:
476 case FieldDescriptor::CPPTYPE_FLOAT:
477 case FieldDescriptor::CPPTYPE_ENUM:
478 case FieldDescriptor::CPPTYPE_MESSAGE:
479 GOOGLE_LOG(FATAL) << "Can't get here.";
480 break;
481 }
482 const MapValueRef& map_val = it->second;
483 switch (val_des->cpp_type()) {
484 case FieldDescriptor::CPPTYPE_STRING:
485 reflection->SetString(new_entry, val_des, map_val.GetStringValue());
486 break;
487 case FieldDescriptor::CPPTYPE_INT64:
488 reflection->SetInt64(new_entry, val_des, map_val.GetInt64Value());
489 break;
490 case FieldDescriptor::CPPTYPE_INT32:
491 reflection->SetInt32(new_entry, val_des, map_val.GetInt32Value());
492 break;
493 case FieldDescriptor::CPPTYPE_UINT64:
494 reflection->SetUInt64(new_entry, val_des, map_val.GetUInt64Value());
495 break;
496 case FieldDescriptor::CPPTYPE_UINT32:
497 reflection->SetUInt32(new_entry, val_des, map_val.GetUInt32Value());
498 break;
499 case FieldDescriptor::CPPTYPE_BOOL:
500 reflection->SetBool(new_entry, val_des, map_val.GetBoolValue());
501 break;
502 case FieldDescriptor::CPPTYPE_DOUBLE:
503 reflection->SetDouble(new_entry, val_des, map_val.GetDoubleValue());
504 break;
505 case FieldDescriptor::CPPTYPE_FLOAT:
506 reflection->SetFloat(new_entry, val_des, map_val.GetFloatValue());
507 break;
508 case FieldDescriptor::CPPTYPE_ENUM:
509 reflection->SetEnumValue(new_entry, val_des, map_val.GetEnumValue());
510 break;
511 case FieldDescriptor::CPPTYPE_MESSAGE: {
512 const Message& message = map_val.GetMessageValue();
513 reflection->MutableMessage(new_entry, val_des)->CopyFrom(message);
514 break;
515 }
516 }
517 }
518 }
519
SyncMapWithRepeatedFieldNoLock() const520 void DynamicMapField::SyncMapWithRepeatedFieldNoLock() const {
521 Map<MapKey, MapValueRef>* map = &const_cast<DynamicMapField*>(this)->map_;
522 const Reflection* reflection = default_entry_->GetReflection();
523 const FieldDescriptor* key_des = default_entry_->GetDescriptor()->map_key();
524 const FieldDescriptor* val_des = default_entry_->GetDescriptor()->map_value();
525 // DynamicMapField owns map values. Need to delete them before clearing
526 // the map.
527 if (MapFieldBase::arena_ == nullptr) {
528 for (Map<MapKey, MapValueRef>::iterator iter = map->begin();
529 iter != map->end(); ++iter) {
530 iter->second.DeleteData();
531 }
532 }
533 map->clear();
534 for (RepeatedPtrField<Message>::iterator it =
535 MapFieldBase::repeated_field_->begin();
536 it != MapFieldBase::repeated_field_->end(); ++it) {
537 // MapKey type will be set later.
538 MapKey map_key;
539 switch (key_des->cpp_type()) {
540 case FieldDescriptor::CPPTYPE_STRING:
541 map_key.SetStringValue(reflection->GetString(*it, key_des));
542 break;
543 case FieldDescriptor::CPPTYPE_INT64:
544 map_key.SetInt64Value(reflection->GetInt64(*it, key_des));
545 break;
546 case FieldDescriptor::CPPTYPE_INT32:
547 map_key.SetInt32Value(reflection->GetInt32(*it, key_des));
548 break;
549 case FieldDescriptor::CPPTYPE_UINT64:
550 map_key.SetUInt64Value(reflection->GetUInt64(*it, key_des));
551 break;
552 case FieldDescriptor::CPPTYPE_UINT32:
553 map_key.SetUInt32Value(reflection->GetUInt32(*it, key_des));
554 break;
555 case FieldDescriptor::CPPTYPE_BOOL:
556 map_key.SetBoolValue(reflection->GetBool(*it, key_des));
557 break;
558 case FieldDescriptor::CPPTYPE_DOUBLE:
559 case FieldDescriptor::CPPTYPE_FLOAT:
560 case FieldDescriptor::CPPTYPE_ENUM:
561 case FieldDescriptor::CPPTYPE_MESSAGE:
562 GOOGLE_LOG(FATAL) << "Can't get here.";
563 break;
564 }
565
566 if (MapFieldBase::arena_ == nullptr) {
567 // Remove existing map value with same key.
568 Map<MapKey, MapValueRef>::iterator iter = map->find(map_key);
569 if (iter != map->end()) {
570 iter->second.DeleteData();
571 }
572 }
573
574 MapValueRef& map_val = (*map)[map_key];
575 map_val.SetType(val_des->cpp_type());
576 switch (val_des->cpp_type()) {
577 #define HANDLE_TYPE(CPPTYPE, TYPE, METHOD) \
578 case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
579 TYPE* value = Arena::Create<TYPE>(MapFieldBase::arena_); \
580 *value = reflection->Get##METHOD(*it, val_des); \
581 map_val.SetValue(value); \
582 break; \
583 }
584 HANDLE_TYPE(INT32, int32_t, Int32);
585 HANDLE_TYPE(INT64, int64_t, Int64);
586 HANDLE_TYPE(UINT32, uint32_t, UInt32);
587 HANDLE_TYPE(UINT64, uint64_t, UInt64);
588 HANDLE_TYPE(DOUBLE, double, Double);
589 HANDLE_TYPE(FLOAT, float, Float);
590 HANDLE_TYPE(BOOL, bool, Bool);
591 HANDLE_TYPE(STRING, std::string, String);
592 HANDLE_TYPE(ENUM, int32_t, EnumValue);
593 #undef HANDLE_TYPE
594 case FieldDescriptor::CPPTYPE_MESSAGE: {
595 const Message& message = reflection->GetMessage(*it, val_des);
596 Message* value = message.New(MapFieldBase::arena_);
597 value->CopyFrom(message);
598 map_val.SetValue(value);
599 break;
600 }
601 }
602 }
603 }
604
SpaceUsedExcludingSelfNoLock() const605 size_t DynamicMapField::SpaceUsedExcludingSelfNoLock() const {
606 size_t size = 0;
607 if (MapFieldBase::repeated_field_ != nullptr) {
608 size += MapFieldBase::repeated_field_->SpaceUsedExcludingSelfLong();
609 }
610 size += sizeof(map_);
611 size_t map_size = map_.size();
612 if (map_size) {
613 Map<MapKey, MapValueRef>::const_iterator it = map_.begin();
614 size += sizeof(it->first) * map_size;
615 size += sizeof(it->second) * map_size;
616 // If key is string, add the allocated space.
617 if (it->first.type() == FieldDescriptor::CPPTYPE_STRING) {
618 size += sizeof(std::string) * map_size;
619 }
620 // Add the allocated space in MapValueRef.
621 switch (it->second.type()) {
622 #define HANDLE_TYPE(CPPTYPE, TYPE) \
623 case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
624 size += sizeof(TYPE) * map_size; \
625 break; \
626 }
627 HANDLE_TYPE(INT32, int32_t);
628 HANDLE_TYPE(INT64, int64_t);
629 HANDLE_TYPE(UINT32, uint32_t);
630 HANDLE_TYPE(UINT64, uint64_t);
631 HANDLE_TYPE(DOUBLE, double);
632 HANDLE_TYPE(FLOAT, float);
633 HANDLE_TYPE(BOOL, bool);
634 HANDLE_TYPE(STRING, std::string);
635 HANDLE_TYPE(ENUM, int32_t);
636 #undef HANDLE_TYPE
637 case FieldDescriptor::CPPTYPE_MESSAGE: {
638 while (it != map_.end()) {
639 const Message& message = it->second.GetMessageValue();
640 size += message.GetReflection()->SpaceUsedLong(message);
641 ++it;
642 }
643 break;
644 }
645 }
646 }
647 return size;
648 }
649
650 } // namespace internal
651 } // namespace protobuf
652 } // namespace google
653
654 #include <google/protobuf/port_undef.inc>
655