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>)>, 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>)>, 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>)>, 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>)>, 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>>, 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);