Coverage Report

Created: 2023-12-13 14:58

src/zserio/IReflectable.h
Line
Count
Source
1
#ifndef ZSERIO_I_REFLECTABLE_H_INC
2
#define ZSERIO_I_REFLECTABLE_H_INC
3
4
#include <memory>
5
6
#include "zserio/AnyHolder.h"
7
#include "zserio/BitBuffer.h"
8
#include "zserio/BitStreamWriter.h"
9
#include "zserio/Span.h"
10
#include "zserio/String.h"
11
#include "zserio/StringView.h"
12
#include "zserio/RebindAlloc.h"
13
#include "zserio/Vector.h"
14
15
namespace zserio
16
{
17
18
// forward declaration
19
template <typename ALLOC>
20
class IBasicTypeInfo;
21
22
/**
23
 * Interface for reflectable view to instances of zserio objects.
24
 *
25
 * \note Users are responsible to maintain life-time of reflected objects which must exist
26
 * as long as the views are used.
27
 *
28
 * \note The object in this context may be also an instance of a built-in type.
29
 */
30
template <typename ALLOC = std::allocator<uint8_t>>
31
class IBasicReflectable
32
{
33
public:
34
    /** Shared pointer to the reflectable interface. */
35
    using Ptr = std::shared_ptr<IBasicReflectable>;
36
37
    /** Shared pointer to the constant reflectable interface. */
38
    using ConstPtr = std::shared_ptr<const IBasicReflectable>;
39
40
    /**
41
     * Destructor.
42
     */
43
1.72k
    virtual ~IBasicReflectable() = default;
44
45
    /**
46
     * Gets type info for the current zserio object.
47
     *
48
     * \return Reference to the static instance of type info.
49
     */
50
    virtual const IBasicTypeInfo<ALLOC>& getTypeInfo() const = 0;
51
52
    /**
53
     * Gets whether the reflected object is an array.
54
     *
55
     * \return True when the object is an array, false otherwise.
56
     */
57
    virtual bool isArray() const = 0;
58
59
    /**
60
     * Initializes children of the reflected compound. Calls initializeChildren method on the generated
61
     * C++ object, which recursively initializes the whole object tree. When nothing within the object tree is
62
     * parameterized, does nothing.
63
     *
64
     * \note This method is designed to be called on the top level object (i.e. root).
65
     *
66
     * \throw CppRuntimeException When the reflected object is not a compound type.
67
     */
68
    virtual void initializeChildren() = 0;
69
70
    /**
71
     * Initializes the reflected parameterized compound object. Calls initialize method on the generated
72
     * C++ object. Note that the arguments must exactly match. In case that the argument is a compound type,
73
     * which is normally passed as a reference, it must be wrapped in a reference wrapper.
74
     *
75
     * \throw CppRuntimeException When the reflected object is not parameterized or when the arguments
76
     *                            do not match.
77
     */
78
    virtual void initialize(const vector<AnyHolder<ALLOC>, ALLOC>& typeArguments) = 0;
79
80
    /**
81
     * Initializes indexed offsets of the reflected compound object.
82
     *
83
     * \param bitPosition The bit stream position to be used for calculation.
84
     *
85
     * \throw CppRuntimeException When the reflected object is not a compound.
86
     *
87
     * \return Updated bit position which points to the first bit after the compound.
88
     */
89
    virtual size_t initializeOffsets(size_t bitPosition) = 0;
90
91
    /**
92
     * Initializes indexed offsets of the reflected compound object.
93
     *
94
     * The bit stream position to be used for calculation is defaulted to zero.
95
     *
96
     * \throw CppRuntimeException When the reflected object is not a compound.
97
     *
98
     * \return Updated bit position which points to the first bit after the compound.
99
     */
100
    virtual size_t initializeOffsets() = 0;
101
102
    /**
103
     * Gets the number of bits needed for serialization of the reflected object.
104
     *
105
     * \note Works for all reflectable types except arrays!
106
     *
107
     * \param bitPosition The bit stream position to be used for calculation.
108
     *
109
     * \throw CppRuntimeException When the reflected object is an array.
110
     *
111
     * \return The size of the serialized reflected object in bits.
112
     */
113
    virtual size_t bitSizeOf(size_t bitPosition) const = 0;
114
115
    /**
116
     * Gets the number of bits needed for serialization of the reflected object.
117
     *
118
     * The bit stream position to be used for calculation is defaulted to zero.
119
     *
120
     * \note Works for all reflectable types except arrays!
121
     *
122
     * \throw CppRuntimeException When the reflected object is an array.
123
     *
124
     * \return The size of the serialized reflected object in bits.
125
     */
126
    virtual size_t bitSizeOf() const = 0;
127
128
    /**
129
     * Writes the reflected object to a bit stream using the given bit stream writer.
130
     *
131
     * \note Works for all reflectable types except arrays!
132
     *
133
     * \param writer Bit stream writer to use.
134
     *
135
     * \throw CppRuntimeException When the reflected object is an array.
136
     */
137
    virtual void write(BitStreamWriter& writer) const = 0;
138
139
    /**
140
     * Gets reflectable view to the field (i.e. member) with the given schema name.
141
     *
142
     * \note Can be called only when the reflected object is a zserio compound type.
143
     *
144
     * \param name Field schema name.
145
     *
146
     * \return Reflectable view to the requested field.
147
     *
148
     * \throw CppRuntimeException When the reflected object is not a compound type or when the field with
149
     *                            the given name doesn't exist or when the field getter itself throws.
150
     */
151
    /** \{ */
152
    virtual ConstPtr getField(StringView name) const = 0;
153
    virtual Ptr getField(StringView name) = 0;
154
    /** \} */
155
156
    /**
157
     * Sets the field (i.e. member) with the given schema name.
158
     *
159
     * \note For optional fields, the value can be also nullptr of type std::nullptr_t which allows
160
     *       to reset an optional field.
161
     *
162
     * \param name Field schema name.
163
     * \param value Value to set. The type must exactly match the type of the zserio field mapped to C++!
164
     *
165
     * \throw CppRuntimeException When the reflected object is not a compound type or when the field with
166
     *                            the given name doesn't exist or when the provided value is of a wrong type
167
     *                            or when the field setter itself throws.
168
     */
169
    virtual void setField(StringView name, const AnyHolder<ALLOC>& value) = 0;
170
171
    /**
172
     * Creates a default constructed field within current object and returns reflectable pointer to it.
173
     *
174
     * \note When the field already exists, it's reset with the new default constructed value.
175
     *
176
     * \param name Name of the optional field to create.
177
     *
178
     * \return Reflectable to just created object.
179
     *
180
     * \throw CppRuntimeException When the reflected object is not a compound type or when the field with
181
     *                            the given name doesn't exists.
182
     */
183
    virtual Ptr createField(StringView name) = 0;
184
185
    /**
186
     * Gets reflectable view to the parameter (i.e. member) with the given schema name.
187
     *
188
     * \note Can be called only when the reflected object is a zserio compound type.
189
     *
190
     * \param name Parameter schema name.
191
     *
192
     * \return Reflectable view to the requested parameter.
193
     *
194
     * \throw CppRuntimeException When the reflected object is not a compound type or when the parameter with
195
     *                            the given name doesn't exist or when the parameter getter itself throws.
196
     */
197
    /** \{ */
198
    virtual ConstPtr getParameter(StringView name) const = 0;
199
    virtual Ptr getParameter(StringView name) = 0;
200
    /** \} */
201
202
    /**
203
     * Calls function with the given name on the reflected zserio object and gets reflectable view to its
204
     * result.
205
     *
206
     * \note Can be called only when the reflected object is a zserio compound type.
207
     *
208
     * \param name Function schema name.
209
     *
210
     * \return Reflectable view to the value returns from the called function.
211
     *
212
     * \throw CppRuntimeException When the reflected object is not a compound type or when the function with
213
     *                            the given name doesn't exist or the the function call itself throws.
214
     */
215
    /** \{ */
216
    virtual ConstPtr callFunction(StringView name) const = 0;
217
    virtual Ptr callFunction(StringView name) = 0;
218
    /** \} */
219
220
    /**
221
     * Gets name of the field which is active in the reflected choice type.
222
     *
223
     * \note Applicable only on zserio unions and choices.
224
     *
225
     * \return Name of the active field (i.e. currently selected choice).
226
     *
227
     * \throw CppRuntimeException When the reflected object is not a choice type (or union).
228
     */
229
    virtual StringView getChoice() const = 0;
230
231
    /**
232
     * Universal accessor to zserio entities within the zserio sub-tree represented by the reflected object.
233
     *
234
     * Supports dot notation corresponding to the tree defined in zserio language. Can access fields or
235
     * parameters or call functions within the zserio sub-tree.
236
     *
237
     * Examples:
238
     * * 'fieldA.param' - Gets reflectable view to parameter 'param' within the parameterized field 'fieldA'.
239
     * * 'child.getValue' - Gets reflectable view to result of the function called on field ̈́'child'.
240
     * * 'child.nonexisting.field' - Gets nullptr since the path doesn't represent a valid entity.
241
     *
242
     * \param path Dot notation corresponding to the zserio tree.
243
     *
244
     * \return Reflectable view to the result of the given path. Returns nullptr when the path doesn't exist
245
     *         or when the requested operation throws CppRuntimeException.
246
     */
247
    /** \{ */
248
    virtual ConstPtr find(StringView path) const = 0;
249
    virtual Ptr find(StringView path) = 0;
250
    /** \} */
251
252
    /**
253
     * \copydoc IBasicReflectable::find
254
     *
255
     * Overloaded method provided for convenience.
256
     */
257
    /** \{ */
258
    virtual ConstPtr operator[](StringView path) const = 0;
259
    virtual Ptr operator[](StringView path) = 0;
260
    /** \} */
261
262
    /**
263
     * Gets size of the reflected array.
264
     *
265
     * \note Can be called only when the reflected object is an array.
266
     *
267
     * \return Size of the reflected array.
268
     *
269
     * \throw CppRuntimeException When the reflected object is not an array.
270
     */
271
    virtual size_t size() const = 0;
272
273
    /**
274
     * Resizes the reflected array.
275
     *
276
     * \note Can be called only when the reflected object is an array.
277
     *
278
     * \param size New array size.
279
     *
280
     * \throws CppRuntimeException When the reflected object is not an array.
281
     */
282
    virtual void resize(size_t size) = 0;
283
284
    /**
285
     * Gets reflectable view to an array element.
286
     *
287
     * \note Can be called only when the reflected object is an array.
288
     *
289
     * \return Reflectable view to an array element on the given index.
290
     *
291
     * \throw CppRuntimeException When the reflected object is not an array or when the given index is
292
     *                            out of bounds of the underlying array.
293
     */
294
    /** \{ */
295
    virtual ConstPtr at(size_t index) const = 0;
296
    virtual Ptr at(size_t index) = 0;
297
    /** \} */
298
299
    /**
300
     * \copydoc IBasicReflectable::at
301
     *
302
     * Overloaded method provided for convenience.
303
     */
304
    /** \{ */
305
    virtual ConstPtr operator[](size_t index) const = 0;
306
    virtual Ptr operator[](size_t index) = 0;
307
    /** \} */
308
309
    /**
310
     * Sets an element value at the given index within the reflected array.
311
     *
312
     * \param value Value to set.
313
     * \param index Index of the element to set.
314
     *
315
     * \throws CppRuntimeException When the reflected object is not an array.
316
     */
317
    virtual void setAt(const AnyHolder<ALLOC>& value, size_t index) = 0;
318
319
    /**
320
     * Appends an element at the given index within the reflected array.
321
     *
322
     * \param value Value to append.
323
     *
324
     * \throws CppRuntimeException When the reflected object is not an array.
325
     */
326
    virtual void append(const AnyHolder<ALLOC>& value) = 0;
327
328
    /**
329
     * Gets any value within the reflected object.
330
     *
331
     * For builtin types, enums and bitmasks the value is "returned by value" - i.e. it's copied
332
     * into the any holder, but note that for bytes the any holder contains Span,
333
     * for string the any holder contains an appropriate StringView and for compounds, bit buffers and arrays
334
     * the value is "returned by reference" - i.e. the any holder contains std::reference_wrapper<T> with the
335
     * reference to the compound type or the raw array type.
336
     *
337
     * \note For bit buffers only const reference is available.
338
     * \note Overloads without parameter use default constructed allocator.
339
     *
340
     * \param allocator Allocator to use for the value allocation.
341
     *
342
     * \return Any value.
343
     */
344
    /** \{ */
345
    virtual AnyHolder<ALLOC> getAnyValue(const ALLOC& allocator) const = 0;
346
    virtual AnyHolder<ALLOC> getAnyValue(const ALLOC& allocator) = 0;
347
    virtual AnyHolder<ALLOC> getAnyValue() const = 0;
348
    virtual AnyHolder<ALLOC> getAnyValue() = 0;
349
    /** \} */
350
351
    /**
352
     * Gets bool value of the bool reflectable.
353
     *
354
     * \return Bool value.
355
     * \throw CppRuntimeException When the reflected object is not a bool type.
356
     */
357
    virtual bool getBool() const = 0;
358
359
    /**
360
     * Gets 8-bit signed integral value of the int8_t reflectable.
361
     *
362
     * \return 8-bit signed integral value.
363
     * \throw CppRuntimeException When the reflected object is not a int8_t type.
364
     */
365
    virtual int8_t getInt8() const = 0;
366
367
    /**
368
     * Gets 16-bit signed integral value of the int16_t reflectable.
369
     *
370
     * \return 16-bit signed integral value.
371
     * \throw CppRuntimeException When the reflected object is not a int16_t type.
372
     */
373
    virtual int16_t getInt16() const = 0;
374
375
    /**
376
     * Gets 32-bit signed integral value of the int32_t reflectable.
377
     *
378
     * \return 32-bit signed integral value.
379
     * \throw CppRuntimeException When the reflected object is not a int32_t type.
380
     */
381
    virtual int32_t getInt32() const = 0;
382
383
    /**
384
     * Gets 64-bit signed integral value of the int64_t reflectable.
385
     *
386
     * \return 64-bit signed integral value.
387
     * \throw CppRuntimeException When the reflected object is not a int64_t type.
388
     */
389
    virtual int64_t getInt64() const = 0;
390
391
    /**
392
     * Gets 8-bit unsigned integral value of the uint8_t reflectable.
393
     *
394
     * \return 8-bit unsigned integral value.
395
     * \throw CppRuntimeException When the reflected object is not a uint8_t type.
396
     */
397
    virtual uint8_t getUInt8() const = 0;
398
399
    /**
400
     * Gets 16-bit unsigned integral value of the uint16_t reflectable.
401
     *
402
     * \return 16-bit unsigned integral value.
403
     * \throw CppRuntimeException When the reflected object is not a uint16_t type.
404
     */
405
    virtual uint16_t getUInt16() const = 0;
406
407
    /**
408
     * Gets 32-bit unsigned integral value of the uint32_t reflectable.
409
     *
410
     * \return 32-bit unsigned integral value.
411
     * \throw CppRuntimeException When the reflected object is not a uint32_t type.
412
     */
413
    virtual uint32_t getUInt32() const = 0;
414
415
    /**
416
     * Gets 64-bit unsigned integral value of the uint64_t reflectable.
417
     *
418
     * \return 64-bit unsigned integral value.
419
     * \throw CppRuntimeException When the reflected object is not a uint64_t type.
420
     */
421
    virtual uint64_t getUInt64() const = 0;
422
423
    /**
424
     * Gets float value of the float reflectable.
425
     *
426
     * \return Float value.
427
     * \throw CppRuntimeException When the reflected object is not a float type.
428
     */
429
    virtual float getFloat() const = 0;
430
431
    /**
432
     * Gets double value of the double reflectable.
433
     *
434
     * \return Double value.
435
     * \throw CppRuntimeException When the reflected object is not a double type.
436
     */
437
    virtual double getDouble() const = 0;
438
439
    /**
440
     * Gets byte value of the bytes reflectable.
441
     *
442
     * \return Bytes value as a span.
443
     * \throw CppRuntimeException When the reflected object is not a bytes type.
444
     */
445
    virtual Span<const uint8_t> getBytes() const = 0;
446
447
    /**
448
     * Gets reference to the string value of the string reflectable.
449
     *
450
     * \return Reference to the string value.
451
     * \throw CppRuntimeException When the reflected object is not a string type.
452
     */
453
    virtual StringView getStringView() const = 0;
454
455
    /**
456
     * Gets reference to the reflected bit buffer.
457
     *
458
     * \return Reference to the bit buffer.
459
     * \throw CppRuntimeException When the reflected object is not a bit buffer (i.e. extern type).
460
     */
461
    virtual const BasicBitBuffer<ALLOC>& getBitBuffer() const = 0;
462
463
    /**
464
     * Converts any signed integral value to 64-bit singed integer.
465
     *
466
     * Works also for enum types defined with signed underlying type.
467
     *
468
     * \return 64-bit signed integral value.
469
     * \throw CppRuntimeException When the reflected object cannot be converted to a signed integral value.
470
     */
471
    virtual int64_t toInt() const = 0;
472
473
    /**
474
     * Converts any unsigned integral value to 64-bit unsigned integer.
475
     *
476
     * Works also for bitmask and enum typed defined with unsigned underlying type.
477
     *
478
     * \return 64-bit unsigned integral value.
479
     * \throw CppRuntimeException When the reflected object cannot be converted to
480
     *                            an unsigned integral value.
481
     */
482
    virtual uint64_t toUInt() const = 0;
483
484
    /**
485
     * Converts any numeric value to double.
486
     *
487
     * Works also for bitmask and enum types.
488
     *
489
     * \return Double value.
490
     * \throw CppRuntimeException When the reflected object cannot be converted to double.
491
     */
492
    virtual double toDouble() const = 0;
493
494
    /**
495
     * Converts an reflected object to string.
496
     *
497
     * Works for all integral types including bool, bitmask and enum types and for string types.
498
     *
499
     * \note Floating point types are not currently supported!
500
     * \note The conversion to string can be implemented for more types in future versions.
501
     * \note Overload without parameter use default constructed allocator.
502
     *
503
     * \param allocator Allocator to use for the string allocation.
504
     *
505
     * \return String value representing the reflected object.
506
     */
507
    /** \{ */
508
    virtual string<ALLOC> toString(const ALLOC& allocator) const = 0;
509
    virtual string<ALLOC> toString() const = 0;
510
    /** \} */
511
};
512
513
/** Typedef to reflectable smart pointer needed for convenience in generated code. */
514
/** \{ */
515
template <typename ALLOC = std::allocator<uint8_t>>
516
using IBasicReflectablePtr = typename IBasicReflectable<ALLOC>::Ptr;
517
518
template <typename ALLOC = std::allocator<uint8_t>>
519
using IBasicReflectableConstPtr = typename IBasicReflectable<ALLOC>::ConstPtr;
520
/** \} */
521
522
/** Typedef to reflectable interface provided for convenience - using default std::allocator<uint8_t>. */
523
/** \{ */
524
using IReflectable = IBasicReflectable<>;
525
using IReflectablePtr = IBasicReflectablePtr<>;
526
using IReflectableConstPtr = IBasicReflectableConstPtr<>;
527
/** \} */
528
529
/**
530
 * Gets reflectable view for the given enum item.
531
 *
532
 * \param value Enum value to reflect.
533
 * \param allocator Allocator to use for reflectable allocation.
534
 *
535
 * \return Enum reflectable view.
536
 */
537
template <typename T, typename ALLOC = std::allocator<uint8_t>>
538
IBasicReflectablePtr<ALLOC> enumReflectable(T value, const ALLOC& allocator = ALLOC());
539
540
} // namespace zserio
541
542
#endif // ZSERIO_I_REFLECTABLE_H_INC