use crate::component::*; use crate::core; use crate::kw; use crate::parser::Lookahead1; use crate::parser::Peek; use crate::parser::{Parse, Parser, Result}; use crate::token::Index; use crate::token::LParen; use crate::token::{Id, NameAnnotation, Span}; /// A core type declaration. #[derive(Debug)] pub struct CoreType<'a> { /// Where this type was defined. pub span: Span, /// An optional identifier to refer to this `core type` by as part of name /// resolution. pub id: Option>, /// An optional name for this type stored in the custom `name` section. pub name: Option>, /// The core type's definition. pub def: CoreTypeDef<'a>, } impl<'a> Parse<'a> for CoreType<'a> { fn parse(parser: Parser<'a>) -> Result { let span = parser.parse::()?.0; parser.parse::()?; let id = parser.parse()?; let name = parser.parse()?; let def = parser.parens(|p| p.parse())?; Ok(Self { span, id, name, def, }) } } /// Represents a core type definition. /// /// In the future this may be removed when module types are a part of /// a core module. #[derive(Debug)] pub enum CoreTypeDef<'a> { /// The type definition is one of the core types. Def(core::TypeDef<'a>), /// The type definition is a module type. Module(ModuleType<'a>), } impl<'a> Parse<'a> for CoreTypeDef<'a> { fn parse(parser: Parser<'a>) -> Result { if parser.peek::()? { parser.parse::()?; Ok(Self::Module(parser.parse()?)) } else { Ok(Self::Def(parser.parse()?)) } } } /// A type definition for a core module. #[derive(Debug)] pub struct ModuleType<'a> { /// The declarations of the module type. pub decls: Vec>, } impl<'a> Parse<'a> for ModuleType<'a> { fn parse(parser: Parser<'a>) -> Result { parser.depth_check()?; Ok(Self { decls: parser.parse()?, }) } } /// The declarations of a [`ModuleType`]. #[derive(Debug)] pub enum ModuleTypeDecl<'a> { /// A core type. Type(core::Type<'a>), /// An alias local to the component type. Alias(Alias<'a>), /// An import. Import(core::Import<'a>), /// An export. Export(&'a str, core::ItemSig<'a>), } impl<'a> Parse<'a> for ModuleTypeDecl<'a> { fn parse(parser: Parser<'a>) -> Result { let mut l = parser.lookahead1(); if l.peek::()? { Ok(Self::Type(parser.parse()?)) } else if l.peek::()? { Ok(Self::Alias(Alias::parse_outer_core_type_alias(parser)?)) } else if l.peek::()? { Ok(Self::Import(parser.parse()?)) } else if l.peek::()? { parser.parse::()?; let name = parser.parse()?; let et = parser.parens(|parser| parser.parse())?; Ok(Self::Export(name, et)) } else { Err(l.error()) } } } impl<'a> Parse<'a> for Vec> { fn parse(parser: Parser<'a>) -> Result { let mut decls = Vec::new(); while !parser.is_empty() { decls.push(parser.parens(|parser| parser.parse())?); } Ok(decls) } } /// A type declaration in a component. #[derive(Debug)] pub struct Type<'a> { /// Where this type was defined. pub span: Span, /// An optional identifier to refer to this `type` by as part of name /// resolution. pub id: Option>, /// An optional name for this type stored in the custom `name` section. pub name: Option>, /// If present, inline export annotations which indicate names this /// definition should be exported under. pub exports: InlineExport<'a>, /// The type definition. pub def: TypeDef<'a>, } impl<'a> Type<'a> { /// Parses a `Type` while allowing inline `(export "...")` names to be /// defined. pub fn parse_maybe_with_inline_exports(parser: Parser<'a>) -> Result { Type::parse(parser, true) } fn parse_no_inline_exports(parser: Parser<'a>) -> Result { Type::parse(parser, false) } fn parse(parser: Parser<'a>, allow_inline_exports: bool) -> Result { let span = parser.parse::()?.0; let id = parser.parse()?; let name = parser.parse()?; let exports = if allow_inline_exports { parser.parse()? } else { Default::default() }; let def = parser.parse()?; Ok(Self { span, id, name, exports, def, }) } } /// A definition of a component type. #[derive(Debug)] pub enum TypeDef<'a> { /// A defined value type. Defined(ComponentDefinedType<'a>), /// A component function type. Func(ComponentFunctionType<'a>), /// A component type. Component(ComponentType<'a>), /// An instance type. Instance(InstanceType<'a>), /// A resource type. Resource(ResourceType<'a>), } impl<'a> Parse<'a> for TypeDef<'a> { fn parse(parser: Parser<'a>) -> Result { if parser.peek::()? { parser.parens(|parser| { let mut l = parser.lookahead1(); if l.peek::()? { parser.parse::()?; Ok(Self::Func(parser.parse()?)) } else if l.peek::()? { parser.parse::()?; Ok(Self::Component(parser.parse()?)) } else if l.peek::()? { parser.parse::()?; Ok(Self::Instance(parser.parse()?)) } else if l.peek::()? { parser.parse::()?; Ok(Self::Resource(parser.parse()?)) } else { Ok(Self::Defined(ComponentDefinedType::parse_non_primitive( parser, l, )?)) } }) } else { // Only primitive types have no parens Ok(Self::Defined(ComponentDefinedType::Primitive( parser.parse()?, ))) } } } /// A primitive value type. #[allow(missing_docs)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum PrimitiveValType { Bool, S8, U8, S16, U16, S32, U32, S64, U64, Float32, Float64, Char, String, } impl<'a> Parse<'a> for PrimitiveValType { fn parse(parser: Parser<'a>) -> Result { let mut l = parser.lookahead1(); if l.peek::()? { parser.parse::()?; Ok(Self::Bool) } else if l.peek::()? { parser.parse::()?; Ok(Self::S8) } else if l.peek::()? { parser.parse::()?; Ok(Self::U8) } else if l.peek::()? { parser.parse::()?; Ok(Self::S16) } else if l.peek::()? { parser.parse::()?; Ok(Self::U16) } else if l.peek::()? { parser.parse::()?; Ok(Self::S32) } else if l.peek::()? { parser.parse::()?; Ok(Self::U32) } else if l.peek::()? { parser.parse::()?; Ok(Self::S64) } else if l.peek::()? { parser.parse::()?; Ok(Self::U64) } else if l.peek::()? { parser.parse::()?; Ok(Self::Float32) } else if l.peek::()? { parser.parse::()?; Ok(Self::Float64) } else if l.peek::()? { parser.parse::()?; Ok(Self::Char) } else if l.peek::()? { parser.parse::()?; Ok(Self::String) } else { Err(l.error()) } } } impl Peek for PrimitiveValType { fn peek(cursor: crate::parser::Cursor<'_>) -> Result { Ok(matches!( cursor.keyword()?, Some(("bool", _)) | Some(("s8", _)) | Some(("u8", _)) | Some(("s16", _)) | Some(("u16", _)) | Some(("s32", _)) | Some(("u32", _)) | Some(("s64", _)) | Some(("u64", _)) | Some(("float32", _)) | Some(("float64", _)) | Some(("char", _)) | Some(("string", _)) )) } fn display() -> &'static str { "primitive value type" } } /// A component value type. #[allow(missing_docs)] #[derive(Debug)] pub enum ComponentValType<'a> { /// The value type is an inline defined type. Inline(ComponentDefinedType<'a>), /// The value type is an index reference to a defined type. Ref(Index<'a>), } impl<'a> Parse<'a> for ComponentValType<'a> { fn parse(parser: Parser<'a>) -> Result { if parser.peek::>()? { Ok(Self::Ref(parser.parse()?)) } else { Ok(Self::Inline(InlineComponentValType::parse(parser)?.0)) } } } impl Peek for ComponentValType<'_> { fn peek(cursor: crate::parser::Cursor<'_>) -> Result { Ok(Index::peek(cursor)? || ComponentDefinedType::peek(cursor)?) } fn display() -> &'static str { "component value type" } } /// An inline-only component value type. /// /// This variation does not parse type indexes. #[allow(missing_docs)] #[derive(Debug)] pub struct InlineComponentValType<'a>(ComponentDefinedType<'a>); impl<'a> Parse<'a> for InlineComponentValType<'a> { fn parse(parser: Parser<'a>) -> Result { if parser.peek::()? { parser.parens(|parser| { Ok(Self(ComponentDefinedType::parse_non_primitive( parser, parser.lookahead1(), )?)) }) } else { Ok(Self(ComponentDefinedType::Primitive(parser.parse()?))) } } } // A component defined type. #[allow(missing_docs)] #[derive(Debug)] pub enum ComponentDefinedType<'a> { Primitive(PrimitiveValType), Record(Record<'a>), Variant(Variant<'a>), List(List<'a>), Tuple(Tuple<'a>), Flags(Flags<'a>), Enum(Enum<'a>), Option(OptionType<'a>), Result(ResultType<'a>), Own(Index<'a>), Borrow(Index<'a>), } impl<'a> ComponentDefinedType<'a> { fn parse_non_primitive(parser: Parser<'a>, mut l: Lookahead1<'a>) -> Result { parser.depth_check()?; if l.peek::()? { Ok(Self::Record(parser.parse()?)) } else if l.peek::()? { Ok(Self::Variant(parser.parse()?)) } else if l.peek::()? { Ok(Self::List(parser.parse()?)) } else if l.peek::()? { Ok(Self::Tuple(parser.parse()?)) } else if l.peek::()? { Ok(Self::Flags(parser.parse()?)) } else if l.peek::()? { Ok(Self::Enum(parser.parse()?)) } else if l.peek::()? { Ok(Self::Option(parser.parse()?)) } else if l.peek::()? { Ok(Self::Result(parser.parse()?)) } else if l.peek::()? { parser.parse::()?; Ok(Self::Own(parser.parse()?)) } else if l.peek::()? { parser.parse::()?; Ok(Self::Borrow(parser.parse()?)) } else { Err(l.error()) } } } impl Default for ComponentDefinedType<'_> { fn default() -> Self { Self::Primitive(PrimitiveValType::Bool) } } impl Peek for ComponentDefinedType<'_> { fn peek(cursor: crate::parser::Cursor<'_>) -> Result { if PrimitiveValType::peek(cursor)? { return Ok(true); } Ok(match cursor.lparen()? { Some(cursor) => matches!( cursor.keyword()?, Some(("record", _)) | Some(("variant", _)) | Some(("list", _)) | Some(("tuple", _)) | Some(("flags", _)) | Some(("enum", _)) | Some(("option", _)) | Some(("result", _)) | Some(("own", _)) | Some(("borrow", _)) ), None => false, }) } fn display() -> &'static str { "component defined type" } } /// A record defined type. #[derive(Debug)] pub struct Record<'a> { /// The fields of the record. pub fields: Vec>, } impl<'a> Parse<'a> for Record<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; let mut fields = Vec::new(); while !parser.is_empty() { fields.push(parser.parens(|p| p.parse())?); } Ok(Self { fields }) } } /// A record type field. #[derive(Debug)] pub struct RecordField<'a> { /// The name of the field. pub name: &'a str, /// The type of the field. pub ty: ComponentValType<'a>, } impl<'a> Parse<'a> for RecordField<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; Ok(Self { name: parser.parse()?, ty: parser.parse()?, }) } } /// A variant defined type. #[derive(Debug)] pub struct Variant<'a> { /// The cases of the variant type. pub cases: Vec>, } impl<'a> Parse<'a> for Variant<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; let mut cases = Vec::new(); while !parser.is_empty() { cases.push(parser.parens(|p| p.parse())?); } Ok(Self { cases }) } } /// A case of a variant type. #[derive(Debug)] pub struct VariantCase<'a> { /// Where this `case` was defined pub span: Span, /// An optional identifier to refer to this case by as part of name /// resolution. pub id: Option>, /// The name of the case. pub name: &'a str, /// The optional type of the case. pub ty: Option>, /// The optional refinement. pub refines: Option>, } impl<'a> Parse<'a> for VariantCase<'a> { fn parse(parser: Parser<'a>) -> Result { let span = parser.parse::()?.0; let id = parser.parse()?; let name = parser.parse()?; let ty = parser.parse()?; let refines = if !parser.is_empty() { Some(parser.parse()?) } else { None }; Ok(Self { span, id, name, ty, refines, }) } } /// A refinement for a variant case. #[derive(Debug)] pub enum Refinement<'a> { /// The refinement is referenced by index. Index(Span, Index<'a>), /// The refinement has been resolved to an index into /// the cases of the variant. Resolved(u32), } impl<'a> Parse<'a> for Refinement<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parens(|parser| { let span = parser.parse::()?.0; let id = parser.parse()?; Ok(Self::Index(span, id)) }) } } /// A list type. #[derive(Debug)] pub struct List<'a> { /// The element type of the array. pub element: Box>, } impl<'a> Parse<'a> for List<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; Ok(Self { element: Box::new(parser.parse()?), }) } } /// A tuple type. #[derive(Debug)] pub struct Tuple<'a> { /// The types of the fields of the tuple. pub fields: Vec>, } impl<'a> Parse<'a> for Tuple<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; let mut fields = Vec::new(); while !parser.is_empty() { fields.push(parser.parse()?); } Ok(Self { fields }) } } /// A flags type. #[derive(Debug)] pub struct Flags<'a> { /// The names of the individual flags. pub names: Vec<&'a str>, } impl<'a> Parse<'a> for Flags<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; let mut names = Vec::new(); while !parser.is_empty() { names.push(parser.parse()?); } Ok(Self { names }) } } /// An enum type. #[derive(Debug)] pub struct Enum<'a> { /// The tag names of the enum. pub names: Vec<&'a str>, } impl<'a> Parse<'a> for Enum<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; let mut names = Vec::new(); while !parser.is_empty() { names.push(parser.parse()?); } Ok(Self { names }) } } /// An optional type. #[derive(Debug)] pub struct OptionType<'a> { /// The type of the value, when a value is present. pub element: Box>, } impl<'a> Parse<'a> for OptionType<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; Ok(Self { element: Box::new(parser.parse()?), }) } } /// A result type. #[derive(Debug)] pub struct ResultType<'a> { /// The type on success. pub ok: Option>>, /// The type on failure. pub err: Option>>, } impl<'a> Parse<'a> for ResultType<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; let ok: Option = parser.parse()?; let err: Option = if parser.peek::()? { Some(parser.parens(|parser| { parser.parse::()?; parser.parse() })?) } else { None }; Ok(Self { ok: ok.map(Box::new), err: err.map(Box::new), }) } } /// A component function type with parameters and result. #[derive(Debug)] pub struct ComponentFunctionType<'a> { /// The parameters of a function, optionally each having an identifier for /// name resolution and a name for the custom `name` section. pub params: Box<[ComponentFunctionParam<'a>]>, /// The result of a function, optionally each having an identifier for /// name resolution and a name for the custom `name` section. pub results: Box<[ComponentFunctionResult<'a>]>, } impl<'a> Parse<'a> for ComponentFunctionType<'a> { fn parse(parser: Parser<'a>) -> Result { let mut params: Vec = Vec::new(); while parser.peek2::()? { params.push(parser.parens(|p| p.parse())?); } let mut results: Vec = Vec::new(); while parser.peek2::()? { results.push(parser.parens(|p| p.parse())?); } Ok(Self { params: params.into(), results: results.into(), }) } } /// A parameter of a [`ComponentFunctionType`]. #[derive(Debug)] pub struct ComponentFunctionParam<'a> { /// The name of the parameter pub name: &'a str, /// The type of the parameter. pub ty: ComponentValType<'a>, } impl<'a> Parse<'a> for ComponentFunctionParam<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; Ok(Self { name: parser.parse()?, ty: parser.parse()?, }) } } /// A result of a [`ComponentFunctionType`]. #[derive(Debug)] pub struct ComponentFunctionResult<'a> { /// An optionally-specified name of this result pub name: Option<&'a str>, /// The type of the result. pub ty: ComponentValType<'a>, } impl<'a> Parse<'a> for ComponentFunctionResult<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; Ok(Self { name: parser.parse()?, ty: parser.parse()?, }) } } /// The type of an exported item from an component or instance type. #[derive(Debug)] pub struct ComponentExportType<'a> { /// Where this export was defined. pub span: Span, /// The name of this export. pub name: ComponentExternName<'a>, /// The signature of the item. pub item: ItemSig<'a>, } impl<'a> Parse<'a> for ComponentExportType<'a> { fn parse(parser: Parser<'a>) -> Result { let span = parser.parse::()?.0; let id = parser.parse()?; let debug_name = parser.parse()?; let name = parser.parse()?; let item = parser.parens(|p| { let mut item = p.parse::>()?.0; item.id = id; item.name = debug_name; Ok(item) })?; Ok(Self { span, name, item }) } } /// A type definition for a component type. #[derive(Debug, Default)] pub struct ComponentType<'a> { /// The declarations of the component type. pub decls: Vec>, } impl<'a> Parse<'a> for ComponentType<'a> { fn parse(parser: Parser<'a>) -> Result { parser.depth_check()?; Ok(Self { decls: parser.parse()?, }) } } /// A declaration of a component type. #[derive(Debug)] pub enum ComponentTypeDecl<'a> { /// A core type definition local to the component type. CoreType(CoreType<'a>), /// A type definition local to the component type. Type(Type<'a>), /// An alias local to the component type. Alias(Alias<'a>), /// An import of the component type. Import(ComponentImport<'a>), /// An export of the component type. Export(ComponentExportType<'a>), } impl<'a> Parse<'a> for ComponentTypeDecl<'a> { fn parse(parser: Parser<'a>) -> Result { let mut l = parser.lookahead1(); if l.peek::()? { Ok(Self::CoreType(parser.parse()?)) } else if l.peek::()? { Ok(Self::Type(Type::parse_no_inline_exports(parser)?)) } else if l.peek::()? { Ok(Self::Alias(parser.parse()?)) } else if l.peek::()? { Ok(Self::Import(parser.parse()?)) } else if l.peek::()? { Ok(Self::Export(parser.parse()?)) } else { Err(l.error()) } } } impl<'a> Parse<'a> for Vec> { fn parse(parser: Parser<'a>) -> Result { let mut decls = Vec::new(); while !parser.is_empty() { decls.push(parser.parens(|parser| parser.parse())?); } Ok(decls) } } /// A type definition for an instance type. #[derive(Debug)] pub struct InstanceType<'a> { /// The declarations of the instance type. pub decls: Vec>, } impl<'a> Parse<'a> for InstanceType<'a> { fn parse(parser: Parser<'a>) -> Result { parser.depth_check()?; Ok(Self { decls: parser.parse()?, }) } } /// A declaration of an instance type. #[derive(Debug)] pub enum InstanceTypeDecl<'a> { /// A core type definition local to the component type. CoreType(CoreType<'a>), /// A type definition local to the instance type. Type(Type<'a>), /// An alias local to the instance type. Alias(Alias<'a>), /// An export of the instance type. Export(ComponentExportType<'a>), } impl<'a> Parse<'a> for InstanceTypeDecl<'a> { fn parse(parser: Parser<'a>) -> Result { let mut l = parser.lookahead1(); if l.peek::()? { Ok(Self::CoreType(parser.parse()?)) } else if l.peek::()? { Ok(Self::Type(Type::parse_no_inline_exports(parser)?)) } else if l.peek::()? { Ok(Self::Alias(parser.parse()?)) } else if l.peek::()? { Ok(Self::Export(parser.parse()?)) } else { Err(l.error()) } } } impl<'a> Parse<'a> for Vec> { fn parse(parser: Parser<'a>) -> Result { let mut decls = Vec::new(); while !parser.is_empty() { decls.push(parser.parens(|parser| parser.parse())?); } Ok(decls) } } /// A type definition for an instance type. #[derive(Debug)] pub struct ResourceType<'a> { /// Representation, in core WebAssembly, of this resource. pub rep: core::ValType<'a>, /// The declarations of the instance type. pub dtor: Option>, } impl<'a> Parse<'a> for ResourceType<'a> { fn parse(parser: Parser<'a>) -> Result { let rep = parser.parens(|p| { p.parse::()?; p.parse() })?; let dtor = if parser.is_empty() { None } else { Some(parser.parens(|p| { p.parse::()?; p.parens(|p| p.parse()) })?) }; Ok(Self { rep, dtor }) } } /// A value type declaration used for values in import signatures. #[derive(Debug)] pub struct ComponentValTypeUse<'a>(pub ComponentValType<'a>); impl<'a> Parse<'a> for ComponentValTypeUse<'a> { fn parse(parser: Parser<'a>) -> Result { match ComponentTypeUse::<'a, InlineComponentValType<'a>>::parse(parser)? { ComponentTypeUse::Ref(i) => Ok(Self(ComponentValType::Ref(i.idx))), ComponentTypeUse::Inline(t) => Ok(Self(ComponentValType::Inline(t.0))), } } } /// A reference to a core type defined in this component. /// /// This is the same as `TypeUse`, but accepts `$T` as shorthand for /// `(type $T)`. #[derive(Debug, Clone)] pub enum CoreTypeUse<'a, T> { /// The type that we're referencing. Ref(CoreItemRef<'a, kw::r#type>), /// The inline type. Inline(T), } impl<'a, T: Parse<'a>> Parse<'a> for CoreTypeUse<'a, T> { fn parse(parser: Parser<'a>) -> Result { // Here the core context is assumed, so no core prefix is expected if parser.peek::()? && parser.peek2::>()? { Ok(Self::Ref(parser.parens(|parser| parser.parse())?)) } else { Ok(Self::Inline(parser.parse()?)) } } } impl Default for CoreTypeUse<'_, T> { fn default() -> Self { let span = Span::from_offset(0); Self::Ref(CoreItemRef { idx: Index::Num(0, span), kind: kw::r#type(span), export_name: None, }) } } /// A reference to a type defined in this component. /// /// This is the same as `TypeUse`, but accepts `$T` as shorthand for /// `(type $T)`. #[derive(Debug, Clone)] pub enum ComponentTypeUse<'a, T> { /// The type that we're referencing. Ref(ItemRef<'a, kw::r#type>), /// The inline type. Inline(T), } impl<'a, T: Parse<'a>> Parse<'a> for ComponentTypeUse<'a, T> { fn parse(parser: Parser<'a>) -> Result { if parser.peek::()? && parser.peek2::>()? { Ok(Self::Ref(parser.parens(|parser| parser.parse())?)) } else { Ok(Self::Inline(parser.parse()?)) } } } impl Default for ComponentTypeUse<'_, T> { fn default() -> Self { let span = Span::from_offset(0); Self::Ref(ItemRef { idx: Index::Num(0, span), kind: kw::r#type(span), export_names: Vec::new(), }) } }