blob: f78a4f407a2f3fd50018076aa85e957cb91f564f [file] [log] [blame]
Feng Xiaof157a562014-11-14 11:50:31 -08001// 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_ENTRY_H__
32#define GOOGLE_PROTOBUF_MAP_ENTRY_H__
33
Jisi Liu885b6122015-02-28 14:51:22 -080034#include <google/protobuf/generated_message_reflection.h>
35#include <google/protobuf/map_entry_lite.h>
Feng Xiaof157a562014-11-14 11:50:31 -080036#include <google/protobuf/map_type_handler.h>
Jisi Liu885b6122015-02-28 14:51:22 -080037#include <google/protobuf/reflection_ops.h>
38#include <google/protobuf/unknown_field_set.h>
Feng Xiaof157a562014-11-14 11:50:31 -080039#include <google/protobuf/wire_format_lite_inl.h>
40
41namespace google {
42namespace protobuf {
43class Arena;
Jisi Liu885b6122015-02-28 14:51:22 -080044namespace internal {
45template <typename Key, typename Value,
46 WireFormatLite::FieldType kKeyFieldType,
47 WireFormatLite::FieldType kValueFieldType,
48 int default_enum_value>
49class MapField;
50}
Feng Xiaof157a562014-11-14 11:50:31 -080051}
52
53namespace protobuf {
54namespace internal {
55
Feng Xiao137dd0f2014-12-03 16:31:47 -080056// Register all MapEntry default instances so we can delete them in
57// ShutdownProtobufLibrary().
Josh Habermancb3caf12015-02-17 18:23:41 -080058void LIBPROTOBUF_EXPORT RegisterMapEntryDefaultInstance(
59 MessageLite* default_instance);
Feng Xiao137dd0f2014-12-03 16:31:47 -080060
Feng Xiaof157a562014-11-14 11:50:31 -080061// This is the common base class for MapEntry. It is used by MapFieldBase in
62// reflection api, in which the static type of key and value is unknown.
63class LIBPROTOBUF_EXPORT MapEntryBase : public Message {
64 public:
65 ::google::protobuf::Metadata GetMetadata() const {
66 ::google::protobuf::Metadata metadata;
67 metadata.descriptor = descriptor_;
68 metadata.reflection = reflection_;
69 return metadata;
70 }
71
72 protected:
73 MapEntryBase() : descriptor_(NULL), reflection_(NULL) { }
74 virtual ~MapEntryBase() {}
75
76 const Descriptor* descriptor_;
77 const Reflection* reflection_;
78};
79
80// MapEntry is the returned google::protobuf::Message when calling AddMessage of
81// google::protobuf::Reflection. In order to let it work with generated message
82// reflection, its internal layout is the same as generated message with the
83// same fields. However, in order to decide the internal layout of key/value, we
84// need to know both their cpp type in generated api and proto type.
85//
86// cpp type | proto type | internal layout
87// int32 TYPE_INT32 int32
88// int32 TYPE_FIXED32 int32
89// FooEnum TYPE_ENUM int
90// FooMessage TYPE_MESSAGE FooMessage*
91//
92// The internal layouts of primitive types can be inferred from its proto type,
93// while we need to explicitly tell cpp type if proto type is TYPE_MESSAGE to
94// get internal layout.
95// Moreover, default_enum_value is used to initialize enum field in proto2.
Jisi Liu885b6122015-02-28 14:51:22 -080096template <typename Key, typename Value,
97 WireFormatLite::FieldType kKeyFieldType,
98 WireFormatLite::FieldType kValueFieldType,
99 int default_enum_value>
100class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase {
101 // Handlers for key/value wire type. Provide utilities to parse/serialize
102 // key/value.
103 typedef MapWireFieldTypeHandler<kKeyFieldType> KeyWireHandler;
104 typedef MapWireFieldTypeHandler<kValueFieldType> ValueWireHandler;
Feng Xiaof157a562014-11-14 11:50:31 -0800105
106 // Define key/value's internal stored type. Message is the only one whose
107 // internal stored type cannot be inferred from its proto type.
Jisi Liu885b6122015-02-28 14:51:22 -0800108 static const bool kIsKeyMessage = KeyWireHandler::kIsMessage;
109 static const bool kIsValueMessage = ValueWireHandler::kIsMessage;
110 typedef typename KeyWireHandler::CppType KeyInternalType;
111 typedef typename ValueWireHandler::CppType ValueInternalType;
112 typedef typename MapIf<kIsKeyMessage, Key, KeyInternalType>::type
Feng Xiaof157a562014-11-14 11:50:31 -0800113 KeyCppType;
Jisi Liu885b6122015-02-28 14:51:22 -0800114 typedef typename MapIf<kIsValueMessage, Value, ValueInternalType>::type
Feng Xiaof157a562014-11-14 11:50:31 -0800115 ValCppType;
116
Feng Xiaof157a562014-11-14 11:50:31 -0800117 // Abbreviation for MapEntry
118 typedef typename google::protobuf::internal::MapEntry<
Jisi Liu885b6122015-02-28 14:51:22 -0800119 Key, Value, kKeyFieldType, kValueFieldType, default_enum_value> EntryType;
Feng Xiaof157a562014-11-14 11:50:31 -0800120
Jisi Liu885b6122015-02-28 14:51:22 -0800121 // Abbreviation for MapEntryLite
122 typedef typename google::protobuf::internal::MapEntryLite<
123 Key, Value, kKeyFieldType, kValueFieldType, default_enum_value>
124 EntryLiteType;
Feng Xiaof157a562014-11-14 11:50:31 -0800125
126 public:
127 ~MapEntry() {
128 if (this == default_instance_) {
129 delete reflection_;
Feng Xiaof157a562014-11-14 11:50:31 -0800130 }
131 }
132
133 // accessors ======================================================
134
Feng Xiaof157a562014-11-14 11:50:31 -0800135 virtual inline const KeyCppType& key() const {
Jisi Liu885b6122015-02-28 14:51:22 -0800136 return entry_lite_.key();
Feng Xiaof157a562014-11-14 11:50:31 -0800137 }
138 inline KeyCppType* mutable_key() {
Jisi Liu885b6122015-02-28 14:51:22 -0800139 return entry_lite_.mutable_key();
Feng Xiaof157a562014-11-14 11:50:31 -0800140 }
141 virtual inline const ValCppType& value() const {
Jisi Liu885b6122015-02-28 14:51:22 -0800142 return entry_lite_.value();
Feng Xiaof157a562014-11-14 11:50:31 -0800143 }
144 inline ValCppType* mutable_value() {
Jisi Liu885b6122015-02-28 14:51:22 -0800145 return entry_lite_.mutable_value();
Feng Xiaof157a562014-11-14 11:50:31 -0800146 }
147
148 // implements Message =============================================
149
150 bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
Jisi Liu885b6122015-02-28 14:51:22 -0800151 return entry_lite_.MergePartialFromCodedStream(input);
Feng Xiaof157a562014-11-14 11:50:31 -0800152 }
153
154 int ByteSize() const {
Jisi Liu885b6122015-02-28 14:51:22 -0800155 return entry_lite_.ByteSize();
Feng Xiaof157a562014-11-14 11:50:31 -0800156 }
157
158 void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const {
Jisi Liu885b6122015-02-28 14:51:22 -0800159 entry_lite_.SerializeWithCachedSizes(output);
Feng Xiaof157a562014-11-14 11:50:31 -0800160 }
161
162 ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
Jisi Liu885b6122015-02-28 14:51:22 -0800163 return entry_lite_.SerializeWithCachedSizesToArray(output);
Feng Xiaof157a562014-11-14 11:50:31 -0800164 }
165
166 int GetCachedSize() const {
Jisi Liu885b6122015-02-28 14:51:22 -0800167 return entry_lite_.GetCachedSize();
Feng Xiaof157a562014-11-14 11:50:31 -0800168 }
169
Jisi Liu885b6122015-02-28 14:51:22 -0800170 bool IsInitialized() const {
171 return entry_lite_.IsInitialized();
172 }
Feng Xiaof157a562014-11-14 11:50:31 -0800173
174 Message* New() const {
175 MapEntry* entry = new MapEntry;
176 entry->descriptor_ = descriptor_;
177 entry->reflection_ = reflection_;
Jisi Liu885b6122015-02-28 14:51:22 -0800178 entry->set_default_instance(default_instance_);
179 return entry;
180 }
181
182 Message* New(Arena* arena) const {
183 MapEntry* entry = Arena::CreateMessage<MapEntry>(arena);
184 entry->descriptor_ = descriptor_;
185 entry->reflection_ = reflection_;
186 entry->set_default_instance(default_instance_);
Feng Xiaof157a562014-11-14 11:50:31 -0800187 return entry;
188 }
189
190 int SpaceUsed() const {
191 int size = sizeof(MapEntry);
Jisi Liu885b6122015-02-28 14:51:22 -0800192 size += entry_lite_.SpaceUsed();
Feng Xiaof157a562014-11-14 11:50:31 -0800193 return size;
194 }
195
196 void CopyFrom(const ::google::protobuf::Message& from) {
197 Clear();
198 MergeFrom(from);
199 }
200
201 void MergeFrom(const ::google::protobuf::Message& from) {
202 GOOGLE_CHECK_NE(&from, this);
203 const MapEntry* source = dynamic_cast_if_available<const MapEntry*>(&from);
204 if (source == NULL) {
205 ReflectionOps::Merge(from, this);
206 } else {
207 MergeFrom(*source);
208 }
209 }
210
211 void CopyFrom(const MapEntry& from) {
212 Clear();
213 MergeFrom(from);
214 }
215
216 void MergeFrom(const MapEntry& from) {
Jisi Liu885b6122015-02-28 14:51:22 -0800217 entry_lite_.MergeFrom(from.entry_lite_);
Feng Xiaof157a562014-11-14 11:50:31 -0800218 }
219
220 void Clear() {
Jisi Liu885b6122015-02-28 14:51:22 -0800221 entry_lite_.Clear();
Feng Xiaof157a562014-11-14 11:50:31 -0800222 }
223
224 void InitAsDefaultInstance() {
Jisi Liu885b6122015-02-28 14:51:22 -0800225 entry_lite_.InitAsDefaultInstance();
226 }
227
228 Arena* GetArena() const {
229 return entry_lite_.GetArena();
Feng Xiaof157a562014-11-14 11:50:31 -0800230 }
231
232 // Create default MapEntry instance for given descriptor. Descriptor has to be
233 // given when creating default MapEntry instance because different map field
234 // may have the same type and MapEntry class. The given descriptor is needed
235 // to distinguish instances of the same MapEntry class.
236 static MapEntry* CreateDefaultInstance(const Descriptor* descriptor) {
Jisi Liu885b6122015-02-28 14:51:22 -0800237 MapEntry* entry = new MapEntry;
Feng Xiaof157a562014-11-14 11:50:31 -0800238 const Reflection* reflection = new GeneratedMessageReflection(
239 descriptor, entry, offsets_,
Jisi Liu885b6122015-02-28 14:51:22 -0800240 GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_._has_bits_),
Feng Xiaof157a562014-11-14 11:50:31 -0800241 GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _unknown_fields_), -1,
242 DescriptorPool::generated_pool(),
243 ::google::protobuf::MessageFactory::generated_factory(), sizeof(MapEntry), -1);
244 entry->descriptor_ = descriptor;
245 entry->reflection_ = reflection;
Jisi Liu885b6122015-02-28 14:51:22 -0800246 entry->set_default_instance(entry);
Feng Xiaof157a562014-11-14 11:50:31 -0800247 entry->InitAsDefaultInstance();
Feng Xiao137dd0f2014-12-03 16:31:47 -0800248 RegisterMapEntryDefaultInstance(entry);
Feng Xiaof157a562014-11-14 11:50:31 -0800249 return entry;
250 }
251
Feng Xiaof157a562014-11-14 11:50:31 -0800252 private:
Jisi Liu885b6122015-02-28 14:51:22 -0800253 MapEntry() : default_instance_(NULL), entry_lite_() {}
Feng Xiaof157a562014-11-14 11:50:31 -0800254
Jisi Liu885b6122015-02-28 14:51:22 -0800255 explicit MapEntry(Arena* arena)
256 : default_instance_(NULL), entry_lite_(arena) {}
Feng Xiaof157a562014-11-14 11:50:31 -0800257
Jisi Liu885b6122015-02-28 14:51:22 -0800258 inline Arena* GetArenaNoVirtual() const {
259 return entry_lite_.GetArenaNoVirtual();
Feng Xiaof157a562014-11-14 11:50:31 -0800260 }
261
Jisi Liu885b6122015-02-28 14:51:22 -0800262 void set_default_instance(MapEntry* default_instance) {
263 default_instance_ = default_instance;
264 entry_lite_.set_default_instance(&default_instance->entry_lite_);
265 }
266
Feng Xiaof157a562014-11-14 11:50:31 -0800267 static int offsets_[2];
268 UnknownFieldSet _unknown_fields_;
Feng Xiaof157a562014-11-14 11:50:31 -0800269 MapEntry* default_instance_;
Jisi Liu885b6122015-02-28 14:51:22 -0800270 EntryLiteType entry_lite_;
Feng Xiaof157a562014-11-14 11:50:31 -0800271
272 friend class ::google::protobuf::Arena;
Jisi Liu885b6122015-02-28 14:51:22 -0800273 typedef void InternalArenaConstructable_;
274 typedef void DestructorSkippable_;
275 template <typename K, typename V, WireFormatLite::FieldType k_wire_type,
276 WireFormatLite::FieldType, int default_enum>
277 friend class LIBPROTOBUF_EXPORT internal::MapField;
Feng Xiaof157a562014-11-14 11:50:31 -0800278 friend class LIBPROTOBUF_EXPORT internal::GeneratedMessageReflection;
279
280 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry);
281};
282
Jisi Liu885b6122015-02-28 14:51:22 -0800283template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType,
284 WireFormatLite::FieldType kValueFieldType, int default_enum_value>
285int MapEntry<Key, Value, kKeyFieldType, kValueFieldType,
Feng Xiaof157a562014-11-14 11:50:31 -0800286 default_enum_value>::offsets_[2] = {
Jisi Liu885b6122015-02-28 14:51:22 -0800287 GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.key_),
288 GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.value_),
Feng Xiaof157a562014-11-14 11:50:31 -0800289};
290
291} // namespace internal
292} // namespace protobuf
293
294} // namespace google
295#endif // GOOGLE_PROTOBUF_MAP_ENTRY_H__