planus_types/
cst.rs

1use codespan::{ByteIndex, Span};
2use lalrpop_util::ErrorRecovery;
3use planus_lexer::{LexicalError, TokenMetadata, TokenWithMetadata};
4
5#[derive(Clone, Debug, Eq, PartialEq)]
6pub struct ParseError<'input> {
7    pub span: Span,
8    pub inner_error: ErrorRecovery<codespan::ByteIndex, TokenWithMetadata<'input>, LexicalError>,
9}
10
11#[derive(Clone, Debug)]
12pub struct Schema<'input> {
13    pub span: Span,
14    pub declarations: Vec<Declaration<'input>>,
15    pub end_of_stream: SimpleToken<'input>,
16}
17
18#[derive(Clone, Debug)]
19pub struct Declaration<'input> {
20    pub span: Span,
21    pub kind: DeclarationKind<'input>,
22}
23
24#[derive(Clone, Debug)]
25#[allow(clippy::large_enum_variant)]
26pub enum DeclarationKind<'input> {
27    Include(IncludeDeclaration<'input>),
28    NativeInclude(NativeIncludeDeclaration<'input>),
29    Namespace(NamespaceDeclaration<'input>),
30    Attribute(AttributeDeclaration<'input>),
31    Table(TableDeclaration<'input>),
32    Struct(StructDeclaration<'input>),
33    Enum(EnumDeclaration<'input>),
34    Union(UnionDeclaration<'input>),
35    RootType(RootTypeDeclaration<'input>),
36    RpcService(RpcServiceDeclaration<'input>),
37    FileExtension(FileExtensionDeclaration<'input>),
38    FileIdentifier(FileIdentifierDeclaration<'input>),
39    Invalid(ErrorRecovery<ByteIndex, TokenWithMetadata<'input>, LexicalError>),
40}
41
42#[derive(Clone, Debug)]
43pub struct IncludeDeclaration<'input> {
44    pub keyword: SimpleToken<'input>,
45    pub path: StringLiteral<'input>,
46    pub semicolon: SimpleToken<'input>,
47}
48
49#[derive(Clone, Debug)]
50pub struct NativeIncludeDeclaration<'input> {
51    pub keyword: SimpleToken<'input>,
52    pub path: StringLiteral<'input>,
53    pub semicolon: SimpleToken<'input>,
54}
55
56#[derive(Clone, Debug)]
57pub struct NamespaceDeclaration<'input> {
58    pub keyword: SimpleToken<'input>,
59    pub namespace: NamespacePath<'input>,
60    pub semicolon: SimpleToken<'input>,
61}
62
63#[derive(Clone, Debug)]
64pub struct AttributeDeclaration<'input> {
65    pub keyword: SimpleToken<'input>,
66    pub attribute: AttributeKind<'input>,
67    pub semicolon: SimpleToken<'input>,
68}
69
70#[derive(Clone, Debug)]
71pub enum AttributeKind<'input> {
72    Ident(IdentToken<'input>),
73    String(StringLiteral<'input>),
74}
75
76#[derive(Clone, Debug)]
77pub struct TableDeclaration<'input> {
78    pub keyword: SimpleToken<'input>,
79    pub ident: IdentToken<'input>,
80    pub metadata: Option<Metadata<'input>>,
81    pub start_brace: SimpleToken<'input>,
82    pub fields: Vec<FieldDeclaration<'input>>,
83    pub end_brace: SimpleToken<'input>,
84}
85
86#[derive(Clone, Debug)]
87pub struct StructDeclaration<'input> {
88    pub keyword: SimpleToken<'input>,
89    pub ident: IdentToken<'input>,
90    pub metadata: Option<Metadata<'input>>,
91    pub start_brace: SimpleToken<'input>,
92    pub fields: Vec<FieldDeclaration<'input>>,
93    pub end_brace: SimpleToken<'input>,
94}
95
96#[derive(Clone, Debug)]
97pub struct EnumDeclaration<'input> {
98    pub keyword: SimpleToken<'input>,
99    pub ident: IdentToken<'input>,
100    pub type_: Option<(SimpleToken<'input>, Type<'input>)>,
101    pub metadata: Option<Metadata<'input>>,
102    pub start_brace: SimpleToken<'input>,
103    pub declarations: Vec<EnumValDeclaration<'input>>,
104    pub end_brace: SimpleToken<'input>,
105}
106
107#[derive(Clone, Debug)]
108pub struct UnionDeclaration<'input> {
109    pub keyword: SimpleToken<'input>,
110    pub ident: IdentToken<'input>,
111    pub metadata: Option<Metadata<'input>>,
112    pub start_brace: SimpleToken<'input>,
113    pub declarations: Vec<UnionValDeclaration<'input>>,
114    pub end_brace: SimpleToken<'input>,
115}
116
117#[derive(Clone, Debug)]
118pub struct RootTypeDeclaration<'input> {
119    pub keyword: SimpleToken<'input>,
120    pub root_type: Type<'input>,
121    pub semicolon: SimpleToken<'input>,
122}
123
124#[derive(Clone, Debug)]
125pub struct RpcServiceDeclaration<'input> {
126    pub keyword: SimpleToken<'input>,
127    pub ident: IdentToken<'input>,
128    pub start_brace: SimpleToken<'input>,
129    pub methods: Vec<RpcMethod<'input>>,
130    pub end_brace: SimpleToken<'input>,
131}
132
133#[derive(Clone, Debug)]
134pub struct RpcMethod<'input> {
135    pub span: Span,
136    pub ident: IdentToken<'input>,
137    pub start_paren: SimpleToken<'input>,
138    pub argument_type: Type<'input>,
139    pub end_paren: SimpleToken<'input>,
140    pub colon: SimpleToken<'input>,
141    pub return_type: Type<'input>,
142    pub metadata: Option<Metadata<'input>>,
143    pub semicolon: SimpleToken<'input>,
144}
145
146#[derive(Clone, Debug)]
147pub struct FileExtensionDeclaration<'input> {
148    pub keyword: SimpleToken<'input>,
149    pub file_extension: StringLiteral<'input>,
150    pub semicolon: SimpleToken<'input>,
151}
152
153#[derive(Clone, Debug)]
154pub struct FileIdentifierDeclaration<'input> {
155    pub keyword: SimpleToken<'input>,
156    pub file_identifier: StringLiteral<'input>,
157    pub semicolon: SimpleToken<'input>,
158}
159
160#[derive(Clone, Debug)]
161pub struct Metadata<'input> {
162    pub span: Span,
163    pub start_paren: SimpleToken<'input>,
164    pub values: Vec<MetadataValue<'input>>,
165    pub end_paren: SimpleToken<'input>,
166}
167
168#[derive(Clone, Debug)]
169pub struct MetadataValue<'input> {
170    pub span: Span,
171    pub key: IdentToken<'input>,
172    pub assignment: Option<(SimpleToken<'input>, Expr<'input>)>, // the token is the '='
173    pub comma: Option<SimpleToken<'input>>,
174}
175
176#[derive(Clone, Debug)]
177pub struct FieldDeclaration<'input> {
178    pub span: Span,
179    pub ident: IdentToken<'input>,
180    pub colon: SimpleToken<'input>,
181    pub type_: Type<'input>,
182    pub assignment: Option<(SimpleToken<'input>, Expr<'input>)>, // the token is the '='
183    pub metadata: Option<Metadata<'input>>,
184    pub semicolon: SimpleToken<'input>,
185}
186
187#[derive(Clone, Debug)]
188pub struct EnumValDeclaration<'input> {
189    pub span: Span,
190    pub ident: IdentToken<'input>,
191    pub assignment: Option<(SimpleToken<'input>, Expr<'input>)>, // the token is the '='
192    pub comma: Option<SimpleToken<'input>>,
193}
194
195#[derive(Clone, Debug)]
196pub struct UnionValDeclaration<'input> {
197    pub span: Span,
198    pub name: Option<(IdentToken<'input>, SimpleToken<'input>)>, // the token is the ':'
199    pub type_: Type<'input>,
200    pub comma: Option<SimpleToken<'input>>,
201}
202
203#[derive(Clone, Debug)]
204pub struct Type<'input> {
205    pub span: Span,
206    pub kind: TypeKind<'input>,
207}
208
209#[derive(Clone, Debug)]
210#[allow(clippy::large_enum_variant)]
211pub enum TypeKind<'input> {
212    Vector(VectorType<'input>),
213    Array(ArrayType<'input>),
214    Path(NamespacePath<'input>),
215}
216
217#[derive(Clone, Debug)]
218pub struct VectorType<'input> {
219    pub span: Span,
220    pub start_bracket: SimpleToken<'input>,
221    pub inner_type: Box<Type<'input>>,
222    pub end_bracket: SimpleToken<'input>,
223}
224
225#[derive(Clone, Debug)]
226pub struct ArrayType<'input> {
227    pub span: Span,
228    pub start_bracket: SimpleToken<'input>,
229    pub inner_type: Box<Type<'input>>,
230    pub colon: SimpleToken<'input>,
231    pub size: Expr<'input>,
232    pub end_bracket: SimpleToken<'input>,
233}
234
235#[derive(Clone, Debug)]
236pub struct Expr<'input> {
237    pub span: Span,
238    pub kind: ExprKind<'input>,
239}
240
241#[derive(Clone, Debug)]
242pub enum ExprKind<'input> {
243    Ident(IdentToken<'input>),
244    Integer(IntegerLiteral<'input>),
245    Float(FloatLiteral<'input>),
246    String(StringLiteral<'input>),
247    List(ListLiteral<'input>),
248    Signed {
249        sign: Sign<'input>,
250        inner: Box<Expr<'input>>,
251    },
252}
253
254#[derive(Clone, Debug)]
255pub struct Sign<'input> {
256    pub span: Span,
257    pub token: SimpleToken<'input>,
258    pub is_negative: bool,
259}
260
261#[derive(Clone, Debug)]
262pub struct IdentToken<'input> {
263    pub span: Span,
264    pub token_metadata: TokenMetadata<'input>,
265    pub ident: &'input str,
266}
267
268#[derive(Clone, Debug)]
269pub struct IntegerLiteral<'input> {
270    pub span: Span,
271    pub token_metadata: TokenMetadata<'input>,
272    pub value: &'input str,
273}
274
275#[derive(Clone, Debug)]
276pub struct FloatLiteral<'input> {
277    pub span: Span,
278    pub token_metadata: TokenMetadata<'input>,
279    pub value: &'input str,
280}
281
282#[derive(Clone, Debug)]
283pub struct StringLiteral<'input> {
284    pub span: Span,
285    pub token_metadata: TokenMetadata<'input>,
286    pub value: String,
287}
288
289#[derive(Clone, Debug)]
290pub struct ListLiteral<'input> {
291    pub span: Span,
292    pub start_bracket: SimpleToken<'input>,
293    pub values: Vec<ListLiteralValue<'input>>, // the SimpleToken is the comma
294    pub end_bracket: SimpleToken<'input>,
295}
296
297#[derive(Clone, Debug)]
298pub struct ListLiteralValue<'input> {
299    pub span: Span,
300    pub expr: Expr<'input>,
301    pub comma: Option<SimpleToken<'input>>,
302}
303
304#[derive(Clone, Debug)]
305pub struct SimpleToken<'input> {
306    pub span: Span,
307    pub token_metadata: TokenMetadata<'input>,
308}
309
310#[derive(Clone, Debug)]
311pub struct NamespacePath<'input> {
312    pub span: Span,
313    pub initial_segments: Vec<NamespacePathSegment<'input>>,
314    pub final_segment: IdentToken<'input>,
315}
316
317impl<'input> AttributeKind<'input> {
318    pub fn token_meta<'a>(&'a self) -> &'a TokenMetadata<'input> {
319        match self {
320            AttributeKind::Ident(ident) => &ident.token_metadata,
321            AttributeKind::String(string) => &string.token_metadata,
322        }
323    }
324}
325
326impl<'input> Metadata<'input> {
327    pub fn token_metas<'a>(&'a self) -> impl Iterator<Item = &'a TokenMetadata<'input>> {
328        std::iter::once(&self.start_paren.token_metadata)
329            .chain(self.values.iter().flat_map(|value| value.token_metas()))
330            .chain([&self.end_paren.token_metadata])
331    }
332}
333
334impl<'input> MetadataValue<'input> {
335    pub fn token_metas<'a>(&'a self) -> impl Iterator<Item = &'a TokenMetadata<'input>> {
336        std::iter::once(&self.key.token_metadata)
337            .chain(self.assignment.iter().flat_map(|(equals, expr)| {
338                std::iter::once(&equals.token_metadata).chain(expr.kind.token_metas())
339            }))
340            .chain(self.comma.as_ref().map(|token| &token.token_metadata))
341    }
342}
343
344mod token_metadata_iterator {
345    use super::*;
346
347    pub(super) enum Node<'a, 'input> {
348        Direct(&'a TokenMetadata<'input>),
349        Expr(&'a ExprKind<'input>),
350        Type(&'a TypeKind<'input>),
351    }
352
353    pub(super) struct Iter<'a, 'input> {
354        queue: Vec<Node<'a, 'input>>,
355    }
356
357    impl<'a, 'input> Iter<'a, 'input> {
358        pub(super) fn new(initial: Node<'a, 'input>) -> Self {
359            Self {
360                queue: vec![initial],
361            }
362        }
363    }
364
365    impl<'a, 'input> Iterator for Iter<'a, 'input> {
366        type Item = &'a TokenMetadata<'input>;
367
368        fn next(&mut self) -> Option<Self::Item> {
369            Some(match self.queue.pop()? {
370                Node::Direct(token_metadata) => token_metadata,
371                Node::Expr(ExprKind::Ident(tok)) => &tok.token_metadata,
372                Node::Expr(ExprKind::Integer(tok)) => &tok.token_metadata,
373                Node::Expr(ExprKind::Float(tok)) => &tok.token_metadata,
374                Node::Expr(ExprKind::String(tok)) => &tok.token_metadata,
375                Node::Expr(ExprKind::List(literal)) => {
376                    self.queue
377                        .push(Node::Direct(&literal.end_bracket.token_metadata));
378                    for value in literal.values.iter().rev() {
379                        if let Some(comma) = &value.comma {
380                            self.queue.push(Node::Direct(&comma.token_metadata));
381                        }
382                        self.queue.push(Node::Expr(&value.expr.kind));
383                    }
384                    &literal.start_bracket.token_metadata
385                }
386                Node::Expr(ExprKind::Signed { sign, inner }) => {
387                    self.queue.push(Node::Expr(&inner.kind));
388                    &sign.token.token_metadata
389                }
390                Node::Type(TypeKind::Vector(typ)) => {
391                    self.queue
392                        .push(Node::Direct(&typ.end_bracket.token_metadata));
393                    self.queue.push(Node::Type(&typ.inner_type.kind));
394                    &typ.start_bracket.token_metadata
395                }
396                Node::Type(TypeKind::Array(typ)) => {
397                    self.queue
398                        .push(Node::Direct(&typ.end_bracket.token_metadata));
399                    self.queue.push(Node::Expr(&typ.size.kind));
400                    self.queue.push(Node::Direct(&typ.colon.token_metadata));
401                    self.queue.push(Node::Type(&typ.inner_type.kind));
402                    &typ.start_bracket.token_metadata
403                }
404                Node::Type(TypeKind::Path(typ)) => {
405                    let mut result = &typ.final_segment.token_metadata;
406                    for segment in typ.initial_segments.iter().rev() {
407                        self.queue.push(Node::Direct(result));
408                        self.queue
409                            .push(Node::Direct(&segment.period.token_metadata));
410                        result = &segment.ident.token_metadata;
411                    }
412                    result
413                }
414            })
415        }
416    }
417}
418
419impl<'input> ExprKind<'input> {
420    pub fn token_metas<'a>(&'a self) -> impl Iterator<Item = &'a TokenMetadata<'input>> {
421        token_metadata_iterator::Iter::new(token_metadata_iterator::Node::Expr(self))
422    }
423}
424
425impl<'input> TypeKind<'input> {
426    pub fn token_metas<'a>(&'a self) -> impl Iterator<Item = &'a TokenMetadata<'input>> {
427        token_metadata_iterator::Iter::new(token_metadata_iterator::Node::Type(self))
428    }
429}
430
431impl<'input> NamespacePath<'input> {
432    pub fn token_metas<'a>(&'a self) -> impl Iterator<Item = &'a TokenMetadata<'input>> {
433        self.initial_segments
434            .iter()
435            .flat_map(|segment| {
436                [
437                    &segment.ident.token_metadata,
438                    &segment.period.token_metadata,
439                ]
440            })
441            .chain([&self.final_segment.token_metadata])
442    }
443}
444
445#[derive(Clone, Debug)]
446pub struct NamespacePathSegment<'input> {
447    pub span: Span,
448    pub ident: IdentToken<'input>,
449    pub period: SimpleToken<'input>,
450}
451
452pub trait CstNode {
453    fn span(&self) -> Span;
454}
455
456macro_rules! cst_node {
457    ($t:ident) => {
458        impl<'input> CstNode for $t<'input> {
459            fn span(&self) -> Span {
460                self.span
461            }
462        }
463    };
464}
465
466cst_node!(Schema);
467cst_node!(Declaration);
468cst_node!(RpcMethod);
469cst_node!(Metadata);
470cst_node!(MetadataValue);
471cst_node!(FieldDeclaration);
472cst_node!(EnumValDeclaration);
473cst_node!(UnionValDeclaration);
474cst_node!(Type);
475cst_node!(VectorType);
476cst_node!(ArrayType);
477cst_node!(Expr);
478cst_node!(Sign);
479cst_node!(IntegerLiteral);
480cst_node!(FloatLiteral);
481cst_node!(StringLiteral);
482cst_node!(ListLiteral);
483cst_node!(ListLiteralValue);
484cst_node!(SimpleToken);
485cst_node!(IdentToken);
486cst_node!(NamespacePath);
487cst_node!(NamespacePathSegment);