Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:12:24

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 "google/protobuf/generated_enum_util.h"
0017 #include "google/protobuf/descriptor.h"
0018 
0019 #ifdef SWIG
0020 #error "You cannot SWIG proto headers"
0021 #endif
0022 
0023 // Must be included last.
0024 #include "google/protobuf/port_def.inc"
0025 
0026 namespace google {
0027 namespace protobuf {
0028 namespace internal {
0029 template <typename T, typename Enable = void>
0030 struct RefTypeTraits;
0031 }  // namespace internal
0032 
0033 class Message;
0034 
0035 template <typename Dep, typename T>
0036 using MakeDependent = std::conditional_t<true, T, Dep>;
0037 
0038 // Forward-declare RepeatedFieldRef templates. The second type parameter is
0039 // used for SFINAE tricks. Users should ignore it.
0040 template <typename T, typename Enable = void>
0041 class RepeatedFieldRef;
0042 
0043 template <typename T, typename Enable = void>
0044 class MutableRepeatedFieldRef;
0045 
0046 // RepeatedFieldRef definition for non-message types.
0047 template <typename T>
0048 class RepeatedFieldRef<
0049     T, typename std::enable_if<!std::is_base_of<Message, T>::value>::type> {
0050   typedef typename internal::RefTypeTraits<T>::iterator IteratorType;
0051   typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
0052 
0053  public:
0054   bool empty() const { return accessor_->IsEmpty(data_); }
0055   int size() const { return accessor_->Size(data_); }
0056   T Get(int index) const { return accessor_->template Get<T>(data_, index); }
0057 
0058   typedef IteratorType iterator;
0059   typedef IteratorType const_iterator;
0060   typedef T value_type;
0061   typedef T& reference;
0062   typedef const T& const_reference;
0063   typedef int size_type;
0064   typedef ptrdiff_t difference_type;
0065 
0066   iterator begin() const { return iterator(data_, accessor_, true); }
0067   iterator end() const { return iterator(data_, accessor_, false); }
0068 
0069  private:
0070   friend class Reflection;
0071   RepeatedFieldRef(const MakeDependent<T, Message>& message,
0072                    const FieldDescriptor* field) {
0073     const auto* reflection = message.GetReflection();
0074     data_ = reflection->RepeatedFieldData(
0075         message, field, internal::RefTypeTraits<T>::cpp_type, nullptr);
0076     accessor_ = reflection->RepeatedFieldAccessor(field);
0077   }
0078 
0079   const void* data_;
0080   const AccessorType* accessor_;
0081 };
0082 
0083 // MutableRepeatedFieldRef definition for non-message types.
0084 template <typename T>
0085 class MutableRepeatedFieldRef<
0086     T, typename std::enable_if<!std::is_base_of<Message, T>::value>::type> {
0087   typedef typename internal::RefTypeTraits<T>::AccessorType AccessorType;
0088 
0089  public:
0090   bool empty() const { return accessor_->IsEmpty(data_); }
0091   int size() const { return accessor_->Size(data_); }
0092   T Get(int index) const { return accessor_->template Get<T>(data_, index); }
0093 
0094   void Set(int index, const T& value) const {
0095     accessor_->template Set<T>(data_, index, value);
0096   }
0097   void Add(const T& value) const { accessor_->template Add<T>(data_, value); }
0098   void RemoveLast() const { accessor_->RemoveLast(data_); }
0099   void Reserve(int size) const { accessor_->Reserve(data_, size); }
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>* message,
0125                           const FieldDescriptor* 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* data_;
0133   const AccessorType* 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* 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* 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* 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* data_;
0192   const AccessorType* accessor_;
0193   const T* 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* 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* 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 Reserve(int size) const { accessor_->Reserve(data_, size); }
0219   void SwapElements(int index1, int index2) const {
0220     accessor_->SwapElements(data_, index1, index2);
0221   }
0222   void Clear() const { accessor_->Clear(data_); }
0223 
0224   void Swap(const MutableRepeatedFieldRef& other) const {
0225     accessor_->Swap(data_, other.accessor_, other.data_);
0226   }
0227 
0228   template <typename Container>
0229   void MergeFrom(const Container& container) const {
0230     typedef typename Container::const_iterator Iterator;
0231     for (Iterator it = container.begin(); it != container.end(); ++it) {
0232       Add(*it);
0233     }
0234   }
0235   template <typename Container>
0236   void CopyFrom(const Container& container) const {
0237     Clear();
0238     MergeFrom(container);
0239   }
0240 
0241  private:
0242   friend class Reflection;
0243   MutableRepeatedFieldRef(MakeDependent<T, Message>* message,
0244                           const FieldDescriptor* field) {
0245     const auto* reflection = message->GetReflection();
0246     data_ = reflection->RepeatedFieldData(
0247         message, field, internal::RefTypeTraits<T>::cpp_type,
0248         internal::RefTypeTraits<T>::GetMessageFieldDescriptor());
0249     accessor_ = reflection->RepeatedFieldAccessor(field);
0250     default_instance_ = static_cast<const T*>(
0251         reflection->GetMessageFactory()->GetPrototype(field->message_type()));
0252   }
0253 
0254   void* data_;
0255   const AccessorType* accessor_;
0256   const T* default_instance_;
0257 };
0258 
0259 namespace internal {
0260 // Interfaces used to implement reflection RepeatedFieldRef API.
0261 // Reflection::GetRepeatedAccessor() should return a pointer to an singleton
0262 // object that implements the below interface.
0263 //
0264 // This interface passes/returns values using void pointers. The actual type
0265 // of the value depends on the field's cpp_type. Following is a mapping from
0266 // cpp_type to the type that should be used in this interface:
0267 //
0268 //   field->cpp_type()      T                Actual type of void*
0269 //   CPPTYPE_INT32        int32_t                 int32_t
0270 //   CPPTYPE_UINT32       uint32_t                uint32_t
0271 //   CPPTYPE_INT64        int64_t                 int64_t
0272 //   CPPTYPE_UINT64       uint64_t                uint64_t
0273 //   CPPTYPE_DOUBLE       double                  double
0274 //   CPPTYPE_FLOAT        float                   float
0275 //   CPPTYPE_BOOL         bool                    bool
0276 //   CPPTYPE_ENUM         generated enum type     int32_t
0277 //   CPPTYPE_STRING       string                  std::string
0278 //   CPPTYPE_MESSAGE      generated message type  google::protobuf::Message
0279 //                        or google::protobuf::Message
0280 //
0281 // Note that for enums we use int32_t in the interface.
0282 //
0283 // You can map from T to the actual type using RefTypeTraits:
0284 //   typedef RefTypeTraits<T>::AccessorValueType ActualType;
0285 class PROTOBUF_EXPORT RepeatedFieldAccessor {
0286  public:
0287   // Typedefs for clarity.
0288   typedef void Field;
0289   typedef void Value;
0290   typedef void Iterator;
0291 
0292   virtual bool IsEmpty(const Field* data) const = 0;
0293   virtual int Size(const Field* data) const = 0;
0294   // Depends on the underlying representation of the repeated field, this
0295   // method can return a pointer to the underlying object if such an object
0296   // exists, or fill the data into scratch_space and return scratch_space.
0297   // Callers of this method must ensure scratch_space is a valid pointer
0298   // to a mutable object of the correct type.
0299   virtual const Value* Get(const Field* data, int index,
0300                            Value* scratch_space) const = 0;
0301 
0302   virtual void Clear(Field* data) const = 0;
0303   virtual void Set(Field* data, int index, const Value* value) const = 0;
0304   virtual void Add(Field* data, const Value* value) const = 0;
0305   virtual void RemoveLast(Field* data) const = 0;
0306   virtual void Reserve(Field* data, int size) const = 0;
0307   virtual void SwapElements(Field* data, int index1, int index2) const = 0;
0308   virtual void Swap(Field* data, const RepeatedFieldAccessor* other_mutator,
0309                     Field* other_data) const = 0;
0310 
0311   // Create an iterator that points at the beginning of the repeated field.
0312   virtual Iterator* BeginIterator(const Field* data) const = 0;
0313   // Create an iterator that points at the end of the repeated field.
0314   virtual Iterator* EndIterator(const Field* data) const = 0;
0315   // Make a copy of an iterator and return the new copy.
0316   virtual Iterator* CopyIterator(const Field* data,
0317                                  const Iterator* iterator) const = 0;
0318   // Move an iterator to point to the next element.
0319   virtual Iterator* AdvanceIterator(const Field* data,
0320                                     Iterator* iterator) const = 0;
0321   // Compare whether two iterators point to the same element.
0322   virtual bool EqualsIterator(const Field* data, const Iterator* a,
0323                               const Iterator* b) const = 0;
0324   // Delete an iterator created by BeginIterator(), EndIterator() and
0325   // CopyIterator().
0326   virtual void DeleteIterator(const Field* data, Iterator* iterator) const = 0;
0327   // Like Get() but for iterators.
0328   virtual const Value* GetIteratorValue(const Field* data,
0329                                         const Iterator* iterator,
0330                                         Value* scratch_space) const = 0;
0331 
0332   // Templated methods that make using this interface easier for non-message
0333   // types.
0334   template <typename T>
0335   T Get(const Field* data, int index) const {
0336     typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
0337     ActualType scratch_space;
0338     return static_cast<T>(*reinterpret_cast<const ActualType*>(
0339         Get(data, index, static_cast<Value*>(&scratch_space))));
0340   }
0341 
0342   template <typename T, typename ValueType>
0343   void Set(Field* data, int index, const ValueType& value) const {
0344     typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
0345     // In this RepeatedFieldAccessor interface we pass/return data using
0346     // raw pointers. Type of the data these raw pointers point to should
0347     // be ActualType. Here we have a ValueType object and want a ActualType
0348     // pointer. We can't cast a ValueType pointer to an ActualType pointer
0349     // directly because their type might be different (for enums ValueType
0350     // may be a generated enum type while ActualType is int32_t). To be safe
0351     // we make a copy to get a temporary ActualType object and use it.
0352     ActualType tmp = static_cast<ActualType>(value);
0353     Set(data, index, static_cast<const Value*>(&tmp));
0354   }
0355 
0356   template <typename T, typename ValueType>
0357   void Add(Field* data, const ValueType& value) const {
0358     typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
0359     // In this RepeatedFieldAccessor interface we pass/return data using
0360     // raw pointers. Type of the data these raw pointers point to should
0361     // be ActualType. Here we have a ValueType object and want a ActualType
0362     // pointer. We can't cast a ValueType pointer to an ActualType pointer
0363     // directly because their type might be different (for enums ValueType
0364     // may be a generated enum type while ActualType is int32_t). To be safe
0365     // we make a copy to get a temporary ActualType object and use it.
0366     ActualType tmp = static_cast<ActualType>(value);
0367     Add(data, static_cast<const Value*>(&tmp));
0368   }
0369 
0370  protected:
0371   // We want the destructor to be completely trivial as to allow it to be
0372   // a function local static. Hence we make it non-virtual and protected,
0373   // this class only live as part of a global singleton and should not be
0374   // deleted.
0375   ~RepeatedFieldAccessor() = default;
0376 };
0377 
0378 // Implement (Mutable)RepeatedFieldRef::iterator
0379 template <typename T>
0380 class RepeatedFieldRefIterator {
0381   typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType;
0382   typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType;
0383   typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType;
0384 
0385  public:
0386   using iterator_category = std::forward_iterator_tag;
0387   using value_type = T;
0388   using pointer = T*;
0389   using reference = T&;
0390   using difference_type = std::ptrdiff_t;
0391 
0392   // Constructor for non-message fields.
0393   RepeatedFieldRefIterator(const void* data,
0394                            const RepeatedFieldAccessor* accessor, bool begin)
0395       : data_(data),
0396         accessor_(accessor),
0397         iterator_(begin ? accessor->BeginIterator(data)
0398                         : accessor->EndIterator(data)),
0399         // The end iterator must not be dereferenced, no need for scratch space.
0400         scratch_space_(begin ? new AccessorValueType : nullptr) {}
0401   // Constructor for message fields.
0402   RepeatedFieldRefIterator(const void* data,
0403                            const RepeatedFieldAccessor* accessor, bool begin,
0404                            AccessorValueType* scratch_space)
0405       : data_(data),
0406         accessor_(accessor),
0407         iterator_(begin ? accessor->BeginIterator(data)
0408                         : accessor->EndIterator(data)),
0409         scratch_space_(scratch_space) {}
0410   ~RepeatedFieldRefIterator() { accessor_->DeleteIterator(data_, iterator_); }
0411   RepeatedFieldRefIterator operator++(int) {
0412     RepeatedFieldRefIterator tmp(*this);
0413     iterator_ = accessor_->AdvanceIterator(data_, iterator_);
0414     return tmp;
0415   }
0416   RepeatedFieldRefIterator& operator++() {
0417     iterator_ = accessor_->AdvanceIterator(data_, iterator_);
0418     return *this;
0419   }
0420   IteratorValueType operator*() const {
0421     return static_cast<IteratorValueType>(
0422         *static_cast<const AccessorValueType*>(accessor_->GetIteratorValue(
0423             data_, iterator_, scratch_space_.get())));
0424   }
0425   IteratorPointerType operator->() const {
0426     return static_cast<IteratorPointerType>(
0427         accessor_->GetIteratorValue(data_, iterator_, scratch_space_.get()));
0428   }
0429   bool operator!=(const RepeatedFieldRefIterator& other) const {
0430     assert(data_ == other.data_);
0431     assert(accessor_ == other.accessor_);
0432     return !accessor_->EqualsIterator(data_, iterator_, other.iterator_);
0433   }
0434   bool operator==(const RepeatedFieldRefIterator& other) const {
0435     return !this->operator!=(other);
0436   }
0437 
0438   RepeatedFieldRefIterator(const RepeatedFieldRefIterator& other)
0439       : data_(other.data_),
0440         accessor_(other.accessor_),
0441         iterator_(accessor_->CopyIterator(data_, other.iterator_)) {}
0442   RepeatedFieldRefIterator& operator=(const RepeatedFieldRefIterator& other) {
0443     if (this != &other) {
0444       accessor_->DeleteIterator(data_, iterator_);
0445       data_ = other.data_;
0446       accessor_ = other.accessor_;
0447       iterator_ = accessor_->CopyIterator(data_, other.iterator_);
0448     }
0449     return *this;
0450   }
0451 
0452  protected:
0453   const void* data_;
0454   const RepeatedFieldAccessor* accessor_;
0455   void* iterator_;
0456   std::unique_ptr<AccessorValueType> scratch_space_;
0457 };
0458 
0459 // TypeTraits that maps the type parameter T of RepeatedFieldRef or
0460 // MutableRepeatedFieldRef to corresponding iterator type,
0461 // RepeatedFieldAccessor type, etc.
0462 template <typename T>
0463 struct PrimitiveTraits {
0464   static constexpr bool is_primitive = false;
0465 };
0466 #define DEFINE_PRIMITIVE(TYPE, type)                 \
0467   template <>                                        \
0468   struct PrimitiveTraits<type> {                     \
0469     static const bool is_primitive = true;           \
0470     static const FieldDescriptor::CppType cpp_type = \
0471         FieldDescriptor::CPPTYPE_##TYPE;             \
0472   };
0473 DEFINE_PRIMITIVE(INT32, int32_t)
0474 DEFINE_PRIMITIVE(UINT32, uint32_t)
0475 DEFINE_PRIMITIVE(INT64, int64_t)
0476 DEFINE_PRIMITIVE(UINT64, uint64_t)
0477 DEFINE_PRIMITIVE(FLOAT, float)
0478 DEFINE_PRIMITIVE(DOUBLE, double)
0479 DEFINE_PRIMITIVE(BOOL, bool)
0480 #undef DEFINE_PRIMITIVE
0481 
0482 template <typename T>
0483 struct RefTypeTraits<
0484     T, typename std::enable_if<PrimitiveTraits<T>::is_primitive>::type> {
0485   typedef RepeatedFieldRefIterator<T> iterator;
0486   typedef RepeatedFieldAccessor AccessorType;
0487   typedef T AccessorValueType;
0488   typedef T IteratorValueType;
0489   typedef T* IteratorPointerType;
0490   static constexpr FieldDescriptor::CppType cpp_type =
0491       PrimitiveTraits<T>::cpp_type;
0492   static const Descriptor* GetMessageFieldDescriptor() { return nullptr; }
0493 };
0494 
0495 template <typename T>
0496 struct RefTypeTraits<
0497     T, typename std::enable_if<is_proto_enum<T>::value>::type> {
0498   typedef RepeatedFieldRefIterator<T> iterator;
0499   typedef RepeatedFieldAccessor AccessorType;
0500   // We use int32_t for repeated enums in RepeatedFieldAccessor.
0501   typedef int32_t AccessorValueType;
0502   typedef T IteratorValueType;
0503   typedef int32_t* IteratorPointerType;
0504   static constexpr FieldDescriptor::CppType cpp_type =
0505       FieldDescriptor::CPPTYPE_ENUM;
0506   static const Descriptor* GetMessageFieldDescriptor() { return nullptr; }
0507 };
0508 
0509 template <typename T>
0510 struct RefTypeTraits<
0511     T, typename std::enable_if<std::is_same<std::string, T>::value>::type> {
0512   typedef RepeatedFieldRefIterator<T> iterator;
0513   typedef RepeatedFieldAccessor AccessorType;
0514   typedef std::string AccessorValueType;
0515   typedef const std::string IteratorValueType;
0516   typedef const std::string* IteratorPointerType;
0517   static constexpr FieldDescriptor::CppType cpp_type =
0518       FieldDescriptor::CPPTYPE_STRING;
0519   static const Descriptor* GetMessageFieldDescriptor() { return nullptr; }
0520 };
0521 
0522 template <typename T>
0523 struct MessageDescriptorGetter {
0524   static const Descriptor* get() {
0525     return T::default_instance().GetDescriptor();
0526   }
0527 };
0528 template <>
0529 struct MessageDescriptorGetter<Message> {
0530   static const Descriptor* get() { return nullptr; }
0531 };
0532 
0533 template <typename T>
0534 struct RefTypeTraits<
0535     T, typename std::enable_if<std::is_base_of<Message, T>::value>::type> {
0536   typedef RepeatedFieldRefIterator<T> iterator;
0537   typedef RepeatedFieldAccessor AccessorType;
0538   typedef Message AccessorValueType;
0539   typedef const T& IteratorValueType;
0540   typedef const T* IteratorPointerType;
0541   static constexpr FieldDescriptor::CppType cpp_type =
0542       FieldDescriptor::CPPTYPE_MESSAGE;
0543   static const Descriptor* GetMessageFieldDescriptor() {
0544     return MessageDescriptorGetter<T>::get();
0545   }
0546 };
0547 }  // namespace internal
0548 }  // namespace protobuf
0549 }  // namespace google
0550 
0551 #include "google/protobuf/port_undef.inc"
0552 
0553 #endif  // GOOGLE_PROTOBUF_REFLECTION_H__