File indexing completed on 2026-09-19 09:23:44
0001
0002
0003
0004
0005
0006
0007
0008
0009
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
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 }
0033
0034 class Message;
0035
0036 template <typename Dep, typename T>
0037 using MakeDependent = std::conditional_t<true, T, Dep>;
0038
0039
0040
0041 template <typename T, typename Enable = void>
0042 class RepeatedFieldRef;
0043
0044 template <typename T, typename Enable = void>
0045 class MutableRepeatedFieldRef;
0046
0047
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
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
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
0147
0148
0149
0150
0151
0152
0153
0154
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
0159
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
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
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
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
0210
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
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284 class PROTOBUF_EXPORT RepeatedFieldAccessor {
0285 public:
0286
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
0294
0295
0296
0297
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
0315 virtual Iterator* PROTOBUF_NULLABLE
0316 BeginIterator(const Field* PROTOBUF_NONNULL data) const = 0;
0317
0318 virtual Iterator* PROTOBUF_NULLABLE
0319 EndIterator(const Field* PROTOBUF_NONNULL data) const = 0;
0320
0321 virtual Iterator* PROTOBUF_NULLABLE
0322 CopyIterator(const Field* PROTOBUF_NONNULL data,
0323 const Iterator* PROTOBUF_NULLABLE iterator) const = 0;
0324
0325 virtual Iterator* PROTOBUF_NONNULL
0326 AdvanceIterator(const Field* PROTOBUF_NONNULL data,
0327 Iterator* PROTOBUF_NULLABLE iterator) const = 0;
0328
0329 virtual bool EqualsIterator(const Field* PROTOBUF_NONNULL data,
0330 const Iterator* PROTOBUF_NULLABLE a,
0331 const Iterator* PROTOBUF_NULLABLE b) const = 0;
0332
0333
0334 virtual void DeleteIterator(const Field* PROTOBUF_NONNULL data,
0335 Iterator* PROTOBUF_NULLABLE iterator) const = 0;
0336
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
0343
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
0357
0358
0359
0360
0361
0362
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
0371
0372
0373
0374
0375
0376
0377 ActualType tmp = static_cast<ActualType>(value);
0378 Add(data, static_cast<const Value*>(&tmp));
0379 }
0380
0381 protected:
0382
0383
0384
0385
0386 ~RepeatedFieldAccessor() = default;
0387 };
0388
0389
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
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
0412 scratch_space_(begin ? new AccessorValueType : nullptr) {}
0413
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
0473
0474
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
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 }
0567 }
0568 }
0569
0570 #include "google/protobuf/port_undef.inc"
0571
0572 #endif