1use crate::error::AstError;
17use crate::facet::Facets;
18use crate::model::Ast;
19use crate::node::AnyId;
20use crate::node::type_::{Bound, CharWidth, Completeness, PrimitiveKind, TypeKind};
21use alloc::string::String;
22use alloc::vec::Vec;
23use zerodds_ast_core::{AstCoreError, Id, IdSpace, NodeId, Ref, SnapshotReader, SnapshotWriter};
24
25mod tag {
27 pub const PRIMITIVE: u8 = 1;
28 pub const FIXED: u8 = 2;
29 pub const STRING: u8 = 3;
30 pub const SEQUENCE: u8 = 4;
31 pub const ARRAY: u8 = 5;
32 pub const MAP: u8 = 6;
33 pub const STRUCTURE: u8 = 7;
34 pub const UNION: u8 = 8;
35 pub const ENUMERATION: u8 = 9;
36 pub const BITMASK: u8 = 10;
37 pub const BITSET: u8 = 11;
38 pub const ALIAS: u8 = 12;
39 pub const NATIVE: u8 = 13;
40 pub const VALUETYPE: u8 = 14;
41 pub const VALUE_BOX: u8 = 15;
42 pub const OBJECT_REF: u8 = 16;
43 pub const ANY: u8 = 17;
44 pub const VALUE_BASE: u8 = 18;
45 pub const ANNOTATION_TYPE: u8 = 19;
46}
47
48impl Ast {
49 pub fn to_snapshot(&self) -> Result<Vec<u8>, AstError> {
55 let mut w = SnapshotWriter::with_header();
56
57 w.u64(self.model_ids.next_counter());
60 w.u64(self.builtin_ids.next_counter());
61 w.u64(self.synthetic_ids.next_counter());
62 w.u64(self.sequence);
63
64 w.u32(count(self.modules.slot_count())?);
66 w.u32(count(self.modules.len())?);
67 for (id, module) in self.modules.iter() {
68 w.u32(id.slot());
69 w.u32(id.generation());
70 w.node_id(module.node_id);
71 w.str(&module.name)?;
72 match module.parent {
73 Some(parent) => {
74 w.bool(true);
75 w.u32(parent.slot());
76 w.u32(parent.generation());
77 }
78 None => w.bool(false),
79 }
80 write_facets(&mut w, &module.facets)?;
81 }
82
83 w.u32(count(self.exprs.slot_count())?);
85 w.u32(count(self.exprs.len())?);
86 for (id, expr) in self.exprs.iter() {
87 w.u32(id.slot());
88 w.u32(id.generation());
89 w.node_id(expr.node_id);
90 write_expr(&mut w, &expr.expr)?;
91 write_facets(&mut w, &expr.facets)?;
92 }
93
94 w.u32(count(self.types.slot_count())?);
96 w.u32(count(self.types.len())?);
97 for (id, node) in self.types.iter() {
98 w.u32(id.slot());
99 w.u32(id.generation());
100 w.node_id(node.node_id);
101 w.str(&node.name)?;
102 w.u32(node.module.slot());
103 w.u32(node.module.generation());
104 write_str_opt(&mut w, node.scope.as_deref())?;
105 w.bool(node.completeness == Completeness::Complete);
106 write_kind(&mut w, &node.kind)?;
107 write_facets(&mut w, &node.facets)?;
108 }
109
110 w.u32(count(self.members.slot_count())?);
112 w.u32(count(self.members.len())?);
113 for (id, member) in self.members.iter() {
114 w.u32(id.slot());
115 w.u32(id.generation());
116 w.node_id(member.node_id);
117 w.str(&member.name)?;
118 write_type_ref(&mut w, &member.type_)?;
119 match member.parent {
122 AnyId::Type(id, _) => {
123 w.u8(1);
124 w.u32(id.slot());
125 w.u32(id.generation());
126 }
127 AnyId::Exception(id, _) => {
128 w.u8(2);
129 w.u32(id.slot());
130 w.u32(id.generation());
131 }
132 _ => w.u8(0),
133 }
134 write_facets(&mut w, &member.facets)?;
135 }
136
137 w.u32(count(self.cases.slot_count())?);
140 w.u32(count(self.cases.len())?);
141 for (id, case) in self.cases.iter() {
142 w.u32(id.slot());
143 w.u32(id.generation());
144 w.node_id(case.node_id);
145 w.u32(case.parent.slot());
146 w.u32(case.parent.generation());
147 w.u32(case.member.slot());
148 w.u32(case.member.generation());
149 w.u32(count(case.labels.len())?);
150 for label in &case.labels {
151 match label {
152 crate::CaseLabel::Default => w.u8(0),
153 crate::CaseLabel::Value(expr) => {
154 w.u8(1);
155 w.u32(expr.slot());
156 w.u32(expr.generation());
157 }
158 }
159 }
160 write_facets(&mut w, &case.facets)?;
161 }
162
163 w.u32(count(self.enumerators.slot_count())?);
164 w.u32(count(self.enumerators.len())?);
165 for (id, node) in self.enumerators.iter() {
166 w.u32(id.slot());
167 w.u32(id.generation());
168 w.node_id(node.node_id);
169 w.str(&node.name)?;
170 w.u32(node.parent.slot());
171 w.u32(node.parent.generation());
172 match node.value {
173 Some(expr) => {
174 w.bool(true);
175 w.u32(expr.slot());
176 w.u32(expr.generation());
177 }
178 None => w.bool(false),
179 }
180 write_facets(&mut w, &node.facets)?;
181 }
182
183 w.u32(count(self.bit_values.slot_count())?);
184 w.u32(count(self.bit_values.len())?);
185 for (id, node) in self.bit_values.iter() {
186 w.u32(id.slot());
187 w.u32(id.generation());
188 w.node_id(node.node_id);
189 w.str(&node.name)?;
190 w.u32(node.parent.slot());
191 w.u32(node.parent.generation());
192 match node.position {
193 Some(position) => {
194 w.bool(true);
195 w.u16(position);
196 }
197 None => w.bool(false),
198 }
199 write_facets(&mut w, &node.facets)?;
200 }
201
202 w.u32(count(self.bitfields.slot_count())?);
203 w.u32(count(self.bitfields.len())?);
204 for (id, node) in self.bitfields.iter() {
205 w.u32(id.slot());
206 w.u32(id.generation());
207 w.node_id(node.node_id);
208 match node.name.as_deref() {
209 Some(name) => {
210 w.bool(true);
211 w.str(name)?;
212 }
213 None => w.bool(false),
214 }
215 w.u16(node.bits);
216 w.u32(node.parent.slot());
217 w.u32(node.parent.generation());
218 write_type_ref_opt(&mut w, node.holder_type.as_ref())?;
219 write_facets(&mut w, &node.facets)?;
220 }
221
222 w.u32(count(self.constants.slot_count())?);
224 w.u32(count(self.constants.len())?);
225 for (id, node) in self.constants.iter() {
226 w.u32(id.slot());
227 w.u32(id.generation());
228 w.node_id(node.node_id);
229 w.str(&node.name)?;
230 w.u32(node.module.slot());
231 w.u32(node.module.generation());
232 write_str_opt(&mut w, node.scope.as_deref())?;
233 w.u32(node.expr.slot());
234 w.u32(node.expr.generation());
235 write_type_ref(&mut w, &node.type_)?;
236 write_facets(&mut w, &node.facets)?;
237 }
238
239 w.u32(count(self.exceptions.slot_count())?);
241 w.u32(count(self.exceptions.len())?);
242 for (id, node) in self.exceptions.iter() {
243 w.u32(id.slot());
244 w.u32(id.generation());
245 w.node_id(node.node_id);
246 w.str(&node.name)?;
247 w.u32(node.module.slot());
248 w.u32(node.module.generation());
249 write_str_opt(&mut w, node.scope.as_deref())?;
250 write_handles(&mut w, &node.members)?;
251 write_facets(&mut w, &node.facets)?;
252 }
253
254 w.u32(count(self.interfaces.slot_count())?);
256 w.u32(count(self.interfaces.len())?);
257 for (id, node) in self.interfaces.iter() {
258 w.u32(id.slot());
259 w.u32(id.generation());
260 w.node_id(node.node_id);
261 w.str(&node.name)?;
262 w.u32(node.module.slot());
263 w.u32(node.module.generation());
264 w.u8(interface_kind_tag(node.kind));
265 w.bool(node.completeness == Completeness::Complete);
266 w.u32(count(node.bases.len())?);
267 for base in &node.bases {
268 write_ref(&mut w, base)?;
269 }
270 write_handles(&mut w, &node.operations)?;
271 write_handles(&mut w, &node.attributes)?;
272 write_facets(&mut w, &node.facets)?;
273 }
274
275 w.u32(count(self.operations.slot_count())?);
276 w.u32(count(self.operations.len())?);
277 for (id, node) in self.operations.iter() {
278 w.u32(id.slot());
279 w.u32(id.generation());
280 w.node_id(node.node_id);
281 w.str(&node.name)?;
282 write_type_ref_opt(&mut w, node.return_type.as_ref())?;
283 w.bool(node.oneway);
284 write_handles(&mut w, &node.params)?;
285 w.u32(count(node.raises.len())?);
286 for raise in &node.raises {
287 write_ref(&mut w, raise)?;
288 }
289 w.u32(count(node.contexts.len())?);
290 for context in &node.contexts {
291 w.str(context)?;
292 }
293 write_any_parent(&mut w, node.parent);
294 write_facets(&mut w, &node.facets)?;
295 }
296
297 w.u32(count(self.params.slot_count())?);
298 w.u32(count(self.params.len())?);
299 for (id, node) in self.params.iter() {
300 w.u32(id.slot());
301 w.u32(id.generation());
302 w.node_id(node.node_id);
303 w.str(&node.name)?;
304 w.u8(direction_tag(node.direction));
305 write_type_ref(&mut w, &node.type_)?;
306 w.u32(node.parent.slot());
307 w.u32(node.parent.generation());
308 write_facets(&mut w, &node.facets)?;
309 }
310
311 w.u32(count(self.attributes.slot_count())?);
312 w.u32(count(self.attributes.len())?);
313 for (id, node) in self.attributes.iter() {
314 w.u32(id.slot());
315 w.u32(id.generation());
316 w.node_id(node.node_id);
317 w.str(&node.name)?;
318 write_type_ref(&mut w, &node.type_)?;
319 w.bool(node.readonly);
320 w.u32(node.parent.slot());
321 w.u32(node.parent.generation());
322 w.u32(count(node.get_raises.len())?);
323 for raise in &node.get_raises {
324 write_ref(&mut w, raise)?;
325 }
326 w.u32(count(node.set_raises.len())?);
327 for raise in &node.set_raises {
328 write_ref(&mut w, raise)?;
329 }
330 write_facets(&mut w, &node.facets)?;
331 }
332
333 w.u32(count(self.annotation_defs.slot_count())?);
335 w.u32(count(self.annotation_defs.len())?);
336 for (id, node) in self.annotation_defs.iter() {
337 w.u32(id.slot());
338 w.u32(id.generation());
339 w.node_id(node.node_id);
340 w.str(&node.name)?;
341 w.u32(node.module.slot());
342 w.u32(node.module.generation());
343 write_handles(&mut w, &node.members)?;
344 write_facets(&mut w, &node.facets)?;
345 }
346
347 w.u32(count(self.annotation_members.slot_count())?);
348 w.u32(count(self.annotation_members.len())?);
349 for (id, node) in self.annotation_members.iter() {
350 w.u32(id.slot());
351 w.u32(id.generation());
352 w.node_id(node.node_id);
353 w.str(&node.name)?;
354 write_type_ref(&mut w, &node.type_)?;
355 w.bool(node.is_value_member);
356 w.u32(node.parent.slot());
357 w.u32(node.parent.generation());
358 match node.default {
359 Some(expr) => {
360 w.bool(true);
361 w.u32(expr.slot());
362 w.u32(expr.generation());
363 }
364 None => w.bool(false),
365 }
366 write_facets(&mut w, &node.facets)?;
367 }
368
369 w.u32(count(self.libraries.slot_count())?);
371 w.u32(count(self.libraries.len())?);
372 for (id, node) in self.libraries.iter() {
373 w.u32(id.slot());
374 w.u32(id.generation());
375 w.node_id(node.node_id);
376 w.str(&node.name)?;
377 write_facets(&mut w, &node.facets)?;
378 }
379
380 w.u32(count(self.domains.slot_count())?);
381 w.u32(count(self.domains.len())?);
382 for (id, node) in self.domains.iter() {
383 w.u32(id.slot());
384 w.u32(id.generation());
385 w.node_id(node.node_id);
386 w.str(&node.name)?;
387 w.u32(node.domain_id);
388 w.u32(node.parent.slot());
389 w.u32(node.parent.generation());
390 write_facets(&mut w, &node.facets)?;
391 }
392
393 w.u32(count(self.qos_profiles.slot_count())?);
394 w.u32(count(self.qos_profiles.len())?);
395 for (id, node) in self.qos_profiles.iter() {
396 w.u32(id.slot());
397 w.u32(id.generation());
398 w.node_id(node.node_id);
399 w.str(&node.name)?;
400 w.u32(node.parent.slot());
401 w.u32(node.parent.generation());
402 write_ref_opt(&mut w, node.base.as_ref())?;
403 write_policies(&mut w, &node.policies)?;
404 write_facets(&mut w, &node.facets)?;
405 }
406
407 w.u32(count(self.topics.slot_count())?);
408 w.u32(count(self.topics.len())?);
409 for (id, node) in self.topics.iter() {
410 w.u32(id.slot());
411 w.u32(id.generation());
412 w.node_id(node.node_id);
413 w.str(&node.name)?;
414 write_type_ref(&mut w, &node.type_)?;
415 write_ref_opt(&mut w, node.qos.as_ref())?;
416 w.u32(node.parent.slot());
417 w.u32(node.parent.generation());
418 write_facets(&mut w, &node.facets)?;
419 }
420
421 w.u32(count(self.participants.slot_count())?);
422 w.u32(count(self.participants.len())?);
423 for (id, node) in self.participants.iter() {
424 w.u32(id.slot());
425 w.u32(id.generation());
426 w.node_id(node.node_id);
427 w.str(&node.name)?;
428 write_ref(&mut w, &node.domain)?;
429 write_ref_opt(&mut w, node.qos.as_ref())?;
430 w.u32(node.parent.slot());
431 w.u32(node.parent.generation());
432 write_facets(&mut w, &node.facets)?;
433 }
434
435 w.u32(count(self.endpoints.slot_count())?);
436 w.u32(count(self.endpoints.len())?);
437 for (id, node) in self.endpoints.iter() {
438 w.u32(id.slot());
439 w.u32(id.generation());
440 w.node_id(node.node_id);
441 w.str(&node.name)?;
442 w.bool(node.role == crate::EndpointRole::DataWriter);
443 write_ref(&mut w, &node.topic)?;
444 write_ref_opt(&mut w, node.qos.as_ref())?;
445 w.u32(node.parent.slot());
446 w.u32(node.parent.generation());
447 write_facets(&mut w, &node.facets)?;
448 }
449
450 Ok(w.finish())
451 }
452
453 pub fn from_snapshot(bytes: &[u8]) -> Result<Self, AstError> {
463 let mut r = SnapshotReader::with_header(bytes)?;
464 let mut ast = Self::empty_for_load();
465
466 ast.model_ids.set_next_counter(r.u64()?);
467 ast.builtin_ids.set_next_counter(r.u64()?);
468 ast.synthetic_ids.set_next_counter(r.u64()?);
469 ast.sequence = r.u64()?;
470
471 let module_slots = bounded_count(&mut r, 1)?;
472 let module_count = bounded_count(&mut r, min_size::MODULE)?;
473 for _ in 0..module_count {
474 let slot = bounded_slot(&mut r, module_slots)?;
475 let generation = r.u32()?;
476 let node_id = r.node_id()?;
477 let name = r.string()?;
478 let parent = if r.bool()? {
479 Some(Id::from_parts(r.u32()?, r.u32()?)?)
480 } else {
481 None
482 };
483 let facets = read_facets(&mut r)?;
484 let id = ast.modules.insert_at(
485 slot,
486 generation,
487 crate::ModuleNode {
488 node_id,
489 name,
490 parent,
491 children: Vec::new(),
492 facets,
493 },
494 )?;
495 let _ = ast.by_node_id.insert(node_id, AnyId::Module(id, node_id));
496 }
497
498 let expr_slots = bounded_count(&mut r, 1)?;
499 let expr_count = bounded_count(&mut r, min_size::EXPR)?;
500 for _ in 0..expr_count {
501 let slot = bounded_slot(&mut r, expr_slots)?;
502 let generation = r.u32()?;
503 let node_id = r.node_id()?;
504 let expr = read_expr(&mut r)?;
505 let facets = read_facets(&mut r)?;
506 let id = ast.exprs.insert_at(
507 slot,
508 generation,
509 crate::ConstExprNode {
510 node_id,
511 expr,
512 facets,
513 },
514 )?;
515 let _ = ast
516 .by_node_id
517 .insert(node_id, AnyId::ConstExpr(id, node_id));
518 }
519
520 let type_slots = bounded_count(&mut r, 1)?;
521 let type_count = bounded_count(&mut r, min_size::TYPE)?;
522 for _ in 0..type_count {
523 let slot = bounded_slot(&mut r, type_slots)?;
524 let generation = r.u32()?;
525 let node_id = r.node_id()?;
526 let name = r.string()?;
527 let module = Id::from_parts(r.u32()?, r.u32()?)?;
528 let scope = read_str_opt(&mut r)?;
529 let completeness = if r.bool()? {
530 Completeness::Complete
531 } else {
532 Completeness::Forward
533 };
534 let kind = read_kind(&mut r)?;
535 let facets = read_facets(&mut r)?;
536 let id = ast.types.insert_at(
537 slot,
538 generation,
539 crate::TypeNode {
540 node_id,
541 name,
542 module,
543 scope,
544 kind,
545 completeness,
546 facets,
547 },
548 )?;
549 let any = AnyId::Type(id, node_id);
550 let _ = ast.by_node_id.insert(node_id, any);
551 if let Ok(m) = ast.modules.get_mut(module) {
552 m.children.push(any);
553 }
554 }
555
556 let member_slots = bounded_count(&mut r, 1)?;
557 let member_count = bounded_count(&mut r, min_size::MEMBER)?;
558 for _ in 0..member_count {
559 let slot = bounded_slot(&mut r, member_slots)?;
560 let generation = r.u32()?;
561 let node_id = r.node_id()?;
562 let name = r.string()?;
563 let type_ = read_type_ref(&mut r)?;
564 let owner_tag = r.u8()?;
565 let owner = if owner_tag == 0 {
566 None
567 } else {
568 Some((r.u32()?, r.u32()?))
569 };
570 let facets = read_facets(&mut r)?;
571
572 let parent = match (owner_tag, owner) {
573 (1, Some((slot, generation))) => {
574 let id: Id<crate::TypeNode> = Id::from_parts(slot, generation)?;
575 AnyId::Type(id, ast.types.get(id)?.node_id)
576 }
577 (2, Some((slot, generation))) => {
578 let id: Id<crate::ExceptionNode> = Id::from_parts(slot, generation)?;
582 AnyId::Exception(id, NodeId::from_parts(IdSpace::MODEL, 0))
583 }
584 _ => {
585 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
586 offset: r.offset(),
587 expected: "a member's owning type or exception",
588 }));
589 }
590 };
591
592 let id = ast.members.insert_at(
593 slot,
594 generation,
595 crate::MemberNode {
596 node_id,
597 name,
598 type_,
599 parent,
600 facets,
601 },
602 )?;
603 let _ = ast.by_node_id.insert(node_id, AnyId::Member(id, node_id));
604 }
605
606 let case_slots = bounded_count(&mut r, 1)?;
608 let case_count = bounded_count(&mut r, 24)?;
609 for _ in 0..case_count {
610 let slot = bounded_slot(&mut r, case_slots)?;
611 let generation = r.u32()?;
612 let node_id = r.node_id()?;
613 let parent = Id::from_parts(r.u32()?, r.u32()?)?;
614 let member = Id::from_parts(r.u32()?, r.u32()?)?;
615 let label_count = bounded_count(&mut r, 1)? as usize;
616 let mut labels = Vec::new();
617 for _ in 0..label_count {
618 labels.push(match r.u8()? {
619 0 => crate::CaseLabel::Default,
620 1 => crate::CaseLabel::Value(Id::from_parts(r.u32()?, r.u32()?)?),
621 _ => {
622 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
623 offset: r.offset(),
624 expected: "case label tag 0 or 1",
625 }));
626 }
627 });
628 }
629 let facets = read_facets(&mut r)?;
630 let id = ast.cases.insert_at(
631 slot,
632 generation,
633 crate::CaseNode {
634 node_id,
635 labels,
636 member,
637 parent,
638 facets,
639 },
640 )?;
641 let _ = ast.by_node_id.insert(node_id, AnyId::Case(id, node_id));
642 }
643
644 let enum_slots = bounded_count(&mut r, 1)?;
645 let enum_count = bounded_count(&mut r, 24)?;
646 for _ in 0..enum_count {
647 let slot = bounded_slot(&mut r, enum_slots)?;
648 let generation = r.u32()?;
649 let node_id = r.node_id()?;
650 let name = r.string()?;
651 let parent = Id::from_parts(r.u32()?, r.u32()?)?;
652 let value = read_handle_opt(&mut r)?;
653 let facets = read_facets(&mut r)?;
654 let id = ast.enumerators.insert_at(
655 slot,
656 generation,
657 crate::EnumeratorNode {
658 node_id,
659 name,
660 value,
661 parent,
662 facets,
663 },
664 )?;
665 let _ = ast
666 .by_node_id
667 .insert(node_id, AnyId::Enumerator(id, node_id));
668 }
669
670 let bit_slots = bounded_count(&mut r, 1)?;
671 let bit_count = bounded_count(&mut r, 24)?;
672 for _ in 0..bit_count {
673 let slot = bounded_slot(&mut r, bit_slots)?;
674 let generation = r.u32()?;
675 let node_id = r.node_id()?;
676 let name = r.string()?;
677 let parent = Id::from_parts(r.u32()?, r.u32()?)?;
678 let position = if r.bool()? { Some(r.u16()?) } else { None };
679 let facets = read_facets(&mut r)?;
680 let id = ast.bit_values.insert_at(
681 slot,
682 generation,
683 crate::BitValueNode {
684 node_id,
685 name,
686 position,
687 parent,
688 facets,
689 },
690 )?;
691 let _ = ast.by_node_id.insert(node_id, AnyId::BitValue(id, node_id));
692 }
693
694 let field_slots = bounded_count(&mut r, 1)?;
695 let field_count = bounded_count(&mut r, 24)?;
696 for _ in 0..field_count {
697 let slot = bounded_slot(&mut r, field_slots)?;
698 let generation = r.u32()?;
699 let node_id = r.node_id()?;
700 let name = if r.bool()? { Some(r.string()?) } else { None };
701 let bits = r.u16()?;
702 let parent = Id::from_parts(r.u32()?, r.u32()?)?;
703 let holder_type = read_ref_opt(&mut r)?;
704 let facets = read_facets(&mut r)?;
705 let id = ast.bitfields.insert_at(
706 slot,
707 generation,
708 crate::BitfieldNode {
709 node_id,
710 name,
711 bits,
712 holder_type,
713 parent,
714 facets,
715 },
716 )?;
717 let _ = ast.by_node_id.insert(node_id, AnyId::Bitfield(id, node_id));
718 }
719
720 let const_slots = bounded_count(&mut r, 1)?;
722 let const_count = bounded_count(&mut r, 24)?;
723 for _ in 0..const_count {
724 let slot = bounded_slot(&mut r, const_slots)?;
725 let generation = r.u32()?;
726 let node_id = r.node_id()?;
727 let name = r.string()?;
728 let module = Id::from_parts(r.u32()?, r.u32()?)?;
729 let scope = read_str_opt(&mut r)?;
730 let expr = Id::from_parts(r.u32()?, r.u32()?)?;
731 let type_ = read_type_ref(&mut r)?;
732 let facets = read_facets(&mut r)?;
733 let id = ast.constants.insert_at(
734 slot,
735 generation,
736 crate::ConstNode {
737 node_id,
738 name,
739 module,
740 scope,
741 type_,
742 expr,
743 facets,
744 },
745 )?;
746 let any = AnyId::Const(id, node_id);
747 let _ = ast.by_node_id.insert(node_id, any);
748 if let Ok(m) = ast.modules.get_mut(module) {
749 m.children.push(any);
750 }
751 }
752
753 let exc_slots = bounded_count(&mut r, 1)?;
755 let exc_count = bounded_count(&mut r, 24)?;
756 for _ in 0..exc_count {
757 let slot = bounded_slot(&mut r, exc_slots)?;
758 let generation = r.u32()?;
759 let node_id = r.node_id()?;
760 let name = r.string()?;
761 let module = Id::from_parts(r.u32()?, r.u32()?)?;
762 let scope = read_str_opt(&mut r)?;
763 let members = read_handles(&mut r)?;
764 let facets = read_facets(&mut r)?;
765 let id = ast.exceptions.insert_at(
766 slot,
767 generation,
768 crate::ExceptionNode {
769 node_id,
770 name,
771 module,
772 scope,
773 members,
774 facets,
775 },
776 )?;
777 let any = AnyId::Exception(id, node_id);
778 let _ = ast.by_node_id.insert(node_id, any);
779 if let Ok(m) = ast.modules.get_mut(module) {
780 m.children.push(any);
781 }
782 }
783
784 let iface_slots = bounded_count(&mut r, 1)?;
786 let iface_count = bounded_count(&mut r, 24)?;
787 for _ in 0..iface_count {
788 let slot = bounded_slot(&mut r, iface_slots)?;
789 let generation = r.u32()?;
790 let node_id = r.node_id()?;
791 let name = r.string()?;
792 let module = Id::from_parts(r.u32()?, r.u32()?)?;
793 let kind = interface_kind_from_tag(r.u8()?, &r)?;
794 let completeness = if r.bool()? {
795 Completeness::Complete
796 } else {
797 Completeness::Forward
798 };
799 let base_count = bounded_count(&mut r, 1)? as usize;
800 let mut bases = Vec::new();
801 for _ in 0..base_count {
802 bases.push(read_ref(&mut r)?);
803 }
804 let operations = read_handles(&mut r)?;
805 let attributes = read_handles(&mut r)?;
806 let facets = read_facets(&mut r)?;
807 let id = ast.interfaces.insert_at(
808 slot,
809 generation,
810 crate::InterfaceNode {
811 node_id,
812 name,
813 module,
814 kind,
815 bases,
816 operations,
817 attributes,
818 completeness,
819 facets,
820 },
821 )?;
822 let any = AnyId::Interface(id, node_id);
823 let _ = ast.by_node_id.insert(node_id, any);
824 if let Ok(m) = ast.modules.get_mut(module) {
825 m.children.push(any);
826 }
827 }
828
829 let op_slots = bounded_count(&mut r, 1)?;
830 let op_count = bounded_count(&mut r, 24)?;
831 for _ in 0..op_count {
832 let slot = bounded_slot(&mut r, op_slots)?;
833 let generation = r.u32()?;
834 let node_id = r.node_id()?;
835 let name = r.string()?;
836 let return_type = read_ref_opt(&mut r)?;
837 let oneway = r.bool()?;
838 let params = read_handles(&mut r)?;
839 let raise_count = bounded_count(&mut r, 1)? as usize;
840 let mut raises = Vec::new();
841 for _ in 0..raise_count {
842 raises.push(read_ref(&mut r)?);
843 }
844 let context_count = bounded_count(&mut r, 4)? as usize;
845 let mut contexts = Vec::new();
846 for _ in 0..context_count {
847 contexts.push(r.string()?);
848 }
849 let parent = read_any_parent(&mut r, &ast)?;
850 let facets = read_facets(&mut r)?;
851 let id = ast.operations.insert_at(
852 slot,
853 generation,
854 crate::OperationNode {
855 node_id,
856 name,
857 return_type,
858 params,
859 raises,
860 oneway,
861 contexts,
862 parent,
863 facets,
864 },
865 )?;
866 let _ = ast
867 .by_node_id
868 .insert(node_id, AnyId::Operation(id, node_id));
869 }
870
871 let param_slots = bounded_count(&mut r, 1)?;
872 let param_count = bounded_count(&mut r, 24)?;
873 for _ in 0..param_count {
874 let slot = bounded_slot(&mut r, param_slots)?;
875 let generation = r.u32()?;
876 let node_id = r.node_id()?;
877 let name = r.string()?;
878 let direction = direction_from_tag(r.u8()?, &r)?;
879 let type_ = read_type_ref(&mut r)?;
880 let parent = Id::from_parts(r.u32()?, r.u32()?)?;
881 let facets = read_facets(&mut r)?;
882 let id = ast.params.insert_at(
883 slot,
884 generation,
885 crate::ParamNode {
886 node_id,
887 name,
888 direction,
889 type_,
890 parent,
891 facets,
892 },
893 )?;
894 let _ = ast.by_node_id.insert(node_id, AnyId::Param(id, node_id));
895 }
896
897 let attr_slots = bounded_count(&mut r, 1)?;
898 let attr_count = bounded_count(&mut r, 24)?;
899 for _ in 0..attr_count {
900 let slot = bounded_slot(&mut r, attr_slots)?;
901 let generation = r.u32()?;
902 let node_id = r.node_id()?;
903 let name = r.string()?;
904 let type_ = read_type_ref(&mut r)?;
905 let readonly = r.bool()?;
906 let parent = Id::from_parts(r.u32()?, r.u32()?)?;
907 let get_count = bounded_count(&mut r, 1)? as usize;
908 let mut get_raises = Vec::new();
909 for _ in 0..get_count {
910 get_raises.push(read_ref(&mut r)?);
911 }
912 let set_count = bounded_count(&mut r, 1)? as usize;
913 let mut set_raises = Vec::new();
914 for _ in 0..set_count {
915 set_raises.push(read_ref(&mut r)?);
916 }
917 let facets = read_facets(&mut r)?;
918 let id = ast.attributes.insert_at(
919 slot,
920 generation,
921 crate::AttributeNode {
922 node_id,
923 name,
924 type_,
925 readonly,
926 get_raises,
927 set_raises,
928 parent,
929 facets,
930 },
931 )?;
932 let _ = ast
933 .by_node_id
934 .insert(node_id, AnyId::Attribute(id, node_id));
935 }
936
937 let adef_slots = bounded_count(&mut r, 1)?;
939 let adef_count = bounded_count(&mut r, 24)?;
940 for _ in 0..adef_count {
941 let slot = bounded_slot(&mut r, adef_slots)?;
942 let generation = r.u32()?;
943 let node_id = r.node_id()?;
944 let name = r.string()?;
945 let module = Id::from_parts(r.u32()?, r.u32()?)?;
946 let members = read_handles(&mut r)?;
947 let facets = read_facets(&mut r)?;
948 let id = ast.annotation_defs.insert_at(
949 slot,
950 generation,
951 crate::AnnotationDefNode {
952 node_id,
953 name,
954 module,
955 members,
956 facets,
957 },
958 )?;
959 let any = AnyId::AnnotationDef(id, node_id);
960 let _ = ast.by_node_id.insert(node_id, any);
961 if let Ok(m) = ast.modules.get_mut(module) {
962 m.children.push(any);
963 }
964 }
965
966 let amem_slots = bounded_count(&mut r, 1)?;
967 let amem_count = bounded_count(&mut r, 24)?;
968 for _ in 0..amem_count {
969 let slot = bounded_slot(&mut r, amem_slots)?;
970 let generation = r.u32()?;
971 let node_id = r.node_id()?;
972 let name = r.string()?;
973 let type_ = read_type_ref(&mut r)?;
974 let is_value_member = r.bool()?;
975 let parent = Id::from_parts(r.u32()?, r.u32()?)?;
976 let default = read_handle_opt(&mut r)?;
977 let facets = read_facets(&mut r)?;
978 let id = ast.annotation_members.insert_at(
979 slot,
980 generation,
981 crate::AnnotationMemberNode {
982 node_id,
983 name,
984 type_,
985 default,
986 is_value_member,
987 parent,
988 facets,
989 },
990 )?;
991 let _ = ast
992 .by_node_id
993 .insert(node_id, AnyId::AnnotationMember(id, node_id));
994 }
995
996 let lib_slots = bounded_count(&mut r, 1)?;
998 let lib_count = bounded_count(&mut r, 24)?;
999 for _ in 0..lib_count {
1000 let slot = bounded_slot(&mut r, lib_slots)?;
1001 let generation = r.u32()?;
1002 let node_id = r.node_id()?;
1003 let name = r.string()?;
1004 let facets = read_facets(&mut r)?;
1005 let id = ast.libraries.insert_at(
1006 slot,
1007 generation,
1008 crate::LibraryNode {
1009 node_id,
1010 name,
1011 children: Vec::new(),
1012 facets,
1013 },
1014 )?;
1015 let _ = ast.by_node_id.insert(node_id, AnyId::Library(id, node_id));
1016 }
1017
1018 let dom_slots = bounded_count(&mut r, 1)?;
1019 let dom_count = bounded_count(&mut r, 24)?;
1020 for _ in 0..dom_count {
1021 let slot = bounded_slot(&mut r, dom_slots)?;
1022 let generation = r.u32()?;
1023 let node_id = r.node_id()?;
1024 let name = r.string()?;
1025 let domain_id = r.u32()?;
1026 let parent = Id::from_parts(r.u32()?, r.u32()?)?;
1027 let facets = read_facets(&mut r)?;
1028 let id = ast.domains.insert_at(
1029 slot,
1030 generation,
1031 crate::DomainNode {
1032 node_id,
1033 name,
1034 domain_id,
1035 topics: Vec::new(),
1036 parent,
1037 facets,
1038 },
1039 )?;
1040 let any = AnyId::Domain(id, node_id);
1041 let _ = ast.by_node_id.insert(node_id, any);
1042 if let Ok(l) = ast.libraries.get_mut(parent) {
1043 l.children.push(any);
1044 }
1045 }
1046
1047 let qos_slots = bounded_count(&mut r, 1)?;
1048 let qos_count = bounded_count(&mut r, 24)?;
1049 for _ in 0..qos_count {
1050 let slot = bounded_slot(&mut r, qos_slots)?;
1051 let generation = r.u32()?;
1052 let node_id = r.node_id()?;
1053 let name = r.string()?;
1054 let parent = Id::from_parts(r.u32()?, r.u32()?)?;
1055 let base = read_ref_opt(&mut r)?;
1056 let policies = read_policies(&mut r)?;
1057 let facets = read_facets(&mut r)?;
1058 let id = ast.qos_profiles.insert_at(
1059 slot,
1060 generation,
1061 crate::QosProfileNode {
1062 node_id,
1063 name,
1064 base,
1065 policies,
1066 parent,
1067 facets,
1068 },
1069 )?;
1070 let any = AnyId::QosProfile(id, node_id);
1071 let _ = ast.by_node_id.insert(node_id, any);
1072 if let Ok(l) = ast.libraries.get_mut(parent) {
1073 l.children.push(any);
1074 }
1075 }
1076
1077 let topic_slots = bounded_count(&mut r, 1)?;
1078 let topic_count = bounded_count(&mut r, 24)?;
1079 for _ in 0..topic_count {
1080 let slot = bounded_slot(&mut r, topic_slots)?;
1081 let generation = r.u32()?;
1082 let node_id = r.node_id()?;
1083 let name = r.string()?;
1084 let type_ = read_type_ref(&mut r)?;
1085 let qos = read_ref_opt(&mut r)?;
1086 let parent = Id::from_parts(r.u32()?, r.u32()?)?;
1087 let facets = read_facets(&mut r)?;
1088 let id = ast.topics.insert_at(
1089 slot,
1090 generation,
1091 crate::TopicNode {
1092 node_id,
1093 name,
1094 type_,
1095 qos,
1096 parent,
1097 facets,
1098 },
1099 )?;
1100 let _ = ast.by_node_id.insert(node_id, AnyId::Topic(id, node_id));
1101 if let Ok(d) = ast.domains.get_mut(parent) {
1102 d.topics.push(id);
1103 }
1104 }
1105
1106 let part_slots = bounded_count(&mut r, 1)?;
1107 let part_count = bounded_count(&mut r, 24)?;
1108 for _ in 0..part_count {
1109 let slot = bounded_slot(&mut r, part_slots)?;
1110 let generation = r.u32()?;
1111 let node_id = r.node_id()?;
1112 let name = r.string()?;
1113 let domain = read_ref(&mut r)?;
1114 let qos = read_ref_opt(&mut r)?;
1115 let parent = Id::from_parts(r.u32()?, r.u32()?)?;
1116 let facets = read_facets(&mut r)?;
1117 let id = ast.participants.insert_at(
1118 slot,
1119 generation,
1120 crate::ParticipantNode {
1121 node_id,
1122 name,
1123 domain,
1124 qos,
1125 endpoints: Vec::new(),
1126 parent,
1127 facets,
1128 },
1129 )?;
1130 let any = AnyId::Participant(id, node_id);
1131 let _ = ast.by_node_id.insert(node_id, any);
1132 if let Ok(l) = ast.libraries.get_mut(parent) {
1133 l.children.push(any);
1134 }
1135 }
1136
1137 let ep_slots = bounded_count(&mut r, 1)?;
1138 let ep_count = bounded_count(&mut r, 24)?;
1139 for _ in 0..ep_count {
1140 let slot = bounded_slot(&mut r, ep_slots)?;
1141 let generation = r.u32()?;
1142 let node_id = r.node_id()?;
1143 let name = r.string()?;
1144 let role = if r.bool()? {
1145 crate::EndpointRole::DataWriter
1146 } else {
1147 crate::EndpointRole::DataReader
1148 };
1149 let topic = read_ref(&mut r)?;
1150 let qos = read_ref_opt(&mut r)?;
1151 let parent = Id::from_parts(r.u32()?, r.u32()?)?;
1152 let facets = read_facets(&mut r)?;
1153 let id = ast.endpoints.insert_at(
1154 slot,
1155 generation,
1156 crate::EndpointNode {
1157 node_id,
1158 name,
1159 role,
1160 topic,
1161 qos,
1162 parent,
1163 facets,
1164 },
1165 )?;
1166 let _ = ast.by_node_id.insert(node_id, AnyId::Endpoint(id, node_id));
1167 if let Ok(p) = ast.participants.get_mut(parent) {
1168 p.endpoints.push(id);
1169 }
1170 }
1171
1172 r.expect_end()?;
1173
1174 let member_ids: Vec<Id<crate::MemberNode>> = ast.members.ids().collect();
1179 for member in member_ids {
1180 let Ok(node) = ast.members.get(member) else {
1181 continue;
1182 };
1183 let AnyId::Exception(owner, _) = node.parent else {
1184 continue;
1185 };
1186 let Ok(owner_node) = ast.exceptions.get(owner) else {
1187 continue;
1188 };
1189 let owner_id = owner_node.node_id;
1190 if let Ok(node) = ast.members.get_mut(member) {
1191 node.parent = AnyId::Exception(owner, owner_id);
1192 }
1193 }
1194
1195 let member_ids: Vec<Id<crate::MemberNode>> = ast.members.ids().collect();
1201 for member in member_ids {
1202 let Ok(node) = ast.members.get(member) else {
1203 continue;
1204 };
1205 let AnyId::Exception(owner, _) = node.parent else {
1206 continue;
1207 };
1208 let Ok(owner_node) = ast.exceptions.get(owner) else {
1209 continue;
1210 };
1211 let owner_id = owner_node.node_id;
1212 if let Ok(node) = ast.members.get_mut(member) {
1213 node.parent = AnyId::Exception(owner, owner_id);
1214 }
1215 }
1216
1217 ast.reindex();
1222 let nodes: Vec<AnyId> = ast.by_node_id.values().copied().collect();
1223 for any in nodes {
1224 ast.index_pending(any);
1225 }
1226 Ok(ast)
1227 }
1228}
1229
1230fn count(value: usize) -> Result<u32, AstError> {
1231 u32::try_from(value).map_err(|_| AstError::Core(AstCoreError::Exhausted))
1232}
1233
1234fn bounded_count(r: &mut SnapshotReader<'_>, min_entry: usize) -> Result<u32, AstError> {
1243 let declared = r.u32()?;
1244 let needed = (declared as usize).saturating_mul(min_entry);
1245 if needed > r.remaining() {
1246 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
1247 offset: r.offset(),
1248 expected: "an element count the remaining buffer can hold",
1249 }));
1250 }
1251 Ok(declared)
1252}
1253
1254fn bounded_slot(r: &mut SnapshotReader<'_>, capacity: u32) -> Result<u32, AstError> {
1262 let slot = r.u32()?;
1263 if slot >= capacity {
1264 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
1265 offset: r.offset(),
1266 expected: "a slot index within the section's declared capacity",
1267 }));
1268 }
1269 Ok(slot)
1270}
1271
1272mod min_size {
1275 pub const MODULE: usize = 4 + 4 + 16 + 4 + 1;
1277 pub const EXPR: usize = 4 + 4 + 16 + 1;
1279 pub const TYPE: usize = 4 + 4 + 16 + 4 + 8 + 1 + 1;
1282 pub const MEMBER: usize = 4 + 4 + 16 + 4 + 1 + 1 + 1;
1285 pub const HANDLE: usize = 8;
1287 pub const REFERENCE: usize = 1;
1289}
1290
1291fn write_type_ref(
1292 w: &mut SnapshotWriter,
1293 reference: &Ref<crate::TypeNode>,
1294) -> Result<(), AstError> {
1295 write_ref(w, reference)
1296}
1297
1298fn read_type_ref(r: &mut SnapshotReader<'_>) -> Result<Ref<crate::TypeNode>, AstError> {
1299 read_ref(r)
1300}
1301
1302fn write_bound(w: &mut SnapshotWriter, bound: Bound) {
1303 match bound {
1304 Bound::Unbounded => w.u8(0),
1305 Bound::Const(id) => {
1306 w.u8(1);
1307 w.u32(id.slot());
1308 w.u32(id.generation());
1309 }
1310 }
1311}
1312
1313fn read_bound(r: &mut SnapshotReader<'_>) -> Result<Bound, AstError> {
1314 Ok(match r.u8()? {
1315 0 => Bound::Unbounded,
1316 1 => Bound::Const(Id::from_parts(r.u32()?, r.u32()?)?),
1317 _ => {
1318 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
1319 offset: r.offset(),
1320 expected: "bound tag 0 or 1",
1321 }));
1322 }
1323 })
1324}
1325
1326fn write_handles<T>(w: &mut SnapshotWriter, handles: &[Id<T>]) -> Result<(), AstError> {
1327 w.u32(count(handles.len())?);
1328 for handle in handles {
1329 w.u32(handle.slot());
1330 w.u32(handle.generation());
1331 }
1332 Ok(())
1333}
1334
1335fn read_handles<T>(r: &mut SnapshotReader<'_>) -> Result<Vec<Id<T>>, AstError> {
1336 let len = bounded_count(r, min_size::HANDLE)? as usize;
1337 let mut out = Vec::new();
1338 for _ in 0..len {
1339 out.push(Id::from_parts(r.u32()?, r.u32()?)?);
1340 }
1341 Ok(out)
1342}
1343
1344fn write_kind(w: &mut SnapshotWriter, kind: &TypeKind) -> Result<(), AstError> {
1345 match kind {
1346 TypeKind::Primitive(p) => {
1347 w.u8(tag::PRIMITIVE);
1348 w.u8(primitive_tag(*p));
1349 }
1350 TypeKind::Fixed { digits, scale } => {
1351 w.u8(tag::FIXED);
1352 w.u8(*digits);
1353 w.u8(*scale);
1354 }
1355 TypeKind::String { width, bound } => {
1356 w.u8(tag::STRING);
1357 w.u8(u8::from(matches!(width, CharWidth::WChar)));
1358 write_bound(w, *bound);
1359 }
1360 TypeKind::Sequence { element, bound } => {
1361 w.u8(tag::SEQUENCE);
1362 write_type_ref(w, element)?;
1363 write_bound(w, *bound);
1364 }
1365 TypeKind::Array { element, dims } => {
1366 w.u8(tag::ARRAY);
1367 write_type_ref(w, element)?;
1368 write_handles(w, dims)?;
1369 }
1370 TypeKind::Map { key, value, bound } => {
1371 w.u8(tag::MAP);
1372 write_type_ref(w, key)?;
1373 write_type_ref(w, value)?;
1374 write_bound(w, *bound);
1375 }
1376 TypeKind::Structure { base, members } => {
1377 w.u8(tag::STRUCTURE);
1378 match base {
1379 Some(base) => {
1380 w.bool(true);
1381 write_type_ref(w, base)?;
1382 }
1383 None => w.bool(false),
1384 }
1385 write_handles(w, members)?;
1386 }
1387 TypeKind::Union {
1388 discriminator,
1389 cases,
1390 default_case,
1391 } => {
1392 w.u8(tag::UNION);
1393 write_type_ref(w, discriminator)?;
1394 write_handles(w, cases)?;
1395 write_handle_opt(w, *default_case);
1400 }
1401 TypeKind::Enumeration { enumerators } => {
1402 w.u8(tag::ENUMERATION);
1403 write_handles(w, enumerators)?;
1404 }
1405 TypeKind::Bitmask { bits } => {
1406 w.u8(tag::BITMASK);
1407 write_handles(w, bits)?;
1408 }
1409 TypeKind::Bitset { base, fields } => {
1410 w.u8(tag::BITSET);
1411 write_handles(w, fields)?;
1412 write_type_ref_opt(w, base.as_ref())?;
1414 }
1415 TypeKind::Alias { aliased } => {
1416 w.u8(tag::ALIAS);
1417 write_type_ref(w, aliased)?;
1418 }
1419 TypeKind::Valuetype {
1420 kind,
1421 bases,
1422 state,
1423 initializers,
1424 supported,
1425 } => {
1426 w.u8(tag::VALUETYPE);
1427 w.u8(valuetype_tag(*kind));
1428 w.u32(count(bases.len())?);
1429 for base in bases {
1430 write_type_ref(w, base)?;
1431 }
1432 write_handles(w, state)?;
1433 write_handles(w, initializers)?;
1434 w.u32(count(supported.len())?);
1435 for interface in supported {
1436 write_ref(w, interface)?;
1437 }
1438 }
1439 TypeKind::ValueBox { boxed } => {
1440 w.u8(tag::VALUE_BOX);
1441 write_type_ref(w, boxed)?;
1442 }
1443 TypeKind::ObjectRef { interface } => {
1444 w.u8(tag::OBJECT_REF);
1445 match interface {
1446 Some(interface) => {
1447 w.bool(true);
1448 write_ref(w, interface)?;
1449 }
1450 None => w.bool(false),
1451 }
1452 }
1453 TypeKind::Any => w.u8(tag::ANY),
1454 TypeKind::ValueBase => w.u8(tag::VALUE_BASE),
1455 TypeKind::AnnotationType { definition } => {
1456 w.u8(tag::ANNOTATION_TYPE);
1457 write_handle_opt(w, Some(*definition));
1458 }
1459 TypeKind::Native => w.u8(tag::NATIVE),
1460 }
1461 Ok(())
1462}
1463
1464fn valuetype_tag(kind: crate::ValuetypeKind) -> u8 {
1465 match kind {
1466 crate::ValuetypeKind::Regular => 0,
1467 crate::ValuetypeKind::Abstract => 1,
1468 crate::ValuetypeKind::Custom => 2,
1469 crate::ValuetypeKind::Truncatable => 3,
1470 }
1471}
1472
1473fn read_kind(r: &mut SnapshotReader<'_>) -> Result<TypeKind, AstError> {
1474 Ok(match r.u8()? {
1475 tag::PRIMITIVE => TypeKind::Primitive(primitive_from_tag(r.u8()?, r)?),
1476 tag::FIXED => TypeKind::Fixed {
1477 digits: r.u8()?,
1478 scale: r.u8()?,
1479 },
1480 tag::STRING => TypeKind::String {
1481 width: if r.u8()? == 0 {
1482 CharWidth::Char
1483 } else {
1484 CharWidth::WChar
1485 },
1486 bound: read_bound(r)?,
1487 },
1488 tag::SEQUENCE => TypeKind::Sequence {
1489 element: read_type_ref(r)?,
1490 bound: read_bound(r)?,
1491 },
1492 tag::ARRAY => TypeKind::Array {
1493 element: read_type_ref(r)?,
1494 dims: read_handles(r)?,
1495 },
1496 tag::MAP => TypeKind::Map {
1497 key: read_type_ref(r)?,
1498 value: read_type_ref(r)?,
1499 bound: read_bound(r)?,
1500 },
1501 tag::STRUCTURE => TypeKind::Structure {
1502 base: if r.bool()? {
1503 Some(read_type_ref(r)?)
1504 } else {
1505 None
1506 },
1507 members: read_handles(r)?,
1508 },
1509 tag::UNION => TypeKind::Union {
1510 discriminator: read_type_ref(r)?,
1511 cases: read_handles(r)?,
1512 default_case: read_handle_opt(r)?,
1513 },
1514 tag::ENUMERATION => TypeKind::Enumeration {
1515 enumerators: read_handles(r)?,
1516 },
1517 tag::BITMASK => TypeKind::Bitmask {
1518 bits: read_handles(r)?,
1519 },
1520 tag::BITSET => {
1521 let fields = read_handles(r)?;
1522 TypeKind::Bitset {
1523 fields,
1524 base: read_ref_opt(r)?,
1525 }
1526 }
1527 tag::ALIAS => TypeKind::Alias {
1528 aliased: read_type_ref(r)?,
1529 },
1530 tag::NATIVE => TypeKind::Native,
1531 tag::VALUETYPE => {
1532 let tag = r.u8()?;
1533 let kind =
1534 crate::ValuetypeKind::ALL
1535 .get(tag as usize)
1536 .copied()
1537 .ok_or(AstError::Core(AstCoreError::MalformedSnapshot {
1538 offset: r.offset(),
1539 expected: "a known valuetype modifier tag",
1540 }))?;
1541 let base_count = bounded_count(r, min_size::REFERENCE)? as usize;
1542 let mut bases = Vec::new();
1543 for _ in 0..base_count {
1544 bases.push(read_type_ref(r)?);
1545 }
1546 let state = read_handles(r)?;
1547 let initializers = read_handles(r)?;
1548 let supported_count = bounded_count(r, min_size::REFERENCE)? as usize;
1549 let mut supported = Vec::new();
1550 for _ in 0..supported_count {
1551 supported.push(read_ref(r)?);
1552 }
1553 TypeKind::Valuetype {
1554 kind,
1555 bases,
1556 state,
1557 initializers,
1558 supported,
1559 }
1560 }
1561 tag::VALUE_BOX => TypeKind::ValueBox {
1562 boxed: read_type_ref(r)?,
1563 },
1564 tag::OBJECT_REF => TypeKind::ObjectRef {
1565 interface: if r.bool()? { Some(read_ref(r)?) } else { None },
1566 },
1567 tag::ANY => TypeKind::Any,
1568 tag::VALUE_BASE => TypeKind::ValueBase,
1569 tag::ANNOTATION_TYPE => TypeKind::AnnotationType {
1570 definition: read_handle_opt(r)?.ok_or(AstError::Core(
1571 AstCoreError::MalformedSnapshot {
1572 offset: r.offset(),
1573 expected: "an annotation type's declaration handle",
1574 },
1575 ))?,
1576 },
1577 _ => {
1578 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
1579 offset: r.offset(),
1580 expected: "a known type kind tag",
1581 }));
1582 }
1583 })
1584}
1585
1586fn primitive_tag(kind: PrimitiveKind) -> u8 {
1587 match kind {
1588 PrimitiveKind::Boolean => 0,
1589 PrimitiveKind::Octet => 1,
1590 PrimitiveKind::Char => 2,
1591 PrimitiveKind::WChar => 3,
1592 PrimitiveKind::Int8 => 4,
1593 PrimitiveKind::UInt8 => 5,
1594 PrimitiveKind::Int16 => 6,
1595 PrimitiveKind::UInt16 => 7,
1596 PrimitiveKind::Int32 => 8,
1597 PrimitiveKind::UInt32 => 9,
1598 PrimitiveKind::Int64 => 10,
1599 PrimitiveKind::UInt64 => 11,
1600 PrimitiveKind::Float32 => 12,
1601 PrimitiveKind::Float64 => 13,
1602 PrimitiveKind::Float128 => 14,
1603 }
1604}
1605
1606fn primitive_from_tag(tag: u8, r: &SnapshotReader<'_>) -> Result<PrimitiveKind, AstError> {
1607 PrimitiveKind::ALL
1608 .get(tag as usize)
1609 .copied()
1610 .ok_or(AstError::Core(AstCoreError::MalformedSnapshot {
1611 offset: r.offset(),
1612 expected: "a known primitive tag",
1613 }))
1614}
1615
1616fn write_expr(w: &mut SnapshotWriter, expr: &crate::ConstExpr) -> Result<(), AstError> {
1617 match expr {
1618 crate::ConstExpr::Literal(crate::Literal::Integer(value)) => {
1619 w.u8(0);
1620 w.i128(*value);
1621 }
1622 crate::ConstExpr::Literal(crate::Literal::Boolean(value)) => {
1623 w.u8(1);
1624 w.bool(*value);
1625 }
1626 crate::ConstExpr::Binary { op, lhs, rhs } => {
1627 w.u8(2);
1628 w.u8(binary_tag(*op));
1629 w.u32(lhs.slot());
1630 w.u32(lhs.generation());
1631 w.u32(rhs.slot());
1632 w.u32(rhs.generation());
1633 }
1634 crate::ConstExpr::Unary { op, operand } => {
1635 w.u8(3);
1636 w.u8(unary_tag(*op));
1637 w.u32(operand.slot());
1638 w.u32(operand.generation());
1639 }
1640 crate::ConstExpr::Literal(crate::Literal::Float { mantissa, exponent }) => {
1641 w.u8(4);
1642 w.str(mantissa)?;
1643 write_str_opt(w, exponent.as_deref())?;
1644 }
1645 crate::ConstExpr::Literal(crate::Literal::Fixed { digits, scale }) => {
1646 w.u8(5);
1647 w.str(digits)?;
1648 w.u8(*scale);
1649 }
1650 crate::ConstExpr::Literal(crate::Literal::Char(value)) => {
1651 w.u8(6);
1652 w.u32(*value as u32);
1653 }
1654 crate::ConstExpr::Literal(crate::Literal::WChar(value)) => {
1655 w.u8(7);
1656 w.u32(*value);
1657 }
1658 crate::ConstExpr::Literal(crate::Literal::String(value)) => {
1659 w.u8(8);
1660 w.str(value)?;
1661 }
1662 crate::ConstExpr::Literal(crate::Literal::WString(value)) => {
1663 w.u8(9);
1664 w.u32(count(value.len())?);
1665 for point in value {
1666 w.u32(*point);
1667 }
1668 }
1669 crate::ConstExpr::Literal(crate::Literal::Enumerator(reference)) => {
1670 w.u8(10);
1671 write_ref(w, reference)?;
1672 }
1673 crate::ConstExpr::NameRef(reference) => {
1674 w.u8(11);
1675 write_ref(w, reference)?;
1676 }
1677 }
1678 Ok(())
1679}
1680
1681fn read_expr(r: &mut SnapshotReader<'_>) -> Result<crate::ConstExpr, AstError> {
1682 Ok(match r.u8()? {
1683 0 => crate::ConstExpr::Literal(crate::Literal::Integer(r.i128()?)),
1684 1 => crate::ConstExpr::Literal(crate::Literal::Boolean(r.bool()?)),
1685 2 => {
1686 let op = binary_from_tag(r.u8()?, r)?;
1687 let lhs = Id::from_parts(r.u32()?, r.u32()?)?;
1688 let rhs = Id::from_parts(r.u32()?, r.u32()?)?;
1689 crate::ConstExpr::Binary { op, lhs, rhs }
1690 }
1691 3 => {
1692 let op = unary_from_tag(r.u8()?, r)?;
1693 let operand = Id::from_parts(r.u32()?, r.u32()?)?;
1694 crate::ConstExpr::Unary { op, operand }
1695 }
1696 4 => crate::ConstExpr::Literal(crate::Literal::Float {
1697 mantissa: r.string()?,
1698 exponent: read_str_opt(r)?,
1699 }),
1700 5 => crate::ConstExpr::Literal(crate::Literal::Fixed {
1701 digits: r.string()?,
1702 scale: r.u8()?,
1703 }),
1704 6 => {
1705 let value = r.u32()?;
1706 let ch =
1707 char::from_u32(value).ok_or(AstError::Core(AstCoreError::MalformedSnapshot {
1708 offset: r.offset(),
1709 expected: "a character literal's code point",
1710 }))?;
1711 crate::ConstExpr::Literal(crate::Literal::Char(ch))
1712 }
1713 7 => crate::ConstExpr::Literal(crate::Literal::WChar(r.u32()?)),
1714 8 => crate::ConstExpr::Literal(crate::Literal::String(r.string()?)),
1715 9 => {
1716 let n = bounded_count(r, 4)? as usize;
1717 let mut points = Vec::new();
1718 for _ in 0..n {
1719 points.push(r.u32()?);
1720 }
1721 crate::ConstExpr::Literal(crate::Literal::WString(points))
1722 }
1723 10 => crate::ConstExpr::Literal(crate::Literal::Enumerator(read_ref(r)?)),
1724 11 => crate::ConstExpr::NameRef(read_ref(r)?),
1725 _ => {
1726 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
1727 offset: r.offset(),
1728 expected: "a known expression tag",
1729 }));
1730 }
1731 })
1732}
1733
1734fn binary_tag(op: crate::node::constant::BinaryOp) -> u8 {
1735 use crate::node::constant::BinaryOp as B;
1736 match op {
1737 B::Or => 0,
1738 B::Xor => 1,
1739 B::And => 2,
1740 B::Shl => 3,
1741 B::Shr => 4,
1742 B::Add => 5,
1743 B::Sub => 6,
1744 B::Mul => 7,
1745 B::Div => 8,
1746 B::Mod => 9,
1747 }
1748}
1749
1750fn binary_from_tag(
1751 tag: u8,
1752 r: &SnapshotReader<'_>,
1753) -> Result<crate::node::constant::BinaryOp, AstError> {
1754 crate::node::constant::BinaryOp::ALL
1755 .get(tag as usize)
1756 .copied()
1757 .ok_or(AstError::Core(AstCoreError::MalformedSnapshot {
1758 offset: r.offset(),
1759 expected: "a known binary operator tag",
1760 }))
1761}
1762
1763fn unary_tag(op: crate::UnaryOp) -> u8 {
1764 match op {
1765 crate::UnaryOp::Plus => 0,
1766 crate::UnaryOp::Minus => 1,
1767 crate::UnaryOp::Not => 2,
1768 }
1769}
1770
1771fn unary_from_tag(tag: u8, r: &SnapshotReader<'_>) -> Result<crate::UnaryOp, AstError> {
1772 crate::UnaryOp::ALL
1773 .get(tag as usize)
1774 .copied()
1775 .ok_or(AstError::Core(AstCoreError::MalformedSnapshot {
1776 offset: r.offset(),
1777 expected: "a known unary operator tag",
1778 }))
1779}
1780
1781fn write_ref<T>(w: &mut SnapshotWriter, reference: &Ref<T>) -> Result<(), AstError> {
1792 match reference {
1793 Ref::Resolved(id) => {
1794 w.u8(1);
1795 w.u32(id.slot());
1796 w.u32(id.generation());
1797 }
1798 Ref::Pending(key) => {
1799 w.u8(2);
1800 write_pending_key(w, key)?;
1801 }
1802 Ref::Broken(cause) => {
1803 w.u8(3);
1804 write_break_cause(w, cause)?;
1805 }
1806 }
1807 Ok(())
1808}
1809
1810fn write_pending_key(
1811 w: &mut SnapshotWriter,
1812 key: &zerodds_ast_core::PendingRef,
1813) -> Result<(), AstError> {
1814 use zerodds_ast_core::{PendingRef, RosInterfaceKind};
1815 match key {
1816 PendingRef::ScopedName(name) => {
1817 w.u8(0);
1818 w.bool(name.is_absolute());
1819 write_strings(w, name.segments())?;
1820 }
1821 PendingRef::TypeIdentifier(identifier) => {
1822 w.u8(1);
1823 for octet in identifier.0 {
1824 w.u8(octet);
1825 }
1826 }
1827 PendingRef::RosTypeName(name) => {
1828 w.u8(2);
1829 w.str(&name.package)?;
1830 w.u8(match name.kind {
1831 RosInterfaceKind::Msg => 0,
1832 RosInterfaceKind::Srv => 1,
1833 RosInterfaceKind::Action => 2,
1834 });
1835 w.str(&name.name)?;
1836 }
1837 PendingRef::RepositoryId(id) => {
1838 w.u8(3);
1839 w.str(&id.0)?;
1840 }
1841 PendingRef::XmlRef(key) => {
1842 w.u8(4);
1843 w.str(&key.0)?;
1844 }
1845 }
1846 Ok(())
1847}
1848
1849fn write_break_cause(
1850 w: &mut SnapshotWriter,
1851 cause: &zerodds_ast_core::BreakCause,
1852) -> Result<(), AstError> {
1853 use zerodds_ast_core::BreakCause;
1854 match cause {
1855 BreakCause::NotFound { what } => {
1856 w.u8(0);
1857 write_pending_key(w, what)?;
1858 }
1859 BreakCause::Ambiguous { what, candidates } => {
1860 w.u8(1);
1861 write_pending_key(w, what)?;
1862 w.u32(count(candidates.len())?);
1863 for candidate in candidates {
1864 w.node_id(*candidate);
1865 }
1866 }
1867 BreakCause::KindMismatch { expected, found } => {
1868 w.u8(2);
1869 w.str(expected)?;
1870 w.str(found)?;
1871 }
1872 BreakCause::IllegalCycle { through } => {
1873 w.u8(3);
1874 w.node_id(*through);
1875 }
1876 }
1877 Ok(())
1878}
1879
1880fn write_ref_opt<T>(w: &mut SnapshotWriter, reference: Option<&Ref<T>>) -> Result<(), AstError> {
1881 match reference {
1882 Some(reference) => {
1883 w.bool(true);
1884 write_ref(w, reference)?;
1885 }
1886 None => w.bool(false),
1887 }
1888 Ok(())
1889}
1890
1891fn write_type_ref_opt(
1892 w: &mut SnapshotWriter,
1893 reference: Option<&Ref<crate::TypeNode>>,
1894) -> Result<(), AstError> {
1895 write_ref_opt(w, reference)
1896}
1897
1898fn read_ref<T>(r: &mut SnapshotReader<'_>) -> Result<Ref<T>, AstError> {
1899 Ok(match r.u8()? {
1900 1 => Ref::Resolved(Id::from_parts(r.u32()?, r.u32()?)?),
1901 2 => Ref::Pending(read_pending_key(r)?),
1902 3 => Ref::Broken(read_break_cause(r)?),
1903 _ => {
1904 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
1905 offset: r.offset(),
1906 expected: "reference tag 1, 2 or 3",
1907 }));
1908 }
1909 })
1910}
1911
1912fn read_pending_key(r: &mut SnapshotReader<'_>) -> Result<zerodds_ast_core::PendingRef, AstError> {
1913 use zerodds_ast_core::{
1914 PendingRef, RepositoryId, RosInterfaceKind, RosTypeName, ScopedName, TypeIdentifierKey,
1915 XmlRefKey,
1916 };
1917 Ok(match r.u8()? {
1918 0 => {
1919 let absolute = r.bool()?;
1920 let segments = read_strings(r)?;
1921 PendingRef::ScopedName(if absolute {
1922 ScopedName::absolute(segments)
1923 } else {
1924 ScopedName::relative(segments)
1925 })
1926 }
1927 1 => {
1928 let mut identifier = [0u8; 16];
1929 for octet in &mut identifier {
1930 *octet = r.u8()?;
1931 }
1932 PendingRef::TypeIdentifier(TypeIdentifierKey(identifier))
1933 }
1934 2 => {
1935 let package = r.string()?;
1936 let kind = match r.u8()? {
1937 0 => RosInterfaceKind::Msg,
1938 1 => RosInterfaceKind::Srv,
1939 2 => RosInterfaceKind::Action,
1940 _ => {
1941 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
1942 offset: r.offset(),
1943 expected: "a ROS interface kind tag 0, 1 or 2",
1944 }));
1945 }
1946 };
1947 let name = r.string()?;
1948 PendingRef::RosTypeName(RosTypeName {
1949 package,
1950 kind,
1951 name,
1952 })
1953 }
1954 3 => PendingRef::RepositoryId(RepositoryId(r.string()?)),
1955 4 => PendingRef::XmlRef(XmlRefKey(r.string()?)),
1956 _ => {
1957 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
1958 offset: r.offset(),
1959 expected: "a lookup key tag 0 to 4",
1960 }));
1961 }
1962 })
1963}
1964
1965fn kind_mismatch_name(text: &str) -> Option<&'static str> {
1970 const PHRASES: [&str; 3] = [
1971 "a different kind of declaration",
1972 "a declaration the reference accepts",
1973 "nothing",
1974 ];
1975 PHRASES
1976 .iter()
1977 .copied()
1978 .chain(crate::NodeKind::ALL.iter().map(|kind| kind.as_str()))
1979 .find(|known| *known == text)
1980}
1981
1982fn read_break_cause(r: &mut SnapshotReader<'_>) -> Result<zerodds_ast_core::BreakCause, AstError> {
1983 use zerodds_ast_core::BreakCause;
1984 Ok(match r.u8()? {
1985 0 => BreakCause::NotFound {
1986 what: read_pending_key(r)?,
1987 },
1988 1 => {
1989 let what = read_pending_key(r)?;
1990 let n = bounded_count(r, 16)? as usize;
1991 let mut candidates = Vec::new();
1992 for _ in 0..n {
1993 candidates.push(r.node_id()?);
1994 }
1995 BreakCause::Ambiguous { what, candidates }
1996 }
1997 2 => {
1998 let name = |r: &mut SnapshotReader<'_>| -> Result<&'static str, AstError> {
1999 let text = r.string()?;
2000 kind_mismatch_name(&text).ok_or(AstError::Core(AstCoreError::MalformedSnapshot {
2001 offset: r.offset(),
2002 expected: "a kind name the resolver writes",
2003 }))
2004 };
2005 let expected = name(r)?;
2006 let found = name(r)?;
2007 BreakCause::KindMismatch { expected, found }
2008 }
2009 3 => BreakCause::IllegalCycle {
2010 through: r.node_id()?,
2011 },
2012 _ => {
2013 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
2014 offset: r.offset(),
2015 expected: "a break cause tag 0 to 3",
2016 }));
2017 }
2018 })
2019}
2020
2021fn read_ref_opt<T>(r: &mut SnapshotReader<'_>) -> Result<Option<Ref<T>>, AstError> {
2022 Ok(if r.bool()? { Some(read_ref(r)?) } else { None })
2023}
2024
2025fn write_handle_opt<T>(w: &mut SnapshotWriter, handle: Option<Id<T>>) {
2026 match handle {
2027 Some(id) => {
2028 w.bool(true);
2029 w.u32(id.slot());
2030 w.u32(id.generation());
2031 }
2032 None => w.bool(false),
2033 }
2034}
2035
2036fn read_handle_opt<T>(r: &mut SnapshotReader<'_>) -> Result<Option<Id<T>>, AstError> {
2037 Ok(if r.bool()? {
2038 Some(Id::from_parts(r.u32()?, r.u32()?)?)
2039 } else {
2040 None
2041 })
2042}
2043
2044fn write_any_parent(w: &mut SnapshotWriter, parent: AnyId) {
2045 match parent {
2048 AnyId::Interface(id, _) => {
2049 w.u8(1);
2050 w.u32(id.slot());
2051 w.u32(id.generation());
2052 }
2053 AnyId::Type(id, _) => {
2054 w.u8(2);
2055 w.u32(id.slot());
2056 w.u32(id.generation());
2057 }
2058 _ => w.u8(0),
2059 }
2060}
2061
2062fn read_any_parent(r: &mut SnapshotReader<'_>, ast: &Ast) -> Result<AnyId, AstError> {
2063 match r.u8()? {
2064 1 => {
2065 let id: Id<crate::InterfaceNode> = Id::from_parts(r.u32()?, r.u32()?)?;
2066 let node_id = ast.interfaces.get(id)?.node_id;
2067 Ok(AnyId::Interface(id, node_id))
2068 }
2069 2 => {
2070 let id: Id<crate::TypeNode> = Id::from_parts(r.u32()?, r.u32()?)?;
2071 let node_id = ast.types.get(id)?.node_id;
2072 Ok(AnyId::Type(id, node_id))
2073 }
2074 _ => Err(AstError::Core(AstCoreError::MalformedSnapshot {
2075 offset: r.offset(),
2076 expected: "an operation's owning interface or valuetype",
2077 })),
2078 }
2079}
2080
2081fn interface_kind_tag(kind: crate::InterfaceKind) -> u8 {
2082 use crate::InterfaceKind as K;
2083 match kind {
2084 K::Interface => 0,
2085 K::Local => 1,
2086 K::Abstract => 2,
2087 K::Component => 3,
2088 K::Home => 4,
2089 K::Connector => 5,
2090 K::PortType => 6,
2091 }
2092}
2093
2094fn interface_kind_from_tag(
2095 tag: u8,
2096 r: &SnapshotReader<'_>,
2097) -> Result<crate::InterfaceKind, AstError> {
2098 crate::InterfaceKind::ALL
2099 .get(tag as usize)
2100 .copied()
2101 .ok_or(AstError::Core(AstCoreError::MalformedSnapshot {
2102 offset: r.offset(),
2103 expected: "a known interface kind tag",
2104 }))
2105}
2106
2107fn direction_tag(direction: crate::ParamDirection) -> u8 {
2108 use crate::ParamDirection as D;
2109 match direction {
2110 D::In => 0,
2111 D::Out => 1,
2112 D::InOut => 2,
2113 }
2114}
2115
2116fn direction_from_tag(tag: u8, r: &SnapshotReader<'_>) -> Result<crate::ParamDirection, AstError> {
2117 crate::ParamDirection::ALL
2118 .get(tag as usize)
2119 .copied()
2120 .ok_or(AstError::Core(AstCoreError::MalformedSnapshot {
2121 offset: r.offset(),
2122 expected: "a known parameter direction tag",
2123 }))
2124}
2125
2126fn write_policies(w: &mut SnapshotWriter, policies: &[crate::QosPolicy]) -> Result<(), AstError> {
2134 w.u32(count(policies.len())?);
2135 for policy in policies {
2136 w.u8(policy_tag(policy.kind())?);
2137 }
2138 Ok(())
2139}
2140
2141fn policy_tag(kind: crate::QosPolicyKind) -> Result<u8, AstError> {
2149 tag_of(crate::QosPolicyKind::ALL.iter().position(|c| *c == kind))
2150}
2151
2152fn tag_of(position: Option<usize>) -> Result<u8, AstError> {
2154 position
2155 .and_then(|index| u8::try_from(index).ok())
2156 .ok_or(AstError::Core(AstCoreError::Exhausted))
2157}
2158
2159fn read_policies(r: &mut SnapshotReader<'_>) -> Result<Vec<crate::QosPolicy>, AstError> {
2160 let len = bounded_count(r, 1)? as usize;
2161 let mut out = Vec::new();
2162 for _ in 0..len {
2163 let tag = r.u8()?;
2164 let kind = crate::QosPolicyKind::ALL
2165 .get(tag as usize)
2166 .copied()
2167 .ok_or(AstError::Core(AstCoreError::MalformedSnapshot {
2168 offset: r.offset(),
2169 expected: "a known QoS policy tag",
2170 }))?;
2171 out.push(empty_policy(kind));
2172 }
2173 Ok(out)
2174}
2175
2176fn empty_policy(kind: crate::QosPolicyKind) -> crate::QosPolicy {
2182 use crate::QosPolicy as P;
2183 use crate::QosPolicyKind as K;
2184 match kind {
2185 K::UserData => P::UserData { value: Vec::new() },
2186 K::TopicData => P::TopicData { value: Vec::new() },
2187 K::GroupData => P::GroupData { value: Vec::new() },
2188 K::Durability => P::Durability { kind: None },
2189 K::DurabilityService => P::DurabilityService {
2190 service_cleanup_delay: None,
2191 history_kind: None,
2192 history_depth: None,
2193 max_samples: None,
2194 max_instances: None,
2195 max_samples_per_instance: None,
2196 },
2197 K::Presentation => P::Presentation {
2198 access_scope: None,
2199 coherent_access: None,
2200 ordered_access: None,
2201 },
2202 K::Deadline => P::Deadline { period: None },
2203 K::LatencyBudget => P::LatencyBudget { duration: None },
2204 K::Ownership => P::Ownership { kind: None },
2205 K::OwnershipStrength => P::OwnershipStrength { value: None },
2206 K::Liveliness => P::Liveliness {
2207 kind: None,
2208 lease_duration: None,
2209 },
2210 K::TimeBasedFilter => P::TimeBasedFilter {
2211 minimum_separation: None,
2212 },
2213 K::Partition => P::Partition { name: Vec::new() },
2214 K::Reliability => P::Reliability {
2215 kind: None,
2216 max_blocking_time: None,
2217 },
2218 K::TransportPriority => P::TransportPriority { value: None },
2219 K::Lifespan => P::Lifespan { duration: None },
2220 K::DestinationOrder => P::DestinationOrder { kind: None },
2221 K::History => P::History {
2222 kind: None,
2223 depth: None,
2224 },
2225 K::ResourceLimits => P::ResourceLimits {
2226 max_samples: None,
2227 max_instances: None,
2228 max_samples_per_instance: None,
2229 },
2230 K::EntityFactory => P::EntityFactory {
2231 autoenable_created_entities: None,
2232 },
2233 K::WriterDataLifecycle => P::WriterDataLifecycle {
2234 autodispose_unregistered_instances: None,
2235 },
2236 K::ReaderDataLifecycle => P::ReaderDataLifecycle {
2237 autopurge_nowriter_samples_delay: None,
2238 autopurge_disposed_samples_delay: None,
2239 },
2240 K::DataRepresentation => P::DataRepresentation { value: Vec::new() },
2241 K::TypeConsistencyEnforcement => P::TypeConsistencyEnforcement {
2242 kind: None,
2243 ignore_sequence_bounds: None,
2244 ignore_string_bounds: None,
2245 ignore_member_names: None,
2246 prevent_type_widening: None,
2247 force_type_validation: None,
2248 },
2249 }
2250}
2251
2252fn write_facets(w: &mut SnapshotWriter, facets: &Facets) -> Result<(), AstError> {
2259 match &facets.source.origin {
2261 crate::SourceOrigin::File { path } => {
2262 w.u8(0);
2263 w.str(path)?;
2264 }
2265 crate::SourceOrigin::Synthetic { reason } => {
2266 w.u8(1);
2267 w.str(reason)?;
2268 }
2269 crate::SourceOrigin::Builtin => w.u8(2),
2270 }
2271 match facets.source.span {
2272 Some(span) => {
2273 w.bool(true);
2274 w.u32(span.start);
2275 w.u32(span.end);
2276 }
2277 None => w.bool(false),
2278 }
2279 w.u32(count(facets.source.macro_chain.len())?);
2280 for expansion in &facets.source.macro_chain {
2281 w.str(&expansion.name)?;
2282 match expansion.invoked_at {
2283 Some(span) => {
2284 w.bool(true);
2285 w.u32(span.start);
2286 w.u32(span.end);
2287 }
2288 None => w.bool(false),
2289 }
2290 match &expansion.path {
2291 Some(path) => {
2292 w.bool(true);
2293 w.str(path)?;
2294 }
2295 None => w.bool(false),
2296 }
2297 }
2298 w.u32(count(facets.source.doc_comments.len())?);
2299 for comment in &facets.source.doc_comments {
2300 w.str(comment)?;
2301 }
2302
2303 match facets.xtypes.as_ref() {
2305 Some(x) => {
2306 w.bool(true);
2307 w.u8(match x.extensibility {
2308 None => 0,
2309 Some(crate::Extensibility::Final) => 1,
2310 Some(crate::Extensibility::Appendable) => 2,
2311 Some(crate::Extensibility::Mutable) => 3,
2312 });
2313 w.bool(x.is_key);
2314 w.bool(x.is_optional);
2315 w.bool(x.is_external);
2316 w.bool(x.is_must_understand);
2317 w.bool(x.is_non_serialized);
2318 w.bool(x.is_nested);
2319 w.bool(x.is_default_literal);
2320 w.bool(x.discriminator_is_key);
2321 match x.default_nested {
2322 None => w.u8(0),
2323 Some(false) => w.u8(1),
2324 Some(true) => w.u8(2),
2325 }
2326 for behaviour in [
2327 x.try_construct,
2328 x.element_try_construct,
2329 x.key_try_construct,
2330 x.discriminator_try_construct,
2331 ] {
2332 w.u8(try_construct_tag(behaviour));
2333 }
2334 w.bool(x.discriminator_is_key);
2335 match x.member_id.as_ref() {
2336 Some(assignment) => {
2337 w.bool(true);
2338 w.u32(assignment.effective);
2339 w.u8(match &assignment.origin {
2340 crate::MemberIdOrigin::Declared => 0,
2341 crate::MemberIdOrigin::Hashed { .. } => 1,
2342 crate::MemberIdOrigin::AutoSequential => 2,
2343 crate::MemberIdOrigin::AutoHash => 3,
2344 crate::MemberIdOrigin::PreviousPlusOne => 4,
2345 });
2346 if let crate::MemberIdOrigin::Hashed { source_name } = &assignment.origin {
2347 w.str(source_name)?;
2348 }
2349 }
2350 None => w.bool(false),
2351 }
2352 match x.bit_bound {
2353 Some(bound) => {
2354 w.bool(true);
2355 w.u16(bound);
2356 }
2357 None => w.bool(false),
2358 }
2359 write_handle_opt(w, x.default_value);
2360 match x.range.as_ref() {
2361 Some(range) => {
2362 w.bool(true);
2363 write_handle_opt(w, range.min);
2364 write_handle_opt(w, range.max);
2365 }
2366 None => w.bool(false),
2367 }
2368 match x.unit.as_deref() {
2369 Some(unit) => {
2370 w.bool(true);
2371 w.str(unit)?;
2372 }
2373 None => w.bool(false),
2374 }
2375 w.u32(count(x.verbatim.len())?);
2376 for directive in &x.verbatim {
2377 w.str(&directive.language)?;
2378 w.u8(verbatim_tag(directive.placement)?);
2379 w.str(&directive.text)?;
2380 }
2381 w.u8(match x.autoid {
2382 None => 0,
2383 Some(crate::AutoId::Sequential) => 1,
2384 Some(crate::AutoId::Hash) => 2,
2385 });
2386 match x.topic.as_ref() {
2387 Some(topic) => {
2388 w.bool(true);
2389 write_str_opt(&mut *w, topic.name.as_deref())?;
2390 write_str_opt(&mut *w, topic.platform.as_deref())?;
2391 }
2392 None => w.bool(false),
2393 }
2394 match x.data_representation {
2395 Some(mask) => {
2396 w.bool(true);
2397 w.bool(mask.xcdr1);
2398 w.bool(mask.xcdr2);
2399 w.bool(mask.xml);
2400 }
2401 None => w.bool(false),
2402 }
2403 w.bool(x.ignore_literal_names);
2404 w.bool(x.nested_explicit);
2405 w.bool(x.element_is_external);
2406 w.bool(x.key_is_external);
2407 }
2408 None => w.bool(false),
2409 }
2410
2411 match facets.corba.as_ref() {
2413 Some(c) => {
2414 w.bool(true);
2415 match c.repository_id.as_ref() {
2416 Some(id) => {
2417 w.bool(true);
2418 w.str(&id.0)?;
2419 }
2420 None => w.bool(false),
2421 }
2422 match c.native_mapping.as_deref() {
2423 Some(mapping) => {
2424 w.bool(true);
2425 w.str(mapping)?;
2426 }
2427 None => w.bool(false),
2428 }
2429 w.u8(match c.repository_id_origin {
2430 None => 0,
2431 Some(crate::RepositoryIdOrigin::Derived) => 1,
2432 Some(crate::RepositoryIdOrigin::PragmaPrefix) => 2,
2433 Some(crate::RepositoryIdOrigin::PragmaVersion) => 3,
2434 Some(crate::RepositoryIdOrigin::PragmaId) => 4,
2435 });
2436 write_component_role(w, c.component_role.as_ref())?;
2437 w.u32(count(c.template_params.len())?);
2438 for param in &c.template_params {
2439 w.str(¶m.name)?;
2440 w.u8(template_param_tag(param.kind)?);
2441 write_type_ref_opt(w, param.constraint.as_ref())?;
2442 }
2443 w.u32(count(c.template_args.len())?);
2444 for arg in &c.template_args {
2445 match arg {
2446 crate::facet::corba::TemplateArg::Type(reference) => {
2447 w.u8(0);
2448 write_type_ref(w, reference)?;
2449 }
2450 crate::facet::corba::TemplateArg::Const(expr) => {
2451 w.u8(1);
2452 write_handle_opt(w, Some(*expr));
2453 }
2454 }
2455 }
2456 w.bool(c.is_service);
2457 w.u32(count(c.service_arguments.len())?);
2458 for argument in &c.service_arguments {
2459 write_str_opt(w, argument.name.as_deref())?;
2460 write_handle_opt(w, Some(argument.value));
2461 }
2462 w.bool(c.is_ami);
2463 match c.manages.as_ref() {
2464 Some(manages) => {
2465 w.bool(true);
2466 write_ref(w, &manages.component)?;
2467 write_type_ref_opt(w, manages.primary_key.as_ref())?;
2468 }
2469 None => w.bool(false),
2470 }
2471 write_strings(w, &c.imports)?;
2472 write_strings(w, &c.repository_directives)?;
2473 w.u32(count(c.supports.len())?);
2474 for interface in &c.supports {
2475 write_ref(w, interface)?;
2476 }
2477 w.u8(match c.state_visibility {
2478 None => 0,
2479 Some(crate::StateVisibility::Public) => 1,
2480 Some(crate::StateVisibility::Private) => 2,
2481 });
2482 w.bool(c.is_event_type);
2483 }
2484 None => w.bool(false),
2485 }
2486
2487 match facets.ros2.as_ref() {
2489 Some(rf) => {
2490 w.bool(true);
2491 w.bool(rf.was_constant);
2492 write_handle_opt(w, rf.default_value);
2493 match rf.ros_name.as_ref() {
2494 Some(name) => {
2495 w.bool(true);
2496 w.str(&name.package)?;
2497 w.u8(match name.kind {
2498 zerodds_ast_core::RosInterfaceKind::Msg => 0,
2499 zerodds_ast_core::RosInterfaceKind::Srv => 1,
2500 zerodds_ast_core::RosInterfaceKind::Action => 2,
2501 });
2502 w.str(&name.name)?;
2503 }
2504 None => w.bool(false),
2505 }
2506 w.u8(match rf.bounded_origin {
2507 None => 0,
2508 Some(crate::RosBoundedOrigin::BoundedArray) => 1,
2509 Some(crate::RosBoundedOrigin::FixedArray) => 2,
2510 Some(crate::RosBoundedOrigin::BoundedString) => 3,
2511 Some(crate::RosBoundedOrigin::UnboundedArray) => 4,
2512 });
2513 w.u8(match rf.interface_role {
2514 None => 0,
2515 Some(crate::RosInterfaceRole::Msg) => 1,
2516 Some(crate::RosInterfaceRole::Request) => 2,
2517 Some(crate::RosInterfaceRole::Response) => 3,
2518 Some(crate::RosInterfaceRole::Goal) => 4,
2519 Some(crate::RosInterfaceRole::Result) => 5,
2520 Some(crate::RosInterfaceRole::Feedback) => 6,
2521 });
2522 }
2523 None => w.bool(false),
2524 }
2525
2526 match facets.xml.as_ref() {
2528 Some(x) => {
2529 w.bool(true);
2530 w.str(&x.element)?;
2531 w.u32(count(x.library_path.len())?);
2532 for segment in &x.library_path {
2533 w.str(segment)?;
2534 }
2535 w.u32(count(x.attributes.len())?);
2536 for (name, value) in &x.attributes {
2537 w.str(name)?;
2538 w.str(value)?;
2539 }
2540 w.u32(count(x.unresolved_idrefs.len())?);
2541 for key in &x.unresolved_idrefs {
2542 w.str(&key.0)?;
2543 }
2544 match x.xsd_type.as_deref() {
2545 Some(xsd) => {
2546 w.bool(true);
2547 w.str(xsd)?;
2548 }
2549 None => w.bool(false),
2550 }
2551 }
2552 None => w.bool(false),
2553 }
2554
2555 match facets.flatdata.as_ref() {
2557 Some(f) => {
2558 w.bool(true);
2559 w.bool(f.is_plain);
2560 w.bool(f.explicit_fixed_layout);
2561 match f.loan_alignment {
2562 Some(align) => {
2563 w.bool(true);
2564 w.u8(align);
2565 }
2566 None => w.bool(false),
2567 }
2568 }
2569 None => w.bool(false),
2570 }
2571
2572 match facets.vendor.rti.as_ref() {
2575 Some(rti) => {
2576 w.bool(true);
2577 write_strings(w, &rti.copy_directives)?;
2578 write_bool_opt(w, rti.resolve_name);
2579 write_bool_opt(w, rti.top_level);
2580 write_strings(w, &rti.keylist)?;
2581 write_pairs(w, &rti.unrecognised)?;
2582 }
2583 None => w.bool(false),
2584 }
2585 match facets.vendor.open_dds.as_ref() {
2586 Some(open_dds) => {
2587 w.bool(true);
2588 w.bool(open_dds.dcps_data_type);
2589 write_strings(w, &open_dds.dcps_data_keys)?;
2590 write_bool_opt(w, open_dds.supports_zero_copy);
2591 write_pairs(w, &open_dds.unrecognised)?;
2592 }
2593 None => w.bool(false),
2594 }
2595 match facets.vendor.fast_dds.as_ref() {
2596 Some(fast_dds) => {
2597 w.bool(true);
2598 write_strings(w, &fast_dds.xtypes_extensions)?;
2599 write_bool_opt(w, fast_dds.plain_data_type);
2600 write_pairs(w, &fast_dds.unrecognised)?;
2601 }
2602 None => w.bool(false),
2603 }
2604 match facets.vendor.core_dx.as_ref() {
2605 Some(core_dx) => {
2606 w.bool(true);
2607 write_strings(w, &core_dx.key_fields)?;
2608 write_pairs(w, &core_dx.unrecognised)?;
2609 }
2610 None => w.bool(false),
2611 }
2612
2613 w.u32(count(facets.annotations.len())?);
2616 for applied in &facets.annotations {
2617 w.str(&applied.name)?;
2618 write_ref(w, &applied.definition)?;
2619 w.u32(count(applied.arguments.len())?);
2620 for argument in &applied.arguments {
2621 write_str_opt(w, argument.name.as_deref())?;
2622 write_handle_opt(w, Some(argument.value));
2623 }
2624 }
2625
2626 Ok(())
2627}
2628
2629fn write_strings(w: &mut SnapshotWriter, values: &[String]) -> Result<(), AstError> {
2630 w.u32(count(values.len())?);
2631 for value in values {
2632 w.str(value)?;
2633 }
2634 Ok(())
2635}
2636
2637fn write_pairs(w: &mut SnapshotWriter, pairs: &[(String, String)]) -> Result<(), AstError> {
2638 w.u32(count(pairs.len())?);
2639 for (name, value) in pairs {
2640 w.str(name)?;
2641 w.str(value)?;
2642 }
2643 Ok(())
2644}
2645
2646fn write_bool_opt(w: &mut SnapshotWriter, value: Option<bool>) {
2647 match value {
2648 None => w.u8(0),
2649 Some(false) => w.u8(1),
2650 Some(true) => w.u8(2),
2651 }
2652}
2653
2654fn write_str_opt(w: &mut SnapshotWriter, value: Option<&str>) -> Result<(), AstError> {
2655 match value {
2656 Some(text) => {
2657 w.bool(true);
2658 w.str(text)?;
2659 }
2660 None => w.bool(false),
2661 }
2662 Ok(())
2663}
2664
2665fn template_param_tag(kind: crate::TemplateParamKind) -> Result<u8, AstError> {
2671 tag_of(
2672 crate::TemplateParamKind::ALL
2673 .iter()
2674 .position(|c| *c == kind),
2675 )
2676}
2677
2678fn write_component_role(
2680 w: &mut SnapshotWriter,
2681 role: Option<&crate::ComponentRole>,
2682) -> Result<(), AstError> {
2683 let Some(role) = role else {
2684 w.u8(0);
2685 return Ok(());
2686 };
2687 match role {
2688 crate::ComponentRole::Facet { name, interface } => {
2689 w.u8(1);
2690 w.str(name)?;
2691 write_ref(w, interface)?;
2692 }
2693 crate::ComponentRole::Receptacle {
2694 name,
2695 interface,
2696 multiple,
2697 } => {
2698 w.u8(2);
2699 w.str(name)?;
2700 write_ref(w, interface)?;
2701 w.bool(*multiple);
2702 }
2703 crate::ComponentRole::EventSource {
2704 name,
2705 event,
2706 publisher,
2707 } => {
2708 w.u8(3);
2709 w.str(name)?;
2710 write_type_ref(w, event)?;
2711 w.bool(*publisher);
2712 }
2713 crate::ComponentRole::EventSink { name, event } => {
2714 w.u8(4);
2715 w.str(name)?;
2716 write_type_ref(w, event)?;
2717 }
2718 crate::ComponentRole::HomeFactory => w.u8(5),
2719 crate::ComponentRole::HomeFinder => w.u8(6),
2720 crate::ComponentRole::PortTypeRole => w.u8(7),
2721 crate::ComponentRole::ConnectorRole => w.u8(8),
2722 }
2723 Ok(())
2724}
2725
2726fn verbatim_tag(placement: crate::VerbatimPlacement) -> Result<u8, AstError> {
2732 tag_of(
2733 crate::VerbatimPlacement::ALL
2734 .iter()
2735 .position(|c| *c == placement),
2736 )
2737}
2738
2739const fn try_construct_tag(behaviour: Option<crate::TryConstruct>) -> u8 {
2744 match behaviour {
2745 None => 0,
2746 Some(crate::TryConstruct::Discard) => 1,
2747 Some(crate::TryConstruct::UseDefault) => 2,
2748 Some(crate::TryConstruct::Trim) => 3,
2749 }
2750}
2751
2752fn read_try_construct(r: &mut SnapshotReader<'_>) -> Result<Option<crate::TryConstruct>, AstError> {
2753 match r.u8()? {
2754 0 => Ok(None),
2755 1 => Ok(Some(crate::TryConstruct::Discard)),
2756 2 => Ok(Some(crate::TryConstruct::UseDefault)),
2757 3 => Ok(Some(crate::TryConstruct::Trim)),
2758 _ => Err(AstError::Core(AstCoreError::MalformedSnapshot {
2759 offset: r.offset(),
2760 expected: "a known try-construct tag",
2761 })),
2762 }
2763}
2764
2765fn read_facets(r: &mut SnapshotReader<'_>) -> Result<Facets, AstError> {
2766 let mut facets = Facets::synthetic("loaded from a snapshot");
2767
2768 facets.source.origin = match r.u8()? {
2769 0 => crate::SourceOrigin::File { path: r.string()? },
2770 1 => crate::SourceOrigin::Synthetic {
2771 reason: r.string()?,
2772 },
2773 2 => crate::SourceOrigin::Builtin,
2774 _ => {
2775 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
2776 offset: r.offset(),
2777 expected: "a known source-origin tag",
2778 }));
2779 }
2780 };
2781 facets.source.span = if r.bool()? {
2782 Some(crate::ByteSpan {
2783 start: r.u32()?,
2784 end: r.u32()?,
2785 })
2786 } else {
2787 None
2788 };
2789 let expansions = bounded_count(r, 5)? as usize;
2790 for _ in 0..expansions {
2791 let name = r.string()?;
2792 let invoked_at = if r.bool()? {
2793 Some(crate::ByteSpan {
2794 start: r.u32()?,
2795 end: r.u32()?,
2796 })
2797 } else {
2798 None
2799 };
2800 let path = if r.bool()? { Some(r.string()?) } else { None };
2801 facets.source.macro_chain.push(crate::MacroExpansion {
2802 name,
2803 invoked_at,
2804 path,
2805 });
2806 }
2807 let comments = bounded_count(r, 4)? as usize;
2808 for _ in 0..comments {
2809 facets.source.doc_comments.push(r.string()?);
2810 }
2811
2812 if r.bool()? {
2813 let x = facets.xtypes_mut();
2814 x.extensibility = match r.u8()? {
2815 0 => None,
2816 1 => Some(crate::Extensibility::Final),
2817 2 => Some(crate::Extensibility::Appendable),
2818 3 => Some(crate::Extensibility::Mutable),
2819 _ => {
2820 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
2821 offset: r.offset(),
2822 expected: "a known extensibility tag",
2823 }));
2824 }
2825 };
2826 x.is_key = r.bool()?;
2827 x.is_optional = r.bool()?;
2828 x.is_external = r.bool()?;
2829 x.is_must_understand = r.bool()?;
2830 x.is_non_serialized = r.bool()?;
2831 x.is_nested = r.bool()?;
2832 x.is_default_literal = r.bool()?;
2833 x.discriminator_is_key = r.bool()?;
2834 x.default_nested = match r.u8()? {
2835 0 => None,
2836 1 => Some(false),
2837 2 => Some(true),
2838 _ => {
2839 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
2840 offset: r.offset(),
2841 expected: "a known @default_nested tag",
2842 }));
2843 }
2844 };
2845 x.try_construct = read_try_construct(r)?;
2846 x.element_try_construct = read_try_construct(r)?;
2847 x.key_try_construct = read_try_construct(r)?;
2848 x.discriminator_try_construct = read_try_construct(r)?;
2849 x.discriminator_is_key = r.bool()?;
2850 if r.bool()? {
2851 let effective = r.u32()?;
2852 let origin_tag = r.u8()?;
2853 let origin = match origin_tag {
2854 0 => crate::MemberIdOrigin::Declared,
2855 1 => crate::MemberIdOrigin::Hashed {
2856 source_name: r.string()?,
2857 },
2858 2 => crate::MemberIdOrigin::AutoSequential,
2859 3 => crate::MemberIdOrigin::AutoHash,
2860 4 => crate::MemberIdOrigin::PreviousPlusOne,
2861 _ => {
2862 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
2863 offset: r.offset(),
2864 expected: "a known member-id origin tag",
2865 }));
2866 }
2867 };
2868 x.member_id = Some(crate::MemberIdAssignment { effective, origin });
2869 }
2870 if r.bool()? {
2871 x.bit_bound = Some(r.u16()?);
2872 }
2873 x.default_value = read_handle_opt(r)?;
2874 if r.bool()? {
2875 x.range = Some(crate::RangeConstraint {
2876 min: read_handle_opt(r)?,
2877 max: read_handle_opt(r)?,
2878 });
2879 }
2880 if r.bool()? {
2881 x.unit = Some(r.string()?);
2882 }
2883 let directives = bounded_count(r, 6)? as usize;
2884 for _ in 0..directives {
2885 let language = r.string()?;
2886 let tag = r.u8()?;
2887 let placement = crate::VerbatimPlacement::ALL
2888 .get(tag as usize)
2889 .copied()
2890 .ok_or(AstError::Core(AstCoreError::MalformedSnapshot {
2891 offset: r.offset(),
2892 expected: "a known verbatim placement tag",
2893 }))?;
2894 let text = r.string()?;
2895 x.verbatim.push(crate::VerbatimDirective {
2896 language,
2897 placement,
2898 text,
2899 });
2900 }
2901 x.autoid = match r.u8()? {
2902 0 => None,
2903 1 => Some(crate::AutoId::Sequential),
2904 2 => Some(crate::AutoId::Hash),
2905 _ => {
2906 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
2907 offset: r.offset(),
2908 expected: "a known autoid tag",
2909 }));
2910 }
2911 };
2912 if r.bool()? {
2913 x.topic = Some(crate::TopicAnnotation {
2914 name: read_str_opt(r)?,
2915 platform: read_str_opt(r)?,
2916 });
2917 }
2918 if r.bool()? {
2919 x.data_representation = Some(crate::DataRepresentationMask {
2920 xcdr1: r.bool()?,
2921 xcdr2: r.bool()?,
2922 xml: r.bool()?,
2923 });
2924 }
2925 x.ignore_literal_names = r.bool()?;
2926 x.nested_explicit = r.bool()?;
2927 x.element_is_external = r.bool()?;
2928 x.key_is_external = r.bool()?;
2929 }
2930
2931 if r.bool()? {
2932 let c = facets.corba_mut();
2933 if r.bool()? {
2934 c.repository_id = Some(zerodds_ast_core::RepositoryId(r.string()?));
2935 }
2936 if r.bool()? {
2937 c.native_mapping = Some(r.string()?);
2938 }
2939 c.repository_id_origin = match r.u8()? {
2940 0 => None,
2941 1 => Some(crate::RepositoryIdOrigin::Derived),
2942 2 => Some(crate::RepositoryIdOrigin::PragmaPrefix),
2943 3 => Some(crate::RepositoryIdOrigin::PragmaVersion),
2944 4 => Some(crate::RepositoryIdOrigin::PragmaId),
2945 _ => {
2946 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
2947 offset: r.offset(),
2948 expected: "a known repository-id origin tag",
2949 }));
2950 }
2951 };
2952 c.component_role = read_component_role(r)?;
2953 let params = bounded_count(r, 8)? as usize;
2954 for _ in 0..params {
2955 let name = r.string()?;
2956 let tag = r.u8()?;
2957 let kind = crate::TemplateParamKind::ALL
2958 .get(tag as usize)
2959 .copied()
2960 .ok_or(AstError::Core(AstCoreError::MalformedSnapshot {
2961 offset: r.offset(),
2962 expected: "a known template-parameter kind tag",
2963 }))?;
2964 let constraint = read_ref_opt(r)?;
2965 c.template_params.push(crate::TemplateParam {
2966 name,
2967 kind,
2968 constraint,
2969 });
2970 }
2971 let args = bounded_count(r, 8)? as usize;
2972 for _ in 0..args {
2973 let arg = match r.u8()? {
2974 0 => crate::facet::corba::TemplateArg::Type(read_type_ref(r)?),
2975 1 => {
2976 let expr = read_handle_opt(r)?.ok_or(AstError::Core(
2977 AstCoreError::MalformedSnapshot {
2978 offset: r.offset(),
2979 expected: "a constant template argument's expression",
2980 },
2981 ))?;
2982 crate::facet::corba::TemplateArg::Const(expr)
2983 }
2984 _ => {
2985 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
2986 offset: r.offset(),
2987 expected: "a known template-argument tag",
2988 }));
2989 }
2990 };
2991 c.template_args.push(arg);
2992 }
2993 c.is_service = r.bool()?;
2994 let service_argument_count = bounded_count(r, 5)? as usize;
2995 for _ in 0..service_argument_count {
2996 let argument_name = read_str_opt(r)?;
2997 let value =
2998 read_handle_opt(r)?.ok_or(AstError::Core(AstCoreError::MalformedSnapshot {
2999 offset: r.offset(),
3000 expected: "a `@service` argument's expression",
3001 }))?;
3002 c.service_arguments.push(crate::AppliedArgument {
3003 name: argument_name,
3004 value,
3005 });
3006 }
3007 c.is_ami = r.bool()?;
3008 if r.bool()? {
3009 c.manages = Some(crate::HomeManages {
3010 component: read_ref(r)?,
3011 primary_key: read_ref_opt(r)?,
3012 });
3013 }
3014 c.imports = read_strings(r)?;
3015 c.repository_directives = read_strings(r)?;
3016 let supports = bounded_count(r, 8)? as usize;
3017 for _ in 0..supports {
3018 c.supports.push(read_ref(r)?);
3019 }
3020 c.state_visibility = match r.u8()? {
3021 0 => None,
3022 1 => Some(crate::StateVisibility::Public),
3023 2 => Some(crate::StateVisibility::Private),
3024 _ => {
3025 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
3026 offset: r.offset(),
3027 expected: "a known state-visibility tag",
3028 }));
3029 }
3030 };
3031 c.is_event_type = r.bool()?;
3032 }
3033
3034 if r.bool()? {
3035 let rf = facets.ros2_mut();
3036 rf.was_constant = r.bool()?;
3037 rf.default_value = read_handle_opt(r)?;
3038 if r.bool()? {
3039 let package = r.string()?;
3040 let kind = match r.u8()? {
3041 0 => zerodds_ast_core::RosInterfaceKind::Msg,
3042 1 => zerodds_ast_core::RosInterfaceKind::Srv,
3043 2 => zerodds_ast_core::RosInterfaceKind::Action,
3044 _ => {
3045 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
3046 offset: r.offset(),
3047 expected: "a known ROS interface kind tag",
3048 }));
3049 }
3050 };
3051 let name = r.string()?;
3052 rf.ros_name = Some(zerodds_ast_core::RosTypeName {
3053 package,
3054 kind,
3055 name,
3056 });
3057 }
3058 rf.bounded_origin = match r.u8()? {
3059 0 => None,
3060 1 => Some(crate::RosBoundedOrigin::BoundedArray),
3061 2 => Some(crate::RosBoundedOrigin::FixedArray),
3062 3 => Some(crate::RosBoundedOrigin::BoundedString),
3063 4 => Some(crate::RosBoundedOrigin::UnboundedArray),
3064 _ => {
3065 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
3066 offset: r.offset(),
3067 expected: "a known ROS bounded-origin tag",
3068 }));
3069 }
3070 };
3071 rf.interface_role = match r.u8()? {
3072 0 => None,
3073 1 => Some(crate::RosInterfaceRole::Msg),
3074 2 => Some(crate::RosInterfaceRole::Request),
3075 3 => Some(crate::RosInterfaceRole::Response),
3076 4 => Some(crate::RosInterfaceRole::Goal),
3077 5 => Some(crate::RosInterfaceRole::Result),
3078 6 => Some(crate::RosInterfaceRole::Feedback),
3079 _ => {
3080 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
3081 offset: r.offset(),
3082 expected: "a known ROS interface-role tag",
3083 }));
3084 }
3085 };
3086 }
3087
3088 if r.bool()? {
3089 let x = facets.xml_mut();
3090 x.element = r.string()?;
3091 let segments = bounded_count(r, 4)? as usize;
3092 for _ in 0..segments {
3093 x.library_path.push(r.string()?);
3094 }
3095 let attributes = bounded_count(r, 8)? as usize;
3096 for _ in 0..attributes {
3097 let name = r.string()?;
3098 let value = r.string()?;
3099 x.attributes.push((name, value));
3100 }
3101 let idrefs = bounded_count(r, 4)? as usize;
3102 for _ in 0..idrefs {
3103 x.unresolved_idrefs
3104 .push(zerodds_ast_core::XmlRefKey(r.string()?));
3105 }
3106 if r.bool()? {
3107 x.xsd_type = Some(r.string()?);
3108 }
3109 }
3110
3111 if r.bool()? {
3112 let f = facets.flatdata_mut();
3113 f.is_plain = r.bool()?;
3114 f.explicit_fixed_layout = r.bool()?;
3115 if r.bool()? {
3116 f.loan_alignment = Some(r.u8()?);
3117 }
3118 }
3119
3120 if r.bool()? {
3121 facets.vendor.rti = Some(crate::RtiFacet {
3122 copy_directives: read_strings(r)?,
3123 resolve_name: read_bool_opt(r)?,
3124 top_level: read_bool_opt(r)?,
3125 keylist: read_strings(r)?,
3126 unrecognised: read_pairs(r)?,
3127 });
3128 }
3129 if r.bool()? {
3130 facets.vendor.open_dds = Some(crate::OpenDdsFacet {
3131 dcps_data_type: r.bool()?,
3132 dcps_data_keys: read_strings(r)?,
3133 supports_zero_copy: read_bool_opt(r)?,
3134 unrecognised: read_pairs(r)?,
3135 });
3136 }
3137 if r.bool()? {
3138 facets.vendor.fast_dds = Some(crate::FastDdsFacet {
3139 xtypes_extensions: read_strings(r)?,
3140 plain_data_type: read_bool_opt(r)?,
3141 unrecognised: read_pairs(r)?,
3142 });
3143 }
3144 if r.bool()? {
3145 facets.vendor.core_dx = Some(crate::CoreDxFacet {
3146 key_fields: read_strings(r)?,
3147 unrecognised: read_pairs(r)?,
3148 });
3149 }
3150
3151 let applied_count = bounded_count(r, 10)? as usize;
3152 for _ in 0..applied_count {
3153 let name = r.string()?;
3154 let definition = read_ref(r)?;
3155 let argument_count = bounded_count(r, 5)? as usize;
3156 let mut arguments = Vec::new();
3157 for _ in 0..argument_count {
3158 let argument_name = read_str_opt(r)?;
3159 let value =
3160 read_handle_opt(r)?.ok_or(AstError::Core(AstCoreError::MalformedSnapshot {
3161 offset: r.offset(),
3162 expected: "an annotation argument's expression",
3163 }))?;
3164 arguments.push(crate::AppliedArgument {
3165 name: argument_name,
3166 value,
3167 });
3168 }
3169 facets.annotations.push(crate::AppliedAnnotation {
3170 name,
3171 definition,
3172 arguments,
3173 });
3174 }
3175
3176 Ok(facets)
3177}
3178
3179fn read_strings(r: &mut SnapshotReader<'_>) -> Result<Vec<String>, AstError> {
3180 let n = bounded_count(r, 4)? as usize;
3181 let mut out = Vec::new();
3182 for _ in 0..n {
3183 out.push(r.string()?);
3184 }
3185 Ok(out)
3186}
3187
3188fn read_pairs(r: &mut SnapshotReader<'_>) -> Result<Vec<(String, String)>, AstError> {
3189 let n = bounded_count(r, 8)? as usize;
3190 let mut out = Vec::new();
3191 for _ in 0..n {
3192 let name = r.string()?;
3193 let value = r.string()?;
3194 out.push((name, value));
3195 }
3196 Ok(out)
3197}
3198
3199fn read_bool_opt(r: &mut SnapshotReader<'_>) -> Result<Option<bool>, AstError> {
3200 Ok(match r.u8()? {
3201 0 => None,
3202 1 => Some(false),
3203 2 => Some(true),
3204 _ => {
3205 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
3206 offset: r.offset(),
3207 expected: "a known optional-boolean tag",
3208 }));
3209 }
3210 })
3211}
3212
3213fn read_str_opt(r: &mut SnapshotReader<'_>) -> Result<Option<String>, AstError> {
3214 Ok(if r.bool()? { Some(r.string()?) } else { None })
3215}
3216
3217fn read_component_role(
3219 r: &mut SnapshotReader<'_>,
3220) -> Result<Option<crate::ComponentRole>, AstError> {
3221 Ok(match r.u8()? {
3222 0 => None,
3223 1 => Some(crate::ComponentRole::Facet {
3224 name: r.string()?,
3225 interface: read_ref(r)?,
3226 }),
3227 2 => Some(crate::ComponentRole::Receptacle {
3228 name: r.string()?,
3229 interface: read_ref(r)?,
3230 multiple: r.bool()?,
3231 }),
3232 3 => Some(crate::ComponentRole::EventSource {
3233 name: r.string()?,
3234 event: read_type_ref(r)?,
3235 publisher: r.bool()?,
3236 }),
3237 4 => Some(crate::ComponentRole::EventSink {
3238 name: r.string()?,
3239 event: read_type_ref(r)?,
3240 }),
3241 5 => Some(crate::ComponentRole::HomeFactory),
3242 6 => Some(crate::ComponentRole::HomeFinder),
3243 7 => Some(crate::ComponentRole::PortTypeRole),
3244 8 => Some(crate::ComponentRole::ConnectorRole),
3245 _ => {
3246 return Err(AstError::Core(AstCoreError::MalformedSnapshot {
3247 offset: r.offset(),
3248 expected: "a known component-role tag",
3249 }));
3250 }
3251 })
3252}
3253
3254impl Ast {
3255 fn empty_for_load() -> Self {
3258 let mut ast = Self::empty_public();
3259 ast.modules = zerodds_ast_core::Arena::new();
3260 ast.annotation_defs = zerodds_ast_core::Arena::new();
3261 ast.annotation_members = zerodds_ast_core::Arena::new();
3262 ast.by_node_id.clear();
3263 ast.model_ids = zerodds_ast_core::IdAllocator::new(IdSpace::MODEL);
3264 ast.builtin_ids = zerodds_ast_core::IdAllocator::new(IdSpace::BUILTIN);
3265 ast.synthetic_ids = zerodds_ast_core::IdAllocator::new(IdSpace::SYNTHETIC);
3266 ast
3267 }
3268}
3269
3270pub const ROOT_MODULE_ID: NodeId = NodeId::from_parts(IdSpace::MODEL, 1);