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};
#[derive(Debug)]
pub struct CoreType<'a> {
pub span: Span,
pub id: Option<Id<'a>>,
pub name: Option<NameAnnotation<'a>>,
pub def: CoreTypeDef<'a>,
}
impl<'a> Parse<'a> for CoreType<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let span = parser.parse::<kw::core>()?.0;
parser.parse::<kw::r#type>()?;
let id = parser.parse()?;
let name = parser.parse()?;
let def = parser.parens(|p| p.parse())?;
Ok(Self {
span,
id,
name,
def,
})
}
}
#[derive(Debug)]
pub enum CoreTypeDef<'a> {
Def(core::TypeDef<'a>),
Module(ModuleType<'a>),
}
impl<'a> Parse<'a> for CoreTypeDef<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
if parser.peek::<kw::module>()? {
parser.parse::<kw::module>()?;
Ok(Self::Module(parser.parse()?))
} else {
Ok(Self::Def(parser.parse()?))
}
}
}
#[derive(Debug)]
pub struct ModuleType<'a> {
pub decls: Vec<ModuleTypeDecl<'a>>,
}
impl<'a> Parse<'a> for ModuleType<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.depth_check()?;
Ok(Self {
decls: parser.parse()?,
})
}
}
#[derive(Debug)]
pub enum ModuleTypeDecl<'a> {
Type(core::Type<'a>),
Alias(Alias<'a>),
Import(core::Import<'a>),
Export(&'a str, core::ItemSig<'a>),
}
impl<'a> Parse<'a> for ModuleTypeDecl<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut l = parser.lookahead1();
if l.peek::<kw::r#type>()? {
Ok(Self::Type(parser.parse()?))
} else if l.peek::<kw::alias>()? {
Ok(Self::Alias(Alias::parse_outer_core_type_alias(parser)?))
} else if l.peek::<kw::import>()? {
Ok(Self::Import(parser.parse()?))
} else if l.peek::<kw::export>()? {
parser.parse::<kw::export>()?;
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<ModuleTypeDecl<'a>> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut decls = Vec::new();
while !parser.is_empty() {
decls.push(parser.parens(|parser| parser.parse())?);
}
Ok(decls)
}
}
#[derive(Debug)]
pub struct Type<'a> {
pub span: Span,
pub id: Option<Id<'a>>,
pub name: Option<NameAnnotation<'a>>,
pub exports: InlineExport<'a>,
pub def: TypeDef<'a>,
}
impl<'a> Type<'a> {
pub fn parse_maybe_with_inline_exports(parser: Parser<'a>) -> Result<Self> {
Type::parse(parser, true)
}
fn parse_no_inline_exports(parser: Parser<'a>) -> Result<Self> {
Type::parse(parser, false)
}
fn parse(parser: Parser<'a>, allow_inline_exports: bool) -> Result<Self> {
let span = parser.parse::<kw::r#type>()?.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,
})
}
}
#[derive(Debug)]
pub enum TypeDef<'a> {
Defined(ComponentDefinedType<'a>),
Func(ComponentFunctionType<'a>),
Component(ComponentType<'a>),
Instance(InstanceType<'a>),
Resource(ResourceType<'a>),
}
impl<'a> Parse<'a> for TypeDef<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
if parser.peek::<LParen>()? {
parser.parens(|parser| {
let mut l = parser.lookahead1();
if l.peek::<kw::func>()? {
parser.parse::<kw::func>()?;
Ok(Self::Func(parser.parse()?))
} else if l.peek::<kw::component>()? {
parser.parse::<kw::component>()?;
Ok(Self::Component(parser.parse()?))
} else if l.peek::<kw::instance>()? {
parser.parse::<kw::instance>()?;
Ok(Self::Instance(parser.parse()?))
} else if l.peek::<kw::resource>()? {
parser.parse::<kw::resource>()?;
Ok(Self::Resource(parser.parse()?))
} else {
Ok(Self::Defined(ComponentDefinedType::parse_non_primitive(
parser, l,
)?))
}
})
} else {
Ok(Self::Defined(ComponentDefinedType::Primitive(
parser.parse()?,
)))
}
}
}
#[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<Self> {
let mut l = parser.lookahead1();
if l.peek::<kw::bool_>()? {
parser.parse::<kw::bool_>()?;
Ok(Self::Bool)
} else if l.peek::<kw::s8>()? {
parser.parse::<kw::s8>()?;
Ok(Self::S8)
} else if l.peek::<kw::u8>()? {
parser.parse::<kw::u8>()?;
Ok(Self::U8)
} else if l.peek::<kw::s16>()? {
parser.parse::<kw::s16>()?;
Ok(Self::S16)
} else if l.peek::<kw::u16>()? {
parser.parse::<kw::u16>()?;
Ok(Self::U16)
} else if l.peek::<kw::s32>()? {
parser.parse::<kw::s32>()?;
Ok(Self::S32)
} else if l.peek::<kw::u32>()? {
parser.parse::<kw::u32>()?;
Ok(Self::U32)
} else if l.peek::<kw::s64>()? {
parser.parse::<kw::s64>()?;
Ok(Self::S64)
} else if l.peek::<kw::u64>()? {
parser.parse::<kw::u64>()?;
Ok(Self::U64)
} else if l.peek::<kw::float32>()? {
parser.parse::<kw::float32>()?;
Ok(Self::Float32)
} else if l.peek::<kw::float64>()? {
parser.parse::<kw::float64>()?;
Ok(Self::Float64)
} else if l.peek::<kw::char>()? {
parser.parse::<kw::char>()?;
Ok(Self::Char)
} else if l.peek::<kw::string>()? {
parser.parse::<kw::string>()?;
Ok(Self::String)
} else {
Err(l.error())
}
}
}
impl Peek for PrimitiveValType {
fn peek(cursor: crate::parser::Cursor<'_>) -> Result<bool> {
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"
}
}
#[allow(missing_docs)]
#[derive(Debug)]
pub enum ComponentValType<'a> {
Inline(ComponentDefinedType<'a>),
Ref(Index<'a>),
}
impl<'a> Parse<'a> for ComponentValType<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
if parser.peek::<Index<'_>>()? {
Ok(Self::Ref(parser.parse()?))
} else {
Ok(Self::Inline(InlineComponentValType::parse(parser)?.0))
}
}
}
impl Peek for ComponentValType<'_> {
fn peek(cursor: crate::parser::Cursor<'_>) -> Result<bool> {
Ok(Index::peek(cursor)? || ComponentDefinedType::peek(cursor)?)
}
fn display() -> &'static str {
"component value type"
}
}
#[allow(missing_docs)]
#[derive(Debug)]
pub struct InlineComponentValType<'a>(ComponentDefinedType<'a>);
impl<'a> Parse<'a> for InlineComponentValType<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
if parser.peek::<LParen>()? {
parser.parens(|parser| {
Ok(Self(ComponentDefinedType::parse_non_primitive(
parser,
parser.lookahead1(),
)?))
})
} else {
Ok(Self(ComponentDefinedType::Primitive(parser.parse()?)))
}
}
}
#[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<Self> {
parser.depth_check()?;
if l.peek::<kw::record>()? {
Ok(Self::Record(parser.parse()?))
} else if l.peek::<kw::variant>()? {
Ok(Self::Variant(parser.parse()?))
} else if l.peek::<kw::list>()? {
Ok(Self::List(parser.parse()?))
} else if l.peek::<kw::tuple>()? {
Ok(Self::Tuple(parser.parse()?))
} else if l.peek::<kw::flags>()? {
Ok(Self::Flags(parser.parse()?))
} else if l.peek::<kw::enum_>()? {
Ok(Self::Enum(parser.parse()?))
} else if l.peek::<kw::option>()? {
Ok(Self::Option(parser.parse()?))
} else if l.peek::<kw::result>()? {
Ok(Self::Result(parser.parse()?))
} else if l.peek::<kw::own>()? {
parser.parse::<kw::own>()?;
Ok(Self::Own(parser.parse()?))
} else if l.peek::<kw::borrow>()? {
parser.parse::<kw::borrow>()?;
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<bool> {
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"
}
}
#[derive(Debug)]
pub struct Record<'a> {
pub fields: Vec<RecordField<'a>>,
}
impl<'a> Parse<'a> for Record<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::record>()?;
let mut fields = Vec::new();
while !parser.is_empty() {
fields.push(parser.parens(|p| p.parse())?);
}
Ok(Self { fields })
}
}
#[derive(Debug)]
pub struct RecordField<'a> {
pub name: &'a str,
pub ty: ComponentValType<'a>,
}
impl<'a> Parse<'a> for RecordField<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::field>()?;
Ok(Self {
name: parser.parse()?,
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct Variant<'a> {
pub cases: Vec<VariantCase<'a>>,
}
impl<'a> Parse<'a> for Variant<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::variant>()?;
let mut cases = Vec::new();
while !parser.is_empty() {
cases.push(parser.parens(|p| p.parse())?);
}
Ok(Self { cases })
}
}
#[derive(Debug)]
pub struct VariantCase<'a> {
pub span: Span,
pub id: Option<Id<'a>>,
pub name: &'a str,
pub ty: Option<ComponentValType<'a>>,
pub refines: Option<Refinement<'a>>,
}
impl<'a> Parse<'a> for VariantCase<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let span = parser.parse::<kw::case>()?.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,
})
}
}
#[derive(Debug)]
pub enum Refinement<'a> {
Index(Span, Index<'a>),
Resolved(u32),
}
impl<'a> Parse<'a> for Refinement<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parens(|parser| {
let span = parser.parse::<kw::refines>()?.0;
let id = parser.parse()?;
Ok(Self::Index(span, id))
})
}
}
#[derive(Debug)]
pub struct List<'a> {
pub element: Box<ComponentValType<'a>>,
}
impl<'a> Parse<'a> for List<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::list>()?;
Ok(Self {
element: Box::new(parser.parse()?),
})
}
}
#[derive(Debug)]
pub struct Tuple<'a> {
pub fields: Vec<ComponentValType<'a>>,
}
impl<'a> Parse<'a> for Tuple<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::tuple>()?;
let mut fields = Vec::new();
while !parser.is_empty() {
fields.push(parser.parse()?);
}
Ok(Self { fields })
}
}
#[derive(Debug)]
pub struct Flags<'a> {
pub names: Vec<&'a str>,
}
impl<'a> Parse<'a> for Flags<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::flags>()?;
let mut names = Vec::new();
while !parser.is_empty() {
names.push(parser.parse()?);
}
Ok(Self { names })
}
}
#[derive(Debug)]
pub struct Enum<'a> {
pub names: Vec<&'a str>,
}
impl<'a> Parse<'a> for Enum<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::enum_>()?;
let mut names = Vec::new();
while !parser.is_empty() {
names.push(parser.parse()?);
}
Ok(Self { names })
}
}
#[derive(Debug)]
pub struct OptionType<'a> {
pub element: Box<ComponentValType<'a>>,
}
impl<'a> Parse<'a> for OptionType<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::option>()?;
Ok(Self {
element: Box::new(parser.parse()?),
})
}
}
#[derive(Debug)]
pub struct ResultType<'a> {
pub ok: Option<Box<ComponentValType<'a>>>,
pub err: Option<Box<ComponentValType<'a>>>,
}
impl<'a> Parse<'a> for ResultType<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::result>()?;
let ok: Option<ComponentValType> = parser.parse()?;
let err: Option<ComponentValType> = if parser.peek::<LParen>()? {
Some(parser.parens(|parser| {
parser.parse::<kw::error>()?;
parser.parse()
})?)
} else {
None
};
Ok(Self {
ok: ok.map(Box::new),
err: err.map(Box::new),
})
}
}
#[derive(Debug)]
pub struct ComponentFunctionType<'a> {
pub params: Box<[ComponentFunctionParam<'a>]>,
pub results: Box<[ComponentFunctionResult<'a>]>,
}
impl<'a> Parse<'a> for ComponentFunctionType<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut params: Vec<ComponentFunctionParam> = Vec::new();
while parser.peek2::<kw::param>()? {
params.push(parser.parens(|p| p.parse())?);
}
let mut results: Vec<ComponentFunctionResult> = Vec::new();
while parser.peek2::<kw::result>()? {
results.push(parser.parens(|p| p.parse())?);
}
Ok(Self {
params: params.into(),
results: results.into(),
})
}
}
#[derive(Debug)]
pub struct ComponentFunctionParam<'a> {
pub name: &'a str,
pub ty: ComponentValType<'a>,
}
impl<'a> Parse<'a> for ComponentFunctionParam<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::param>()?;
Ok(Self {
name: parser.parse()?,
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct ComponentFunctionResult<'a> {
pub name: Option<&'a str>,
pub ty: ComponentValType<'a>,
}
impl<'a> Parse<'a> for ComponentFunctionResult<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::result>()?;
Ok(Self {
name: parser.parse()?,
ty: parser.parse()?,
})
}
}
#[derive(Debug)]
pub struct ComponentExportType<'a> {
pub span: Span,
pub name: ComponentExternName<'a>,
pub item: ItemSig<'a>,
}
impl<'a> Parse<'a> for ComponentExportType<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let span = parser.parse::<kw::export>()?.0;
let id = parser.parse()?;
let debug_name = parser.parse()?;
let name = parser.parse()?;
let item = parser.parens(|p| {
let mut item = p.parse::<ItemSigNoName<'_>>()?.0;
item.id = id;
item.name = debug_name;
Ok(item)
})?;
Ok(Self { span, name, item })
}
}
#[derive(Debug, Default)]
pub struct ComponentType<'a> {
pub decls: Vec<ComponentTypeDecl<'a>>,
}
impl<'a> Parse<'a> for ComponentType<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.depth_check()?;
Ok(Self {
decls: parser.parse()?,
})
}
}
#[derive(Debug)]
pub enum ComponentTypeDecl<'a> {
CoreType(CoreType<'a>),
Type(Type<'a>),
Alias(Alias<'a>),
Import(ComponentImport<'a>),
Export(ComponentExportType<'a>),
}
impl<'a> Parse<'a> for ComponentTypeDecl<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut l = parser.lookahead1();
if l.peek::<kw::core>()? {
Ok(Self::CoreType(parser.parse()?))
} else if l.peek::<kw::r#type>()? {
Ok(Self::Type(Type::parse_no_inline_exports(parser)?))
} else if l.peek::<kw::alias>()? {
Ok(Self::Alias(parser.parse()?))
} else if l.peek::<kw::import>()? {
Ok(Self::Import(parser.parse()?))
} else if l.peek::<kw::export>()? {
Ok(Self::Export(parser.parse()?))
} else {
Err(l.error())
}
}
}
impl<'a> Parse<'a> for Vec<ComponentTypeDecl<'a>> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut decls = Vec::new();
while !parser.is_empty() {
decls.push(parser.parens(|parser| parser.parse())?);
}
Ok(decls)
}
}
#[derive(Debug)]
pub struct InstanceType<'a> {
pub decls: Vec<InstanceTypeDecl<'a>>,
}
impl<'a> Parse<'a> for InstanceType<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.depth_check()?;
Ok(Self {
decls: parser.parse()?,
})
}
}
#[derive(Debug)]
pub enum InstanceTypeDecl<'a> {
CoreType(CoreType<'a>),
Type(Type<'a>),
Alias(Alias<'a>),
Export(ComponentExportType<'a>),
}
impl<'a> Parse<'a> for InstanceTypeDecl<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut l = parser.lookahead1();
if l.peek::<kw::core>()? {
Ok(Self::CoreType(parser.parse()?))
} else if l.peek::<kw::r#type>()? {
Ok(Self::Type(Type::parse_no_inline_exports(parser)?))
} else if l.peek::<kw::alias>()? {
Ok(Self::Alias(parser.parse()?))
} else if l.peek::<kw::export>()? {
Ok(Self::Export(parser.parse()?))
} else {
Err(l.error())
}
}
}
impl<'a> Parse<'a> for Vec<InstanceTypeDecl<'a>> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut decls = Vec::new();
while !parser.is_empty() {
decls.push(parser.parens(|parser| parser.parse())?);
}
Ok(decls)
}
}
#[derive(Debug)]
pub struct ResourceType<'a> {
pub rep: core::ValType<'a>,
pub dtor: Option<CoreItemRef<'a, kw::func>>,
}
impl<'a> Parse<'a> for ResourceType<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let rep = parser.parens(|p| {
p.parse::<kw::rep>()?;
p.parse()
})?;
let dtor = if parser.is_empty() {
None
} else {
Some(parser.parens(|p| {
p.parse::<kw::dtor>()?;
p.parens(|p| p.parse())
})?)
};
Ok(Self { rep, dtor })
}
}
#[derive(Debug)]
pub struct ComponentValTypeUse<'a>(pub ComponentValType<'a>);
impl<'a> Parse<'a> for ComponentValTypeUse<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
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))),
}
}
}
#[derive(Debug, Clone)]
pub enum CoreTypeUse<'a, T> {
Ref(CoreItemRef<'a, kw::r#type>),
Inline(T),
}
impl<'a, T: Parse<'a>> Parse<'a> for CoreTypeUse<'a, T> {
fn parse(parser: Parser<'a>) -> Result<Self> {
if parser.peek::<LParen>()? && parser.peek2::<CoreItemRef<'a, kw::r#type>>()? {
Ok(Self::Ref(parser.parens(|parser| parser.parse())?))
} else {
Ok(Self::Inline(parser.parse()?))
}
}
}
impl<T> 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,
})
}
}
#[derive(Debug, Clone)]
pub enum ComponentTypeUse<'a, T> {
Ref(ItemRef<'a, kw::r#type>),
Inline(T),
}
impl<'a, T: Parse<'a>> Parse<'a> for ComponentTypeUse<'a, T> {
fn parse(parser: Parser<'a>) -> Result<Self> {
if parser.peek::<LParen>()? && parser.peek2::<ItemRef<'a, kw::r#type>>()? {
Ok(Self::Ref(parser.parens(|parser| parser.parse())?))
} else {
Ok(Self::Inline(parser.parse()?))
}
}
}
impl<T> 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(),
})
}
}