EmbeddedProto 4.0.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. EmbeddedProto/EmbeddedProto.py +122 -0
  2. EmbeddedProto/Features.py +255 -0
  3. EmbeddedProto/Field.py +1295 -0
  4. EmbeddedProto/Oneof.py +74 -0
  5. EmbeddedProto/ProtoFile.py +210 -0
  6. EmbeddedProto/TypeDefinitions.py +367 -0
  7. EmbeddedProto/__init__.py +0 -0
  8. EmbeddedProto/__main__.py +28 -0
  9. EmbeddedProto/config.py +173 -0
  10. EmbeddedProto/custom_header.py +513 -0
  11. EmbeddedProto/embedded_proto_options.proto +62 -0
  12. EmbeddedProto/embedded_proto_options_pb2.py +37 -0
  13. EmbeddedProto/field_options.py +344 -0
  14. EmbeddedProto/main.py +316 -0
  15. EmbeddedProto/src/EmbeddedProto/BytesStringCallback.h +476 -0
  16. EmbeddedProto/src/EmbeddedProto/Defines.h +118 -0
  17. EmbeddedProto/src/EmbeddedProto/EmptyArray.h +81 -0
  18. EmbeddedProto/src/EmbeddedProto/Errors.h +53 -0
  19. EmbeddedProto/src/EmbeddedProto/FieldStringBytes.h +793 -0
  20. EmbeddedProto/src/EmbeddedProto/Fields.h +832 -0
  21. EmbeddedProto/src/EmbeddedProto/Functional.h +412 -0
  22. EmbeddedProto/src/EmbeddedProto/MessageCallback.h +688 -0
  23. EmbeddedProto/src/EmbeddedProto/MessageInterface.h +792 -0
  24. EmbeddedProto/src/EmbeddedProto/MessageSizeCalculator.h +109 -0
  25. EmbeddedProto/src/EmbeddedProto/MessageState.h +207 -0
  26. EmbeddedProto/src/EmbeddedProto/ReadBufferFixedSize.h +204 -0
  27. EmbeddedProto/src/EmbeddedProto/ReadBufferInterface.h +181 -0
  28. EmbeddedProto/src/EmbeddedProto/ReadBufferSection.h +232 -0
  29. EmbeddedProto/src/EmbeddedProto/RepeatedField.h +1053 -0
  30. EmbeddedProto/src/EmbeddedProto/RepeatedFieldCallback.h +432 -0
  31. EmbeddedProto/src/EmbeddedProto/RepeatedFieldFixedSize.h +367 -0
  32. EmbeddedProto/src/EmbeddedProto/Version.h +39 -0
  33. EmbeddedProto/src/EmbeddedProto/WireFormatter.h +852 -0
  34. EmbeddedProto/src/EmbeddedProto/WriteBufferFixedSize.h +114 -0
  35. EmbeddedProto/src/EmbeddedProto/WriteBufferInterface.h +134 -0
  36. EmbeddedProto/src/EmbeddedProto.h +55 -0
  37. EmbeddedProto/templates/FieldBasic_Deserialize.h.jinja2 +26 -0
  38. EmbeddedProto/templates/FieldBasic_GetSet.h.jinja2 +89 -0
  39. EmbeddedProto/templates/FieldBytes_GetSet.h.jinja2 +86 -0
  40. EmbeddedProto/templates/FieldEnum_Deserialize.h.jinja2 +50 -0
  41. EmbeddedProto/templates/FieldEnum_GetSet.h.jinja2 +93 -0
  42. EmbeddedProto/templates/FieldErrorRecursive_GetSet.h.jinja2 +29 -0
  43. EmbeddedProto/templates/FieldMap_GetSet.h.jinja2 +203 -0
  44. EmbeddedProto/templates/FieldMsg_Deserialize.h.jinja2 +44 -0
  45. EmbeddedProto/templates/FieldMsg_GetSet.h.jinja2 +93 -0
  46. EmbeddedProto/templates/FieldRepeated_GetSet.h.jinja2 +94 -0
  47. EmbeddedProto/templates/FieldString_GetSet.h.jinja2 +86 -0
  48. EmbeddedProto/templates/Field_DeserializePartial.h.jinja2 +33 -0
  49. EmbeddedProto/templates/Field_Serialize.h.jinja2 +112 -0
  50. EmbeddedProto/templates/Field_SerializePartial.h.jinja2 +119 -0
  51. EmbeddedProto/templates/Header.h.jinja2 +108 -0
  52. EmbeddedProto/templates/TypeDefEnum.h.jinja2 +45 -0
  53. EmbeddedProto/templates/TypeDefMsg.h.jinja2 +791 -0
  54. EmbeddedProto/templates/TypeOneof.h.jinja2 +178 -0
  55. EmbeddedProto/version.json +3 -0
  56. embeddedproto-4.0.0b1.dist-info/METADATA +141 -0
  57. embeddedproto-4.0.0b1.dist-info/RECORD +63 -0
  58. embeddedproto-4.0.0b1.dist-info/WHEEL +5 -0
  59. embeddedproto-4.0.0b1.dist-info/entry_points.txt +3 -0
  60. embeddedproto-4.0.0b1.dist-info/licenses/LICENSE +30 -0
  61. embeddedproto-4.0.0b1.dist-info/licenses/LICENSES/GPL-3.0-only.txt +674 -0
  62. embeddedproto-4.0.0b1.dist-info/licenses/LICENSES/LicenseRef-EmbeddedProto-Commercial.txt +12 -0
  63. embeddedproto-4.0.0b1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1053 @@
