Skip to main content

sysml_v2_parser/
ast.rs

1//! Abstract syntax tree types for SysML v2 textual notation.
2
3/// Source location: byte offset, line, column, and length in the source file.
4/// Line and column are **1-based**. Use [`Span::to_lsp_range`] for 0-based LSP ranges.
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct Span {
7    pub offset: usize,
8    pub line: u32,
9    pub column: usize,
10    pub len: usize,
11}
12
13impl Span {
14    /// Dummy span for tests or synthetic nodes (offset 0, line 1, column 1, len 0).
15    pub fn dummy() -> Self {
16        Self {
17            offset: 0,
18            line: 1,
19            column: 1,
20            len: 0,
21        }
22    }
23
24    /// LSP uses 0-based line and 0-based character. Returns (start_line, start_character, end_line, end_character).
25    pub fn to_lsp_range(&self) -> (u32, u32, u32, u32) {
26        let start_line = self.line.saturating_sub(1);
27        let start_char = self.column.saturating_sub(1);
28        let end_char = start_char.saturating_add(self.len);
29        (start_line, start_char as u32, start_line, end_char as u32)
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::Span;
36
37    #[test]
38    fn span_dummy() {
39        let s = Span::dummy();
40        assert_eq!(s.offset, 0);
41        assert_eq!(s.line, 1);
42        assert_eq!(s.column, 1);
43        assert_eq!(s.len, 0);
44    }
45}
46
47#[derive(Debug, Clone)]
48pub struct Node<T> {
49    pub span: Span,
50    pub value: T,
51}
52
53impl<T: PartialEq> PartialEq for Node<T> {
54    fn eq(&self, other: &Self) -> bool {
55        self.value == other.value
56    }
57}
58
59impl<T: Eq> Eq for Node<T> {}
60
61impl<T> Node<T> {
62    pub fn new(span: Span, value: T) -> Self {
63        Self { span, value }
64    }
65}
66
67impl<T> std::ops::Deref for Node<T> {
68    type Target = T;
69    fn deref(&self) -> &T {
70        &self.value
71    }
72}
73
74/// Trait for generic access to node source span (e.g. visitors).
75pub trait AstNode {
76    fn span(&self) -> Span;
77}
78
79impl<T> AstNode for Node<T> {
80    fn span(&self) -> Span {
81        self.span.clone()
82    }
83}
84
85/// Expression: literals, feature refs, member access, index, bracket/unit, etc.
86#[derive(Debug, Clone, PartialEq, Eq)]
87pub enum Expression {
88    LiteralInteger(i64),
89    LiteralReal(String),
90    LiteralString(String),
91    LiteralBoolean(bool),
92    /// Single name or qualified name.
93    FeatureRef(String),
94    /// base.member (e.g. engine.fuelCmdPort).
95    MemberAccess(Box<Node<Expression>>, String),
96    /// base#(index) e.g. frontWheel#(1).
97    Index {
98        base: Box<Node<Expression>>,
99        index: Box<Node<Expression>>,
100    },
101    /// [unit] e.g. [kg].
102    Bracket(Box<Node<Expression>>),
103    /// value [unit] e.g. 1750 [kg].
104    LiteralWithUnit {
105        value: Box<Node<Expression>>,
106        unit: Box<Node<Expression>>,
107    },
108    /// Binary infix operation e.g. `a >= b * c`, `x / y`.
109    BinaryOp {
110        op: String,
111        left: Box<Node<Expression>>,
112        right: Box<Node<Expression>>,
113    },
114    /// Unary prefix: + - ~ not
115    UnaryOp {
116        op: String,
117        operand: Box<Node<Expression>>,
118    },
119    /// KerML null or empty sequence ().
120    Null,
121}
122
123/// KerML top-level element: package, namespace, import, or library package (BNF RootNamespace = PackageBodyElement*).
124#[derive(Debug, Clone, PartialEq, Eq)]
125pub enum RootElement {
126    Package(Node<Package>),
127    LibraryPackage(Node<LibraryPackage>),
128    Namespace(Node<NamespaceDecl>),
129    Import(Node<Import>),
130}
131
132/// KerML NamespaceDeclaration: `namespace` Identification NamespaceBody (same body structure as Package).
133#[derive(Debug, Clone, PartialEq, Eq)]
134pub struct NamespaceDecl {
135    pub identification: Identification,
136    pub body: PackageBody,
137}
138
139/// Root of a SysML/KerML document: a sequence of top-level package or namespace elements.
140#[derive(Debug, Clone, PartialEq, Eq)]
141pub struct RootNamespace {
142    pub elements: Vec<Node<RootElement>>,
143}
144
145/// KerML ElementFilterMember: MemberPrefix? 'filter' condition ';'
146#[derive(Debug, Clone, PartialEq, Eq)]
147pub struct FilterMember {
148    pub visibility: Option<Visibility>,
149    pub condition: Node<Expression>,
150}
151
152/// Placeholder node inserted when resilient parsing skips malformed input.
153#[derive(Debug, Clone, PartialEq, Eq)]
154pub struct ParseErrorNode {
155    pub message: String,
156    pub code: String,
157    pub expected: Option<String>,
158    pub found: Option<String>,
159    pub suggestion: Option<String>,
160}
161
162/// Modeled KerML semantic declaration captured as package-level syntax.
163#[derive(Debug, Clone, PartialEq, Eq)]
164pub struct KermlSemanticDecl {
165    pub bnf_production: String,
166    pub text: String,
167}
168
169/// Modeled KerML feature declaration family (occurrence/expr/predicate/succession).
170#[derive(Debug, Clone, PartialEq, Eq)]
171pub struct KermlFeatureDecl {
172    pub bnf_production: String,
173    pub text: String,
174}
175
176/// Package-level KerML feature declaration captured as an explicit dedicated node.
177#[derive(Debug, Clone, PartialEq, Eq)]
178pub struct FeatureDecl {
179    pub keyword: String,
180    pub text: String,
181}
182
183/// Package-level KerML classifier declaration captured as an explicit dedicated node.
184#[derive(Debug, Clone, PartialEq, Eq)]
185pub struct ClassifierDecl {
186    pub keyword: String,
187    pub text: String,
188}
189
190/// Modeled extended SysML/KerML declaration family not yet represented by
191/// dedicated concrete nodes (e.g. concern/message style library declarations).
192#[derive(Debug, Clone, PartialEq, Eq)]
193pub struct ExtendedLibraryDecl {
194    pub bnf_production: String,
195    pub text: String,
196}
197
198/// Top-level element inside a namespace or package body.
199#[derive(Debug, Clone, PartialEq, Eq)]
200pub enum PackageBodyElement {
201    Error(Node<ParseErrorNode>),
202    Doc(Node<DocComment>),
203    Comment(Node<CommentAnnotation>),
204    TextualRep(Node<TextualRepresentation>),
205    Filter(Node<FilterMember>),
206    Package(Node<Package>),
207    LibraryPackage(Node<LibraryPackage>),
208    Import(Node<Import>),
209    PartDef(Node<PartDef>),
210    PartUsage(Node<PartUsage>),
211    PortDef(Node<PortDef>),
212    InterfaceDef(Node<InterfaceDef>),
213    AliasDef(Node<AliasDef>),
214    AttributeDef(Node<AttributeDef>),
215    ActionDef(Node<ActionDef>),
216    ActionUsage(Node<ActionUsage>),
217    RequirementDef(Node<RequirementDef>),
218    RequirementUsage(Node<RequirementUsage>),
219    Satisfy(Node<Satisfy>),
220    UseCaseDef(Node<UseCaseDef>),
221    Actor(Node<ActorDecl>),
222    StateDef(Node<StateDef>),
223    StateUsage(Node<StateUsage>),
224    ItemDef(Node<ItemDef>),
225    IndividualDef(Node<IndividualDef>),
226    ConstraintDef(Node<ConstraintDef>),
227    CalcDef(Node<CalcDef>),
228    ViewDef(Node<ViewDef>),
229    ViewpointDef(Node<ViewpointDef>),
230    RenderingDef(Node<RenderingDef>),
231    ViewUsage(Node<ViewUsage>),
232    ViewpointUsage(Node<ViewpointUsage>),
233    RenderingUsage(Node<RenderingUsage>),
234    ConnectionDef(Node<ConnectionDef>),
235    MetadataDef(Node<MetadataDef>),
236    EnumDef(Node<EnumDef>),
237    OccurrenceDef(Node<OccurrenceDef>),
238    OccurrenceUsage(Node<OccurrenceUsage>),
239    Dependency(Node<Dependency>),
240    AllocationDef(Node<AllocationDef>),
241    AllocationUsage(Node<AllocationUsage>),
242    FlowDef(Node<FlowDef>),
243    FlowUsage(Node<FlowUsage>),
244    ConcernUsage(Node<ConcernUsage>),
245    CaseDef(Node<CaseDef>),
246    CaseUsage(Node<CaseUsage>),
247    AnalysisCaseDef(Node<AnalysisCaseDef>),
248    AnalysisCaseUsage(Node<AnalysisCaseUsage>),
249    VerificationCaseDef(Node<VerificationCaseDef>),
250    VerificationCaseUsage(Node<VerificationCaseUsage>),
251    UseCaseUsage(Node<UseCaseUsage>),
252    FeatureDecl(Node<FeatureDecl>),
253    ClassifierDecl(Node<ClassifierDecl>),
254    KermlSemanticDecl(Node<KermlSemanticDecl>),
255    KermlFeatureDecl(Node<KermlFeatureDecl>),
256    ExtendedLibraryDecl(Node<ExtendedLibraryDecl>),
257}
258
259/// A package declaration: `package` Identification PackageBody
260#[derive(Debug, Clone, PartialEq, Eq)]
261pub struct Package {
262    pub identification: Identification,
263    pub body: PackageBody,
264}
265
266/// Identification: optional short name in `< >`, optional name.
267/// BNF: ( '<' declaredShortName = NAME '>' )? ( declaredName = NAME )?
268#[derive(Debug, Clone, PartialEq, Eq)]
269pub struct Identification {
270    /// Short name inside `< ... >`, if present.
271    pub short_name: Option<String>,
272    /// Main declared name (may be quoted, e.g. '1a-Parts Tree').
273    pub name: Option<String>,
274}
275
276/// Package body: either `;` or `{` PackageBodyElement* `}`
277#[derive(Debug, Clone, PartialEq, Eq)]
278pub enum PackageBody {
279    /// Semicolon form: no body elements.
280    Semicolon,
281    /// Brace form: list of body elements (may be empty).
282    Brace {
283        elements: Vec<Node<PackageBodyElement>>,
284    },
285}
286
287/// Visibility for imports and members.
288#[derive(Debug, Clone, Copy, PartialEq, Eq)]
289pub enum Visibility {
290    Public,
291    Private,
292    Protected,
293}
294
295/// KerML FilterPackageMember: `[` OwnedExpression `]`.
296#[derive(Debug, Clone, PartialEq, Eq)]
297pub struct FilterPackageMember {
298    pub expression: Node<Expression>,
299}
300
301/// Import: `private`? `import` `all`? QualifiedName (`::` `*`)? or FilterPackage form.
302#[derive(Debug, Clone, PartialEq, Eq)]
303pub struct Import {
304    pub visibility: Option<Visibility>,
305    /// Whether this is a namespace import (QualifiedName::* or FilterPackage) or membership import (single QualifiedName).
306    pub is_import_all: bool,
307    /// Import target, e.g. "SI::kg" or "Definitions::*".
308    pub target: String,
309    /// KerML: optional recursive import after :: (e.g. QualifiedName::** or QualifiedName::*::**).
310    pub is_recursive: bool,
311    /// KerML FilterPackage form: one or more `[ expr ]` members. When present, this is a namespace import of a filter package.
312    pub filter_members: Option<Vec<Node<FilterPackageMember>>>,
313}
314
315/// Part definition: `part def` Identification (`:>` specializes)? Body.
316#[derive(Debug, Clone, PartialEq, Eq)]
317pub struct PartDef {
318    /// Optional `abstract` or `variation` prefix (BNF BasicDefinitionPrefix).
319    pub definition_prefix: Option<DefinitionPrefix>,
320    /// Whether this is an `individual part def`.
321    pub is_individual: bool,
322    pub identification: Identification,
323    /// Supertype after `:>`, e.g. Some("Axle") for `part def FrontAxle :> Axle`.
324    pub specializes: Option<String>,
325    /// Span of the `:> <type>` fragment (for semantic tokens), when present.
326    pub specializes_span: Option<Span>,
327    pub body: PartDefBody,
328}
329
330/// BNF BasicDefinitionPrefix: `abstract` | `variation`.
331#[derive(Debug, Clone, PartialEq, Eq)]
332pub enum DefinitionPrefix {
333    Abstract,
334    Variation,
335}
336
337/// Body of a part definition: `;` or `{` PartDefBodyElement* `}`.
338#[derive(Debug, Clone, PartialEq, Eq)]
339pub enum PartDefBody {
340    Semicolon,
341    Brace {
342        elements: Vec<Node<PartDefBodyElement>>,
343    },
344}
345
346/// Element inside a part definition body.
347#[derive(Debug, Clone, PartialEq, Eq)]
348pub enum PartDefBodyElement {
349    Error(Node<ParseErrorNode>),
350    Doc(Node<DocComment>),
351    Annotation(Node<Annotation>),
352    Other(String),
353    AttributeDef(Node<AttributeDef>),
354    AttributeUsage(Node<AttributeUsage>),
355    RequirementUsage(Node<RequirementUsage>),
356    Ref(Node<RefDecl>),
357    PortUsage(Node<PortUsage>),
358    PartUsage(Box<Node<PartUsage>>),
359    OccurrenceUsage(Box<Node<OccurrenceUsage>>),
360    InterfaceUsage(Node<InterfaceUsage>),
361    Connect(Node<Connect>),
362    Perform(Node<Perform>),
363    Allocate(Node<Allocate>),
364    OpaqueMember(Node<OpaqueMemberDecl>),
365    /// `exhibit state` name `:` type (`;` or body).
366    ExhibitState(Node<ExhibitState>),
367}
368
369/// Library-tolerant part member preserved without forcing it into an unrelated node shape.
370#[derive(Debug, Clone, PartialEq, Eq)]
371pub struct OpaqueMemberDecl {
372    pub keyword: String,
373    pub name: String,
374    pub text: String,
375    pub body: AttributeBody,
376}
377
378/// Exhibit state usage: `exhibit state` name `:` type (`;` or body).
379#[derive(Debug, Clone, PartialEq, Eq)]
380pub struct ExhibitState {
381    pub name: String,
382    pub type_name: Option<String>,
383    pub body: StateDefBody,
384}
385
386/// Attribute definition: `attribute` name (`:>` type)? body.
387#[derive(Debug, Clone, PartialEq, Eq)]
388pub struct AttributeDef {
389    pub name: String,
390    /// Type after `:>`, e.g. Some("ISQ::mass").
391    pub typing: Option<String>,
392    pub body: AttributeBody,
393    /// Span of the defined name (for semantic tokens).
394    pub name_span: Option<Span>,
395    /// Span of the type after `:>`, if present (for semantic tokens).
396    pub typing_span: Option<Span>,
397}
398
399/// Body of an attribute (def or usage): `;` or `{` ... `}`.
400#[derive(Debug, Clone, PartialEq, Eq)]
401pub enum AttributeBody {
402    Semicolon,
403    Brace,
404}
405
406/// Item definition: `item def` Identification body (for events, etc.).
407#[derive(Debug, Clone, PartialEq, Eq)]
408pub struct ItemDef {
409    pub identification: Identification,
410    pub body: AttributeBody,
411}
412
413/// Individual definition: `individual def` Identification `:>` type body.
414#[derive(Debug, Clone, PartialEq, Eq)]
415pub struct IndividualDef {
416    pub identification: Identification,
417    pub specializes: Option<String>,
418    pub body: AttributeBody,
419}
420
421/// Part usage: `part` name `:` type multiplicity? `ordered`? (`redefines`|`:>>`)? value? body.
422#[derive(Debug, Clone, PartialEq, Eq)]
423pub struct PartUsage {
424    pub is_individual: bool,
425    pub name: String,
426    /// Type after `:`, e.g. "Vehicle", "AxleAssembly".
427    pub type_name: String,
428    /// Multiplicity, e.g. Some("[2]").
429    pub multiplicity: Option<String>,
430    pub ordered: bool,
431    /// Optional `subsets` feature and value expression.
432    pub subsets: Option<(String, Option<Node<Expression>>)>,
433    /// Redefines target, e.g. Some("frontAxleAssembly") or Some("vehicle1::mass").
434    pub redefines: Option<String>,
435    /// Value expression (= expr, default = expr, := expr).
436    pub value: Option<Node<Expression>>,
437    pub body: PartUsageBody,
438    /// Span of the usage name (for semantic tokens).
439    pub name_span: Option<Span>,
440    /// Span of the type reference after `:` (for semantic tokens).
441    pub type_ref_span: Option<Span>,
442}
443
444/// Body of a part usage: `;` or `{` PartUsageBodyElement* `}`.
445#[derive(Debug, Clone, PartialEq, Eq)]
446pub enum PartUsageBody {
447    Semicolon,
448    Brace {
449        elements: Vec<Node<PartUsageBodyElement>>,
450    },
451}
452
453/// Metadata annotation on usage: `@` Name (`:` Type)? MetadataBody (e.g. `@Security;` or `@Safety{isMandatory = true;}`).
454#[derive(Debug, Clone, PartialEq, Eq)]
455pub struct MetadataAnnotation {
456    pub name: String,
457    pub type_name: Option<String>,
458    pub body: ConnectBody,
459}
460
461/// Generic annotation or metadata usage captured in body scopes.
462#[derive(Debug, Clone, PartialEq, Eq)]
463pub struct Annotation {
464    pub sigil: String,
465    pub head: String,
466    pub type_name: Option<String>,
467    pub body: ConnectBody,
468}
469
470/// Element inside a part usage body.
471#[derive(Debug, Clone, PartialEq, Eq)]
472pub enum PartUsageBodyElement {
473    Error(Node<ParseErrorNode>),
474    Doc(Node<DocComment>),
475    Annotation(Node<Annotation>),
476    AttributeUsage(Node<AttributeUsage>),
477    PartUsage(Box<Node<PartUsage>>),
478    OccurrenceUsage(Box<Node<OccurrenceUsage>>),
479    PortUsage(Node<PortUsage>),
480    Bind(Node<Bind>),
481    /// `ref` name `:` type body (reference binding in part usage).
482    Ref(Node<RefDecl>),
483    InterfaceUsage(Node<InterfaceUsage>),
484    Connect(Node<Connect>),
485    Perform(Node<Perform>),
486    Allocate(Node<Allocate>),
487    Satisfy(Node<Satisfy>),
488    StateUsage(Node<StateUsage>),
489    MetadataAnnotation(Node<MetadataAnnotation>),
490}
491
492/// Enacted performance: `perform` action_path `{` body `}` inside a part usage.
493#[derive(Debug, Clone, PartialEq, Eq)]
494pub struct Perform {
495    /// Qualified action name (e.g. "provide power" or "provide power.generate torque").
496    pub action_name: String,
497    /// Type after `:` in "perform action name : Type" form.
498    pub type_name: Option<String>,
499    pub body: PerformBody,
500}
501
502/// Body of a perform: `;` or `{` PerformBodyElement* `}`.
503#[derive(Debug, Clone, PartialEq, Eq)]
504pub enum PerformBody {
505    Semicolon,
506    Brace {
507        elements: Vec<Node<PerformBodyElement>>,
508    },
509}
510
511/// Element inside a perform body: doc comment or in/out binding.
512#[derive(Debug, Clone, PartialEq, Eq)]
513pub enum PerformBodyElement {
514    Doc(Node<DocComment>),
515    InOut(Node<PerformInOutBinding>),
516}
517
518/// In/out binding inside a perform body: `in` name `=` expr `;` or `out` name `=` expr `;`.
519#[derive(Debug, Clone, PartialEq, Eq)]
520pub struct PerformInOutBinding {
521    pub direction: InOut,
522    pub name: String,
523    pub value: Node<Expression>,
524}
525
526/// Attribute usage: `attribute` name `redefines`? value? body.
527#[derive(Debug, Clone, PartialEq, Eq)]
528pub struct AttributeUsage {
529    pub name: String,
530    /// Redefines target, e.g. Some("Vehicle::mass").
531    pub redefines: Option<String>,
532    /// Value expression.
533    pub value: Option<Node<Expression>>,
534    pub body: AttributeBody,
535    /// Span of the usage name (for semantic tokens).
536    pub name_span: Option<Span>,
537    /// Span of the redefines target after `redefines`, if present (for semantic tokens).
538    pub redefines_span: Option<Span>,
539}
540
541// ---------------------------------------------------------------------------
542// Port
543// ---------------------------------------------------------------------------
544
545/// Port definition: `port def` Identification body.
546#[derive(Debug, Clone, PartialEq, Eq)]
547pub struct PortDef {
548    pub identification: Identification,
549    /// Supertype after `:>`, e.g. Some("ClutchPort") for `port def ManualClutchPort :> ClutchPort`.
550    pub specializes: Option<String>,
551    pub body: PortDefBody,
552}
553
554/// Body of a port definition: `;` or `{` PortDefBodyElement* `}`.
555#[derive(Debug, Clone, PartialEq, Eq)]
556pub enum PortDefBody {
557    Semicolon,
558    Brace {
559        elements: Vec<Node<PortDefBodyElement>>,
560    },
561}
562
563/// Element inside a port definition body (in/out declarations or nested port usages).
564#[derive(Debug, Clone, PartialEq, Eq)]
565pub enum PortDefBodyElement {
566    InOutDecl(Node<InOutDecl>),
567    Doc(Node<DocComment>),
568    AttributeDef(Node<AttributeDef>),
569    AttributeUsage(Node<AttributeUsage>),
570    PortUsage(Node<PortUsage>),
571}
572
573/// Port usage: `port` name `:` type multiplicity? `:>` subsets? `redefines`? body.
574#[derive(Debug, Clone, PartialEq, Eq)]
575pub struct PortUsage {
576    pub name: String,
577    pub type_name: Option<String>,
578    pub multiplicity: Option<String>,
579    /// Subsets feature and optional value expression.
580    pub subsets: Option<(String, Option<Node<Expression>>)>,
581    pub redefines: Option<String>,
582    pub body: PortBody,
583    /// Span of the usage name (for semantic tokens).
584    pub name_span: Option<Span>,
585    /// Span of the type reference after `:`, if present (for semantic tokens).
586    pub type_ref_span: Option<Span>,
587}
588
589/// Body of a port usage: `;` or `{` PortUsage* `}` (nested ports).
590#[derive(Debug, Clone, PartialEq, Eq)]
591pub enum PortBody {
592    Semicolon,
593    Brace,
594    /// Brace with nested port usages (e.g. port vehicleToRoadPort redefines ... { port left...; port right...; }).
595    BraceWithPorts {
596        elements: Vec<Node<PortUsage>>,
597    },
598}
599
600// ---------------------------------------------------------------------------
601// Interface
602// ---------------------------------------------------------------------------
603
604/// Interface definition: `interface def` Identification body.
605#[derive(Debug, Clone, PartialEq, Eq)]
606pub struct InterfaceDef {
607    pub identification: Identification,
608    pub body: InterfaceDefBody,
609}
610
611/// Body of an interface definition: `;` or `{` InterfaceDefBodyElement* `}`.
612#[derive(Debug, Clone, PartialEq, Eq)]
613pub enum InterfaceDefBody {
614    Semicolon,
615    Brace {
616        elements: Vec<Node<InterfaceDefBodyElement>>,
617    },
618}
619
620/// Element inside an interface definition body.
621#[derive(Debug, Clone, PartialEq, Eq)]
622pub enum InterfaceDefBodyElement {
623    Doc(Node<DocComment>),
624    EndDecl(Node<EndDecl>),
625    RefDecl(Node<RefDecl>),
626    ConnectStmt(Node<ConnectStmt>),
627}
628
629/// End declaration in interface def: `end` name `:` type `;`.
630#[derive(Debug, Clone, PartialEq, Eq)]
631pub struct EndDecl {
632    pub name: String,
633    pub type_name: String,
634    /// Span of the name (for semantic tokens).
635    pub name_span: Option<Span>,
636    /// Span of the type after `:` (for semantic tokens).
637    pub type_ref_span: Option<Span>,
638}
639
640/// Ref declaration in interface def: `ref` name `:` type body.
641#[derive(Debug, Clone, PartialEq, Eq)]
642pub struct RefDecl {
643    pub name: String,
644    pub type_name: String,
645    /// Optional binding value: `= expr` (SysML shorthand binding for references).
646    pub value: Option<Node<Expression>>,
647    pub body: RefBody,
648    /// Span of the name (for semantic tokens).
649    pub name_span: Option<Span>,
650    /// Span of the type after `:` (for semantic tokens).
651    pub type_ref_span: Option<Span>,
652}
653
654/// Body of a ref declaration: `;` or `{` ... `}`.
655#[derive(Debug, Clone, PartialEq, Eq)]
656pub enum RefBody {
657    Semicolon,
658    Brace,
659}
660
661// ---------------------------------------------------------------------------
662// Connection (Phase 2)
663// ---------------------------------------------------------------------------
664
665/// Connection definition: `connection def` Identification body (BNF ConnectionDefinition).
666#[derive(Debug, Clone, PartialEq, Eq)]
667pub struct ConnectionDef {
668    pub identification: Identification,
669    pub body: ConnectionDefBody,
670}
671
672/// Body of a connection definition: `;` or `{` end/ref/connect* `}`.
673#[derive(Debug, Clone, PartialEq, Eq)]
674pub enum ConnectionDefBody {
675    Semicolon,
676    Brace {
677        elements: Vec<Node<ConnectionDefBodyElement>>,
678    },
679}
680
681#[derive(Debug, Clone, PartialEq, Eq)]
682pub enum ConnectionDefBodyElement {
683    EndDecl(Node<EndDecl>),
684    RefDecl(Node<RefDecl>),
685    ConnectStmt(Node<ConnectStmt>),
686}
687
688// ---------------------------------------------------------------------------
689// Metadata (Phase 2)
690// ---------------------------------------------------------------------------
691
692/// Metadata definition: `metadata def` Identification body (BNF MetadataDefinition).
693#[derive(Debug, Clone, PartialEq, Eq)]
694pub struct MetadataDef {
695    pub is_abstract: bool,
696    pub identification: Identification,
697    pub body: DefinitionBody,
698}
699
700// ---------------------------------------------------------------------------
701// Enumeration (Phase 2)
702// ---------------------------------------------------------------------------
703
704/// Enumeration definition: `enum def` Identification EnumerationBody (BNF EnumerationDefinition).
705#[derive(Debug, Clone, PartialEq, Eq)]
706pub struct EnumDef {
707    pub identification: Identification,
708    pub body: EnumerationBody,
709}
710
711#[derive(Debug, Clone, PartialEq, Eq)]
712pub enum EnumerationBody {
713    Semicolon,
714    Brace { values: Vec<String> },
715}
716
717// ---------------------------------------------------------------------------
718// Occurrence (Phase 2)
719// ---------------------------------------------------------------------------
720
721/// Occurrence definition: `occurrence def` Identification body (BNF OccurrenceDefinition).
722#[derive(Debug, Clone, PartialEq, Eq)]
723pub struct OccurrenceDef {
724    pub is_abstract: bool,
725    pub identification: Identification,
726    pub body: DefinitionBody,
727}
728
729/// Occurrence usage: `occurrence` name (`:` type)? body, with optional individual/portion modifiers.
730#[derive(Debug, Clone, PartialEq, Eq)]
731pub struct OccurrenceUsage {
732    pub is_individual: bool,
733    pub portion_kind: Option<String>,
734    pub name: String,
735    pub type_name: Option<String>,
736    pub body: OccurrenceUsageBody,
737}
738
739#[derive(Debug, Clone, PartialEq, Eq)]
740pub enum OccurrenceUsageBody {
741    Semicolon,
742    Brace {
743        elements: Vec<Node<OccurrenceBodyElement>>,
744    },
745}
746
747#[derive(Debug, Clone, PartialEq, Eq)]
748pub enum OccurrenceBodyElement {
749    Error(Node<ParseErrorNode>),
750    Doc(Node<DocComment>),
751    Annotation(Node<Annotation>),
752    AttributeUsage(Node<AttributeUsage>),
753    PartUsage(Box<Node<PartUsage>>),
754    OccurrenceUsage(Box<Node<OccurrenceUsage>>),
755}
756
757// ---------------------------------------------------------------------------
758// Library Package (Phase 2)
759// ---------------------------------------------------------------------------
760
761/// Library package: `library` (optional `standard`) `package` Identification PackageBody (BNF LibraryPackage).
762#[derive(Debug, Clone, PartialEq, Eq)]
763pub struct LibraryPackage {
764    pub is_standard: bool,
765    pub identification: Identification,
766    pub body: PackageBody,
767}
768
769/// Generic definition body: `;` or `{` ... `}` (skip content for metadata/occurrence).
770#[derive(Debug, Clone, PartialEq, Eq)]
771pub enum DefinitionBody {
772    Semicolon,
773    Brace,
774}
775
776/// Connect statement in interface def or usage: `connect` from `to` to body.
777#[derive(Debug, Clone, PartialEq, Eq)]
778pub struct ConnectStmt {
779    pub from: Node<Expression>,
780    pub to: Node<Expression>,
781    pub body: ConnectBody,
782}
783
784/// Body of a connect statement: `;` or `{` ... `}`.
785#[derive(Debug, Clone, PartialEq, Eq)]
786pub enum ConnectBody {
787    Semicolon,
788    Brace,
789}
790
791// ---------------------------------------------------------------------------
792// Part usage body: bind, interface usage, connect
793// ---------------------------------------------------------------------------
794
795/// Bind: `bind` left `=` right (`;` or `{ }`).
796#[derive(Debug, Clone, PartialEq, Eq)]
797pub struct Bind {
798    pub left: Node<Expression>,
799    pub right: Node<Expression>,
800    /// Optional body after the bind (semicolon or brace); 3a fixture uses `bind x = y { }`.
801    pub body: Option<ConnectBody>,
802}
803
804/// Interface usage: typed+connect or connection form.
805#[derive(Debug, Clone, PartialEq, Eq)]
806pub enum InterfaceUsage {
807    /// `interface` `:Type`? `connect` from `to` to body; optional body with ref redefs.
808    TypedConnect {
809        interface_type: Option<String>,
810        from: Node<Expression>,
811        to: Node<Expression>,
812        body: ConnectBody,
813        body_elements: Vec<Node<InterfaceUsageBodyElement>>,
814    },
815    /// `interface` from `to` to body.
816    Connection {
817        from: Node<Expression>,
818        to: Node<Expression>,
819        body_elements: Vec<Node<InterfaceUsageBodyElement>>,
820    },
821}
822
823/// Element in interface usage body (e.g. ref redefinition).
824#[derive(Debug, Clone, PartialEq, Eq)]
825pub enum InterfaceUsageBodyElement {
826    /// `ref` `:>>` name `=` value body.
827    RefRedef {
828        name: String,
829        value: Node<Expression>,
830        body: RefBody,
831    },
832}
833
834/// Connect at part usage level: `connect` from `to` to body.
835#[derive(Debug, Clone, PartialEq, Eq)]
836pub struct Connect {
837    pub from: Node<Expression>,
838    pub to: Node<Expression>,
839    pub body: ConnectBody,
840}
841
842// ---------------------------------------------------------------------------
843// Alias
844// ---------------------------------------------------------------------------
845
846/// Alias definition: `alias` Identification `for` qualified_name body.
847#[derive(Debug, Clone, PartialEq, Eq)]
848pub struct AliasDef {
849    pub identification: Identification,
850    pub target: String,
851    pub body: AliasBody,
852}
853
854/// Body of an alias definition: `;` or `{` ... `}`.
855#[derive(Debug, Clone, PartialEq, Eq)]
856pub enum AliasBody {
857    Semicolon,
858    Brace,
859}
860
861// ---------------------------------------------------------------------------
862// Action (function-based behavior)
863// ---------------------------------------------------------------------------
864
865/// Action definition: `action def` Identification body (in/out params).
866#[derive(Debug, Clone, PartialEq, Eq)]
867pub struct ActionDef {
868    pub identification: Identification,
869    pub body: ActionDefBody,
870}
871
872/// Body of an action definition: `;` or `{` ActionDefBodyElement* `}`.
873#[derive(Debug, Clone, PartialEq, Eq)]
874pub enum ActionDefBody {
875    Semicolon,
876    Brace {
877        elements: Vec<Node<ActionDefBodyElement>>,
878    },
879}
880
881/// Element inside an action definition body.
882#[derive(Debug, Clone, PartialEq, Eq)]
883pub enum ActionDefBodyElement {
884    Error(Node<ParseErrorNode>),
885    InOutDecl(Node<InOutDecl>),
886    Doc(Node<DocComment>),
887    Annotation(Node<Annotation>),
888    RefDecl(Node<RefDecl>),
889    Perform(Node<Perform>),
890    Bind(Node<Bind>),
891    Flow(Node<Flow>),
892    FirstStmt(Node<FirstStmt>),
893    MergeStmt(Node<MergeStmt>),
894    StateUsage(Node<StateUsage>),
895    ActionUsage(Box<Node<ActionUsage>>),
896    Assign(Node<AssignStmt>),
897    ForLoop(Node<ForLoop>),
898    ThenAction(Node<ThenAction>),
899    Decl(Node<ActionBodyDecl>),
900}
901
902/// Assignment statement (SysML v2 AssignmentNode/AssignmentActionUsage).
903///
904/// Examples:
905/// - `assign x := y;`
906/// - `then assign position := dynamics.x_out;`
907#[derive(Debug, Clone, PartialEq, Eq)]
908pub struct AssignStmt {
909    pub is_then: bool,
910    pub lhs: String,
911    pub rhs: String,
912}
913
914/// For-loop node (SysML v2 ForLoopNode) - modeled minimally.
915#[derive(Debug, Clone, PartialEq, Eq)]
916pub struct ForLoop {
917    pub var: String,
918    pub range: String,
919    pub body: ActionDefBody,
920}
921
922/// Succession to an action usage: `then action ...`.
923#[derive(Debug, Clone, PartialEq, Eq)]
924pub struct ThenAction {
925    pub action: Node<ActionUsage>,
926}
927
928/// In/out parameter in action def: `in` name `:` type `;` or `out` name `:` type `;`.
929#[derive(Debug, Clone, PartialEq, Eq)]
930pub struct InOutDecl {
931    pub direction: InOut,
932    pub name: String,
933    pub type_name: String,
934}
935
936#[derive(Debug, Clone, Copy, PartialEq, Eq)]
937pub enum InOut {
938    In,
939    Out,
940    InOut,
941}
942
943/// Action usage: `action` name `:` type_name (`accept` param_name `:` param_type)? body.
944#[derive(Debug, Clone, PartialEq, Eq)]
945pub struct ActionUsage {
946    pub name: String,
947    pub type_name: String,
948    /// For accept form: (param_name, param_type).
949    pub accept: Option<(String, String)>,
950    pub body: ActionUsageBody,
951    /// Span of the usage name (for semantic tokens).
952    pub name_span: Option<Span>,
953    /// Span of the type reference after `:` (for semantic tokens).
954    pub type_ref_span: Option<Span>,
955}
956
957/// Body of an action usage: `;` or `{` ActionUsageBodyElement* `}`.
958#[derive(Debug, Clone, PartialEq, Eq)]
959pub enum ActionUsageBody {
960    Semicolon,
961    Brace {
962        elements: Vec<Node<ActionUsageBodyElement>>,
963    },
964}
965
966/// Element inside an action usage body.
967#[derive(Debug, Clone, PartialEq, Eq)]
968pub enum ActionUsageBodyElement {
969    Error(Node<ParseErrorNode>),
970    Doc(Node<DocComment>),
971    Annotation(Node<Annotation>),
972    InOutDecl(Node<InOutDecl>),
973    RefDecl(Node<RefDecl>),
974    Bind(Node<Bind>),
975    Flow(Node<Flow>),
976    FirstStmt(Node<FirstStmt>),
977    MergeStmt(Node<MergeStmt>),
978    StateUsage(Node<StateUsage>),
979    ActionUsage(Box<Node<ActionUsage>>),
980    Assign(Node<AssignStmt>),
981    ForLoop(Node<ForLoop>),
982    ThenAction(Node<ThenAction>),
983    Decl(Node<ActionBodyDecl>),
984}
985
986/// A minimally-modeled declaration inside an action/behavior body (e.g. `attribute ...;`, `calc ...;`).
987#[derive(Debug, Clone, PartialEq, Eq)]
988pub struct ActionBodyDecl {
989    pub keyword: String,
990    pub text: String,
991}
992
993/// Flow: `flow` from `to` to body.
994#[derive(Debug, Clone, PartialEq, Eq)]
995pub struct Flow {
996    pub from: Node<Expression>,
997    pub to: Node<Expression>,
998    pub body: ConnectBody,
999}
1000
1001/// Flow definition: `flow def` Identification body.
1002#[derive(Debug, Clone, PartialEq, Eq)]
1003pub struct FlowDef {
1004    pub identification: Identification,
1005    pub body: DefinitionBody,
1006}
1007
1008/// Flow usage: `flow` name (`:` type)? [`from` expr `to` expr]? body.
1009#[derive(Debug, Clone, PartialEq, Eq)]
1010pub struct FlowUsage {
1011    pub name: String,
1012    pub type_name: Option<String>,
1013    pub from: Option<Node<Expression>>,
1014    pub to: Option<Node<Expression>>,
1015    pub body: DefinitionBody,
1016}
1017
1018/// First/then control flow: `first` expr `then` expr body.
1019#[derive(Debug, Clone, PartialEq, Eq)]
1020pub struct FirstStmt {
1021    pub first: Node<Expression>,
1022    pub then: Node<Expression>,
1023    pub body: FirstMergeBody,
1024}
1025
1026/// Merge: `merge` expr body.
1027#[derive(Debug, Clone, PartialEq, Eq)]
1028pub struct MergeStmt {
1029    pub merge: Node<Expression>,
1030    pub body: FirstMergeBody,
1031}
1032
1033/// Body of first/merge: `;` or `{` ... `}`.
1034#[derive(Debug, Clone, PartialEq, Eq)]
1035pub enum FirstMergeBody {
1036    Semicolon,
1037    Brace,
1038}
1039
1040// ---------------------------------------------------------------------------
1041// Allocation
1042// ---------------------------------------------------------------------------
1043
1044/// Allocate statement at part usage level: `allocate` from `to` to body.
1045#[derive(Debug, Clone, PartialEq, Eq)]
1046pub struct Allocate {
1047    pub source: Node<Expression>,
1048    pub target: Node<Expression>,
1049    pub body: ConnectBody,
1050}
1051
1052/// Allocation definition: `allocation def` Identification body.
1053#[derive(Debug, Clone, PartialEq, Eq)]
1054pub struct AllocationDef {
1055    pub identification: Identification,
1056    pub body: DefinitionBody,
1057}
1058
1059/// Allocation usage: `allocation` name (`:` type)? [`allocate` source `to` target]? body.
1060#[derive(Debug, Clone, PartialEq, Eq)]
1061pub struct AllocationUsage {
1062    pub name: String,
1063    pub type_name: Option<String>,
1064    pub source: Option<Node<Expression>>,
1065    pub target: Option<Node<Expression>>,
1066    pub body: DefinitionBody,
1067}
1068
1069// ---------------------------------------------------------------------------
1070// Requirements
1071// ---------------------------------------------------------------------------
1072
1073/// Requirement definition: `requirement def` Identification body.
1074#[derive(Debug, Clone, PartialEq, Eq)]
1075pub struct RequirementDef {
1076    pub identification: Identification,
1077    pub body: RequirementDefBody,
1078}
1079
1080/// Body of an requirement definition: `;` or `{` RequirementDefBodyElement* `}`.
1081#[derive(Debug, Clone, PartialEq, Eq)]
1082pub enum RequirementDefBody {
1083    Semicolon,
1084    Brace {
1085        elements: Vec<Node<RequirementDefBodyElement>>,
1086    },
1087}
1088
1089#[derive(Debug, Clone, PartialEq, Eq)]
1090pub enum RequirementDefBodyElement {
1091    Error(Node<ParseErrorNode>),
1092    /// Unmodeled requirement-body element captured as raw text (used for library parsing).
1093    Other(String),
1094    Annotation(Node<Annotation>),
1095    Import(Node<Import>),
1096    SubjectDecl(Node<SubjectDecl>),
1097    AttributeDef(Node<AttributeDef>),
1098    AttributeUsage(Node<AttributeUsage>),
1099    RequireConstraint(Node<RequireConstraint>),
1100    Frame(Node<FrameMember>),
1101    Doc(Node<DocComment>),
1102}
1103
1104/// Subject declaration: `subject` name `:` type `;`.
1105#[derive(Debug, Clone, PartialEq, Eq)]
1106pub struct SubjectDecl {
1107    pub name: String,
1108    pub type_name: String,
1109}
1110
1111/// Require constraint: `require constraint { ... }`.
1112#[derive(Debug, Clone, PartialEq, Eq)]
1113pub struct RequireConstraint {
1114    pub body: RequireConstraintBody,
1115}
1116
1117/// Require constraint body: `;` or `{` ConstraintDefBodyElement* `}`.
1118#[derive(Debug, Clone, PartialEq, Eq)]
1119pub enum RequireConstraintBody {
1120    Semicolon,
1121    Brace {
1122        elements: Vec<Node<ConstraintDefBodyElement>>,
1123    },
1124}
1125
1126/// Requirement usage / Satisfy. Example: `satisfy EnduranceReq by droneInstance;`
1127#[derive(Debug, Clone, PartialEq, Eq)]
1128pub struct Satisfy {
1129    pub source: Node<Expression>,
1130    pub target: Node<Expression>,
1131    pub body: ConnectBody,
1132}
1133
1134/// Bare requirement Usage.
1135#[derive(Debug, Clone, PartialEq, Eq)]
1136pub struct RequirementUsage {
1137    pub name: String,
1138    pub type_name: Option<String>,
1139    pub subsets: Option<String>,
1140    pub body: RequirementDefBody,
1141}
1142
1143/// Dependency: `dependency` (Identification `from`)? client(s) `to` supplier(s) RelationshipBody.
1144#[derive(Debug, Clone, PartialEq, Eq)]
1145pub struct Dependency {
1146    pub identification: Option<Identification>,
1147    pub clients: Vec<String>,
1148    pub suppliers: Vec<String>,
1149    pub body: ConnectBody,
1150}
1151
1152/// Framed concern member in requirement body: `frame` name (`;` or body).
1153#[derive(Debug, Clone, PartialEq, Eq)]
1154pub struct FrameMember {
1155    pub name: String,
1156    pub body: RequirementDefBody,
1157}
1158
1159/// Concern usage at package level: `concern` name (`:` type)? RequirementBody.
1160#[derive(Debug, Clone, PartialEq, Eq)]
1161pub struct ConcernUsage {
1162    pub name: String,
1163    pub type_name: Option<String>,
1164    pub body: RequirementDefBody,
1165}
1166
1167/// Case definition: `case def` Identification body.
1168#[derive(Debug, Clone, PartialEq, Eq)]
1169pub struct CaseDef {
1170    pub identification: Identification,
1171    pub body: UseCaseDefBody,
1172}
1173
1174/// Case usage: `case` name (`:` type)? body.
1175#[derive(Debug, Clone, PartialEq, Eq)]
1176pub struct CaseUsage {
1177    pub name: String,
1178    pub type_name: Option<String>,
1179    pub body: UseCaseDefBody,
1180}
1181
1182/// Analysis case definition: `analysis def` Identification body.
1183#[derive(Debug, Clone, PartialEq, Eq)]
1184pub struct AnalysisCaseDef {
1185    pub identification: Identification,
1186    pub body: UseCaseDefBody,
1187}
1188
1189/// Analysis case usage: `analysis` name (`:` type)? body.
1190#[derive(Debug, Clone, PartialEq, Eq)]
1191pub struct AnalysisCaseUsage {
1192    pub name: String,
1193    pub type_name: Option<String>,
1194    pub body: UseCaseDefBody,
1195}
1196
1197/// Verification case definition: `verification def` Identification body.
1198#[derive(Debug, Clone, PartialEq, Eq)]
1199pub struct VerificationCaseDef {
1200    pub identification: Identification,
1201    pub body: UseCaseDefBody,
1202}
1203
1204/// Verification case usage: `verification` name (`:` type)? body.
1205#[derive(Debug, Clone, PartialEq, Eq)]
1206pub struct VerificationCaseUsage {
1207    pub name: String,
1208    pub type_name: Option<String>,
1209    pub body: UseCaseDefBody,
1210}
1211
1212/// Use case usage at package level: `use case` name (`:` type)? CaseBody.
1213#[derive(Debug, Clone, PartialEq, Eq)]
1214pub struct UseCaseUsage {
1215    pub name: String,
1216    pub type_name: Option<String>,
1217    pub body: UseCaseDefBody,
1218}
1219
1220// ---------------------------------------------------------------------------
1221// Use Cases
1222// ---------------------------------------------------------------------------
1223
1224/// Actor declaration: `actor` Identification `;`.
1225#[derive(Debug, Clone, PartialEq, Eq)]
1226pub struct ActorDecl {
1227    pub identification: Identification,
1228}
1229
1230/// Use Case definition: `use case def` Identification body.
1231#[derive(Debug, Clone, PartialEq, Eq)]
1232pub struct UseCaseDef {
1233    pub identification: Identification,
1234    pub body: UseCaseDefBody,
1235}
1236
1237#[derive(Debug, Clone, PartialEq, Eq)]
1238pub enum UseCaseDefBody {
1239    Semicolon,
1240    Brace {
1241        elements: Vec<Node<UseCaseDefBodyElement>>,
1242    },
1243}
1244
1245/// `first <name>;` inside a case/use-case body (used in SysML v2 release fixtures).
1246#[derive(Debug, Clone, PartialEq, Eq)]
1247pub struct FirstSuccession {
1248    pub target: String,
1249}
1250
1251/// `then done;` inside a case/use-case body.
1252#[derive(Debug, Clone, PartialEq, Eq)]
1253pub struct ThenDone {}
1254
1255/// `include <usecase> ...` inside a case/use-case body.
1256#[derive(Debug, Clone, PartialEq, Eq)]
1257pub struct IncludeUseCase {
1258    pub name: String,
1259    /// Optional multiplicity suffix like `[0..*]` captured as raw text including brackets.
1260    pub multiplicity: Option<String>,
1261    pub body: UseCaseDefBody,
1262}
1263
1264/// `then include <usecase> ...` inside a case/use-case body.
1265#[derive(Debug, Clone, PartialEq, Eq)]
1266pub struct ThenIncludeUseCase {
1267    pub include: Node<IncludeUseCase>,
1268}
1269
1270/// `then use case <name> ...` inside a case/use-case body.
1271#[derive(Debug, Clone, PartialEq, Eq)]
1272pub struct ThenUseCaseUsage {
1273    pub use_case: Node<UseCaseUsage>,
1274}
1275
1276/// `subject;` shorthand used in SysML v2 release fixtures (subject of an enclosing case/use case).
1277#[derive(Debug, Clone, PartialEq, Eq)]
1278pub struct SubjectRef {}
1279
1280/// `actor :>> <name> = <expr>;` redefinition/assignment used in SysML v2 release fixtures.
1281#[derive(Debug, Clone, PartialEq, Eq)]
1282pub struct ActorRedefinitionAssignment {
1283    pub name: String,
1284    /// Raw RHS expression text up to `;` (we don't model the expression grammar here yet).
1285    pub rhs: String,
1286}
1287
1288/// `ref :>> <name> { ... }` redefinition used in SysML v2 release fixtures.
1289#[derive(Debug, Clone, PartialEq, Eq)]
1290pub struct RefRedefinition {
1291    pub name: String,
1292    /// Raw body text for now (balanced `{ ... }` including nested braces).
1293    pub body: String,
1294}
1295
1296/// `return ref <name><multiplicity?> { ... }` used in SysML v2 release libraries.
1297#[derive(Debug, Clone, PartialEq, Eq)]
1298pub struct ReturnRef {
1299    pub name: String,
1300    pub multiplicity: Option<String>,
1301    /// Raw body text for now (balanced `{ ... }` including nested braces).
1302    pub body: String,
1303}
1304
1305#[derive(Debug, Clone, PartialEq, Eq)]
1306pub enum UseCaseDefBodyElement {
1307    Error(Node<ParseErrorNode>),
1308    /// Unmodeled use-case / analysis-case body element captured as raw text (used for library parsing).
1309    Other(String),
1310    Doc(Node<DocComment>),
1311    SubjectDecl(Node<SubjectDecl>),
1312    /// `subject;` shorthand.
1313    SubjectRef(Node<SubjectRef>),
1314    ActorUsage(Node<ActorUsage>),
1315    ActorRedefinitionAssignment(Node<ActorRedefinitionAssignment>),
1316    Objective(Node<Objective>),
1317    FirstSuccession(Node<FirstSuccession>),
1318    ThenIncludeUseCase(Node<ThenIncludeUseCase>),
1319    ThenUseCaseUsage(Node<ThenUseCaseUsage>),
1320    ThenDone(Node<ThenDone>),
1321    IncludeUseCase(Node<IncludeUseCase>),
1322    RefRedefinition(Node<RefRedefinition>),
1323    ReturnRef(Node<ReturnRef>),
1324    Assign(Node<AssignStmt>),
1325    ForLoop(Node<ForLoop>),
1326    ThenAction(Node<ThenAction>),
1327}
1328
1329/// actor usage `actor pilot : Operator;`
1330#[derive(Debug, Clone, PartialEq, Eq)]
1331pub struct ActorUsage {
1332    pub name: String,
1333    pub type_name: String,
1334}
1335
1336/// Objective `objective { doc ... }`
1337#[derive(Debug, Clone, PartialEq, Eq)]
1338pub struct Objective {
1339    pub body: ConstraintBody,
1340}
1341
1342// ---------------------------------------------------------------------------
1343// State Machine
1344// ---------------------------------------------------------------------------
1345
1346/// State definition: `state def` Identification body.
1347#[derive(Debug, Clone, PartialEq, Eq)]
1348pub struct StateDef {
1349    pub identification: Identification,
1350    pub body: StateDefBody,
1351}
1352
1353#[derive(Debug, Clone, PartialEq, Eq)]
1354pub enum StateDefBody {
1355    Semicolon,
1356    Brace {
1357        elements: Vec<Node<StateDefBodyElement>>,
1358    },
1359}
1360
1361#[derive(Debug, Clone, PartialEq, Eq)]
1362pub enum StateDefBodyElement {
1363    Error(Node<ParseErrorNode>),
1364    Doc(Node<DocComment>),
1365    Annotation(Node<Annotation>),
1366    Other(String),
1367    /// `entry` (`;` or body) - entry action.
1368    Entry(Node<EntryAction>),
1369    /// `then` name `;` - initial state.
1370    Then(Node<ThenStmt>),
1371    /// `ref` name `:` type body – reference binding in state.
1372    Ref(Node<RefDecl>),
1373    StateUsage(Node<StateUsage>),
1374    Transition(Node<Transition>),
1375}
1376
1377/// Entry action: `entry` (`;` or body).
1378#[derive(Debug, Clone, PartialEq, Eq)]
1379pub struct EntryAction {
1380    /// For `entry action name body` form; None for plain `entry` body.
1381    pub action_name: Option<String>,
1382    pub body: StateDefBody,
1383}
1384
1385/// Then (initial state): `then` name `;`
1386#[derive(Debug, Clone, PartialEq, Eq)]
1387pub struct ThenStmt {
1388    pub state_name: String,
1389}
1390
1391/// State usage: `state` name (`:` type)? body.
1392#[derive(Debug, Clone, PartialEq, Eq)]
1393pub struct StateUsage {
1394    pub name: String,
1395    pub type_name: Option<String>,
1396    pub body: StateDefBody,
1397}
1398
1399/// Transition: `transition` name [`first` source] [`if` guard] [`do` effect] `then` target body.
1400#[derive(Debug, Clone, PartialEq, Eq)]
1401pub struct Transition {
1402    pub name: Option<String>,
1403    /// If omitted, form is `transition name then target;`.
1404    pub source: Option<Node<Expression>>,
1405    pub guard: Option<Node<Expression>>,
1406    pub effect: Option<Node<Expression>>,
1407    pub target: Node<Expression>,
1408    pub body: ConnectBody,
1409}
1410
1411// ---------------------------------------------------------------------------
1412// Constraints & Calculations
1413// ---------------------------------------------------------------------------
1414
1415/// Constraint definition: `constraint def` Identification body.
1416#[derive(Debug, Clone, PartialEq, Eq)]
1417pub struct ConstraintDef {
1418    pub identification: Identification,
1419    pub body: ConstraintDefBody,
1420}
1421
1422#[derive(Debug, Clone, PartialEq, Eq)]
1423pub enum ConstraintDefBody {
1424    Semicolon,
1425    Brace {
1426        elements: Vec<Node<ConstraintDefBodyElement>>,
1427    },
1428}
1429
1430#[derive(Debug, Clone, PartialEq, Eq)]
1431pub enum ConstraintDefBodyElement {
1432    Error(Node<ParseErrorNode>),
1433    Doc(Node<DocComment>),
1434    InOutDecl(Node<InOutDecl>),
1435    Expression(Node<Expression>), // e.g. totalThrust >= totalWeight * margin
1436    /// Unmodeled constraint-body element captured as raw text (used for library parsing).
1437    Other(String),
1438}
1439
1440/// constraint body {}
1441#[derive(Debug, Clone, PartialEq, Eq)]
1442pub enum ConstraintBody {
1443    Semicolon,
1444    Brace, // Often contains docs or block of expressions
1445}
1446
1447/// KerML Documentation: 'doc' Identification? ( 'locale' STRING_VALUE )? body = REGULAR_COMMENT.
1448#[derive(Debug, Clone, PartialEq, Eq)]
1449pub struct DocComment {
1450    /// Optional identification after 'doc'.
1451    pub identification: Option<Identification>,
1452    /// Optional locale string (e.g. "en").
1453    pub locale: Option<String>,
1454    /// Body text (content between /* and */).
1455    pub text: String,
1456}
1457
1458/// KerML Comment: ( 'comment' Identification? )? ( 'locale' STRING_VALUE )? body = REGULAR_COMMENT.
1459#[derive(Debug, Clone, PartialEq, Eq)]
1460pub struct CommentAnnotation {
1461    pub identification: Option<Identification>,
1462    pub locale: Option<String>,
1463    pub text: String,
1464}
1465
1466/// KerML TextualRepresentation: ( 'rep' Identification )? 'language' STRING_VALUE body.
1467#[derive(Debug, Clone, PartialEq, Eq)]
1468pub struct TextualRepresentation {
1469    pub rep_identification: Option<Identification>,
1470    pub language: String,
1471    pub text: String,
1472}
1473
1474/// Calc definition: `calc def` Identification body.
1475#[derive(Debug, Clone, PartialEq, Eq)]
1476pub struct CalcDef {
1477    pub identification: Identification,
1478    pub body: CalcDefBody,
1479}
1480
1481#[derive(Debug, Clone, PartialEq, Eq)]
1482pub enum CalcDefBody {
1483    Semicolon,
1484    Brace {
1485        elements: Vec<Node<CalcDefBodyElement>>,
1486    },
1487}
1488
1489#[derive(Debug, Clone, PartialEq, Eq)]
1490pub enum CalcDefBodyElement {
1491    Error(Node<ParseErrorNode>),
1492    Doc(Node<DocComment>),
1493    InOutDecl(Node<InOutDecl>),
1494    ReturnDecl(Node<ReturnDecl>),
1495    Expression(Node<Expression>), // formula
1496    /// Unmodeled calc-body element captured as raw text (used for library parsing).
1497    Other(String),
1498}
1499
1500/// Return declaration: `return` name `:` type `;`.
1501#[derive(Debug, Clone, PartialEq, Eq)]
1502pub struct ReturnDecl {
1503    pub name: String,
1504    pub type_name: String,
1505}
1506
1507// ---------------------------------------------------------------------------
1508// Views and Viewpoints (SysML v2 Clause 8.2.2.26)
1509// ---------------------------------------------------------------------------
1510
1511/// View definition: `view def` Identification ViewDefinitionBody.
1512#[derive(Debug, Clone, PartialEq, Eq)]
1513pub struct ViewDef {
1514    pub identification: Identification,
1515    pub body: ViewDefBody,
1516}
1517
1518#[derive(Debug, Clone, PartialEq, Eq)]
1519pub enum ViewDefBody {
1520    Semicolon,
1521    Brace {
1522        elements: Vec<Node<ViewDefBodyElement>>,
1523    },
1524}
1525
1526#[derive(Debug, Clone, PartialEq, Eq)]
1527pub enum ViewDefBodyElement {
1528    Error(Node<ParseErrorNode>),
1529    /// Unmodeled view-definition body element captured as raw text (used for library parsing).
1530    Other(String),
1531    Doc(Node<DocComment>),
1532    Filter(Node<FilterMember>),
1533    ViewRendering(Node<ViewRenderingUsage>),
1534}
1535
1536/// View rendering usage: `render` name `:` type (`;` or body).
1537#[derive(Debug, Clone, PartialEq, Eq)]
1538pub struct ViewRenderingUsage {
1539    pub name: String,
1540    pub type_name: Option<String>,
1541    pub body: ConnectBody,
1542}
1543
1544/// Viewpoint definition: `viewpoint def` Identification RequirementBody.
1545#[derive(Debug, Clone, PartialEq, Eq)]
1546pub struct ViewpointDef {
1547    pub identification: Identification,
1548    pub body: RequirementDefBody,
1549}
1550
1551/// Rendering definition: `rendering def` Definition.
1552#[derive(Debug, Clone, PartialEq, Eq)]
1553pub struct RenderingDef {
1554    pub identification: Identification,
1555    pub body: RenderingDefBody,
1556}
1557
1558#[derive(Debug, Clone, PartialEq, Eq)]
1559pub enum RenderingDefBody {
1560    Semicolon,
1561    Brace,
1562}
1563
1564/// View usage: `view` name `:` type? ViewBody.
1565#[derive(Debug, Clone, PartialEq, Eq)]
1566pub struct ViewUsage {
1567    pub name: String,
1568    pub type_name: Option<String>,
1569    pub body: ViewBody,
1570}
1571
1572#[derive(Debug, Clone, PartialEq, Eq)]
1573pub enum ViewBody {
1574    Semicolon,
1575    Brace {
1576        elements: Vec<Node<ViewBodyElement>>,
1577    },
1578}
1579
1580#[derive(Debug, Clone, PartialEq, Eq)]
1581pub enum ViewBodyElement {
1582    Error(Node<ParseErrorNode>),
1583    /// Unmodeled view body element captured as raw text (used for library parsing).
1584    Other(String),
1585    Doc(Node<DocComment>),
1586    Filter(Node<FilterMember>),
1587    ViewRendering(Node<ViewRenderingUsage>),
1588    Expose(Node<ExposeMember>),
1589    Satisfy(Node<SatisfyViewMember>),
1590}
1591
1592/// Expose in view body: `expose` (MembershipImport | NamespaceImport) RelationshipBody.
1593#[derive(Debug, Clone, PartialEq, Eq)]
1594pub struct ExposeMember {
1595    /// Full target path (e.g. vehicle, vehicle::*, vehicle::*::**, SystemModel::vehicle::**).
1596    pub target: String,
1597    pub body: ConnectBody,
1598}
1599
1600/// Satisfy in view body: `satisfy` QualifiedName RelationshipBody.
1601#[derive(Debug, Clone, PartialEq, Eq)]
1602pub struct SatisfyViewMember {
1603    pub viewpoint_ref: String,
1604    pub body: ConnectBody,
1605}
1606
1607/// Viewpoint usage: `viewpoint` ConstraintUsageDeclaration RequirementBody.
1608#[derive(Debug, Clone, PartialEq, Eq)]
1609pub struct ViewpointUsage {
1610    pub name: String,
1611    pub type_name: String,
1612    pub body: RequirementDefBody,
1613}
1614
1615/// Rendering usage: `rendering` Usage.
1616#[derive(Debug, Clone, PartialEq, Eq)]
1617pub struct RenderingUsage {
1618    pub name: String,
1619    pub type_name: Option<String>,
1620    pub body: ConnectBody,
1621}
1622
1623// ---------------------------------------------------------------------------
1624// Normalization for test comparison (strips optional spans so parsed == expected)
1625// ---------------------------------------------------------------------------
1626
1627impl RootNamespace {
1628    /// Returns a copy with all optional source spans set to `None` and all `Node` spans set to
1629    /// `Span::dummy()`. Use when comparing parser output to hand-built expected AST in tests.
1630    pub fn normalize_for_test_comparison(&self) -> Self {
1631        RootNamespace {
1632            elements: self
1633                .elements
1634                .iter()
1635                .map(normalize_root_element_node)
1636                .collect(),
1637        }
1638    }
1639}
1640
1641fn dummy_node<T: Clone>(_n: &Node<T>, value: T) -> Node<T> {
1642    Node::new(Span::dummy(), value)
1643}
1644
1645fn normalize_root_element_node(el: &Node<RootElement>) -> Node<RootElement> {
1646    let value = match &el.value {
1647        RootElement::Package(p) => RootElement::Package(dummy_node(p, normalize_package(&p.value))),
1648        RootElement::LibraryPackage(lp) => {
1649            RootElement::LibraryPackage(dummy_node(lp, normalize_library_package(&lp.value)))
1650        }
1651        RootElement::Namespace(n) => {
1652            RootElement::Namespace(dummy_node(n, normalize_namespace_decl(&n.value)))
1653        }
1654        RootElement::Import(n) => RootElement::Import(dummy_node(n, n.value.clone())),
1655    };
1656    dummy_node(el, value)
1657}
1658
1659fn normalize_library_package(lp: &LibraryPackage) -> LibraryPackage {
1660    LibraryPackage {
1661        is_standard: lp.is_standard,
1662        identification: lp.identification.clone(),
1663        body: normalize_package_body(&lp.body),
1664    }
1665}
1666
1667fn normalize_namespace_decl(n: &NamespaceDecl) -> NamespaceDecl {
1668    NamespaceDecl {
1669        identification: n.identification.clone(),
1670        body: normalize_package_body(&n.body),
1671    }
1672}
1673
1674fn normalize_package(p: &Package) -> Package {
1675    Package {
1676        identification: p.identification.clone(),
1677        body: normalize_package_body(&p.body),
1678    }
1679}
1680
1681fn normalize_package_body(b: &PackageBody) -> PackageBody {
1682    match b {
1683        PackageBody::Semicolon => PackageBody::Semicolon,
1684        PackageBody::Brace { elements } => PackageBody::Brace {
1685            elements: elements
1686                .iter()
1687                .map(normalize_package_body_element_node)
1688                .collect(),
1689        },
1690    }
1691}
1692
1693fn normalize_package_body_element_node(el: &Node<PackageBodyElement>) -> Node<PackageBodyElement> {
1694    let value = match &el.value {
1695        PackageBodyElement::Error(n) => PackageBodyElement::Error(dummy_node(n, n.value.clone())),
1696        PackageBodyElement::Doc(n) => PackageBodyElement::Doc(dummy_node(n, n.value.clone())),
1697        PackageBodyElement::Comment(n) => {
1698            PackageBodyElement::Comment(dummy_node(n, n.value.clone()))
1699        }
1700        PackageBodyElement::TextualRep(n) => {
1701            PackageBodyElement::TextualRep(dummy_node(n, n.value.clone()))
1702        }
1703        PackageBodyElement::Filter(n) => PackageBodyElement::Filter(dummy_node(n, n.value.clone())),
1704        PackageBodyElement::Package(n) => {
1705            PackageBodyElement::Package(dummy_node(n, normalize_package(&n.value)))
1706        }
1707        PackageBodyElement::LibraryPackage(n) => {
1708            PackageBodyElement::LibraryPackage(dummy_node(n, normalize_library_package(&n.value)))
1709        }
1710        PackageBodyElement::Import(n) => PackageBodyElement::Import(dummy_node(n, n.value.clone())),
1711        PackageBodyElement::PartDef(n) => {
1712            PackageBodyElement::PartDef(dummy_node(n, normalize_part_def(&n.value)))
1713        }
1714        PackageBodyElement::PartUsage(n) => {
1715            PackageBodyElement::PartUsage(dummy_node(n, normalize_part_usage(&n.value)))
1716        }
1717        PackageBodyElement::PortDef(n) => {
1718            PackageBodyElement::PortDef(dummy_node(n, normalize_port_def(&n.value)))
1719        }
1720        PackageBodyElement::InterfaceDef(n) => {
1721            PackageBodyElement::InterfaceDef(dummy_node(n, normalize_interface_def(&n.value)))
1722        }
1723        PackageBodyElement::ConnectionDef(n) => {
1724            PackageBodyElement::ConnectionDef(dummy_node(n, normalize_connection_def(&n.value)))
1725        }
1726        PackageBodyElement::MetadataDef(n) => {
1727            PackageBodyElement::MetadataDef(dummy_node(n, normalize_metadata_def(&n.value)))
1728        }
1729        PackageBodyElement::EnumDef(n) => {
1730            PackageBodyElement::EnumDef(dummy_node(n, normalize_enum_def(&n.value)))
1731        }
1732        PackageBodyElement::OccurrenceDef(n) => {
1733            PackageBodyElement::OccurrenceDef(dummy_node(n, normalize_occurrence_def(&n.value)))
1734        }
1735        PackageBodyElement::OccurrenceUsage(n) => {
1736            PackageBodyElement::OccurrenceUsage(dummy_node(n, n.value.clone()))
1737        }
1738        PackageBodyElement::AliasDef(n) => {
1739            PackageBodyElement::AliasDef(dummy_node(n, n.value.clone()))
1740        }
1741        PackageBodyElement::AttributeDef(n) => {
1742            PackageBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
1743        }
1744        PackageBodyElement::ActionDef(n) => {
1745            PackageBodyElement::ActionDef(dummy_node(n, normalize_action_def(&n.value)))
1746        }
1747        PackageBodyElement::ActionUsage(n) => {
1748            PackageBodyElement::ActionUsage(dummy_node(n, normalize_action_usage(&n.value)))
1749        }
1750        PackageBodyElement::RequirementDef(n) => {
1751            PackageBodyElement::RequirementDef(dummy_node(n, n.value.clone()))
1752        }
1753        PackageBodyElement::RequirementUsage(n) => {
1754            PackageBodyElement::RequirementUsage(dummy_node(n, n.value.clone()))
1755        }
1756        PackageBodyElement::Satisfy(n) => {
1757            PackageBodyElement::Satisfy(dummy_node(n, n.value.clone()))
1758        }
1759        PackageBodyElement::UseCaseDef(n) => {
1760            PackageBodyElement::UseCaseDef(dummy_node(n, n.value.clone()))
1761        }
1762        PackageBodyElement::Actor(n) => PackageBodyElement::Actor(dummy_node(n, n.value.clone())),
1763        PackageBodyElement::StateDef(n) => {
1764            PackageBodyElement::StateDef(dummy_node(n, n.value.clone()))
1765        }
1766        PackageBodyElement::StateUsage(n) => {
1767            PackageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
1768        }
1769        PackageBodyElement::ItemDef(n) => {
1770            PackageBodyElement::ItemDef(dummy_node(n, n.value.clone()))
1771        }
1772        PackageBodyElement::IndividualDef(n) => {
1773            PackageBodyElement::IndividualDef(dummy_node(n, n.value.clone()))
1774        }
1775        PackageBodyElement::ConstraintDef(n) => {
1776            PackageBodyElement::ConstraintDef(dummy_node(n, n.value.clone()))
1777        }
1778        PackageBodyElement::CalcDef(n) => {
1779            PackageBodyElement::CalcDef(dummy_node(n, n.value.clone()))
1780        }
1781        PackageBodyElement::ViewDef(n) => {
1782            PackageBodyElement::ViewDef(dummy_node(n, n.value.clone()))
1783        }
1784        PackageBodyElement::ViewpointDef(n) => {
1785            PackageBodyElement::ViewpointDef(dummy_node(n, n.value.clone()))
1786        }
1787        PackageBodyElement::RenderingDef(n) => {
1788            PackageBodyElement::RenderingDef(dummy_node(n, n.value.clone()))
1789        }
1790        PackageBodyElement::ViewUsage(n) => {
1791            PackageBodyElement::ViewUsage(dummy_node(n, n.value.clone()))
1792        }
1793        PackageBodyElement::ViewpointUsage(n) => {
1794            PackageBodyElement::ViewpointUsage(dummy_node(n, n.value.clone()))
1795        }
1796        PackageBodyElement::RenderingUsage(n) => {
1797            PackageBodyElement::RenderingUsage(dummy_node(n, n.value.clone()))
1798        }
1799        PackageBodyElement::Dependency(n) => {
1800            PackageBodyElement::Dependency(dummy_node(n, n.value.clone()))
1801        }
1802        PackageBodyElement::AllocationDef(n) => {
1803            PackageBodyElement::AllocationDef(dummy_node(n, n.value.clone()))
1804        }
1805        PackageBodyElement::AllocationUsage(n) => {
1806            PackageBodyElement::AllocationUsage(dummy_node(n, n.value.clone()))
1807        }
1808        PackageBodyElement::FlowDef(n) => {
1809            PackageBodyElement::FlowDef(dummy_node(n, n.value.clone()))
1810        }
1811        PackageBodyElement::FlowUsage(n) => {
1812            PackageBodyElement::FlowUsage(dummy_node(n, n.value.clone()))
1813        }
1814        PackageBodyElement::ConcernUsage(n) => {
1815            PackageBodyElement::ConcernUsage(dummy_node(n, n.value.clone()))
1816        }
1817        PackageBodyElement::CaseDef(n) => {
1818            PackageBodyElement::CaseDef(dummy_node(n, n.value.clone()))
1819        }
1820        PackageBodyElement::CaseUsage(n) => {
1821            PackageBodyElement::CaseUsage(dummy_node(n, n.value.clone()))
1822        }
1823        PackageBodyElement::AnalysisCaseDef(n) => {
1824            PackageBodyElement::AnalysisCaseDef(dummy_node(n, n.value.clone()))
1825        }
1826        PackageBodyElement::AnalysisCaseUsage(n) => {
1827            PackageBodyElement::AnalysisCaseUsage(dummy_node(n, n.value.clone()))
1828        }
1829        PackageBodyElement::VerificationCaseDef(n) => {
1830            PackageBodyElement::VerificationCaseDef(dummy_node(n, n.value.clone()))
1831        }
1832        PackageBodyElement::VerificationCaseUsage(n) => {
1833            PackageBodyElement::VerificationCaseUsage(dummy_node(n, n.value.clone()))
1834        }
1835        PackageBodyElement::UseCaseUsage(n) => {
1836            PackageBodyElement::UseCaseUsage(dummy_node(n, n.value.clone()))
1837        }
1838        PackageBodyElement::FeatureDecl(n) => {
1839            PackageBodyElement::FeatureDecl(dummy_node(n, n.value.clone()))
1840        }
1841        PackageBodyElement::ClassifierDecl(n) => {
1842            PackageBodyElement::ClassifierDecl(dummy_node(n, n.value.clone()))
1843        }
1844        PackageBodyElement::KermlSemanticDecl(n) => {
1845            PackageBodyElement::KermlSemanticDecl(dummy_node(n, n.value.clone()))
1846        }
1847        PackageBodyElement::KermlFeatureDecl(n) => {
1848            PackageBodyElement::KermlFeatureDecl(dummy_node(n, n.value.clone()))
1849        }
1850        PackageBodyElement::ExtendedLibraryDecl(n) => {
1851            PackageBodyElement::ExtendedLibraryDecl(dummy_node(n, n.value.clone()))
1852        }
1853    };
1854    dummy_node(el, value)
1855}
1856
1857fn normalize_attribute_def(a: &AttributeDef) -> AttributeDef {
1858    AttributeDef {
1859        name: a.name.clone(),
1860        typing: a.typing.clone(),
1861        body: a.body.clone(),
1862        name_span: None,
1863        typing_span: None,
1864    }
1865}
1866
1867fn normalize_part_def(p: &PartDef) -> PartDef {
1868    PartDef {
1869        definition_prefix: p.definition_prefix.clone(),
1870        is_individual: p.is_individual,
1871        identification: p.identification.clone(),
1872        specializes: p.specializes.clone(),
1873        specializes_span: None,
1874        body: normalize_part_def_body(&p.body),
1875    }
1876}
1877
1878fn normalize_part_def_body(b: &PartDefBody) -> PartDefBody {
1879    match b {
1880        PartDefBody::Semicolon => PartDefBody::Semicolon,
1881        PartDefBody::Brace { elements } => PartDefBody::Brace {
1882            elements: elements
1883                .iter()
1884                .map(normalize_part_def_body_element_node)
1885                .collect(),
1886        },
1887    }
1888}
1889
1890fn normalize_part_def_body_element_node(el: &Node<PartDefBodyElement>) -> Node<PartDefBodyElement> {
1891    let value = match &el.value {
1892        PartDefBodyElement::Error(n) => PartDefBodyElement::Error(dummy_node(n, n.value.clone())),
1893        PartDefBodyElement::Doc(n) => PartDefBodyElement::Doc(dummy_node(n, n.value.clone())),
1894        PartDefBodyElement::Annotation(n) => {
1895            PartDefBodyElement::Annotation(dummy_node(n, n.value.clone()))
1896        }
1897        PartDefBodyElement::Other(text) => PartDefBodyElement::Other(text.clone()),
1898        PartDefBodyElement::AttributeDef(n) => {
1899            PartDefBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
1900        }
1901        PartDefBodyElement::AttributeUsage(n) => {
1902            PartDefBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
1903        }
1904        PartDefBodyElement::RequirementUsage(n) => {
1905            PartDefBodyElement::RequirementUsage(dummy_node(n, n.value.clone()))
1906        }
1907        PartDefBodyElement::Ref(n) => {
1908            PartDefBodyElement::Ref(dummy_node(n, normalize_ref_decl(&n.value)))
1909        }
1910        PartDefBodyElement::PortUsage(n) => {
1911            PartDefBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
1912        }
1913        PartDefBodyElement::PartUsage(n) => {
1914            PartDefBodyElement::PartUsage(Box::new(dummy_node(n, normalize_part_usage(&n.value))))
1915        }
1916        PartDefBodyElement::OccurrenceUsage(n) => {
1917            PartDefBodyElement::OccurrenceUsage(Box::new(dummy_node(n, n.value.clone())))
1918        }
1919        PartDefBodyElement::InterfaceUsage(n) => {
1920            PartDefBodyElement::InterfaceUsage(dummy_node(n, n.value.clone()))
1921        }
1922        PartDefBodyElement::Connect(n) => {
1923            PartDefBodyElement::Connect(dummy_node(n, n.value.clone()))
1924        }
1925        PartDefBodyElement::Perform(n) => {
1926            PartDefBodyElement::Perform(dummy_node(n, n.value.clone()))
1927        }
1928        PartDefBodyElement::Allocate(n) => {
1929            PartDefBodyElement::Allocate(dummy_node(n, n.value.clone()))
1930        }
1931        PartDefBodyElement::OpaqueMember(n) => {
1932            PartDefBodyElement::OpaqueMember(dummy_node(n, n.value.clone()))
1933        }
1934        PartDefBodyElement::ExhibitState(n) => {
1935            PartDefBodyElement::ExhibitState(dummy_node(n, n.value.clone()))
1936        }
1937    };
1938    dummy_node(el, value)
1939}
1940
1941fn normalize_attribute_usage(a: &AttributeUsage) -> AttributeUsage {
1942    AttributeUsage {
1943        name: a.name.clone(),
1944        redefines: a.redefines.clone(),
1945        value: a.value.clone(),
1946        body: a.body.clone(),
1947        name_span: None,
1948        redefines_span: None,
1949    }
1950}
1951
1952fn normalize_part_usage(p: &PartUsage) -> PartUsage {
1953    PartUsage {
1954        is_individual: p.is_individual,
1955        name: p.name.clone(),
1956        type_name: p.type_name.clone(),
1957        multiplicity: p.multiplicity.clone(),
1958        ordered: p.ordered,
1959        subsets: p.subsets.clone(),
1960        redefines: p.redefines.clone(),
1961        value: p.value.clone(),
1962        body: normalize_part_usage_body(&p.body),
1963        name_span: None,
1964        type_ref_span: None,
1965    }
1966}
1967
1968fn normalize_part_usage_body(b: &PartUsageBody) -> PartUsageBody {
1969    match b {
1970        PartUsageBody::Semicolon => PartUsageBody::Semicolon,
1971        PartUsageBody::Brace { elements } => PartUsageBody::Brace {
1972            elements: elements
1973                .iter()
1974                .map(normalize_part_usage_body_element_node)
1975                .collect(),
1976        },
1977    }
1978}
1979
1980fn normalize_perform(p: &Perform) -> Perform {
1981    Perform {
1982        action_name: p.action_name.clone(),
1983        type_name: p.type_name.clone(),
1984        body: normalize_perform_body(&p.body),
1985    }
1986}
1987
1988fn normalize_perform_body(b: &PerformBody) -> PerformBody {
1989    match b {
1990        PerformBody::Semicolon => PerformBody::Semicolon,
1991        PerformBody::Brace { elements } => PerformBody::Brace {
1992            elements: elements
1993                .iter()
1994                .map(normalize_perform_body_element_node)
1995                .collect(),
1996        },
1997    }
1998}
1999
2000fn normalize_perform_body_element_node(el: &Node<PerformBodyElement>) -> Node<PerformBodyElement> {
2001    let value = match &el.value {
2002        PerformBodyElement::Doc(n) => PerformBodyElement::Doc(dummy_node(n, n.value.clone())),
2003        PerformBodyElement::InOut(n) => PerformBodyElement::InOut(dummy_node(
2004            n,
2005            PerformInOutBinding {
2006                direction: n.value.direction,
2007                name: n.value.name.clone(),
2008                value: normalize_expression_node(&n.value.value),
2009            },
2010        )),
2011    };
2012    dummy_node(el, value)
2013}
2014
2015fn normalize_expression_node(node: &Node<Expression>) -> Node<Expression> {
2016    let value = match &node.value {
2017        Expression::LiteralInteger(x) => Expression::LiteralInteger(*x),
2018        Expression::LiteralReal(s) => Expression::LiteralReal(s.clone()),
2019        Expression::LiteralString(s) => Expression::LiteralString(s.clone()),
2020        Expression::LiteralBoolean(b) => Expression::LiteralBoolean(*b),
2021        Expression::FeatureRef(s) => Expression::FeatureRef(s.clone()),
2022        Expression::MemberAccess(base, member) => {
2023            Expression::MemberAccess(Box::new(normalize_expression_node(base)), member.clone())
2024        }
2025        Expression::Index { base, index } => Expression::Index {
2026            base: Box::new(normalize_expression_node(base)),
2027            index: Box::new(normalize_expression_node(index)),
2028        },
2029        Expression::Bracket(inner) => {
2030            Expression::Bracket(Box::new(normalize_expression_node(inner)))
2031        }
2032        Expression::LiteralWithUnit { value: v, unit } => Expression::LiteralWithUnit {
2033            value: Box::new(normalize_expression_node(v)),
2034            unit: Box::new(normalize_expression_node(unit)),
2035        },
2036        Expression::BinaryOp { op, left, right } => Expression::BinaryOp {
2037            op: op.clone(),
2038            left: Box::new(normalize_expression_node(left)),
2039            right: Box::new(normalize_expression_node(right)),
2040        },
2041        Expression::UnaryOp { op, operand } => Expression::UnaryOp {
2042            op: op.clone(),
2043            operand: Box::new(normalize_expression_node(operand)),
2044        },
2045        Expression::Null => Expression::Null,
2046    };
2047    Node::new(Span::dummy(), value)
2048}
2049
2050fn normalize_part_usage_body_element_node(
2051    el: &Node<PartUsageBodyElement>,
2052) -> Node<PartUsageBodyElement> {
2053    let value = match &el.value {
2054        PartUsageBodyElement::Error(n) => {
2055            PartUsageBodyElement::Error(dummy_node(n, n.value.clone()))
2056        }
2057        PartUsageBodyElement::Doc(n) => PartUsageBodyElement::Doc(dummy_node(n, n.value.clone())),
2058        PartUsageBodyElement::Annotation(n) => {
2059            PartUsageBodyElement::Annotation(dummy_node(n, n.value.clone()))
2060        }
2061        PartUsageBodyElement::AttributeUsage(n) => {
2062            PartUsageBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
2063        }
2064        PartUsageBodyElement::PartUsage(n) => {
2065            PartUsageBodyElement::PartUsage(Box::new(dummy_node(n, normalize_part_usage(&n.value))))
2066        }
2067        PartUsageBodyElement::OccurrenceUsage(n) => {
2068            PartUsageBodyElement::OccurrenceUsage(Box::new(dummy_node(n, n.value.clone())))
2069        }
2070        PartUsageBodyElement::PortUsage(n) => {
2071            PartUsageBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
2072        }
2073        PartUsageBodyElement::Ref(n) => {
2074            PartUsageBodyElement::Ref(dummy_node(n, normalize_ref_decl(&n.value)))
2075        }
2076        PartUsageBodyElement::Bind(n) => PartUsageBodyElement::Bind(dummy_node(n, n.value.clone())),
2077        PartUsageBodyElement::InterfaceUsage(n) => {
2078            PartUsageBodyElement::InterfaceUsage(dummy_node(n, n.value.clone()))
2079        }
2080        PartUsageBodyElement::Connect(n) => {
2081            PartUsageBodyElement::Connect(dummy_node(n, n.value.clone()))
2082        }
2083        PartUsageBodyElement::Perform(n) => {
2084            PartUsageBodyElement::Perform(dummy_node(n, normalize_perform(&n.value)))
2085        }
2086        PartUsageBodyElement::Allocate(n) => {
2087            PartUsageBodyElement::Allocate(dummy_node(n, n.value.clone()))
2088        }
2089        PartUsageBodyElement::Satisfy(n) => {
2090            PartUsageBodyElement::Satisfy(dummy_node(n, n.value.clone()))
2091        }
2092        PartUsageBodyElement::StateUsage(n) => {
2093            PartUsageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
2094        }
2095        PartUsageBodyElement::MetadataAnnotation(n) => {
2096            PartUsageBodyElement::MetadataAnnotation(dummy_node(n, n.value.clone()))
2097        }
2098    };
2099    dummy_node(el, value)
2100}
2101
2102fn normalize_port_usage(p: &PortUsage) -> PortUsage {
2103    PortUsage {
2104        name: p.name.clone(),
2105        type_name: p.type_name.clone(),
2106        multiplicity: p.multiplicity.clone(),
2107        subsets: p.subsets.clone(),
2108        redefines: p.redefines.clone(),
2109        body: normalize_port_body(&p.body),
2110        name_span: None,
2111        type_ref_span: None,
2112    }
2113}
2114
2115fn normalize_port_body(b: &PortBody) -> PortBody {
2116    match b {
2117        PortBody::Semicolon => PortBody::Semicolon,
2118        PortBody::Brace => PortBody::Brace,
2119        PortBody::BraceWithPorts { elements } => PortBody::BraceWithPorts {
2120            elements: elements
2121                .iter()
2122                .map(|n| dummy_node(n, normalize_port_usage(&n.value)))
2123                .collect(),
2124        },
2125    }
2126}
2127
2128fn normalize_port_def(p: &PortDef) -> PortDef {
2129    PortDef {
2130        identification: p.identification.clone(),
2131        specializes: p.specializes.clone(),
2132        body: normalize_port_def_body(&p.body),
2133    }
2134}
2135
2136fn normalize_port_def_body(b: &PortDefBody) -> PortDefBody {
2137    match b {
2138        PortDefBody::Semicolon => PortDefBody::Semicolon,
2139        PortDefBody::Brace { elements } => PortDefBody::Brace {
2140            elements: elements
2141                .iter()
2142                .map(normalize_port_def_body_element_node)
2143                .collect(),
2144        },
2145    }
2146}
2147
2148fn normalize_port_def_body_element_node(el: &Node<PortDefBodyElement>) -> Node<PortDefBodyElement> {
2149    let value = match &el.value {
2150        PortDefBodyElement::InOutDecl(n) => {
2151            PortDefBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
2152        }
2153        PortDefBodyElement::Doc(n) => PortDefBodyElement::Doc(dummy_node(n, n.value.clone())),
2154        PortDefBodyElement::AttributeDef(n) => {
2155            PortDefBodyElement::AttributeDef(dummy_node(n, normalize_attribute_def(&n.value)))
2156        }
2157        PortDefBodyElement::AttributeUsage(n) => {
2158            PortDefBodyElement::AttributeUsage(dummy_node(n, normalize_attribute_usage(&n.value)))
2159        }
2160        PortDefBodyElement::PortUsage(n) => {
2161            PortDefBodyElement::PortUsage(dummy_node(n, normalize_port_usage(&n.value)))
2162        }
2163    };
2164    dummy_node(el, value)
2165}
2166
2167fn normalize_interface_def(i: &InterfaceDef) -> InterfaceDef {
2168    InterfaceDef {
2169        identification: i.identification.clone(),
2170        body: normalize_interface_def_body(&i.body),
2171    }
2172}
2173
2174fn normalize_connection_def(c: &ConnectionDef) -> ConnectionDef {
2175    ConnectionDef {
2176        identification: c.identification.clone(),
2177        body: normalize_connection_def_body(&c.body),
2178    }
2179}
2180
2181fn normalize_connection_def_body(b: &ConnectionDefBody) -> ConnectionDefBody {
2182    match b {
2183        ConnectionDefBody::Semicolon => ConnectionDefBody::Semicolon,
2184        ConnectionDefBody::Brace { elements } => ConnectionDefBody::Brace {
2185            elements: elements
2186                .iter()
2187                .map(normalize_connection_def_body_element_node)
2188                .collect(),
2189        },
2190    }
2191}
2192
2193fn normalize_connection_def_body_element_node(
2194    el: &Node<ConnectionDefBodyElement>,
2195) -> Node<ConnectionDefBodyElement> {
2196    let value = match &el.value {
2197        ConnectionDefBodyElement::EndDecl(n) => {
2198            ConnectionDefBodyElement::EndDecl(dummy_node(n, normalize_end_decl(&n.value)))
2199        }
2200        ConnectionDefBodyElement::RefDecl(n) => {
2201            ConnectionDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
2202        }
2203        ConnectionDefBodyElement::ConnectStmt(n) => {
2204            ConnectionDefBodyElement::ConnectStmt(dummy_node(n, n.value.clone()))
2205        }
2206    };
2207    dummy_node(el, value)
2208}
2209
2210fn normalize_metadata_def(m: &MetadataDef) -> MetadataDef {
2211    MetadataDef {
2212        is_abstract: m.is_abstract,
2213        identification: m.identification.clone(),
2214        body: m.body.clone(),
2215    }
2216}
2217
2218fn normalize_enum_def(e: &EnumDef) -> EnumDef {
2219    EnumDef {
2220        identification: e.identification.clone(),
2221        body: e.body.clone(),
2222    }
2223}
2224
2225fn normalize_occurrence_def(o: &OccurrenceDef) -> OccurrenceDef {
2226    OccurrenceDef {
2227        is_abstract: o.is_abstract,
2228        identification: o.identification.clone(),
2229        body: o.body.clone(),
2230    }
2231}
2232
2233fn normalize_interface_def_body(b: &InterfaceDefBody) -> InterfaceDefBody {
2234    match b {
2235        InterfaceDefBody::Semicolon => InterfaceDefBody::Semicolon,
2236        InterfaceDefBody::Brace { elements } => InterfaceDefBody::Brace {
2237            elements: elements
2238                .iter()
2239                .map(normalize_interface_def_body_element_node)
2240                .collect(),
2241        },
2242    }
2243}
2244
2245fn normalize_interface_def_body_element_node(
2246    el: &Node<InterfaceDefBodyElement>,
2247) -> Node<InterfaceDefBodyElement> {
2248    let value = match &el.value {
2249        InterfaceDefBodyElement::Doc(n) => {
2250            InterfaceDefBodyElement::Doc(dummy_node(n, n.value.clone()))
2251        }
2252        InterfaceDefBodyElement::EndDecl(n) => {
2253            InterfaceDefBodyElement::EndDecl(dummy_node(n, normalize_end_decl(&n.value)))
2254        }
2255        InterfaceDefBodyElement::RefDecl(n) => {
2256            InterfaceDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
2257        }
2258        InterfaceDefBodyElement::ConnectStmt(n) => {
2259            InterfaceDefBodyElement::ConnectStmt(dummy_node(n, n.value.clone()))
2260        }
2261    };
2262    dummy_node(el, value)
2263}
2264
2265fn normalize_end_decl(e: &EndDecl) -> EndDecl {
2266    EndDecl {
2267        name: e.name.clone(),
2268        type_name: e.type_name.clone(),
2269        name_span: None,
2270        type_ref_span: None,
2271    }
2272}
2273
2274fn normalize_ref_decl(r: &RefDecl) -> RefDecl {
2275    RefDecl {
2276        name: r.name.clone(),
2277        type_name: r.type_name.clone(),
2278        value: r.value.clone(),
2279        body: r.body.clone(),
2280        name_span: None,
2281        type_ref_span: None,
2282    }
2283}
2284
2285fn normalize_action_def(a: &ActionDef) -> ActionDef {
2286    ActionDef {
2287        identification: a.identification.clone(),
2288        body: normalize_action_def_body(&a.body),
2289    }
2290}
2291
2292fn normalize_action_def_body(b: &ActionDefBody) -> ActionDefBody {
2293    match b {
2294        ActionDefBody::Semicolon => ActionDefBody::Semicolon,
2295        ActionDefBody::Brace { elements } => ActionDefBody::Brace {
2296            elements: elements
2297                .iter()
2298                .map(normalize_action_def_body_element_node)
2299                .collect(),
2300        },
2301    }
2302}
2303
2304fn normalize_action_def_body_element_node(
2305    el: &Node<ActionDefBodyElement>,
2306) -> Node<ActionDefBodyElement> {
2307    let value = match &el.value {
2308        ActionDefBodyElement::Error(n) => {
2309            ActionDefBodyElement::Error(dummy_node(n, n.value.clone()))
2310        }
2311        ActionDefBodyElement::InOutDecl(n) => {
2312            ActionDefBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
2313        }
2314        ActionDefBodyElement::Doc(n) => ActionDefBodyElement::Doc(dummy_node(n, n.value.clone())),
2315        ActionDefBodyElement::Annotation(n) => {
2316            ActionDefBodyElement::Annotation(dummy_node(n, n.value.clone()))
2317        }
2318        ActionDefBodyElement::RefDecl(n) => {
2319            ActionDefBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
2320        }
2321        ActionDefBodyElement::Perform(n) => {
2322            ActionDefBodyElement::Perform(dummy_node(n, normalize_perform(&n.value)))
2323        }
2324        ActionDefBodyElement::Bind(n) => ActionDefBodyElement::Bind(dummy_node(n, n.value.clone())),
2325        ActionDefBodyElement::Flow(n) => ActionDefBodyElement::Flow(dummy_node(n, n.value.clone())),
2326        ActionDefBodyElement::FirstStmt(n) => {
2327            ActionDefBodyElement::FirstStmt(dummy_node(n, n.value.clone()))
2328        }
2329        ActionDefBodyElement::MergeStmt(n) => {
2330            ActionDefBodyElement::MergeStmt(dummy_node(n, n.value.clone()))
2331        }
2332        ActionDefBodyElement::StateUsage(n) => {
2333            ActionDefBodyElement::StateUsage(dummy_node(n, n.value.clone()))
2334        }
2335        ActionDefBodyElement::ActionUsage(n) => ActionDefBodyElement::ActionUsage(Box::new(
2336            dummy_node(n, normalize_action_usage(&n.value)),
2337        )),
2338        ActionDefBodyElement::Assign(n) => {
2339            ActionDefBodyElement::Assign(dummy_node(n, n.value.clone()))
2340        }
2341        ActionDefBodyElement::ForLoop(n) => {
2342            ActionDefBodyElement::ForLoop(dummy_node(n, n.value.clone()))
2343        }
2344        ActionDefBodyElement::ThenAction(n) => {
2345            ActionDefBodyElement::ThenAction(dummy_node(n, n.value.clone()))
2346        }
2347        ActionDefBodyElement::Decl(n) => ActionDefBodyElement::Decl(dummy_node(n, n.value.clone())),
2348    };
2349    dummy_node(el, value)
2350}
2351
2352fn normalize_action_usage(a: &ActionUsage) -> ActionUsage {
2353    ActionUsage {
2354        name: a.name.clone(),
2355        type_name: a.type_name.clone(),
2356        accept: a.accept.clone(),
2357        body: normalize_action_usage_body(&a.body),
2358        name_span: None,
2359        type_ref_span: None,
2360    }
2361}
2362
2363fn normalize_action_usage_body(b: &ActionUsageBody) -> ActionUsageBody {
2364    match b {
2365        ActionUsageBody::Semicolon => ActionUsageBody::Semicolon,
2366        ActionUsageBody::Brace { elements } => ActionUsageBody::Brace {
2367            elements: elements
2368                .iter()
2369                .map(normalize_action_usage_body_element_node)
2370                .collect(),
2371        },
2372    }
2373}
2374
2375fn normalize_action_usage_body_element_node(
2376    el: &Node<ActionUsageBodyElement>,
2377) -> Node<ActionUsageBodyElement> {
2378    let value = match &el.value {
2379        ActionUsageBodyElement::Error(n) => {
2380            ActionUsageBodyElement::Error(dummy_node(n, n.value.clone()))
2381        }
2382        ActionUsageBodyElement::Doc(n) => {
2383            ActionUsageBodyElement::Doc(dummy_node(n, n.value.clone()))
2384        }
2385        ActionUsageBodyElement::Annotation(n) => {
2386            ActionUsageBodyElement::Annotation(dummy_node(n, n.value.clone()))
2387        }
2388        ActionUsageBodyElement::InOutDecl(n) => {
2389            ActionUsageBodyElement::InOutDecl(dummy_node(n, n.value.clone()))
2390        }
2391        ActionUsageBodyElement::RefDecl(n) => {
2392            ActionUsageBodyElement::RefDecl(dummy_node(n, normalize_ref_decl(&n.value)))
2393        }
2394        ActionUsageBodyElement::Bind(n) => {
2395            ActionUsageBodyElement::Bind(dummy_node(n, n.value.clone()))
2396        }
2397        ActionUsageBodyElement::Flow(n) => {
2398            ActionUsageBodyElement::Flow(dummy_node(n, n.value.clone()))
2399        }
2400        ActionUsageBodyElement::FirstStmt(n) => {
2401            ActionUsageBodyElement::FirstStmt(dummy_node(n, n.value.clone()))
2402        }
2403        ActionUsageBodyElement::MergeStmt(n) => {
2404            ActionUsageBodyElement::MergeStmt(dummy_node(n, n.value.clone()))
2405        }
2406        ActionUsageBodyElement::StateUsage(n) => {
2407            ActionUsageBodyElement::StateUsage(dummy_node(n, n.value.clone()))
2408        }
2409        ActionUsageBodyElement::ActionUsage(n) => ActionUsageBodyElement::ActionUsage(Box::new(
2410            dummy_node(n, normalize_action_usage(&n.value)),
2411        )),
2412        ActionUsageBodyElement::Assign(n) => {
2413            ActionUsageBodyElement::Assign(dummy_node(n, n.value.clone()))
2414        }
2415        ActionUsageBodyElement::ForLoop(n) => {
2416            ActionUsageBodyElement::ForLoop(dummy_node(n, n.value.clone()))
2417        }
2418        ActionUsageBodyElement::ThenAction(n) => {
2419            ActionUsageBodyElement::ThenAction(dummy_node(n, n.value.clone()))
2420        }
2421        ActionUsageBodyElement::Decl(n) => {
2422            ActionUsageBodyElement::Decl(dummy_node(n, n.value.clone()))
2423        }
2424    };
2425    dummy_node(el, value)
2426}