Skip to main content

wit_parser/
decoding.rs

1use crate::*;
2use alloc::string::{String, ToString};
3use alloc::vec;
4use alloc::vec::Vec;
5use anyhow::Result;
6use anyhow::{Context, anyhow, bail};
7use core::mem;
8use std::io::Read;
9use wasmparser::Chunk;
10use wasmparser::{
11    ComponentExternalKind, Parser, Payload, PrimitiveValType, ValidPayload, Validator,
12    WasmFeatures,
13    component_types::{
14        ComponentAnyTypeId, ComponentDefinedType, ComponentEntityType, ComponentItem,
15        ComponentType, ComponentValType,
16    },
17    names::{
18        AccessorKind as ComponentAccessorKind, ComponentName, ComponentNameKind, ResourceFuncKind,
19    },
20    types,
21    types::Types,
22};
23
24/// Represents information about a decoded WebAssembly component.
25struct ComponentInfo {
26    /// Wasmparser-defined type information learned after a component is fully
27    /// validated.
28    types: types::Types,
29    /// List of all imports and exports from this component.
30    externs: Vec<(String, Extern)>,
31    /// Decoded package metadata
32    package_metadata: Option<PackageMetadata>,
33}
34
35enum Extern {
36    Import(ComponentItem),
37    Export(ComponentItem),
38}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41enum WitEncodingVersion {
42    V1,
43    V2,
44}
45
46impl ComponentInfo {
47    /// Creates a new component info by parsing the given WebAssembly component bytes.
48    fn from_reader(mut reader: impl Read) -> Result<Self> {
49        let mut validator = Validator::new_with_features(WasmFeatures::all());
50        let mut externs = Vec::new();
51        let mut depth = 1;
52        let mut types = None;
53        let mut _package_metadata = None;
54        let mut cur = Parser::new(0);
55        let mut eof = false;
56        let mut stack = Vec::new();
57        let mut buffer = Vec::new();
58
59        loop {
60            let chunk = cur.parse(&buffer, eof)?;
61            let (payload, consumed) = match chunk {
62                Chunk::NeedMoreData(hint) => {
63                    assert!(!eof); // otherwise an error would be returned
64
65                    // Use the hint to preallocate more space, then read
66                    // some more data into our buffer.
67                    //
68                    // Note that the buffer management here is not ideal,
69                    // but it's compact enough to fit in an example!
70                    let len = buffer.len();
71                    buffer.extend((0..hint).map(|_| 0u8));
72                    let n = reader.read(&mut buffer[len..])?;
73                    buffer.truncate(len + n);
74                    eof = n == 0;
75                    continue;
76                }
77
78                Chunk::Parsed { consumed, payload } => (payload, consumed),
79            };
80            match validator.payload(&payload)? {
81                ValidPayload::Ok => {}
82                ValidPayload::Parser(_) => depth += 1,
83                ValidPayload::End(t) => {
84                    depth -= 1;
85                    if depth == 0 {
86                        types = Some(t);
87                    }
88                }
89                ValidPayload::Func(..) => {}
90            }
91
92            match payload {
93                Payload::ComponentImportSection(s) if depth == 1 => {
94                    for import in s {
95                        let import = import?;
96                        let ty = validator
97                            .types(0)
98                            .unwrap()
99                            .component_item_for_import(import.name.name)
100                            .unwrap();
101                        externs.push((import.name.name.to_string(), Extern::Import(ty.clone())));
102                    }
103                }
104                Payload::ComponentExportSection(s) if depth == 1 => {
105                    for export in s {
106                        let export = export?;
107                        let ty = validator
108                            .types(0)
109                            .unwrap()
110                            .component_item_for_export(export.name.name)
111                            .unwrap();
112                        externs.push((export.name.name.to_string(), Extern::Export(ty.clone())));
113                    }
114                }
115                #[cfg(feature = "serde")]
116                Payload::CustomSection(s) if s.name() == PackageMetadata::SECTION_NAME => {
117                    if _package_metadata.is_some() {
118                        bail!("multiple {:?} sections", PackageMetadata::SECTION_NAME);
119                    }
120                    _package_metadata = Some(PackageMetadata::decode(s.data())?);
121                }
122                Payload::ModuleSection { parser, .. }
123                | Payload::ComponentSection { parser, .. } => {
124                    stack.push(cur.clone());
125                    cur = parser.clone();
126                }
127                Payload::End(_) => {
128                    if let Some(parent_parser) = stack.pop() {
129                        cur = parent_parser.clone();
130                    } else {
131                        break;
132                    }
133                }
134                _ => {}
135            }
136
137            // once we're done processing the payload we can forget the
138            // original.
139            buffer.drain(..consumed);
140        }
141
142        Ok(Self {
143            types: types.unwrap(),
144            externs,
145            package_metadata: _package_metadata,
146        })
147    }
148
149    fn is_wit_package(&self) -> Option<WitEncodingVersion> {
150        // all wit package exports must be component types, and there must be at
151        // least one
152        if self.externs.is_empty() {
153            return None;
154        }
155
156        if !self.externs.iter().all(|(_, item)| {
157            let export = match item {
158                Extern::Export(e) => e,
159                _ => return false,
160            };
161            match export.ty {
162                ComponentEntityType::Type { created, .. } => {
163                    matches!(created, ComponentAnyTypeId::Component(_))
164                }
165                _ => false,
166            }
167        }) {
168            return None;
169        }
170
171        // The distinction between v1 and v2 encoding formats is the structure of the export
172        // strings for each component. The v1 format uses "<namespace>:<package>/wit" as the name
173        // for the top-level exports, while the v2 format uses the unqualified name of the encoded
174        // entity.
175        match crate::parse_component_name(&self.externs[0].0).ok()?.kind() {
176            ComponentNameKind::Interface(name) if name.interface().as_str() == "wit" => {
177                Some(WitEncodingVersion::V1)
178            }
179            ComponentNameKind::Plain(name) if name.is_bare() => Some(WitEncodingVersion::V2),
180            _ => None,
181        }
182    }
183
184    fn decode_wit_v1_package(&self) -> Result<(Resolve, PackageId)> {
185        let mut decoder = WitPackageDecoder::new(&self.types);
186
187        let mut pkg = None;
188        for (name, item) in self.externs.iter() {
189            let export = match item {
190                Extern::Export(e) => e,
191                _ => unreachable!(),
192            };
193            if pkg.is_some() {
194                bail!("more than one top-level exported component type found");
195            }
196            let name = crate::parse_component_name(name).unwrap();
197            pkg = Some(
198                decoder
199                    .decode_v1_package(&name, export)
200                    .with_context(|| format!("failed to decode document `{name}`"))?,
201            );
202        }
203
204        let pkg = pkg.ok_or_else(|| anyhow!("no exported component type found"))?;
205        let (mut resolve, package) = decoder.finish(pkg)?;
206        if let Some(package_metadata) = &self.package_metadata {
207            package_metadata.inject(&mut resolve, package)?;
208        }
209        Ok((resolve, package))
210    }
211
212    fn decode_wit_v2_package(&self) -> Result<(Resolve, PackageId)> {
213        let mut decoder = WitPackageDecoder::new(&self.types);
214
215        let mut pkg_name = None;
216
217        let mut interfaces = IndexMap::default();
218        let mut worlds = IndexMap::default();
219        let mut fields = PackageFields {
220            interfaces: &mut interfaces,
221            worlds: &mut worlds,
222        };
223
224        for (_, item) in self.externs.iter() {
225            let export = match item {
226                Extern::Export(e) => e,
227                _ => unreachable!(),
228            };
229            let component = match export.ty {
230                ComponentEntityType::Type {
231                    created: ComponentAnyTypeId::Component(id),
232                    ..
233                } => &self.types[id],
234                _ => unreachable!(),
235            };
236
237            // The single export of this component will determine if it's a world or an interface:
238            // worlds export a component, while interfaces export an instance.
239            if component.exports.len() != 1 {
240                bail!(
241                    "Expected a single export, but found {} instead",
242                    component.exports.len()
243                );
244            }
245
246            let name = component.exports.keys().nth(0).unwrap();
247
248            let item = &component.exports[name];
249            let name = match item.ty {
250                ComponentEntityType::Component(_) => {
251                    let package_name = decoder.decode_world(name.as_str(), item, &mut fields)?;
252                    package_name
253                }
254                ComponentEntityType::Instance(_) => {
255                    let package_name = decoder.decode_interface(
256                        name.as_str(),
257                        &component.imports,
258                        item,
259                        &mut fields,
260                    )?;
261                    package_name
262                }
263                _ => unreachable!(),
264            };
265
266            if let Some(pkg_name) = pkg_name.as_ref() {
267                // TODO: when we have fully switched to the v2 format, we should switch to parsing
268                // multiple wit documents instead of bailing.
269                if pkg_name != &name {
270                    bail!("item defined with mismatched package name")
271                }
272            } else {
273                pkg_name.replace(name);
274            }
275        }
276
277        let pkg = if let Some(name) = pkg_name {
278            Package {
279                name,
280                docs: Docs::default(),
281                interfaces,
282                worlds,
283            }
284        } else {
285            bail!("no exported component type found");
286        };
287
288        let (mut resolve, package) = decoder.finish(pkg)?;
289        if let Some(package_metadata) = &self.package_metadata {
290            package_metadata.inject(&mut resolve, package)?;
291        }
292        Ok((resolve, package))
293    }
294
295    fn decode_component(&self) -> Result<(Resolve, WorldId)> {
296        assert!(self.is_wit_package().is_none());
297        let mut decoder = WitPackageDecoder::new(&self.types);
298        // Note that this name is arbitrarily chosen. We may one day perhaps
299        // want to encode this in the component binary format itself, but for
300        // now it shouldn't be an issue to have a defaulted name here.
301        let world_name = "root";
302        let world = decoder.resolve.worlds.alloc(World {
303            name: world_name.to_string(),
304            docs: Default::default(),
305            imports: Default::default(),
306            exports: Default::default(),
307            package: None,
308            includes: Default::default(),
309            stability: Default::default(),
310            span: Default::default(),
311        });
312        let mut package = Package {
313            // Similar to `world_name` above this is arbitrarily chosen as it's
314            // not otherwise encoded in a binary component. This theoretically
315            // shouldn't cause issues, however.
316            name: PackageName {
317                namespace: "root".to_string(),
318                version: None,
319                name: "component".to_string(),
320            },
321            docs: Default::default(),
322            worlds: [(world_name.to_string(), world)].into_iter().collect(),
323            interfaces: Default::default(),
324        };
325
326        let mut fields = PackageFields {
327            worlds: &mut package.worlds,
328            interfaces: &mut package.interfaces,
329        };
330
331        for (name, item) in self.externs.iter() {
332            match item {
333                Extern::Import(i) => {
334                    decoder.decode_component_import(name, i, world, &mut fields)?
335                }
336                Extern::Export(e) => {
337                    decoder.decode_component_export(name, e, world, &mut fields)?
338                }
339            }
340        }
341
342        let (mut resolve, pkg) = decoder.finish(package)?;
343        if let Some(package_metadata) = &self.package_metadata {
344            package_metadata.inject(&mut resolve, pkg)?;
345        }
346        Ok((resolve, world))
347    }
348}
349
350/// Result of the [`decode`] function.
351pub enum DecodedWasm {
352    /// The input to [`decode`] was one or more binary-encoded WIT package(s).
353    ///
354    /// The full resolve graph is here plus the identifier of the packages that
355    /// were encoded. Note that other packages may be within the resolve if any
356    /// of the main packages refer to other, foreign packages.
357    WitPackage(Resolve, PackageId),
358
359    /// The input to [`decode`] was a component and its interface is specified
360    /// by the world here.
361    Component(Resolve, WorldId),
362}
363
364impl DecodedWasm {
365    /// Returns the [`Resolve`] for WIT types contained.
366    pub fn resolve(&self) -> &Resolve {
367        match self {
368            DecodedWasm::WitPackage(resolve, _) => resolve,
369            DecodedWasm::Component(resolve, _) => resolve,
370        }
371    }
372
373    /// Returns the main packages of what was decoded.
374    pub fn package(&self) -> PackageId {
375        match self {
376            DecodedWasm::WitPackage(_, id) => *id,
377            DecodedWasm::Component(resolve, world) => resolve.worlds[*world].package.unwrap(),
378        }
379    }
380}
381
382/// Decode for incremental reading
383pub fn decode_reader(reader: impl Read) -> Result<DecodedWasm> {
384    let info = ComponentInfo::from_reader(reader)?;
385
386    if let Some(version) = info.is_wit_package() {
387        match version {
388            WitEncodingVersion::V1 => {
389                log::debug!("decoding a v1 WIT package encoded as wasm");
390                let (resolve, pkg) = info.decode_wit_v1_package()?;
391                Ok(DecodedWasm::WitPackage(resolve, pkg))
392            }
393            WitEncodingVersion::V2 => {
394                log::debug!("decoding a v2 WIT package encoded as wasm");
395                let (resolve, pkg) = info.decode_wit_v2_package()?;
396                Ok(DecodedWasm::WitPackage(resolve, pkg))
397            }
398        }
399    } else {
400        log::debug!("inferring the WIT of a concrete component");
401        let (resolve, world) = info.decode_component()?;
402        Ok(DecodedWasm::Component(resolve, world))
403    }
404}
405
406/// Decodes an in-memory WebAssembly binary into a WIT [`Resolve`] and
407/// associated metadata.
408///
409/// The WebAssembly binary provided here can either be a
410/// WIT-package-encoded-as-binary or an actual component itself. A [`Resolve`]
411/// is always created and the return value indicates which was detected.
412pub fn decode(bytes: &[u8]) -> Result<DecodedWasm> {
413    decode_reader(bytes)
414}
415
416/// Decodes the single component type `world` specified as a WIT world.
417///
418/// The `world` should be an exported component type. The `world` must have been
419/// previously created via `encode_world` meaning that it is a component that
420/// itself imports nothing and exports a single component, and the single
421/// component export represents the world. The name of the export is also the
422/// name of the package/world/etc.
423pub fn decode_world(wasm: &[u8]) -> Result<(Resolve, WorldId)> {
424    let mut validator = Validator::new_with_features(WasmFeatures::all());
425    let mut exports = Vec::new();
426    let mut depth = 1;
427    let mut types = None;
428
429    for payload in Parser::new(0).parse_all(wasm) {
430        let payload = payload?;
431
432        match validator.payload(&payload)? {
433            ValidPayload::Ok => {}
434            ValidPayload::Parser(_) => depth += 1,
435            ValidPayload::End(t) => {
436                depth -= 1;
437                if depth == 0 {
438                    types = Some(t);
439                }
440            }
441            ValidPayload::Func(..) => {}
442        }
443
444        match payload {
445            Payload::ComponentExportSection(s) if depth == 1 => {
446                for export in s {
447                    exports.push(export?);
448                }
449            }
450            _ => {}
451        }
452    }
453
454    if exports.len() != 1 {
455        bail!("expected one export in component");
456    }
457    if exports[0].kind != ComponentExternalKind::Type {
458        bail!("expected an export of a type");
459    }
460    if exports[0].ty.is_some() {
461        bail!("expected an un-ascribed exported type");
462    }
463    let types = types.as_ref().unwrap();
464    let world = match types.as_ref().component_any_type_at(exports[0].index) {
465        ComponentAnyTypeId::Component(c) => c,
466        _ => bail!("expected an exported component type"),
467    };
468
469    let mut decoder = WitPackageDecoder::new(types);
470    let mut interfaces = IndexMap::default();
471    let mut worlds = IndexMap::default();
472    let ty = &types[world];
473    assert_eq!(ty.imports.len(), 0);
474    assert_eq!(ty.exports.len(), 1);
475    let name = ty.exports.keys().nth(0).unwrap();
476    let name = decoder.decode_world(
477        name,
478        &ty.exports[0],
479        &mut PackageFields {
480            interfaces: &mut interfaces,
481            worlds: &mut worlds,
482        },
483    )?;
484    let (resolve, pkg) = decoder.finish(Package {
485        name,
486        interfaces,
487        worlds,
488        docs: Default::default(),
489    })?;
490    // The package decoded here should only have a single world so extract that
491    // here to return.
492    let world = *resolve.packages[pkg].worlds.iter().next().unwrap().1;
493    Ok((resolve, world))
494}
495
496struct PackageFields<'a> {
497    interfaces: &'a mut IndexMap<String, InterfaceId>,
498    worlds: &'a mut IndexMap<String, WorldId>,
499}
500
501struct WitPackageDecoder<'a> {
502    resolve: Resolve,
503    types: &'a Types,
504    foreign_packages: IndexMap<String, Package>,
505    iface_to_package_index: HashMap<InterfaceId, usize>,
506    named_interfaces: HashMap<String, InterfaceId>,
507
508    /// A map which tracks named resources to what their corresponding `TypeId`
509    /// is. This first layer of key in this map is the owner scope of a
510    /// resource, more-or-less the `world` or `interface` that it's defined
511    /// within. The second layer of this map is keyed by name of the resource
512    /// and points to the actual ID of the resource.
513    ///
514    /// This map is populated in `register_type_export`.
515    resources: HashMap<TypeOwner, HashMap<String, TypeId>>,
516
517    /// A map from a type id to what it's been translated to.
518    type_map: HashMap<ComponentAnyTypeId, TypeId>,
519}
520
521impl WitPackageDecoder<'_> {
522    fn new<'a>(types: &'a Types) -> WitPackageDecoder<'a> {
523        WitPackageDecoder {
524            resolve: Resolve::default(),
525            types,
526            type_map: HashMap::new(),
527            foreign_packages: Default::default(),
528            iface_to_package_index: Default::default(),
529            named_interfaces: Default::default(),
530            resources: Default::default(),
531        }
532    }
533
534    fn decode_v1_package(&mut self, name: &ComponentName, item: &ComponentItem) -> Result<Package> {
535        let ty = match item.ty {
536            ComponentEntityType::Type {
537                created: ComponentAnyTypeId::Component(id),
538                ..
539            } => &self.types[id],
540            _ => unreachable!(),
541        };
542
543        // Process all imports for this package first, where imports are
544        // importing from remote packages.
545        for (name, item) in ty.imports.iter() {
546            self.register_import(name, item)
547                .with_context(|| format!("failed to process import `{name}`"))?;
548        }
549
550        let mut package = Package {
551            // The name encoded for packages must be of the form `foo:bar/wit`
552            // where "wit" is just a placeholder for now. The package name in
553            // this case would be `foo:bar`.
554            name: match name.kind() {
555                ComponentNameKind::Interface(name) if name.interface().as_str() == "wit" => {
556                    name.to_package_name(item)?
557                }
558                _ => bail!("package name is not a valid id: {name}"),
559            },
560            docs: Default::default(),
561            interfaces: Default::default(),
562            worlds: Default::default(),
563        };
564
565        let mut fields = PackageFields {
566            interfaces: &mut package.interfaces,
567            worlds: &mut package.worlds,
568        };
569
570        for (name, ty) in ty.exports.iter() {
571            match ty.ty {
572                ComponentEntityType::Instance(_) => {
573                    self.register_interface(name.as_str(), ty, &mut fields)
574                        .with_context(|| format!("failed to process export `{name}`"))?;
575                }
576                ComponentEntityType::Component(idx) => {
577                    let ty = &self.types[idx];
578                    self.register_world(name.as_str(), ty, &mut fields)
579                        .with_context(|| format!("failed to process export `{name}`"))?;
580                }
581                _ => bail!("component export `{name}` is not an instance or component"),
582            }
583        }
584        Ok(package)
585    }
586
587    fn decode_interface<'a>(
588        &mut self,
589        name: &str,
590        imports: &wasmparser::collections::IndexMap<String, ComponentItem>,
591        item: &ComponentItem,
592        fields: &mut PackageFields<'a>,
593    ) -> Result<PackageName> {
594        let component_name = self
595            .parse_component_name(name)
596            .context("expected world name to have an ID form")?;
597
598        let package = match component_name.kind() {
599            ComponentNameKind::Interface(name) => name.to_package_name(item)?,
600            _ => bail!("expected world name to be fully qualified"),
601        };
602
603        for (name, ty) in imports.iter() {
604            self.register_import(name, ty)
605                .with_context(|| format!("failed to process import `{name}`"))?;
606        }
607
608        let _ = self.register_interface(name, item, fields)?;
609
610        Ok(package)
611    }
612
613    fn decode_world<'a>(
614        &mut self,
615        name: &str,
616        item: &ComponentItem,
617        fields: &mut PackageFields<'a>,
618    ) -> Result<PackageName> {
619        let ty = match item.ty {
620            ComponentEntityType::Component(ty) => &self.types[ty],
621            _ => unreachable!(),
622        };
623        let kebab_name = self
624            .parse_component_name(name)
625            .context("expected world name to have an ID form")?;
626
627        let package = match kebab_name.kind() {
628            ComponentNameKind::Interface(name) => name.to_package_name(item)?,
629            _ => bail!("expected world name to be fully qualified"),
630        };
631
632        let _ = self.register_world(name, ty, fields)?;
633
634        Ok(package)
635    }
636
637    fn decode_component_import<'a>(
638        &mut self,
639        name: &str,
640        item: &ComponentItem,
641        world: WorldId,
642        package: &mut PackageFields<'a>,
643    ) -> Result<()> {
644        log::debug!("decoding component import `{name}`");
645        let owner = TypeOwner::World(world);
646        let (name, item) = match item.ty {
647            ComponentEntityType::Instance(_) => self
648                .decode_world_instance(name, item, package)
649                .with_context(|| format!("failed to decode WIT from import `{name}`"))?,
650            ComponentEntityType::Func(_) => {
651                let func = self
652                    .convert_function(name, item, owner)
653                    .with_context(|| format!("failed to decode function from import `{name}`"))?;
654                (WorldKey::Name(name.to_string()), WorldItem::Function(func))
655            }
656            ComponentEntityType::Type { .. } => {
657                let id = self
658                    .register_type_export(name, item, owner)
659                    .with_context(|| format!("failed to decode type from export `{name}`"))?;
660                (
661                    WorldKey::Name(name.to_string()),
662                    WorldItem::Type {
663                        id,
664                        span: Default::default(),
665                    },
666                )
667            }
668            // All other imports do not form part of the component's world
669            _ => return Ok(()),
670        };
671        self.resolve.worlds[world].imports.insert(name, item);
672        Ok(())
673    }
674
675    fn decode_component_export<'a>(
676        &mut self,
677        name: &str,
678        item: &ComponentItem,
679        world: WorldId,
680        package: &mut PackageFields<'a>,
681    ) -> Result<()> {
682        log::debug!("decoding component export `{name}`");
683        let (name, item) = match item.ty {
684            ComponentEntityType::Func(_) => {
685                let func = self
686                    .convert_function(name, item, TypeOwner::World(world))
687                    .with_context(|| format!("failed to decode function from export `{name}`"))?;
688
689                (WorldKey::Name(name.to_string()), WorldItem::Function(func))
690            }
691            ComponentEntityType::Instance(_) => self
692                .decode_world_instance(name, item, package)
693                .with_context(|| format!("failed to decode WIT from export `{name}`"))?,
694            _ => {
695                bail!("component export `{name}` was not a function or instance")
696            }
697        };
698        self.resolve.worlds[world].exports.insert(name, item);
699        Ok(())
700    }
701
702    /// Decodes a component instance import/export name into a
703    /// `(WorldKey, WorldItem)` pair.
704    ///
705    /// Handles three name forms:
706    /// - `ns:pkg/iface` — qualified interface name, keyed by `InterfaceId`
707    /// - `plain-name` — unqualified name for an inline or local interface
708    /// - `plain-name (implements "...")` - reference to a preexisting interface
709    ///   elsewhere
710    fn decode_world_instance<'a>(
711        &mut self,
712        name: &str,
713        item: &ComponentItem,
714        package: &mut PackageFields<'a>,
715    ) -> Result<(WorldKey, WorldItem)> {
716        let (key, id) = match &item.implements {
717            Some(i) => {
718                let id = self.register_import(i, item)?;
719                (WorldKey::Name(name.to_string()), id)
720            }
721            None => match self.parse_component_name(name)?.kind() {
722                ComponentNameKind::Interface(i) => {
723                    let id = self.register_import(i.as_str(), item)?;
724                    (WorldKey::Interface(id), id)
725                }
726                _ => self.register_interface(name, item, package)?,
727            },
728        };
729        Ok((
730            key,
731            WorldItem::Interface {
732                id,
733                stability: Default::default(),
734                docs: Default::default(),
735                span: Default::default(),
736                external_id: item.external_id.clone(),
737            },
738        ))
739    }
740
741    /// Registers that the `name` provided is either imported interface from a
742    /// foreign package or  referencing a previously defined interface in this
743    /// package.
744    ///
745    /// This function will internally ensure that `name` is well-structured and
746    /// will fill in any information as necessary. For example with a foreign
747    /// dependency the foreign package structure, types, etc, all need to be
748    /// created. For a local dependency it's instead ensured that all the types
749    /// line up with the previous definitions.
750    fn register_import(&mut self, name: &str, item: &ComponentItem) -> Result<InterfaceId> {
751        let ty = match item.ty {
752            ComponentEntityType::Instance(idx) => &self.types[idx],
753            _ => bail!("import `{name}` is not an instance"),
754        };
755        let (is_local, interface) = match self.named_interfaces.get(name) {
756            Some(id) => (true, *id),
757            None => (false, self.extract_dep_interface(name, item)?),
758        };
759        let owner = TypeOwner::Interface(interface);
760        for (name, item) in ty.exports.iter() {
761            log::debug!("decoding import instance export `{name}`");
762            match item.ty {
763                ComponentEntityType::Type {
764                    referenced,
765                    created,
766                } => {
767                    match self.resolve.interfaces[interface]
768                        .types
769                        .get(name.as_str())
770                        .copied()
771                    {
772                        // If this name is already defined as a type in the
773                        // specified interface then that's ok. For package-local
774                        // interfaces that's expected since the interface was
775                        // fully defined. For remote interfaces it means we're
776                        // using something that was already used elsewhere. In
777                        // both cases continue along.
778                        //
779                        // Notably for the remotely defined case this will also
780                        // walk over the structure of the type and register
781                        // internal wasmparser ids with wit-parser ids. This is
782                        // necessary to ensure that anonymous types like
783                        // `list<u8>` defined in original definitions are
784                        // unified with anonymous types when duplicated inside
785                        // of worlds. Overall this prevents, for example, extra
786                        // `list<u8>` types from popping up when decoding. This
787                        // is not strictly necessary but assists with
788                        // roundtripping assertions during fuzzing.
789                        Some(id) => {
790                            log::debug!("type already exist");
791                            match referenced {
792                                ComponentAnyTypeId::Defined(ty) => {
793                                    self.register_defined(id, &self.types[ty])?;
794                                }
795                                ComponentAnyTypeId::Resource(_) => {}
796                                _ => unreachable!(),
797                            }
798                            let prev = self.type_map.insert(created, id);
799                            assert!(prev.is_none());
800                        }
801
802                        // If the name is not defined, however, then there's two
803                        // possibilities:
804                        //
805                        // * For package-local interfaces this is an error
806                        //   because the package-local interface defined
807                        //   everything already and this is referencing
808                        //   something that isn't defined.
809                        //
810                        // * For remote interfaces they're never fully declared
811                        //   so it's lazily filled in here. This means that the
812                        //   view of remote interfaces ends up being the minimal
813                        //   slice needed for this resolve, which is what's
814                        //   intended.
815                        None => {
816                            if is_local {
817                                bail!("instance type export `{name}` not defined in interface");
818                            }
819                            let id = self.register_type_export(name.as_str(), item, owner)?;
820                            let prev = self.resolve.interfaces[interface]
821                                .types
822                                .insert(name.to_string(), id);
823                            assert!(prev.is_none());
824                        }
825                    }
826                }
827
828                // This has similar logic to types above where we lazily fill in
829                // functions for remote dependencies and otherwise assert
830                // they're already defined for local dependencies.
831                ComponentEntityType::Func(_) => {
832                    if self.resolve.interfaces[interface]
833                        .functions
834                        .contains_key(name.as_str())
835                    {
836                        // TODO: should ideally verify that function signatures
837                        // match.
838                        continue;
839                    }
840                    if is_local {
841                        bail!("instance function export `{name}` not defined in interface");
842                    }
843                    let func = self.convert_function(name.as_str(), item, owner)?;
844                    let prev = self.resolve.interfaces[interface]
845                        .functions
846                        .insert(name.to_string(), func);
847                    assert!(prev.is_none());
848                }
849
850                _ => bail!("instance type export `{name}` is not a type"),
851            }
852        }
853
854        Ok(interface)
855    }
856
857    fn find_alias(&self, id: ComponentAnyTypeId) -> Option<TypeId> {
858        // Consult `type_map` for `referenced` or anything in its
859        // chain of aliases to determine what it maps to. This may
860        // bottom out in `None` in the case that this type is
861        // just now being defined, but this should otherwise follow
862        // chains of aliases to determine what exactly this was a
863        // `use` of if it exists.
864        let mut prev = None;
865        let mut cur = id;
866        while prev.is_none() {
867            prev = self.type_map.get(&cur).copied();
868            cur = match self.types.as_ref().peel_alias(cur) {
869                Some(next) => next,
870                None => break,
871            };
872        }
873        prev
874    }
875
876    /// This will parse the `name_string` as a component model ID string and
877    /// ensure that there's an `InterfaceId` corresponding to its components.
878    fn extract_dep_interface(
879        &mut self,
880        name_string: &str,
881        item: &ComponentItem,
882    ) -> Result<InterfaceId> {
883        let name = crate::parse_component_name(name_string).unwrap();
884        let name = match name.kind() {
885            ComponentNameKind::Interface(name) => name,
886            _ => bail!("package name is not a valid id: {name_string}"),
887        };
888        let package_name = name.to_package_name(item)?;
889        // Lazily create a `Package` as necessary, along with the interface.
890        let package = self
891            .foreign_packages
892            .entry(package_name.to_string())
893            .or_insert_with(|| Package {
894                name: package_name.clone(),
895                docs: Default::default(),
896                interfaces: Default::default(),
897                worlds: Default::default(),
898            });
899        let interface = *package
900            .interfaces
901            .entry(name.interface().to_string())
902            .or_insert_with(|| {
903                self.resolve.interfaces.alloc(Interface {
904                    name: Some(name.interface().to_string()),
905                    docs: Default::default(),
906                    types: IndexMap::default(),
907                    functions: IndexMap::default(),
908                    package: None,
909                    stability: Default::default(),
910                    span: Default::default(),
911                    clone_of: None,
912                })
913            });
914
915        // Record a mapping of which foreign package this interface belongs to
916        self.iface_to_package_index.insert(
917            interface,
918            self.foreign_packages
919                .get_full(&package_name.to_string())
920                .unwrap()
921                .0,
922        );
923        Ok(interface)
924    }
925
926    /// A general-purpose helper function to translate a component instance
927    /// into a WIT interface.
928    ///
929    /// This is one of the main workhorses of this module. This handles
930    /// interfaces both at the type level, for concrete components, and
931    /// internally within worlds as well.
932    ///
933    /// The `name` provided is the contextual ID or name of the interface. This
934    /// could be a kebab-name in the case of a world import or export or it can
935    /// also be an ID. This is used to guide insertion into various maps.
936    ///
937    /// The `ty` provided is the actual component type being decoded.
938    ///
939    /// The `package` is where to insert the final interface if `name` is an ID
940    /// meaning it's registered as a named standalone item within the package.
941    fn register_interface<'a>(
942        &mut self,
943        name: &str,
944        item: &ComponentItem,
945        package: &mut PackageFields<'a>,
946    ) -> Result<(WorldKey, InterfaceId)> {
947        let ty = match item.ty {
948            ComponentEntityType::Instance(i) => &self.types[i],
949            _ => unreachable!(),
950        };
951        // If this interface's name is already known then that means this is an
952        // interface that's both imported and exported.  Use `register_import`
953        // to draw connections between types and this interface's types.
954        if self.named_interfaces.contains_key(name) {
955            let id = self.register_import(name, item)?;
956            return Ok((WorldKey::Interface(id), id));
957        }
958
959        // If this is a bare kebab-name for an interface then the interface's
960        // listed name is `None` and the name goes out through the key.
961        // Otherwise this name is extracted from `name` interpreted as an ID.
962        let interface_name = self.extract_interface_name_from_component_name(name)?;
963
964        let mut interface = Interface {
965            name: interface_name.clone(),
966            docs: Default::default(),
967            types: IndexMap::default(),
968            functions: IndexMap::default(),
969            package: None,
970            stability: Default::default(),
971            span: Default::default(),
972            clone_of: None,
973        };
974
975        let owner = TypeOwner::Interface(self.resolve.interfaces.next_id());
976        for (name, item) in ty.exports.iter() {
977            match item.ty {
978                ComponentEntityType::Type { .. } => {
979                    let ty = self
980                        .register_type_export(name.as_str(), item, owner)
981                        .with_context(|| format!("failed to register type export '{name}'"))?;
982                    let prev = interface.types.insert(name.to_string(), ty);
983                    assert!(prev.is_none());
984                }
985
986                ComponentEntityType::Func(_) => {
987                    let func = self
988                        .convert_function(name.as_str(), item, owner)
989                        .with_context(|| format!("failed to convert function '{name}'"))?;
990                    let prev = interface.functions.insert(name.to_string(), func);
991                    assert!(prev.is_none());
992                }
993                _ => bail!("instance type export `{name}` is not a type or function"),
994            };
995        }
996        let id = self.resolve.interfaces.alloc(interface);
997        let key = match interface_name {
998            // If this interface is named then it's part of the package, so
999            // insert it. Additionally register it in `named_interfaces` so
1000            // further use comes back to this original definition.
1001            Some(interface_name) => {
1002                let prev = package.interfaces.insert(interface_name, id);
1003                assert!(prev.is_none(), "duplicate interface added for {name:?}");
1004                let prev = self.named_interfaces.insert(name.to_string(), id);
1005                assert!(prev.is_none());
1006                WorldKey::Interface(id)
1007            }
1008
1009            // If this interface isn't named then its key is always a
1010            // kebab-name.
1011            None => WorldKey::Name(name.to_string()),
1012        };
1013        Ok((key, id))
1014    }
1015
1016    fn parse_component_name(&self, name: &str) -> Result<ComponentName> {
1017        crate::parse_component_name(name)
1018            .with_context(|| format!("cannot extract item name from: {name}"))
1019    }
1020
1021    fn extract_interface_name_from_component_name(&self, name: &str) -> Result<Option<String>> {
1022        let component_name = self.parse_component_name(name)?;
1023        match component_name.kind() {
1024            ComponentNameKind::Interface(name) => Ok(Some(name.interface().to_string())),
1025            ComponentNameKind::Plain(name) if name.is_bare() => Ok(None),
1026            _ => bail!("cannot extract item name from: {name}"),
1027        }
1028    }
1029
1030    fn register_type_export(
1031        &mut self,
1032        name: &str,
1033        item: &ComponentItem,
1034        owner: TypeOwner,
1035    ) -> Result<TypeId> {
1036        let (referenced, created) = match item.ty {
1037            ComponentEntityType::Type {
1038                referenced,
1039                created,
1040            } => (referenced, created),
1041            _ => unreachable!(),
1042        };
1043        let kind = match self.find_alias(referenced) {
1044            // If this `TypeId` points to a type which has
1045            // previously been defined, meaning we're aliasing a
1046            // prior definition.
1047            Some(prev) => {
1048                log::debug!("type export for `{name}` is an alias");
1049                // An interface can only `use` types from other interfaces.
1050                // Anything else, such as a type the world imports or an
1051                // anonymous type, has no WIT form, and code reading a
1052                // `Resolve` assumes it can't happen: `type_interface_dep`
1053                // panics on it, which `finish` reaches for interfaces in
1054                // foreign packages, and the WIT printer panics on it for
1055                // interfaces defined in a world. Catch it here, where the
1056                // `use` is created, so that both are covered.
1057                if matches!(owner, TypeOwner::Interface(_))
1058                    && !matches!(self.resolve.types[prev].owner, TypeOwner::Interface(_))
1059                {
1060                    bail!(
1061                        "cannot represent this component in WIT: type `{name}` refers to a \
1062                         type that isn't defined in an interface"
1063                    );
1064                }
1065                TypeDefKind::Type(Type::Id(prev))
1066            }
1067
1068            // ... or this `TypeId`'s source definition has never
1069            // been seen before, so declare the full type.
1070            None => {
1071                log::debug!("type export for `{name}` is a new type");
1072                match referenced {
1073                    ComponentAnyTypeId::Defined(ty) => self
1074                        .convert_defined(&self.types[ty])
1075                        .context("failed to convert unaliased type")?,
1076                    ComponentAnyTypeId::Resource(_) => TypeDefKind::Resource,
1077                    _ => unreachable!(),
1078                }
1079            }
1080        };
1081        let ty = self.resolve.types.alloc(TypeDef {
1082            name: Some(name.to_string()),
1083            kind,
1084            docs: Default::default(),
1085            stability: Default::default(),
1086            owner,
1087            span: Default::default(),
1088            external_id: item.external_id.clone(),
1089        });
1090
1091        // If this is a resource then doubly-register it in `self.resources` so
1092        // the ID allocated here can be looked up via name later on during
1093        // `convert_function`.
1094        if let TypeDefKind::Resource = self.resolve.types[ty].kind {
1095            let prev = self
1096                .resources
1097                .entry(owner)
1098                .or_insert(HashMap::new())
1099                .insert(name.to_string(), ty);
1100            assert!(prev.is_none());
1101        }
1102
1103        // A duplicate mapping here comes from a valid component that WIT cannot
1104        // represent (for example an imported resource re-exported under a new
1105        // name), not an internal invariant, so report it instead of asserting.
1106        let prev = self.type_map.insert(created, ty);
1107        if prev.is_some() {
1108            bail!(
1109                "cannot represent this component in WIT: the type `{name}` appears \
1110                 more than once (for example, when an imported instance is \
1111                 re-exported under a new name)"
1112            );
1113        }
1114        Ok(ty)
1115    }
1116
1117    fn register_world<'a>(
1118        &mut self,
1119        name: &str,
1120        ty: &ComponentType,
1121        package: &mut PackageFields<'a>,
1122    ) -> Result<WorldId> {
1123        let name = self
1124            .extract_interface_name_from_component_name(name)?
1125            .context("expected world name to have an ID form")?;
1126        let mut world = World {
1127            name: name.clone(),
1128            docs: Default::default(),
1129            imports: Default::default(),
1130            exports: Default::default(),
1131            includes: Default::default(),
1132            package: None,
1133            stability: Default::default(),
1134            span: Default::default(),
1135        };
1136
1137        let owner = TypeOwner::World(self.resolve.worlds.next_id());
1138        for (name, item) in ty.imports.iter() {
1139            let (name, item) = match item.ty {
1140                ComponentEntityType::Instance(_) => {
1141                    self.decode_world_instance(name, item, package)?
1142                }
1143                ComponentEntityType::Type { .. } => {
1144                    let ty = self.register_type_export(name.as_str(), item, owner)?;
1145                    (
1146                        WorldKey::Name(name.to_string()),
1147                        WorldItem::Type {
1148                            id: ty,
1149                            span: Default::default(),
1150                        },
1151                    )
1152                }
1153                ComponentEntityType::Func(_) => {
1154                    let func = self.convert_function(name.as_str(), item, owner)?;
1155                    (WorldKey::Name(name.to_string()), WorldItem::Function(func))
1156                }
1157                _ => bail!("component import `{name}` is not an instance, func, or type"),
1158            };
1159            world.imports.insert(name, item);
1160        }
1161
1162        for (name, item) in ty.exports.iter() {
1163            let (name, item) = match item.ty {
1164                ComponentEntityType::Instance(_) => {
1165                    self.decode_world_instance(name, item, package)?
1166                }
1167
1168                ComponentEntityType::Func(_) => {
1169                    let func = self.convert_function(name.as_str(), item, owner)?;
1170                    (WorldKey::Name(name.to_string()), WorldItem::Function(func))
1171                }
1172
1173                _ => bail!("component export `{name}` is not an instance or function"),
1174            };
1175            world.exports.insert(name, item);
1176        }
1177        let id = self.resolve.worlds.alloc(world);
1178        let prev = package.worlds.insert(name, id);
1179        assert!(prev.is_none());
1180        Ok(id)
1181    }
1182
1183    fn convert_function(
1184        &mut self,
1185        name: &str,
1186        item: &ComponentItem,
1187        owner: TypeOwner,
1188    ) -> Result<Function> {
1189        let ty = match item.ty {
1190            ComponentEntityType::Func(i) => &self.types[i],
1191            _ => unreachable!(),
1192        };
1193        let name = crate::parse_component_name(name).unwrap();
1194        let params = ty
1195            .params
1196            .iter()
1197            .map(|(name, ty)| {
1198                Ok(Param {
1199                    name: name.to_string(),
1200                    ty: self.convert_valtype(ty)?,
1201                    span: Default::default(),
1202                })
1203            })
1204            .collect::<Result<Vec<_>>>()
1205            .context("failed to convert params")?;
1206        let result = match &ty.result {
1207            Some(ty) => Some(
1208                self.convert_valtype(ty)
1209                    .context("failed to convert anonymous result type")?,
1210            ),
1211            None => None,
1212        };
1213        Ok(Function {
1214            docs: Default::default(),
1215            stability: Default::default(),
1216            external_id: item.external_id.clone(),
1217            kind: match name.kind() {
1218                ComponentNameKind::Plain(plain) => {
1219                    if plain.accessor.is_some() && ty.async_ {
1220                        panic!("function `{name}` is an async accessor (should be impossible)");
1221                    }
1222
1223                    let resource = plain
1224                        .resource()
1225                        .map(|resource| self.resources[&owner][resource.as_str()]);
1226                    match (plain.resource_func, plain.accessor) {
1227                        (None, None) => {
1228                            if ty.async_ {
1229                                FunctionKind::AsyncFreestanding
1230                            } else {
1231                                FunctionKind::Freestanding
1232                            }
1233                        }
1234                        (None, Some(ComponentAccessorKind::Get)) => FunctionKind::Getter,
1235                        (None, Some(ComponentAccessorKind::Set)) => FunctionKind::Setter,
1236
1237                        (Some(ResourceFuncKind::Constructor), None) => {
1238                            FunctionKind::Constructor(resource.unwrap())
1239                        }
1240                        (Some(ResourceFuncKind::Constructor), Some(_)) => {
1241                            panic!(
1242                                "function `{name}` is a constructor with an accessor (should be impossible)"
1243                            );
1244                        }
1245
1246                        (Some(ResourceFuncKind::Method), None) => {
1247                            if ty.async_ {
1248                                FunctionKind::AsyncMethod(resource.unwrap())
1249                            } else {
1250                                FunctionKind::Method(resource.unwrap())
1251                            }
1252                        }
1253                        (Some(ResourceFuncKind::Method), Some(ComponentAccessorKind::Get)) => {
1254                            FunctionKind::MethodGetter(resource.unwrap())
1255                        }
1256                        (Some(ResourceFuncKind::Method), Some(ComponentAccessorKind::Set)) => {
1257                            FunctionKind::MethodSetter(resource.unwrap())
1258                        }
1259
1260                        (Some(ResourceFuncKind::Static), None) => {
1261                            if ty.async_ {
1262                                FunctionKind::AsyncStatic(resource.unwrap())
1263                            } else {
1264                                FunctionKind::Static(resource.unwrap())
1265                            }
1266                        }
1267                        (Some(ResourceFuncKind::Static), Some(ComponentAccessorKind::Get)) => {
1268                            FunctionKind::StaticGetter(resource.unwrap())
1269                        }
1270                        (Some(ResourceFuncKind::Static), Some(ComponentAccessorKind::Set)) => {
1271                            FunctionKind::StaticSetter(resource.unwrap())
1272                        }
1273                    }
1274                }
1275
1276                // Functions shouldn't have ID-based names at this time.
1277                ComponentNameKind::Interface(_) => unreachable!(),
1278            },
1279
1280            // Note that this name includes "name mangling" such as
1281            // `[method]foo.bar` which is intentional. The `FunctionKind`
1282            // discriminant calculated above indicates how to interpret this
1283            // name.
1284            name: name.to_string(),
1285            params,
1286            result,
1287            span: Default::default(),
1288        })
1289    }
1290
1291    fn convert_valtype(&mut self, ty: &ComponentValType) -> Result<Type> {
1292        let id = match ty {
1293            ComponentValType::Primitive(ty) => return Ok(self.convert_primitive(*ty)),
1294            ComponentValType::Type(id) => *id,
1295        };
1296
1297        // Don't create duplicate types for anything previously created.
1298        let key: ComponentAnyTypeId = id.into();
1299        if let Some(ret) = self.type_map.get(&key) {
1300            return Ok(Type::Id(*ret));
1301        }
1302
1303        // Otherwise create a new `TypeDef` without a name since this is an
1304        // anonymous valtype. Note that this is invalid for some types so return
1305        // errors on those types, but eventually the `bail!` here  is
1306        // more-or-less unreachable due to expected validation to be added to
1307        // the component model binary format itself.
1308        let def = &self.types[id];
1309        let kind = self.convert_defined(def)?;
1310        match &kind {
1311            TypeDefKind::Type(_)
1312            | TypeDefKind::List(_)
1313            | TypeDefKind::Map(_, _)
1314            | TypeDefKind::FixedLengthList(..)
1315            | TypeDefKind::Tuple(_)
1316            | TypeDefKind::Option(_)
1317            | TypeDefKind::Result(_)
1318            | TypeDefKind::Handle(_)
1319            | TypeDefKind::Future(_)
1320            | TypeDefKind::Stream(_) => {}
1321
1322            TypeDefKind::Resource
1323            | TypeDefKind::Record(_)
1324            | TypeDefKind::Enum(_)
1325            | TypeDefKind::Variant(_)
1326            | TypeDefKind::Flags(_) => {
1327                bail!("unexpected unnamed type of kind '{}'", kind.as_str());
1328            }
1329            TypeDefKind::Unknown => unreachable!(),
1330        }
1331        let ty = self.resolve.types.alloc(TypeDef {
1332            name: None,
1333            docs: Default::default(),
1334            stability: Default::default(),
1335            owner: TypeOwner::None,
1336            kind,
1337            span: Default::default(),
1338            external_id: None,
1339        });
1340        let prev = self.type_map.insert(id.into(), ty);
1341        assert!(prev.is_none());
1342        Ok(Type::Id(ty))
1343    }
1344
1345    /// Converts a wasmparser `ComponentDefinedType`, the definition of a type
1346    /// in the component model, to a WIT `TypeDefKind` to get inserted into the
1347    /// types arena by the caller.
1348    fn convert_defined(&mut self, ty: &ComponentDefinedType) -> Result<TypeDefKind> {
1349        match ty {
1350            ComponentDefinedType::Primitive(t) => Ok(TypeDefKind::Type(self.convert_primitive(*t))),
1351
1352            ComponentDefinedType::List { element, .. } => {
1353                let t = self.convert_valtype(element)?;
1354                Ok(TypeDefKind::List(t))
1355            }
1356
1357            ComponentDefinedType::Map { key, value, .. } => {
1358                let k = self.convert_valtype(key)?;
1359                let v = self.convert_valtype(value)?;
1360                Ok(TypeDefKind::Map(k, v))
1361            }
1362
1363            ComponentDefinedType::FixedLengthList {
1364                element, length, ..
1365            } => {
1366                let t = self.convert_valtype(element)?;
1367                Ok(TypeDefKind::FixedLengthList(t, *length))
1368            }
1369
1370            ComponentDefinedType::Tuple(t) => {
1371                let types = t
1372                    .types
1373                    .iter()
1374                    .map(|t| self.convert_valtype(t))
1375                    .collect::<Result<_>>()?;
1376                Ok(TypeDefKind::Tuple(Tuple { types }))
1377            }
1378
1379            ComponentDefinedType::Option { ty, .. } => {
1380                let t = self.convert_valtype(ty)?;
1381                Ok(TypeDefKind::Option(t))
1382            }
1383
1384            ComponentDefinedType::Result { ok, err, .. } => {
1385                let ok = match ok {
1386                    Some(t) => Some(self.convert_valtype(t)?),
1387                    None => None,
1388                };
1389                let err = match err {
1390                    Some(t) => Some(self.convert_valtype(t)?),
1391                    None => None,
1392                };
1393                Ok(TypeDefKind::Result(Result_ { ok, err }))
1394            }
1395
1396            ComponentDefinedType::Record(r) => {
1397                let fields = r
1398                    .fields
1399                    .iter()
1400                    .map(|(name, ty)| {
1401                        Ok(Field {
1402                            name: name.to_string(),
1403                            ty: self.convert_valtype(ty).with_context(|| {
1404                                format!("failed to convert record field '{name}'")
1405                            })?,
1406                            docs: Default::default(),
1407                            span: Default::default(),
1408                        })
1409                    })
1410                    .collect::<Result<_>>()?;
1411                Ok(TypeDefKind::Record(Record { fields }))
1412            }
1413
1414            ComponentDefinedType::Variant(v) => {
1415                let cases = v
1416                    .cases
1417                    .iter()
1418                    .map(|(name, case)| {
1419                        Ok(Case {
1420                            name: name.to_string(),
1421                            ty: match &case.ty {
1422                                Some(ty) => Some(self.convert_valtype(ty)?),
1423                                None => None,
1424                            },
1425                            docs: Default::default(),
1426                            span: Default::default(),
1427                        })
1428                    })
1429                    .collect::<Result<_>>()?;
1430                Ok(TypeDefKind::Variant(Variant { cases }))
1431            }
1432
1433            ComponentDefinedType::Flags(f) => {
1434                let flags = f
1435                    .iter()
1436                    .map(|name| Flag {
1437                        name: name.to_string(),
1438                        docs: Default::default(),
1439                        span: Default::default(),
1440                    })
1441                    .collect();
1442                Ok(TypeDefKind::Flags(Flags { flags }))
1443            }
1444
1445            ComponentDefinedType::Enum(e) => {
1446                let cases = e
1447                    .iter()
1448                    .cloned()
1449                    .map(|name| EnumCase {
1450                        name: name.into(),
1451                        docs: Default::default(),
1452                        span: Default::default(),
1453                    })
1454                    .collect();
1455                Ok(TypeDefKind::Enum(Enum { cases }))
1456            }
1457
1458            ComponentDefinedType::Own(id) => {
1459                let key: ComponentAnyTypeId = (*id).into();
1460                let id = self.type_map[&key];
1461                Ok(TypeDefKind::Handle(Handle::Own(id)))
1462            }
1463
1464            ComponentDefinedType::Borrow(id) => {
1465                let key: ComponentAnyTypeId = (*id).into();
1466                let id = self.type_map[&key];
1467                Ok(TypeDefKind::Handle(Handle::Borrow(id)))
1468            }
1469
1470            ComponentDefinedType::Future { ty, .. } => Ok(TypeDefKind::Future(
1471                ty.as_ref().map(|ty| self.convert_valtype(ty)).transpose()?,
1472            )),
1473
1474            ComponentDefinedType::Stream { ty, .. } => Ok(TypeDefKind::Stream(
1475                ty.as_ref().map(|ty| self.convert_valtype(ty)).transpose()?,
1476            )),
1477        }
1478    }
1479
1480    fn convert_primitive(&self, ty: PrimitiveValType) -> Type {
1481        match ty {
1482            PrimitiveValType::U8 => Type::U8,
1483            PrimitiveValType::S8 => Type::S8,
1484            PrimitiveValType::U16 => Type::U16,
1485            PrimitiveValType::S16 => Type::S16,
1486            PrimitiveValType::U32 => Type::U32,
1487            PrimitiveValType::S32 => Type::S32,
1488            PrimitiveValType::U64 => Type::U64,
1489            PrimitiveValType::S64 => Type::S64,
1490            PrimitiveValType::Bool => Type::Bool,
1491            PrimitiveValType::Char => Type::Char,
1492            PrimitiveValType::String => Type::String,
1493            PrimitiveValType::F32 => Type::F32,
1494            PrimitiveValType::F64 => Type::F64,
1495            PrimitiveValType::ErrorContext => Type::ErrorContext,
1496        }
1497    }
1498
1499    fn register_defined(&mut self, id: TypeId, def: &ComponentDefinedType) -> Result<()> {
1500        Registrar {
1501            types: &self.types,
1502            type_map: &mut self.type_map,
1503            resolve: &self.resolve,
1504        }
1505        .defined(id, def)
1506    }
1507
1508    /// Completes the decoding of this resolve by finalizing all packages into
1509    /// their topological ordering within the returned `Resolve`.
1510    ///
1511    /// Takes the root package as an argument to insert.
1512    fn finish(mut self, package: Package) -> Result<(Resolve, PackageId)> {
1513        // Build a topological ordering is then calculated by visiting all the
1514        // transitive dependencies of packages.
1515        let mut order = IndexSet::default();
1516        let mut visiting = HashSet::new();
1517        for i in 0..self.foreign_packages.len() {
1518            self.visit_package(i, &mut order, &mut visiting)?;
1519        }
1520
1521        // Using the topological ordering create a temporary map from
1522        // index-in-`foreign_packages` to index-in-`order`
1523        let mut idx_to_pos = vec![0; self.foreign_packages.len()];
1524        for (pos, idx) in order.iter().enumerate() {
1525            idx_to_pos[*idx] = pos;
1526        }
1527        // .. and then using `idx_to_pos` sort the `foreign_packages` array based
1528        // on the position it's at in the topological ordering
1529        let mut deps = mem::take(&mut self.foreign_packages)
1530            .into_iter()
1531            .enumerate()
1532            .collect::<Vec<_>>();
1533        deps.sort_by_key(|(idx, _)| idx_to_pos[*idx]);
1534
1535        // .. and finally insert the packages, in their final topological
1536        // ordering, into the returned array.
1537        for (_idx, (_url, pkg)) in deps {
1538            self.insert_package(pkg);
1539        }
1540
1541        let id = self.insert_package(package);
1542        assert!(self.resolve.worlds.iter().all(|(_, w)| w.package.is_some()));
1543        assert!(
1544            self.resolve
1545                .interfaces
1546                .iter()
1547                .all(|(_, i)| i.package.is_some())
1548        );
1549        Ok((self.resolve, id))
1550    }
1551
1552    fn insert_package(&mut self, package: Package) -> PackageId {
1553        let Package {
1554            name,
1555            interfaces,
1556            worlds,
1557            docs,
1558        } = package;
1559
1560        // Most of the time the `package` being inserted is not already present
1561        // in `self.resolve`, but in the case of the top-level `decode_world`
1562        // function this isn't the case. This shouldn't in general be a problem
1563        // so union-up the packages here while asserting that nothing gets
1564        // replaced by accident which would indicate a bug.
1565        let pkg = self
1566            .resolve
1567            .package_names
1568            .get(&name)
1569            .copied()
1570            .unwrap_or_else(|| {
1571                let id = self.resolve.packages.alloc(Package {
1572                    name: name.clone(),
1573                    interfaces: Default::default(),
1574                    worlds: Default::default(),
1575                    docs,
1576                });
1577                let prev = self.resolve.package_names.insert(name, id);
1578                assert!(prev.is_none());
1579                id
1580            });
1581
1582        for (name, id) in interfaces {
1583            let prev = self.resolve.packages[pkg].interfaces.insert(name, id);
1584            assert!(prev.is_none());
1585            self.resolve.interfaces[id].package = Some(pkg);
1586        }
1587
1588        for (name, id) in worlds {
1589            let prev = self.resolve.packages[pkg].worlds.insert(name, id);
1590            assert!(prev.is_none());
1591            let world = &mut self.resolve.worlds[id];
1592            world.package = Some(pkg);
1593            for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1594                if let WorldKey::Name(_) = name {
1595                    if let WorldItem::Interface { id, .. } = item {
1596                        let iface = &mut self.resolve.interfaces[*id];
1597                        if iface.name.is_none() {
1598                            iface.package = Some(pkg);
1599                        }
1600                    }
1601                }
1602            }
1603        }
1604
1605        pkg
1606    }
1607
1608    fn visit_package(
1609        &self,
1610        idx: usize,
1611        order: &mut IndexSet<usize>,
1612        visiting: &mut HashSet<usize>,
1613    ) -> Result<()> {
1614        if order.contains(&idx) {
1615            return Ok(());
1616        }
1617
1618        let (name, pkg) = self.foreign_packages.get_index(idx).unwrap();
1619        if !visiting.insert(idx) {
1620            bail!(
1621                "cannot represent this component in WIT: package `{name}` creates a dependency cycle"
1622            );
1623        }
1624        let interfaces = pkg.interfaces.values().copied().chain(
1625            pkg.worlds
1626                .values()
1627                .flat_map(|w| {
1628                    let world = &self.resolve.worlds[*w];
1629                    world.imports.values().chain(world.exports.values())
1630                })
1631                .filter_map(|item| match item {
1632                    WorldItem::Interface { id, .. } => Some(*id),
1633                    WorldItem::Function(_) | WorldItem::Type { .. } => None,
1634                }),
1635        );
1636        for iface in interfaces {
1637            for dep in self.resolve.interface_direct_deps(iface) {
1638                let Some(&dep_idx) = self.iface_to_package_index.get(&dep) else {
1639                    bail!(
1640                        "cannot represent this component in WIT: package `{name}` uses a type \
1641                         from an interface it can't depend on"
1642                    );
1643                };
1644                if dep_idx != idx {
1645                    self.visit_package(dep_idx, order, visiting)?;
1646                }
1647            }
1648        }
1649
1650        visiting.remove(&idx);
1651        assert!(order.insert(idx));
1652        Ok(())
1653    }
1654}
1655
1656/// Helper type to register the structure of a wasm-defined type against a
1657/// wit-defined type.
1658struct Registrar<'a> {
1659    types: &'a Types,
1660    type_map: &'a mut HashMap<ComponentAnyTypeId, TypeId>,
1661    resolve: &'a Resolve,
1662}
1663
1664impl Registrar<'_> {
1665    /// Verifies that the wasm structure of `def` matches the wit structure of
1666    /// `id` and recursively registers types.
1667    fn defined(&mut self, id: TypeId, def: &ComponentDefinedType) -> Result<()> {
1668        match def {
1669            ComponentDefinedType::Primitive(_) => Ok(()),
1670
1671            ComponentDefinedType::List { element, .. } => {
1672                let ty = match &self.resolve.types[id].kind {
1673                    TypeDefKind::List(r) => r,
1674                    // Note that all cases below have this match and the general
1675                    // idea is that once a type is named or otherwise identified
1676                    // here there's no need to recurse. The purpose of this
1677                    // registrar is to build connections for anonymous types
1678                    // that don't otherwise have a name to ensure that they're
1679                    // decoded to reuse the same constructs consistently. For
1680                    // that reason once something is named we can bail out.
1681                    TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1682                    _ => bail!("expected a list"),
1683                };
1684                self.valtype(element, ty)
1685            }
1686
1687            ComponentDefinedType::Map { key, value, .. } => {
1688                let (key_ty, value_ty) = match &self.resolve.types[id].kind {
1689                    TypeDefKind::Map(k, v) => (k, v),
1690                    TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1691                    _ => bail!("expected a map"),
1692                };
1693                self.valtype(key, key_ty)?;
1694                self.valtype(value, value_ty)
1695            }
1696
1697            ComponentDefinedType::FixedLengthList {
1698                element, length, ..
1699            } => {
1700                let ty = match &self.resolve.types[id].kind {
1701                    TypeDefKind::FixedLengthList(r, elements2) if elements2 == length => r,
1702                    TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1703                    _ => bail!("expected a fixed-length {length} list"),
1704                };
1705                self.valtype(element, ty)
1706            }
1707
1708            ComponentDefinedType::Tuple(t) => {
1709                let ty = match &self.resolve.types[id].kind {
1710                    TypeDefKind::Tuple(r) => r,
1711                    TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1712                    _ => bail!("expected a tuple"),
1713                };
1714                if ty.types.len() != t.types.len() {
1715                    bail!("mismatched number of tuple fields");
1716                }
1717                for (a, b) in t.types.iter().zip(ty.types.iter()) {
1718                    self.valtype(a, b)?;
1719                }
1720                Ok(())
1721            }
1722
1723            ComponentDefinedType::Option { ty: t, .. } => {
1724                let ty = match &self.resolve.types[id].kind {
1725                    TypeDefKind::Option(r) => r,
1726                    TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1727                    _ => bail!("expected an option"),
1728                };
1729                self.valtype(t, ty)
1730            }
1731
1732            ComponentDefinedType::Result { ok, err, .. } => {
1733                let ty = match &self.resolve.types[id].kind {
1734                    TypeDefKind::Result(r) => r,
1735                    TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1736                    _ => bail!("expected a result"),
1737                };
1738                match (ok, &ty.ok) {
1739                    (Some(a), Some(b)) => self.valtype(a, b)?,
1740                    (None, None) => {}
1741                    _ => bail!("disagreement on result structure"),
1742                }
1743                match (err, &ty.err) {
1744                    (Some(a), Some(b)) => self.valtype(a, b)?,
1745                    (None, None) => {}
1746                    _ => bail!("disagreement on result structure"),
1747                }
1748                Ok(())
1749            }
1750
1751            ComponentDefinedType::Record(def) => {
1752                let ty = match &self.resolve.types[id].kind {
1753                    TypeDefKind::Record(r) => r,
1754                    TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1755                    _ => bail!("expected a record"),
1756                };
1757                if def.fields.len() != ty.fields.len() {
1758                    bail!("mismatched number of record fields");
1759                }
1760                for ((name, ty), field) in def.fields.iter().zip(&ty.fields) {
1761                    if name.as_str() != field.name {
1762                        bail!("mismatched field order");
1763                    }
1764                    self.valtype(ty, &field.ty)?;
1765                }
1766                Ok(())
1767            }
1768
1769            ComponentDefinedType::Variant(def) => {
1770                let ty = match &self.resolve.types[id].kind {
1771                    TypeDefKind::Variant(r) => r,
1772                    TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1773                    _ => bail!("expected a variant"),
1774                };
1775                if def.cases.len() != ty.cases.len() {
1776                    bail!("mismatched number of variant cases");
1777                }
1778                for ((name, ty), case) in def.cases.iter().zip(&ty.cases) {
1779                    if name.as_str() != case.name {
1780                        bail!("mismatched case order");
1781                    }
1782                    match (&ty.ty, &case.ty) {
1783                        (Some(a), Some(b)) => self.valtype(a, b)?,
1784                        (None, None) => {}
1785                        _ => bail!("disagreement on case type"),
1786                    }
1787                }
1788                Ok(())
1789            }
1790
1791            ComponentDefinedType::Future { ty: payload, .. } => {
1792                let ty = match &self.resolve.types[id].kind {
1793                    TypeDefKind::Future(p) => p,
1794                    TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1795                    _ => bail!("expected a future"),
1796                };
1797                match (payload, ty) {
1798                    (Some(a), Some(b)) => self.valtype(a, b),
1799                    (None, None) => Ok(()),
1800                    _ => bail!("disagreement on future payload"),
1801                }
1802            }
1803
1804            ComponentDefinedType::Stream { ty: payload, .. } => {
1805                let ty = match &self.resolve.types[id].kind {
1806                    TypeDefKind::Stream(p) => p,
1807                    TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1808                    _ => bail!("expected a stream"),
1809                };
1810                match (payload, ty) {
1811                    (Some(a), Some(b)) => self.valtype(a, b),
1812                    (None, None) => Ok(()),
1813                    _ => bail!("disagreement on stream payload"),
1814                }
1815            }
1816
1817            // These have no recursive structure so they can bail out.
1818            ComponentDefinedType::Flags(_)
1819            | ComponentDefinedType::Enum(_)
1820            | ComponentDefinedType::Own(_)
1821            | ComponentDefinedType::Borrow(_) => Ok(()),
1822        }
1823    }
1824
1825    fn valtype(&mut self, wasm: &ComponentValType, wit: &Type) -> Result<()> {
1826        let wasm = match wasm {
1827            ComponentValType::Type(wasm) => *wasm,
1828            ComponentValType::Primitive(_wasm) => {
1829                assert!(!matches!(wit, Type::Id(_)));
1830                return Ok(());
1831            }
1832        };
1833        let wit = match wit {
1834            Type::Id(id) => *id,
1835            _ => bail!("expected id-based type"),
1836        };
1837        let prev = match self.type_map.insert(wasm.into(), wit) {
1838            Some(prev) => prev,
1839            None => {
1840                let wasm = &self.types[wasm];
1841                return self.defined(wit, wasm);
1842            }
1843        };
1844        // If `wit` matches `prev` then we've just rediscovered what we already
1845        // knew which is that the `wasm` id maps to the `wit` id.
1846        //
1847        // If, however, `wit` is not equal to `prev` then that's more
1848        // interesting. Consider a component such as:
1849        //
1850        // ```wasm
1851        // (component
1852        //   (import (interface "a:b/name") (instance
1853        //      (type $l (list string))
1854        //      (type $foo (variant (case "l" $l)))
1855        //      (export "foo" (type (eq $foo)))
1856        //   ))
1857        //   (component $c
1858        //     (type $l (list string))
1859        //     (type $bar (variant (case "n" u16) (case "l" $l)))
1860        //     (export "bar" (type $bar))
1861        //     (type $foo (variant (case "l" $l)))
1862        //     (export "foo" (type $foo))
1863        //   )
1864        //   (instance $i (instantiate $c))
1865        //   (export (interface "a:b/name") (instance $i))
1866        // )
1867        // ```
1868        //
1869        // This roughly corresponds to:
1870        //
1871        // ```wit
1872        // package a:b
1873        //
1874        // interface name {
1875        //   variant bar {
1876        //     n(u16),
1877        //     l(list<string>),
1878        //   }
1879        //
1880        //   variant foo {
1881        //     l(list<string>),
1882        //   }
1883        // }
1884        //
1885        // world module {
1886        //   import name
1887        //   export name
1888        // }
1889        // ```
1890        //
1891        // In this situation first we'll see the `import` which records type
1892        // information for the `foo` type in `interface name`. Later on the full
1893        // picture of `interface name` becomes apparent with the export of a
1894        // component which has full type information. When walking over this
1895        // first `bar` is seen and its recursive structure.
1896        //
1897        // The problem arises when walking over the `foo` type. In this
1898        // situation the code path we're currently on will be hit because
1899        // there's a preexisting definition of `foo` from the import and it's
1900        // now going to be unified with what we've seen in the export. When
1901        // visiting the `list<string>` case of the `foo` variant this ends up
1902        // being different than the `list<string>` used by the `bar` variant. The
1903        // reason for this is that when visiting `bar` the wasm-defined `(list
1904        // string)` hasn't been seen before so a new type is allocated. Later
1905        // though this same wasm type is unified with the first `(list string)`
1906        // type in the `import`.
1907        //
1908        // All-in-all this ends up meaning that it's possible for `prev` to not
1909        // match `wit`. In this situation it means the decoded WIT interface
1910        // will have duplicate definitions of `list<string>`. This is,
1911        // theoretically, not that big of a problem because the same underlying
1912        // definition is still there and the meaning of the type is the same.
1913        // This can, however, perhaps be a problem for consumers where it's
1914        // assumed that all `list<string>` are equal and there's only one. For
1915        // example a bindings generator for C may assume that `list<string>`
1916        // will only appear once and generate a single name for it, but with two
1917        // different types in play here it may generate two types of the same
1918        // name (or something like that).
1919        //
1920        // For now though this is left for a future refactoring. Fixing this
1921        // issue would require tracking anonymous types during type translation
1922        // so the decoding process for the `bar` export would reuse the
1923        // `list<string>` type created from decoding the `foo` import. That's
1924        // somewhat nontrivial at this time, so it's left for a future
1925        // refactoring.
1926        let _ = prev;
1927        Ok(())
1928    }
1929}
1930
1931pub(crate) trait InterfaceNameExt {
1932    fn to_package_name(&self, item: &ComponentItem) -> Result<PackageName>;
1933}
1934
1935impl InterfaceNameExt for wasmparser::names::InterfaceName<'_> {
1936    fn to_package_name(&self, item: &ComponentItem) -> Result<PackageName> {
1937        Ok(PackageName {
1938            namespace: self.namespace().to_string(),
1939            name: self.package().to_string(),
1940            version: self.version(item.version_suffix.as_deref())?,
1941        })
1942    }
1943}