Coverage Report

Created: 2025-04-27 06:20

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