webkit  2cdf99a9e3038c7e01b3c37e8ad903ecbe5eecf1
https://github.com/WebKit/webkit
map_entry_lite.h
Go to the documentation of this file.
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_ENTRY_LITE_H__
32 #define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
33 
36 
37 namespace google {
38 namespace protobuf {
39 class Arena;
40 namespace internal {
41 template <typename Key, typename Value,
42  WireFormatLite::FieldType kKeyFieldType,
43  WireFormatLite::FieldType kValueFieldType,
44  int default_enum_value>
45 class MapEntry;
46 template <typename Key, typename Value,
47  WireFormatLite::FieldType kKeyFieldType,
48  WireFormatLite::FieldType kValueFieldType,
49  int default_enum_value>
50 class MapFieldLite;
51 } // namespace internal
52 } // namespace protobuf
53 
54 namespace protobuf {
55 namespace internal {
56 
57 // MapEntryLite is used to implement parsing and serialization of map for lite
58 // runtime.
59 template <typename Key, typename Value,
60  WireFormatLite::FieldType kKeyFieldType,
61  WireFormatLite::FieldType kValueFieldType,
62  int default_enum_value>
63 class MapEntryLite : public MessageLite {
64  // Provide utilities to parse/serialize key/value. Provide utilities to
65  // manipulate internal stored type.
68 
69  // Define internal memory layout. Strings and messages are stored as
70  // pointers, while other types are stored as values.
71  typedef typename KeyTypeHandler::TypeOnMemory KeyOnMemory;
72  typedef typename ValueTypeHandler::TypeOnMemory ValueOnMemory;
73 
74  // Enum type cannot be used for MapTypeHandler::Read. Define a type
75  // which will replace Enum with int.
76  typedef typename KeyTypeHandler::MapEntryAccessorType KeyMapEntryAccessorType;
77  typedef typename ValueTypeHandler::MapEntryAccessorType
78  ValueMapEntryAccessorType;
79 
80  // Constants for field number.
81  static const int kKeyFieldNumber = 1;
82  static const int kValueFieldNumber = 2;
83 
84  // Constants for field tag.
85  static const uint8 kKeyTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
86  kKeyFieldNumber, KeyTypeHandler::kWireType);
87  static const uint8 kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
88  kValueFieldNumber, ValueTypeHandler::kWireType);
89  static const int kTagSize = 1;
90 
91  public:
93  if (this != default_instance_) {
94  if (GetArenaNoVirtual() != NULL) return;
95  KeyTypeHandler::DeleteNoArena(key_);
96  ValueTypeHandler::DeleteNoArena(value_);
97  }
98  }
99 
100  // accessors ======================================================
101 
102  virtual inline const KeyMapEntryAccessorType& key() const {
103  return KeyTypeHandler::GetExternalReference(key_);
104  }
105  virtual inline const ValueMapEntryAccessorType& value() const {
106  GOOGLE_CHECK(default_instance_ != NULL);
107  return ValueTypeHandler::DefaultIfNotInitialized(value_,
108  default_instance_->value_);
109  }
110  inline KeyMapEntryAccessorType* mutable_key() {
111  set_has_key();
112  return KeyTypeHandler::EnsureMutable(&key_, GetArenaNoVirtual());
113  }
114  inline ValueMapEntryAccessorType* mutable_value() {
115  set_has_value();
116  return ValueTypeHandler::EnsureMutable(&value_, GetArenaNoVirtual());
117  }
118 
119  // implements MessageLite =========================================
120 
121  // MapEntryLite is for implementation only and this function isn't called
122  // anywhere. Just provide a fake implementation here for MessageLite.
123  string GetTypeName() const { return ""; }
124 
125  void CheckTypeAndMergeFrom(const MessageLite& other) {
126  MergeFrom(*::google::protobuf::down_cast<const MapEntryLite*>(&other));
127  }
128 
130  uint32 tag;
131 
132  for (;;) {
133  // 1) corrupted data: return false;
134  // 2) unknown field: skip without putting into unknown field set;
135  // 3) unknown enum value: keep it in parsing. In proto2, caller should
136  // check the value and put this entry into containing message's unknown
137  // field set if the value is an unknown enum. In proto3, caller doesn't
138  // need to care whether the value is unknown enum;
139  // 4) missing key/value: missed key/value will have default value. caller
140  // should take this entry as if key/value is set to default value.
141  tag = input->ReadTag();
142  switch (tag) {
143  case kKeyTag:
144  if (!KeyTypeHandler::Read(input, mutable_key())) {
145  return false;
146  }
147  set_has_key();
148  if (!input->ExpectTag(kValueTag)) break;
150 
151  case kValueTag:
152  if (!ValueTypeHandler::Read(input, mutable_value())) {
153  return false;
154  }
155  set_has_value();
156  if (input->ExpectAtEnd()) return true;
157  break;
158 
159  default:
160  if (tag == 0 ||
163  return true;
164  }
165  if (!WireFormatLite::SkipField(input, tag)) return false;
166  break;
167  }
168  }
169  }
170 
171  int ByteSize() const {
172  int size = 0;
173  size += has_key() ? kTagSize + KeyTypeHandler::ByteSize(key()) : 0;
174  size += has_value() ? kTagSize + ValueTypeHandler::ByteSize(value()) : 0;
175  return size;
176  }
177 
179  KeyTypeHandler::Write(kKeyFieldNumber, key(), output);
180  ValueTypeHandler::Write(kValueFieldNumber, value(), output);
181  }
182 
184  output = KeyTypeHandler::WriteToArray(kKeyFieldNumber, key(), output);
185  output = ValueTypeHandler::WriteToArray(kValueFieldNumber, value(), output);
186  return output;
187  }
188 
189  int GetCachedSize() const {
190  int size = 0;
191  size += has_key()
192  ? kTagSize + KeyTypeHandler::GetCachedSize(key())
193  : 0;
194  size += has_value()
195  ? kTagSize + ValueTypeHandler::GetCachedSize(
196  value())
197  : 0;
198  return size;
199  }
200 
201  bool IsInitialized() const { return ValueTypeHandler::IsInitialized(value_); }
202 
203  MessageLite* New() const {
204  MapEntryLite* entry = new MapEntryLite;
205  entry->default_instance_ = default_instance_;
206  return entry;
207  }
208 
209  MessageLite* New(Arena* arena) const {
210  MapEntryLite* entry = Arena::CreateMessage<MapEntryLite>(arena);
211  entry->default_instance_ = default_instance_;
212  return entry;
213  }
214 
215  int SpaceUsed() const {
216  int size = sizeof(MapEntryLite);
217  size += KeyTypeHandler::SpaceUsedInMapEntry(key_);
218  size += ValueTypeHandler::SpaceUsedInMapEntry(value_);
219  return size;
220  }
221 
222  void MergeFrom(const MapEntryLite& from) {
223  if (from._has_bits_[0]) {
224  if (from.has_key()) {
225  KeyTypeHandler::EnsureMutable(&key_, GetArenaNoVirtual());
226  KeyTypeHandler::Merge(from.key(), &key_, GetArenaNoVirtual());
227  set_has_key();
228  }
229  if (from.has_value()) {
230  ValueTypeHandler::EnsureMutable(&value_, GetArenaNoVirtual());
231  ValueTypeHandler::Merge(from.value(), &value_, GetArenaNoVirtual());
232  set_has_value();
233  }
234  }
235  }
236 
237  void Clear() {
238  KeyTypeHandler::Clear(&key_, GetArenaNoVirtual());
239  ValueTypeHandler::ClearMaybeByDefaultEnum(
240  &value_, GetArenaNoVirtual(), default_enum_value);
241  clear_has_key();
242  clear_has_value();
243  }
244 
246  KeyTypeHandler::AssignDefaultValue(&key_);
247  ValueTypeHandler::AssignDefaultValue(&value_);
248  }
249 
250  Arena* GetArena() const {
251  return GetArenaNoVirtual();
252  }
253 
254  // Create a MapEntryLite for given key and value from google::protobuf::Map in
255  // serialization. This function is only called when value is enum. Enum is
256  // treated differently because its type in MapEntry is int and its type in
257  // google::protobuf::Map is enum. We cannot create a reference to int from an enum.
258  static MapEntryLite* EnumWrap(const Key& key, const Value value,
259  Arena* arena) {
260  return Arena::CreateMessage<MapEnumEntryWrapper<
261  Key, Value, kKeyFieldType, kValueFieldType, default_enum_value> >(
262  arena, key, value);
263  }
264 
265  // Like above, but for all the other types. This avoids value copy to create
266  // MapEntryLite from google::protobuf::Map in serialization.
267  static MapEntryLite* Wrap(const Key& key, const Value& value, Arena* arena) {
268  return Arena::CreateMessage<MapEntryWrapper<Key, Value, kKeyFieldType,
269  kValueFieldType,
270  default_enum_value> >(
271  arena, key, value);
272  }
273 
274  protected:
275  void set_has_key() { _has_bits_[0] |= 0x00000001u; }
276  bool has_key() const { return (_has_bits_[0] & 0x00000001u) != 0; }
277  void clear_has_key() { _has_bits_[0] &= ~0x00000001u; }
278  void set_has_value() { _has_bits_[0] |= 0x00000002u; }
279  bool has_value() const { return (_has_bits_[0] & 0x00000002u) != 0; }
280  void clear_has_value() { _has_bits_[0] &= ~0x00000002u; }
281 
282  private:
283  // Serializing a generated message containing map field involves serializing
284  // key-value pairs from google::protobuf::Map. The wire format of each key-value pair
285  // after serialization should be the same as that of a MapEntry message
286  // containing the same key and value inside it. However, google::protobuf::Map doesn't
287  // store key and value as MapEntry message, which disables us to use existing
288  // code to serialize message. In order to use existing code to serialize
289  // message, we need to construct a MapEntry from key-value pair. But it
290  // involves copy of key and value to construct a MapEntry. In order to avoid
291  // this copy in constructing a MapEntry, we need the following class which
292  // only takes references of given key and value.
293  template <typename K, typename V, WireFormatLite::FieldType k_wire_type,
294  WireFormatLite::FieldType v_wire_type, int default_enum>
295  class MapEntryWrapper
296  : public MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> {
298  typedef typename Base::KeyMapEntryAccessorType KeyMapEntryAccessorType;
299  typedef typename Base::ValueMapEntryAccessorType ValueMapEntryAccessorType;
300 
301  public:
302  MapEntryWrapper(Arena* arena, const K& key, const V& value)
304  key_(key),
305  value_(value) {
306  Base::set_has_key();
307  Base::set_has_value();
308  }
309  inline const KeyMapEntryAccessorType& key() const { return key_; }
310  inline const ValueMapEntryAccessorType& value() const { return value_; }
311 
312  private:
313  const Key& key_;
314  const Value& value_;
315 
316  friend class ::google::protobuf::Arena;
317  typedef void InternalArenaConstructable_;
318  typedef void DestructorSkippable_;
319  };
320 
321  // Like above, but for enum value only, which stores value instead of
322  // reference of value field inside. This is needed because the type of value
323  // field in constructor is an enum, while we need to store it as an int. If we
324  // initialize a reference to int with a reference to enum, compiler will
325  // generate a temporary int from enum and initialize the reference to int with
326  // the temporary.
327  template <typename K, typename V, WireFormatLite::FieldType k_wire_type,
328  WireFormatLite::FieldType v_wire_type, int default_enum>
329  class MapEnumEntryWrapper
330  : public MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> {
332  typedef typename Base::KeyMapEntryAccessorType KeyMapEntryAccessorType;
333  typedef typename Base::ValueMapEntryAccessorType ValueMapEntryAccessorType;
334 
335  public:
336  MapEnumEntryWrapper(Arena* arena, const K& key, const V& value)
338  key_(key),
339  value_(value) {
340  Base::set_has_key();
341  Base::set_has_value();
342  }
343  inline const KeyMapEntryAccessorType& key() const { return key_; }
344  inline const ValueMapEntryAccessorType& value() const { return value_; }
345 
346  private:
347  const KeyMapEntryAccessorType& key_;
348  const ValueMapEntryAccessorType value_;
349 
350  friend class google::protobuf::Arena;
351  typedef void DestructorSkippable_;
352  };
353 
354  MapEntryLite() : default_instance_(NULL), arena_(NULL) {
356  ValueTypeHandler::InitializeMaybeByDefaultEnum(
357  &value_, default_enum_value, NULL);
358  _has_bits_[0] = 0;
359  }
360 
361  explicit MapEntryLite(Arena* arena)
362  : default_instance_(NULL), arena_(arena) {
363  KeyTypeHandler::Initialize(&key_, arena);
364  ValueTypeHandler::InitializeMaybeByDefaultEnum(
365  &value_, default_enum_value, arena);
366  _has_bits_[0] = 0;
367  }
368 
369  inline Arena* GetArenaNoVirtual() const {
370  return arena_;
371  }
372 
373  void set_default_instance(MapEntryLite* default_instance) {
374  default_instance_ = default_instance;
375  }
376 
377  MapEntryLite* default_instance_;
378 
379  KeyOnMemory key_;
380  ValueOnMemory value_;
381  Arena* arena_;
382  uint32 _has_bits_[1];
383 
384  friend class ::google::protobuf::Arena;
385  typedef void InternalArenaConstructable_;
386  typedef void DestructorSkippable_;
387  template <typename K, typename V, WireFormatLite::FieldType,
389  friend class internal::MapEntry;
390  template <typename K, typename V, WireFormatLite::FieldType,
393 
395 };
396 
397 } // namespace internal
398 } // namespace protobuf
399 
400 } // namespace google
401 #endif // GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream *input)
Definition: map_entry_lite.h:129
MessageLite * New(Arena *arena) const
Definition: map_entry_lite.h:209
FieldType
Definition: wire_format_lite.h:96
static MapEntryLite * EnumWrap(const Key &key, const Value value, Arena *arena)
Definition: map_entry_lite.h:258
void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream *output) const
Definition: map_entry_lite.h:178
#define size
Definition: float-mm.c:27
EGLStreamKHR EGLint EGLint EGLint size
Definition: eglext.h:984
MessageLite * New() const
Definition: map_entry_lite.h:203
void set_has_value()
Definition: map_entry_lite.h:278
void clear_has_key()
Definition: map_entry_lite.h:277
#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName)
Definition: macros.h:40
OPENSSL_EXPORT pem_password_cb void * u
Definition: pem.h:398
KeyMapEntryAccessorType * mutable_key()
Definition: map_entry_lite.h:110
#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE)
Definition: wire_format_lite.h:186
uint8_t uint8
Definition: port.h:133
bool has_key() const
Definition: map_entry_lite.h:276
Arena * GetArena() const
Definition: map_entry_lite.h:250
static MapEntryLite * Wrap(const Key &key, const Value &value, Arena *arena)
Definition: map_entry_lite.h:267
void Clear()
Definition: map_entry_lite.h:237
bool ExpectAtEnd()
Definition: coded_stream.h:1043
string GetTypeName() const
Definition: map_entry_lite.h:123
void InitAsDefaultInstance()
Definition: map_entry_lite.h:245
bool has_value() const
Definition: map_entry_lite.h:279
int GetCachedSize() const
Definition: map_entry_lite.h:189
#define output
Definition: wire_format_lite.h:418
DOMString tag
Definition: Notification.idl:66
int Write(int fd, const void *buf, unsigned int count)
Definition: gtest-port.h:1393
Clear
Definition: python_message.py:1326
#define K
Definition: gcc-loops.cpp:16
void clear_has_value()
Definition: map_entry_lite.h:280
const FieldDescriptor const OneofDescriptor value
Definition: descriptor.h:1717
static bool SkipField(io::CodedInputStream *input, uint32 tag)
Definition: wire_format_lite.cc:121
void CheckTypeAndMergeFrom(const MessageLite &other)
Definition: map_entry_lite.h:125
def Merge(text, message, allow_unknown_extension=False, allow_field_number=False)
Definition: text_format.py:349
IsInitialized
Definition: python_message.py:1169
EGLAttrib * value
Definition: eglext.h:120
int Read(int fd, void *buf, unsigned int count)
Definition: gtest-port.h:1390
::google::protobuf::uint8 * SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const
Definition: map_entry_lite.h:183
Definition: message_lite.h:78
uint32_t uint32
Definition: port.h:135
Definition: __init__.py:1
Definition: map_type_handler.h:138
static WireType GetTagWireType(uint32 tag)
Definition: wire_format_lite.h:593
bool IsInitialized() const
Definition: map_entry_lite.h:201
static GOOGLE_ATTRIBUTE_ALWAYS_INLINE T * CreateMessage(::google::protobuf::Arena *arena)
Definition: arena.h:250
virtual const ValueMapEntryAccessorType & value() const
Definition: map_entry_lite.h:105
GOOGLE_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTag()
Definition: coded_stream.h:936
~MapEntryLite()
Definition: map_entry_lite.h:92
Definition: arena.h:218
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:1613
Definition: document.h:393
int SpaceUsed() const
Definition: map_entry_lite.h:215
ValueMapEntryAccessorType * mutable_value()
Definition: map_entry_lite.h:114
#define GOOGLE_CHECK(EXPRESSION)
Definition: logging.h:151
typename detail::has_key_impl< L, K >::type has_key
Definition: Brigand.h:2219
virtual const KeyMapEntryAccessorType & key() const
Definition: map_entry_lite.h:102
#define NULL
Definition: common_types.h:41
Key
Definition: keyboard.h:10
GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool ExpectTag(uint32 expected)
Definition: coded_stream.h:999
void set_has_key()
Definition: map_entry_lite.h:275
void MergeFrom(const MapEntryLite &from)
Definition: map_entry_lite.h:222
Definition: gflags_completions.h:115
int ByteSize() const
Definition: map_entry_lite.h:171
ANGLE_EXPORT EGLBoolean EGLAPIENTRY Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
Definition: entry_points_egl.cpp:48
string input
Definition: tokenizer_unittest.cc:198
ByteSize
Definition: python_message.py:1040
Definition: map_entry.h:112
Definition: coded_stream.h:665
CFArrayRef CFTypeRef key
Definition: AVFoundationCFSoftLinking.h:129
#define GOOGLE_FALLTHROUGH_INTENDED
Definition: port.h:239
Definition: coded_stream.h:159
MergeFrom
Definition: python_message.py:1259
Definition: map_entry_lite.h:63