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