Coverage Report

Created: 2026-07-05 07:39

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