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,432 @@
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_CALLBACK_H_
25
+ #define _REPEATED_FIELD_CALLBACK_H_
26
+
27
+ #include "RepeatedField.h"
28
+ #include "Functional.h"
29
+ #include "Errors.h"
30
+
31
+ #include <cstdint>
32
+
33
+
34
+ namespace EmbeddedProto
35
+ {
36
+
37
+ //! A repeated field whose elements are streamed to/from the user, not stored.
38
+ /*!
39
+ RepeatedFieldCallback is a drop-in storage type for a repeated scalar field
40
+ that owns no element buffer. Instead of holding an array it forwards each
41
+ element across the interface seam:
42
+
43
+ - on deserialize, every parsed element is pushed to a user *sink*;
44
+ - on serialize, elements are pulled one by one from a user *source*.
45
+
46
+ This lets a device stream arbitrarily many elements through a fixed, tiny
47
+ RAM footprint (just the two Functional handles plus a single transient
48
+ return slot required by the RepeatedField interface). It plugs in through
49
+ the existing customStorage mechanism: it derives from RepeatedField and
50
+ satisfies the same static_assert.
51
+
52
+ This skeleton implements the RepeatedField interface minimally; the
53
+ streaming behaviour is wired up in the following steps of the callback
54
+ storage plan (sink on deserialize, source on serialize, then partial /
55
+ resumable support).
56
+
57
+ \tparam DATA_TYPE The element field type (a FieldTemplate scalar such as
58
+ EmbeddedProto::int32).
59
+ */
60
+ template<class DATA_TYPE>
61
+ class RepeatedFieldCallback : public RepeatedField<DATA_TYPE>
62
+ {
63
+ public:
64
+
65
+ //! Pull callback used during serialize: fill \p element, return true when a value was produced, false to signal the end of the stream.
66
+ using SourceCallback = Functional<bool(DATA_TYPE&)>;
67
+
68
+ //! Push callback used during deserialize: consume one parsed \p element, return an Error (NO_ERRORS to continue).
69
+ using SinkCallback = Functional<Error(const DATA_TYPE&)>;
70
+
71
+ RepeatedFieldCallback() = default;
72
+ ~RepeatedFieldCallback() = default;
73
+
74
+ // --- Binding (reference-taking, no ownership) --------------------------
75
+
76
+ //! Bind the source used to pull elements during serialization.
77
+ void set_source(const SourceCallback& source) { source_ = source; }
78
+
79
+ //! Bind the sink used to push elements during deserialization.
80
+ void set_sink(const SinkCallback& sink) { sink_ = sink; }
81
+
82
+ //! Remove the bound source.
83
+ void clear_source() { source_.clear(); }
84
+
85
+ //! Remove the bound sink.
86
+ void clear_sink() { sink_.clear(); }
87
+
88
+ //! Check whether a source (pull) callback is bound.
89
+ bool is_source_set() const { return source_.is_set(); }
90
+
91
+ //! Check whether a sink (push) callback is bound.
92
+ bool is_sink_set() const { return sink_.is_set(); }
93
+
94
+ //! Require a binding for the direction being used.
95
+ /*!
96
+ When strict, streaming without the relevant callback bound returns
97
+ CALLBACK_NOT_SET instead of silently discarding (deserialize) or
98
+ emitting nothing (serialize).
99
+ */
100
+ void set_strict(bool strict) { strict_ = strict; }
101
+
102
+ //! Whether strict (require-binding) mode is enabled.
103
+ bool is_strict() const { return strict_; }
104
+
105
+ // --- RepeatedField interface -------------------------------------------
106
+
107
+ //! Number of elements streamed so far (a running counter, not a capacity).
108
+ uint32_t get_length() const override { return length_; }
109
+
110
+ //! Streaming is effectively unbounded; report a large sentinel so the engine's "array full" checks never fire.
111
+ uint32_t get_max_length() const override { return UINT32_MAX; }
112
+
113
+ //! No elements are stored, so no bytes are resident.
114
+ uint32_t get_size() const override { return 0U; }
115
+
116
+ //! Streaming is effectively unbounded.
117
+ uint32_t get_max_size() const override { return UINT32_MAX; }
118
+
119
+ //! Required of a customStorage repeated type.
120
+ /*!
121
+ A stream has no finite serialized size, so report the unbounded sentinel
122
+ (consistent with get_max_length/get_max_size). A message with a callback field
123
+ therefore cannot be statically buffer-sized, which is inherent.
124
+ */
125
+ static constexpr uint32_t max_serialized_size(const uint32_t field_number)
126
+ {
127
+ static_cast<void>(field_number);
128
+ return UINT32_MAX;
129
+ }
130
+
131
+ //! Random access is unsupported; return the transient slot as a landing area for the engine (its contents are not retained).
132
+ DATA_TYPE& get(uint32_t index) override
133
+ {
134
+ static_cast<void>(index);
135
+ return transient_;
136
+ }
137
+
138
+ //! Random access is unsupported; return the transient slot.
139
+ const DATA_TYPE& get_const(uint32_t index) const override
140
+ {
141
+ static_cast<void>(index);
142
+ return transient_;
143
+ }
144
+
145
+ //! Random access is unsupported.
146
+ Error get_const(const uint32_t index, DATA_TYPE& value) const override
147
+ {
148
+ static_cast<void>(index);
149
+ static_cast<void>(value);
150
+ return Error::INDEX_OUT_OF_BOUND;
151
+ }
152
+
153
+ //! Random access is unsupported; setting a specific index is a no-op.
154
+ void set(uint32_t index, const DATA_TYPE& value) override
155
+ {
156
+ static_cast<void>(index);
157
+ static_cast<void>(value);
158
+ }
159
+
160
+ //! Keep the pointer and length form of set_data() reachable next to the override below.
161
+ using RepeatedField<DATA_TYPE>::set_data;
162
+
163
+ //! Bulk assignment is unsupported for a streaming field.
164
+ Error set_data(const array_view<const DATA_TYPE>& data) override
165
+ {
166
+ static_cast<void>(data);
167
+ return Error::ARRAY_FULL;
168
+ }
169
+
170
+ //! Append one element: push it to the bound sink instead of storing it.
171
+ /*!
172
+ Every parsed element funnels through here (the base packed-decode loop
173
+ calls the virtual add(), and the expanded path is routed here by the
174
+ deserialize_check_type override below). With a sink bound, the element
175
+ is forwarded and the sink's Error is propagated. With no sink bound the
176
+ element is drained and discarded (NO_ERRORS), unless strict mode is on,
177
+ in which case CALLBACK_NOT_SET is returned. The element counter is
178
+ advanced only for an element that was accepted.
179
+ */
180
+ Error add(const DATA_TYPE& value) override
181
+ {
182
+ Error return_value = Error::NO_ERRORS;
183
+ if(sink_.is_set())
184
+ {
185
+ Error sink_result = Error::NO_ERRORS;
186
+ static_cast<void>(sink_.invoke(sink_result, value));
187
+ return_value = sink_result;
188
+ }
189
+ else if(strict_)
190
+ {
191
+ return_value = Error::CALLBACK_NOT_SET;
192
+ }
193
+ else
194
+ {
195
+ // No sink bound and not strict: drain and discard.
196
+ static_cast<void>(value);
197
+ }
198
+
199
+ if(Error::NO_ERRORS == return_value)
200
+ {
201
+ ++length_;
202
+ }
203
+ return return_value;
204
+ }
205
+
206
+ //! Route deserialization through add() for both packed and expanded input.
207
+ /*!
208
+ Length-delimited (packed) input is handled by the base deserialize(),
209
+ whose element loop already calls the virtual add(). Expanded input
210
+ (one tag per element) would otherwise be routed to the random-access
211
+ get(index) slot this field lacks, so it is deserialized into a stack
212
+ local here and pushed through add() as well.
213
+ */
214
+ Error deserialize_check_type(::EmbeddedProto::ReadBufferInterface& buffer,
215
+ const ::EmbeddedProto::WireFormatter::WireType& wire_type) override
216
+ {
217
+ Error return_value = Error::NO_ERRORS;
218
+ const bool is_length_delimited =
219
+ ::EmbeddedProto::WireFormatter::WireType::LENGTH_DELIMITED == wire_type;
220
+ if(is_length_delimited)
221
+ {
222
+ return_value = this->deserialize(buffer);
223
+ }
224
+ else
225
+ {
226
+ DATA_TYPE element;
227
+ return_value = element.deserialize_check_type(buffer, wire_type);
228
+ if(Error::NO_ERRORS == return_value)
229
+ {
230
+ return_value = this->add(element);
231
+ }
232
+ }
233
+ return return_value;
234
+ }
235
+
236
+ //! Guard against packed / size-pass serialization of a streaming field.
237
+ /*!
238
+ The base RepeatedField::serialize() writes the packed element payload
239
+ with no tags, and is also what a size pass reaches via
240
+ Field::serialized_size() (serialize into a counting buffer). A callback
241
+ field owns no elements to pack and must not be pulled twice, so it only
242
+ ever emits EXPANDED through serialize_expanded(). Any call here means the
243
+ field was placed where a length-delimited (LEN) framing is required
244
+ (e.g. as a packed field or under a LEN ancestor), which is unsupported
245
+ for streaming storage: report CALLBACK_SEQUENCE instead of silently
246
+ draining the source. See design section 16.3.
247
+ */
248
+ Error serialize(WriteBufferInterface& buffer) const override
249
+ {
250
+ static_cast<void>(buffer);
251
+ return Error::CALLBACK_SEQUENCE;
252
+ }
253
+
254
+ //! Pull elements from the bound source and emit them EXPANDED.
255
+ /*!
256
+ One tag+value is written per element (the same wire form as an EXPANDED
257
+ repeated scalar field), so no field-level size prefix is needed and the
258
+ source is drained exactly once in a single pass. Production ends when the
259
+ source callback returns false. With no source bound nothing is emitted
260
+ (NO_ERRORS), unless strict mode is on, in which case CALLBACK_NOT_SET is
261
+ returned. A re-entrant call (the field being pulled while already
262
+ pulling, e.g. a stray size pass) returns CALLBACK_SEQUENCE rather than
263
+ double-pulling the stream.
264
+
265
+ \param field_number The field number written in each element's tag.
266
+ \param buffer The destination buffer.
267
+ */
268
+ Error serialize_expanded(uint32_t field_number, WriteBufferInterface& buffer) const
269
+ {
270
+ Error return_value = Error::NO_ERRORS;
271
+ if(pulling_)
272
+ {
273
+ return_value = Error::CALLBACK_SEQUENCE;
274
+ }
275
+ else if(!source_.is_set())
276
+ {
277
+ if(strict_)
278
+ {
279
+ return_value = Error::CALLBACK_NOT_SET;
280
+ }
281
+ // Not strict: no source bound, emit nothing.
282
+ }
283
+ else
284
+ {
285
+ pulling_ = true;
286
+ bool more = true;
287
+ while(more && (Error::NO_ERRORS == return_value))
288
+ {
289
+ bool produced = false;
290
+ transient_ = DATA_TYPE();
291
+ static_cast<void>(source_.invoke(produced, transient_));
292
+ if(produced)
293
+ {
294
+ return_value = transient_.serialize_with_id(field_number, buffer, true);
295
+ if(Error::NO_ERRORS == return_value)
296
+ {
297
+ ++length_;
298
+ }
299
+ }
300
+ else
301
+ {
302
+ more = false;
303
+ }
304
+ }
305
+ pulling_ = false;
306
+ }
307
+ return return_value;
308
+ }
309
+
310
+ #ifdef PARTIAL_SERIALIZATION_ENABLED
311
+ //! Resumable EXPANDED pull-serialize for the partial engine.
312
+ /*!
313
+ Emits one tag+value per element, pulling from the source, and survives a
314
+ write buffer that fills mid-stream. Before each element is pulled the
315
+ remaining buffer space is checked against the element's maximum
316
+ serialized size; when it does not fit, BUFFER_FULL is returned WITHOUT
317
+ pulling, so the not-yet-produced element stays in the source and the next
318
+ call resumes with it (all-or-nothing, no double-pull). The source's own
319
+ cursor is the resumable state; no in-flight element is stored in the
320
+ field (design section 8.2). The write buffer must be able to hold at
321
+ least one element's maximum size for the stream to make progress.
322
+ */
323
+ Error serialize_partial_as_field_expanded(uint32_t field_number,
324
+ WriteBufferInterface& buffer,
325
+ MessageState& state,
326
+ bool optional) const
327
+ {
328
+ static_cast<void>(optional);
329
+ Error return_value = Error::NO_ERRORS;
330
+ if(::EmbeddedProto::FieldProcessingPhase::COMPLETE == state.phase)
331
+ {
332
+ // The stream was already fully drained on an earlier call.
333
+ }
334
+ else if(!source_.is_set())
335
+ {
336
+ if(strict_)
337
+ {
338
+ return_value = Error::CALLBACK_NOT_SET;
339
+ }
340
+ else
341
+ {
342
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
343
+ }
344
+ }
345
+ else
346
+ {
347
+ bool more = true;
348
+ while(more && (Error::NO_ERRORS == return_value))
349
+ {
350
+ if(buffer.get_available_size() < DATA_TYPE::max_serialized_size(field_number))
351
+ {
352
+ // Cannot guarantee the next element fits: stop before pulling and
353
+ // resume on the next call once the buffer has been flushed.
354
+ return_value = Error::BUFFER_FULL;
355
+ }
356
+ else
357
+ {
358
+ bool produced = false;
359
+ transient_ = DATA_TYPE();
360
+ static_cast<void>(source_.invoke(produced, transient_));
361
+ if(produced)
362
+ {
363
+ // Space was pre-checked, so this write always fits.
364
+ return_value = transient_.serialize_with_id(field_number, buffer, true);
365
+ if(Error::NO_ERRORS == return_value)
366
+ {
367
+ ++length_;
368
+ }
369
+ }
370
+ else
371
+ {
372
+ more = false;
373
+ state.phase = ::EmbeddedProto::FieldProcessingPhase::COMPLETE;
374
+ }
375
+ }
376
+ }
377
+ }
378
+ return return_value;
379
+ }
380
+
381
+ //! Guard the packed / LEN partial path.
382
+ /*!
383
+ A streaming field is emitted EXPANDED only (via
384
+ serialize_partial_as_field_expanded). The default
385
+ serialize_partial_as_field routes packed scalars through a length-prefixed
386
+ block that needs a size pass, which a callback field cannot provide
387
+ without draining its source twice. Reject it with CALLBACK_SEQUENCE
388
+ instead (design section 16.3).
389
+ */
390
+ Error serialize_partial_as_field(uint32_t field_number,
391
+ WriteBufferInterface& buffer,
392
+ MessageState& state,
393
+ bool optional) const override
394
+ {
395
+ static_cast<void>(field_number);
396
+ static_cast<void>(buffer);
397
+ static_cast<void>(state);
398
+ static_cast<void>(optional);
399
+ return Error::CALLBACK_SEQUENCE;
400
+ }
401
+ #endif // PARTIAL_SERIALIZATION_ENABLED
402
+
403
+ //! Reset the streaming state (the element counter). Bindings are kept.
404
+ void clear() override { length_ = 0U; }
405
+
406
+ private:
407
+
408
+ //! Running count of elements streamed through this field. Mutable because serialize is const yet advances the counter as elements are pulled.
409
+ mutable uint32_t length_ = 0U;
410
+
411
+ //! Set while serialize_expanded() is draining the source, so a re-entrant call (e.g. a stray size pass) is rejected instead of double-pulling.
412
+ mutable bool pulling_ = false;
413
+
414
+ //! When true, streaming without a bound callback is an error rather than a silent drain/no-op.
415
+ bool strict_ = false;
416
+
417
+ //! Single-element landing slot required by the reference-returning RepeatedField interface.
418
+ /*!
419
+ It is not stream storage: the collection owns no per-element buffer.
420
+ */
421
+ mutable DATA_TYPE transient_ = {};
422
+
423
+ //! Pull callback invoked to produce elements while serializing.
424
+ SourceCallback source_{};
425
+
426
+ //! Push callback invoked to consume elements while deserializing.
427
+ SinkCallback sink_{};
428
+ };
429
+
430
+ } // End of namespace EmbeddedProto
431
+
432
+ #endif // End of _REPEATED_FIELD_CALLBACK_H_