// Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd #ifndef GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__ #define GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__ #include #include #include "absl/log/absl_check.h" #include "google/protobuf/internal_visibility.h" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/map.h" #include "google/protobuf/parse_context.h" #include "google/protobuf/port.h" #include "google/protobuf/wire_format_lite.h" // Must be included last. #include "google/protobuf/port_def.inc" #ifdef SWIG #error "You cannot SWIG proto headers" #endif namespace google { namespace protobuf { namespace internal { // This class provides access to map field using generated api. It is used for // internal generated message implementation only. Users should never use this // directly. template class MapFieldLite { public: typedef Map MapType; constexpr MapFieldLite() : map_() {} explicit MapFieldLite(Arena* arena) : map_(arena) {} MapFieldLite(ArenaInitialized, Arena* arena) : MapFieldLite(arena) {} MapFieldLite(InternalVisibility, Arena* arena) : map_(arena) {} MapFieldLite(InternalVisibility, Arena* arena, const MapFieldLite& from) : map_(arena) { MergeFrom(from); } #ifdef NDEBUG ~MapFieldLite() { map_.~Map(); } #else ~MapFieldLite() { ABSL_DCHECK_EQ(map_.arena(), nullptr); // We want to destruct the map in such a way that we can verify // that we've done that, but also be sure that we've deallocated // everything (as opposed to leaving an allocation behind with no // data in it, as would happen if a vector was resize'd to zero. // Map::Swap with an empty map accomplishes that. decltype(map_) swapped_map(map_.arena()); map_.InternalSwap(&swapped_map); } #endif // Accessors const Map& GetMap() const { return map_; } Map* MutableMap() { return &map_; } // Convenient methods for generated message implementation. int size() const { return static_cast(map_.size()); } void Clear() { return map_.clear(); } void MergeFrom(const MapFieldLite& other) { internal::MapMergeFrom(map_, other.map_); } void Swap(MapFieldLite* other) { map_.swap(other->map_); } void InternalSwap(MapFieldLite* other) { map_.InternalSwap(&other->map_); } static constexpr size_t InternalGetArenaOffset( internal::InternalVisibility access) { return PROTOBUF_FIELD_OFFSET(MapFieldLite, map_) + decltype(map_)::InternalGetArenaOffset(access); } private: typedef void DestructorSkippable_; // map_ is inside an anonymous union so we can explicitly control its // destruction union { Map map_; }; friend class google::protobuf::Arena; }; // True if IsInitialized() is true for value field in all elements of t. T is // expected to be message. It's useful to have this helper here to keep the // protobuf compiler from ever having to emit loops in IsInitialized() methods. // We want the C++ compiler to inline this or not as it sees fit. template bool AllAreInitialized(const MapFieldLite& field) { const auto& t = field.GetMap(); for (typename Map::const_iterator it = t.begin(); it != t.end(); ++it) { if (!it->second.IsInitialized()) return false; } return true; } template struct MapEntryToMapField : MapEntryToMapField {}; } // namespace internal } // namespace protobuf } // namespace google #include "google/protobuf/port_undef.inc" #endif // GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__