text: // Protocol Buffers - Google's data interchange format
  // Copyright 2008 Google Inc.  All rights reserved.
  // https://developers.google.com/protocol-buffers/
  //
  // Redistribution and use in source and binary forms, with or without
  // modification, are permitted provided that the following conditions are
  // met:
  //
  //     * Redistributions of source code must retain the above copyright
  // notice, this list of conditions and the following disclaimer.
  //     * Redistributions in binary form must reproduce the above
  // copyright notice, this list of conditions and the following disclaimer
  // in the documentation and/or other materials provided with the
  // distribution.
  //     * Neither the name of Google Inc. nor the names of its
  // contributors may be used to endorse or promote products derived from
  // this software without specific prior written permission.
  //
  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
  // This header defines the RepeatedFieldRef class template used to access
  // repeated fields with protobuf reflection API.
  #ifndef GOOGLE_PROTOBUF_REFLECTION_H__
  #define GOOGLE_PROTOBUF_REFLECTION_H__
  
  #include <memory>
  #ifndef _SHARED_PTR_H
  #include <protobuf/stubs/shared_ptr.h>
  #endif
  
  #include <protobuf/message.h>
  #include <protobuf/generated_enum_util.h>
  
  namespace google {
  namespace protobuf {
  namespace internal {
  template<typename T, typename Enable = void>
  struct RefTypeTraits;
  }  // namespace internal
  
  template<typename T>
  RepeatedFieldRef<T> Reflection::GetRepeatedFieldRef(
      const Message& message, const FieldDescriptor* field) const {
    return RepeatedFieldRef<T>(message, field);
  }
  
  template<typename T>
  MutableRepeatedFieldRef<T> Reflection::GetMutableRepeatedFieldRef(
      Message* message, const FieldDescriptor* field) const {
    return MutableRepeatedFieldRef<T>(message, field);
  }
  
  // RepeatedFieldRef definition for non-message types.
  template<typename T>
  class RepeatedFieldRef<
      T, typename internal::enable_if<!internal::is_base_of<Message, T>::value>::type> {
    typedef typename internal::RefTypeTraits<T>::iterator IteratorType;
    typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
  
   public:
    bool empty() const {
      return accessor_->IsEmpty(data_);
    }
    int size() const {
      return accessor_->Size(data_);
    }
    T Get(int index) const {
      return accessor_->template Get<T>(data_, index);
    }
  
    typedef IteratorType iterator;
    typedef IteratorType const_iterator;
    typedef T value_type;
    typedef T& reference;
    typedef const T& const_reference;
    typedef int size_type;
    typedef ptrdiff_t difference_type;
  
    iterator begin() const {
      return iterator(data_, accessor_, true);
    }
    iterator end() const {
      return iterator(data_, accessor_, false);
    }
  
   private:
    friend class Reflection;
    RepeatedFieldRef(
        const Message& message,
        const FieldDescriptor* field) {
      const Reflection* reflection = message.GetReflection();
      data_ = reflection->RepeatedFieldData(
          const_cast<Message*>(&message), field,
          internal::RefTypeTraits<T>::cpp_type, NULL);
      accessor_ = reflection->RepeatedFieldAccessor(field);
    }
  
    const void* data_;
    const AccessorType* accessor_;
  };
  
  // MutableRepeatedFieldRef definition for non-message types.
  template<typename T>
  class MutableRepeatedFieldRef<
      T, typename internal::enable_if<!internal::is_base_of<Message, T>::value>::type> {
    typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
  
   public:
    bool empty() const {
      return accessor_->IsEmpty(data_);
    }
    int size() const {
      return accessor_->Size(data_);
    }
    T Get(int index) const {
      return accessor_->template Get<T>(data_, index);
    }
  
    void Set(int index, const T& value) const {
      accessor_->template Set<T>(data_, index, value);
    }
    void Add(const T& value) const {
      accessor_->template Add<T>(data_, value);
    }
    void RemoveLast() const {
      accessor_->RemoveLast(data_);
    }
    void SwapElements(int index1, int index2) const {
      accessor_->SwapElements(data_, index1, index2);
    }
    void Clear() const {
      accessor_->Clear(data_);
    }
  
    void Swap(const MutableRepeatedFieldRef& other) const {
      accessor_->Swap(data_, other.accessor_, other.data_);
    }
  
    template<typename Container>
    void MergeFrom(const Container& container) const {
      typedef typename Container::const_iterator Iterator;
      for (Iterator it = container.begin(); it != container.end(); ++it) {
        Add(*it);
      }
    }
    template<typename Container>
    void CopyFrom(const Container& container) const {
      Clear();
      MergeFrom(container);
    }
  
   private:
    friend class Reflection;
    MutableRepeatedFieldRef(
        Message* message,
        const FieldDescriptor* field) {
      const Reflection* reflection = message->GetReflection();
      data_ = reflection->RepeatedFieldData(
          message, field, internal::RefTypeTraits<T>::cpp_type, NULL);
      accessor_ = reflection->RepeatedFieldAccessor(field);
    }
  
    void* data_;
    const AccessorType* accessor_;
  };
  
  // RepeatedFieldRef definition for message types.
  template<typename T>
  class RepeatedFieldRef<
      T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
    typedef typename internal::RefTypeTraits<T>::iterator IteratorType;
    typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
  
   public:
    bool empty() const {
      return accessor_->IsEmpty(data_);
    }
    int size() const {
      return accessor_->Size(data_);
    }
    // This method returns a reference to the underlying message object if it
    // exists. If a message object doesn't exist (e.g., data stored in serialized
    // form), scratch_space will be filled with the data and a reference to it
    // will be returned.
    //
    // Example:
    //   RepeatedFieldRef<Message> h = ...
    //   unique_ptr<Message> scratch_space(h.NewMessage());
    //   const Message& item = h.Get(index, scratch_space.get());
    const T& Get(int index, T* scratch_space) const {
      return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space));
    }
    // Create a new message of the same type as the messages stored in this
    // repeated field. Caller takes ownership of the returned object.
    T* NewMessage() const {
      return static_cast<T*>(default_instance_->New());
    }
  
    typedef IteratorType iterator;
    typedef IteratorType const_iterator;
    typedef T value_type;
    typedef T& reference;
    typedef const T& const_reference;
    typedef int size_type;
    typedef ptrdiff_t difference_type;
  
    iterator begin() const {
      return iterator(data_, accessor_, true, NewMessage());
    }
    iterator end() const {
      // The end iterator must not be dereferenced, no need for scratch space.
      return iterator(data_, accessor_, false, NULL);
    }
  
   private:
    friend class Reflection;
    RepeatedFieldRef(
        const Message& message,
        const FieldDescriptor* field) {
      const Reflection* reflection = message.GetReflection();
      data_ = reflection->RepeatedFieldData(
          const_cast<Message*>(&message), field,
          internal::RefTypeTraits<T>::cpp_type,
          internal::RefTypeTraits<T>::GetMessageFieldDescriptor());
      accessor_ = reflection->RepeatedFieldAccessor(field);
      default_instance_ =
          reflection->GetMessageFactory()->GetPrototype(field->message_type());
    }
  
    const void* data_;
    const AccessorType* accessor_;
    const Message* default_instance_;
  };
  
  // MutableRepeatedFieldRef definition for message types.
  template<typename T>
  class MutableRepeatedFieldRef<
      T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
    typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
  
   public:
    bool empty() const {
      return accessor_->IsEmpty(data_);
    }
    int size() const {
      return accessor_->Size(data_);
    }
    // See comments for RepeatedFieldRef<Message>::Get()
    const T& Get(int index, T* scratch_space) const {
      return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space));
    }
    // Create a new message of the same type as the messages stored in this
    // repeated field. Caller takes ownership of the returned object.
    T* NewMessage() const {
      return static_cast<T*>(default_instance_->New());
    }
  
    void Set(int index, const T& value) const {
      accessor_->Set(data_, index, &value);
    }
    void Add(const T& value) const {
      accessor_->Add(data_, &value);
    }
    void RemoveLast() const {
      accessor_->RemoveLast(data_);
    }
    void SwapElements(int index1, int index2) const {
      accessor_->SwapElements(data_, index1, index2);
    }
    void Clear() const {
      accessor_->Clear(data_);
    }
  
    void Swap(const MutableRepeatedFieldRef& other) const {
      accessor_->Swap(data_, other.accessor_, other.data_);
    }
  
    template<typename Container>
    void MergeFrom(const Container& container) const {
      typedef typename Container::const_iterator Iterator;
      for (Iterator it = container.begin(); it != container.end(); ++it) {
        Add(*it);
      }
    }
    template<typename Container>
    void CopyFrom(const Container& container) const {
      Clear();
      MergeFrom(container);
    }
  
   private:
    friend class Reflection;
    MutableRepeatedFieldRef(
        Message* message,
        const FieldDescriptor* field) {
      const Reflection* reflection = message->GetReflection();
      data_ = reflection->RepeatedFieldData(
          message, field, internal::RefTypeTraits<T>::cpp_type,
          internal::RefTypeTraits<T>::GetMessageFieldDescriptor());
      accessor_ = reflection->RepeatedFieldAccessor(field);
      default_instance_ =
          reflection->GetMessageFactory()->GetPrototype(field->message_type());
    }
  
    void* data_;
    const AccessorType* accessor_;
    const Message* default_instance_;
  };
  
  namespace internal {
  // Interfaces used to implement reflection RepeatedFieldRef API.
  // Reflection::GetRepeatedAccessor() should return a pointer to an singleton
  // object that implements the below interface.
  //
  // This interface passes/returns values using void pointers. The actual type
  // of the value depends on the field's cpp_type. Following is a mapping from
  // cpp_type to the type that should be used in this interface:
  //
  //   field->cpp_type()      T                Actual type of void*
  //   CPPTYPE_INT32        int32                   int32
  //   CPPTYPE_UINT32       uint32                  uint32
  //   CPPTYPE_INT64        int64                   int64
  //   CPPTYPE_UINT64       uint64                  uint64
  //   CPPTYPE_DOUBLE       double                  double
  //   CPPTYPE_FLOAT        float                   float
  //   CPPTYPE_BOOL         bool                    bool
  //   CPPTYPE_ENUM         generated enum type     int32
  //   CPPTYPE_STRING       string                  string
  //   CPPTYPE_MESSAGE      generated message type  google::protobuf::Message
  //                        or google::protobuf::Message
  //
  // Note that for enums we use int32 in the interface.
  //
  // You can map from T to the actual type using RefTypeTraits:
  //   typedef RefTypeTraits<T>::AccessorValueType ActualType;
  class LIBPROTOBUF_EXPORT RepeatedFieldAccessor {
   public:
    // Typedefs for clarity.
    typedef void Field;
    typedef void Value;
    typedef void Iterator;
  
    virtual ~RepeatedFieldAccessor();
    virtual bool IsEmpty(const Field* data) const = 0;
    virtual int Size(const Field* data) const = 0;
    // Depends on the underlying representation of the repeated field, this
    // method can return a pointer to the underlying object if such an object
    // exists, or fill the data into scratch_space and return scratch_space.
    // Callers of this method must ensure scratch_space is a valid pointer
    // to a mutable object of the correct type.
    virtual const Value* Get(
        const Field* data, int index, Value* scratch_space) const = 0;
  
    virtual void Clear(Field* data) const = 0;
    virtual void Set(Field* data, int index, const Value* value) const = 0;
    virtual void Add(Field* data, const Value* value) const = 0;
    virtual void RemoveLast(Field* data) const = 0;
    virtual void SwapElements(Field* data, int index1, int index2) const = 0;
    virtual void Swap(Field* data, const RepeatedFieldAccessor* other_mutator,
                      Field* other_data) const = 0;
  
    // Create an iterator that points at the beginning of the repeated field.
    virtual Iterator* BeginIterator(const Field* data) const = 0;
    // Create an iterator that points at the end of the repeated field.
    virtual Iterator* EndIterator(const Field* data) const = 0;
    // Make a copy of an iterator and return the new copy.
    virtual Iterator* CopyIterator(const Field* data,
                                   const Iterator* iterator) const = 0;
    // Move an iterator to point to the next element.
    virtual Iterator* AdvanceIterator(const Field* data,
                                      Iterator* iterator) const = 0;
    // Compare whether two iterators point to the same element.
    virtual bool EqualsIterator(const Field* data, const Iterator* a,
                                const Iterator* b) const = 0;
    // Delete an iterator created by BeginIterator(), EndIterator() and
    // CopyIterator().
    virtual void DeleteIterator(const Field* data, Iterator* iterator) const = 0;
    // Like Get() but for iterators.
    virtual const Value* GetIteratorValue(const Field* data,
                                          const Iterator* iterator,
                                          Value* scratch_space) const = 0;
  
    // Templated methods that make using this interface easier for non-message
    // types.
    template<typename T>
    T Get(const Field* data, int index) const {
      typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
      ActualType scratch_space;
      return static_cast<T>(
          *reinterpret_cast<const ActualType*>(
              Get(data, index, static_cast<Value*>(&scratch_space))));
    }
  
    template<typename T, typename ValueType>
    void Set(Field* data, int index, const ValueType& value) const {
      typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
      // In this RepeatedFieldAccessor interface we pass/return data using
      // raw pointers. Type of the data these raw pointers point to should
      // be ActualType. Here we have a ValueType object and want a ActualType
      // pointer. We can't cast a ValueType pointer to an ActualType pointer
      // directly because their type might be different (for enums ValueType
      // may be a generated enum type while ActualType is int32). To be safe
      // we make a copy to get a temporary ActualType object and use it.
      ActualType tmp = static_cast<ActualType>(value);
      Set(data, index, static_cast<const Value*>(&tmp));
    }
  
    template<typename T, typename ValueType>
    void Add(Field* data, const ValueType& value) const {
      typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
      // In this RepeatedFieldAccessor interface we pass/return data using
      // raw pointers. Type of the data these raw pointers point to should
      // be ActualType. Here we have a ValueType object and want a ActualType
      // pointer. We can't cast a ValueType pointer to an ActualType pointer
      // directly because their type might be different (for enums ValueType
      // may be a generated enum type while ActualType is int32). To be safe
      // we make a copy to get a temporary ActualType object and use it.
      ActualType tmp = static_cast<ActualType>(value);
      Add(data, static_cast<const Value*>(&tmp));
    }
  };
  
  // Implement (Mutable)RepeatedFieldRef::iterator
  template<typename T>
  class RepeatedFieldRefIterator
      : public std::iterator<std::forward_iterator_tag, T> {
    typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType;
    typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType;
    typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType;
  
   public:
    // Constructor for non-message fields.
    RepeatedFieldRefIterator(const void* data,
                             const RepeatedFieldAccessor* accessor, bool begin)
        : data_(data),
          accessor_(accessor),
          iterator_(begin ? accessor->BeginIterator(data)
                          : accessor->EndIterator(data)),
          // The end iterator must not be dereferenced, no need for scratch space.
          scratch_space_(begin ? new AccessorValueType : NULL) {}
    // Constructor for message fields.
    RepeatedFieldRefIterator(const void* data,
                             const RepeatedFieldAccessor* accessor,
                             bool begin,
                             AccessorValueType* scratch_space)
        : data_(data), accessor_(accessor),
          iterator_(begin ? accessor->BeginIterator(data) :
                            accessor->EndIterator(data)),
          scratch_space_(scratch_space) {
    }
    ~RepeatedFieldRefIterator() {
      accessor_->DeleteIterator(data_, iterator_);
    }
    RepeatedFieldRefIterator operator++(int) {
      RepeatedFieldRefIterator tmp(*this);
      iterator_ = accessor_->AdvanceIterator(data_, iterator_);
      return tmp;
    }
    RepeatedFieldRefIterator& operator++() {
      iterator_ = accessor_->AdvanceIterator(data_, iterator_);
      return *this;
    }
    IteratorValueType operator*() const {
      return static_cast<IteratorValueType>(
          *static_cast<const AccessorValueType*>(
              accessor_->GetIteratorValue(
                  data_, iterator_, scratch_space_.get())));
    }
    IteratorPointerType operator->() const {
      return static_cast<IteratorPointerType>(
          accessor_->GetIteratorValue(
              data_, iterator_, scratch_space_.get()));
    }
    bool operator!=(const RepeatedFieldRefIterator& other) const {
      assert(data_ == other.data_);
      assert(accessor_ == other.accessor_);
      return !accessor_->EqualsIterator(data_, iterator_, other.iterator_);
    }
    bool operator==(const RepeatedFieldRefIterator& other) const {
      return !this->operator!=(other);
    }
  
    RepeatedFieldRefIterator(const RepeatedFieldRefIterator& other)
        : data_(other.data_), accessor_(other.accessor_),
          iterator_(accessor_->CopyIterator(data_, other.iterator_)) {
    }
    RepeatedFieldRefIterator& operator=(const RepeatedFieldRefIterator& other) {
      if (this != &other) {
        accessor_->DeleteIterator(data_, iterator_);
        data_ = other.data_;
        accessor_ = other.accessor_;
        iterator_ = accessor_->CopyIterator(data_, other.iterator_);
      }
      return *this;
    }
  
   protected:
    const void* data_;
    const RepeatedFieldAccessor* accessor_;
    void* iterator_;
    google::protobuf::scoped_ptr<AccessorValueType> scratch_space_;
  };
  
  // TypeTraits that maps the type parameter T of RepeatedFieldRef or
  // MutableRepeatedFieldRef to corresponding iterator type,
  // RepeatedFieldAccessor type, etc.
  template<typename T>
  struct PrimitiveTraits {
    static const bool is_primitive = false;
  };
  #define DEFINE_PRIMITIVE(TYPE, type) \
      template<> struct PrimitiveTraits<type> { \
        static const bool is_primitive = true; \
        static const FieldDescriptor::CppType cpp_type = \
            FieldDescriptor::CPPTYPE_ ## TYPE; \
      };
  DEFINE_PRIMITIVE(INT32, int32)
  DEFINE_PRIMITIVE(UINT32, uint32)
  DEFINE_PRIMITIVE(INT64, int64)
  DEFINE_PRIMITIVE(UINT64, uint64)
  DEFINE_PRIMITIVE(FLOAT, float)
  DEFINE_PRIMITIVE(DOUBLE, double)
  DEFINE_PRIMITIVE(BOOL, bool)
  #undef DEFINE_PRIMITIVE
  
  template<typename T>
  struct RefTypeTraits<
      T, typename internal::enable_if<PrimitiveTraits<T>::is_primitive>::type> {
    typedef RepeatedFieldRefIterator<T> iterator;
    typedef RepeatedFieldAccessor AccessorType;
    typedef T AccessorValueType;
    typedef T IteratorValueType;
    typedef T* IteratorPointerType;
    static const FieldDescriptor::CppType cpp_type =
        PrimitiveTraits<T>::cpp_type;
    static const Descriptor* GetMessageFieldDescriptor() {
      return NULL;
    }
  };
  
  template<typename T>
  struct RefTypeTraits<
      T, typename internal::enable_if<is_proto_enum<T>::value>::type> {
    typedef RepeatedFieldRefIterator<T> iterator;
    typedef RepeatedFieldAccessor AccessorType;
    // We use int32 for repeated enums in RepeatedFieldAccessor.
    typedef int32 AccessorValueType;
    typedef T IteratorValueType;
    typedef int32* IteratorPointerType;
    static const FieldDescriptor::CppType cpp_type =
        FieldDescriptor::CPPTYPE_ENUM;
    static const Descriptor* GetMessageFieldDescriptor() {
      return NULL;
    }
  };
  
  template<typename T>
  struct RefTypeTraits<
      T, typename internal::enable_if< ::google::protobuf::internal::is_same<string, T>::value>::type> {
    typedef RepeatedFieldRefIterator<T> iterator;
    typedef RepeatedFieldAccessor AccessorType;
    typedef string AccessorValueType;
    typedef string IteratorValueType;
    typedef string* IteratorPointerType;
    static const FieldDescriptor::CppType cpp_type =
        FieldDescriptor::CPPTYPE_STRING;
    static const Descriptor* GetMessageFieldDescriptor() {
      return NULL;
    }
  };
  
  template<typename T>
  struct MessageDescriptorGetter {
    static const Descriptor* get() {
      return T::default_instance().GetDescriptor();
    }
  };
  template<>
  struct MessageDescriptorGetter<Message> {
    static const Descriptor* get() {
      return NULL;
    }
  };
  
  template<typename T>
  struct RefTypeTraits<
      T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
    typedef RepeatedFieldRefIterator<T> iterator;
    typedef RepeatedFieldAccessor AccessorType;
    typedef Message AccessorValueType;
    typedef const T& IteratorValueType;
    typedef const T* IteratorPointerType;
    static const FieldDescriptor::CppType cpp_type =
        FieldDescriptor::CPPTYPE_MESSAGE;
    static const Descriptor* GetMessageFieldDescriptor() {
      return MessageDescriptorGetter<T>::get();
    }
  };
  }  // namespace internal
  }  // namespace protobuf
  }  // namespace google
  
  #endif  // GOOGLE_PROTOBUF_REFLECTION_H__
  