Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-19 09:23:44

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 // This header defines the RepeatedFieldRef class template used to access
0009 // repeated fields with protobuf reflection API.
0010 #ifndef GOOGLE_PROTOBUF_REFLECTION_H__
0011 #define GOOGLE_PROTOBUF_REFLECTION_H__
0012 
0013 #include <memory>
0014 #include <type_traits>
0015 
0016 #include "absl/base/attributes.h"
0017 #include "google/protobuf/generated_enum_util.h"
0018 #include "google/protobuf/descriptor.h"
0019 
0020 #ifdef SWIG
0021 #error "You cannot SWIG proto headers"
0022 #endif
0023 
0024 // Must be included last.
0025 #include "google/protobuf/port_def.inc"
0026 
0027 namespace google {
0028 namespace protobuf {
0029 namespace internal {
0030 template <typename T, typename Enable = void>
0031 struct RefTypeTraits;
0032 }  // namespace internal
0033 
0034 class Message;
0035 
0036 template <typename Dep, typename T>
0037 using MakeDependent = std::conditional_t<true, T, Dep>;
0038 
0039 // Forward-declare RepeatedFieldRef templates. The second type parameter is
0040 // used for SFINAE tricks. Users should ignore it.
0041 template <typename T, typename Enable = void>
0042 class RepeatedFieldRef;
0043 
0044 template <typename T, typename Enable = void>
0045 class MutableRepeatedFieldRef;
0046 
0047 // RepeatedFieldRef definition for non-message types.
0048 template <typename T>
0049 class RepeatedFieldRef<
0050     T, typename std::enable_if<!std::is_base_of<Message, T>::value>::type> {
0051   typedef typename internal::RefTypeTraits<T>::iterator IteratorType;
0052   typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
0053 
0054  public:
0055   bool empty() const { return accessor_->IsEmpty(data_); }
0056   int size() const { return accessor_->Size(data_); }
0057   T Get(int index) const { return accessor_->template Get<T>(data_, index); }
0058 
0059   typedef IteratorType iterator;
0060   typedef IteratorType const_iterator;
0061   typedef T value_type;
0062   typedef T& reference;
0063   typedef const T& const_reference;
0064   typedef int size_type;
0065   typedef ptrdiff_t difference_type;
0066 
0067   iterator begin() const { return iterator(data_, accessor_, true); }
0068   iterator end() const { return iterator(data_, accessor_, false); }
0069 
0070  private:
0071   friend class Reflection;
0072   RepeatedFieldRef(const MakeDependent<T, Message>& message,
0073                    const FieldDescriptor* PROTOBUF_NONNULL field) {
0074     const auto* reflection = message.GetReflection();
0075     data_ = reflection->RepeatedFieldData(
0076         message, field, internal::RefTypeTraits<T>::cpp_type, nullptr);
0077     accessor_ = reflection->RepeatedFieldAccessor(field);
0078   }
0079 
0080   const void* PROTOBUF_NONNULL data_;
0081   const AccessorType* PROTOBUF_NONNULL accessor_;
0082 };
0083 
0084 // MutableRepeatedFieldRef definition for non-message types.
0085 template <typename T>
0086 class MutableRepeatedFieldRef<
0087     T, typename std::enable_if<!std::is_base_of<Message, T>::value>::type> {
0088   typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
0089 
0090  public:
0091   bool empty() const { return accessor_->IsEmpty(data_); }
0092   int size() const { return accessor_->Size(data_); }
0093   T Get(int index) const { return accessor_->template Get<T>(data_, index); }
0094 
0095   void Set(int index, const T& value) const {
0096     accessor_->template Set<T>(data_, index, value);
0097   }
0098   void Add(const T& value) const { accessor_->template Add<T>(data_, value); }
0099   void RemoveLast() const { accessor_->RemoveLast(data_); }
0100   void SwapElements(int index1, int index2) const {
0101     accessor_->SwapElements(data_, index1, index2);
0102   }
0103   void Clear() const { accessor_->Clear(data_); }
0104 
0105   void Swap(const MutableRepeatedFieldRef& other) const {
0106     accessor_->Swap(data_, other.accessor_, other.data_);
0107   }
0108 
0109   template <typename Container>
0110   void MergeFrom(const Container& container) const {
0111     typedef typename Container::const_iterator Iterator;
0112     for (Iterator it = container.begin(); it != container.end(); ++it) {
0113       Add(*it);
0114     }
0115   }
0116   template <typename Container>
0117   void CopyFrom(const Container& container) const {
0118     Clear();
0119     MergeFrom(container);
0120   }
0121 
0122  private:
0123   friend class Reflection;
0124   MutableRepeatedFieldRef(MakeDependent<T, Message>* PROTOBUF_NONNULL message,
0125                           const FieldDescriptor* PROTOBUF_NONNULL field) {
0126     const auto* reflection = message->GetReflection();
0127     data_ = reflection->RepeatedFieldData(
0128         message, field, internal::RefTypeTraits<T>::cpp_type, nullptr);
0129     accessor_ = reflection->RepeatedFieldAccessor(field);
0130   }
0131 
0132   void* PROTOBUF_NONNULL data_;
0133   const AccessorType* PROTOBUF_NONNULL accessor_;
0134 };
0135 
0136 // RepeatedFieldRef definition for message types.
0137 template <typename T>
0138 class RepeatedFieldRef<
0139     T, typename std::enable_if<std::is_base_of<Message, T>::value>::type> {
0140   typedef typename internal::RefTypeTraits<T>::iterator IteratorType;
0141   typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
0142 
0143  public:
0144   bool empty() const { return accessor_->IsEmpty(data_); }
0145   int size() const { return accessor_->Size(data_); }
0146   // This method returns a reference to the underlying message object if it
0147   // exists. If a message object doesn't exist (e.g., data stored in serialized
0148   // form), scratch_space will be filled with the data and a reference to it
0149   // will be returned.
0150   //
0151   // Example:
0152   //   RepeatedFieldRef<Message> h = ...
0153   //   unique_ptr<Message> scratch_space(h.NewMessage());
0154   //   const Message& item = h.Get(index, scratch_space.get());
0155   const T& Get(int index, T* PROTOBUF_NULLABLE scratch_space) const {
0156     return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space));
0157   }
0158   // Create a new message of the same type as the messages stored in this
0159   // repeated field. Caller takes ownership of the returned object.
0160   T* PROTOBUF_NONNULL NewMessage() const { return default_instance_->New(); }
0161 
0162   typedef IteratorType iterator;
0163   typedef IteratorType const_iterator;
0164   typedef T value_type;
0165   typedef T& reference;
0166   typedef const T& const_reference;
0167   typedef int size_type;
0168   typedef ptrdiff_t difference_type;
0169 
0170   iterator begin() const {
0171     return iterator(data_, accessor_, true, NewMessage());
0172   }
0173   iterator end() const {
0174     // The end iterator must not be dereferenced, no need for scratch space.
0175     return iterator(data_, accessor_, false, nullptr);
0176   }
0177 
0178  private:
0179   friend class Reflection;
0180   RepeatedFieldRef(const MakeDependent<T, Message>& message,
0181                    const FieldDescriptor* PROTOBUF_NONNULL field) {
0182     const auto* reflection = message.GetReflection();
0183     data_ = reflection->RepeatedFieldData(
0184         message, field, internal::RefTypeTraits<T>::cpp_type,
0185         internal::RefTypeTraits<T>::GetMessageFieldDescriptor());
0186     accessor_ = reflection->RepeatedFieldAccessor(field);
0187     default_instance_ = static_cast<const T*>(
0188         reflection->GetMessageFactory()->GetPrototype(field->message_type()));
0189   }
0190 
0191   const void* PROTOBUF_NONNULL data_;
0192   const AccessorType* PROTOBUF_NONNULL accessor_;
0193   const T* PROTOBUF_NONNULL default_instance_;
0194 };
0195 
0196 // MutableRepeatedFieldRef definition for message types.
0197 template <typename T>
0198 class MutableRepeatedFieldRef<
0199     T, typename std::enable_if<std::is_base_of<Message, T>::value>::type> {
0200   typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
0201 
0202  public:
0203   bool empty() const { return accessor_->IsEmpty(data_); }
0204   int size() const { return accessor_->Size(data_); }
0205   // See comments for RepeatedFieldRef<Message>::Get()
0206   const T& Get(int index, T* PROTOBUF_NULLABLE scratch_space) const {
0207     return *static_cast<const T*>(accessor_->Get(data_, index, scratch_space));
0208   }
0209   // Create a new message of the same type as the messages stored in this
0210   // repeated field. Caller takes ownership of the returned object.
0211   T* PROTOBUF_NONNULL NewMessage() const { return default_instance_->New(); }
0212 
0213   void Set(int index, const T& value) const {
0214     accessor_->Set(data_, index, &value);
0215   }
0216   void Add(const T& value) const { accessor_->Add(data_, &value); }
0217   void RemoveLast() const { accessor_->RemoveLast(data_); }
0218   void SwapElements(int index1, int index2) const {
0219     accessor_->SwapElements(data_, index1, index2);
0220   }
0221   void Clear() const { accessor_->Clear(data_); }
0222 
0223   void Swap(const MutableRepeatedFieldRef& other) const {
0224     accessor_->Swap(data_, other.accessor_, other.data_);
0225   }
0226 
0227   template <typename Container>
0228   void MergeFrom(const Container& container) const {
0229     typedef typename Container::const_iterator Iterator;
0230     for (Iterator it = container.begin(); it != container.end(); ++it) {
0231       Add(*it);
0232     }
0233   }
0234   template <typename Container>
0235   void CopyFrom(const Container& container) const {
0236     Clear();
0237     MergeFrom(container);
0238   }
0239 
0240  private:
0241   friend class Reflection;
0242   MutableRepeatedFieldRef(MakeDependent<T, Message>* PROTOBUF_NONNULL message,
0243                           const FieldDescriptor* PROTOBUF_NONNULL field) {
0244     const auto* reflection = message->GetReflection();
0245     data_ = reflection->RepeatedFieldData(
0246         message, field, internal::RefTypeTraits<T>::cpp_type,
0247         internal::RefTypeTraits<T>::GetMessageFieldDescriptor());
0248     accessor_ = reflection->RepeatedFieldAccessor(field);
0249     default_instance_ = static_cast<const T*>(
0250         reflection->GetMessageFactory()->GetPrototype(field->message_type()));
0251   }
0252 
0253   void* PROTOBUF_NONNULL data_;
0254   const AccessorType* PROTOBUF_NONNULL accessor_;
0255   const T* PROTOBUF_NONNULL default_instance_;
0256 };
0257 
0258 namespace internal {
0259 // Interfaces used to implement reflection RepeatedFieldRef API.
0260 // Reflection::GetRepeatedAccessor() should return a pointer to an singleton
0261 // object that implements the below interface.
0262 //
0263 // This interface passes/returns values using void pointers. The actual type
0264 // of the value depends on the field's cpp_type. Following is a mapping from
0265 // cpp_type to the type that should be used in this interface:
0266 //
0267 //   field->cpp_type()      T                Actual type of void*
0268 //   CPPTYPE_INT32        int32_t                 int32_t
0269 //   CPPTYPE_UINT32       uint32_t                uint32_t
0270 //   CPPTYPE_INT64        int64_t                 int64_t
0271 //   CPPTYPE_UINT64       uint64_t                uint64_t
0272 //   CPPTYPE_DOUBLE       double                  double
0273 //   CPPTYPE_FLOAT        float                   float
0274 //   CPPTYPE_BOOL         bool                    bool
0275 //   CPPTYPE_ENUM         generated enum type     int32_t
0276 //   CPPTYPE_STRING       string                  std::string
0277 //   CPPTYPE_MESSAGE      generated message type  google::protobuf::Message
0278 //                        or google::protobuf::Message
0279 //
0280 // Note that for enums we use int32_t in the interface.
0281 //
0282 // You can map from T to the actual type using RefTypeTraits:
0283 //   typedef RefTypeTraits<T>::AccessorValueType ActualType;
0284 class PROTOBUF_EXPORT RepeatedFieldAccessor {
0285  public:
0286   // Typedefs for clarity.
0287   typedef void Field;
0288   typedef void Value;
0289   typedef void Iterator;
0290 
0291   virtual bool IsEmpty(const Field* PROTOBUF_NONNULL data) const = 0;
0292   virtual int Size(const Field* PROTOBUF_NONNULL data) const = 0;
0293   // Depends on the underlying representation of the repeated field, this
0294   // method can return a pointer to the underlying object if such an object
0295   // exists, or fill the data into scratch_space and return scratch_space.
0296   // Callers of this method must ensure scratch_space is a valid pointer
0297   // to a mutable object of the correct type.
0298   virtual const Value* PROTOBUF_NONNULL
0299   Get(const Field* PROTOBUF_NONNULL data, int index,
0300       Value* PROTOBUF_NULLABLE scratch_space) const = 0;
0301 
0302   virtual void Clear(Field* PROTOBUF_NONNULL data) const = 0;
0303   virtual void Set(Field* PROTOBUF_NONNULL data, int index,
0304                    const Value* PROTOBUF_NONNULL value) const = 0;
0305   virtual void Add(Field* PROTOBUF_NONNULL data,
0306                    const Value* PROTOBUF_NONNULL value) const = 0;
0307   virtual void RemoveLast(Field* PROTOBUF_NONNULL data) const = 0;
0308   virtual void SwapElements(Field* PROTOBUF_NONNULL data, int index1,
0309                             int index2) const = 0;
0310   virtual void Swap(Field* PROTOBUF_NONNULL data,
0311                     const RepeatedFieldAccessor* PROTOBUF_NONNULL other_mutator,
0312                     Field* PROTOBUF_NONNULL other_data) const = 0;
0313 
0314   // Create an iterator that points at the beginning of the repeated field.
0315   virtual Iterator* PROTOBUF_NULLABLE
0316   BeginIterator(const Field* PROTOBUF_NONNULL data) const = 0;
0317   // Create an iterator that points at the end of the repeated field.
0318   virtual Iterator* PROTOBUF_NULLABLE
0319   EndIterator(const Field* PROTOBUF_NONNULL data) const = 0;
0320   // Make a copy of an iterator and return the new copy.
0321   virtual Iterator* PROTOBUF_NULLABLE
0322   CopyIterator(const Field* PROTOBUF_NONNULL data,
0323                const Iterator* PROTOBUF_NULLABLE iterator) const = 0;
0324   // Move an iterator to point to the next element.
0325   virtual Iterator* PROTOBUF_NONNULL
0326   AdvanceIterator(const Field* PROTOBUF_NONNULL data,
0327                   Iterator* PROTOBUF_NULLABLE iterator) const = 0;
0328   // Compare whether two iterators point to the same element.
0329   virtual bool EqualsIterator(const Field* PROTOBUF_NONNULL data,
0330                               const Iterator* PROTOBUF_NULLABLE a,
0331                               const Iterator* PROTOBUF_NULLABLE b) const = 0;
0332   // Delete an iterator created by BeginIterator(), EndIterator() and
0333   // CopyIterator().
0334   virtual void DeleteIterator(const Field* PROTOBUF_NONNULL data,
0335                               Iterator* PROTOBUF_NULLABLE iterator) const = 0;
0336   // Like Get() but for iterators.
0337   virtual const Value* PROTOBUF_NONNULL
0338   GetIteratorValue(const Field* PROTOBUF_NONNULL data,
0339                    const Iterator* PROTOBUF_NULLABLE iterator,
0340                    Value* PROTOBUF_NULLABLE scratch_space) const = 0;
0341 
0342   // Templated methods that make using this interface easier for non-message
0343   // types.
0344   template <typename T>
0345   T Get(const Field* PROTOBUF_NONNULL data, int index) const {
0346     typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
0347     ActualType scratch_space;
0348     return static_cast<T>(*reinterpret_cast<const ActualType*>(
0349         Get(data, index, static_cast<Value*>(&scratch_space))));
0350   }
0351 
0352   template <typename T, typename ValueType>
0353   void Set(Field* PROTOBUF_NONNULL data, int index,
0354            const ValueType& value) const {
0355     typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
0356     // In this RepeatedFieldAccessor interface we pass/return data using
0357     // raw pointers. Type of the data these raw pointers point to should
0358     // be ActualType. Here we have a ValueType object and want a ActualType
0359     // pointer. We can't cast a ValueType pointer to an ActualType pointer
0360     // directly because their type might be different (for enums ValueType
0361     // may be a generated enum type while ActualType is int32_t). To be safe
0362     // we make a copy to get a temporary ActualType object and use it.
0363     ActualType tmp = static_cast<ActualType>(value);
0364     Set(data, index, static_cast<const Value*>(&tmp));
0365   }
0366 
0367   template <typename T, typename ValueType>
0368   void Add(Field* PROTOBUF_NONNULL data, const ValueType& value) const {
0369     typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
0370     // In this RepeatedFieldAccessor interface we pass/return data using
0371     // raw pointers. Type of the data these raw pointers point to should
0372     // be ActualType. Here we have a ValueType object and want a ActualType
0373     // pointer. We can't cast a ValueType pointer to an ActualType pointer
0374     // directly because their type might be different (for enums ValueType
0375     // may be a generated enum type while ActualType is int32_t). To be safe
0376     // we make a copy to get a temporary ActualType object and use it.
0377     ActualType tmp = static_cast<ActualType>(value);
0378     Add(data, static_cast<const Value*>(&tmp));
0379   }
0380 
0381  protected:
0382   // We want the destructor to be completely trivial as to allow it to be
0383   // a function local static. Hence we make it non-virtual and protected,
0384   // this class only live as part of a global singleton and should not be
0385   // deleted.
0386   ~RepeatedFieldAccessor() = default;
0387 };
0388 
0389 // Implement (Mutable)RepeatedFieldRef::iterator
0390 template <typename T>
0391 class RepeatedFieldRefIterator {
0392   typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType;
0393   typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType;
0394   typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType;
0395 
0396  public:
0397   using iterator_category = std::forward_iterator_tag;
0398   using value_type = T;
0399   using pointer = T*;
0400   using reference = T&;
0401   using difference_type = std::ptrdiff_t;
0402 
0403   // Constructor for non-message fields.
0404   RepeatedFieldRefIterator(
0405       const void* PROTOBUF_NONNULL data,
0406       const RepeatedFieldAccessor* PROTOBUF_NONNULL accessor, bool begin)
0407       : data_(data),
0408         accessor_(accessor),
0409         iterator_(begin ? accessor->BeginIterator(data)
0410                         : accessor->EndIterator(data)),
0411         // The end iterator must not be dereferenced, no need for scratch space.
0412         scratch_space_(begin ? new AccessorValueType : nullptr) {}
0413   // Constructor for message fields.
0414   RepeatedFieldRefIterator(
0415       const void* PROTOBUF_NONNULL data,
0416       const RepeatedFieldAccessor* PROTOBUF_NONNULL accessor, bool begin,
0417       AccessorValueType* PROTOBUF_NULLABLE scratch_space)
0418       : data_(data),
0419         accessor_(accessor),
0420         iterator_(begin ? accessor->BeginIterator(data)
0421                         : accessor->EndIterator(data)),
0422         scratch_space_(scratch_space) {}
0423   ~RepeatedFieldRefIterator() { accessor_->DeleteIterator(data_, iterator_); }
0424   RepeatedFieldRefIterator operator++(int) {
0425     RepeatedFieldRefIterator tmp(*this);
0426     iterator_ = accessor_->AdvanceIterator(data_, iterator_);
0427     return tmp;
0428   }
0429   RepeatedFieldRefIterator& operator++() {
0430     iterator_ = accessor_->AdvanceIterator(data_, iterator_);
0431     return *this;
0432   }
0433   IteratorValueType operator*() const {
0434     return static_cast<IteratorValueType>(
0435         *static_cast<const AccessorValueType*>(accessor_->GetIteratorValue(
0436             data_, iterator_, scratch_space_.get())));
0437   }
0438   IteratorPointerType operator->() const {
0439     return static_cast<IteratorPointerType>(
0440         accessor_->GetIteratorValue(data_, iterator_, scratch_space_.get()));
0441   }
0442   bool operator!=(const RepeatedFieldRefIterator& other) const {
0443     assert(data_ == other.data_);
0444     assert(accessor_ == other.accessor_);
0445     return !accessor_->EqualsIterator(data_, iterator_, other.iterator_);
0446   }
0447   bool operator==(const RepeatedFieldRefIterator& other) const {
0448     return !this->operator!=(other);
0449   }
0450 
0451   RepeatedFieldRefIterator(const RepeatedFieldRefIterator& other)
0452       : data_(other.data_),
0453         accessor_(other.accessor_),
0454         iterator_(accessor_->CopyIterator(data_, other.iterator_)) {}
0455   RepeatedFieldRefIterator& operator=(const RepeatedFieldRefIterator& other) {
0456     if (this != &other) {
0457       accessor_->DeleteIterator(data_, iterator_);
0458       data_ = other.data_;
0459       accessor_ = other.accessor_;
0460       iterator_ = accessor_->CopyIterator(data_, other.iterator_);
0461     }
0462     return *this;
0463   }
0464 
0465  protected:
0466   const void* PROTOBUF_NONNULL data_;
0467   const RepeatedFieldAccessor* PROTOBUF_NONNULL accessor_;
0468   void* PROTOBUF_NULLABLE iterator_;
0469   std::unique_ptr<AccessorValueType> scratch_space_;
0470 };
0471 
0472 // TypeTraits that maps the type parameter T of RepeatedFieldRef or
0473 // MutableRepeatedFieldRef to corresponding iterator type,
0474 // RepeatedFieldAccessor type, etc.
0475 template <typename T>
0476 struct PrimitiveTraits {
0477   static constexpr bool is_primitive = false;
0478 };
0479 #define DEFINE_PRIMITIVE(TYPE, type)                 \
0480   template <>                                        \
0481   struct PrimitiveTraits<type> {                     \
0482     static const bool is_primitive = true;           \
0483     static const FieldDescriptor::CppType cpp_type = \
0484         FieldDescriptor::CPPTYPE_##TYPE;             \
0485   };
0486 DEFINE_PRIMITIVE(INT32, int32_t)
0487 DEFINE_PRIMITIVE(UINT32, uint32_t)
0488 DEFINE_PRIMITIVE(INT64, int64_t)
0489 DEFINE_PRIMITIVE(UINT64, uint64_t)
0490 DEFINE_PRIMITIVE(FLOAT, float)
0491 DEFINE_PRIMITIVE(DOUBLE, double)
0492 DEFINE_PRIMITIVE(BOOL, bool)
0493 #undef DEFINE_PRIMITIVE
0494 
0495 template <typename T>
0496 struct RefTypeTraits<
0497     T, typename std::enable_if<PrimitiveTraits<T>::is_primitive>::type> {
0498   typedef RepeatedFieldRefIterator<T> iterator;
0499   typedef RepeatedFieldAccessor AccessorType;
0500   typedef T AccessorValueType;
0501   typedef T IteratorValueType;
0502   typedef T* IteratorPointerType;
0503   static constexpr FieldDescriptor::CppType cpp_type =
0504       PrimitiveTraits<T>::cpp_type;
0505   static const Descriptor* PROTOBUF_NULLABLE GetMessageFieldDescriptor() {
0506     return nullptr;
0507   }
0508 };
0509 
0510 template <typename T>
0511 struct RefTypeTraits<
0512     T, typename std::enable_if<is_proto_enum<T>::value>::type> {
0513   typedef RepeatedFieldRefIterator<T> iterator;
0514   typedef RepeatedFieldAccessor AccessorType;
0515   // We use int32_t for repeated enums in RepeatedFieldAccessor.
0516   typedef int32_t AccessorValueType;
0517   typedef T IteratorValueType;
0518   typedef int32_t* IteratorPointerType;
0519   static constexpr FieldDescriptor::CppType cpp_type =
0520       FieldDescriptor::CPPTYPE_ENUM;
0521   static const Descriptor* PROTOBUF_NULLABLE GetMessageFieldDescriptor() {
0522     return nullptr;
0523   }
0524 };
0525 
0526 template <typename T>
0527 struct RefTypeTraits<
0528     T, typename std::enable_if<std::is_same<std::string, T>::value>::type> {
0529   typedef RepeatedFieldRefIterator<T> iterator;
0530   typedef RepeatedFieldAccessor AccessorType;
0531   typedef std::string AccessorValueType;
0532   typedef const std::string IteratorValueType;
0533   typedef const std::string* IteratorPointerType;
0534   static constexpr FieldDescriptor::CppType cpp_type =
0535       FieldDescriptor::CPPTYPE_STRING;
0536   static const Descriptor* PROTOBUF_NULLABLE GetMessageFieldDescriptor() {
0537     return nullptr;
0538   }
0539 };
0540 
0541 template <typename T>
0542 struct MessageDescriptorGetter {
0543   static const Descriptor* PROTOBUF_NONNULL get() {
0544     return T::default_instance().GetDescriptor();
0545   }
0546 };
0547 template <>
0548 struct MessageDescriptorGetter<Message> {
0549   static const Descriptor* PROTOBUF_NULLABLE get() { return nullptr; }
0550 };
0551 
0552 template <typename T>
0553 struct RefTypeTraits<
0554     T, typename std::enable_if<std::is_base_of<Message, T>::value>::type> {
0555   typedef RepeatedFieldRefIterator<T> iterator;
0556   typedef RepeatedFieldAccessor AccessorType;
0557   typedef Message AccessorValueType;
0558   typedef const T& IteratorValueType;
0559   typedef const T* IteratorPointerType;
0560   static constexpr FieldDescriptor::CppType cpp_type =
0561       FieldDescriptor::CPPTYPE_MESSAGE;
0562   static const Descriptor* PROTOBUF_NULLABLE GetMessageFieldDescriptor() {
0563     return MessageDescriptorGetter<T>::get();
0564   }
0565 };
0566 }  // namespace internal
0567 }  // namespace protobuf
0568 }  // namespace google
0569 
0570 #include "google/protobuf/port_undef.inc"
0571 
0572 #endif  // GOOGLE_PROTOBUF_REFLECTION_H__