summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wast/src/component/types.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/wast/src/component/types.rs
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/wast/src/component/types.rs')
-rw-r--r--third_party/rust/wast/src/component/types.rs991
1 files changed, 991 insertions, 0 deletions
diff --git a/third_party/rust/wast/src/component/types.rs b/third_party/rust/wast/src/component/types.rs
new file mode 100644
index 0000000000..72eced02a8
--- /dev/null
+++ b/third_party/rust/wast/src/component/types.rs
@@ -0,0 +1,991 @@
+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<Id<'a>>,
+ /// An optional name for this type stored in the custom `name` section.
+ pub name: Option<NameAnnotation<'a>>,
+ /// The core type's definition.
+ 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,
+ })
+ }
+}
+
+/// 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<Self> {
+ if parser.peek::<kw::module>()? {
+ parser.parse::<kw::module>()?;
+ 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<ModuleTypeDecl<'a>>,
+}
+
+impl<'a> Parse<'a> for ModuleType<'a> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ 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<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)
+ }
+}
+
+/// 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<Id<'a>>,
+ /// An optional name for this type stored in the custom `name` section.
+ pub name: Option<NameAnnotation<'a>>,
+ /// 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<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,
+ })
+ }
+}
+
+/// 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<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 {
+ // 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<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"
+ }
+}
+
+/// 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<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"
+ }
+}
+
+/// 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<Self> {
+ if parser.peek::<LParen>()? {
+ 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<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"
+ }
+}
+
+/// A record defined type.
+#[derive(Debug)]
+pub struct Record<'a> {
+ /// The fields of the record.
+ 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 })
+ }
+}
+
+/// 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<Self> {
+ parser.parse::<kw::field>()?;
+ 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<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 })
+ }
+}
+
+/// 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<Id<'a>>,
+ /// The name of the case.
+ pub name: &'a str,
+ /// The optional type of the case.
+ pub ty: Option<ComponentValType<'a>>,
+ /// The optional refinement.
+ 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,
+ })
+ }
+}
+
+/// 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<Self> {
+ parser.parens(|parser| {
+ let span = parser.parse::<kw::refines>()?.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<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()?),
+ })
+ }
+}
+
+/// A tuple type.
+#[derive(Debug)]
+pub struct Tuple<'a> {
+ /// The types of the fields of the tuple.
+ 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 })
+ }
+}
+
+/// 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<Self> {
+ parser.parse::<kw::flags>()?;
+ 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<Self> {
+ parser.parse::<kw::enum_>()?;
+ 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<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()?),
+ })
+ }
+}
+
+/// A result type.
+#[derive(Debug)]
+pub struct ResultType<'a> {
+ /// The type on success.
+ pub ok: Option<Box<ComponentValType<'a>>>,
+ /// The type on failure.
+ 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),
+ })
+ }
+}
+
+/// 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<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(),
+ })
+ }
+}
+
+/// 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<Self> {
+ parser.parse::<kw::param>()?;
+ 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<Self> {
+ parser.parse::<kw::result>()?;
+ 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<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 })
+ }
+}
+
+/// A type definition for a component type.
+#[derive(Debug, Default)]
+pub struct ComponentType<'a> {
+ /// The declarations of the component type.
+ 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()?,
+ })
+ }
+}
+
+/// 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<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)
+ }
+}
+
+/// A type definition for an instance type.
+#[derive(Debug)]
+pub struct InstanceType<'a> {
+ /// The declarations of the instance type.
+ 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()?,
+ })
+ }
+}
+
+/// 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<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)
+ }
+}
+
+/// 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<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 })
+ }
+}
+
+/// 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<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))),
+ }
+ }
+}
+
+/// 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<Self> {
+ // Here the core context is assumed, so no core prefix is expected
+ 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,
+ })
+ }
+}
+
+/// 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<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(),
+ })
+ }
+}