1use crate::*;
2use alloc::string::{String, ToString};
3use alloc::vec;
4use alloc::vec::Vec;
5use anyhow::Result;
6use anyhow::{Context, anyhow, bail};
7use core::mem;
8use std::io::Read;
9use wasmparser::Chunk;
10use wasmparser::{
11 ComponentExternalKind, Parser, Payload, PrimitiveValType, ValidPayload, Validator,
12 WasmFeatures,
13 component_types::{
14 ComponentAnyTypeId, ComponentDefinedType, ComponentEntityType, ComponentItem,
15 ComponentType, ComponentValType,
16 },
17 names::{
18 AccessorKind as ComponentAccessorKind, ComponentName, ComponentNameKind, ResourceFuncKind,
19 },
20 types,
21 types::Types,
22};
23
24struct ComponentInfo {
26 types: types::Types,
29 externs: Vec<(String, Extern)>,
31 package_metadata: Option<PackageMetadata>,
33}
34
35enum Extern {
36 Import(ComponentItem),
37 Export(ComponentItem),
38}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41enum WitEncodingVersion {
42 V1,
43 V2,
44}
45
46impl ComponentInfo {
47 fn from_reader(mut reader: impl Read) -> Result<Self> {
49 let mut validator = Validator::new_with_features(WasmFeatures::all());
50 let mut externs = Vec::new();
51 let mut depth = 1;
52 let mut types = None;
53 let mut _package_metadata = None;
54 let mut cur = Parser::new(0);
55 let mut eof = false;
56 let mut stack = Vec::new();
57 let mut buffer = Vec::new();
58
59 loop {
60 let chunk = cur.parse(&buffer, eof)?;
61 let (payload, consumed) = match chunk {
62 Chunk::NeedMoreData(hint) => {
63 assert!(!eof); let len = buffer.len();
71 buffer.extend((0..hint).map(|_| 0u8));
72 let n = reader.read(&mut buffer[len..])?;
73 buffer.truncate(len + n);
74 eof = n == 0;
75 continue;
76 }
77
78 Chunk::Parsed { consumed, payload } => (payload, consumed),
79 };
80 match validator.payload(&payload)? {
81 ValidPayload::Ok => {}
82 ValidPayload::Parser(_) => depth += 1,
83 ValidPayload::End(t) => {
84 depth -= 1;
85 if depth == 0 {
86 types = Some(t);
87 }
88 }
89 ValidPayload::Func(..) => {}
90 }
91
92 match payload {
93 Payload::ComponentImportSection(s) if depth == 1 => {
94 for import in s {
95 let import = import?;
96 let ty = validator
97 .types(0)
98 .unwrap()
99 .component_item_for_import(import.name.name)
100 .unwrap();
101 externs.push((import.name.name.to_string(), Extern::Import(ty.clone())));
102 }
103 }
104 Payload::ComponentExportSection(s) if depth == 1 => {
105 for export in s {
106 let export = export?;
107 let ty = validator
108 .types(0)
109 .unwrap()
110 .component_item_for_export(export.name.name)
111 .unwrap();
112 externs.push((export.name.name.to_string(), Extern::Export(ty.clone())));
113 }
114 }
115 #[cfg(feature = "serde")]
116 Payload::CustomSection(s) if s.name() == PackageMetadata::SECTION_NAME => {
117 if _package_metadata.is_some() {
118 bail!("multiple {:?} sections", PackageMetadata::SECTION_NAME);
119 }
120 _package_metadata = Some(PackageMetadata::decode(s.data())?);
121 }
122 Payload::ModuleSection { parser, .. }
123 | Payload::ComponentSection { parser, .. } => {
124 stack.push(cur.clone());
125 cur = parser.clone();
126 }
127 Payload::End(_) => {
128 if let Some(parent_parser) = stack.pop() {
129 cur = parent_parser.clone();
130 } else {
131 break;
132 }
133 }
134 _ => {}
135 }
136
137 buffer.drain(..consumed);
140 }
141
142 Ok(Self {
143 types: types.unwrap(),
144 externs,
145 package_metadata: _package_metadata,
146 })
147 }
148
149 fn is_wit_package(&self) -> Option<WitEncodingVersion> {
150 if self.externs.is_empty() {
153 return None;
154 }
155
156 if !self.externs.iter().all(|(_, item)| {
157 let export = match item {
158 Extern::Export(e) => e,
159 _ => return false,
160 };
161 match export.ty {
162 ComponentEntityType::Type { created, .. } => {
163 matches!(created, ComponentAnyTypeId::Component(_))
164 }
165 _ => false,
166 }
167 }) {
168 return None;
169 }
170
171 match crate::parse_component_name(&self.externs[0].0).ok()?.kind() {
176 ComponentNameKind::Interface(name) if name.interface().as_str() == "wit" => {
177 Some(WitEncodingVersion::V1)
178 }
179 ComponentNameKind::Plain(name) if name.is_bare() => Some(WitEncodingVersion::V2),
180 _ => None,
181 }
182 }
183
184 fn decode_wit_v1_package(&self) -> Result<(Resolve, PackageId)> {
185 let mut decoder = WitPackageDecoder::new(&self.types);
186
187 let mut pkg = None;
188 for (name, item) in self.externs.iter() {
189 let export = match item {
190 Extern::Export(e) => e,
191 _ => unreachable!(),
192 };
193 if pkg.is_some() {
194 bail!("more than one top-level exported component type found");
195 }
196 let name = crate::parse_component_name(name).unwrap();
197 pkg = Some(
198 decoder
199 .decode_v1_package(&name, export)
200 .with_context(|| format!("failed to decode document `{name}`"))?,
201 );
202 }
203
204 let pkg = pkg.ok_or_else(|| anyhow!("no exported component type found"))?;
205 let (mut resolve, package) = decoder.finish(pkg)?;
206 if let Some(package_metadata) = &self.package_metadata {
207 package_metadata.inject(&mut resolve, package)?;
208 }
209 Ok((resolve, package))
210 }
211
212 fn decode_wit_v2_package(&self) -> Result<(Resolve, PackageId)> {
213 let mut decoder = WitPackageDecoder::new(&self.types);
214
215 let mut pkg_name = None;
216
217 let mut interfaces = IndexMap::default();
218 let mut worlds = IndexMap::default();
219 let mut fields = PackageFields {
220 interfaces: &mut interfaces,
221 worlds: &mut worlds,
222 };
223
224 for (_, item) in self.externs.iter() {
225 let export = match item {
226 Extern::Export(e) => e,
227 _ => unreachable!(),
228 };
229 let component = match export.ty {
230 ComponentEntityType::Type {
231 created: ComponentAnyTypeId::Component(id),
232 ..
233 } => &self.types[id],
234 _ => unreachable!(),
235 };
236
237 if component.exports.len() != 1 {
240 bail!(
241 "Expected a single export, but found {} instead",
242 component.exports.len()
243 );
244 }
245
246 let name = component.exports.keys().nth(0).unwrap();
247
248 let item = &component.exports[name];
249 let name = match item.ty {
250 ComponentEntityType::Component(_) => {
251 let package_name = decoder.decode_world(name.as_str(), item, &mut fields)?;
252 package_name
253 }
254 ComponentEntityType::Instance(_) => {
255 let package_name = decoder.decode_interface(
256 name.as_str(),
257 &component.imports,
258 item,
259 &mut fields,
260 )?;
261 package_name
262 }
263 _ => unreachable!(),
264 };
265
266 if let Some(pkg_name) = pkg_name.as_ref() {
267 if pkg_name != &name {
270 bail!("item defined with mismatched package name")
271 }
272 } else {
273 pkg_name.replace(name);
274 }
275 }
276
277 let pkg = if let Some(name) = pkg_name {
278 Package {
279 name,
280 docs: Docs::default(),
281 interfaces,
282 worlds,
283 }
284 } else {
285 bail!("no exported component type found");
286 };
287
288 let (mut resolve, package) = decoder.finish(pkg)?;
289 if let Some(package_metadata) = &self.package_metadata {
290 package_metadata.inject(&mut resolve, package)?;
291 }
292 Ok((resolve, package))
293 }
294
295 fn decode_component(&self) -> Result<(Resolve, WorldId)> {
296 assert!(self.is_wit_package().is_none());
297 let mut decoder = WitPackageDecoder::new(&self.types);
298 let world_name = "root";
302 let world = decoder.resolve.worlds.alloc(World {
303 name: world_name.to_string(),
304 docs: Default::default(),
305 imports: Default::default(),
306 exports: Default::default(),
307 package: None,
308 includes: Default::default(),
309 stability: Default::default(),
310 span: Default::default(),
311 });
312 let mut package = Package {
313 name: PackageName {
317 namespace: "root".to_string(),
318 version: None,
319 name: "component".to_string(),
320 },
321 docs: Default::default(),
322 worlds: [(world_name.to_string(), world)].into_iter().collect(),
323 interfaces: Default::default(),
324 };
325
326 let mut fields = PackageFields {
327 worlds: &mut package.worlds,
328 interfaces: &mut package.interfaces,
329 };
330
331 for (name, item) in self.externs.iter() {
332 match item {
333 Extern::Import(i) => {
334 decoder.decode_component_import(name, i, world, &mut fields)?
335 }
336 Extern::Export(e) => {
337 decoder.decode_component_export(name, e, world, &mut fields)?
338 }
339 }
340 }
341
342 let (mut resolve, pkg) = decoder.finish(package)?;
343 if let Some(package_metadata) = &self.package_metadata {
344 package_metadata.inject(&mut resolve, pkg)?;
345 }
346 Ok((resolve, world))
347 }
348}
349
350pub enum DecodedWasm {
352 WitPackage(Resolve, PackageId),
358
359 Component(Resolve, WorldId),
362}
363
364impl DecodedWasm {
365 pub fn resolve(&self) -> &Resolve {
367 match self {
368 DecodedWasm::WitPackage(resolve, _) => resolve,
369 DecodedWasm::Component(resolve, _) => resolve,
370 }
371 }
372
373 pub fn package(&self) -> PackageId {
375 match self {
376 DecodedWasm::WitPackage(_, id) => *id,
377 DecodedWasm::Component(resolve, world) => resolve.worlds[*world].package.unwrap(),
378 }
379 }
380}
381
382pub fn decode_reader(reader: impl Read) -> Result<DecodedWasm> {
384 let info = ComponentInfo::from_reader(reader)?;
385
386 if let Some(version) = info.is_wit_package() {
387 match version {
388 WitEncodingVersion::V1 => {
389 log::debug!("decoding a v1 WIT package encoded as wasm");
390 let (resolve, pkg) = info.decode_wit_v1_package()?;
391 Ok(DecodedWasm::WitPackage(resolve, pkg))
392 }
393 WitEncodingVersion::V2 => {
394 log::debug!("decoding a v2 WIT package encoded as wasm");
395 let (resolve, pkg) = info.decode_wit_v2_package()?;
396 Ok(DecodedWasm::WitPackage(resolve, pkg))
397 }
398 }
399 } else {
400 log::debug!("inferring the WIT of a concrete component");
401 let (resolve, world) = info.decode_component()?;
402 Ok(DecodedWasm::Component(resolve, world))
403 }
404}
405
406pub fn decode(bytes: &[u8]) -> Result<DecodedWasm> {
413 decode_reader(bytes)
414}
415
416pub fn decode_world(wasm: &[u8]) -> Result<(Resolve, WorldId)> {
424 let mut validator = Validator::new_with_features(WasmFeatures::all());
425 let mut exports = Vec::new();
426 let mut depth = 1;
427 let mut types = None;
428
429 for payload in Parser::new(0).parse_all(wasm) {
430 let payload = payload?;
431
432 match validator.payload(&payload)? {
433 ValidPayload::Ok => {}
434 ValidPayload::Parser(_) => depth += 1,
435 ValidPayload::End(t) => {
436 depth -= 1;
437 if depth == 0 {
438 types = Some(t);
439 }
440 }
441 ValidPayload::Func(..) => {}
442 }
443
444 match payload {
445 Payload::ComponentExportSection(s) if depth == 1 => {
446 for export in s {
447 exports.push(export?);
448 }
449 }
450 _ => {}
451 }
452 }
453
454 if exports.len() != 1 {
455 bail!("expected one export in component");
456 }
457 if exports[0].kind != ComponentExternalKind::Type {
458 bail!("expected an export of a type");
459 }
460 if exports[0].ty.is_some() {
461 bail!("expected an un-ascribed exported type");
462 }
463 let types = types.as_ref().unwrap();
464 let world = match types.as_ref().component_any_type_at(exports[0].index) {
465 ComponentAnyTypeId::Component(c) => c,
466 _ => bail!("expected an exported component type"),
467 };
468
469 let mut decoder = WitPackageDecoder::new(types);
470 let mut interfaces = IndexMap::default();
471 let mut worlds = IndexMap::default();
472 let ty = &types[world];
473 assert_eq!(ty.imports.len(), 0);
474 assert_eq!(ty.exports.len(), 1);
475 let name = ty.exports.keys().nth(0).unwrap();
476 let name = decoder.decode_world(
477 name,
478 &ty.exports[0],
479 &mut PackageFields {
480 interfaces: &mut interfaces,
481 worlds: &mut worlds,
482 },
483 )?;
484 let (resolve, pkg) = decoder.finish(Package {
485 name,
486 interfaces,
487 worlds,
488 docs: Default::default(),
489 })?;
490 let world = *resolve.packages[pkg].worlds.iter().next().unwrap().1;
493 Ok((resolve, world))
494}
495
496struct PackageFields<'a> {
497 interfaces: &'a mut IndexMap<String, InterfaceId>,
498 worlds: &'a mut IndexMap<String, WorldId>,
499}
500
501struct WitPackageDecoder<'a> {
502 resolve: Resolve,
503 types: &'a Types,
504 foreign_packages: IndexMap<String, Package>,
505 iface_to_package_index: HashMap<InterfaceId, usize>,
506 named_interfaces: HashMap<String, InterfaceId>,
507
508 resources: HashMap<TypeOwner, HashMap<String, TypeId>>,
516
517 type_map: HashMap<ComponentAnyTypeId, TypeId>,
519}
520
521impl WitPackageDecoder<'_> {
522 fn new<'a>(types: &'a Types) -> WitPackageDecoder<'a> {
523 WitPackageDecoder {
524 resolve: Resolve::default(),
525 types,
526 type_map: HashMap::new(),
527 foreign_packages: Default::default(),
528 iface_to_package_index: Default::default(),
529 named_interfaces: Default::default(),
530 resources: Default::default(),
531 }
532 }
533
534 fn decode_v1_package(&mut self, name: &ComponentName, item: &ComponentItem) -> Result<Package> {
535 let ty = match item.ty {
536 ComponentEntityType::Type {
537 created: ComponentAnyTypeId::Component(id),
538 ..
539 } => &self.types[id],
540 _ => unreachable!(),
541 };
542
543 for (name, item) in ty.imports.iter() {
546 self.register_import(name, item)
547 .with_context(|| format!("failed to process import `{name}`"))?;
548 }
549
550 let mut package = Package {
551 name: match name.kind() {
555 ComponentNameKind::Interface(name) if name.interface().as_str() == "wit" => {
556 name.to_package_name(item)?
557 }
558 _ => bail!("package name is not a valid id: {name}"),
559 },
560 docs: Default::default(),
561 interfaces: Default::default(),
562 worlds: Default::default(),
563 };
564
565 let mut fields = PackageFields {
566 interfaces: &mut package.interfaces,
567 worlds: &mut package.worlds,
568 };
569
570 for (name, ty) in ty.exports.iter() {
571 match ty.ty {
572 ComponentEntityType::Instance(_) => {
573 self.register_interface(name.as_str(), ty, &mut fields)
574 .with_context(|| format!("failed to process export `{name}`"))?;
575 }
576 ComponentEntityType::Component(idx) => {
577 let ty = &self.types[idx];
578 self.register_world(name.as_str(), ty, &mut fields)
579 .with_context(|| format!("failed to process export `{name}`"))?;
580 }
581 _ => bail!("component export `{name}` is not an instance or component"),
582 }
583 }
584 Ok(package)
585 }
586
587 fn decode_interface<'a>(
588 &mut self,
589 name: &str,
590 imports: &wasmparser::collections::IndexMap<String, ComponentItem>,
591 item: &ComponentItem,
592 fields: &mut PackageFields<'a>,
593 ) -> Result<PackageName> {
594 let component_name = self
595 .parse_component_name(name)
596 .context("expected world name to have an ID form")?;
597
598 let package = match component_name.kind() {
599 ComponentNameKind::Interface(name) => name.to_package_name(item)?,
600 _ => bail!("expected world name to be fully qualified"),
601 };
602
603 for (name, ty) in imports.iter() {
604 self.register_import(name, ty)
605 .with_context(|| format!("failed to process import `{name}`"))?;
606 }
607
608 let _ = self.register_interface(name, item, fields)?;
609
610 Ok(package)
611 }
612
613 fn decode_world<'a>(
614 &mut self,
615 name: &str,
616 item: &ComponentItem,
617 fields: &mut PackageFields<'a>,
618 ) -> Result<PackageName> {
619 let ty = match item.ty {
620 ComponentEntityType::Component(ty) => &self.types[ty],
621 _ => unreachable!(),
622 };
623 let kebab_name = self
624 .parse_component_name(name)
625 .context("expected world name to have an ID form")?;
626
627 let package = match kebab_name.kind() {
628 ComponentNameKind::Interface(name) => name.to_package_name(item)?,
629 _ => bail!("expected world name to be fully qualified"),
630 };
631
632 let _ = self.register_world(name, ty, fields)?;
633
634 Ok(package)
635 }
636
637 fn decode_component_import<'a>(
638 &mut self,
639 name: &str,
640 item: &ComponentItem,
641 world: WorldId,
642 package: &mut PackageFields<'a>,
643 ) -> Result<()> {
644 log::debug!("decoding component import `{name}`");
645 let owner = TypeOwner::World(world);
646 let (name, item) = match item.ty {
647 ComponentEntityType::Instance(_) => self
648 .decode_world_instance(name, item, package)
649 .with_context(|| format!("failed to decode WIT from import `{name}`"))?,
650 ComponentEntityType::Func(_) => {
651 let func = self
652 .convert_function(name, item, owner)
653 .with_context(|| format!("failed to decode function from import `{name}`"))?;
654 (WorldKey::Name(name.to_string()), WorldItem::Function(func))
655 }
656 ComponentEntityType::Type { .. } => {
657 let id = self
658 .register_type_export(name, item, owner)
659 .with_context(|| format!("failed to decode type from export `{name}`"))?;
660 (
661 WorldKey::Name(name.to_string()),
662 WorldItem::Type {
663 id,
664 span: Default::default(),
665 },
666 )
667 }
668 _ => return Ok(()),
670 };
671 self.resolve.worlds[world].imports.insert(name, item);
672 Ok(())
673 }
674
675 fn decode_component_export<'a>(
676 &mut self,
677 name: &str,
678 item: &ComponentItem,
679 world: WorldId,
680 package: &mut PackageFields<'a>,
681 ) -> Result<()> {
682 log::debug!("decoding component export `{name}`");
683 let (name, item) = match item.ty {
684 ComponentEntityType::Func(_) => {
685 let func = self
686 .convert_function(name, item, TypeOwner::World(world))
687 .with_context(|| format!("failed to decode function from export `{name}`"))?;
688
689 (WorldKey::Name(name.to_string()), WorldItem::Function(func))
690 }
691 ComponentEntityType::Instance(_) => self
692 .decode_world_instance(name, item, package)
693 .with_context(|| format!("failed to decode WIT from export `{name}`"))?,
694 _ => {
695 bail!("component export `{name}` was not a function or instance")
696 }
697 };
698 self.resolve.worlds[world].exports.insert(name, item);
699 Ok(())
700 }
701
702 fn decode_world_instance<'a>(
711 &mut self,
712 name: &str,
713 item: &ComponentItem,
714 package: &mut PackageFields<'a>,
715 ) -> Result<(WorldKey, WorldItem)> {
716 let (key, id) = match &item.implements {
717 Some(i) => {
718 let id = self.register_import(i, item)?;
719 (WorldKey::Name(name.to_string()), id)
720 }
721 None => match self.parse_component_name(name)?.kind() {
722 ComponentNameKind::Interface(i) => {
723 let id = self.register_import(i.as_str(), item)?;
724 (WorldKey::Interface(id), id)
725 }
726 _ => self.register_interface(name, item, package)?,
727 },
728 };
729 Ok((
730 key,
731 WorldItem::Interface {
732 id,
733 stability: Default::default(),
734 docs: Default::default(),
735 span: Default::default(),
736 external_id: item.external_id.clone(),
737 },
738 ))
739 }
740
741 fn register_import(&mut self, name: &str, item: &ComponentItem) -> Result<InterfaceId> {
751 let ty = match item.ty {
752 ComponentEntityType::Instance(idx) => &self.types[idx],
753 _ => bail!("import `{name}` is not an instance"),
754 };
755 let (is_local, interface) = match self.named_interfaces.get(name) {
756 Some(id) => (true, *id),
757 None => (false, self.extract_dep_interface(name, item)?),
758 };
759 let owner = TypeOwner::Interface(interface);
760 for (name, item) in ty.exports.iter() {
761 log::debug!("decoding import instance export `{name}`");
762 match item.ty {
763 ComponentEntityType::Type {
764 referenced,
765 created,
766 } => {
767 match self.resolve.interfaces[interface]
768 .types
769 .get(name.as_str())
770 .copied()
771 {
772 Some(id) => {
790 log::debug!("type already exist");
791 match referenced {
792 ComponentAnyTypeId::Defined(ty) => {
793 self.register_defined(id, &self.types[ty])?;
794 }
795 ComponentAnyTypeId::Resource(_) => {}
796 _ => unreachable!(),
797 }
798 let prev = self.type_map.insert(created, id);
799 assert!(prev.is_none());
800 }
801
802 None => {
816 if is_local {
817 bail!("instance type export `{name}` not defined in interface");
818 }
819 let id = self.register_type_export(name.as_str(), item, owner)?;
820 let prev = self.resolve.interfaces[interface]
821 .types
822 .insert(name.to_string(), id);
823 assert!(prev.is_none());
824 }
825 }
826 }
827
828 ComponentEntityType::Func(_) => {
832 if self.resolve.interfaces[interface]
833 .functions
834 .contains_key(name.as_str())
835 {
836 continue;
839 }
840 if is_local {
841 bail!("instance function export `{name}` not defined in interface");
842 }
843 let func = self.convert_function(name.as_str(), item, owner)?;
844 let prev = self.resolve.interfaces[interface]
845 .functions
846 .insert(name.to_string(), func);
847 assert!(prev.is_none());
848 }
849
850 _ => bail!("instance type export `{name}` is not a type"),
851 }
852 }
853
854 Ok(interface)
855 }
856
857 fn find_alias(&self, id: ComponentAnyTypeId) -> Option<TypeId> {
858 let mut prev = None;
865 let mut cur = id;
866 while prev.is_none() {
867 prev = self.type_map.get(&cur).copied();
868 cur = match self.types.as_ref().peel_alias(cur) {
869 Some(next) => next,
870 None => break,
871 };
872 }
873 prev
874 }
875
876 fn extract_dep_interface(
879 &mut self,
880 name_string: &str,
881 item: &ComponentItem,
882 ) -> Result<InterfaceId> {
883 let name = crate::parse_component_name(name_string).unwrap();
884 let name = match name.kind() {
885 ComponentNameKind::Interface(name) => name,
886 _ => bail!("package name is not a valid id: {name_string}"),
887 };
888 let package_name = name.to_package_name(item)?;
889 let package = self
891 .foreign_packages
892 .entry(package_name.to_string())
893 .or_insert_with(|| Package {
894 name: package_name.clone(),
895 docs: Default::default(),
896 interfaces: Default::default(),
897 worlds: Default::default(),
898 });
899 let interface = *package
900 .interfaces
901 .entry(name.interface().to_string())
902 .or_insert_with(|| {
903 self.resolve.interfaces.alloc(Interface {
904 name: Some(name.interface().to_string()),
905 docs: Default::default(),
906 types: IndexMap::default(),
907 functions: IndexMap::default(),
908 package: None,
909 stability: Default::default(),
910 span: Default::default(),
911 clone_of: None,
912 })
913 });
914
915 self.iface_to_package_index.insert(
917 interface,
918 self.foreign_packages
919 .get_full(&package_name.to_string())
920 .unwrap()
921 .0,
922 );
923 Ok(interface)
924 }
925
926 fn register_interface<'a>(
942 &mut self,
943 name: &str,
944 item: &ComponentItem,
945 package: &mut PackageFields<'a>,
946 ) -> Result<(WorldKey, InterfaceId)> {
947 let ty = match item.ty {
948 ComponentEntityType::Instance(i) => &self.types[i],
949 _ => unreachable!(),
950 };
951 if self.named_interfaces.contains_key(name) {
955 let id = self.register_import(name, item)?;
956 return Ok((WorldKey::Interface(id), id));
957 }
958
959 let interface_name = self.extract_interface_name_from_component_name(name)?;
963
964 let mut interface = Interface {
965 name: interface_name.clone(),
966 docs: Default::default(),
967 types: IndexMap::default(),
968 functions: IndexMap::default(),
969 package: None,
970 stability: Default::default(),
971 span: Default::default(),
972 clone_of: None,
973 };
974
975 let owner = TypeOwner::Interface(self.resolve.interfaces.next_id());
976 for (name, item) in ty.exports.iter() {
977 match item.ty {
978 ComponentEntityType::Type { .. } => {
979 let ty = self
980 .register_type_export(name.as_str(), item, owner)
981 .with_context(|| format!("failed to register type export '{name}'"))?;
982 let prev = interface.types.insert(name.to_string(), ty);
983 assert!(prev.is_none());
984 }
985
986 ComponentEntityType::Func(_) => {
987 let func = self
988 .convert_function(name.as_str(), item, owner)
989 .with_context(|| format!("failed to convert function '{name}'"))?;
990 let prev = interface.functions.insert(name.to_string(), func);
991 assert!(prev.is_none());
992 }
993 _ => bail!("instance type export `{name}` is not a type or function"),
994 };
995 }
996 let id = self.resolve.interfaces.alloc(interface);
997 let key = match interface_name {
998 Some(interface_name) => {
1002 let prev = package.interfaces.insert(interface_name, id);
1003 assert!(prev.is_none(), "duplicate interface added for {name:?}");
1004 let prev = self.named_interfaces.insert(name.to_string(), id);
1005 assert!(prev.is_none());
1006 WorldKey::Interface(id)
1007 }
1008
1009 None => WorldKey::Name(name.to_string()),
1012 };
1013 Ok((key, id))
1014 }
1015
1016 fn parse_component_name(&self, name: &str) -> Result<ComponentName> {
1017 crate::parse_component_name(name)
1018 .with_context(|| format!("cannot extract item name from: {name}"))
1019 }
1020
1021 fn extract_interface_name_from_component_name(&self, name: &str) -> Result<Option<String>> {
1022 let component_name = self.parse_component_name(name)?;
1023 match component_name.kind() {
1024 ComponentNameKind::Interface(name) => Ok(Some(name.interface().to_string())),
1025 ComponentNameKind::Plain(name) if name.is_bare() => Ok(None),
1026 _ => bail!("cannot extract item name from: {name}"),
1027 }
1028 }
1029
1030 fn register_type_export(
1031 &mut self,
1032 name: &str,
1033 item: &ComponentItem,
1034 owner: TypeOwner,
1035 ) -> Result<TypeId> {
1036 let (referenced, created) = match item.ty {
1037 ComponentEntityType::Type {
1038 referenced,
1039 created,
1040 } => (referenced, created),
1041 _ => unreachable!(),
1042 };
1043 let kind = match self.find_alias(referenced) {
1044 Some(prev) => {
1048 log::debug!("type export for `{name}` is an alias");
1049 if matches!(owner, TypeOwner::Interface(_))
1058 && !matches!(self.resolve.types[prev].owner, TypeOwner::Interface(_))
1059 {
1060 bail!(
1061 "cannot represent this component in WIT: type `{name}` refers to a \
1062 type that isn't defined in an interface"
1063 );
1064 }
1065 TypeDefKind::Type(Type::Id(prev))
1066 }
1067
1068 None => {
1071 log::debug!("type export for `{name}` is a new type");
1072 match referenced {
1073 ComponentAnyTypeId::Defined(ty) => self
1074 .convert_defined(&self.types[ty])
1075 .context("failed to convert unaliased type")?,
1076 ComponentAnyTypeId::Resource(_) => TypeDefKind::Resource,
1077 _ => unreachable!(),
1078 }
1079 }
1080 };
1081 let ty = self.resolve.types.alloc(TypeDef {
1082 name: Some(name.to_string()),
1083 kind,
1084 docs: Default::default(),
1085 stability: Default::default(),
1086 owner,
1087 span: Default::default(),
1088 external_id: item.external_id.clone(),
1089 });
1090
1091 if let TypeDefKind::Resource = self.resolve.types[ty].kind {
1095 let prev = self
1096 .resources
1097 .entry(owner)
1098 .or_insert(HashMap::new())
1099 .insert(name.to_string(), ty);
1100 assert!(prev.is_none());
1101 }
1102
1103 let prev = self.type_map.insert(created, ty);
1107 if prev.is_some() {
1108 bail!(
1109 "cannot represent this component in WIT: the type `{name}` appears \
1110 more than once (for example, when an imported instance is \
1111 re-exported under a new name)"
1112 );
1113 }
1114 Ok(ty)
1115 }
1116
1117 fn register_world<'a>(
1118 &mut self,
1119 name: &str,
1120 ty: &ComponentType,
1121 package: &mut PackageFields<'a>,
1122 ) -> Result<WorldId> {
1123 let name = self
1124 .extract_interface_name_from_component_name(name)?
1125 .context("expected world name to have an ID form")?;
1126 let mut world = World {
1127 name: name.clone(),
1128 docs: Default::default(),
1129 imports: Default::default(),
1130 exports: Default::default(),
1131 includes: Default::default(),
1132 package: None,
1133 stability: Default::default(),
1134 span: Default::default(),
1135 };
1136
1137 let owner = TypeOwner::World(self.resolve.worlds.next_id());
1138 for (name, item) in ty.imports.iter() {
1139 let (name, item) = match item.ty {
1140 ComponentEntityType::Instance(_) => {
1141 self.decode_world_instance(name, item, package)?
1142 }
1143 ComponentEntityType::Type { .. } => {
1144 let ty = self.register_type_export(name.as_str(), item, owner)?;
1145 (
1146 WorldKey::Name(name.to_string()),
1147 WorldItem::Type {
1148 id: ty,
1149 span: Default::default(),
1150 },
1151 )
1152 }
1153 ComponentEntityType::Func(_) => {
1154 let func = self.convert_function(name.as_str(), item, owner)?;
1155 (WorldKey::Name(name.to_string()), WorldItem::Function(func))
1156 }
1157 _ => bail!("component import `{name}` is not an instance, func, or type"),
1158 };
1159 world.imports.insert(name, item);
1160 }
1161
1162 for (name, item) in ty.exports.iter() {
1163 let (name, item) = match item.ty {
1164 ComponentEntityType::Instance(_) => {
1165 self.decode_world_instance(name, item, package)?
1166 }
1167
1168 ComponentEntityType::Func(_) => {
1169 let func = self.convert_function(name.as_str(), item, owner)?;
1170 (WorldKey::Name(name.to_string()), WorldItem::Function(func))
1171 }
1172
1173 _ => bail!("component export `{name}` is not an instance or function"),
1174 };
1175 world.exports.insert(name, item);
1176 }
1177 let id = self.resolve.worlds.alloc(world);
1178 let prev = package.worlds.insert(name, id);
1179 assert!(prev.is_none());
1180 Ok(id)
1181 }
1182
1183 fn convert_function(
1184 &mut self,
1185 name: &str,
1186 item: &ComponentItem,
1187 owner: TypeOwner,
1188 ) -> Result<Function> {
1189 let ty = match item.ty {
1190 ComponentEntityType::Func(i) => &self.types[i],
1191 _ => unreachable!(),
1192 };
1193 let name = crate::parse_component_name(name).unwrap();
1194 let params = ty
1195 .params
1196 .iter()
1197 .map(|(name, ty)| {
1198 Ok(Param {
1199 name: name.to_string(),
1200 ty: self.convert_valtype(ty)?,
1201 span: Default::default(),
1202 })
1203 })
1204 .collect::<Result<Vec<_>>>()
1205 .context("failed to convert params")?;
1206 let result = match &ty.result {
1207 Some(ty) => Some(
1208 self.convert_valtype(ty)
1209 .context("failed to convert anonymous result type")?,
1210 ),
1211 None => None,
1212 };
1213 Ok(Function {
1214 docs: Default::default(),
1215 stability: Default::default(),
1216 external_id: item.external_id.clone(),
1217 kind: match name.kind() {
1218 ComponentNameKind::Plain(plain) => {
1219 if plain.accessor.is_some() && ty.async_ {
1220 panic!("function `{name}` is an async accessor (should be impossible)");
1221 }
1222
1223 let resource = plain
1224 .resource()
1225 .map(|resource| self.resources[&owner][resource.as_str()]);
1226 match (plain.resource_func, plain.accessor) {
1227 (None, None) => {
1228 if ty.async_ {
1229 FunctionKind::AsyncFreestanding
1230 } else {
1231 FunctionKind::Freestanding
1232 }
1233 }
1234 (None, Some(ComponentAccessorKind::Get)) => FunctionKind::Getter,
1235 (None, Some(ComponentAccessorKind::Set)) => FunctionKind::Setter,
1236
1237 (Some(ResourceFuncKind::Constructor), None) => {
1238 FunctionKind::Constructor(resource.unwrap())
1239 }
1240 (Some(ResourceFuncKind::Constructor), Some(_)) => {
1241 panic!(
1242 "function `{name}` is a constructor with an accessor (should be impossible)"
1243 );
1244 }
1245
1246 (Some(ResourceFuncKind::Method), None) => {
1247 if ty.async_ {
1248 FunctionKind::AsyncMethod(resource.unwrap())
1249 } else {
1250 FunctionKind::Method(resource.unwrap())
1251 }
1252 }
1253 (Some(ResourceFuncKind::Method), Some(ComponentAccessorKind::Get)) => {
1254 FunctionKind::MethodGetter(resource.unwrap())
1255 }
1256 (Some(ResourceFuncKind::Method), Some(ComponentAccessorKind::Set)) => {
1257 FunctionKind::MethodSetter(resource.unwrap())
1258 }
1259
1260 (Some(ResourceFuncKind::Static), None) => {
1261 if ty.async_ {
1262 FunctionKind::AsyncStatic(resource.unwrap())
1263 } else {
1264 FunctionKind::Static(resource.unwrap())
1265 }
1266 }
1267 (Some(ResourceFuncKind::Static), Some(ComponentAccessorKind::Get)) => {
1268 FunctionKind::StaticGetter(resource.unwrap())
1269 }
1270 (Some(ResourceFuncKind::Static), Some(ComponentAccessorKind::Set)) => {
1271 FunctionKind::StaticSetter(resource.unwrap())
1272 }
1273 }
1274 }
1275
1276 ComponentNameKind::Interface(_) => unreachable!(),
1278 },
1279
1280 name: name.to_string(),
1285 params,
1286 result,
1287 span: Default::default(),
1288 })
1289 }
1290
1291 fn convert_valtype(&mut self, ty: &ComponentValType) -> Result<Type> {
1292 let id = match ty {
1293 ComponentValType::Primitive(ty) => return Ok(self.convert_primitive(*ty)),
1294 ComponentValType::Type(id) => *id,
1295 };
1296
1297 let key: ComponentAnyTypeId = id.into();
1299 if let Some(ret) = self.type_map.get(&key) {
1300 return Ok(Type::Id(*ret));
1301 }
1302
1303 let def = &self.types[id];
1309 let kind = self.convert_defined(def)?;
1310 match &kind {
1311 TypeDefKind::Type(_)
1312 | TypeDefKind::List(_)
1313 | TypeDefKind::Map(_, _)
1314 | TypeDefKind::FixedLengthList(..)
1315 | TypeDefKind::Tuple(_)
1316 | TypeDefKind::Option(_)
1317 | TypeDefKind::Result(_)
1318 | TypeDefKind::Handle(_)
1319 | TypeDefKind::Future(_)
1320 | TypeDefKind::Stream(_) => {}
1321
1322 TypeDefKind::Resource
1323 | TypeDefKind::Record(_)
1324 | TypeDefKind::Enum(_)
1325 | TypeDefKind::Variant(_)
1326 | TypeDefKind::Flags(_) => {
1327 bail!("unexpected unnamed type of kind '{}'", kind.as_str());
1328 }
1329 TypeDefKind::Unknown => unreachable!(),
1330 }
1331 let ty = self.resolve.types.alloc(TypeDef {
1332 name: None,
1333 docs: Default::default(),
1334 stability: Default::default(),
1335 owner: TypeOwner::None,
1336 kind,
1337 span: Default::default(),
1338 external_id: None,
1339 });
1340 let prev = self.type_map.insert(id.into(), ty);
1341 assert!(prev.is_none());
1342 Ok(Type::Id(ty))
1343 }
1344
1345 fn convert_defined(&mut self, ty: &ComponentDefinedType) -> Result<TypeDefKind> {
1349 match ty {
1350 ComponentDefinedType::Primitive(t) => Ok(TypeDefKind::Type(self.convert_primitive(*t))),
1351
1352 ComponentDefinedType::List { element, .. } => {
1353 let t = self.convert_valtype(element)?;
1354 Ok(TypeDefKind::List(t))
1355 }
1356
1357 ComponentDefinedType::Map { key, value, .. } => {
1358 let k = self.convert_valtype(key)?;
1359 let v = self.convert_valtype(value)?;
1360 Ok(TypeDefKind::Map(k, v))
1361 }
1362
1363 ComponentDefinedType::FixedLengthList {
1364 element, length, ..
1365 } => {
1366 let t = self.convert_valtype(element)?;
1367 Ok(TypeDefKind::FixedLengthList(t, *length))
1368 }
1369
1370 ComponentDefinedType::Tuple(t) => {
1371 let types = t
1372 .types
1373 .iter()
1374 .map(|t| self.convert_valtype(t))
1375 .collect::<Result<_>>()?;
1376 Ok(TypeDefKind::Tuple(Tuple { types }))
1377 }
1378
1379 ComponentDefinedType::Option { ty, .. } => {
1380 let t = self.convert_valtype(ty)?;
1381 Ok(TypeDefKind::Option(t))
1382 }
1383
1384 ComponentDefinedType::Result { ok, err, .. } => {
1385 let ok = match ok {
1386 Some(t) => Some(self.convert_valtype(t)?),
1387 None => None,
1388 };
1389 let err = match err {
1390 Some(t) => Some(self.convert_valtype(t)?),
1391 None => None,
1392 };
1393 Ok(TypeDefKind::Result(Result_ { ok, err }))
1394 }
1395
1396 ComponentDefinedType::Record(r) => {
1397 let fields = r
1398 .fields
1399 .iter()
1400 .map(|(name, ty)| {
1401 Ok(Field {
1402 name: name.to_string(),
1403 ty: self.convert_valtype(ty).with_context(|| {
1404 format!("failed to convert record field '{name}'")
1405 })?,
1406 docs: Default::default(),
1407 span: Default::default(),
1408 })
1409 })
1410 .collect::<Result<_>>()?;
1411 Ok(TypeDefKind::Record(Record { fields }))
1412 }
1413
1414 ComponentDefinedType::Variant(v) => {
1415 let cases = v
1416 .cases
1417 .iter()
1418 .map(|(name, case)| {
1419 Ok(Case {
1420 name: name.to_string(),
1421 ty: match &case.ty {
1422 Some(ty) => Some(self.convert_valtype(ty)?),
1423 None => None,
1424 },
1425 docs: Default::default(),
1426 span: Default::default(),
1427 })
1428 })
1429 .collect::<Result<_>>()?;
1430 Ok(TypeDefKind::Variant(Variant { cases }))
1431 }
1432
1433 ComponentDefinedType::Flags(f) => {
1434 let flags = f
1435 .iter()
1436 .map(|name| Flag {
1437 name: name.to_string(),
1438 docs: Default::default(),
1439 span: Default::default(),
1440 })
1441 .collect();
1442 Ok(TypeDefKind::Flags(Flags { flags }))
1443 }
1444
1445 ComponentDefinedType::Enum(e) => {
1446 let cases = e
1447 .iter()
1448 .cloned()
1449 .map(|name| EnumCase {
1450 name: name.into(),
1451 docs: Default::default(),
1452 span: Default::default(),
1453 })
1454 .collect();
1455 Ok(TypeDefKind::Enum(Enum { cases }))
1456 }
1457
1458 ComponentDefinedType::Own(id) => {
1459 let key: ComponentAnyTypeId = (*id).into();
1460 let id = self.type_map[&key];
1461 Ok(TypeDefKind::Handle(Handle::Own(id)))
1462 }
1463
1464 ComponentDefinedType::Borrow(id) => {
1465 let key: ComponentAnyTypeId = (*id).into();
1466 let id = self.type_map[&key];
1467 Ok(TypeDefKind::Handle(Handle::Borrow(id)))
1468 }
1469
1470 ComponentDefinedType::Future { ty, .. } => Ok(TypeDefKind::Future(
1471 ty.as_ref().map(|ty| self.convert_valtype(ty)).transpose()?,
1472 )),
1473
1474 ComponentDefinedType::Stream { ty, .. } => Ok(TypeDefKind::Stream(
1475 ty.as_ref().map(|ty| self.convert_valtype(ty)).transpose()?,
1476 )),
1477 }
1478 }
1479
1480 fn convert_primitive(&self, ty: PrimitiveValType) -> Type {
1481 match ty {
1482 PrimitiveValType::U8 => Type::U8,
1483 PrimitiveValType::S8 => Type::S8,
1484 PrimitiveValType::U16 => Type::U16,
1485 PrimitiveValType::S16 => Type::S16,
1486 PrimitiveValType::U32 => Type::U32,
1487 PrimitiveValType::S32 => Type::S32,
1488 PrimitiveValType::U64 => Type::U64,
1489 PrimitiveValType::S64 => Type::S64,
1490 PrimitiveValType::Bool => Type::Bool,
1491 PrimitiveValType::Char => Type::Char,
1492 PrimitiveValType::String => Type::String,
1493 PrimitiveValType::F32 => Type::F32,
1494 PrimitiveValType::F64 => Type::F64,
1495 PrimitiveValType::ErrorContext => Type::ErrorContext,
1496 }
1497 }
1498
1499 fn register_defined(&mut self, id: TypeId, def: &ComponentDefinedType) -> Result<()> {
1500 Registrar {
1501 types: &self.types,
1502 type_map: &mut self.type_map,
1503 resolve: &self.resolve,
1504 }
1505 .defined(id, def)
1506 }
1507
1508 fn finish(mut self, package: Package) -> Result<(Resolve, PackageId)> {
1513 let mut order = IndexSet::default();
1516 let mut visiting = HashSet::new();
1517 for i in 0..self.foreign_packages.len() {
1518 self.visit_package(i, &mut order, &mut visiting)?;
1519 }
1520
1521 let mut idx_to_pos = vec![0; self.foreign_packages.len()];
1524 for (pos, idx) in order.iter().enumerate() {
1525 idx_to_pos[*idx] = pos;
1526 }
1527 let mut deps = mem::take(&mut self.foreign_packages)
1530 .into_iter()
1531 .enumerate()
1532 .collect::<Vec<_>>();
1533 deps.sort_by_key(|(idx, _)| idx_to_pos[*idx]);
1534
1535 for (_idx, (_url, pkg)) in deps {
1538 self.insert_package(pkg);
1539 }
1540
1541 let id = self.insert_package(package);
1542 assert!(self.resolve.worlds.iter().all(|(_, w)| w.package.is_some()));
1543 assert!(
1544 self.resolve
1545 .interfaces
1546 .iter()
1547 .all(|(_, i)| i.package.is_some())
1548 );
1549 Ok((self.resolve, id))
1550 }
1551
1552 fn insert_package(&mut self, package: Package) -> PackageId {
1553 let Package {
1554 name,
1555 interfaces,
1556 worlds,
1557 docs,
1558 } = package;
1559
1560 let pkg = self
1566 .resolve
1567 .package_names
1568 .get(&name)
1569 .copied()
1570 .unwrap_or_else(|| {
1571 let id = self.resolve.packages.alloc(Package {
1572 name: name.clone(),
1573 interfaces: Default::default(),
1574 worlds: Default::default(),
1575 docs,
1576 });
1577 let prev = self.resolve.package_names.insert(name, id);
1578 assert!(prev.is_none());
1579 id
1580 });
1581
1582 for (name, id) in interfaces {
1583 let prev = self.resolve.packages[pkg].interfaces.insert(name, id);
1584 assert!(prev.is_none());
1585 self.resolve.interfaces[id].package = Some(pkg);
1586 }
1587
1588 for (name, id) in worlds {
1589 let prev = self.resolve.packages[pkg].worlds.insert(name, id);
1590 assert!(prev.is_none());
1591 let world = &mut self.resolve.worlds[id];
1592 world.package = Some(pkg);
1593 for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1594 if let WorldKey::Name(_) = name {
1595 if let WorldItem::Interface { id, .. } = item {
1596 let iface = &mut self.resolve.interfaces[*id];
1597 if iface.name.is_none() {
1598 iface.package = Some(pkg);
1599 }
1600 }
1601 }
1602 }
1603 }
1604
1605 pkg
1606 }
1607
1608 fn visit_package(
1609 &self,
1610 idx: usize,
1611 order: &mut IndexSet<usize>,
1612 visiting: &mut HashSet<usize>,
1613 ) -> Result<()> {
1614 if order.contains(&idx) {
1615 return Ok(());
1616 }
1617
1618 let (name, pkg) = self.foreign_packages.get_index(idx).unwrap();
1619 if !visiting.insert(idx) {
1620 bail!(
1621 "cannot represent this component in WIT: package `{name}` creates a dependency cycle"
1622 );
1623 }
1624 let interfaces = pkg.interfaces.values().copied().chain(
1625 pkg.worlds
1626 .values()
1627 .flat_map(|w| {
1628 let world = &self.resolve.worlds[*w];
1629 world.imports.values().chain(world.exports.values())
1630 })
1631 .filter_map(|item| match item {
1632 WorldItem::Interface { id, .. } => Some(*id),
1633 WorldItem::Function(_) | WorldItem::Type { .. } => None,
1634 }),
1635 );
1636 for iface in interfaces {
1637 for dep in self.resolve.interface_direct_deps(iface) {
1638 let Some(&dep_idx) = self.iface_to_package_index.get(&dep) else {
1639 bail!(
1640 "cannot represent this component in WIT: package `{name}` uses a type \
1641 from an interface it can't depend on"
1642 );
1643 };
1644 if dep_idx != idx {
1645 self.visit_package(dep_idx, order, visiting)?;
1646 }
1647 }
1648 }
1649
1650 visiting.remove(&idx);
1651 assert!(order.insert(idx));
1652 Ok(())
1653 }
1654}
1655
1656struct Registrar<'a> {
1659 types: &'a Types,
1660 type_map: &'a mut HashMap<ComponentAnyTypeId, TypeId>,
1661 resolve: &'a Resolve,
1662}
1663
1664impl Registrar<'_> {
1665 fn defined(&mut self, id: TypeId, def: &ComponentDefinedType) -> Result<()> {
1668 match def {
1669 ComponentDefinedType::Primitive(_) => Ok(()),
1670
1671 ComponentDefinedType::List { element, .. } => {
1672 let ty = match &self.resolve.types[id].kind {
1673 TypeDefKind::List(r) => r,
1674 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1682 _ => bail!("expected a list"),
1683 };
1684 self.valtype(element, ty)
1685 }
1686
1687 ComponentDefinedType::Map { key, value, .. } => {
1688 let (key_ty, value_ty) = match &self.resolve.types[id].kind {
1689 TypeDefKind::Map(k, v) => (k, v),
1690 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1691 _ => bail!("expected a map"),
1692 };
1693 self.valtype(key, key_ty)?;
1694 self.valtype(value, value_ty)
1695 }
1696
1697 ComponentDefinedType::FixedLengthList {
1698 element, length, ..
1699 } => {
1700 let ty = match &self.resolve.types[id].kind {
1701 TypeDefKind::FixedLengthList(r, elements2) if elements2 == length => r,
1702 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1703 _ => bail!("expected a fixed-length {length} list"),
1704 };
1705 self.valtype(element, ty)
1706 }
1707
1708 ComponentDefinedType::Tuple(t) => {
1709 let ty = match &self.resolve.types[id].kind {
1710 TypeDefKind::Tuple(r) => r,
1711 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1712 _ => bail!("expected a tuple"),
1713 };
1714 if ty.types.len() != t.types.len() {
1715 bail!("mismatched number of tuple fields");
1716 }
1717 for (a, b) in t.types.iter().zip(ty.types.iter()) {
1718 self.valtype(a, b)?;
1719 }
1720 Ok(())
1721 }
1722
1723 ComponentDefinedType::Option { ty: t, .. } => {
1724 let ty = match &self.resolve.types[id].kind {
1725 TypeDefKind::Option(r) => r,
1726 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1727 _ => bail!("expected an option"),
1728 };
1729 self.valtype(t, ty)
1730 }
1731
1732 ComponentDefinedType::Result { ok, err, .. } => {
1733 let ty = match &self.resolve.types[id].kind {
1734 TypeDefKind::Result(r) => r,
1735 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1736 _ => bail!("expected a result"),
1737 };
1738 match (ok, &ty.ok) {
1739 (Some(a), Some(b)) => self.valtype(a, b)?,
1740 (None, None) => {}
1741 _ => bail!("disagreement on result structure"),
1742 }
1743 match (err, &ty.err) {
1744 (Some(a), Some(b)) => self.valtype(a, b)?,
1745 (None, None) => {}
1746 _ => bail!("disagreement on result structure"),
1747 }
1748 Ok(())
1749 }
1750
1751 ComponentDefinedType::Record(def) => {
1752 let ty = match &self.resolve.types[id].kind {
1753 TypeDefKind::Record(r) => r,
1754 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1755 _ => bail!("expected a record"),
1756 };
1757 if def.fields.len() != ty.fields.len() {
1758 bail!("mismatched number of record fields");
1759 }
1760 for ((name, ty), field) in def.fields.iter().zip(&ty.fields) {
1761 if name.as_str() != field.name {
1762 bail!("mismatched field order");
1763 }
1764 self.valtype(ty, &field.ty)?;
1765 }
1766 Ok(())
1767 }
1768
1769 ComponentDefinedType::Variant(def) => {
1770 let ty = match &self.resolve.types[id].kind {
1771 TypeDefKind::Variant(r) => r,
1772 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1773 _ => bail!("expected a variant"),
1774 };
1775 if def.cases.len() != ty.cases.len() {
1776 bail!("mismatched number of variant cases");
1777 }
1778 for ((name, ty), case) in def.cases.iter().zip(&ty.cases) {
1779 if name.as_str() != case.name {
1780 bail!("mismatched case order");
1781 }
1782 match (&ty.ty, &case.ty) {
1783 (Some(a), Some(b)) => self.valtype(a, b)?,
1784 (None, None) => {}
1785 _ => bail!("disagreement on case type"),
1786 }
1787 }
1788 Ok(())
1789 }
1790
1791 ComponentDefinedType::Future { ty: payload, .. } => {
1792 let ty = match &self.resolve.types[id].kind {
1793 TypeDefKind::Future(p) => p,
1794 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1795 _ => bail!("expected a future"),
1796 };
1797 match (payload, ty) {
1798 (Some(a), Some(b)) => self.valtype(a, b),
1799 (None, None) => Ok(()),
1800 _ => bail!("disagreement on future payload"),
1801 }
1802 }
1803
1804 ComponentDefinedType::Stream { ty: payload, .. } => {
1805 let ty = match &self.resolve.types[id].kind {
1806 TypeDefKind::Stream(p) => p,
1807 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1808 _ => bail!("expected a stream"),
1809 };
1810 match (payload, ty) {
1811 (Some(a), Some(b)) => self.valtype(a, b),
1812 (None, None) => Ok(()),
1813 _ => bail!("disagreement on stream payload"),
1814 }
1815 }
1816
1817 ComponentDefinedType::Flags(_)
1819 | ComponentDefinedType::Enum(_)
1820 | ComponentDefinedType::Own(_)
1821 | ComponentDefinedType::Borrow(_) => Ok(()),
1822 }
1823 }
1824
1825 fn valtype(&mut self, wasm: &ComponentValType, wit: &Type) -> Result<()> {
1826 let wasm = match wasm {
1827 ComponentValType::Type(wasm) => *wasm,
1828 ComponentValType::Primitive(_wasm) => {
1829 assert!(!matches!(wit, Type::Id(_)));
1830 return Ok(());
1831 }
1832 };
1833 let wit = match wit {
1834 Type::Id(id) => *id,
1835 _ => bail!("expected id-based type"),
1836 };
1837 let prev = match self.type_map.insert(wasm.into(), wit) {
1838 Some(prev) => prev,
1839 None => {
1840 let wasm = &self.types[wasm];
1841 return self.defined(wit, wasm);
1842 }
1843 };
1844 let _ = prev;
1927 Ok(())
1928 }
1929}
1930
1931pub(crate) trait InterfaceNameExt {
1932 fn to_package_name(&self, item: &ComponentItem) -> Result<PackageName>;
1933}
1934
1935impl InterfaceNameExt for wasmparser::names::InterfaceName<'_> {
1936 fn to_package_name(&self, item: &ComponentItem) -> Result<PackageName> {
1937 Ok(PackageName {
1938 namespace: self.namespace().to_string(),
1939 name: self.package().to_string(),
1940 version: self.version(item.version_suffix.as_deref())?,
1941 })
1942 }
1943}