• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #ifndef GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
9 #define GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
10 
11 #include <cstddef>
12 #include <type_traits>
13 
14 #include "absl/log/absl_check.h"
15 #include "google/protobuf/internal_visibility.h"
16 #include "google/protobuf/io/coded_stream.h"
17 #include "google/protobuf/map.h"
18 #include "google/protobuf/parse_context.h"
19 #include "google/protobuf/port.h"
20 #include "google/protobuf/wire_format_lite.h"
21 
22 // Must be included last.
23 #include "google/protobuf/port_def.inc"
24 
25 #ifdef SWIG
26 #error "You cannot SWIG proto headers"
27 #endif
28 
29 namespace google {
30 namespace protobuf {
31 namespace internal {
32 
33 // This class provides access to map field using generated api. It is used for
34 // internal generated message implementation only. Users should never use this
35 // directly.
36 template <typename Key, typename T>
37 class MapFieldLite {
38  public:
39   typedef Map<Key, T> MapType;
40 
MapFieldLite()41   constexpr MapFieldLite() : map_() {}
MapFieldLite(Arena * arena)42   explicit MapFieldLite(Arena* arena) : map_(arena) {}
MapFieldLite(ArenaInitialized,Arena * arena)43   MapFieldLite(ArenaInitialized, Arena* arena) : MapFieldLite(arena) {}
44 
MapFieldLite(InternalVisibility,Arena * arena)45   MapFieldLite(InternalVisibility, Arena* arena) : map_(arena) {}
MapFieldLite(InternalVisibility,Arena * arena,const MapFieldLite & from)46   MapFieldLite(InternalVisibility, Arena* arena, const MapFieldLite& from)
47       : map_(arena) {
48     MergeFrom(from);
49   }
50 
51 #ifdef NDEBUG
~MapFieldLite()52   ~MapFieldLite() { map_.~Map(); }
53 #else
~MapFieldLite()54   ~MapFieldLite() {
55     ABSL_DCHECK_EQ(map_.arena(), nullptr);
56     // We want to destruct the map in such a way that we can verify
57     // that we've done that, but also be sure that we've deallocated
58     // everything (as opposed to leaving an allocation behind with no
59     // data in it, as would happen if a vector was resize'd to zero.
60     // Map::Swap with an empty map accomplishes that.
61     decltype(map_) swapped_map(map_.arena());
62     map_.InternalSwap(&swapped_map);
63   }
64 #endif
65   // Accessors
GetMap()66   const Map<Key, T>& GetMap() const { return map_; }
MutableMap()67   Map<Key, T>* MutableMap() { return &map_; }
68 
69   // Convenient methods for generated message implementation.
size()70   int size() const { return static_cast<int>(map_.size()); }
Clear()71   void Clear() { return map_.clear(); }
MergeFrom(const MapFieldLite & other)72   void MergeFrom(const MapFieldLite& other) {
73     internal::MapMergeFrom(map_, other.map_);
74   }
Swap(MapFieldLite * other)75   void Swap(MapFieldLite* other) { map_.swap(other->map_); }
InternalSwap(MapFieldLite * other)76   void InternalSwap(MapFieldLite* other) { map_.InternalSwap(&other->map_); }
77 
InternalGetArenaOffset(internal::InternalVisibility access)78   static constexpr size_t InternalGetArenaOffset(
79       internal::InternalVisibility access) {
80     return PROTOBUF_FIELD_OFFSET(MapFieldLite, map_) +
81            decltype(map_)::InternalGetArenaOffset(access);
82   }
83 
84  private:
85   typedef void DestructorSkippable_;
86 
87   // map_ is inside an anonymous union so we can explicitly control its
88   // destruction
89   union {
90     Map<Key, T> map_;
91   };
92 
93   friend class google::protobuf::Arena;
94 };
95 
96 // True if IsInitialized() is true for value field in all elements of t. T is
97 // expected to be message.  It's useful to have this helper here to keep the
98 // protobuf compiler from ever having to emit loops in IsInitialized() methods.
99 // We want the C++ compiler to inline this or not as it sees fit.
100 template <typename Key, typename T>
AllAreInitialized(const MapFieldLite<Key,T> & field)101 bool AllAreInitialized(const MapFieldLite<Key, T>& field) {
102   const auto& t = field.GetMap();
103   for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end();
104        ++it) {
105     if (!it->second.IsInitialized()) return false;
106   }
107   return true;
108 }
109 
110 template <typename MEntry>
111 struct MapEntryToMapField : MapEntryToMapField<typename MEntry::SuperType> {};
112 
113 }  // namespace internal
114 }  // namespace protobuf
115 }  // namespace google
116 
117 #include "google/protobuf/port_undef.inc"
118 
119 #endif  // GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
120