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 defines the RepeatedFieldRef class template used to access
32// repeated fields with protobuf reflection API.
33#ifndef GOOGLE_PROTOBUF_REFLECTION_H__
34#define GOOGLE_PROTOBUF_REFLECTION_H__
35
36#include <memory>
37#ifndef _SHARED_PTR_H
38#include <google/protobuf/stubs/shared_ptr.h>
39#endif
40
41#include <google/protobuf/message.h>
42#include <google/protobuf/generated_enum_util.h>
43
44namespace google {
45namespace protobuf {
46namespace internal {
47template<typename T, typename Enable = void>
48struct RefTypeTraits;
49}  // namespace internal
50
51template<typename T>
52RepeatedFieldRef<T> Reflection::GetRepeatedFieldRef(
53    const Message& message, const FieldDescriptor* field) const {
54  return RepeatedFieldRef<T>(message, field);
55}
56
57template<typename T>
58MutableRepeatedFieldRef<T> Reflection::GetMutableRepeatedFieldRef(
59    Message* message, const FieldDescriptor* field) const {
60  return MutableRepeatedFieldRef<T>(message, field);
61}
62
63// RepeatedFieldRef definition for non-message types.
64template<typename T>
65class RepeatedFieldRef<
66    T, typename internal::enable_if<!internal::is_base_of<Message, T>::value>::type> {
67  typedef typename internal::RefTypeTraits<T>::iterator IteratorType;
68  typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
69
70 public:
71  bool empty() const {
72    return accessor_->IsEmpty(data_);
73  }
74  int size() const {
75    return accessor_->Size(data_);
76  }
77  T Get(int index) const {
78    return accessor_->template Get<T>(data_, index);
79  }
80
81  typedef IteratorType iterator;
82  typedef IteratorType const_iterator;
83  iterator begin() const {
84    return iterator(data_, accessor_, true);
85  }
86  iterator end() const {
87    return iterator(data_, accessor_, false);
88  }
89
90 private:
91  friend class Reflection;
92  RepeatedFieldRef(
93      const Message& message,
94      const FieldDescriptor* field) {
95    const Reflection* reflection = message.GetReflection();
96    data_ = reflection->RepeatedFieldData(
97        const_cast<Message*>(&message), field,
98        internal::RefTypeTraits<T>::cpp_type, NULL);
99    accessor_ = reflection->RepeatedFieldAccessor(field);
100  }
101
102  const void* data_;
103  const AccessorType* accessor_;
104};
105
106// MutableRepeatedFieldRef definition for non-message types.
107template<typename T>
108class MutableRepeatedFieldRef<
109    T, typename internal::enable_if<!internal::is_base_of<Message, T>::value>::type> {
110  typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
111
112 public:
113  bool empty() const {
114    return accessor_->IsEmpty(data_);
115  }
116  int size() const {
117    return accessor_->Size(data_);
118  }
119  T Get(int index) const {
120    return accessor_->template Get<T>(data_, index);
121  }
122
123  void Set(int index, const T& value) const {
124    accessor_->template Set<T>(data_, index, value);
125  }
126  void Add(const T& value) const {
127    accessor_->template Add<T>(data_, value);
128  }
129  void RemoveLast() const {
130    accessor_->RemoveLast(data_);
131  }
132  void SwapElements(int index1, int index2) const {
133    accessor_->SwapElements(data_, index1, index2);
134  }
135  void Clear() const {
136    accessor_->Clear(data_);
137  }
138
139  void Swap(const MutableRepeatedFieldRef& other) const {
140    accessor_->Swap(data_, other.accessor_, other.data_);
141  }
142
143  template<typename Container>
144  void MergeFrom(const Container& container) const {
145    typedef typename Container::const_iterator Iterator;
146    for (Iterator it = container.begin(); it != container.end(); ++it) {
147      Add(*it);
148    }
149  }
150  template<typename Container>
151  void CopyFrom(const Container& container) const {
152    Clear();
153    MergeFrom(container);
154  }
155
156 private:
157  friend class Reflection;
158  MutableRepeatedFieldRef(
159      Message* message,
160      const FieldDescriptor* field) {
161    const Reflection* reflection = message->GetReflection();
162    data_ = reflection->RepeatedFieldData(
163        message, field, internal::RefTypeTraits<T>::cpp_type, NULL);
164    accessor_ = reflection->RepeatedFieldAccessor(field);
165  }
166
167  void* data_;
168  const AccessorType* accessor_;
169};
170
171// RepeatedFieldRef definition for message types.
172template<typename T>
173class RepeatedFieldRef<
174    T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
175  typedef typename internal::RefTypeTraits<T>::iterator IteratorType;
176  typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
177
178 public:
179  bool empty() const {
180    return accessor_->IsEmpty(data_);
181  }
182  int size() const {
183    return accessor_->Size(data_);
184  }
185  // This method returns a reference to the underlying message object if it
186  // exists. If a message object doesn't exist (e.g., data stored in serialized
187  // form), scratch_space will be filled with the data and a reference to it
188  // will be returned.
189  //
190  // Example:
191  //   RepeatedFieldRef<Message> h = ...
192  //   unique_ptr<Message> scratch_space(h.NewMessage());
193  //   const Message& item = h.Get(index, scratch_space.get());
194  const T& Get(int index, T* scratch_space) const {
195    return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space));
196  }
197  // Create a new message of the same type as the messages stored in this
198  // repeated field. Caller takes ownership of the returned object.
199  T* NewMessage() const {
200    return static_cast<T*>(default_instance_->New());
201  }
202
203  typedef IteratorType iterator;
204  typedef IteratorType const_iterator;
205  iterator begin() const {
206    return iterator(data_, accessor_, true, NewMessage());
207  }
208  iterator end() const {
209    return iterator(data_, accessor_, false, NewMessage());
210  }
211
212 private:
213  friend class Reflection;
214  RepeatedFieldRef(
215      const Message& message,
216      const FieldDescriptor* field) {
217    const Reflection* reflection = message.GetReflection();
218    data_ = reflection->RepeatedFieldData(
219        const_cast<Message*>(&message), field,
220        internal::RefTypeTraits<T>::cpp_type,
221        internal::RefTypeTraits<T>::GetMessageFieldDescriptor());
222    accessor_ = reflection->RepeatedFieldAccessor(field);
223    default_instance_ =
224        reflection->GetMessageFactory()->GetPrototype(field->message_type());
225  }
226
227  const void* data_;
228  const AccessorType* accessor_;
229  const Message* default_instance_;
230};
231
232// MutableRepeatedFieldRef definition for message types.
233template<typename T>
234class MutableRepeatedFieldRef<
235    T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
236  typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
237
238 public:
239  bool empty() const {
240    return accessor_->IsEmpty(data_);
241  }
242  int size() const {
243    return accessor_->Size(data_);
244  }
245  // See comments for RepeatedFieldRef<Message>::Get()
246  const T& Get(int index, T* scratch_space) const {
247    return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space));
248  }
249  // Create a new message of the same type as the messages stored in this
250  // repeated field. Caller takes ownership of the returned object.
251  T* NewMessage() const {
252    return static_cast<T*>(default_instance_->New());
253  }
254
255  void Set(int index, const T& value) const {
256    accessor_->Set(data_, index, &value);
257  }
258  void Add(const T& value) const {
259    accessor_->Add(data_, &value);
260  }
261  void RemoveLast() const {
262    accessor_->RemoveLast(data_);
263  }
264  void SwapElements(int index1, int index2) const {
265    accessor_->SwapElements(data_, index1, index2);
266  }
267  void Clear() const {
268    accessor_->Clear(data_);
269  }
270
271  void Swap(const MutableRepeatedFieldRef& other) const {
272    accessor_->Swap(data_, other.accessor_, other.data_);
273  }
274
275  template<typename Container>
276  void MergeFrom(const Container& container) const {
277    typedef typename Container::const_iterator Iterator;
278    for (Iterator it = container.begin(); it != container.end(); ++it) {
279      Add(*it);
280    }
281  }
282  template<typename Container>
283  void CopyFrom(const Container& container) const {
284    Clear();
285    MergeFrom(container);
286  }
287
288 private:
289  friend class Reflection;
290  MutableRepeatedFieldRef(
291      Message* message,
292      const FieldDescriptor* field) {
293    const Reflection* reflection = message->GetReflection();
294    data_ = reflection->RepeatedFieldData(
295        message, field, internal::RefTypeTraits<T>::cpp_type,
296        internal::RefTypeTraits<T>::GetMessageFieldDescriptor());
297    accessor_ = reflection->RepeatedFieldAccessor(field);
298    default_instance_ =
299        reflection->GetMessageFactory()->GetPrototype(field->message_type());
300  }
301
302  void* data_;
303  const AccessorType* accessor_;
304  const Message* default_instance_;
305};
306
307namespace internal {
308// Interfaces used to implement reflection RepeatedFieldRef API.
309// Reflection::GetRepeatedAccessor() should return a pointer to an singleton
310// object that implements the below interface.
311//
312// This interface passes/returns values using void pointers. The actual type
313// of the value depends on the field's cpp_type. Following is a mapping from
314// cpp_type to the type that should be used in this interface:
315//
316//   field->cpp_type()      T                Actual type of void*
317//   CPPTYPE_INT32        int32                   int32
318//   CPPTYPE_UINT32       uint32                  uint32
319//   CPPTYPE_INT64        int64                   int64
320//   CPPTYPE_UINT64       uint64                  uint64
321//   CPPTYPE_DOUBLE       double                  double
322//   CPPTYPE_FLOAT        float                   float
323//   CPPTYPE_BOOL         bool                    bool
324//   CPPTYPE_ENUM         generated enum type     int32
325//   CPPTYPE_STRING       string                  string
326//   CPPTYPE_MESSAGE      generated message type  google::protobuf::Message
327//                        or google::protobuf::Message
328//
329// Note that for enums we use int32 in the interface.
330//
331// You can map from T to the actual type using RefTypeTraits:
332//   typedef RefTypeTraits<T>::AccessorValueType ActualType;
333class LIBPROTOBUF_EXPORT RepeatedFieldAccessor {
334 public:
335  // Typedefs for clarity.
336  typedef void Field;
337  typedef void Value;
338  typedef void Iterator;
339
340  virtual ~RepeatedFieldAccessor();
341  virtual bool IsEmpty(const Field* data) const = 0;
342  virtual int Size(const Field* data) const = 0;
343  // Depends on the underlying representation of the repeated field, this
344  // method can return a pointer to the underlying object if such an object
345  // exists, or fill the data into scratch_space and return scratch_space.
346  // Callers of this method must ensure scratch_space is a valid pointer
347  // to a mutable object of the correct type.
348  virtual const Value* Get(
349      const Field* data, int index, Value* scratch_space) const = 0;
350
351  virtual void Clear(Field* data) const = 0;
352  virtual void Set(Field* data, int index, const Value* value) const = 0;
353  virtual void Add(Field* data, const Value* value) const = 0;
354  virtual void RemoveLast(Field* data) const = 0;
355  virtual void SwapElements(Field* data, int index1, int index2) const = 0;
356  virtual void Swap(Field* data, const RepeatedFieldAccessor* other_mutator,
357                    Field* other_data) const = 0;
358
359  // Create an iterator that points at the begining of the repeated field.
360  virtual Iterator* BeginIterator(const Field* data) const = 0;
361  // Create an iterator that points at the end of the repeated field.
362  virtual Iterator* EndIterator(const Field* data) const = 0;
363  // Make a copy of an iterator and return the new copy.
364  virtual Iterator* CopyIterator(const Field* data,
365                                 const Iterator* iterator) const = 0;
366  // Move an iterator to point to the next element.
367  virtual Iterator* AdvanceIterator(const Field* data,
368                                    Iterator* iterator) const = 0;
369  // Compare whether two iterators point to the same element.
370  virtual bool EqualsIterator(const Field* data, const Iterator* a,
371                              const Iterator* b) const = 0;
372  // Delete an iterator created by BeginIterator(), EndIterator() and
373  // CopyIterator().
374  virtual void DeleteIterator(const Field* data, Iterator* iterator) const = 0;
375  // Like Get() but for iterators.
376  virtual const Value* GetIteratorValue(const Field* data,
377                                        const Iterator* iterator,
378                                        Value* scratch_space) const = 0;
379
380  // Templated methods that make using this interface easier for non-message
381  // types.
382  template<typename T>
383  T Get(const Field* data, int index) const {
384    typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
385    ActualType scratch_space;
386    return static_cast<T>(
387        *reinterpret_cast<const ActualType*>(
388            Get(data, index, static_cast<Value*>(&scratch_space))));
389  }
390
391  template<typename T, typename ValueType>
392  void Set(Field* data, int index, const ValueType& value) const {
393    typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
394    // In this RepeatedFieldAccessor interface we pass/return data using
395    // raw pointers. Type of the data these raw pointers point to should
396    // be ActualType. Here we have a ValueType object and want a ActualType
397    // pointer. We can't cast a ValueType pointer to an ActualType pointer
398    // directly because their type might be different (for enums ValueType
399    // may be a generated enum type while ActualType is int32). To be safe
400    // we make a copy to get a temporary ActualType object and use it.
401    ActualType tmp = static_cast<ActualType>(value);
402    Set(data, index, static_cast<const Value*>(&tmp));
403  }
404
405  template<typename T, typename ValueType>
406  void Add(Field* data, const ValueType& value) const {
407    typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
408    // In this RepeatedFieldAccessor interface we pass/return data using
409    // raw pointers. Type of the data these raw pointers point to should
410    // be ActualType. Here we have a ValueType object and want a ActualType
411    // pointer. We can't cast a ValueType pointer to an ActualType pointer
412    // directly because their type might be different (for enums ValueType
413    // may be a generated enum type while ActualType is int32). To be safe
414    // we make a copy to get a temporary ActualType object and use it.
415    ActualType tmp = static_cast<ActualType>(value);
416    Add(data, static_cast<const Value*>(&tmp));
417  }
418};
419
420// Implement (Mutable)RepeatedFieldRef::iterator
421template<typename T>
422class RepeatedFieldRefIterator
423    : public std::iterator<std::forward_iterator_tag, T> {
424  typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType;
425  typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType;
426  typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType;
427
428 public:
429  // Constructor for non-message fields.
430  RepeatedFieldRefIterator(const void* data,
431                           const RepeatedFieldAccessor* accessor,
432                           bool begin)
433      : data_(data), accessor_(accessor),
434        iterator_(begin ? accessor->BeginIterator(data) :
435                          accessor->EndIterator(data)),
436        scratch_space_(new AccessorValueType) {
437  }
438  // Constructor for message fields.
439  RepeatedFieldRefIterator(const void* data,
440                           const RepeatedFieldAccessor* accessor,
441                           bool begin,
442                           AccessorValueType* scratch_space)
443      : data_(data), accessor_(accessor),
444        iterator_(begin ? accessor->BeginIterator(data) :
445                          accessor->EndIterator(data)),
446        scratch_space_(scratch_space) {
447  }
448  ~RepeatedFieldRefIterator() {
449    accessor_->DeleteIterator(data_, iterator_);
450  }
451  RepeatedFieldRefIterator operator++(int) {
452    RepeatedFieldRefIterator tmp(*this);
453    iterator_ = accessor_->AdvanceIterator(data_, iterator_);
454    return tmp;
455  }
456  RepeatedFieldRefIterator& operator++() {
457    iterator_ = accessor_->AdvanceIterator(data_, iterator_);
458    return *this;
459  }
460  IteratorValueType operator*() const {
461    return static_cast<IteratorValueType>(
462        *static_cast<const AccessorValueType*>(
463            accessor_->GetIteratorValue(
464                data_, iterator_, scratch_space_.get())));
465  }
466  IteratorPointerType operator->() const {
467    return static_cast<IteratorPointerType>(
468        accessor_->GetIteratorValue(
469            data_, iterator_, scratch_space_.get()));
470  }
471  bool operator!=(const RepeatedFieldRefIterator& other) const {
472    assert(data_ == other.data_);
473    assert(accessor_ == other.accessor_);
474    return !accessor_->EqualsIterator(data_, iterator_, other.iterator_);
475  }
476  bool operator==(const RepeatedFieldRefIterator& other) const {
477    return !this->operator!=(other);
478  }
479
480  RepeatedFieldRefIterator(const RepeatedFieldRefIterator& other)
481      : data_(other.data_), accessor_(other.accessor_),
482        iterator_(accessor_->CopyIterator(data_, other.iterator_)) {
483  }
484  RepeatedFieldRefIterator& operator=(const RepeatedFieldRefIterator& other) {
485    if (this != &other) {
486      accessor_->DeleteIterator(data_, iterator_);
487      data_ = other.data_;
488      accessor_ = other.accessor_;
489      iterator_ = accessor_->CopyIterator(data_, other.iterator_);
490    }
491    return *this;
492  }
493
494 protected:
495  const void* data_;
496  const RepeatedFieldAccessor* accessor_;
497  void* iterator_;
498  google::protobuf::scoped_ptr<AccessorValueType> scratch_space_;
499};
500
501// TypeTraits that maps the type parameter T of RepeatedFieldRef or
502// MutableRepeatedFieldRef to corresponding iterator type,
503// RepeatedFieldAccessor type, etc.
504template<typename T>
505struct PrimitiveTraits {
506  static const bool is_primitive = false;
507};
508#define DEFINE_PRIMITIVE(TYPE, type) \
509    template<> struct PrimitiveTraits<type> { \
510      static const bool is_primitive = true; \
511      static const FieldDescriptor::CppType cpp_type = \
512          FieldDescriptor::CPPTYPE_ ## TYPE; \
513    };
514DEFINE_PRIMITIVE(INT32, int32)
515DEFINE_PRIMITIVE(UINT32, uint32)
516DEFINE_PRIMITIVE(INT64, int64)
517DEFINE_PRIMITIVE(UINT64, uint64)
518DEFINE_PRIMITIVE(FLOAT, float)
519DEFINE_PRIMITIVE(DOUBLE, double)
520DEFINE_PRIMITIVE(BOOL, bool)
521#undef DEFINE_PRIMITIVE
522
523template<typename T>
524struct RefTypeTraits<
525    T, typename internal::enable_if<PrimitiveTraits<T>::is_primitive>::type> {
526  typedef RepeatedFieldRefIterator<T> iterator;
527  typedef RepeatedFieldAccessor AccessorType;
528  typedef T AccessorValueType;
529  typedef T IteratorValueType;
530  typedef T* IteratorPointerType;
531  static const FieldDescriptor::CppType cpp_type =
532      PrimitiveTraits<T>::cpp_type;
533  static const Descriptor* GetMessageFieldDescriptor() {
534    return NULL;
535  }
536};
537
538template<typename T>
539struct RefTypeTraits<
540    T, typename internal::enable_if<is_proto_enum<T>::value>::type> {
541  typedef RepeatedFieldRefIterator<T> iterator;
542  typedef RepeatedFieldAccessor AccessorType;
543  // We use int32 for repeated enums in RepeatedFieldAccessor.
544  typedef int32 AccessorValueType;
545  typedef T IteratorValueType;
546  typedef int32* IteratorPointerType;
547  static const FieldDescriptor::CppType cpp_type =
548      FieldDescriptor::CPPTYPE_ENUM;
549  static const Descriptor* GetMessageFieldDescriptor() {
550    return NULL;
551  }
552};
553
554template<typename T>
555struct RefTypeTraits<
556    T, typename internal::enable_if< ::google::protobuf::internal::is_same<string, T>::value>::type> {
557  typedef RepeatedFieldRefIterator<T> iterator;
558  typedef RepeatedFieldAccessor AccessorType;
559  typedef string AccessorValueType;
560  typedef string IteratorValueType;
561  typedef string* IteratorPointerType;
562  static const FieldDescriptor::CppType cpp_type =
563      FieldDescriptor::CPPTYPE_STRING;
564  static const Descriptor* GetMessageFieldDescriptor() {
565    return NULL;
566  }
567};
568
569template<typename T>
570struct MessageDescriptorGetter {
571  static const Descriptor* get() {
572    return T::default_instance().GetDescriptor();
573  }
574};
575template<>
576struct MessageDescriptorGetter<Message> {
577  static const Descriptor* get() {
578    return NULL;
579  }
580};
581
582template<typename T>
583struct RefTypeTraits<
584    T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
585  typedef RepeatedFieldRefIterator<T> iterator;
586  typedef RepeatedFieldAccessor AccessorType;
587  typedef Message AccessorValueType;
588  typedef const T& IteratorValueType;
589  typedef const T* IteratorPointerType;
590  static const FieldDescriptor::CppType cpp_type =
591      FieldDescriptor::CPPTYPE_MESSAGE;
592  static const Descriptor* GetMessageFieldDescriptor() {
593    return MessageDescriptorGetter<T>::get();
594  }
595};
596}  // namespace internal
597}  // namespace protobuf
598}  // namespace google
599
600#endif  // GOOGLE_PROTOBUF_REFLECTION_H__
601