webkit  2cdf99a9e3038c7e01b3c37e8ad903ecbe5eecf1
https://github.com/WebKit/webkit
repeated_field_reflection.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 // This header file is protobuf internal. Users should not include this
32 // file directly.
33 #ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_REFLECTION_H__
34 #define GOOGLE_PROTOBUF_REPEATED_FIELD_REFLECTION_H__
35 
36 #include <memory>
37 #ifndef _SHARED_PTR_H
39 #endif
40 
42 
43 namespace google {
44 namespace protobuf {
45 namespace internal {
46 // Interfaces used to implement reflection RepeatedFieldRef API.
47 // Reflection::GetRepeatedAccessor() should return a pointer to an singleton
48 // object that implements the below interface.
49 //
50 // This interface passes/returns values using void pointers. The actual type
51 // of the value depends on the field's cpp_type. Following is a mapping from
52 // cpp_type to the type that should be used in this interface:
53 //
54 // field->cpp_type() T Actual type of void*
55 // CPPTYPE_INT32 int32 int32
56 // CPPTYPE_UINT32 uint32 uint32
57 // CPPTYPE_INT64 int64 int64
58 // CPPTYPE_UINT64 uint64 uint64
59 // CPPTYPE_DOUBLE double double
60 // CPPTYPE_FLOAT float float
61 // CPPTYPE_BOOL bool bool
62 // CPPTYPE_ENUM generated enum type int32
63 // CPPTYPE_STRING string string
64 // CPPTYPE_MESSAGE generated message type google::protobuf::Message
65 // or google::protobuf::Message
66 //
67 // Note that for enums we use int32 in the interface.
68 //
69 // You can map from T to the actual type using RefTypeTraits:
70 // typedef RefTypeTraits<T>::AccessorValueType ActualType;
71 class LIBPROTOBUF_EXPORT RepeatedFieldAccessor {
72  public:
73  // Typedefs for clarity.
74  typedef void Field;
75  typedef void Value;
76  typedef void Iterator;
77 
78  virtual ~RepeatedFieldAccessor();
79  virtual bool IsEmpty(const Field* data) const = 0;
80  virtual int Size(const Field* data) const = 0;
81  // Depends on the underlying representation of the repeated field, this
82  // method can return a pointer to the underlying object if such an object
83  // exists, or fill the data into scratch_space and return scratch_space.
84  // Callers of this method must ensure scratch_space is a valid pointer
85  // to a mutable object of the correct type.
86  virtual const Value* Get(
87  const Field* data, int index, Value* scratch_space) const = 0;
88 
89  virtual void Clear(Field* data) const = 0;
90  virtual void Set(Field* data, int index, const Value* value) const = 0;
91  virtual void Add(Field* data, const Value* value) const = 0;
92  virtual void RemoveLast(Field* data) const = 0;
93  virtual void SwapElements(Field* data, int index1, int index2) const = 0;
94  virtual void Swap(Field* data, const RepeatedFieldAccessor* other_mutator,
95  Field* other_data) const = 0;
96 
97  // Create an iterator that points at the begining of the repeated field.
98  virtual Iterator* BeginIterator(const Field* data) const = 0;
99  // Create an iterator that points at the end of the repeated field.
100  virtual Iterator* EndIterator(const Field* data) const = 0;
101  // Make a copy of an iterator and return the new copy.
102  virtual Iterator* CopyIterator(const Field* data,
103  const Iterator* iterator) const = 0;
104  // Move an iterator to point to the next element.
105  virtual Iterator* AdvanceIterator(const Field* data,
106  Iterator* iterator) const = 0;
107  // Compare whether two iterators point to the same element.
108  virtual bool EqualsIterator(const Field* data, const Iterator* a,
109  const Iterator* b) const = 0;
110  // Delete an iterator created by BeginIterator(), EndIterator() and
111  // CopyIterator().
112  virtual void DeleteIterator(const Field* data, Iterator* iterator) const = 0;
113  // Like Get() but for iterators.
114  virtual const Value* GetIteratorValue(const Field* data,
115  const Iterator* iterator,
116  Value* scratch_space) const = 0;
117 
118  // Templated methods that make using this interface easier for non-message
119  // types.
120  template<typename T>
121  T Get(const Field* data, int index) const {
122  typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
123  ActualType scratch_space;
124  return static_cast<T>(
125  *reinterpret_cast<const ActualType*>(
126  Get(data, index, static_cast<Value*>(&scratch_space))));
127  }
128 
129  template<typename T, typename ValueType>
130  void Set(Field* data, int index, const ValueType& value) const {
131  typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
132  // In this RepeatedFieldAccessor interface we pass/return data using
133  // raw pointers. Type of the data these raw pointers point to should
134  // be ActualType. Here we have a ValueType object and want a ActualType
135  // pointer. We can't cast a ValueType pointer to an ActualType pointer
136  // directly because their type might be different (for enums ValueType
137  // may be a generated enum type while ActualType is int32). To be safe
138  // we make a copy to get a temporary ActualType object and use it.
139  ActualType tmp = static_cast<ActualType>(value);
140  Set(data, index, static_cast<const Value*>(&tmp));
141  }
142 
143  template<typename T, typename ValueType>
144  void Add(Field* data, const ValueType& value) const {
145  typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
146  // In this RepeatedFieldAccessor interface we pass/return data using
147  // raw pointers. Type of the data these raw pointers point to should
148  // be ActualType. Here we have a ValueType object and want a ActualType
149  // pointer. We can't cast a ValueType pointer to an ActualType pointer
150  // directly because their type might be different (for enums ValueType
151  // may be a generated enum type while ActualType is int32). To be safe
152  // we make a copy to get a temporary ActualType object and use it.
153  ActualType tmp = static_cast<ActualType>(value);
154  Add(data, static_cast<const Value*>(&tmp));
155  }
156 };
157 
158 // Implement (Mutable)RepeatedFieldRef::iterator
159 template<typename T>
161  : public std::iterator<std::forward_iterator_tag, T> {
162  typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType;
163  typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType;
164  typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType;
165 
166  public:
167  // Constructor for non-message fields.
169  const RepeatedFieldAccessor* accessor,
170  bool begin)
171  : data_(data), accessor_(accessor),
172  iterator_(begin ? accessor->BeginIterator(data) :
173  accessor->EndIterator(data)),
174  scratch_space_(new AccessorValueType) {
175  }
176  // Constructor for message fields.
178  const RepeatedFieldAccessor* accessor,
179  bool begin,
180  AccessorValueType* scratch_space)
181  : data_(data), accessor_(accessor),
182  iterator_(begin ? accessor->BeginIterator(data) :
183  accessor->EndIterator(data)),
184  scratch_space_(scratch_space) {
185  }
187  accessor_->DeleteIterator(data_, iterator_);
188  }
190  RepeatedFieldRefIterator tmp(*this);
191  iterator_ = accessor_->AdvanceIterator(data_, iterator_);
192  return tmp;
193  }
195  iterator_ = accessor_->AdvanceIterator(data_, iterator_);
196  return *this;
197  }
198  IteratorValueType operator*() const {
199  return static_cast<IteratorValueType>(
200  *static_cast<const AccessorValueType*>(
201  accessor_->GetIteratorValue(
202  data_, iterator_, scratch_space_.get())));
203  }
204  IteratorPointerType operator->() const {
205  return static_cast<IteratorPointerType>(
206  accessor_->GetIteratorValue(
207  data_, iterator_, scratch_space_.get()));
208  }
209  bool operator!=(const RepeatedFieldRefIterator& other) const {
210  assert(data_ == other.data_);
211  assert(accessor_ == other.accessor_);
212  return !accessor_->EqualsIterator(data_, iterator_, other.iterator_);
213  }
214  bool operator==(const RepeatedFieldRefIterator& other) const {
215  return !this->operator!=(other);
216  }
217 
219  : data_(other.data_), accessor_(other.accessor_),
220  iterator_(accessor_->CopyIterator(data_, other.iterator_)) {
221  }
223  if (this != &other) {
224  accessor_->DeleteIterator(data_, iterator_);
225  data_ = other.data_;
226  accessor_ = other.accessor_;
227  iterator_ = accessor_->CopyIterator(data_, other.iterator_);
228  }
229  return *this;
230  }
231 
232  protected:
233  const void* data_;
234  const RepeatedFieldAccessor* accessor_;
235  void* iterator_;
237 };
238 
239 // TypeTraits that maps the type parameter T of RepeatedFieldRef or
240 // MutableRepeatedFieldRef to corresponding iterator type,
241 // RepeatedFieldAccessor type, etc.
242 template<typename T>
243 struct PrimitiveTraits {
244  static const bool is_primitive = false;
245 };
246 #define DEFINE_PRIMITIVE(TYPE, type) \
247  template<> struct PrimitiveTraits<type> { \
248  static const bool is_primitive = true; \
249  static const FieldDescriptor::CppType cpp_type = \
250  FieldDescriptor::CPPTYPE_ ## TYPE; \
251  };
252 DEFINE_PRIMITIVE(INT32, int32)
253 DEFINE_PRIMITIVE(UINT32, uint32)
254 DEFINE_PRIMITIVE(INT64, int64)
255 DEFINE_PRIMITIVE(UINT64, uint64)
256 DEFINE_PRIMITIVE(FLOAT, float)
257 DEFINE_PRIMITIVE(DOUBLE, double)
258 DEFINE_PRIMITIVE(BOOL, bool)
259 #undef DEFINE_PRIMITIVE
260 
261 template<typename T>
262 struct RefTypeTraits<
263  T, typename internal::enable_if<PrimitiveTraits<T>::is_primitive>::type> {
269  static const FieldDescriptor::CppType cpp_type =
272  return NULL;
273  }
274 };
275 
276 template<typename T>
277 struct RefTypeTraits<
278  T, typename internal::enable_if<is_proto_enum<T>::value>::type> {
281  // We use int32 for repeated enums in RepeatedFieldAccessor.
283  typedef T IteratorValueType;
285  static const FieldDescriptor::CppType cpp_type =
288  return NULL;
289  }
290 };
291 
292 template<typename T>
294  T, typename internal::enable_if<internal::is_same<string, T>::value>::type> {
297  typedef string AccessorValueType;
298  typedef string IteratorValueType;
299  typedef string* IteratorPointerType;
303  return NULL;
304  }
305 };
306 
307 template<typename T>
309  static const Descriptor* get() {
310  return T::default_instance().GetDescriptor();
311  }
312 };
313 template<>
314 struct MessageDescriptorGetter<Message> {
315  static const Descriptor* get() {
316  return NULL;
317  }
318 };
319 
320 template<typename T>
321 struct RefTypeTraits<
322  T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
325  typedef Message AccessorValueType;
326  typedef const T& IteratorValueType;
327  typedef const T* IteratorPointerType;
328  static const FieldDescriptor::CppType cpp_type =
332  }
333 };
334 } // namespace internal
335 } // namespace protobuf
336 } // namespace google
337 #endif // GOOGLE_PROTOBUF_REPEATED_FIELD_REFLECTION_H__
void Add(Field *data, const ValueType &value) const
Definition: repeated_field_reflection.h:144
BOOL
Definition: PlatformScreenIOS.mm:46
void Set(Field *data, int index, const ValueType &value) const
Definition: repeated_field_reflection.h:130
IteratorValueType operator*() const
Definition: repeated_field_reflection.h:198
Definition: reflection.h:505
RepeatedFieldRefIterator & operator++()
Definition: repeated_field_reflection.h:194
CppType
Definition: descriptor.h:475
uint32_t Size
Definition: wav_header.cc:30
static const Descriptor * GetMessageFieldDescriptor()
Definition: repeated_field_reflection.h:287
Definition: descriptor.h:172
void Iterator
Definition: repeated_field_reflection.h:76
bool operator!=(const RepeatedFieldRefIterator &other) const
Definition: repeated_field_reflection.h:209
uint64_t uint64
Definition: angle_config.h:30
int64_t int64
Definition: angle_config.h:29
void * iterator_
Definition: reflection.h:497
const FieldDescriptor const OneofDescriptor value
Definition: descriptor.h:1717
int32_t int32
Definition: port.h:130
TestSubObjConstructor T
Definition: TestTypedefs.idl:84
void Field
Definition: repeated_field_reflection.h:74
~RepeatedFieldRefIterator()
Definition: repeated_field_reflection.h:186
GLuint index
Definition: gl2.h:383
EGLAttrib * value
Definition: eglext.h:120
ValueType
Definition: WebKitPluginHostTypes.h:51
RepeatedFieldRefIterator(const void *data, const RepeatedFieldAccessor *accessor, bool begin)
Definition: repeated_field_reflection.h:168
unrestricted float DOUBLE
Definition: TestTypedefs.idl:71
Definition: __init__.py:1
GLboolean GLboolean GLboolean GLboolean a
Definition: gl2ext.h:306
Definition: type_traits.h:88
bool operator==(const RepeatedFieldRefIterator &other) const
Definition: repeated_field_reflection.h:214
IteratorPointerType operator->() const
Definition: repeated_field_reflection.h:204
RepeatedFieldRefIterator(const void *data, const RepeatedFieldAccessor *accessor, bool begin, AccessorValueType *scratch_space)
Definition: repeated_field_reflection.h:177
const void * data_
Definition: reflection.h:495
void Value
Definition: repeated_field_reflection.h:75
static const Descriptor * get()
Definition: reflection.h:571
EGLenum type
Definition: eglext.h:63
Definition: scoped_ptr.h:48
EGLStreamKHR EGLint EGLint EGLint const void * data
Definition: eglext.h:984
Definition: document.h:393
FieldDescriptor::CppType cpp_type(FieldType type)
Definition: extension_set_heavy.cc:128
#define NULL
Definition: common_types.h:41
RepeatedFieldRefIterator & operator=(const RepeatedFieldRefIterator &other)
Definition: repeated_field_reflection.h:222
RepeatedFieldRefIterator< T > iterator
Definition: repeated_field_reflection.h:279
#define LIBPROTOBUF_EXPORT
Definition: port.h:97
uint32_t uint32
Definition: angle_config.h:28
GLboolean GLboolean GLboolean b
Definition: gl2ext.h:306
virtual Iterator * CopyIterator(const Field *data, const Iterator *iterator) const =0
Definition: gflags_completions.h:115
new
Definition: env.py:34
RepeatedFieldRefIterator(const RepeatedFieldRefIterator &other)
Definition: repeated_field_reflection.h:218
#define DEFINE_PRIMITIVE(TYPE, type)
Definition: repeated_field_reflection.h:246
const RepeatedFieldAccessor * accessor_
Definition: reflection.h:496
bool operator!=(const uint128 &lhs, const uint128 &rhs)
Definition: int128.h:140
RepeatedFieldRefIterator operator++(int)
Definition: repeated_field_reflection.h:189
Definition: GetPutInfo.h:232
Definition: reflection.h:48
int32_t int32
Definition: angle_config.h:27
T Get(const Field *data, int index) const
Definition: repeated_field_reflection.h:121