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