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