1use crate::component::*;
2use crate::core;
3use crate::kw;
4use crate::parser::{Parse, Parser, Result};
5use crate::token::{Id, LParen, NameAnnotation, Span};
6
7/// A core instance defined by instantiation or exporting core items.
8#[derive(Debug)]
9pub struct CoreInstance<'a> {
10 /// Where this `core instance` was defined.
11 pub span: Span,
12 /// An identifier that this instance is resolved with (optionally) for name
13 /// resolution.
14 pub id: Option<Id<'a>>,
15 /// An optional name for this instance stored in the custom `name` section.
16 pub name: Option<NameAnnotation<'a>>,
17 /// What kind of instance this is.
18 pub kind: CoreInstanceKind<'a>,
19}
20
21impl<'a> Parse<'a> for CoreInstance<'a> {
22 fn parse(parser: Parser<'a>) -> Result<Self> {
23 let span: Span = parser.parse::<kw::core>()?.0;
24 parser.parse::<kw::instance>()?;
25 let id: Option> = parser.parse()?;
26 let name: Option> = parser.parse()?;
27 let kind: CoreInstanceKind<'a> = parser.parse()?;
28
29 Ok(Self {
30 span,
31 id,
32 name,
33 kind,
34 })
35 }
36}
37
38/// The kinds of core instances in the text format.
39#[derive(Debug)]
40pub enum CoreInstanceKind<'a> {
41 /// Instantiate a core module.
42 Instantiate {
43 /// The module being instantiated.
44 module: ItemRef<'a, kw::module>,
45 /// Arguments used to instantiate the instance.
46 args: Vec<CoreInstantiationArg<'a>>,
47 },
48 /// The instance is defined by exporting local items as an instance.
49 BundleOfExports(Vec<CoreInstanceExport<'a>>),
50}
51
52impl<'a> Parse<'a> for CoreInstanceKind<'a> {
53 fn parse(parser: Parser<'a>) -> Result<Self> {
54 if parser.peek::<LParen>()? && parser.peek2::<kw::instantiate>()? {
55 parser.parens(|parser: Parser<'a>| {
56 parser.parse::<kw::instantiate>()?;
57 Ok(Self::Instantiate {
58 module: parser.parse::<IndexOrRef<'_, _>>()?.0,
59 args: parser.parse()?,
60 })
61 })
62 } else {
63 Ok(Self::BundleOfExports(parser.parse()?))
64 }
65 }
66}
67
68impl Default for kw::module {
69 fn default() -> kw::module {
70 kw::module(Span::from_offset(0))
71 }
72}
73
74/// An argument to instantiate a core module.
75#[derive(Debug)]
76pub struct CoreInstantiationArg<'a> {
77 /// The name of the instantiation argument.
78 pub name: &'a str,
79 /// The kind of core instantiation argument.
80 pub kind: CoreInstantiationArgKind<'a>,
81}
82
83impl<'a> Parse<'a> for CoreInstantiationArg<'a> {
84 fn parse(parser: Parser<'a>) -> Result<Self> {
85 parser.parse::<kw::with>()?;
86 Ok(Self {
87 name: parser.parse()?,
88 kind: parser.parse()?,
89 })
90 }
91}
92
93impl<'a> Parse<'a> for Vec<CoreInstantiationArg<'a>> {
94 fn parse(parser: Parser<'a>) -> Result<Self> {
95 let mut args: Vec> = Vec::new();
96 while !parser.is_empty() {
97 args.push(parser.parens(|parser: Parser<'a>| parser.parse())?);
98 }
99 Ok(args)
100 }
101}
102
103/// The kind of core instantiation argument.
104#[derive(Debug)]
105pub enum CoreInstantiationArgKind<'a> {
106 /// The argument is a reference to an instance.
107 Instance(CoreItemRef<'a, kw::instance>),
108 /// The argument is an instance created from local exported core items.
109 ///
110 /// This is syntactic sugar for defining a core instance and also using it
111 /// as an instantiation argument.
112 BundleOfExports(Span, Vec<CoreInstanceExport<'a>>),
113}
114
115impl<'a> Parse<'a> for CoreInstantiationArgKind<'a> {
116 fn parse(parser: Parser<'a>) -> Result<Self> {
117 parser.parens(|parser: Parser<'a>| {
118 if let Some(r: CoreItemRef<'_, instance>) = parser.parse()? {
119 Ok(Self::Instance(r))
120 } else {
121 let span: Span = parser.parse::<kw::instance>()?.0;
122 Ok(Self::BundleOfExports(span, parser.parse()?))
123 }
124 })
125 }
126}
127
128/// An exported item as part of a core instance.
129#[derive(Debug)]
130pub struct CoreInstanceExport<'a> {
131 /// Where this export was defined.
132 pub span: Span,
133 /// The name of this export from the instance.
134 pub name: &'a str,
135 /// What's being exported from the instance.
136 pub item: CoreItemRef<'a, core::ExportKind>,
137}
138
139impl<'a> Parse<'a> for CoreInstanceExport<'a> {
140 fn parse(parser: Parser<'a>) -> Result<Self> {
141 Ok(Self {
142 span: parser.parse::<kw::export>()?.0,
143 name: parser.parse()?,
144 item: parser.parens(|parser: Parser<'a>| parser.parse())?,
145 })
146 }
147}
148
149impl<'a> Parse<'a> for Vec<CoreInstanceExport<'a>> {
150 fn parse(parser: Parser<'a>) -> Result<Self> {
151 let mut exports: Vec> = Vec::new();
152 while !parser.is_empty() {
153 exports.push(parser.parens(|parser: Parser<'a>| parser.parse())?);
154 }
155 Ok(exports)
156 }
157}
158
159/// A component instance defined by instantiation or exporting items.
160#[derive(Debug)]
161pub struct Instance<'a> {
162 /// Where this `instance` was defined.
163 pub span: Span,
164 /// An identifier that this instance is resolved with (optionally) for name
165 /// resolution.
166 pub id: Option<Id<'a>>,
167 /// An optional name for this instance stored in the custom `name` section.
168 pub name: Option<NameAnnotation<'a>>,
169 /// If present, inline export annotations which indicate names this
170 /// definition should be exported under.
171 pub exports: InlineExport<'a>,
172 /// What kind of instance this is.
173 pub kind: InstanceKind<'a>,
174}
175
176impl<'a> Parse<'a> for Instance<'a> {
177 fn parse(parser: Parser<'a>) -> Result<Self> {
178 let span: Span = parser.parse::<kw::instance>()?.0;
179 let id: Option> = parser.parse()?;
180 let name: Option> = parser.parse()?;
181 let exports: InlineExport<'a> = parser.parse()?;
182 let kind: InstanceKind<'a> = parser.parse()?;
183
184 Ok(Self {
185 span,
186 id,
187 name,
188 exports,
189 kind,
190 })
191 }
192}
193
194/// The kinds of instances in the text format.
195#[derive(Debug)]
196pub enum InstanceKind<'a> {
197 /// The `(instance (import "x"))` sugar syntax
198 Import {
199 /// The name of the import
200 import: InlineImport<'a>,
201 /// The type of the instance being imported
202 ty: ComponentTypeUse<'a, InstanceType<'a>>,
203 },
204 /// Instantiate a component.
205 Instantiate {
206 /// The component being instantiated.
207 component: ItemRef<'a, kw::component>,
208 /// Arguments used to instantiate the instance.
209 args: Vec<InstantiationArg<'a>>,
210 },
211 /// The instance is defined by exporting local items as an instance.
212 BundleOfExports(Vec<ComponentExport<'a>>),
213}
214
215impl<'a> Parse<'a> for InstanceKind<'a> {
216 fn parse(parser: Parser<'a>) -> Result<Self> {
217 if let Some(import: InlineImport<'a>) = parser.parse()? {
218 return Ok(Self::Import {
219 import,
220 ty: parser.parse()?,
221 });
222 }
223
224 if parser.peek::<LParen>()? && parser.peek2::<kw::instantiate>()? {
225 parser.parens(|parser: Parser<'a>| {
226 parser.parse::<kw::instantiate>()?;
227 Ok(Self::Instantiate {
228 component: parser.parse::<IndexOrRef<'_, _>>()?.0,
229 args: parser.parse()?,
230 })
231 })
232 } else {
233 Ok(Self::BundleOfExports(parser.parse()?))
234 }
235 }
236}
237
238impl Default for kw::component {
239 fn default() -> kw::component {
240 kw::component(Span::from_offset(0))
241 }
242}
243
244/// An argument to instantiate a component.
245#[derive(Debug)]
246pub struct InstantiationArg<'a> {
247 /// The name of the instantiation argument.
248 pub name: &'a str,
249 /// The kind of instantiation argument.
250 pub kind: InstantiationArgKind<'a>,
251}
252
253impl<'a> Parse<'a> for InstantiationArg<'a> {
254 fn parse(parser: Parser<'a>) -> Result<Self> {
255 parser.parse::<kw::with>()?;
256 Ok(Self {
257 name: parser.parse()?,
258 kind: parser.parse()?,
259 })
260 }
261}
262
263impl<'a> Parse<'a> for Vec<InstantiationArg<'a>> {
264 fn parse(parser: Parser<'a>) -> Result<Self> {
265 let mut args: Vec> = Vec::new();
266 while !parser.is_empty() {
267 args.push(parser.parens(|parser: Parser<'a>| parser.parse())?);
268 }
269 Ok(args)
270 }
271}
272
273/// The kind of instantiation argument.
274#[derive(Debug)]
275pub enum InstantiationArgKind<'a> {
276 /// The argument is a reference to a component item.
277 Item(ComponentExportKind<'a>),
278 /// The argument is an instance created from local exported items.
279 ///
280 /// This is syntactic sugar for defining an instance and also using it
281 /// as an instantiation argument.
282 BundleOfExports(Span, Vec<ComponentExport<'a>>),
283}
284
285impl<'a> Parse<'a> for InstantiationArgKind<'a> {
286 fn parse(parser: Parser<'a>) -> Result<Self> {
287 if let Some(item: ComponentExportKind<'_>) = parser.parse()? {
288 Ok(Self::Item(item))
289 } else {
290 parser.parens(|parser: Parser<'a>| {
291 let span: Span = parser.parse::<kw::instance>()?.0;
292 Ok(Self::BundleOfExports(span, parser.parse()?))
293 })
294 }
295 }
296}
297