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