1use crate::error::AstError;
6use crate::facet::Facets;
7use crate::node::AnyId;
8use crate::node::annotation::{
9 AnnotationDefNode, AnnotationMemberNode, BUILTIN_ANNOTATIONS, BUILTIN_MODULE_NAME,
10};
11use crate::node::constant::{
12 ConstExpr, ConstExprNode, ConstNode, ConstValue, EvalError, Literal, MAX_EXPR_DEPTH, UnaryOp,
13};
14use crate::node::deployment::{
15 DomainNode, EndpointNode, EndpointRole, LibraryNode, ParticipantNode, QosPolicy,
16 QosProfileNode, TopicNode,
17};
18use crate::node::exception::ExceptionNode;
19use crate::node::interface::{
20 AttributeNode, InterfaceKind, InterfaceNode, OperationNode, ParamDirection, ParamNode,
21};
22use crate::node::member::{
23 BitValueNode, BitfieldNode, CaseLabel, CaseNode, EnumeratorNode, MemberNode,
24};
25use crate::node::module::ModuleNode;
26use crate::node::type_::{Completeness, PrimitiveKind, TypeKind, TypeNode};
27use alloc::collections::BTreeMap;
28use alloc::string::{String, ToString};
29use alloc::vec::Vec;
30use zerodds_ast_core::{
31 Arena, Id, IdAllocator, IdSpace, NodeId, ObserverRegistry, Ref, ScopedName,
32};
33
34pub struct Ast {
39 pub(crate) modules: Arena<ModuleNode>,
40 pub(crate) types: Arena<TypeNode>,
41 pub(crate) members: Arena<MemberNode>,
42 pub(crate) cases: Arena<CaseNode>,
43 pub(crate) enumerators: Arena<EnumeratorNode>,
44 pub(crate) bit_values: Arena<BitValueNode>,
45 pub(crate) bitfields: Arena<BitfieldNode>,
46 pub(crate) constants: Arena<ConstNode>,
47 pub(crate) exprs: Arena<ConstExprNode>,
48 pub(crate) interfaces: Arena<InterfaceNode>,
49 pub(crate) operations: Arena<OperationNode>,
50 pub(crate) params: Arena<ParamNode>,
51 pub(crate) attributes: Arena<AttributeNode>,
52 pub(crate) exceptions: Arena<ExceptionNode>,
53 pub(crate) annotation_defs: Arena<AnnotationDefNode>,
54 pub(crate) annotation_members: Arena<AnnotationMemberNode>,
55 pub(crate) domains: Arena<DomainNode>,
56 pub(crate) topics: Arena<TopicNode>,
57 pub(crate) qos_profiles: Arena<QosProfileNode>,
58 pub(crate) participants: Arena<ParticipantNode>,
59 pub(crate) endpoints: Arena<EndpointNode>,
60 pub(crate) libraries: Arena<LibraryNode>,
61
62 pub(crate) model_ids: IdAllocator,
63 pub(crate) builtin_ids: IdAllocator,
64 pub(crate) synthetic_ids: IdAllocator,
65
66 pub(crate) by_node_id: BTreeMap<NodeId, AnyId>,
67 pub(crate) by_scoped_name: zerodds_ast_core::Index<ScopedName>,
68 pub(crate) by_type_identifier: zerodds_ast_core::Index<zerodds_ast_core::TypeIdentifierKey>,
69 pub(crate) by_ros_name: zerodds_ast_core::Index<zerodds_ast_core::RosTypeName>,
70 pub(crate) by_repository_id: zerodds_ast_core::Index<zerodds_ast_core::RepositoryId>,
71 pub(crate) by_pending: zerodds_ast_core::Index<zerodds_ast_core::PendingRef>,
74 pub(crate) observers: ObserverRegistry,
75 pub(crate) sequence: u64,
76 pub(crate) pending: Option<zerodds_ast_core::TxnLog>,
78 pub(crate) stash: Vec<Option<crate::edit::Stashed>>,
81 pub(crate) last_commit_error: Option<AstError>,
83
84 root: Id<ModuleNode>,
85 builtin_module: Id<ModuleNode>,
86}
87
88#[derive(Debug, Clone, PartialEq, Eq)]
90pub struct MemberSpec {
91 pub name: String,
93 pub type_: Ref<TypeNode>,
95 pub facets: Facets,
97}
98
99impl MemberSpec {
100 #[must_use]
102 pub fn new(name: &str, type_: Ref<TypeNode>) -> Self {
103 Self {
104 name: name.to_string(),
105 type_,
106 facets: Facets::synthetic("member created through the model API"),
107 }
108 }
109}
110
111impl Default for Ast {
112 fn default() -> Self {
113 Self::new()
114 }
115}
116
117impl Ast {
118 #[must_use]
124 pub fn new() -> Self {
125 let mut ast = Self::empty();
126 ast.populate_builtins();
127 ast
128 }
129
130 pub(crate) fn empty_public() -> Self {
131 Self::empty()
132 }
133
134 fn empty() -> Self {
135 let mut modules = Arena::new();
136 let mut model_ids = IdAllocator::new(IdSpace::MODEL);
137 let root_id = model_ids
140 .allocate()
141 .unwrap_or_else(|_| NodeId::from_parts(IdSpace::MODEL, 1));
142 let root = modules
143 .insert(ModuleNode {
144 node_id: root_id,
145 name: String::new(),
146 parent: None,
147 children: Vec::new(),
148 facets: Facets::synthetic("root module"),
149 })
150 .unwrap_or(Id::first_at(0));
151
152 let mut builtin_ids = IdAllocator::new(IdSpace::BUILTIN);
153 let builtin_module_id = builtin_ids
154 .allocate()
155 .unwrap_or_else(|_| NodeId::from_parts(IdSpace::BUILTIN, 1));
156 let builtin_module = modules
157 .insert(ModuleNode {
158 node_id: builtin_module_id,
159 name: BUILTIN_MODULE_NAME.to_string(),
160 parent: None,
161 children: Vec::new(),
162 facets: Facets::builtin(),
163 })
164 .unwrap_or(Id::first_at(1));
165
166 let mut by_node_id = BTreeMap::new();
167 let _ = by_node_id.insert(root_id, AnyId::Module(root, root_id));
168 let _ = by_node_id.insert(
169 builtin_module_id,
170 AnyId::Module(builtin_module, builtin_module_id),
171 );
172
173 Self {
174 modules,
175 types: Arena::new(),
176 members: Arena::new(),
177 cases: Arena::new(),
178 enumerators: Arena::new(),
179 bit_values: Arena::new(),
180 bitfields: Arena::new(),
181 constants: Arena::new(),
182 exprs: Arena::new(),
183 interfaces: Arena::new(),
184 operations: Arena::new(),
185 params: Arena::new(),
186 attributes: Arena::new(),
187 exceptions: Arena::new(),
188 annotation_defs: Arena::new(),
189 annotation_members: Arena::new(),
190 domains: Arena::new(),
191 topics: Arena::new(),
192 qos_profiles: Arena::new(),
193 participants: Arena::new(),
194 endpoints: Arena::new(),
195 libraries: Arena::new(),
196 model_ids,
197 builtin_ids,
198 synthetic_ids: IdAllocator::new(IdSpace::SYNTHETIC),
199 by_node_id,
200 by_scoped_name: zerodds_ast_core::Index::new(),
201 by_type_identifier: zerodds_ast_core::Index::new(),
202 by_ros_name: zerodds_ast_core::Index::new(),
203 by_repository_id: zerodds_ast_core::Index::new(),
204 by_pending: zerodds_ast_core::Index::new(),
205 observers: ObserverRegistry::new(),
206 sequence: 0,
207 pending: None,
208 stash: Vec::new(),
209 last_commit_error: None,
210 root,
211 builtin_module,
212 }
213 }
214
215 fn populate_builtins(&mut self) {
216 for name in BUILTIN_ANNOTATIONS {
217 let Ok(node_id) = self.builtin_ids.allocate() else {
218 return;
219 };
220 let Ok(id) = self.annotation_defs.insert(AnnotationDefNode {
221 node_id,
222 name: name.to_string(),
223 module: self.builtin_module,
224 members: Vec::new(),
225 facets: Facets::builtin(),
226 }) else {
227 return;
228 };
229 let any = AnyId::AnnotationDef(id, node_id);
230 let _ = self.by_node_id.insert(node_id, any);
231 if let Ok(module) = self.modules.get_mut(self.builtin_module) {
232 module.children.push(any);
233 }
234 let Ok(member_id) = self.builtin_ids.allocate() else {
237 return;
238 };
239 let Ok(member) = self.annotation_members.insert(AnnotationMemberNode {
240 node_id: member_id,
241 name: "value".to_string(),
242 type_: Ref::Pending(zerodds_ast_core::PendingRef::ScopedName(
243 ScopedName::absolute(alloc::vec![name.to_string()]),
244 )),
245 default: None,
246 is_value_member: true,
247 parent: id,
248 facets: Facets::builtin(),
249 }) else {
250 return;
251 };
252 let _ = self
253 .by_node_id
254 .insert(member_id, AnyId::AnnotationMember(member, member_id));
255 if let Ok(def) = self.annotation_defs.get_mut(id) {
256 def.members.push(member);
257 }
258 }
259 }
260
261 #[must_use]
263 pub const fn root_module(&self) -> Id<ModuleNode> {
264 self.root
265 }
266
267 #[must_use]
269 pub const fn builtin_module(&self) -> Id<ModuleNode> {
270 self.builtin_module
271 }
272
273 #[must_use]
275 pub fn builtin_annotation(&self, name: &str) -> Option<Id<AnnotationDefNode>> {
276 self.modules
277 .get(self.builtin_module)
278 .ok()?
279 .children
280 .iter()
281 .filter_map(|child| match child {
282 AnyId::AnnotationDef(id, _) => Some(*id),
283 _ => None,
284 })
285 .find(|id| {
286 self.annotation_defs
287 .get(*id)
288 .is_ok_and(|def| def.name == name)
289 })
290 }
291
292 #[must_use]
294 pub fn resolve_node_id(&self, node: NodeId) -> Option<AnyId> {
295 self.by_node_id.get(&node).copied()
296 }
297
298 pub fn observers_mut(&mut self) -> &mut ObserverRegistry {
300 &mut self.observers
301 }
302
303 #[must_use]
305 pub fn node_count(&self) -> usize {
306 self.by_node_id.len()
307 }
308
309 #[must_use]
314 pub const fn commit_sequence(&self) -> u64 {
315 self.sequence
316 }
317
318 pub fn allocate_synthetic_id(&mut self) -> Result<NodeId, AstError> {
328 Ok(self.synthetic_ids.allocate()?)
329 }
330
331 pub(crate) fn next_model_id(&mut self) -> Result<NodeId, AstError> {
332 Ok(self.model_ids.allocate()?)
333 }
334
335 pub(crate) fn note_parts_changed(&mut self, owner: NodeId) {
340 let change = zerodds_ast_core::Change::Updated {
341 node: owner,
342 field: crate::field::PARTS,
343 before: zerodds_ast_core::FieldValue::Absent,
344 after: zerodds_ast_core::FieldValue::Node(owner),
345 };
346 let undo = zerodds_ast_core::UndoRecord {
347 node: owner,
348 payload: zerodds_ast_core::UndoPayload::RestoreField {
349 field: crate::field::PARTS,
350 value: zerodds_ast_core::FieldValue::Absent,
351 },
352 };
353 if let Some(log) = self.pending.as_mut() {
354 log.record(undo, change);
355 } else if let Err(error) = self.record_standalone(undo, change) {
356 self.last_commit_error = Some(error);
357 }
358 }
359
360 pub(crate) fn register(&mut self, any: AnyId) {
361 let _ = self.by_node_id.insert(any.node_id(), any);
362 self.index_node(any);
363 self.index_pending(any);
364 if let Err(error) = self.record_created(any) {
369 self.last_commit_error = Some(error);
370 }
371 }
372
373 fn committed<T>(&mut self, value: T) -> Result<T, AstError> {
380 match self.last_commit_error.take() {
381 Some(error) => Err(error),
382 None => Ok(value),
383 }
384 }
385
386 pub fn take_commit_error(&mut self) -> Option<AstError> {
393 self.last_commit_error.take()
394 }
395
396 pub fn module(&self, id: Id<ModuleNode>) -> Result<&ModuleNode, AstError> {
403 Ok(self.modules.get(id)?)
404 }
405
406 pub fn ensure_module(
415 &mut self,
416 parent: Id<ModuleNode>,
417 name: &str,
418 ) -> Result<Id<ModuleNode>, AstError> {
419 let existing = self
420 .modules
421 .get(parent)?
422 .children
423 .iter()
424 .filter_map(|child| child.as_module())
425 .find(|id| self.modules.get(*id).is_ok_and(|m| m.name == name));
426 if let Some(id) = existing {
427 return Ok(id);
428 }
429
430 let node_id = self.next_model_id()?;
431 let id = self.modules.insert(ModuleNode {
432 node_id,
433 name: name.to_string(),
434 parent: Some(parent),
435 children: Vec::new(),
436 facets: Facets::synthetic("module created through the model API"),
437 })?;
438 let any = AnyId::Module(id, node_id);
439 self.register(any);
440 self.modules.get_mut(parent)?.children.push(any);
441 self.committed(id)
442 }
443
444 pub fn modules(&self) -> impl Iterator<Item = (Id<ModuleNode>, &ModuleNode)> {
446 self.modules.iter()
447 }
448
449 #[must_use]
451 pub fn module_by_path(&self, path: &ScopedName) -> Option<Id<ModuleNode>> {
452 let mut current = self.root;
453 for segment in path.segments() {
454 current = self
455 .modules
456 .get(current)
457 .ok()?
458 .children
459 .iter()
460 .filter_map(|child| child.as_module())
461 .find(|id| self.modules.get(*id).is_ok_and(|m| &m.name == segment))?;
462 }
463 Some(current)
464 }
465
466 pub fn type_(&self, id: Id<TypeNode>) -> Result<&TypeNode, AstError> {
473 Ok(self.types.get(id)?)
474 }
475
476 pub fn add_type(
482 &mut self,
483 module: Id<ModuleNode>,
484 name: &str,
485 kind: TypeKind,
486 ) -> Result<Id<TypeNode>, AstError> {
487 let node_id = self.next_model_id()?;
488 let id = self.types.insert(TypeNode {
489 node_id,
490 name: name.to_string(),
491 module,
492 scope: None,
493 kind,
494 completeness: Completeness::Complete,
495 facets: Facets::synthetic("type created through the model API"),
496 })?;
497 let any = AnyId::Type(id, node_id);
498 self.register(any);
499 self.modules.get_mut(module)?.children.push(any);
500 self.committed(id)
501 }
502
503 pub fn add_forward_type(
511 &mut self,
512 module: Id<ModuleNode>,
513 name: &str,
514 kind: TypeKind,
515 ) -> Result<Id<TypeNode>, AstError> {
516 let id = self.add_type(module, name, kind)?;
517 self.types.get_mut(id)?.completeness = Completeness::Forward;
518 self.committed(id)
519 }
520
521 pub fn complete_type(&mut self, id: Id<TypeNode>, kind: TypeKind) -> Result<(), AstError> {
532 let node = self.types.get(id)?;
533 let node_id = node.node_id;
534 if node.completeness == Completeness::Complete {
535 return Err(AstError::AlreadyComplete { node: node_id });
536 }
537 self.unindex_pending(AnyId::Type(id, node_id));
541
542 let node = self.types.get_mut(id)?;
543 node.kind = kind;
544 node.completeness = Completeness::Complete;
545
546 self.index_pending(AnyId::Type(id, node_id));
547 self.record_completeness_change(node_id);
548 Ok(())
549 }
550
551 fn record_completeness_change(&mut self, node: NodeId) {
552 let change = zerodds_ast_core::Change::Updated {
553 node,
554 field: crate::field::COMPLETENESS,
555 before: zerodds_ast_core::FieldValue::Bool(false),
556 after: zerodds_ast_core::FieldValue::Bool(true),
557 };
558 let undo = zerodds_ast_core::UndoRecord {
559 node,
560 payload: zerodds_ast_core::UndoPayload::RestoreField {
561 field: crate::field::COMPLETENESS,
562 value: zerodds_ast_core::FieldValue::Bool(false),
563 },
564 };
565 if let Some(log) = self.pending.as_mut() {
566 log.record(undo, change);
567 } else if let Err(error) = self.record_standalone(undo, change) {
568 self.last_commit_error = Some(error);
569 }
570 }
571
572 pub fn types(&self) -> impl Iterator<Item = (Id<TypeNode>, &TypeNode)> {
574 self.types.iter()
575 }
576
577 pub fn member(&self, id: Id<MemberNode>) -> Result<&MemberNode, AstError> {
584 Ok(self.members.get(id)?)
585 }
586
587 pub fn members(&self) -> impl Iterator<Item = (Id<MemberNode>, &MemberNode)> {
589 self.members.iter()
590 }
591
592 pub fn add_member(
598 &mut self,
599 aggregate: Id<TypeNode>,
600 spec: MemberSpec,
601 ) -> Result<Id<MemberNode>, AstError> {
602 let parent_node_id = self.types.get(aggregate)?.node_id;
603 let parent = AnyId::Type(aggregate, parent_node_id);
604 let node_id = self.next_model_id()?;
605 let id = self.members.insert(MemberNode {
606 node_id,
607 name: spec.name,
608 type_: spec.type_,
609 parent,
610 facets: spec.facets,
611 })?;
612 self.register(AnyId::Member(id, node_id));
613 match &mut self.types.get_mut(aggregate)?.kind {
614 TypeKind::Structure { members, .. } | TypeKind::Valuetype { state: members, .. } => {
615 members.push(id);
616 self.note_parts_changed(parent_node_id);
617 self.committed(id)
618 }
619 other => {
620 let found = other.as_str();
621 let _ = self.members.remove(id);
622 let _ = self.by_node_id.remove(&node_id);
623 Err(AstError::NotAnAggregate {
624 node: parent_node_id,
625 found,
626 })
627 }
628 }
629 }
630
631 pub fn add_member_at(
641 &mut self,
642 aggregate: Id<TypeNode>,
643 spec: MemberSpec,
644 index: usize,
645 ) -> Result<Id<MemberNode>, AstError> {
646 let id = self.add_member(aggregate, spec)?;
647 let parent_node_id = self.types.get(aggregate)?.node_id;
648 if let TypeKind::Structure { members, .. } | TypeKind::Valuetype { state: members, .. } =
649 &mut self.types.get_mut(aggregate)?.kind
650 {
651 members.pop();
653 let at = index.min(members.len());
654 members.insert(at, id);
655 self.note_parts_changed(parent_node_id);
656 }
657 Ok(id)
658 }
659
660 pub fn add_case_at(
666 &mut self,
667 union: Id<TypeNode>,
668 labels: Vec<CaseLabel>,
669 spec: MemberSpec,
670 index: usize,
671 ) -> Result<Id<CaseNode>, AstError> {
672 let id = self.add_case(union, labels, spec)?;
673 let union_node_id = self.types.get(union)?.node_id;
674 if let TypeKind::Union { cases, .. } = &mut self.types.get_mut(union)?.kind {
675 cases.pop();
676 let at = index.min(cases.len());
677 cases.insert(at, id);
678 self.note_parts_changed(union_node_id);
679 }
680 Ok(id)
681 }
682
683 pub fn add_exception_member(
688 &mut self,
689 exception: Id<ExceptionNode>,
690 spec: MemberSpec,
691 ) -> Result<Id<MemberNode>, AstError> {
692 let parent_node_id = self.exceptions.get(exception)?.node_id;
693 let node_id = self.next_model_id()?;
694 let id = self.members.insert(MemberNode {
695 node_id,
696 name: spec.name,
697 type_: spec.type_,
698 parent: AnyId::Exception(exception, parent_node_id),
699 facets: spec.facets,
700 })?;
701 self.register(AnyId::Member(id, node_id));
702 self.exceptions.get_mut(exception)?.members.push(id);
703 self.note_parts_changed(parent_node_id);
704 self.committed(id)
705 }
706
707 pub fn case(&self, id: Id<CaseNode>) -> Result<&CaseNode, AstError> {
712 Ok(self.cases.get(id)?)
713 }
714
715 pub fn cases(&self) -> impl Iterator<Item = (Id<CaseNode>, &CaseNode)> {
717 self.cases.iter()
718 }
719
720 pub fn add_case(
728 &mut self,
729 union: Id<TypeNode>,
730 labels: Vec<CaseLabel>,
731 spec: MemberSpec,
732 ) -> Result<Id<CaseNode>, AstError> {
733 let union_node_id = self.types.get(union)?.node_id;
734 if !matches!(self.types.get(union)?.kind, TypeKind::Union { .. }) {
735 return Err(AstError::NotAnAggregate {
736 node: union_node_id,
737 found: self.types.get(union)?.kind.as_str(),
738 });
739 }
740
741 let member_node_id = self.next_model_id()?;
742 let member = self.members.insert(MemberNode {
743 node_id: member_node_id,
744 name: spec.name,
745 type_: spec.type_,
746 parent: AnyId::Type(union, union_node_id),
747 facets: spec.facets,
748 })?;
749 self.register(AnyId::Member(member, member_node_id));
750
751 let node_id = self.next_model_id()?;
752 let is_default = labels.iter().any(|l| l.is_default());
753 let id = self.cases.insert(CaseNode {
754 node_id,
755 labels,
756 member,
757 parent: union,
758 facets: Facets::synthetic("case created through the model API"),
759 })?;
760 self.register(AnyId::Case(id, node_id));
761
762 if let TypeKind::Union {
763 cases,
764 default_case,
765 ..
766 } = &mut self.types.get_mut(union)?.kind
767 {
768 cases.push(id);
769 if is_default {
770 *default_case = Some(id);
771 }
772 }
773 self.note_parts_changed(union_node_id);
774 self.committed(id)
775 }
776
777 pub fn enumerator(&self, id: Id<EnumeratorNode>) -> Result<&EnumeratorNode, AstError> {
782 Ok(self.enumerators.get(id)?)
783 }
784
785 pub fn enumerators(&self) -> impl Iterator<Item = (Id<EnumeratorNode>, &EnumeratorNode)> {
787 self.enumerators.iter()
788 }
789
790 pub fn enumerator_mut(
798 &mut self,
799 id: Id<EnumeratorNode>,
800 ) -> Result<&mut EnumeratorNode, AstError> {
801 Ok(self.enumerators.get_mut(id)?)
802 }
803
804 pub fn add_enumerator(
812 &mut self,
813 enumeration: Id<TypeNode>,
814 name: &str,
815 value: Option<Id<ConstExprNode>>,
816 ) -> Result<Id<EnumeratorNode>, AstError> {
817 let parent_node_id = self.types.get(enumeration)?.node_id;
818 if !matches!(
819 self.types.get(enumeration)?.kind,
820 TypeKind::Enumeration { .. }
821 ) {
822 return Err(AstError::NotAnAggregate {
823 node: parent_node_id,
824 found: self.types.get(enumeration)?.kind.as_str(),
825 });
826 }
827 let node_id = self.next_model_id()?;
828 let id = self.enumerators.insert(EnumeratorNode {
829 node_id,
830 name: name.to_string(),
831 value,
832 parent: enumeration,
833 facets: Facets::synthetic("enumerator created through the model API"),
834 })?;
835 self.register(AnyId::Enumerator(id, node_id));
836 if let TypeKind::Enumeration { enumerators } = &mut self.types.get_mut(enumeration)?.kind {
837 enumerators.push(id);
838 }
839 self.note_parts_changed(parent_node_id);
840 self.committed(id)
841 }
842
843 pub fn bit_value(&self, id: Id<BitValueNode>) -> Result<&BitValueNode, AstError> {
848 Ok(self.bit_values.get(id)?)
849 }
850
851 pub fn bit_value_mut(&mut self, id: Id<BitValueNode>) -> Result<&mut BitValueNode, AstError> {
858 Ok(self.bit_values.get_mut(id)?)
859 }
860
861 pub fn bit_values(&self) -> impl Iterator<Item = (Id<BitValueNode>, &BitValueNode)> {
863 self.bit_values.iter()
864 }
865
866 pub fn add_bit_value(
874 &mut self,
875 bitmask: Id<TypeNode>,
876 name: &str,
877 position: Option<u16>,
878 ) -> Result<Id<BitValueNode>, AstError> {
879 let parent_node_id = self.types.get(bitmask)?.node_id;
880 if !matches!(self.types.get(bitmask)?.kind, TypeKind::Bitmask { .. }) {
881 return Err(AstError::NotAnAggregate {
882 node: parent_node_id,
883 found: self.types.get(bitmask)?.kind.as_str(),
884 });
885 }
886 let node_id = self.next_model_id()?;
887 let id = self.bit_values.insert(BitValueNode {
888 node_id,
889 name: name.to_string(),
890 position,
891 parent: bitmask,
892 facets: Facets::synthetic("bit value created through the model API"),
893 })?;
894 self.register(AnyId::BitValue(id, node_id));
895 if let TypeKind::Bitmask { bits } = &mut self.types.get_mut(bitmask)?.kind {
896 bits.push(id);
897 }
898 self.note_parts_changed(parent_node_id);
899 self.committed(id)
900 }
901
902 pub fn bitfield(&self, id: Id<BitfieldNode>) -> Result<&BitfieldNode, AstError> {
907 Ok(self.bitfields.get(id)?)
908 }
909
910 pub fn add_bitfield(
915 &mut self,
916 bitset: Id<TypeNode>,
917 name: Option<&str>,
918 bits: u16,
919 holder_type: Option<Ref<TypeNode>>,
920 ) -> Result<Id<BitfieldNode>, AstError> {
921 let parent_node_id = self.types.get(bitset)?.node_id;
922 if !matches!(self.types.get(bitset)?.kind, TypeKind::Bitset { .. }) {
923 return Err(AstError::NotAnAggregate {
924 node: parent_node_id,
925 found: self.types.get(bitset)?.kind.as_str(),
926 });
927 }
928 let node_id = self.next_model_id()?;
929 let id = self.bitfields.insert(BitfieldNode {
930 node_id,
931 name: name.map(ToString::to_string),
932 bits,
933 holder_type,
934 parent: bitset,
935 facets: Facets::synthetic("bitfield created through the model API"),
936 })?;
937 self.register(AnyId::Bitfield(id, node_id));
938 if let TypeKind::Bitset { fields, .. } = &mut self.types.get_mut(bitset)?.kind {
939 fields.push(id);
940 }
941 self.note_parts_changed(parent_node_id);
942 self.committed(id)
943 }
944
945 pub fn expr(&self, id: Id<ConstExprNode>) -> Result<&ConstExprNode, AstError> {
952 Ok(self.exprs.get(id)?)
953 }
954
955 pub fn add_expr(&mut self, expr: ConstExpr) -> Result<Id<ConstExprNode>, AstError> {
960 let node_id = self.next_model_id()?;
961 let id = self.exprs.insert(ConstExprNode {
962 node_id,
963 expr,
964 facets: Facets::synthetic("expression created through the model API"),
965 })?;
966 self.register(AnyId::ConstExpr(id, node_id));
967 self.committed(id)
968 }
969
970 pub fn add_int_expr(&mut self, value: i128) -> Result<Id<ConstExprNode>, AstError> {
975 self.add_expr(ConstExpr::Literal(Literal::Integer(value)))
976 }
977
978 pub fn constant(&self, id: Id<ConstNode>) -> Result<&ConstNode, AstError> {
983 Ok(self.constants.get(id)?)
984 }
985
986 pub fn constants(&self) -> impl Iterator<Item = (Id<ConstNode>, &ConstNode)> {
988 self.constants.iter()
989 }
990
991 pub fn add_const(
996 &mut self,
997 module: Id<ModuleNode>,
998 name: &str,
999 type_: Ref<TypeNode>,
1000 expr: Id<ConstExprNode>,
1001 ) -> Result<Id<ConstNode>, AstError> {
1002 let node_id = self.next_model_id()?;
1003 let id = self.constants.insert(ConstNode {
1004 node_id,
1005 name: name.to_string(),
1006 module,
1007 scope: None,
1008 type_,
1009 expr,
1010 facets: Facets::synthetic("constant created through the model API"),
1011 })?;
1012 let any = AnyId::Const(id, node_id);
1013 self.register(any);
1014 self.modules.get_mut(module)?.children.push(any);
1015 self.committed(id)
1016 }
1017
1018 pub fn eval_integral(&self, expr: Id<ConstExprNode>) -> Result<i128, EvalError> {
1031 self.eval_integral_at(expr, 0)
1032 }
1033
1034 pub fn eval_const(&self, expr: Id<ConstExprNode>) -> Result<ConstValue, EvalError> {
1056 self.eval_const_at(expr, expr, 0)
1057 }
1058
1059 fn eval_const_at(
1062 &self,
1063 expr: Id<ConstExprNode>,
1064 root: Id<ConstExprNode>,
1065 depth: usize,
1066 ) -> Result<ConstValue, EvalError> {
1067 if depth > MAX_EXPR_DEPTH {
1068 return Err(EvalError::TooDeep);
1069 }
1070 let node = self.exprs.get(expr).map_err(|_| EvalError::DanglingExpr)?;
1071 let at = node.node_id;
1072 match &node.expr {
1073 ConstExpr::Literal(Literal::Boolean(value)) => Ok(ConstValue::Boolean(*value)),
1074 ConstExpr::Literal(Literal::Integer(value)) => Ok(ConstValue::Integer(*value)),
1075 ConstExpr::Literal(Literal::Char(value)) => Ok(ConstValue::Char(*value)),
1076 ConstExpr::Literal(Literal::WChar(value)) => Ok(ConstValue::WChar(*value)),
1077 ConstExpr::Literal(Literal::String(text)) => Ok(ConstValue::String(text.clone())),
1078 ConstExpr::Literal(Literal::WString(units)) => Ok(ConstValue::WString(units.clone())),
1079 ConstExpr::Literal(Literal::Float { mantissa, exponent }) => Ok(ConstValue::Float {
1080 mantissa: mantissa.clone(),
1081 exponent: exponent.clone(),
1082 }),
1083 ConstExpr::Literal(Literal::Fixed { digits, scale }) => Ok(ConstValue::Fixed {
1084 digits: digits.clone(),
1085 scale: *scale,
1086 }),
1087 ConstExpr::Literal(Literal::Enumerator(_)) => {
1088 self.eval_integral_at(expr, depth).map(ConstValue::Integer)
1089 }
1090 ConstExpr::NameRef(reference) => {
1091 let target = reference.resolved().ok_or(EvalError::Unresolved { at })?;
1092 let constant = self
1093 .constants
1094 .get(target)
1095 .map_err(|_| EvalError::DanglingExpr)?;
1096 self.eval_const_at(constant.expr, constant.expr, depth + 1)
1097 }
1098 ConstExpr::Unary {
1117 op: op @ (UnaryOp::Minus | UnaryOp::Plus),
1118 operand,
1119 } => {
1120 let inner = self.eval_const_at(*operand, root, depth + 1)?;
1121 match inner {
1122 ConstValue::Float { mantissa, exponent } if *op == UnaryOp::Minus => {
1123 Ok(ConstValue::Float {
1124 mantissa: match mantissa.strip_prefix('-') {
1125 Some(rest) => rest.to_string(),
1130 None => alloc::format!("-{mantissa}"),
1131 },
1132 exponent,
1133 })
1134 }
1135 ConstValue::Float { .. } => Ok(inner),
1136 ConstValue::Fixed { digits, scale } => {
1139 let value = crate::decimal::Decimal::parse(&digits, scale)
1140 .map_err(|_| EvalError::NotIntegral { at })?;
1141 let value = if *op == UnaryOp::Minus {
1142 value.negated()
1143 } else {
1144 value
1145 };
1146 let (digits, scale) =
1147 value.to_parts().map_err(|_| EvalError::Overflow { at })?;
1148 Ok(ConstValue::Fixed { digits, scale })
1149 }
1150 _ => self.eval_integral_at(expr, depth).map(ConstValue::Integer),
1151 }
1152 }
1153 ConstExpr::Unary { .. } | ConstExpr::Binary { .. } => {
1154 if self.is_floating_at(expr, depth)? {
1155 self.eval_floating_root(expr, root, depth)
1156 } else if self.is_fixed_at(expr, depth)? {
1157 self.eval_fixed_root(expr, root, depth)
1158 } else {
1159 self.eval_integral_at(expr, depth).map(ConstValue::Integer)
1160 }
1161 }
1162 }
1163 }
1164
1165 fn is_floating_at(&self, expr: Id<ConstExprNode>, depth: usize) -> Result<bool, EvalError> {
1170 if depth > MAX_EXPR_DEPTH {
1171 return Err(EvalError::TooDeep);
1172 }
1173 let node = self.exprs.get(expr).map_err(|_| EvalError::DanglingExpr)?;
1174 match &node.expr {
1175 ConstExpr::Literal(Literal::Float { .. }) => Ok(true),
1176 ConstExpr::Literal(_) => Ok(false),
1177 ConstExpr::NameRef(reference) => {
1178 let target = reference
1179 .resolved()
1180 .ok_or(EvalError::Unresolved { at: node.node_id })?;
1181 let constant = self
1182 .constants
1183 .get(target)
1184 .map_err(|_| EvalError::DanglingExpr)?;
1185 self.is_floating_at(constant.expr, depth + 1)
1186 }
1187 ConstExpr::Unary { operand, .. } => self.is_floating_at(*operand, depth + 1),
1188 ConstExpr::Binary { lhs, rhs, .. } => Ok(
1189 self.is_floating_at(*lhs, depth + 1)? || self.is_floating_at(*rhs, depth + 1)?
1190 ),
1191 }
1192 }
1193
1194 fn is_fixed_at(&self, expr: Id<ConstExprNode>, depth: usize) -> Result<bool, EvalError> {
1198 if depth > MAX_EXPR_DEPTH {
1199 return Err(EvalError::TooDeep);
1200 }
1201 let node = self.exprs.get(expr).map_err(|_| EvalError::DanglingExpr)?;
1202 match &node.expr {
1203 ConstExpr::Literal(Literal::Fixed { .. }) => Ok(true),
1204 ConstExpr::Literal(_) => Ok(false),
1205 ConstExpr::NameRef(reference) => {
1206 let target = reference
1207 .resolved()
1208 .ok_or(EvalError::Unresolved { at: node.node_id })?;
1209 let constant = self
1210 .constants
1211 .get(target)
1212 .map_err(|_| EvalError::DanglingExpr)?;
1213 self.is_fixed_at(constant.expr, depth + 1)
1214 }
1215 ConstExpr::Unary { operand, .. } => self.is_fixed_at(*operand, depth + 1),
1216 ConstExpr::Binary { lhs, rhs, .. } => {
1217 Ok(self.is_fixed_at(*lhs, depth + 1)? || self.is_fixed_at(*rhs, depth + 1)?)
1218 }
1219 }
1220 }
1221
1222 fn eval_fixed_root(
1231 &self,
1232 expr: Id<ConstExprNode>,
1233 root: Id<ConstExprNode>,
1234 depth: usize,
1235 ) -> Result<ConstValue, EvalError> {
1236 let at = self
1237 .exprs
1238 .get(expr)
1239 .map_err(|_| EvalError::DanglingExpr)?
1240 .node_id;
1241 let mut value = self.eval_fixed_at(expr, depth)?;
1242 let declared = match self
1243 .constants
1244 .iter()
1245 .find(|(_, constant)| constant.expr == root)
1246 {
1247 Some((_, constant)) => self.fixed_type_of(&constant.type_, at)?,
1248 None => None,
1249 };
1250 if let Some((digits, scale)) = declared {
1251 value = value
1252 .fitted(digits, scale)
1253 .ok_or(EvalError::Overflow { at })?;
1254 }
1255 let (digits, scale) = value.to_parts().map_err(|_| EvalError::Overflow { at })?;
1256 Ok(ConstValue::Fixed { digits, scale })
1257 }
1258
1259 fn fixed_type_of(&self, ty: &Ref<TypeNode>, at: NodeId) -> Result<Option<(u8, u8)>, EvalError> {
1262 let mut next = ty.resolved().ok_or(EvalError::Unresolved { at })?;
1263 for _ in 0..MAX_EXPR_DEPTH {
1264 let node = self.types.get(next).map_err(|_| EvalError::DanglingExpr)?;
1265 match &node.kind {
1266 TypeKind::Fixed { digits, scale } => return Ok(Some((*digits, *scale))),
1267 TypeKind::Alias { aliased } => {
1268 next = aliased.resolved().ok_or(EvalError::Unresolved { at })?;
1269 }
1270 _ => return Ok(None),
1271 }
1272 }
1273 Err(EvalError::TooDeep)
1274 }
1275
1276 fn eval_fixed_at(
1277 &self,
1278 expr: Id<ConstExprNode>,
1279 depth: usize,
1280 ) -> Result<crate::decimal::Decimal, EvalError> {
1281 use crate::decimal::{Decimal, DecimalError};
1282 if depth > MAX_EXPR_DEPTH {
1283 return Err(EvalError::TooDeep);
1284 }
1285 let node = self.exprs.get(expr).map_err(|_| EvalError::DanglingExpr)?;
1286 let at = node.node_id;
1287 let failed = |error: DecimalError| match error {
1288 DecimalError::DivisionByZero => EvalError::DivisionByZero { at },
1289 DecimalError::TooLarge => EvalError::Overflow { at },
1290 DecimalError::NotDecimal => EvalError::NotIntegral { at },
1291 };
1292 match &node.expr {
1293 ConstExpr::Literal(Literal::Fixed { digits, scale }) => {
1294 Decimal::parse(digits, *scale).map_err(failed)
1295 }
1296 ConstExpr::Literal(_) => Err(EvalError::MixedOperands { at }),
1297 ConstExpr::NameRef(reference) => {
1298 let target = reference.resolved().ok_or(EvalError::Unresolved { at })?;
1299 let constant = self
1300 .constants
1301 .get(target)
1302 .map_err(|_| EvalError::DanglingExpr)?;
1303 self.eval_fixed_at(constant.expr, depth + 1)
1304 }
1305 ConstExpr::Unary { op, operand } => {
1306 let value = self.eval_fixed_at(*operand, depth + 1)?;
1307 match op {
1308 UnaryOp::Plus => Ok(value),
1309 UnaryOp::Minus => Ok(value.negated()),
1310 UnaryOp::Not => Err(EvalError::NotFixedOperator { at }),
1311 }
1312 }
1313 ConstExpr::Binary { op, lhs, rhs } => {
1314 use crate::node::constant::BinaryOp as B;
1315 let left = self.eval_fixed_at(*lhs, depth + 1)?;
1316 let right = self.eval_fixed_at(*rhs, depth + 1)?;
1317 match op {
1318 B::Add => left.add(&right).map_err(failed),
1319 B::Sub => left.subtract(&right).map_err(failed),
1320 B::Mul => left.multiply(&right).map_err(failed),
1321 B::Div => left.divide(&right).map_err(failed),
1322 B::Or | B::Xor | B::And | B::Shl | B::Shr | B::Mod => {
1323 Err(EvalError::NotFixedOperator { at })
1324 }
1325 }
1326 }
1327 }
1328 }
1329
1330 fn eval_floating_root(
1342 &self,
1343 expr: Id<ConstExprNode>,
1344 root: Id<ConstExprNode>,
1345 depth: usize,
1346 ) -> Result<ConstValue, EvalError> {
1347 let at = self
1348 .exprs
1349 .get(expr)
1350 .map_err(|_| EvalError::DanglingExpr)?
1351 .node_id;
1352 let declared = match self
1357 .constants
1358 .iter()
1359 .find(|(_, constant)| constant.expr == root)
1360 {
1361 Some((_, constant)) => self.floating_kind_of(&constant.type_, at)?,
1362 None => None,
1363 };
1364 if declared == Some(PrimitiveKind::Float128) {
1365 return Err(EvalError::LongDouble { at });
1366 }
1367 let value = self.eval_floating_at(expr, depth)?;
1368 if declared == Some(PrimitiveKind::Float32) && value.abs() > f64::from(f32::MAX) {
1369 return Err(EvalError::Overflow { at });
1370 }
1371 let text = alloc::format!("{value:?}");
1372 Ok(match text.split_once('e') {
1373 Some((mantissa, exponent)) => ConstValue::Float {
1374 mantissa: mantissa.to_string(),
1375 exponent: Some(exponent.to_string()),
1376 },
1377 None => ConstValue::Float {
1378 mantissa: text,
1379 exponent: None,
1380 },
1381 })
1382 }
1383
1384 fn floating_kind_of(
1395 &self,
1396 ty: &Ref<TypeNode>,
1397 at: NodeId,
1398 ) -> Result<Option<PrimitiveKind>, EvalError> {
1399 let mut next = ty.resolved().ok_or(EvalError::Unresolved { at })?;
1400 for _ in 0..MAX_EXPR_DEPTH {
1401 let node = self.types.get(next).map_err(|_| EvalError::DanglingExpr)?;
1402 match &node.kind {
1403 TypeKind::Primitive(
1404 kind @ (PrimitiveKind::Float32
1405 | PrimitiveKind::Float64
1406 | PrimitiveKind::Float128),
1407 ) => return Ok(Some(*kind)),
1408 TypeKind::Alias { aliased } => {
1409 next = aliased.resolved().ok_or(EvalError::Unresolved { at })?;
1410 }
1411 _ => return Ok(None),
1412 }
1413 }
1414 Err(EvalError::TooDeep)
1415 }
1416
1417 fn eval_floating_at(&self, expr: Id<ConstExprNode>, depth: usize) -> Result<f64, EvalError> {
1418 if depth > MAX_EXPR_DEPTH {
1419 return Err(EvalError::TooDeep);
1420 }
1421 let node = self.exprs.get(expr).map_err(|_| EvalError::DanglingExpr)?;
1422 let at = node.node_id;
1423 let finite = |value: f64| {
1424 if value.is_finite() {
1425 Ok(value)
1426 } else {
1427 Err(EvalError::Overflow { at })
1428 }
1429 };
1430 match &node.expr {
1431 ConstExpr::Literal(Literal::Float { mantissa, exponent }) => {
1432 let text = match exponent {
1433 Some(exponent) => alloc::format!("{mantissa}e{exponent}"),
1434 None => mantissa.clone(),
1435 };
1436 let value: f64 = text.parse().map_err(|_| EvalError::NotIntegral { at })?;
1437 if value.is_finite() {
1441 Ok(value)
1442 } else {
1443 Err(EvalError::LongDouble { at })
1444 }
1445 }
1446 ConstExpr::Literal(_) => Err(EvalError::MixedOperands { at }),
1447 ConstExpr::NameRef(reference) => {
1448 let target = reference.resolved().ok_or(EvalError::Unresolved { at })?;
1449 let constant = self
1450 .constants
1451 .get(target)
1452 .map_err(|_| EvalError::DanglingExpr)?;
1453 if self.floating_kind_of(&constant.type_, at)? == Some(PrimitiveKind::Float128) {
1454 return Err(EvalError::LongDouble { at });
1455 }
1456 self.eval_floating_at(constant.expr, depth + 1)
1457 }
1458 ConstExpr::Unary { op, operand } => {
1459 let value = self.eval_floating_at(*operand, depth + 1)?;
1460 match op {
1461 UnaryOp::Plus => Ok(value),
1462 UnaryOp::Minus => Ok(-value),
1463 UnaryOp::Not => Err(EvalError::NotFloatingOperator { at }),
1464 }
1465 }
1466 ConstExpr::Binary { op, lhs, rhs } => {
1467 use crate::node::constant::BinaryOp as B;
1468 let left = self.eval_floating_at(*lhs, depth + 1)?;
1469 let right = self.eval_floating_at(*rhs, depth + 1)?;
1470 match op {
1471 B::Add => finite(left + right),
1472 B::Sub => finite(left - right),
1473 B::Mul => finite(left * right),
1474 B::Div if right == 0.0 => Err(EvalError::DivisionByZero { at }),
1475 B::Div => finite(left / right),
1476 B::Or | B::Xor | B::And | B::Shl | B::Shr | B::Mod => {
1477 Err(EvalError::NotFloatingOperator { at })
1478 }
1479 }
1480 }
1481 }
1482 }
1483
1484 fn eval_integral_at(&self, expr: Id<ConstExprNode>, depth: usize) -> Result<i128, EvalError> {
1485 if depth > MAX_EXPR_DEPTH {
1486 return Err(EvalError::TooDeep);
1487 }
1488 let node = self.exprs.get(expr).map_err(|_| EvalError::DanglingExpr)?;
1489 let at = node.node_id;
1490 match &node.expr {
1491 ConstExpr::Literal(Literal::Integer(value)) => Ok(*value),
1492 ConstExpr::Literal(Literal::Boolean(value)) => Ok(i128::from(*value)),
1493 ConstExpr::Literal(Literal::Char(value)) => Ok(i128::from(u32::from(*value))),
1494 ConstExpr::Literal(Literal::WChar(value)) => Ok(i128::from(*value)),
1495 ConstExpr::Literal(Literal::Enumerator(reference)) => {
1501 let target = reference.resolved().ok_or(EvalError::Unresolved { at })?;
1502 self.effective_enumerator_value(target)
1503 .ok_or(EvalError::Unresolved { at })
1504 }
1505 ConstExpr::Literal(_) => Err(EvalError::NotIntegral { at }),
1506 ConstExpr::NameRef(reference) => {
1507 let target = reference.resolved().ok_or(EvalError::Unresolved { at })?;
1508 let constant = self
1509 .constants
1510 .get(target)
1511 .map_err(|_| EvalError::DanglingExpr)?;
1512 self.eval_integral_at(constant.expr, depth + 1)
1513 }
1514 ConstExpr::Unary { op, operand } => {
1515 let value = self.eval_integral_at(*operand, depth + 1)?;
1516 match op {
1517 UnaryOp::Plus => Ok(value),
1518 UnaryOp::Minus => value.checked_neg().ok_or(EvalError::Overflow { at }),
1519 UnaryOp::Not => Ok(!value),
1520 }
1521 }
1522 ConstExpr::Binary { op, lhs, rhs } => {
1523 let left = self.eval_integral_at(*lhs, depth + 1)?;
1524 let right = self.eval_integral_at(*rhs, depth + 1)?;
1525 Self::apply_binary(*op, left, right, at)
1526 }
1527 }
1528 }
1529
1530 fn apply_binary(
1531 op: crate::node::constant::BinaryOp,
1532 left: i128,
1533 right: i128,
1534 at: NodeId,
1535 ) -> Result<i128, EvalError> {
1536 use crate::node::constant::BinaryOp as B;
1537 match op {
1538 B::Or => Ok(left | right),
1539 B::Xor => Ok(left ^ right),
1540 B::And => Ok(left & right),
1541 B::Shl | B::Shr => {
1542 let distance = u32::try_from(right).map_err(|_| EvalError::InvalidShift { at })?;
1543 if distance >= 128 {
1544 return Err(EvalError::InvalidShift { at });
1545 }
1546 if matches!(op, B::Shl) {
1547 left.checked_shl(distance).ok_or(EvalError::Overflow { at })
1548 } else {
1549 left.checked_shr(distance).ok_or(EvalError::Overflow { at })
1550 }
1551 }
1552 B::Add => left.checked_add(right).ok_or(EvalError::Overflow { at }),
1553 B::Sub => left.checked_sub(right).ok_or(EvalError::Overflow { at }),
1554 B::Mul => left.checked_mul(right).ok_or(EvalError::Overflow { at }),
1555 B::Div => {
1556 if right == 0 {
1557 Err(EvalError::DivisionByZero { at })
1558 } else {
1559 left.checked_div(right).ok_or(EvalError::Overflow { at })
1560 }
1561 }
1562 B::Mod => {
1563 if right == 0 {
1564 Err(EvalError::DivisionByZero { at })
1565 } else {
1566 left.checked_rem(right).ok_or(EvalError::Overflow { at })
1567 }
1568 }
1569 }
1570 }
1571
1572 pub fn interface(&self, id: Id<InterfaceNode>) -> Result<&InterfaceNode, AstError> {
1579 Ok(self.interfaces.get(id)?)
1580 }
1581
1582 pub fn add_interface(
1587 &mut self,
1588 module: Id<ModuleNode>,
1589 name: &str,
1590 kind: InterfaceKind,
1591 bases: Vec<Ref<InterfaceNode>>,
1592 ) -> Result<Id<InterfaceNode>, AstError> {
1593 let node_id = self.next_model_id()?;
1594 let id = self.interfaces.insert(InterfaceNode {
1595 node_id,
1596 name: name.to_string(),
1597 module,
1598 kind,
1599 bases,
1600 operations: Vec::new(),
1601 attributes: Vec::new(),
1602 completeness: Completeness::Complete,
1603 facets: Facets::synthetic("interface created through the model API"),
1604 })?;
1605 let any = AnyId::Interface(id, node_id);
1606 self.register(any);
1607 self.modules.get_mut(module)?.children.push(any);
1608 self.committed(id)
1609 }
1610
1611 pub fn add_forward_interface(
1622 &mut self,
1623 module: Id<ModuleNode>,
1624 name: &str,
1625 kind: InterfaceKind,
1626 ) -> Result<Id<InterfaceNode>, AstError> {
1627 let id = self.add_interface(module, name, kind, Vec::new())?;
1628 self.interfaces.get_mut(id)?.completeness = Completeness::Forward;
1629 self.committed(id)
1630 }
1631
1632 pub fn complete_interface(
1642 &mut self,
1643 id: Id<InterfaceNode>,
1644 kind: InterfaceKind,
1645 bases: Vec<Ref<InterfaceNode>>,
1646 ) -> Result<(), AstError> {
1647 let node = self.interfaces.get(id)?;
1648 let node_id = node.node_id;
1649 if node.completeness == Completeness::Complete {
1650 return Err(AstError::AlreadyComplete { node: node_id });
1651 }
1652 self.unindex_pending(AnyId::Interface(id, node_id));
1656
1657 let node = self.interfaces.get_mut(id)?;
1658 node.kind = kind;
1659 node.bases = bases;
1660 node.completeness = Completeness::Complete;
1661
1662 self.index_pending(AnyId::Interface(id, node_id));
1663 self.record_completeness_change(node_id);
1664 Ok(())
1665 }
1666
1667 pub fn interfaces(&self) -> impl Iterator<Item = (Id<InterfaceNode>, &InterfaceNode)> {
1669 self.interfaces.iter()
1670 }
1671
1672 pub fn operations(&self) -> impl Iterator<Item = (Id<OperationNode>, &OperationNode)> {
1680 self.operations.iter()
1681 }
1682
1683 pub fn set_interface_form(
1699 &mut self,
1700 id: Id<InterfaceNode>,
1701 kind: InterfaceKind,
1702 bases: Vec<Ref<InterfaceNode>>,
1703 ) -> Result<(), AstError> {
1704 let node_id = self.interfaces.get(id)?.node_id;
1705 self.unindex_pending(AnyId::Interface(id, node_id));
1706 let node = self.interfaces.get_mut(id)?;
1707 node.kind = kind;
1708 node.bases = bases;
1709 self.index_pending(AnyId::Interface(id, node_id));
1710 Ok(())
1711 }
1712
1713 pub fn add_valuetype_base(
1724 &mut self,
1725 id: Id<TypeNode>,
1726 base: Ref<TypeNode>,
1727 ) -> Result<(), AstError> {
1728 let node_id = self.types.get(id)?.node_id;
1729 if !matches!(self.types.get(id)?.kind, TypeKind::Valuetype { .. }) {
1730 return Err(AstError::NotAnAggregate {
1731 node: node_id,
1732 found: self.types.get(id)?.kind.as_str(),
1733 });
1734 }
1735 if let TypeKind::Valuetype { bases, .. } = &mut self.types.get_mut(id)?.kind {
1736 bases.push(base);
1737 }
1738 self.reindex_pending(AnyId::Type(id, node_id));
1739 Ok(())
1740 }
1741
1742 pub fn object_reference_to(
1759 &mut self,
1760 interface: Id<InterfaceNode>,
1761 ) -> Result<Id<TypeNode>, AstError> {
1762 let existing = self.types.iter().find_map(|(id, node)| {
1763 matches!(
1764 &node.kind,
1765 TypeKind::ObjectRef {
1766 interface: Some(Ref::Resolved(target)),
1767 } if *target == interface
1768 )
1769 .then_some(id)
1770 });
1771 if let Some(id) = existing {
1772 return Ok(id);
1773 }
1774 let node = self.interfaces.get(interface)?;
1775 let (module, name) = (node.module, node.name.clone());
1776 self.add_type(
1777 module,
1778 &name,
1779 TypeKind::ObjectRef {
1780 interface: Some(Ref::Resolved(interface)),
1781 },
1782 )
1783 }
1784
1785 pub fn operation(&self, id: Id<OperationNode>) -> Result<&OperationNode, AstError> {
1790 Ok(self.operations.get(id)?)
1791 }
1792
1793 pub fn add_operation(
1798 &mut self,
1799 interface: Id<InterfaceNode>,
1800 name: &str,
1801 return_type: Option<Ref<TypeNode>>,
1802 oneway: bool,
1803 ) -> Result<Id<OperationNode>, AstError> {
1804 let parent_node_id = self.interfaces.get(interface)?.node_id;
1805 let node_id = self.next_model_id()?;
1806 let id = self.operations.insert(OperationNode {
1807 node_id,
1808 name: name.to_string(),
1809 return_type,
1810 params: Vec::new(),
1811 raises: Vec::new(),
1812 oneway,
1813 contexts: Vec::new(),
1814 parent: AnyId::Interface(interface, parent_node_id),
1815 facets: Facets::synthetic("operation created through the model API"),
1816 })?;
1817 self.register(AnyId::Operation(id, node_id));
1818 self.interfaces.get_mut(interface)?.operations.push(id);
1819 self.committed(id)
1820 }
1821
1822 pub fn add_valuetype_operation(
1840 &mut self,
1841 valuetype: Id<TypeNode>,
1842 name: &str,
1843 return_type: Option<Ref<TypeNode>>,
1844 initializer: bool,
1845 ) -> Result<Id<OperationNode>, AstError> {
1846 let parent_node_id = self.types.get(valuetype)?.node_id;
1847 if !matches!(self.types.get(valuetype)?.kind, TypeKind::Valuetype { .. }) {
1848 return Err(AstError::NotAnAggregate {
1849 node: parent_node_id,
1850 found: "not a valuetype",
1851 });
1852 }
1853 let node_id = self.next_model_id()?;
1854 let id = self.operations.insert(OperationNode {
1855 node_id,
1856 name: name.to_string(),
1857 return_type,
1858 params: Vec::new(),
1859 raises: Vec::new(),
1860 oneway: false,
1861 contexts: Vec::new(),
1862 parent: AnyId::Type(valuetype, parent_node_id),
1863 facets: Facets::synthetic("valuetype operation created through the model API"),
1864 })?;
1865 self.register(AnyId::Operation(id, node_id));
1866 if initializer
1867 && let TypeKind::Valuetype { initializers, .. } =
1868 &mut self.types.get_mut(valuetype)?.kind
1869 {
1870 initializers.push(id);
1871 }
1872 self.committed(id)
1873 }
1874
1875 pub fn set_oneway(&mut self, id: Id<OperationNode>, oneway: bool) -> Result<(), AstError> {
1883 self.operations.get_mut(id)?.oneway = oneway;
1884 Ok(())
1885 }
1886
1887 pub fn add_raises(
1896 &mut self,
1897 id: Id<OperationNode>,
1898 exception: Ref<ExceptionNode>,
1899 ) -> Result<(), AstError> {
1900 let node_id = self.operations.get(id)?.node_id;
1901 self.operations.get_mut(id)?.raises.push(exception);
1902 self.reindex_pending(AnyId::Operation(id, node_id));
1903 Ok(())
1904 }
1905
1906 pub fn add_context(&mut self, id: Id<OperationNode>, context: &str) -> Result<(), AstError> {
1911 self.operations
1912 .get_mut(id)?
1913 .contexts
1914 .push(context.to_string());
1915 Ok(())
1916 }
1917
1918 pub fn param(&self, id: Id<ParamNode>) -> Result<&ParamNode, AstError> {
1923 Ok(self.params.get(id)?)
1924 }
1925
1926 pub fn add_param(
1931 &mut self,
1932 operation: Id<OperationNode>,
1933 name: &str,
1934 direction: ParamDirection,
1935 type_: Ref<TypeNode>,
1936 ) -> Result<Id<ParamNode>, AstError> {
1937 let node_id = self.next_model_id()?;
1938 let id = self.params.insert(ParamNode {
1939 node_id,
1940 name: name.to_string(),
1941 direction,
1942 type_,
1943 parent: operation,
1944 facets: Facets::synthetic("parameter created through the model API"),
1945 })?;
1946 self.register(AnyId::Param(id, node_id));
1947 self.operations.get_mut(operation)?.params.push(id);
1948 self.committed(id)
1949 }
1950
1951 pub fn attribute(&self, id: Id<AttributeNode>) -> Result<&AttributeNode, AstError> {
1956 Ok(self.attributes.get(id)?)
1957 }
1958
1959 pub fn add_attribute_raises(
1965 &mut self,
1966 id: Id<AttributeNode>,
1967 exception: Ref<ExceptionNode>,
1968 on_set: bool,
1969 ) -> Result<(), AstError> {
1970 let node_id = self.attributes.get(id)?.node_id;
1971 let node = self.attributes.get_mut(id)?;
1972 if on_set {
1973 node.set_raises.push(exception);
1974 } else {
1975 node.get_raises.push(exception);
1976 }
1977 self.reindex_pending(AnyId::Attribute(id, node_id));
1978 Ok(())
1979 }
1980
1981 pub fn add_attribute(
1986 &mut self,
1987 interface: Id<InterfaceNode>,
1988 name: &str,
1989 type_: Ref<TypeNode>,
1990 readonly: bool,
1991 ) -> Result<Id<AttributeNode>, AstError> {
1992 let node_id = self.next_model_id()?;
1993 let id = self.attributes.insert(AttributeNode {
1994 node_id,
1995 name: name.to_string(),
1996 type_,
1997 readonly,
1998 get_raises: Vec::new(),
1999 set_raises: Vec::new(),
2000 parent: interface,
2001 facets: Facets::synthetic("attribute created through the model API"),
2002 })?;
2003 self.register(AnyId::Attribute(id, node_id));
2004 self.interfaces.get_mut(interface)?.attributes.push(id);
2005 self.committed(id)
2006 }
2007
2008 pub fn exception(&self, id: Id<ExceptionNode>) -> Result<&ExceptionNode, AstError> {
2013 Ok(self.exceptions.get(id)?)
2014 }
2015
2016 pub fn exceptions(&self) -> impl Iterator<Item = (Id<ExceptionNode>, &ExceptionNode)> {
2018 self.exceptions.iter()
2019 }
2020
2021 pub fn set_declaration_scope(&mut self, any: AnyId, scope: &str) -> Result<(), AstError> {
2028 let slot = match any {
2029 AnyId::Type(id, _) => &mut self.types.get_mut(id)?.scope,
2030 AnyId::Const(id, _) => &mut self.constants.get_mut(id)?.scope,
2031 AnyId::Exception(id, _) => &mut self.exceptions.get_mut(id)?.scope,
2032 other => {
2033 return Err(AstError::WrongKind {
2034 node: other.node_id(),
2035 expected: crate::NodeKind::Type,
2036 found: other.kind(),
2037 });
2038 }
2039 };
2040 *slot = Some(scope.to_string());
2041 self.by_scoped_name.remove_node(any.node_id());
2044 if let Some(name) = self.scoped_name_of(any) {
2045 self.by_scoped_name.insert(name, any.node_id());
2046 }
2047 Ok(())
2048 }
2049
2050 pub fn add_exception(
2055 &mut self,
2056 module: Id<ModuleNode>,
2057 name: &str,
2058 ) -> Result<Id<ExceptionNode>, AstError> {
2059 let node_id = self.next_model_id()?;
2060 let id = self.exceptions.insert(ExceptionNode {
2061 node_id,
2062 name: name.to_string(),
2063 module,
2064 scope: None,
2065 members: Vec::new(),
2066 facets: Facets::synthetic("exception created through the model API"),
2067 })?;
2068 let any = AnyId::Exception(id, node_id);
2069 self.register(any);
2070 self.modules.get_mut(module)?.children.push(any);
2071 self.committed(id)
2072 }
2073
2074 pub fn annotation_defs(
2084 &self,
2085 ) -> impl Iterator<Item = (Id<AnnotationDefNode>, &AnnotationDefNode)> {
2086 self.annotation_defs.iter()
2087 }
2088
2089 pub fn annotation_def(
2094 &self,
2095 id: Id<AnnotationDefNode>,
2096 ) -> Result<&AnnotationDefNode, AstError> {
2097 Ok(self.annotation_defs.get(id)?)
2098 }
2099
2100 pub fn add_annotation_def(
2105 &mut self,
2106 module: Id<ModuleNode>,
2107 name: &str,
2108 ) -> Result<Id<AnnotationDefNode>, AstError> {
2109 let node_id = self.next_model_id()?;
2110 let id = self.annotation_defs.insert(AnnotationDefNode {
2111 node_id,
2112 name: name.to_string(),
2113 module,
2114 members: Vec::new(),
2115 facets: Facets::synthetic("annotation created through the model API"),
2116 })?;
2117 let any = AnyId::AnnotationDef(id, node_id);
2118 self.register(any);
2119 self.modules.get_mut(module)?.children.push(any);
2120 self.committed(id)
2121 }
2122
2123 pub fn annotation_member(
2128 &self,
2129 id: Id<AnnotationMemberNode>,
2130 ) -> Result<&AnnotationMemberNode, AstError> {
2131 Ok(self.annotation_members.get(id)?)
2132 }
2133
2134 pub fn add_annotation_member(
2139 &mut self,
2140 annotation: Id<AnnotationDefNode>,
2141 name: &str,
2142 type_: Ref<TypeNode>,
2143 default: Option<Id<ConstExprNode>>,
2144 ) -> Result<Id<AnnotationMemberNode>, AstError> {
2145 let node_id = self.next_model_id()?;
2146 let is_value_member = name == "value";
2147 let id = self.annotation_members.insert(AnnotationMemberNode {
2148 node_id,
2149 name: name.to_string(),
2150 type_,
2151 default,
2152 is_value_member,
2153 parent: annotation,
2154 facets: Facets::synthetic("annotation member created through the model API"),
2155 })?;
2156 self.register(AnyId::AnnotationMember(id, node_id));
2157 self.annotation_defs.get_mut(annotation)?.members.push(id);
2158 self.committed(id)
2159 }
2160
2161 pub fn library(&self, id: Id<LibraryNode>) -> Result<&LibraryNode, AstError> {
2168 Ok(self.libraries.get(id)?)
2169 }
2170
2171 pub fn add_library(&mut self, name: &str) -> Result<Id<LibraryNode>, AstError> {
2176 let node_id = self.next_model_id()?;
2177 let id = self.libraries.insert(LibraryNode {
2178 node_id,
2179 name: name.to_string(),
2180 children: Vec::new(),
2181 facets: Facets::synthetic("library created through the model API"),
2182 })?;
2183 self.register(AnyId::Library(id, node_id));
2184 self.committed(id)
2185 }
2186
2187 pub fn domain(&self, id: Id<DomainNode>) -> Result<&DomainNode, AstError> {
2192 Ok(self.domains.get(id)?)
2193 }
2194
2195 pub fn add_domain(
2200 &mut self,
2201 library: Id<LibraryNode>,
2202 name: &str,
2203 domain_id: u32,
2204 ) -> Result<Id<DomainNode>, AstError> {
2205 let node_id = self.next_model_id()?;
2206 let id = self.domains.insert(DomainNode {
2207 node_id,
2208 name: name.to_string(),
2209 domain_id,
2210 topics: Vec::new(),
2211 parent: library,
2212 facets: Facets::synthetic("domain created through the model API"),
2213 })?;
2214 let any = AnyId::Domain(id, node_id);
2215 self.register(any);
2216 self.libraries.get_mut(library)?.children.push(any);
2217 self.committed(id)
2218 }
2219
2220 pub fn topic(&self, id: Id<TopicNode>) -> Result<&TopicNode, AstError> {
2225 Ok(self.topics.get(id)?)
2226 }
2227
2228 pub fn add_topic(
2233 &mut self,
2234 domain: Id<DomainNode>,
2235 name: &str,
2236 type_: Ref<TypeNode>,
2237 qos: Option<Ref<QosProfileNode>>,
2238 ) -> Result<Id<TopicNode>, AstError> {
2239 let node_id = self.next_model_id()?;
2240 let id = self.topics.insert(TopicNode {
2241 node_id,
2242 name: name.to_string(),
2243 type_,
2244 qos,
2245 parent: domain,
2246 facets: Facets::synthetic("topic created through the model API"),
2247 })?;
2248 self.register(AnyId::Topic(id, node_id));
2249 self.domains.get_mut(domain)?.topics.push(id);
2250 self.committed(id)
2251 }
2252
2253 pub fn qos_profile(&self, id: Id<QosProfileNode>) -> Result<&QosProfileNode, AstError> {
2258 Ok(self.qos_profiles.get(id)?)
2259 }
2260
2261 pub fn add_qos_profile(
2266 &mut self,
2267 library: Id<LibraryNode>,
2268 name: &str,
2269 base: Option<Ref<QosProfileNode>>,
2270 policies: Vec<QosPolicy>,
2271 ) -> Result<Id<QosProfileNode>, AstError> {
2272 let node_id = self.next_model_id()?;
2273 let id = self.qos_profiles.insert(QosProfileNode {
2274 node_id,
2275 name: name.to_string(),
2276 base,
2277 policies,
2278 parent: library,
2279 facets: Facets::synthetic("QoS profile created through the model API"),
2280 })?;
2281 let any = AnyId::QosProfile(id, node_id);
2282 self.register(any);
2283 self.libraries.get_mut(library)?.children.push(any);
2284 self.committed(id)
2285 }
2286
2287 pub fn participant(&self, id: Id<ParticipantNode>) -> Result<&ParticipantNode, AstError> {
2292 Ok(self.participants.get(id)?)
2293 }
2294
2295 pub fn add_participant(
2300 &mut self,
2301 library: Id<LibraryNode>,
2302 name: &str,
2303 domain: Ref<DomainNode>,
2304 qos: Option<Ref<QosProfileNode>>,
2305 ) -> Result<Id<ParticipantNode>, AstError> {
2306 let node_id = self.next_model_id()?;
2307 let id = self.participants.insert(ParticipantNode {
2308 node_id,
2309 name: name.to_string(),
2310 domain,
2311 qos,
2312 endpoints: Vec::new(),
2313 parent: library,
2314 facets: Facets::synthetic("participant created through the model API"),
2315 })?;
2316 let any = AnyId::Participant(id, node_id);
2317 self.register(any);
2318 self.libraries.get_mut(library)?.children.push(any);
2319 self.committed(id)
2320 }
2321
2322 pub fn endpoint(&self, id: Id<EndpointNode>) -> Result<&EndpointNode, AstError> {
2327 Ok(self.endpoints.get(id)?)
2328 }
2329
2330 pub fn add_endpoint(
2335 &mut self,
2336 participant: Id<ParticipantNode>,
2337 name: &str,
2338 role: EndpointRole,
2339 topic: Ref<TopicNode>,
2340 qos: Option<Ref<QosProfileNode>>,
2341 ) -> Result<Id<EndpointNode>, AstError> {
2342 let node_id = self.next_model_id()?;
2343 let id = self.endpoints.insert(EndpointNode {
2344 node_id,
2345 name: name.to_string(),
2346 role,
2347 topic,
2348 qos,
2349 parent: participant,
2350 facets: Facets::synthetic("endpoint created through the model API"),
2351 })?;
2352 self.register(AnyId::Endpoint(id, node_id));
2353 self.participants.get_mut(participant)?.endpoints.push(id);
2354 self.committed(id)
2355 }
2356
2357 #[must_use]
2361 pub fn facets(&self, any: AnyId) -> Option<&Facets> {
2362 Some(match any {
2363 AnyId::Module(id, _) => &self.modules.get(id).ok()?.facets,
2364 AnyId::Type(id, _) => &self.types.get(id).ok()?.facets,
2365 AnyId::Member(id, _) => &self.members.get(id).ok()?.facets,
2366 AnyId::Case(id, _) => &self.cases.get(id).ok()?.facets,
2367 AnyId::Enumerator(id, _) => &self.enumerators.get(id).ok()?.facets,
2368 AnyId::BitValue(id, _) => &self.bit_values.get(id).ok()?.facets,
2369 AnyId::Bitfield(id, _) => &self.bitfields.get(id).ok()?.facets,
2370 AnyId::Const(id, _) => &self.constants.get(id).ok()?.facets,
2371 AnyId::ConstExpr(id, _) => &self.exprs.get(id).ok()?.facets,
2372 AnyId::Interface(id, _) => &self.interfaces.get(id).ok()?.facets,
2373 AnyId::Operation(id, _) => &self.operations.get(id).ok()?.facets,
2374 AnyId::Param(id, _) => &self.params.get(id).ok()?.facets,
2375 AnyId::Attribute(id, _) => &self.attributes.get(id).ok()?.facets,
2376 AnyId::Exception(id, _) => &self.exceptions.get(id).ok()?.facets,
2377 AnyId::AnnotationDef(id, _) => &self.annotation_defs.get(id).ok()?.facets,
2378 AnyId::AnnotationMember(id, _) => &self.annotation_members.get(id).ok()?.facets,
2379 AnyId::Domain(id, _) => &self.domains.get(id).ok()?.facets,
2380 AnyId::Topic(id, _) => &self.topics.get(id).ok()?.facets,
2381 AnyId::QosProfile(id, _) => &self.qos_profiles.get(id).ok()?.facets,
2382 AnyId::Participant(id, _) => &self.participants.get(id).ok()?.facets,
2383 AnyId::Endpoint(id, _) => &self.endpoints.get(id).ok()?.facets,
2384 AnyId::Library(id, _) => &self.libraries.get(id).ok()?.facets,
2385 })
2386 }
2387
2388 pub fn facets_mut(&mut self, any: AnyId) -> Option<&mut Facets> {
2390 Some(match any {
2391 AnyId::Module(id, _) => &mut self.modules.get_mut(id).ok()?.facets,
2392 AnyId::Type(id, _) => &mut self.types.get_mut(id).ok()?.facets,
2393 AnyId::Member(id, _) => &mut self.members.get_mut(id).ok()?.facets,
2394 AnyId::Case(id, _) => &mut self.cases.get_mut(id).ok()?.facets,
2395 AnyId::Enumerator(id, _) => &mut self.enumerators.get_mut(id).ok()?.facets,
2396 AnyId::BitValue(id, _) => &mut self.bit_values.get_mut(id).ok()?.facets,
2397 AnyId::Bitfield(id, _) => &mut self.bitfields.get_mut(id).ok()?.facets,
2398 AnyId::Const(id, _) => &mut self.constants.get_mut(id).ok()?.facets,
2399 AnyId::ConstExpr(id, _) => &mut self.exprs.get_mut(id).ok()?.facets,
2400 AnyId::Interface(id, _) => &mut self.interfaces.get_mut(id).ok()?.facets,
2401 AnyId::Operation(id, _) => &mut self.operations.get_mut(id).ok()?.facets,
2402 AnyId::Param(id, _) => &mut self.params.get_mut(id).ok()?.facets,
2403 AnyId::Attribute(id, _) => &mut self.attributes.get_mut(id).ok()?.facets,
2404 AnyId::Exception(id, _) => &mut self.exceptions.get_mut(id).ok()?.facets,
2405 AnyId::AnnotationDef(id, _) => &mut self.annotation_defs.get_mut(id).ok()?.facets,
2406 AnyId::AnnotationMember(id, _) => &mut self.annotation_members.get_mut(id).ok()?.facets,
2407 AnyId::Domain(id, _) => &mut self.domains.get_mut(id).ok()?.facets,
2408 AnyId::Topic(id, _) => &mut self.topics.get_mut(id).ok()?.facets,
2409 AnyId::QosProfile(id, _) => &mut self.qos_profiles.get_mut(id).ok()?.facets,
2410 AnyId::Participant(id, _) => &mut self.participants.get_mut(id).ok()?.facets,
2411 AnyId::Endpoint(id, _) => &mut self.endpoints.get_mut(id).ok()?.facets,
2412 AnyId::Library(id, _) => &mut self.libraries.get_mut(id).ok()?.facets,
2413 })
2414 }
2415
2416 pub fn any_of_type(&self, id: Id<TypeNode>) -> Result<AnyId, AstError> {
2421 Ok(AnyId::Type(id, self.types.get(id)?.node_id))
2422 }
2423
2424 pub fn any_of_member(&self, id: Id<MemberNode>) -> Result<AnyId, AstError> {
2429 Ok(AnyId::Member(id, self.members.get(id)?.node_id))
2430 }
2431}
2432
2433#[must_use]
2436pub fn primitive(kind: PrimitiveKind) -> TypeKind {
2437 TypeKind::Primitive(kind)
2438}