Skip to main content

wac_parser/ast/
type.rs

1use super::{
2    parse_delimited, parse_optional, parse_optional_payload, parse_token, DocComment, Error, Ident,
3    Lookahead, PackagePath, Parse, ParseResult, Peek,
4};
5use crate::lexer::{Lexer, Token};
6use miette::SourceSpan;
7use serde::Serialize;
8
9/// Represents a type statement in the AST.
10#[derive(Debug, Clone, Serialize)]
11#[serde(rename_all = "camelCase")]
12pub enum TypeStatement<'a> {
13    /// The statement is for an interface declaration.
14    Interface(InterfaceDecl<'a>),
15    /// The statement is for a world declaration.
16    World(WorldDecl<'a>),
17    /// The statement is for a type declaration.
18    Type(TypeDecl<'a>),
19}
20
21impl<'a> Parse<'a> for TypeStatement<'a> {
22    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
23        let mut lookahead = Lookahead::new(lexer);
24        if InterfaceDecl::peek(&mut lookahead) {
25            Ok(Self::Interface(Parse::parse(lexer)?))
26        } else if WorldDecl::peek(&mut lookahead) {
27            Ok(Self::World(Parse::parse(lexer)?))
28        } else if TypeDecl::peek(&mut lookahead) {
29            Ok(Self::Type(Parse::parse(lexer)?))
30        } else {
31            Err(lookahead.error())
32        }
33    }
34}
35
36impl Peek for TypeStatement<'_> {
37    fn peek(lookahead: &mut Lookahead) -> bool {
38        lookahead.peek(Token::InterfaceKeyword)
39            || lookahead.peek(Token::WorldKeyword)
40            || TypeDecl::peek(lookahead)
41    }
42}
43
44/// Represents a top-level type declaration in the AST.
45///
46/// Unlike tin interfaces and worlds, resources cannot
47/// be declared at the top-level.
48#[derive(Debug, Clone, Serialize)]
49#[serde(rename_all = "camelCase")]
50pub enum TypeDecl<'a> {
51    /// The declaration is for a variant.
52    Variant(VariantDecl<'a>),
53    /// The declaration is for a record.
54    Record(RecordDecl<'a>),
55    /// The declaration is for a flags.
56    Flags(FlagsDecl<'a>),
57    /// The declaration is for an enum.
58    Enum(EnumDecl<'a>),
59    /// The declaration is for a type alias.
60    Alias(TypeAlias<'a>),
61}
62
63impl TypeDecl<'_> {
64    /// Gets the identifier of the type being declared.
65    pub fn id(&self) -> &Ident<'_> {
66        match self {
67            Self::Variant(variant) => &variant.id,
68            Self::Record(record) => &record.id,
69            Self::Flags(flags) => &flags.id,
70            Self::Enum(e) => &e.id,
71            Self::Alias(alias) => &alias.id,
72        }
73    }
74}
75
76impl<'a> Parse<'a> for TypeDecl<'a> {
77    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
78        let mut lookahead = Lookahead::new(lexer);
79        if lookahead.peek(Token::VariantKeyword) {
80            Ok(Self::Variant(Parse::parse(lexer)?))
81        } else if lookahead.peek(Token::RecordKeyword) {
82            Ok(Self::Record(Parse::parse(lexer)?))
83        } else if lookahead.peek(Token::FlagsKeyword) {
84            Ok(Self::Flags(Parse::parse(lexer)?))
85        } else if lookahead.peek(Token::EnumKeyword) {
86            Ok(Self::Enum(Parse::parse(lexer)?))
87        } else if lookahead.peek(Token::TypeKeyword) {
88            Ok(Self::Alias(Parse::parse(lexer)?))
89        } else {
90            Err(lookahead.error())
91        }
92    }
93}
94
95impl Peek for TypeDecl<'_> {
96    fn peek(lookahead: &mut Lookahead) -> bool {
97        lookahead.peek(Token::VariantKeyword)
98            || lookahead.peek(Token::RecordKeyword)
99            || lookahead.peek(Token::FlagsKeyword)
100            || lookahead.peek(Token::EnumKeyword)
101            || lookahead.peek(Token::TypeKeyword)
102    }
103}
104
105/// Represents a resource declaration in the AST.
106#[derive(Debug, Clone, Serialize)]
107#[serde(rename_all = "camelCase")]
108pub struct ResourceDecl<'a> {
109    /// The doc comments for the resource.
110    pub docs: Vec<DocComment<'a>>,
111    /// The identifier of the resource.
112    pub id: Ident<'a>,
113    /// The methods of the resource.
114    pub methods: Vec<ResourceMethod<'a>>,
115}
116
117impl<'a> Parse<'a> for ResourceDecl<'a> {
118    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
119        let docs = Parse::parse(lexer)?;
120        parse_token(lexer, Token::ResourceKeyword)?;
121        let id = Ident::parse(lexer)?;
122        let mut lookahead = Lookahead::new(lexer);
123        let methods = if lookahead.peek(Token::Semicolon) {
124            lexer.next();
125            Default::default()
126        } else if lookahead.peek(Token::OpenBrace) {
127            parse_token(lexer, Token::OpenBrace)?;
128            let methods = parse_delimited(lexer, Token::CloseBrace, false)?;
129            parse_token(lexer, Token::CloseBrace)?;
130            methods
131        } else {
132            return Err(lookahead.error());
133        };
134
135        Ok(Self { docs, id, methods })
136    }
137}
138
139/// Represents a variant declaration in the AST.
140#[derive(Debug, Clone, Serialize)]
141#[serde(rename_all = "camelCase")]
142pub struct VariantDecl<'a> {
143    /// The doc comments for the variant.
144    pub docs: Vec<DocComment<'a>>,
145    /// The identifier of the variant.
146    pub id: Ident<'a>,
147    /// The cases of the variant.
148    pub cases: Vec<VariantCase<'a>>,
149}
150
151impl<'a> Parse<'a> for VariantDecl<'a> {
152    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
153        let docs = Parse::parse(lexer)?;
154        parse_token(lexer, Token::VariantKeyword)?;
155        let id = Ident::parse(lexer)?;
156        parse_token(lexer, Token::OpenBrace)?;
157        let cases = parse_delimited(lexer, Token::CloseBrace, true)?;
158        let close = parse_token(lexer, Token::CloseBrace)?;
159
160        if cases.is_empty() {
161            return Err(Error::EmptyType {
162                ty: "variant",
163                kind: "case",
164                span: close,
165            });
166        }
167
168        Ok(Self { docs, id, cases })
169    }
170}
171
172/// Represents a variant case in the AST.
173#[derive(Debug, Clone, Serialize)]
174#[serde(rename_all = "camelCase")]
175pub struct VariantCase<'a> {
176    /// The doc comments for the case.
177    pub docs: Vec<DocComment<'a>>,
178    /// The identifier of the case.
179    pub id: Ident<'a>,
180    /// The type of the case.
181    pub ty: Option<Type<'a>>,
182}
183
184impl<'a> Parse<'a> for VariantCase<'a> {
185    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
186        let docs = Parse::parse(lexer)?;
187        let id = Ident::parse(lexer)?;
188        let ty = parse_optional(lexer, Token::OpenParen, |lexer| {
189            let ty = Parse::parse(lexer)?;
190            parse_token(lexer, Token::CloseParen)?;
191            Ok(ty)
192        })?;
193        Ok(Self { docs, id, ty })
194    }
195}
196
197impl Peek for VariantCase<'_> {
198    fn peek(lookahead: &mut Lookahead) -> bool {
199        lookahead.peek(Token::Ident)
200    }
201}
202
203/// Represents a record declaration in the AST.
204#[derive(Debug, Clone, Serialize)]
205#[serde(rename_all = "camelCase")]
206pub struct RecordDecl<'a> {
207    /// The doc comments for the record.
208    pub docs: Vec<DocComment<'a>>,
209    /// The identifier of the record.
210    pub id: Ident<'a>,
211    /// The fields of the record.
212    pub fields: Vec<Field<'a>>,
213}
214
215impl<'a> Parse<'a> for RecordDecl<'a> {
216    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
217        let docs = Parse::parse(lexer)?;
218        parse_token(lexer, Token::RecordKeyword)?;
219        let id = Ident::parse(lexer)?;
220        parse_token(lexer, Token::OpenBrace)?;
221        let fields = parse_delimited(lexer, Token::CloseBrace, true)?;
222        let close = parse_token(lexer, Token::CloseBrace)?;
223
224        if fields.is_empty() {
225            return Err(Error::EmptyType {
226                ty: "record",
227                kind: "field",
228                span: close,
229            });
230        }
231
232        Ok(Self { docs, id, fields })
233    }
234}
235
236/// Represents a record field in the AST.
237#[derive(Debug, Clone, Serialize)]
238#[serde(rename_all = "camelCase")]
239pub struct Field<'a> {
240    /// The docs for the field.
241    pub docs: Vec<DocComment<'a>>,
242    /// The identifier of the field.
243    pub id: Ident<'a>,
244    /// The type of the field.
245    pub ty: Type<'a>,
246}
247
248impl<'a> Parse<'a> for Field<'a> {
249    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
250        let docs = Parse::parse(lexer)?;
251        let named: NamedType = Parse::parse(lexer)?;
252        Ok(Self {
253            docs,
254            id: named.id,
255            ty: named.ty,
256        })
257    }
258}
259
260impl Peek for Field<'_> {
261    fn peek(lookahead: &mut Lookahead) -> bool {
262        NamedType::peek(lookahead)
263    }
264}
265
266/// Represents a flags declaration in the AST.
267#[derive(Debug, Clone, Serialize)]
268#[serde(rename_all = "camelCase")]
269pub struct FlagsDecl<'a> {
270    /// The doc comments for the flags.
271    pub docs: Vec<DocComment<'a>>,
272    /// The identifier of the flags.
273    pub id: Ident<'a>,
274    /// The flag values.
275    pub flags: Vec<Flag<'a>>,
276}
277
278impl<'a> Parse<'a> for FlagsDecl<'a> {
279    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
280        let docs = Parse::parse(lexer)?;
281        parse_token(lexer, Token::FlagsKeyword)?;
282        let id = Ident::parse(lexer)?;
283        parse_token(lexer, Token::OpenBrace)?;
284        let flags = parse_delimited(lexer, Token::CloseBrace, true)?;
285        let close = parse_token(lexer, Token::CloseBrace)?;
286
287        if flags.is_empty() {
288            return Err(Error::EmptyType {
289                ty: "flags",
290                kind: "flag",
291                span: close,
292            });
293        }
294
295        Ok(Self { docs, id, flags })
296    }
297}
298
299/// Represents a flag in the AST.
300#[derive(Debug, Clone, Serialize)]
301#[serde(rename_all = "camelCase")]
302pub struct Flag<'a> {
303    /// The doc comments for the flag.
304    pub docs: Vec<DocComment<'a>>,
305    /// The identifier of the flag.
306    pub id: Ident<'a>,
307}
308
309impl<'a> Parse<'a> for Flag<'a> {
310    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
311        let docs = Parse::parse(lexer)?;
312        let id = Ident::parse(lexer)?;
313        Ok(Self { docs, id })
314    }
315}
316
317impl Peek for Flag<'_> {
318    fn peek(lookahead: &mut Lookahead) -> bool {
319        lookahead.peek(Token::Ident)
320    }
321}
322
323/// Represents an enum declaration in the AST.
324#[derive(Debug, Clone, Serialize)]
325#[serde(rename_all = "camelCase")]
326pub struct EnumDecl<'a> {
327    /// The doc comments for the enum.
328    pub docs: Vec<DocComment<'a>>,
329    /// The identifier of the enum.
330    pub id: Ident<'a>,
331    /// The cases of the enum.
332    pub cases: Vec<EnumCase<'a>>,
333}
334
335impl<'a> Parse<'a> for EnumDecl<'a> {
336    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
337        let docs = Parse::parse(lexer)?;
338        parse_token(lexer, Token::EnumKeyword)?;
339        let id = Ident::parse(lexer)?;
340        parse_token(lexer, Token::OpenBrace)?;
341        let cases = parse_delimited(lexer, Token::CloseBrace, true)?;
342        let close = parse_token(lexer, Token::CloseBrace)?;
343
344        if cases.is_empty() {
345            return Err(Error::EmptyType {
346                ty: "enum",
347                kind: "case",
348                span: close,
349            });
350        }
351
352        Ok(Self { docs, id, cases })
353    }
354}
355
356/// Represents an enum case in the AST.
357#[derive(Debug, Clone, Serialize)]
358#[serde(rename_all = "camelCase")]
359pub struct EnumCase<'a> {
360    /// The doc comments for the enum case.
361    pub docs: Vec<DocComment<'a>>,
362    /// The identifier of the enum case.
363    pub id: Ident<'a>,
364}
365
366impl<'a> Parse<'a> for EnumCase<'a> {
367    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
368        let docs = Parse::parse(lexer)?;
369        let id = Ident::parse(lexer)?;
370        Ok(Self { docs, id })
371    }
372}
373
374impl Peek for EnumCase<'_> {
375    fn peek(lookahead: &mut Lookahead) -> bool {
376        lookahead.peek(Token::Ident)
377    }
378}
379
380/// Represents a resource method in the AST.
381#[derive(Debug, Clone, Serialize)]
382#[serde(rename_all = "camelCase")]
383pub enum ResourceMethod<'a> {
384    /// The method is a constructor.
385    Constructor(Constructor<'a>),
386    /// The method is a instance or static method.
387    Method(Method<'a>),
388}
389
390impl<'a> Parse<'a> for ResourceMethod<'a> {
391    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
392        let mut lookahead = Lookahead::new(lexer);
393        if lookahead.peek(Token::ConstructorKeyword) {
394            Ok(Self::Constructor(Parse::parse(lexer)?))
395        } else if Ident::peek(&mut lookahead) {
396            Ok(Self::Method(Parse::parse(lexer)?))
397        } else {
398            Err(lookahead.error())
399        }
400    }
401}
402
403impl Peek for ResourceMethod<'_> {
404    fn peek(lookahead: &mut Lookahead) -> bool {
405        lookahead.peek(Token::ConstructorKeyword) || Ident::peek(lookahead)
406    }
407}
408
409/// Represents a resource constructor in the AST.
410#[derive(Debug, Clone, Serialize)]
411#[serde(rename_all = "camelCase")]
412pub struct Constructor<'a> {
413    /// The doc comments for the constructor.
414    pub docs: Vec<DocComment<'a>>,
415    /// The span of the constructor keyword.
416    pub span: SourceSpan,
417    /// The parameters of the constructor.
418    pub params: Vec<NamedType<'a>>,
419}
420
421impl<'a> Parse<'a> for Constructor<'a> {
422    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
423        let docs = Parse::parse(lexer)?;
424        let span = parse_token(lexer, Token::ConstructorKeyword)?;
425        parse_token(lexer, Token::OpenParen)?;
426        let params = parse_delimited(lexer, Token::CloseParen, true)?;
427        parse_token(lexer, Token::CloseParen)?;
428        parse_token(lexer, Token::Semicolon)?;
429        Ok(Self { docs, span, params })
430    }
431}
432
433/// Represents a resource method in the AST.
434#[derive(Debug, Clone, Serialize)]
435#[serde(rename_all = "camelCase")]
436pub struct Method<'a> {
437    /// The doc comments for the method.
438    pub docs: Vec<DocComment<'a>>,
439    /// The identifier of the method.
440    pub id: Ident<'a>,
441    /// Wether or not the method is static.
442    pub is_static: bool,
443    /// The function type of the method.
444    pub ty: FuncType<'a>,
445}
446
447impl<'a> Parse<'a> for Method<'a> {
448    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
449        let docs = Parse::parse(lexer)?;
450        let id = Ident::parse(lexer)?;
451        parse_token(lexer, Token::Colon)?;
452        let is_static = lexer
453            .peek()
454            .map(|(r, _)| matches!(r, Ok(Token::StaticKeyword)))
455            .unwrap_or(false);
456
457        if is_static {
458            lexer.next();
459        }
460
461        let ty = Parse::parse(lexer)?;
462        parse_token(lexer, Token::Semicolon)?;
463        Ok(Self {
464            docs,
465            id,
466            is_static,
467            ty,
468        })
469    }
470}
471
472/// Represents a function type reference in the AST.
473#[derive(Debug, Clone, Serialize)]
474#[serde(rename_all = "camelCase")]
475pub enum FuncTypeRef<'a> {
476    /// The reference is a function type.
477    Func(FuncType<'a>),
478    /// The reference is an identifier to a function type.
479    Ident(Ident<'a>),
480}
481
482impl<'a> Parse<'a> for FuncTypeRef<'a> {
483    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
484        let mut lookahead = Lookahead::new(lexer);
485        if lookahead.peek(Token::AsyncKeyword) || lookahead.peek(Token::FuncKeyword) {
486            Ok(Self::Func(Parse::parse(lexer)?))
487        } else if Ident::peek(&mut lookahead) {
488            Ok(Self::Ident(Parse::parse(lexer)?))
489        } else {
490            Err(lookahead.error())
491        }
492    }
493}
494
495/// Represents a function type in the AST.
496#[derive(Debug, Clone, Serialize)]
497#[serde(rename_all = "camelCase")]
498pub struct FuncType<'a> {
499    /// Whether the function is async.
500    pub is_async: bool,
501    /// The parameters of the function.
502    pub params: Vec<NamedType<'a>>,
503    /// The results of the function.
504    pub results: ResultList<'a>,
505}
506
507impl<'a> Parse<'a> for FuncType<'a> {
508    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
509        let is_async = parse_optional(lexer, Token::AsyncKeyword, |_| Ok(()))?.is_some();
510        parse_token(lexer, Token::FuncKeyword)?;
511        parse_token(lexer, Token::OpenParen)?;
512        let params = parse_delimited(lexer, Token::CloseParen, true)?;
513        parse_token(lexer, Token::CloseParen)?;
514        let results =
515            parse_optional(lexer, Token::Arrow, Parse::parse)?.unwrap_or(ResultList::Empty);
516
517        Ok(Self {
518            is_async,
519            params,
520            results,
521        })
522    }
523}
524
525impl Peek for FuncType<'_> {
526    fn peek(lookahead: &mut Lookahead) -> bool {
527        lookahead.peek(Token::AsyncKeyword) || lookahead.peek(Token::FuncKeyword)
528    }
529}
530
531/// Represents a result list in the AST.
532#[derive(Debug, Clone, Serialize)]
533#[serde(rename_all = "camelCase")]
534pub enum ResultList<'a> {
535    /// The function has no results.
536    Empty,
537    /// The function returns a scalar value.
538    Scalar(Type<'a>),
539}
540
541impl<'a> Parse<'a> for ResultList<'a> {
542    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
543        let mut lookahead = Lookahead::new(lexer);
544        if Type::peek(&mut lookahead) {
545            Ok(Self::Scalar(Parse::parse(lexer)?))
546        } else {
547            Ok(Self::Empty)
548        }
549    }
550}
551
552/// Represents a name and an associated type in the AST.
553#[derive(Debug, Clone, Serialize)]
554#[serde(rename_all = "camelCase")]
555pub struct NamedType<'a> {
556    /// The identifier of the type.
557    pub id: Ident<'a>,
558    /// The type.
559    pub ty: Type<'a>,
560}
561
562impl<'a> Parse<'a> for NamedType<'a> {
563    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
564        let id = Ident::parse(lexer)?;
565        parse_token(lexer, Token::Colon)?;
566        let ty = Parse::parse(lexer)?;
567        Ok(Self { id, ty })
568    }
569}
570
571impl Peek for NamedType<'_> {
572    fn peek(lookahead: &mut Lookahead) -> bool {
573        Ident::peek(lookahead)
574    }
575}
576
577/// Represents a type alias in the AST.
578#[derive(Debug, Clone, Serialize)]
579#[serde(rename_all = "camelCase")]
580pub struct TypeAlias<'a> {
581    /// The docs for the type alias.
582    pub docs: Vec<DocComment<'a>>,
583    /// The identifier of the type alias.
584    pub id: Ident<'a>,
585    /// The kind of type alias.
586    pub kind: TypeAliasKind<'a>,
587}
588
589impl<'a> Parse<'a> for TypeAlias<'a> {
590    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
591        let docs = Parse::parse(lexer)?;
592        parse_token(lexer, Token::TypeKeyword)?;
593        let id = Ident::parse(lexer)?;
594        parse_token(lexer, Token::Equals)?;
595        let kind = Parse::parse(lexer)?;
596        parse_token(lexer, Token::Semicolon)?;
597        Ok(Self { docs, id, kind })
598    }
599}
600
601/// Represents a type alias kind in the AST.
602#[derive(Debug, Clone, Serialize)]
603#[serde(rename_all = "camelCase")]
604pub enum TypeAliasKind<'a> {
605    /// The alias is to a function type.
606    Func(FuncType<'a>),
607    /// The alias is to another type.
608    Type(Type<'a>),
609}
610
611impl<'a> Parse<'a> for TypeAliasKind<'a> {
612    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
613        let mut lookahead = Lookahead::new(lexer);
614        if lookahead.peek(Token::AsyncKeyword) || lookahead.peek(Token::FuncKeyword) {
615            Ok(Self::Func(Parse::parse(lexer)?))
616        } else if Type::peek(&mut lookahead) {
617            Ok(Self::Type(Parse::parse(lexer)?))
618        } else {
619            Err(lookahead.error())
620        }
621    }
622}
623
624/// Represents a type in the AST.
625#[derive(Debug, Clone, Serialize)]
626#[serde(rename_all = "camelCase")]
627pub enum Type<'a> {
628    /// A `u8` type.
629    U8(SourceSpan),
630    /// A `s8` type.
631    S8(SourceSpan),
632    /// A `u16` type.
633    U16(SourceSpan),
634    /// A `s16` type.
635    S16(SourceSpan),
636    /// A `u32` type.
637    U32(SourceSpan),
638    /// A `s32` type.
639    S32(SourceSpan),
640    /// A `u64` type.
641    U64(SourceSpan),
642    /// A `s64` type.
643    S64(SourceSpan),
644    /// A `f32` type.
645    F32(SourceSpan),
646    /// A `f64` type.
647    F64(SourceSpan),
648    /// A `char` type.
649    Char(SourceSpan),
650    /// A `bool` type.
651    Bool(SourceSpan),
652    /// A `string` type.
653    String(SourceSpan),
654    /// A tuple type.
655    Tuple(Vec<Type<'a>>, SourceSpan),
656    /// A list type.
657    List(Box<Type<'a>>, SourceSpan),
658    /// An option type.
659    Option(Box<Type<'a>>, SourceSpan),
660    /// A result type.
661    Result {
662        /// The `ok` of the result type.
663        ok: Option<Box<Type<'a>>>,
664        /// The `err` of the result type.
665        err: Option<Box<Type<'a>>>,
666        /// The span of the result type.
667        span: SourceSpan,
668    },
669    /// A borrow type.
670    Borrow(Ident<'a>, SourceSpan),
671    /// A stream type.
672    Stream(Option<Box<Type<'a>>>, SourceSpan),
673    /// A future type.
674    Future(Option<Box<Type<'a>>>, SourceSpan),
675    /// An error-context type.
676    ErrorContext(SourceSpan),
677    /// An identifier to a value type.
678    Ident(Ident<'a>),
679}
680
681impl Type<'_> {
682    /// Gets the span of the type.
683    pub fn span(&self) -> SourceSpan {
684        match self {
685            Self::U8(span)
686            | Self::S8(span)
687            | Self::U16(span)
688            | Self::S16(span)
689            | Self::U32(span)
690            | Self::S32(span)
691            | Self::U64(span)
692            | Self::S64(span)
693            | Self::F32(span)
694            | Self::F64(span)
695            | Self::Char(span)
696            | Self::Bool(span)
697            | Self::String(span)
698            | Self::Tuple(_, span)
699            | Self::List(_, span)
700            | Self::Option(_, span)
701            | Self::Result { span, .. }
702            | Self::Borrow(_, span)
703            | Self::Stream(_, span)
704            | Self::Future(_, span)
705            | Self::ErrorContext(span) => *span,
706            Self::Ident(ident) => ident.span,
707        }
708    }
709}
710
711impl<'a> Parse<'a> for Type<'a> {
712    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
713        let mut lookahead = Lookahead::new(lexer);
714        if lookahead.peek(Token::U8Keyword) {
715            Ok(Self::U8(lexer.next().unwrap().1))
716        } else if lookahead.peek(Token::S8Keyword) {
717            Ok(Self::S8(lexer.next().unwrap().1))
718        } else if lookahead.peek(Token::U16Keyword) {
719            Ok(Self::U16(lexer.next().unwrap().1))
720        } else if lookahead.peek(Token::S16Keyword) {
721            Ok(Self::S16(lexer.next().unwrap().1))
722        } else if lookahead.peek(Token::U32Keyword) {
723            Ok(Self::U32(lexer.next().unwrap().1))
724        } else if lookahead.peek(Token::S32Keyword) {
725            Ok(Self::S32(lexer.next().unwrap().1))
726        } else if lookahead.peek(Token::U64Keyword) {
727            Ok(Self::U64(lexer.next().unwrap().1))
728        } else if lookahead.peek(Token::S64Keyword) {
729            Ok(Self::S64(lexer.next().unwrap().1))
730        } else if lookahead.peek(Token::F32Keyword) {
731            Ok(Self::F32(lexer.next().unwrap().1))
732        } else if lookahead.peek(Token::F64Keyword) {
733            Ok(Self::F64(lexer.next().unwrap().1))
734        } else if lookahead.peek(Token::CharKeyword) {
735            Ok(Self::Char(lexer.next().unwrap().1))
736        } else if lookahead.peek(Token::BoolKeyword) {
737            Ok(Self::Bool(lexer.next().unwrap().1))
738        } else if lookahead.peek(Token::StringKeyword) {
739            Ok(Self::String(lexer.next().unwrap().1))
740        } else if lookahead.peek(Token::TupleKeyword) {
741            let span = lexer.next().unwrap().1;
742            parse_token(lexer, Token::OpenAngle)?;
743
744            // There must be at least one type in the tuple.
745            let mut lookahead = Lookahead::new(lexer);
746            if !Type::peek(&mut lookahead) {
747                return Err(lookahead.error());
748            }
749
750            let types = parse_delimited(lexer, Token::CloseAngle, true)?;
751            assert!(!types.is_empty());
752            let close = parse_token(lexer, Token::CloseAngle)?;
753            Ok(Self::Tuple(
754                types,
755                SourceSpan::new(
756                    span.offset().into(),
757                    (close.offset() + close.len()) - span.offset(),
758                ),
759            ))
760        } else if lookahead.peek(Token::ListKeyword) {
761            let span = lexer.next().unwrap().1;
762            parse_token(lexer, Token::OpenAngle)?;
763            let ty = Box::new(Parse::parse(lexer)?);
764            let close = parse_token(lexer, Token::CloseAngle)?;
765            Ok(Self::List(
766                ty,
767                SourceSpan::new(
768                    span.offset().into(),
769                    (close.offset() + close.len()) - span.offset(),
770                ),
771            ))
772        } else if lookahead.peek(Token::OptionKeyword) {
773            let span = lexer.next().unwrap().1;
774            parse_token(lexer, Token::OpenAngle)?;
775            let ty = Box::new(Parse::parse(lexer)?);
776            let close = parse_token(lexer, Token::CloseAngle)?;
777            Ok(Self::Option(
778                ty,
779                SourceSpan::new(
780                    span.offset().into(),
781                    (close.offset() + close.len()) - span.offset(),
782                ),
783            ))
784        } else if lookahead.peek(Token::ResultKeyword) {
785            let mut span = lexer.next().unwrap().1;
786
787            let parse = |lexer: &mut Lexer<'a>| {
788                let mut lookahead = Lookahead::new(lexer);
789                let ok = if lookahead.peek(Token::Underscore) {
790                    lexer.next();
791                    None
792                } else if Type::peek(&mut lookahead) {
793                    Some(Box::new(Parse::parse(lexer)?))
794                } else {
795                    return Err(lookahead.error());
796                };
797
798                let err = parse_optional(lexer, Token::Comma, |lexer| {
799                    let mut lookahead = Lookahead::new(lexer);
800                    if lookahead.peek(Token::Underscore) {
801                        lexer.next();
802                        Ok(None)
803                    } else if Type::peek(&mut lookahead) {
804                        Ok(Some(Box::new(Parse::parse(lexer)?)))
805                    } else {
806                        Err(lookahead.error())
807                    }
808                })?
809                .unwrap_or(None);
810
811                let close = parse_token(lexer, Token::CloseAngle)?;
812                span = SourceSpan::new(
813                    span.offset().into(),
814                    (close.offset() + close.len()) - span.offset(),
815                );
816                Ok((ok, err))
817            };
818
819            let (ok, err) = match parse_optional(lexer, Token::OpenAngle, parse)? {
820                Some((ok, err)) => (ok, err),
821                None => (None, None),
822            };
823            Ok(Self::Result { ok, err, span })
824        } else if lookahead.peek(Token::BorrowKeyword) {
825            let span = lexer.next().unwrap().1;
826            parse_token(lexer, Token::OpenAngle)?;
827            let id = Parse::parse(lexer)?;
828            let close = parse_token(lexer, Token::CloseAngle)?;
829            Ok(Self::Borrow(
830                id,
831                SourceSpan::new(
832                    span.offset().into(),
833                    (close.offset() + close.len()) - span.offset(),
834                ),
835            ))
836        } else if lookahead.peek(Token::StreamKeyword) {
837            parse_optional_payload(lexer, Self::Stream)
838        } else if lookahead.peek(Token::FutureKeyword) {
839            parse_optional_payload(lexer, Self::Future)
840        } else if lookahead.peek(Token::ErrorContextKeyword) {
841            Ok(Self::ErrorContext(lexer.next().unwrap().1))
842        } else if Ident::peek(&mut lookahead) {
843            Ok(Self::Ident(Parse::parse(lexer)?))
844        } else {
845            Err(lookahead.error())
846        }
847    }
848}
849
850impl Peek for Type<'_> {
851    fn peek(lookahead: &mut Lookahead) -> bool {
852        lookahead.peek(Token::U8Keyword)
853            || lookahead.peek(Token::S8Keyword)
854            || lookahead.peek(Token::U16Keyword)
855            || lookahead.peek(Token::S16Keyword)
856            || lookahead.peek(Token::U32Keyword)
857            || lookahead.peek(Token::S32Keyword)
858            || lookahead.peek(Token::U64Keyword)
859            || lookahead.peek(Token::S64Keyword)
860            || lookahead.peek(Token::F32Keyword)
861            || lookahead.peek(Token::F64Keyword)
862            || lookahead.peek(Token::CharKeyword)
863            || lookahead.peek(Token::BoolKeyword)
864            || lookahead.peek(Token::StringKeyword)
865            || lookahead.peek(Token::TupleKeyword)
866            || lookahead.peek(Token::ListKeyword)
867            || lookahead.peek(Token::OptionKeyword)
868            || lookahead.peek(Token::ResultKeyword)
869            || lookahead.peek(Token::BorrowKeyword)
870            || lookahead.peek(Token::StreamKeyword)
871            || lookahead.peek(Token::FutureKeyword)
872            || lookahead.peek(Token::ErrorContextKeyword)
873            || Ident::peek(lookahead)
874    }
875}
876
877/// Represents an interface or world type declaration in the AST.
878///
879/// Unlike top-level type declarations, interfaces and worlds can
880/// also declare resources.
881#[derive(Debug, Clone, Serialize)]
882#[serde(rename_all = "camelCase")]
883pub enum ItemTypeDecl<'a> {
884    /// The declaration is for a resource.
885    Resource(ResourceDecl<'a>),
886    /// The declaration is for a variant.
887    Variant(VariantDecl<'a>),
888    /// The declaration is for a record.
889    Record(RecordDecl<'a>),
890    /// The declaration is for a flags.
891    Flags(FlagsDecl<'a>),
892    /// The declaration is for an enum.
893    Enum(EnumDecl<'a>),
894    /// The declaration is for a type alias.
895    Alias(TypeAlias<'a>),
896}
897
898impl<'a> Parse<'a> for ItemTypeDecl<'a> {
899    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
900        let mut lookahead = Lookahead::new(lexer);
901        if lookahead.peek(Token::ResourceKeyword) {
902            Ok(Self::Resource(Parse::parse(lexer)?))
903        } else if lookahead.peek(Token::VariantKeyword) {
904            Ok(Self::Variant(Parse::parse(lexer)?))
905        } else if lookahead.peek(Token::RecordKeyword) {
906            Ok(Self::Record(Parse::parse(lexer)?))
907        } else if lookahead.peek(Token::FlagsKeyword) {
908            Ok(Self::Flags(Parse::parse(lexer)?))
909        } else if lookahead.peek(Token::EnumKeyword) {
910            Ok(Self::Enum(Parse::parse(lexer)?))
911        } else if lookahead.peek(Token::TypeKeyword) {
912            Ok(Self::Alias(Parse::parse(lexer)?))
913        } else {
914            Err(lookahead.error())
915        }
916    }
917}
918
919impl Peek for ItemTypeDecl<'_> {
920    fn peek(lookahead: &mut Lookahead) -> bool {
921        lookahead.peek(Token::ResourceKeyword)
922            || lookahead.peek(Token::VariantKeyword)
923            || lookahead.peek(Token::RecordKeyword)
924            || lookahead.peek(Token::FlagsKeyword)
925            || lookahead.peek(Token::EnumKeyword)
926            || lookahead.peek(Token::TypeKeyword)
927    }
928}
929
930impl ItemTypeDecl<'_> {
931    /// Gets the identifier of the type being declared.
932    pub fn id(&self) -> &Ident<'_> {
933        match self {
934            Self::Resource(resource) => &resource.id,
935            Self::Variant(variant) => &variant.id,
936            Self::Record(record) => &record.id,
937            Self::Flags(flags) => &flags.id,
938            Self::Enum(e) => &e.id,
939            Self::Alias(alias) => &alias.id,
940        }
941    }
942}
943
944/// Represents an interface declaration in the AST.
945#[derive(Debug, Clone, Serialize)]
946#[serde(rename_all = "camelCase")]
947pub struct InterfaceDecl<'a> {
948    /// The doc comments for the interface.
949    pub docs: Vec<DocComment<'a>>,
950    /// The identifier of the interface.
951    pub id: Ident<'a>,
952    /// The items of the interface.
953    pub items: Vec<InterfaceItem<'a>>,
954}
955
956impl<'a> Parse<'a> for InterfaceDecl<'a> {
957    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
958        let docs = Parse::parse(lexer)?;
959        parse_token(lexer, Token::InterfaceKeyword)?;
960        let id = Ident::parse(lexer)?;
961        parse_token(lexer, Token::OpenBrace)?;
962        let items = parse_delimited(lexer, Token::CloseBrace, false)?;
963        parse_token(lexer, Token::CloseBrace)?;
964        Ok(Self { docs, id, items })
965    }
966}
967
968impl Peek for InterfaceDecl<'_> {
969    fn peek(lookahead: &mut Lookahead) -> bool {
970        lookahead.peek(Token::InterfaceKeyword)
971    }
972}
973
974/// Represents an interface item in the AST.
975#[derive(Debug, Clone, Serialize)]
976#[serde(rename_all = "camelCase")]
977pub enum InterfaceItem<'a> {
978    /// The item is a use of other types.
979    Use(Box<Use<'a>>),
980    /// The item is a type declaration.
981    Type(ItemTypeDecl<'a>),
982    /// The item is an interface export.
983    Export(InterfaceExport<'a>),
984}
985
986impl<'a> Parse<'a> for InterfaceItem<'a> {
987    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
988        let mut lookahead = Lookahead::new(lexer);
989        if Use::peek(&mut lookahead) {
990            Ok(Self::Use(Box::new(Parse::parse(lexer)?)))
991        } else if InterfaceExport::peek(&mut lookahead) {
992            Ok(Self::Export(Parse::parse(lexer)?))
993        } else if ItemTypeDecl::peek(&mut lookahead) {
994            Ok(Self::Type(Parse::parse(lexer)?))
995        } else {
996            Err(lookahead.error())
997        }
998    }
999}
1000
1001impl Peek for InterfaceItem<'_> {
1002    fn peek(lookahead: &mut Lookahead) -> bool {
1003        Use::peek(lookahead) || InterfaceExport::peek(lookahead) || ItemTypeDecl::peek(lookahead)
1004    }
1005}
1006
1007/// Represents a "use" in the AST.
1008#[derive(Debug, Clone, Serialize)]
1009#[serde(rename_all = "camelCase")]
1010pub struct Use<'a> {
1011    /// The doc comments for the use.
1012    pub docs: Vec<DocComment<'a>>,
1013    /// The path to the interface or world being used.
1014    pub path: UsePath<'a>,
1015    /// The items being used.
1016    pub items: Vec<UseItem<'a>>,
1017}
1018
1019impl<'a> Parse<'a> for Use<'a> {
1020    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1021        let docs = Parse::parse(lexer)?;
1022        parse_token(lexer, Token::UseKeyword)?;
1023        let path = Parse::parse(lexer)?;
1024        parse_token(lexer, Token::Dot)?;
1025        parse_token(lexer, Token::OpenBrace)?;
1026        let items = parse_delimited(lexer, Token::CloseBrace, true)?;
1027        parse_token(lexer, Token::CloseBrace)?;
1028        parse_token(lexer, Token::Semicolon)?;
1029        Ok(Self { docs, path, items })
1030    }
1031}
1032
1033impl Peek for Use<'_> {
1034    fn peek(lookahead: &mut Lookahead) -> bool {
1035        lookahead.peek(Token::UseKeyword)
1036    }
1037}
1038
1039/// Represents a use path in the AST.
1040#[derive(Debug, Clone, Serialize)]
1041#[serde(rename_all = "camelCase")]
1042pub enum UsePath<'a> {
1043    /// The path is a package path.
1044    Package(PackagePath<'a>),
1045    /// The path is an identifier.
1046    Ident(Ident<'a>),
1047}
1048
1049impl<'a> Parse<'a> for UsePath<'a> {
1050    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1051        let mut lookahead = Lookahead::new(lexer);
1052        if PackagePath::peek(&mut lookahead) {
1053            Ok(Self::Package(Parse::parse(lexer)?))
1054        } else if Ident::peek(&mut lookahead) {
1055            Ok(Self::Ident(Parse::parse(lexer)?))
1056        } else {
1057            Err(lookahead.error())
1058        }
1059    }
1060}
1061
1062impl Peek for UsePath<'_> {
1063    fn peek(lookahead: &mut Lookahead) -> bool {
1064        PackagePath::peek(lookahead) | Ident::peek(lookahead)
1065    }
1066}
1067
1068/// Represents a use item in the AST.
1069#[derive(Debug, Clone, Serialize)]
1070#[serde(rename_all = "camelCase")]
1071pub struct UseItem<'a> {
1072    /// The identifier of the item.
1073    pub id: Ident<'a>,
1074    /// The optional `as` identifier of the item.
1075    pub as_id: Option<Ident<'a>>,
1076}
1077
1078impl<'a> Parse<'a> for UseItem<'a> {
1079    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1080        let id = Ident::parse(lexer)?;
1081        let as_id = parse_optional(lexer, Token::AsKeyword, Ident::parse)?;
1082        Ok(Self { id, as_id })
1083    }
1084}
1085
1086impl Peek for UseItem<'_> {
1087    fn peek(lookahead: &mut Lookahead) -> bool {
1088        Ident::peek(lookahead)
1089    }
1090}
1091
1092/// Represents an interface export in the AST.
1093#[derive(Debug, Clone, Serialize)]
1094#[serde(rename_all = "camelCase")]
1095pub struct InterfaceExport<'a> {
1096    /// The doc comments for the export.
1097    pub docs: Vec<DocComment<'a>>,
1098    /// The identifier of the export.
1099    pub id: Ident<'a>,
1100    /// The type of the export.
1101    pub ty: FuncTypeRef<'a>,
1102}
1103
1104impl<'a> Parse<'a> for InterfaceExport<'a> {
1105    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1106        let docs = Parse::parse(lexer)?;
1107        let id = Ident::parse(lexer)?;
1108        parse_token(lexer, Token::Colon)?;
1109        let ty = Parse::parse(lexer)?;
1110        parse_token(lexer, Token::Semicolon)?;
1111        Ok(Self { docs, id, ty })
1112    }
1113}
1114
1115impl Peek for InterfaceExport<'_> {
1116    fn peek(lookahead: &mut Lookahead) -> bool {
1117        Ident::peek(lookahead)
1118    }
1119}
1120
1121/// Represents a world declaration in the AST.
1122#[derive(Debug, Clone, Serialize)]
1123#[serde(rename_all = "camelCase")]
1124pub struct WorldDecl<'a> {
1125    /// The doc comments for the world.
1126    pub docs: Vec<DocComment<'a>>,
1127    /// The identifier of the world.
1128    pub id: Ident<'a>,
1129    /// The items of the world.
1130    pub items: Vec<WorldItem<'a>>,
1131}
1132
1133impl<'a> Parse<'a> for WorldDecl<'a> {
1134    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1135        let docs = Parse::parse(lexer)?;
1136        parse_token(lexer, Token::WorldKeyword)?;
1137        let id = Ident::parse(lexer)?;
1138        parse_token(lexer, Token::OpenBrace)?;
1139        let items = parse_delimited(lexer, Token::CloseBrace, false)?;
1140        parse_token(lexer, Token::CloseBrace)?;
1141        Ok(Self { docs, id, items })
1142    }
1143}
1144
1145impl Peek for WorldDecl<'_> {
1146    fn peek(lookahead: &mut Lookahead) -> bool {
1147        lookahead.peek(Token::WorldKeyword)
1148    }
1149}
1150
1151/// Represents a world item in the AST.
1152#[derive(Debug, Clone, Serialize)]
1153#[serde(rename_all = "camelCase")]
1154pub enum WorldItem<'a> {
1155    /// The item is a use.
1156    Use(Use<'a>),
1157    /// The item is a type declaration.
1158    Type(ItemTypeDecl<'a>),
1159    /// The item is a world export.
1160    Import(WorldImport<'a>),
1161    /// The item is a world export.
1162    Export(WorldExport<'a>),
1163    /// The item is a world include.
1164    Include(WorldInclude<'a>),
1165}
1166
1167impl<'a> Parse<'a> for WorldItem<'a> {
1168    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1169        let mut lookahead = Lookahead::new(lexer);
1170        if Use::peek(&mut lookahead) {
1171            Ok(Self::Use(Parse::parse(lexer)?))
1172        } else if WorldImport::peek(&mut lookahead) {
1173            Ok(Self::Import(Parse::parse(lexer)?))
1174        } else if WorldExport::peek(&mut lookahead) {
1175            Ok(Self::Export(Parse::parse(lexer)?))
1176        } else if WorldInclude::peek(&mut lookahead) {
1177            Ok(Self::Include(Parse::parse(lexer)?))
1178        } else if ItemTypeDecl::peek(&mut lookahead) {
1179            Ok(Self::Type(Parse::parse(lexer)?))
1180        } else {
1181            Err(lookahead.error())
1182        }
1183    }
1184}
1185
1186impl Peek for WorldItem<'_> {
1187    fn peek(lookahead: &mut Lookahead) -> bool {
1188        Use::peek(lookahead)
1189            || WorldImport::peek(lookahead)
1190            || WorldExport::peek(lookahead)
1191            || WorldInclude::peek(lookahead)
1192            || ItemTypeDecl::peek(lookahead)
1193    }
1194}
1195
1196/// Represents a world import in the AST.
1197#[derive(Debug, Clone, Serialize)]
1198#[serde(rename_all = "camelCase")]
1199pub struct WorldImport<'a> {
1200    /// The doc comments for the world import.
1201    pub docs: Vec<DocComment<'a>>,
1202    /// The path of the imported item.
1203    pub path: WorldItemPath<'a>,
1204}
1205
1206impl<'a> Parse<'a> for WorldImport<'a> {
1207    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1208        let docs = Parse::parse(lexer)?;
1209        parse_token(lexer, Token::ImportKeyword)?;
1210        let path = Parse::parse(lexer)?;
1211        parse_token(lexer, Token::Semicolon)?;
1212        Ok(Self { docs, path })
1213    }
1214}
1215
1216impl Peek for WorldImport<'_> {
1217    fn peek(lookahead: &mut Lookahead) -> bool {
1218        lookahead.peek(Token::ImportKeyword)
1219    }
1220}
1221
1222/// Represents a world export in the AST.
1223#[derive(Debug, Clone, Serialize)]
1224#[serde(rename_all = "camelCase")]
1225pub struct WorldExport<'a> {
1226    /// The doc comments for the world export.
1227    pub docs: Vec<DocComment<'a>>,
1228    /// The path of the exported item.
1229    pub path: WorldItemPath<'a>,
1230}
1231
1232impl<'a> Parse<'a> for WorldExport<'a> {
1233    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1234        let docs = Parse::parse(lexer)?;
1235        parse_token(lexer, Token::ExportKeyword)?;
1236        let path = Parse::parse(lexer)?;
1237        parse_token(lexer, Token::Semicolon)?;
1238        Ok(Self { docs, path })
1239    }
1240}
1241
1242impl Peek for WorldExport<'_> {
1243    fn peek(lookahead: &mut Lookahead) -> bool {
1244        lookahead.peek(Token::ExportKeyword)
1245    }
1246}
1247
1248/// Represents a world item path in the AST.
1249#[derive(Debug, Clone, Serialize)]
1250#[serde(rename_all = "camelCase")]
1251pub enum WorldItemPath<'a> {
1252    /// The path is by name.
1253    Named(NamedWorldItem<'a>),
1254    /// The path is by a package path.
1255    Package(PackagePath<'a>),
1256    /// The path is by identifier.
1257    Ident(Ident<'a>),
1258}
1259
1260impl<'a> Parse<'a> for WorldItemPath<'a> {
1261    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1262        let mut lookahead = Lookahead::new(lexer);
1263        if PackagePath::peek(&mut lookahead) {
1264            Ok(Self::Package(Parse::parse(lexer)?))
1265        } else if Ident::peek(&mut lookahead) {
1266            // Peek again to see if this is a named item or an interface reference
1267            if let Some((Ok(Token::Colon), _)) = lexer.peek2() {
1268                Ok(Self::Named(Parse::parse(lexer)?))
1269            } else {
1270                Ok(Self::Ident(Parse::parse(lexer)?))
1271            }
1272        } else {
1273            Err(lookahead.error())
1274        }
1275    }
1276}
1277
1278/// Represents a named world item in the AST.
1279#[derive(Debug, Clone, Serialize)]
1280#[serde(rename_all = "camelCase")]
1281pub struct NamedWorldItem<'a> {
1282    /// The identifier of the item being imported or exported.
1283    pub id: Ident<'a>,
1284    /// The extern type of the item.
1285    pub ty: ExternType<'a>,
1286}
1287
1288impl<'a> Parse<'a> for NamedWorldItem<'a> {
1289    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1290        let id = Ident::parse(lexer)?;
1291        parse_token(lexer, Token::Colon)?;
1292        let ty = Parse::parse(lexer)?;
1293        Ok(Self { id, ty })
1294    }
1295}
1296
1297/// Represents the external type of a world item in the AST.
1298#[derive(Debug, Clone, Serialize)]
1299#[serde(rename_all = "camelCase")]
1300pub enum ExternType<'a> {
1301    /// The type is by identifier.
1302    Ident(Ident<'a>),
1303    /// The type is an inline function type.
1304    Func(FuncType<'a>),
1305    /// The type is an inline interface.
1306    Interface(InlineInterface<'a>),
1307}
1308
1309impl<'a> Parse<'a> for ExternType<'a> {
1310    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1311        let mut lookahead = Lookahead::new(lexer);
1312        if Ident::peek(&mut lookahead) {
1313            Ok(Self::Ident(Parse::parse(lexer)?))
1314        } else if FuncType::peek(&mut lookahead) {
1315            Ok(Self::Func(Parse::parse(lexer)?))
1316        } else if InlineInterface::peek(&mut lookahead) {
1317            Ok(Self::Interface(Parse::parse(lexer)?))
1318        } else {
1319            Err(lookahead.error())
1320        }
1321    }
1322}
1323
1324/// Represents an inline interface in the AST.
1325#[derive(Debug, Clone, Serialize)]
1326#[serde(rename_all = "camelCase")]
1327pub struct InlineInterface<'a> {
1328    /// The items of the interface.
1329    pub items: Vec<InterfaceItem<'a>>,
1330}
1331
1332impl<'a> Parse<'a> for InlineInterface<'a> {
1333    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1334        parse_token(lexer, Token::InterfaceKeyword)?;
1335        parse_token(lexer, Token::OpenBrace)?;
1336        let items = parse_delimited(lexer, Token::CloseBrace, false)?;
1337        parse_token(lexer, Token::CloseBrace)?;
1338        Ok(Self { items })
1339    }
1340}
1341
1342impl Peek for InlineInterface<'_> {
1343    fn peek(lookahead: &mut Lookahead) -> bool {
1344        lookahead.peek(Token::InterfaceKeyword)
1345    }
1346}
1347
1348/// Represents a world include in the AST.
1349#[derive(Debug, Clone, Serialize)]
1350#[serde(rename_all = "camelCase")]
1351pub struct WorldInclude<'a> {
1352    /// The doc comments for the world include.
1353    pub docs: Vec<DocComment<'a>>,
1354    /// The reference to the world to include.
1355    pub world: WorldRef<'a>,
1356    /// The optional include-with items.
1357    pub with: Vec<WorldIncludeItem<'a>>,
1358}
1359
1360impl<'a> Parse<'a> for WorldInclude<'a> {
1361    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1362        let docs = Parse::parse(lexer)?;
1363        parse_token(lexer, Token::IncludeKeyword)?;
1364        let world = Parse::parse(lexer)?;
1365        let with = parse_optional(lexer, Token::WithKeyword, |lexer| {
1366            parse_token(lexer, Token::OpenBrace)?;
1367            let items = parse_delimited(lexer, Token::CloseBrace, true)?;
1368            parse_token(lexer, Token::CloseBrace)?;
1369            Ok(items)
1370        })?
1371        .unwrap_or_default();
1372        parse_token(lexer, Token::Semicolon)?;
1373        Ok(Self { docs, world, with })
1374    }
1375}
1376
1377impl Peek for WorldInclude<'_> {
1378    fn peek(lookahead: &mut Lookahead) -> bool {
1379        lookahead.peek(Token::IncludeKeyword)
1380    }
1381}
1382
1383/// Represents a reference to a world in the AST (local or foreign).
1384#[derive(Debug, Clone, Serialize)]
1385#[serde(rename_all = "camelCase")]
1386pub enum WorldRef<'a> {
1387    /// The reference is by identifier.
1388    Ident(Ident<'a>),
1389    /// The reference is by package path.
1390    Package(PackagePath<'a>),
1391}
1392
1393impl<'a> WorldRef<'a> {
1394    /// Gets the name of the world being referred to.
1395    pub fn name(&self) -> &'a str {
1396        match self {
1397            Self::Ident(id) => id.string,
1398            Self::Package(path) => path.string,
1399        }
1400    }
1401
1402    /// Gets the span of the world reference.
1403    pub fn span(&self) -> SourceSpan {
1404        match self {
1405            Self::Ident(id) => id.span,
1406            Self::Package(path) => path.span,
1407        }
1408    }
1409}
1410
1411impl<'a> Parse<'a> for WorldRef<'a> {
1412    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1413        let mut lookahead = Lookahead::new(lexer);
1414        if PackagePath::peek(&mut lookahead) {
1415            Ok(Self::Package(Parse::parse(lexer)?))
1416        } else if Ident::peek(&mut lookahead) {
1417            Ok(Self::Ident(Parse::parse(lexer)?))
1418        } else {
1419            Err(lookahead.error())
1420        }
1421    }
1422}
1423
1424/// Represents a renaming of an included name.
1425#[derive(Debug, Clone, Serialize)]
1426#[serde(rename_all = "camelCase")]
1427pub struct WorldIncludeItem<'a> {
1428    /// The `from` name for the included item.
1429    pub from: Ident<'a>,
1430    /// The `to` name for the included item.
1431    pub to: Ident<'a>,
1432}
1433
1434impl<'a> Parse<'a> for WorldIncludeItem<'a> {
1435    fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
1436        let from = Ident::parse(lexer)?;
1437        parse_token(lexer, Token::AsKeyword)?;
1438        let to = Ident::parse(lexer)?;
1439        Ok(Self { from, to })
1440    }
1441}
1442
1443impl Peek for WorldIncludeItem<'_> {
1444    fn peek(lookahead: &mut Lookahead) -> bool {
1445        Ident::peek(lookahead)
1446    }
1447}
1448
1449#[cfg(test)]
1450mod test {
1451    use crate::ast::test::roundtrip;
1452
1453    #[test]
1454    fn resource_roundtrip() {
1455        roundtrip(
1456            r#"package foo:bar;
1457interface i { resource foo-bar {
1458    /** A constructor */
1459    constructor(foo: u8, bar: u8);
1460    /// A method
1461    foo: func() -> string;
1462    /// A method
1463    set-foo: func(foo: string);
1464    /// A static method
1465    id: static func() -> u32;
1466}}"#,
1467            r#"package foo:bar;
1468
1469interface i {
1470    resource foo-bar {
1471        /// A constructor
1472        constructor(foo: u8, bar: u8);
1473
1474        /// A method
1475        foo: func() -> string;
1476
1477        /// A method
1478        set-foo: func(foo: string);
1479
1480        /// A static method
1481        id: static func() -> u32;
1482    }
1483}
1484"#,
1485        )
1486        .unwrap();
1487    }
1488
1489    #[test]
1490    fn variant_roundtrip() {
1491        roundtrip(
1492            r#"package foo:bar;
1493variant foo {
1494    foo,
1495    bar(u32),
1496    baz(bar),
1497    qux(tuple<u8, u16, u32>)
1498}"#,
1499            r#"package foo:bar;
1500
1501variant foo {
1502    foo,
1503    bar(u32),
1504    baz(bar),
1505    qux(tuple<u8, u16, u32>),
1506}
1507"#,
1508        )
1509        .unwrap();
1510    }
1511
1512    #[test]
1513    fn record_roundtrip() {
1514        roundtrip(
1515            r#"package foo:bar;
1516record foo-bar2-baz {
1517    foo: foo,
1518    bar-qux: list<string>,
1519    // A comment
1520    jam: borrow<foo>,
1521}"#,
1522            r#"package foo:bar;
1523
1524record foo-bar2-baz {
1525    foo: foo,
1526    bar-qux: list<string>,
1527    jam: borrow<foo>,
1528}
1529"#,
1530        )
1531        .unwrap();
1532    }
1533
1534    #[test]
1535    fn flags_roundtrip() {
1536        roundtrip(
1537            r#"package foo:bar;
1538flags %flags {
1539    foo, bar, baz
1540}"#,
1541            r#"package foo:bar;
1542
1543flags %flags {
1544    foo,
1545    bar,
1546    baz,
1547}
1548"#,
1549        )
1550        .unwrap();
1551    }
1552
1553    #[test]
1554    fn enum_roundtrip() {
1555        roundtrip(
1556            r#"package foo:bar; enum foo {
1557    foo, bar, baz
1558}"#,
1559            r#"package foo:bar;
1560
1561enum foo {
1562    foo,
1563    bar,
1564    baz,
1565}
1566"#,
1567        )
1568        .unwrap();
1569    }
1570
1571    #[test]
1572    fn func_type_alias_roundtrip() {
1573        roundtrip(
1574            r#"package foo:bar; type x = func(a: /* comment */ string) -> string;"#,
1575            "package foo:bar;\n\ntype x = func(a: string) -> string;\n",
1576        )
1577        .unwrap();
1578    }
1579
1580    #[test]
1581    fn type_alias_roundtrip() {
1582        roundtrip(
1583            r#"package foo:bar; type x = tuple<u8, s8, u16, s16, u32, s32, u64, s64, f32, f64, char, bool, string, tuple<string, list<u8>>, option<list<bool>>, result, result<string>, result<_, string>, result<u8, u8>, borrow<y>, y>;"#,
1584            "package foo:bar;\n\ntype x = tuple<u8, s8, u16, s16, u32, s32, u64, s64, f32, f64, char, bool, string, tuple<string, list<u8>>, option<list<bool>>, result, result<string>, result<_, string>, result<u8, u8>, borrow<y>, y>;\n",
1585        )
1586        .unwrap();
1587    }
1588
1589    #[test]
1590    fn stream_future_error_context_roundtrip() {
1591        // stream (no payload)
1592        roundtrip(
1593            "package foo:bar; type a = stream;",
1594            "package foo:bar;\n\ntype a = stream;\n",
1595        )
1596        .unwrap();
1597
1598        // stream<u8>
1599        roundtrip(
1600            "package foo:bar; type b = stream<u8>;",
1601            "package foo:bar;\n\ntype b = stream<u8>;\n",
1602        )
1603        .unwrap();
1604
1605        // future (no payload)
1606        roundtrip(
1607            "package foo:bar; type c = future;",
1608            "package foo:bar;\n\ntype c = future;\n",
1609        )
1610        .unwrap();
1611
1612        // future<string>
1613        roundtrip(
1614            "package foo:bar; type d = future<string>;",
1615            "package foo:bar;\n\ntype d = future<string>;\n",
1616        )
1617        .unwrap();
1618
1619        // error-context
1620        roundtrip(
1621            "package foo:bar; type e = error-context;",
1622            "package foo:bar;\n\ntype e = error-context;\n",
1623        )
1624        .unwrap();
1625
1626        // nested: stream<stream<u8>>
1627        roundtrip(
1628            "package foo:bar; type f = stream<stream<u8>>;",
1629            "package foo:bar;\n\ntype f = stream<stream<u8>>;\n",
1630        )
1631        .unwrap();
1632
1633        // future<option<u32>>
1634        roundtrip(
1635            "package foo:bar; type g = future<option<u32>>;",
1636            "package foo:bar;\n\ntype g = future<option<u32>>;\n",
1637        )
1638        .unwrap();
1639    }
1640
1641    #[test]
1642    fn async_func_roundtrip() {
1643        // async func type alias
1644        roundtrip(
1645            "package foo:bar; type x = async func() -> string;",
1646            "package foo:bar;\n\ntype x = async func() -> string;\n",
1647        )
1648        .unwrap();
1649
1650        // async func with params
1651        roundtrip(
1652            "package foo:bar; type y = async func(a: u32, b: string) -> stream<u8>;",
1653            "package foo:bar;\n\ntype y = async func(a: u32, b: string) -> stream<u8>;\n",
1654        )
1655        .unwrap();
1656
1657        // async func with no results
1658        roundtrip(
1659            "package foo:bar; type z = async func();",
1660            "package foo:bar;\n\ntype z = async func();\n",
1661        )
1662        .unwrap();
1663
1664        // sync func still works (no async prefix)
1665        roundtrip(
1666            "package foo:bar; type w = func() -> u32;",
1667            "package foo:bar;\n\ntype w = func() -> u32;\n",
1668        )
1669        .unwrap();
1670
1671        // async func in interface export
1672        roundtrip(
1673            "package foo:bar; interface i { do-work: async func(input: string) -> future<u32>; }",
1674            "package foo:bar;\n\ninterface i {\n    do-work: async func(input: string) -> future<u32>;\n}\n",
1675        )
1676        .unwrap();
1677
1678        // async func in world import/export
1679        roundtrip(
1680            "package foo:bar; world w { import run: async func(); export process: async func(data: list<u8>) -> stream<u8>; }",
1681            "package foo:bar;\n\nworld w {\n    import run: async func();\n\n    export process: async func(data: list<u8>) -> stream<u8>;\n}\n",
1682        )
1683        .unwrap();
1684    }
1685
1686    #[test]
1687    fn interface_roundtrip() {
1688        roundtrip(
1689            r#"package foo:bar;
1690
1691interface foo {
1692    /// Type t
1693    type t = list<string>;
1694
1695    /// Use x and y
1696    use foo.{ x, y, };
1697
1698    /// Function a
1699    a: func(a: string, b: string) -> string;
1700
1701    // not a doc comment
1702    type x = func() -> list<string>;
1703
1704    /// Function b
1705    b: x;
1706}
1707            "#,
1708            r#"package foo:bar;
1709
1710interface foo {
1711    /// Type t
1712    type t = list<string>;
1713
1714    /// Use x and y
1715    use foo.{ x, y };
1716
1717    /// Function a
1718    a: func(a: string, b: string) -> string;
1719
1720    type x = func() -> list<string>;
1721
1722    /// Function b
1723    b: x;
1724}
1725"#,
1726        )
1727        .unwrap();
1728    }
1729
1730    #[test]
1731    fn world_roundtrip() {
1732        roundtrip(
1733            r#"package foo:bar;
1734
1735world foo {
1736    /// Type t
1737    type t = list<string>;
1738
1739    // not a doc comment
1740    type x = func() -> list<string>;
1741
1742    use foo.{ y, };
1743
1744    /// Import with function type.
1745    import a: func(a: string, b: string) -> string;
1746
1747    /// Import with identifier.
1748    import b: x;
1749
1750    /// Import with inline interface.
1751    import c: interface {
1752        /// Function a
1753        a: func(a: string, b: string) -> string;
1754    };
1755
1756    /// Import with package path
1757    import foo:bar/baz@1.0.0;
1758
1759    /// Export with function type.
1760    export a: func(a: string, b: string) -> string;
1761
1762    /// Export with identifier.
1763    export b: x;
1764
1765    /// Export with inline interface.
1766    export c: interface {
1767        /// Function a
1768        a: func(a: string, b: string) -> string;
1769    };
1770
1771    /// Export with package path
1772    export foo:bar/baz@1.0.0;
1773
1774    /// Include world from package path with 2 renames.
1775    include foo:bar/baz with { a as a1, b as b1 };
1776
1777    /// Include world from package path with 1 rename.
1778    include foo:bar/baz with {foo as foo1};
1779
1780    /// Include world from package path (spacing).
1781    include foo:bar/baz with { foo as foo1 };
1782
1783    /// Include world from package path newline delimited renaming.
1784    include foo:bar/baz with {
1785        foo as foo1,
1786        bar as bar1
1787    };
1788
1789    /// Include local world.
1790    include foo-bar;
1791
1792    /// Include local world with renaming.
1793    include foo-bar with { foo as bar };
1794}"#,
1795            r#"package foo:bar;
1796
1797world foo {
1798    /// Type t
1799    type t = list<string>;
1800
1801    type x = func() -> list<string>;
1802
1803    use foo.{ y };
1804
1805    /// Import with function type.
1806    import a: func(a: string, b: string) -> string;
1807
1808    /// Import with identifier.
1809    import b: x;
1810
1811    /// Import with inline interface.
1812    import c: interface {
1813        /// Function a
1814        a: func(a: string, b: string) -> string;
1815    };
1816
1817    /// Import with package path
1818    import foo:bar/baz@1.0.0;
1819
1820    /// Export with function type.
1821    export a: func(a: string, b: string) -> string;
1822
1823    /// Export with identifier.
1824    export b: x;
1825
1826    /// Export with inline interface.
1827    export c: interface {
1828        /// Function a
1829        a: func(a: string, b: string) -> string;
1830    };
1831
1832    /// Export with package path
1833    export foo:bar/baz@1.0.0;
1834
1835    /// Include world from package path with 2 renames.
1836    include foo:bar/baz with {
1837        a as a1,
1838        b as b1,
1839    };
1840
1841    /// Include world from package path with 1 rename.
1842    include foo:bar/baz with {
1843        foo as foo1,
1844    };
1845
1846    /// Include world from package path (spacing).
1847    include foo:bar/baz with {
1848        foo as foo1,
1849    };
1850
1851    /// Include world from package path newline delimited renaming.
1852    include foo:bar/baz with {
1853        foo as foo1,
1854        bar as bar1,
1855    };
1856
1857    /// Include local world.
1858    include foo-bar;
1859
1860    /// Include local world with renaming.
1861    include foo-bar with {
1862        foo as bar,
1863    };
1864}
1865"#,
1866        )
1867        .unwrap();
1868    }
1869}