1
+ /*
2
+ * Copyright (C) 2020-2026 Embedded AMS B.V. - All Rights Reserved
3
+ *
4
+ * This file is part of Embedded Proto.
5
+ *
6
+ * Embedded Proto is dual licensed. You may use it under the terms of the
7
+ * GNU General Public License version 3 (GPLv3) as published by the Free
8
+ * Software Foundation, or under a commercial license from Embedded AMS B.V.
9
+ *
10
+ * Under the GPLv3 you must release the source code of
11
+ * any product you distribute that includes Embedded Proto or code
12
+ * generated by it. A commercial license removes that obligation.
13
+ * See <https://embeddedproto.com/pricing/>.
14
+ *
15
+ * Embedded Proto is distributed WITHOUT ANY WARRANTY; without even the
16
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
+ * See the LICENSE file in the root of the repository for details.
18
+ *
19
+ * SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-EmbeddedProto-Commercial
20
+ *
21
+ * Embedded AMS B.V., Hoorn, the Netherlands - info at EmbeddedProto dot com
22
+ */
23
+
24
+ #ifndef _REPEATED_FIELD_H_
25
+ #define _REPEATED_FIELD_H_
26
+
27
+ #include "Defines.h"
28
+ #include "Fields.h"
29
+ #include "MessageInterface.h"
30
+ #include "MessageSizeCalculator.h"
31
+ #include "ReadBufferSection.h"
32
+ #include "FieldStringBytes.h"
33
+ #include "Errors.h"
34
+
35
+ #include <array>
36
+ #include <cstdint>
37
+ #include <type_traits>
38
+
39
+
40
+ namespace EmbeddedProto
41
+ {
42
+
43
+ namespace internal
44
+ {
45
+ //! Trait describing whether DATA_TYPE is a packed fixed-width scalar field.
46
+ /*!
47
+ Fixed-width scalar fields (fixed32/sfixed32/float and
48
+ fixed64/sfixed64/double) use the FIXED32 or FIXED64 wire type and store
49
+ their value in little-endian layout on a little-endian target. The trait
50
+ exposes both the detection flag and the raw scalar type so the packed
51
+ serialization paths can batch these values into whole-block / per-element
52
+ buffer writes. For any other type the primary template reports false.
53
+ */
54
+ template<typename T>
55
+ struct PackedFixedTraits
56
+ {
57
+ static constexpr bool is_fixed_width = false;
58
+ using scalar_type = uint8_t;
59
+ };
60
+
61
+ template<Field::FieldTypes F, typename V, WireFormatter::WireType W, uint32_t S>
62
+ struct PackedFixedTraits<::EmbeddedProto::FieldTemplate<F, V, W, S>>
63
+ {
64
+ static constexpr bool is_fixed_width =
65
+ (::EmbeddedProto::WireFormatter::WireType::FIXED32 == W)
66
+ || (::EmbeddedProto::WireFormatter::WireType::FIXED64 == W);
67
+ using scalar_type = V;
68
+ };
69
+ } // namespace internal
70
+
71
+ //! Class template that specifies the interface of an arry with the data type.
72
+ template<class DATA_TYPE>
73
+ class RepeatedField : public Field
74
+ {
75
+
76
+ //! Definition of a trait to check if DATA_TYPE is NOT a specialization of the FieldTemplate.
77
+ template<typename>
78
+ struct is_specialization_of_FieldTemplate : std::false_type {};
79
+
80
+ //! Definition of a trait to check if DATA_TYPE is a specialization of the FieldTemplate.
81
+ template<Field::FieldTypes F, typename V, WireFormatter::WireType W, uint32_t S>
82
+ struct is_specialization_of_FieldTemplate<::EmbeddedProto::FieldTemplate<F,V,W,S>> : std::true_type {};
83
+
84
+ //! Helper trait to extract wire type from a FieldTemplate specialization.
85
+ template<typename>
86
+ struct fieldtemplate_wire_type;
87
+
88
+ template<Field::FieldTypes F, typename V, WireFormatter::WireType W, uint32_t S>
89
+ struct fieldtemplate_wire_type<::EmbeddedProto::FieldTemplate<F, V, W, S>>
90
+ {
91
+ static constexpr ::EmbeddedProto::WireFormatter::WireType value = W;
92
+ };
93
+
94
+ //! Helper trait to extract the field type from a FieldTemplate specialization.
95
+ template<typename>
96
+ struct fieldtemplate_field_type;
97
+
98
+ template<Field::FieldTypes F, typename V, WireFormatter::WireType W, uint32_t S>
99
+ struct fieldtemplate_field_type<::EmbeddedProto::FieldTemplate<F, V, W, S>>
100
+ {
101
+ static constexpr Field::FieldTypes value = F;
102
+ };
103
+
104
+ //! Helper trait telling if DATA_TYPE is a scalar or enum which goes on the wire as a varint.
105
+ template<typename>
106
+ struct is_varint_field : std::false_type {};
107
+
108
+ template<Field::FieldTypes F, typename V, WireFormatter::WireType W, uint32_t S>
109
+ struct is_varint_field<::EmbeddedProto::FieldTemplate<F, V, W, S>>
110
+ : std::integral_constant<bool, WireFormatter::WireType::VARINT == W> {};
111
+
112
+ //! Whether a packed block of this field holds varints, the case the windowed decode covers.
113
+ static constexpr bool PACKED_VARINT_ELEMENTS = is_varint_field<DATA_TYPE>::value;
114
+
115
+ //! The number of bytes peeked at once when decoding packed varint elements.
116
+ static constexpr uint32_t PACKED_VARINT_WINDOW_N_BYTES = 32U;
117
+
118
+ // A window holds at least one whole varint, so an element cut by the window end always
119
+ // follows decoded bytes and the next window starts with it.
120
+ static_assert(WireFormatter::VARINT_MAX_N_BYTES <= PACKED_VARINT_WINDOW_N_BYTES,
121
+ "The packed varint window must hold the largest varint.");
122
+
123
+ //! This class only supports Field and FieldTemplate classes as template parameter.
124
+ static_assert(std::is_base_of<::EmbeddedProto::Field, DATA_TYPE>::value || is_specialization_of_FieldTemplate<DATA_TYPE>::value,
125
+ "A Field can only be used as template paramter.");
126
+
127
+ public:
128
+
129
+ //! Check how this field shoeld be serialized, packed or not.
130
+ static constexpr bool REPEATED_FIELD_IS_PACKED =
131
+ !(std::is_base_of<MessageInterface, DATA_TYPE>::value
132
+ || std::is_base_of<internal::BaseStringBytes, DATA_TYPE>::value);
133
+
134
+
135
+ RepeatedField() = default;
136
+ ~RepeatedField() = default;
137
+
138
+ //! Obtain the total number of DATA_TYPE items in the array.
139
+ virtual uint32_t get_length() const = 0;
140
+
141
+ //! Obtain the maximum number of DATA_TYPE items which can at most be stored in the array.
142
+ virtual uint32_t get_max_length() const = 0;
143
+
144
+ //! Obtain the total number of bytes currently stored in the array.
145
+ virtual uint32_t get_size() const = 0;
146
+
147
+ //! Obtain the maximum number of bytes which can at most be stored in the array.
148
+ virtual uint32_t get_max_size() const = 0;
149
+
150
+ //! Get a reference to the value at the given index.
151
+ /*!
152
+ \param[in] index The desired index to return.
153
+ \return The reference to the value at the given index.
154
+ */
155
+ virtual DATA_TYPE& get(uint32_t index) = 0;
156
+
157
+ //! Get a constant reference to the value at the given index.
158
+ /*!
159
+ \param[in] index The desired index to return.
160
+ \return The constant reference to the value at the given index.
161
+ */
162
+ virtual const DATA_TYPE& get_const(uint32_t index) const = 0;
163
+
164
+ //! Get a constant reference to the value at the given index.
165
+ /*!
166
+ \param[in] index The desired index to return.
167
+ \param[out] value The value of the desired index is set in this reference.
168
+ \return An error incase of an index out of bound situation.
169
+ */
170
+ virtual Error get_const(const uint32_t index, DATA_TYPE& value) const = 0;
171
+
172
+ //! Get a reference to the value at the given index.
173
+ /*!
174
+ \param[in] index The desired index to return.
175
+ \return The reference to the value at the given index.
176
+ */
177
+ DATA_TYPE& operator[](uint32_t index) { return this->get(index); }
178
+
179
+ //! Get a reference to the value at the given index. But constant.
180
+ /*!
181
+ \param[in] index The desired index to return.
182
+ \return The constant reference to the value at the given index.
183
+ */
184
+ const DATA_TYPE& operator[](uint32_t index) const { return this->get_const(index); }
185
+
186
+ //! Set the value at the given index.
187
+ /*!
188
+ \param[in] index The desired index to change.
189
+ \param[in] value The value we would like to set.
190
+ */
191
+ virtual void set(uint32_t index, const DATA_TYPE& value) = 0;
192
+
193
+ //! Given a view on a different array copy that data into this object.
194
+ /*!
195
+ \param[in] data A view on the array to copy from, data.size values of DATA_TYPE are copied.
196
+ \return Error::NO_ERRORS when every was successful. Error::ARRAY_FULL when there is no space left.
197
+ */
198
+ virtual Error set_data(const array_view<const DATA_TYPE>& data) = 0;
199
+
200
+ //! Copy an array into this object, pointer and length form of set_data(const array_view<const DATA_TYPE>&).
201
+ /*!
202
+ \deprecated Use the array_view overload set_data(const array_view<const DATA_TYPE>&), a
203
+ view keeps the pointer and its bound together.
204
+ \param[in] data A pointer the array to copy from.
205
+ \param[in] length The number of value of DATA_TYPE in the array.
206
+ \return Error::NO_ERRORS when every was successful. Error::ARRAY_FULL when there is no space left.
207
+ */
208
+ [[deprecated("use the array_view overload set_data(const array_view<const DATA_TYPE>&)")]]
209
+ virtual Error set_data(const DATA_TYPE* data, const uint32_t length)
210
+ {
211
+ return set_data(array_view<const DATA_TYPE>{data, length});
212
+ }
213
+
214
+ //! Append a value to the end of the array.
215
+ /*!
216
+ \param[in] value The data to add.
217
+ \return Error::NO_ERRORS when every was successful. Error::ARRAY_FULL when there is no space left.
218
+ */
219
+ virtual Error add(const DATA_TYPE& value) = 0;
220
+
221
+ //! Remove the element at the given index, moving the elements behind it one place forward.
222
+ /*!
223
+ The default implementation reports INDEX_OUT_OF_BOUND. Storage types which hold no
224
+ resident collection, like the streaming callback storage, keep that behaviour; storage
225
+ types which can shrink override this function. Used among others to remove a key from a
226
+ map field.
227
+
228
+ \param[in] index The index of the element to remove.
229
+ \return Error::NO_ERRORS when the element was removed. Error::INDEX_OUT_OF_BOUND when the
230
+ index is outside of the data held or this storage type can not remove elements.
231
+ */
232
+ virtual Error erase(const uint32_t index)
233
+ {
234
+ static_cast<void>(index);
235
+ return Error::INDEX_OUT_OF_BOUND;
236
+ }
237
+
238
+ //! Remove all data in the array and set it to the default value.
239
+ virtual void clear() override = 0;
240
+
241
+ //! Serialize all elements in the array (used for packed serialization).
242
+ /*!
243
+ Not final: RepeatedFieldFixedSize overrides this to batch packed
244
+ fixed-width payloads into a single whole-block buffer write.
245
+ */
246
+ Error serialize(WriteBufferInterface& buffer) const override
247
+ {
248
+ Error return_value = Error::NO_ERRORS;
249
+ for(uint32_t i = 0; (i < this->get_length()) && (Error::NO_ERRORS == return_value); ++i)
250
+ {
251
+ return_value = this->get_const(i).serialize(buffer);
252
+ }
253
+ return return_value;
254
+ }
255
+
256
+ //! Function to deserialize this array.
257
+ /*!
258
+ From a buffer of data fill this array with data.
259
+ Not final: RepeatedFieldFixedSize overrides this to read a packed
260
+ fixed-width payload out of the buffer in a single batched block read
261
+ instead of one virtual call per byte.
262
+ \param buffer [in] The memory from which the message is obtained.
263
+ \return Error::NO_ERRORS when every was successful.
264
+ */
265
+ Error deserialize(::EmbeddedProto::ReadBufferInterface& buffer) override
266
+ {
267
+ Error return_value = Error::NO_ERRORS;
268
+ if(REPEATED_FIELD_IS_PACKED)
269
+ {
270
+ return_value = deserialize_packed(buffer);
271
+ }
272
+ else
273
+ {
274
+ return_value = deserialize_unpacked(buffer);
275
+ }
276
+ return return_value;
277
+ }
278
+
279
+ //! Not final: RepeatedFieldCallback overrides this so expanded
280
+ //! (one-tag-per-element) scalar input is funnelled through the virtual
281
+ //! add() hook instead of the random-access get(index) slot it lacks.
282
+ Error deserialize_check_type(::EmbeddedProto::ReadBufferInterface& buffer,
283
+ const ::EmbeddedProto::WireFormatter::WireType& wire_type) override
284
+ {
285
+ const bool is_length_delimited =
286
+ ::EmbeddedProto::WireFormatter::WireType::LENGTH_DELIMITED == wire_type;
287
+ Error return_value = Error::NO_ERRORS;
288
+
289
+ if(REPEATED_FIELD_IS_PACKED)
290
+ {
291
+ // Scalar / enum elements may be received either as a single packed block
292
+ // (length-delimited) or as expanded one-tag-per-element values (the
293
+ // element's own wire type). Both forms are accepted regardless of which
294
+ // form this side emits (repeated_field_encoding feature).
295
+ if(is_length_delimited)
296
+ {
297
+ // Route through the virtual deserialize() so RepeatedFieldFixedSize's
298
+ // whole-block fast path is reached on the generated receive path.
299
+ return_value = this->deserialize(buffer);
300
+ }
301
+ else
302
+ {
303
+ return_value = deserialize_unpacked(buffer);
304
+ }
305
+ }
306
+ else
307
+ {
308
+ // Message / string / bytes elements are always length-delimited, one per
309
+ // tag.
310
+ return_value = is_length_delimited ? deserialize_unpacked(buffer)
311
+ : Error::INVALID_WIRETYPE;
312
+ }
313
+
314
+ return return_value;
315
+ }
316
+
317
+ #ifdef PARTIAL_SERIALIZATION_ENABLED
318
+ Error deserialize_partial_as_field(ReadBufferInterface& buffer,
319
+ MessageState& state) override
320
+ {
321
+ Error return_value = Error::NO_ERRORS;
322
+
323
+ if(REPEATED_FIELD_IS_PACKED)
324
+ {
325
+ if((::EmbeddedProto::FieldProcessingPhase::SIZE != state.phase) && (::EmbeddedProto::FieldProcessingPhase::DATA != state.phase))
326
+ {
327
+ return_value = Error::STATE_MISMATCH;
328
+ }
329
+
330
+ if((Error::NO_ERRORS == return_value) && (::EmbeddedProto::FieldProcessingPhase::SIZE == state.phase))
331
+ {
332
+ return_value = deserialize_partial_size_phase(buffer, state);
333
+ }
334
+
335
+ if((Error::NO_ERRORS == return_value) && (::EmbeddedProto::FieldProcessingPhase::DATA == state.phase))
336
+ {
337
+ ReadBufferSection section(buffer, state.bytes_remaining);
338
+ const uint32_t section_size_before = section.get_size();
339
+ Error element_result = Error::NO_ERRORS;
340
+
341
+ if constexpr(PACKED_VARINT_ELEMENTS)
342
+ {
343
+ Error add_result = Error::NO_ERRORS;
344
+ element_result = deserialize_packed_varints(section, state.element_index, add_result);
345
+ if(Error::NO_ERRORS != add_result)
346
+ {
347
+ return_value = Error::ARRAY_FULL;
348
+ element_result = Error::ARRAY_FULL;
349
+ }
350
+ }
351
+ else
352
+ {
353
+ DATA_TYPE element;
354
+ element_result = deserialize_packed_partial_element(element, section);
355
+
356
+ while(Error::NO_ERRORS == element_result)
357
+ {
358
+ return_value = this->add(element);
359
+ if(Error::NO_ERRORS == return_value)
360
+ {
361
+ ++state.element_index;
362
+ element_result = deserialize_packed_partial_element(element, section);
363
+ }
364
+ else
365
+ {
366
+ return_value = Error::ARRAY_FULL;
367
+ element_result = Error::ARRAY_FULL;
368
+ }
369
+ }
370
+ }
371
+
372
+ const uint32_t section_size_after = section.get_size();
373
+ const uint32_t bytes_consumed = section_size_before - section_size_after;
374
+ state.bytes_remaining -= bytes_consumed;
375
+
376
+ if(Error::NO_ERRORS == return_value)
377
+ {
378
+ if(0U == state.bytes_remaining)
379
+ {
380
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
381
+ return_value = Error::NO_ERRORS;
382
+ }
383
+ else if(Error::END_OF_BUFFER == element_result)
384
+ {
385
+ return_value = Error::END_OF_BUFFER;
386
+ }
387
+ else
388
+ {
389
+ return_value = element_result;
390
+ }
391
+ }
392
+ }
393
+ }
394
+ else
395
+ {
396
+ if((::EmbeddedProto::FieldProcessingPhase::SIZE != state.phase) && (::EmbeddedProto::FieldProcessingPhase::DATA != state.phase))
397
+ {
398
+ return_value = Error::STATE_MISMATCH;
399
+ }
400
+
401
+ if(Error::NO_ERRORS == return_value)
402
+ {
403
+ if constexpr(std::is_base_of<Field, DATA_TYPE>::value)
404
+ {
405
+ // Non-packed repeated string/bytes/message element. Each wire
406
+ // occurrence is a separate tag/size/data cycle, and the message loop
407
+ // resets element_index to zero between occurrences. Elements are
408
+ // therefore accumulated based on the current array length rather than
409
+ // element_index. element_index is reused purely as a per-occurrence
410
+ // flag marking that the slot for the current element has already been
411
+ // reserved, so an element split across buffers is not appended twice.
412
+ if(0U == state.element_index)
413
+ {
414
+ if(this->get_max_length() <= this->get_length())
415
+ {
416
+ return_value = Error::ARRAY_FULL;
417
+ }
418
+ else
419
+ {
420
+ // Reserve a slot for this new element.
421
+ (void)this->get(this->get_length());
422
+ state.element_index = 1U;
423
+ }
424
+ }
425
+
426
+ if(Error::NO_ERRORS == return_value)
427
+ {
428
+ return_value = this->get(this->get_length() - 1U).deserialize_partial_as_field(buffer, state);
429
+ }
430
+ }
431
+ else
432
+ {
433
+ if(::EmbeddedProto::FieldProcessingPhase::DATA != state.phase)
434
+ {
435
+ return_value = Error::STATE_MISMATCH;
436
+ }
437
+ else
438
+ {
439
+ DATA_TYPE value;
440
+ return_value = value.deserialize_partial_check_type(
441
+ buffer,
442
+ state,
443
+ fieldtemplate_wire_type<DATA_TYPE>::value);
444
+ if(Error::NO_ERRORS == return_value)
445
+ {
446
+ return_value = this->add(value);
447
+ if(Error::NO_ERRORS != return_value)
448
+ {
449
+ return_value = Error::ARRAY_FULL;
450
+ }
451
+ }
452
+ }
453
+ }
454
+ }
455
+ }
456
+
457
+ return return_value;
458
+ }
459
+
460
+ Error serialize_partial_as_field(uint32_t field_number,
461
+ WriteBufferInterface& buffer,
462
+ MessageState& state,
463
+ bool optional) const override
464
+ {
465
+ // Skip serializing empty non-optional repeated fields (proto3 default behavior).
466
+ if((!optional) && (0U == this->get_length()))
467
+ {
468
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
469
+ return Error::NO_ERRORS;
470
+ }
471
+
472
+ return REPEATED_FIELD_IS_PACKED
473
+ ? serialize_partial_packed(field_number, buffer, state, optional)
474
+ : serialize_partial_unpacked(field_number, buffer, state);
475
+ }
476
+
477
+ //! Serialize a repeated scalar/enum field in EXPANDED form with partial state
478
+ //! support, regardless of the element type's default packing.
479
+ /*!
480
+ Used for the editions repeated_field_encoding = EXPANDED feature so that
481
+ chunked (partial) serialization emits the same one-tag-per-element bytes
482
+ as full serialization instead of a single packed block.
483
+ */
484
+ Error serialize_partial_as_field_expanded(uint32_t field_number,
485
+ WriteBufferInterface& buffer,
486
+ MessageState& state,
487
+ bool optional) const
488
+ {
489
+ // Skip serializing empty non-optional repeated fields (proto3 default behavior).
490
+ if((!optional) && (0U == this->get_length()))
491
+ {
492
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
493
+ return Error::NO_ERRORS;
494
+ }
495
+
496
+ return serialize_partial_unpacked(field_number, buffer, state);
497
+ }
498
+
499
+ private:
500
+ //! Serialize a single packed element with one all-or-nothing push.
501
+ /*!
502
+ Every scalar element is written with a single push(const_bytes_view) call.
503
+ Fixed-width values push their little-endian bytes directly, varint values
504
+ (integers, bools and enums) are first encoded into a local array. This
505
+ keeps the resumable partial path correct: when the element does not fit,
506
+ nothing is written so bytes_remaining / element_index stay untouched and
507
+ the element is retried cleanly on the next call. Message and string
508
+ elements are never packed and keep their own serialization.
509
+ */
510
+ Error serialize_packed_element(uint32_t index, WriteBufferInterface& buffer) const
511
+ {
512
+ return serialize_packed_element_(index, buffer,
513
+ std::integral_constant<bool, internal::PackedFixedTraits<DATA_TYPE>::is_fixed_width>{});
514
+ }
515
+
516
+ Error serialize_packed_element_(uint32_t index, WriteBufferInterface& buffer,
517
+ std::true_type) const
518
+ {
519
+ using VAR = typename internal::PackedFixedTraits<DATA_TYPE>::scalar_type;
520
+ const VAR value = this->get_const(index).get();
521
+ return WireFormatter::SerializeFixedArrayNoTag(array_view<const VAR>{&value, 1U}, buffer);
522
+ }
523
+
524
+ Error serialize_packed_element_(uint32_t index, WriteBufferInterface& buffer,
525
+ std::false_type) const
526
+ {
527
+ Error return_value = Error::NO_ERRORS;
528
+ if constexpr(is_specialization_of_FieldTemplate<DATA_TYPE>::value)
529
+ {
530
+ std::array<uint8_t, WireFormatter::VARINT_MAX_N_BYTES> bytes = {0};
531
+ const uint32_t n_bytes = WireFormatter::EncodeVarint(
532
+ packed_varint_value(this->get_const(index)), bytes);
533
+ return_value = buffer.push(const_bytes_view{bytes.data(), n_bytes}) ? Error::NO_ERRORS
534
+ : Error::BUFFER_FULL;
535
+ }
536
+ else
537
+ {
538
+ return_value = this->get_const(index).serialize(buffer);
539
+ }
540
+ return return_value;
541
+ }
542
+
543
+ //! Return the value of a varint element as it goes on the wire, zero extended to 64 bits.
544
+ /*!
545
+ Mirrors the conversions of the matching FieldTemplate::serialize(): int32 and
546
+ enum values are truncated to 32 bits, sint32 and sint64 values are zig-zag
547
+ encoded and a bool becomes 0 or 1. This way one encoder produces the same
548
+ bytes for every varint element type as full serialization does.
549
+ */
550
+ static uint64_t packed_varint_value(const DATA_TYPE& element)
551
+ {
552
+ constexpr Field::FieldTypes FIELD_TYPE = fieldtemplate_field_type<DATA_TYPE>::value;
553
+ uint64_t value = 0U;
554
+ if constexpr((Field::FieldTypes::sint32 == FIELD_TYPE)
555
+ || (Field::FieldTypes::sint64 == FIELD_TYPE))
556
+ {
557
+ value = static_cast<uint64_t>(WireFormatter::ZigZagEncode(element.get()));
558
+ }
559
+ else if constexpr(Field::FieldTypes::boolean == FIELD_TYPE)
560
+ {
561
+ value = element.get() ? 1U : 0U;
562
+ }
563
+ else if constexpr((Field::FieldTypes::int32 == FIELD_TYPE)
564
+ || (Field::FieldTypes::enumeration == FIELD_TYPE))
565
+ {
566
+ value = static_cast<uint64_t>(static_cast<uint32_t>(element.get()));
567
+ }
568
+ else
569
+ {
570
+ // int64, uint32 and uint64 convert directly.
571
+ value = static_cast<uint64_t>(element.get());
572
+ }
573
+ return value;
574
+ }
575
+
576
+ //! Packed partial serialization: TAG->SIZE->DATA over one length-delimited block.
577
+ Error serialize_partial_packed(uint32_t field_number,
578
+ WriteBufferInterface& buffer,
579
+ MessageState& state,
580
+ bool optional) const
581
+ {
582
+ Error return_value = Error::NO_ERRORS;
583
+
584
+ if(::EmbeddedProto::FieldProcessingPhase::DATA != state.phase)
585
+ {
586
+ // Calculate total packed size
587
+ const uint32_t total_size = serialized_size_packed();
588
+ return_value = serialize_partial_tag_and_size(field_number, total_size, buffer, state, optional);
589
+ }
590
+
591
+ if((Error::NO_ERRORS == return_value) && (::EmbeddedProto::FieldProcessingPhase::DATA == state.phase))
592
+ {
593
+ // Serialize elements sequentially
594
+ if(state.element_index < this->get_length())
595
+ {
596
+ const uint32_t initial_size = buffer.get_size();
597
+ return_value = serialize_packed_element(state.element_index, buffer);
598
+ const uint32_t bytes_written = buffer.get_size() - initial_size;
599
+ state.bytes_remaining -= bytes_written;
600
+
601
+ if(Error::NO_ERRORS == return_value)
602
+ {
603
+ ++state.element_index;
604
+ }
605
+
606
+ if(0 == state.bytes_remaining)
607
+ {
608
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
609
+ }
610
+ }
611
+ else
612
+ {
613
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
614
+ }
615
+ }
616
+
617
+ return return_value;
618
+ }
619
+
620
+ //! Unpacked (expanded) partial serialization: each element gets its own tag.
621
+ Error serialize_partial_unpacked(uint32_t field_number,
622
+ WriteBufferInterface& buffer,
623
+ MessageState& state) const
624
+ {
625
+ Error return_value = Error::NO_ERRORS;
626
+
627
+ if(state.phase == ::EmbeddedProto::FieldProcessingPhase::COMPLETE)
628
+ {
629
+ // All elements serialized
630
+ return return_value;
631
+ }
632
+
633
+ // Handle current element
634
+ if(state.element_index < this->get_length())
635
+ {
636
+ const auto& element = this->get_const(state.element_index);
637
+
638
+ // Check if element is a Field-derived type (messages, strings, bytes) or scalar type
639
+ if constexpr(std::is_base_of<Field, DATA_TYPE>::value)
640
+ {
641
+ // Field-derived types (messages, strings, bytes) use serialize_partial_as_field
642
+ return_value = element.serialize_partial_as_field(field_number, buffer, state, true);
643
+ }
644
+ else
645
+ {
646
+ // Scalar types use serialize_partial_with_id
647
+ return_value = element.serialize_partial_with_id(field_number, buffer, state, true);
648
+ }
649
+
650
+ if((Error::NO_ERRORS == return_value) && (state.phase == ::EmbeddedProto::FieldProcessingPhase::COMPLETE))
651
+ {
652
+ // Element complete, move to next
653
+ ++state.element_index;
654
+ // Reset child state for next element to avoid stale COMPLETE phase
655
+ // in nested message serialization.
656
+ if(nullptr != state.child)
657
+ {
658
+ state.child->reset();
659
+ }
660
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::TAG; // Reset for next element
661
+ }
662
+ }
663
+ else
664
+ {
665
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
666
+ }
667
+
668
+ return return_value;
669
+ }
670
+
671
+ public:
672
+ #endif
673
+
674
+
675
+ //! Calculate the size of this field when serialized.
676
+ /*!
677
+ The calculation only includes the data, not the size required by the tag and
678
+ \return The number of bytes this field will require once serialized.
679
+ */
680
+ uint32_t serialized_size_packed() const
681
+ {
682
+ ::EmbeddedProto::MessageSizeCalculator calcBuffer;
683
+ serialize(calcBuffer);
684
+ return calcBuffer.get_size();
685
+ }
686
+
687
+ //! Calculate the size of this field when serialized.
688
+ /*!
689
+ \return The number of bytes this field will require once serialized.
690
+ */
691
+ uint32_t serialized_size_unpacked(int32_t field_number) const
692
+ {
693
+ ::EmbeddedProto::MessageSizeCalculator calcBuffer;
694
+ serialize_unpacked(field_number, calcBuffer);
695
+ return calcBuffer.get_size();
696
+ }
697
+
698
+ #ifdef MSG_TO_STRING
699
+
700
+ ::EmbeddedProto::string_view to_string(::EmbeddedProto::string_view& str, const uint32_t indent_level, char const* name, const bool first_field) const override
701
+ {
702
+ ::EmbeddedProto::string_view left_chars = str;
703
+ int32_t n_chars_used = 0;
704
+
705
+ if(!first_field)
706
+ {
707
+ // Add a comma behind the previous field.
708
+ n_chars_used = snprintf(left_chars.data, left_chars.size, ",\n");
709
+ if(0 < n_chars_used)
710
+ {
711
+ // Update the character pointer and characters left in the array.
712
+ const int32_t actual_chars_used = EmbeddedProto::min(n_chars_used, left_chars.size);
713
+ left_chars.data += actual_chars_used;
714
+ left_chars.size -= actual_chars_used;
715
+ }
716
+ }
717
+
718
+ n_chars_used = snprintf(left_chars.data, left_chars.size, "%*s\"%s\": [\n", indent_level, " ", name );
719
+
720
+ if(0 < n_chars_used)
721
+ {
722
+ const int32_t actual_chars_used = EmbeddedProto::min(n_chars_used, left_chars.size);
723
+ left_chars.data += actual_chars_used;
724
+ left_chars.size -= actual_chars_used;
725
+ }
726
+
727
+ for(uint32_t i = 0; i < this->get_length(); ++i)
728
+ {
729
+ left_chars = this->get_const(i).to_string(left_chars, n_chars_used, nullptr, (0 == i));
730
+ }
731
+
732
+ n_chars_used = snprintf(left_chars.data, left_chars.size, "\n%*s]", n_chars_used - 2, " ");
733
+
734
+ if(0 < n_chars_used)
735
+ {
736
+ const int32_t actual_chars_used = EmbeddedProto::min(n_chars_used, left_chars.size);
737
+ left_chars.data += actual_chars_used;
738
+ left_chars.size -= actual_chars_used;
739
+ }
740
+
741
+ return left_chars;
742
+ }
743
+
744
+ #endif // End of MSG_TO_STRING
745
+
746
+ private:
747
+
748
+ Error serialize_unpacked(uint32_t field_number, WriteBufferInterface& buffer) const
749
+ {
750
+ Error return_value = Error::NO_ERRORS;
751
+ for(uint32_t i = 0; (i < this->get_length()) && (Error::NO_ERRORS == return_value); ++i)
752
+ {
753
+ // Each element gets its own [tag][size][data]
754
+ // Note: serialize_len() is only available on Field-derived types (messages, strings, bytes)
755
+ // which is exactly what unpacked mode is used for.
756
+ const uint32_t size_x = this->get_const(i).serialized_size();
757
+ uint32_t tag = WireFormatter::MakeTag(field_number,
758
+ WireFormatter::WireType::LENGTH_DELIMITED);
759
+ return_value = WireFormatter::SerializeVarint(tag, buffer);
760
+ if(Error::NO_ERRORS == return_value)
761
+ {
762
+ return_value = WireFormatter::SerializeVarint(size_x, buffer);
763
+ if((Error::NO_ERRORS == return_value) && (0 < size_x))
764
+ {
765
+ return_value = this->get_const(i).serialize(buffer);
766
+ }
767
+ }
768
+ }
769
+ return return_value;
770
+ }
771
+
772
+ protected:
773
+
774
+ //! Deserialize one packed length-delimited block into this array.
775
+ /*!
776
+ Non-virtual helper (no vtable slot): the fixed-width whole-block fast
777
+ path lives in RepeatedFieldFixedSize's deserialize() override, which
778
+ reuses the existing Field::deserialize slot.
779
+ */
780
+ Error deserialize_packed(ReadBufferInterface& buffer)
781
+ {
782
+ uint32_t size = 0;
783
+ Error return_value = WireFormatter::DeserializeVarint(buffer, size);
784
+ ReadBufferSection bufferSection(buffer, size);
785
+ return_value = deserialize_packed_section(bufferSection);
786
+ return return_value;
787
+ }
788
+
789
+ //! Element-by-element loop over an already length-bounded packed section.
790
+ /*!
791
+ The caller must pass a buffer bounded to the packed block (a
792
+ ReadBufferSection); the loop reads elements until it is exhausted
793
+ (END_OF_BUFFER, the expected clean end, mapped back to NO_ERRORS) or an
794
+ error occurs. Takes the base ReadBufferInterface: the boundary is
795
+ enforced by the section object through virtual dispatch, so the concrete
796
+ type is not needed here. Shared with the fixed-width override for its
797
+ fall-back cases. Varint elements are decoded through a local window, see
798
+ deserialize_packed_varints().
799
+ */
800
+ Error deserialize_packed_section(ReadBufferInterface& buffer)
801
+ {
802
+ Error return_value = Error::NO_ERRORS;
803
+
804
+ if constexpr(PACKED_VARINT_ELEMENTS)
805
+ {
806
+ uint32_t n_elements = 0U;
807
+ Error add_result = Error::NO_ERRORS;
808
+ return_value = deserialize_packed_varints(buffer, n_elements, add_result);
809
+ if(Error::NO_ERRORS != add_result)
810
+ {
811
+ return_value = add_result;
812
+ }
813
+ }
814
+ else
815
+ {
816
+ DATA_TYPE x;
817
+
818
+ return_value = x.deserialize(buffer);
819
+ while(Error::NO_ERRORS == return_value)
820
+ {
821
+ return_value = this->add(x);
822
+ if(Error::NO_ERRORS == return_value)
823
+ {
824
+ return_value = x.deserialize(buffer);
825
+ }
826
+ }
827
+ }
828
+
829
+ // We expect the buffersection to be empty, in that case everything is fine..
830
+ if(Error::END_OF_BUFFER == return_value)
831
+ {
832
+ return_value = Error::NO_ERRORS;
833
+ }
834
+
835
+ return return_value;
836
+ }
837
+
838
+ private:
839
+
840
+ Error deserialize_unpacked(ReadBufferInterface& buffer)
841
+ {
842
+ Error return_value = Error::NO_ERRORS;
843
+
844
+ // For repeated messages, strings or bytes
845
+ // First allocate an element in the array.
846
+ const uint32_t index = this->get_length();
847
+ if(this->get_max_length() > index)
848
+ {
849
+ // For messages read the size here, with strings and byte arrays this is include in
850
+ // deserialize.
851
+ if(std::is_base_of<MessageInterface, DATA_TYPE>::value)
852
+ {
853
+ uint32_t size;
854
+ return_value = WireFormatter::DeserializeVarint(buffer, size);
855
+ if(Error::NO_ERRORS == return_value)
856
+ {
857
+ ReadBufferSection bufferSection(buffer, size);
858
+ return_value = this->get(index).deserialize(bufferSection);
859
+ if((Error::END_OF_BUFFER == return_value) && (0U == size))
860
+ {
861
+ // An element of size zero is a valid empty message, see
862
+ // MessageInterface::deserialize_check_type.
863
+ return_value = Error::NO_ERRORS;
864
+ }
865
+ }
866
+ }
867
+ else
868
+ {
869
+ return_value = this->get(index).deserialize(buffer);
870
+ }
871
+ }
872
+ else
873
+ {
874
+ return_value = Error::ARRAY_FULL;
875
+ }
876
+
877
+ return return_value;
878
+ }
879
+
880
+ //! Decode the packed varint elements of a section through a local window and add them.
881
+ /*!
882
+ The section is peeked in blocks of up to PACKED_VARINT_WINDOW_N_BYTES, one
883
+ buffer call for several elements instead of one per byte. The elements are
884
+ decoded from the local copy and the section is advanced by the bytes they took.
885
+ An element cut by the window end is decoded from the next window. An element
886
+ cut by the section end consumes nothing, so a partial deserialization resumes
887
+ at that element once more data arrived. An element which does not fit the
888
+ array is consumed, as it is when read element by element.
889
+
890
+ \param[in] buffer The section holding the packed block.
891
+ \param[out] n_elements Incremented for every element added.
892
+ \param[out] add_result The result of the add() which stopped the loop, NO_ERRORS when none did.
893
+ \return END_OF_BUFFER when the section is exhausted or ends inside an element, a
894
+ decoding error, or NO_ERRORS when add() stopped the loop.
895
+ */
896
+ Error deserialize_packed_varints(ReadBufferInterface& buffer, uint32_t& n_elements, Error& add_result)
897
+ {
898
+ std::array<uint8_t, PACKED_VARINT_WINDOW_N_BYTES> window = {0};
899
+ DATA_TYPE element;
900
+ Error return_value = Error::NO_ERRORS;
901
+ add_result = Error::NO_ERRORS;
902
+
903
+ while((Error::NO_ERRORS == return_value) && (Error::NO_ERRORS == add_result))
904
+ {
905
+ const uint32_t n_section = buffer.get_size();
906
+ const uint32_t n_window = EmbeddedProto::min(PACKED_VARINT_WINDOW_N_BYTES, n_section);
907
+
908
+ if((0U < n_window) && buffer.peek(bytes_view{window.data(), n_window}))
909
+ {
910
+ uint32_t offset = 0U;
911
+ bool window_done = false;
912
+ while(!window_done)
913
+ {
914
+ uint32_t n_used = 0U;
915
+ const Error element_result = decode_packed_varint(
916
+ const_bytes_view{&window[offset], n_window - offset}, element, n_used);
917
+
918
+ if(Error::NO_ERRORS == element_result)
919
+ {
920
+ offset += n_used;
921
+ add_result = this->add(element);
922
+ if(Error::NO_ERRORS == add_result)
923
+ {
924
+ ++n_elements;
925
+ }
926
+ }
927
+ else if((Error::END_OF_BUFFER == element_result) && (n_window < n_section))
928
+ {
929
+ // Cut by the window end, not by the section end: the next window starts with it.
930
+ }
931
+ else
932
+ {
933
+ // The section ends inside the element, which then consumed nothing, or the
934
+ // varint is overlong, which consumed its bytes as DeserializeVarint() does.
935
+ offset += n_used;
936
+ return_value = element_result;
937
+ }
938
+
939
+ window_done = (Error::NO_ERRORS != element_result) || (Error::NO_ERRORS != add_result)
940
+ || (offset >= n_window);
941
+ }
942
+
943
+ if(0U < offset)
944
+ {
945
+ static_cast<void>(buffer.advance(offset));
946
+ }
947
+ }
948
+ else
949
+ {
950
+ return_value = Error::END_OF_BUFFER;
951
+ }
952
+ }
953
+
954
+ return return_value;
955
+ }
956
+
957
+ //! Decode one packed varint element from a local array, the counterpart of packed_varint_value().
958
+ /*!
959
+ Mirrors the conversions of the matching FieldTemplate::deserialize(): uint32 and
960
+ enum values are decoded as 32-bit varints, int32, int64, sint32, sint64 and
961
+ uint64 values as 64-bit ones since some implementations serialize 32-bit values
962
+ with ten bytes, sint values are zig-zag decoded and a bool is one byte.
963
+
964
+ \param[in] bytes The bytes to decode, the element starts at the first one.
965
+ \param[out] element The element receiving the value, only set when NO_ERRORS is returned.
966
+ \param[out] n_used The number of bytes the element took, zero when the array ended before it closed.
967
+ \return As WireFormatter::DecodeVarint().
968
+ */
969
+ static Error decode_packed_varint(const const_bytes_view& bytes, DATA_TYPE& element, uint32_t& n_used)
970
+ {
971
+ constexpr Field::FieldTypes FIELD_TYPE = fieldtemplate_field_type<DATA_TYPE>::value;
972
+ using VALUE_TYPE = typename DATA_TYPE::TYPE;
973
+ Error return_value = Error::NO_ERRORS;
974
+
975
+ if constexpr(Field::FieldTypes::boolean == FIELD_TYPE)
976
+ {
977
+ n_used = 0U;
978
+ if(0U < bytes.size)
979
+ {
980
+ element.set(0U != bytes.data[0]);
981
+ n_used = 1U;
982
+ }
983
+ else
984
+ {
985
+ return_value = Error::END_OF_BUFFER;
986
+ }
987
+ }
988
+ else if constexpr((Field::FieldTypes::uint32 == FIELD_TYPE)
989
+ || (Field::FieldTypes::enumeration == FIELD_TYPE))
990
+ {
991
+ uint32_t value = 0U;
992
+ return_value = WireFormatter::DecodeVarint(bytes, value, n_used);
993
+ if(Error::NO_ERRORS == return_value)
994
+ {
995
+ element.set(static_cast<VALUE_TYPE>(value));
996
+ }
997
+ }
998
+ else if constexpr((Field::FieldTypes::sint32 == FIELD_TYPE)
999
+ || (Field::FieldTypes::sint64 == FIELD_TYPE))
1000
+ {
1001
+ using UINT_TYPE = typename std::make_unsigned<VALUE_TYPE>::type;
1002
+ uint64_t value = 0U;
1003
+ return_value = WireFormatter::DecodeVarint(bytes, value, n_used);
1004
+ if(Error::NO_ERRORS == return_value)
1005
+ {
1006
+ element.set(WireFormatter::ZigZagDecode(static_cast<UINT_TYPE>(value)));
1007
+ }
1008
+ }
1009
+ else
1010
+ {
1011
+ // int32, int64 and uint64.
1012
+ uint64_t value = 0U;
1013
+ return_value = WireFormatter::DecodeVarint(bytes, value, n_used);
1014
+ if(Error::NO_ERRORS == return_value)
1015
+ {
1016
+ element.set(static_cast<VALUE_TYPE>(value));
1017
+ }
1018
+ }
1019
+
1020
+ return return_value;
1021
+ }
1022
+
1023
+ #ifdef PARTIAL_SERIALIZATION_ENABLED
1024
+ //! Read one packed element, batching fixed-width scalars into a single read.
1025
+ /*!
1026
+ For fixed-width scalar element types the whole element is read with one
1027
+ batched pop (via DeserializeFixedArrayNoTag) instead of a per-byte peek
1028
+ loop. The read is all-or-nothing against the section boundary: an element
1029
+ that is not fully present in the current section leaves the element and
1030
+ the section untouched and returns END_OF_BUFFER, so the resumable partial
1031
+ path continues at the same element/bytes_remaining on the next buffer
1032
+ refill. All other element types keep their existing deserialization.
1033
+ */
1034
+ Error deserialize_packed_partial_element(DATA_TYPE& element, ReadBufferSection& section)
1035
+ {
1036
+ if constexpr(internal::PackedFixedTraits<DATA_TYPE>::is_fixed_width)
1037
+ {
1038
+ using VAR = typename internal::PackedFixedTraits<DATA_TYPE>::scalar_type;
1039
+ return WireFormatter::DeserializeFixedArrayNoTag(array_view<VAR>{&element.get(), 1U}, section);
1040
+ }
1041
+ else
1042
+ {
1043
+ return element.deserialize(section);
1044
+ }
1045
+ }
1046
+ #endif // PARTIAL_SERIALIZATION_ENABLED
1047
+
1048
+ };
1049
+
1050
+
1051
+ } // End of namespace EmbeddedProto
1052
+
1053
+ #endif // End of _REPEATED_FIELD_H_