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 TypeDefKind::Type(Type::Id(prev))
1050 }
1051
1052 None => {
1055 log::debug!("type export for `{name}` is a new type");
1056 match referenced {
1057 ComponentAnyTypeId::Defined(ty) => self
1058 .convert_defined(&self.types[ty])
1059 .context("failed to convert unaliased type")?,
1060 ComponentAnyTypeId::Resource(_) => TypeDefKind::Resource,
1061 _ => unreachable!(),
1062 }
1063 }
1064 };
1065 let ty = self.resolve.types.alloc(TypeDef {
1066 name: Some(name.to_string()),
1067 kind,
1068 docs: Default::default(),
1069 stability: Default::default(),
1070 owner,
1071 span: Default::default(),
1072 external_id: item.external_id.clone(),
1073 });
1074
1075 if let TypeDefKind::Resource = self.resolve.types[ty].kind {
1079 let prev = self
1080 .resources
1081 .entry(owner)
1082 .or_insert(HashMap::new())
1083 .insert(name.to_string(), ty);
1084 assert!(prev.is_none());
1085 }
1086
1087 let prev = self.type_map.insert(created, ty);
1091 if prev.is_some() {
1092 bail!(
1093 "cannot represent this component in WIT: the type `{name}` appears \
1094 more than once (for example, when an imported instance is \
1095 re-exported under a new name)"
1096 );
1097 }
1098 Ok(ty)
1099 }
1100
1101 fn register_world<'a>(
1102 &mut self,
1103 name: &str,
1104 ty: &ComponentType,
1105 package: &mut PackageFields<'a>,
1106 ) -> Result<WorldId> {
1107 let name = self
1108 .extract_interface_name_from_component_name(name)?
1109 .context("expected world name to have an ID form")?;
1110 let mut world = World {
1111 name: name.clone(),
1112 docs: Default::default(),
1113 imports: Default::default(),
1114 exports: Default::default(),
1115 includes: Default::default(),
1116 package: None,
1117 stability: Default::default(),
1118 span: Default::default(),
1119 };
1120
1121 let owner = TypeOwner::World(self.resolve.worlds.next_id());
1122 for (name, item) in ty.imports.iter() {
1123 let (name, item) = match item.ty {
1124 ComponentEntityType::Instance(_) => {
1125 self.decode_world_instance(name, item, package)?
1126 }
1127 ComponentEntityType::Type { .. } => {
1128 let ty = self.register_type_export(name.as_str(), item, owner)?;
1129 (
1130 WorldKey::Name(name.to_string()),
1131 WorldItem::Type {
1132 id: ty,
1133 span: Default::default(),
1134 },
1135 )
1136 }
1137 ComponentEntityType::Func(_) => {
1138 let func = self.convert_function(name.as_str(), item, owner)?;
1139 (WorldKey::Name(name.to_string()), WorldItem::Function(func))
1140 }
1141 _ => bail!("component import `{name}` is not an instance, func, or type"),
1142 };
1143 world.imports.insert(name, item);
1144 }
1145
1146 for (name, item) in ty.exports.iter() {
1147 let (name, item) = match item.ty {
1148 ComponentEntityType::Instance(_) => {
1149 self.decode_world_instance(name, item, package)?
1150 }
1151
1152 ComponentEntityType::Func(_) => {
1153 let func = self.convert_function(name.as_str(), item, owner)?;
1154 (WorldKey::Name(name.to_string()), WorldItem::Function(func))
1155 }
1156
1157 _ => bail!("component export `{name}` is not an instance or function"),
1158 };
1159 world.exports.insert(name, item);
1160 }
1161 let id = self.resolve.worlds.alloc(world);
1162 let prev = package.worlds.insert(name, id);
1163 assert!(prev.is_none());
1164 Ok(id)
1165 }
1166
1167 fn convert_function(
1168 &mut self,
1169 name: &str,
1170 item: &ComponentItem,
1171 owner: TypeOwner,
1172 ) -> Result<Function> {
1173 let ty = match item.ty {
1174 ComponentEntityType::Func(i) => &self.types[i],
1175 _ => unreachable!(),
1176 };
1177 let name = crate::parse_component_name(name).unwrap();
1178 let params = ty
1179 .params
1180 .iter()
1181 .map(|(name, ty)| {
1182 Ok(Param {
1183 name: name.to_string(),
1184 ty: self.convert_valtype(ty)?,
1185 span: Default::default(),
1186 })
1187 })
1188 .collect::<Result<Vec<_>>>()
1189 .context("failed to convert params")?;
1190 let result = match &ty.result {
1191 Some(ty) => Some(
1192 self.convert_valtype(ty)
1193 .context("failed to convert anonymous result type")?,
1194 ),
1195 None => None,
1196 };
1197 Ok(Function {
1198 docs: Default::default(),
1199 stability: Default::default(),
1200 external_id: item.external_id.clone(),
1201 kind: match name.kind() {
1202 ComponentNameKind::Plain(plain) => {
1203 if plain.accessor.is_some() && ty.async_ {
1204 panic!("function `{name}` is an async accessor (should be impossible)");
1205 }
1206
1207 let resource = plain
1208 .resource()
1209 .map(|resource| self.resources[&owner][resource.as_str()]);
1210 match (plain.resource_func, plain.accessor) {
1211 (None, None) => {
1212 if ty.async_ {
1213 FunctionKind::AsyncFreestanding
1214 } else {
1215 FunctionKind::Freestanding
1216 }
1217 }
1218 (None, Some(ComponentAccessorKind::Get)) => FunctionKind::Getter,
1219 (None, Some(ComponentAccessorKind::Set)) => FunctionKind::Setter,
1220
1221 (Some(ResourceFuncKind::Constructor), None) => {
1222 FunctionKind::Constructor(resource.unwrap())
1223 }
1224 (Some(ResourceFuncKind::Constructor), Some(_)) => {
1225 panic!(
1226 "function `{name}` is a constructor with an accessor (should be impossible)"
1227 );
1228 }
1229
1230 (Some(ResourceFuncKind::Method), None) => {
1231 if ty.async_ {
1232 FunctionKind::AsyncMethod(resource.unwrap())
1233 } else {
1234 FunctionKind::Method(resource.unwrap())
1235 }
1236 }
1237 (Some(ResourceFuncKind::Method), Some(ComponentAccessorKind::Get)) => {
1238 FunctionKind::MethodGetter(resource.unwrap())
1239 }
1240 (Some(ResourceFuncKind::Method), Some(ComponentAccessorKind::Set)) => {
1241 FunctionKind::MethodSetter(resource.unwrap())
1242 }
1243
1244 (Some(ResourceFuncKind::Static), None) => {
1245 if ty.async_ {
1246 FunctionKind::AsyncStatic(resource.unwrap())
1247 } else {
1248 FunctionKind::Static(resource.unwrap())
1249 }
1250 }
1251 (Some(ResourceFuncKind::Static), Some(ComponentAccessorKind::Get)) => {
1252 FunctionKind::StaticGetter(resource.unwrap())
1253 }
1254 (Some(ResourceFuncKind::Static), Some(ComponentAccessorKind::Set)) => {
1255 FunctionKind::StaticSetter(resource.unwrap())
1256 }
1257 }
1258 }
1259
1260 ComponentNameKind::Interface(_) => unreachable!(),
1262 },
1263
1264 name: name.to_string(),
1269 params,
1270 result,
1271 span: Default::default(),
1272 })
1273 }
1274
1275 fn convert_valtype(&mut self, ty: &ComponentValType) -> Result<Type> {
1276 let id = match ty {
1277 ComponentValType::Primitive(ty) => return Ok(self.convert_primitive(*ty)),
1278 ComponentValType::Type(id) => *id,
1279 };
1280
1281 let key: ComponentAnyTypeId = id.into();
1283 if let Some(ret) = self.type_map.get(&key) {
1284 return Ok(Type::Id(*ret));
1285 }
1286
1287 let def = &self.types[id];
1293 let kind = self.convert_defined(def)?;
1294 match &kind {
1295 TypeDefKind::Type(_)
1296 | TypeDefKind::List(_)
1297 | TypeDefKind::Map(_, _)
1298 | TypeDefKind::FixedLengthList(..)
1299 | TypeDefKind::Tuple(_)
1300 | TypeDefKind::Option(_)
1301 | TypeDefKind::Result(_)
1302 | TypeDefKind::Handle(_)
1303 | TypeDefKind::Future(_)
1304 | TypeDefKind::Stream(_) => {}
1305
1306 TypeDefKind::Resource
1307 | TypeDefKind::Record(_)
1308 | TypeDefKind::Enum(_)
1309 | TypeDefKind::Variant(_)
1310 | TypeDefKind::Flags(_) => {
1311 bail!("unexpected unnamed type of kind '{}'", kind.as_str());
1312 }
1313 TypeDefKind::Unknown => unreachable!(),
1314 }
1315 let ty = self.resolve.types.alloc(TypeDef {
1316 name: None,
1317 docs: Default::default(),
1318 stability: Default::default(),
1319 owner: TypeOwner::None,
1320 kind,
1321 span: Default::default(),
1322 external_id: None,
1323 });
1324 let prev = self.type_map.insert(id.into(), ty);
1325 assert!(prev.is_none());
1326 Ok(Type::Id(ty))
1327 }
1328
1329 fn convert_defined(&mut self, ty: &ComponentDefinedType) -> Result<TypeDefKind> {
1333 match ty {
1334 ComponentDefinedType::Primitive(t) => Ok(TypeDefKind::Type(self.convert_primitive(*t))),
1335
1336 ComponentDefinedType::List { element, .. } => {
1337 let t = self.convert_valtype(element)?;
1338 Ok(TypeDefKind::List(t))
1339 }
1340
1341 ComponentDefinedType::Map { key, value, .. } => {
1342 let k = self.convert_valtype(key)?;
1343 let v = self.convert_valtype(value)?;
1344 Ok(TypeDefKind::Map(k, v))
1345 }
1346
1347 ComponentDefinedType::FixedLengthList {
1348 element, length, ..
1349 } => {
1350 let t = self.convert_valtype(element)?;
1351 Ok(TypeDefKind::FixedLengthList(t, *length))
1352 }
1353
1354 ComponentDefinedType::Tuple(t) => {
1355 let types = t
1356 .types
1357 .iter()
1358 .map(|t| self.convert_valtype(t))
1359 .collect::<Result<_>>()?;
1360 Ok(TypeDefKind::Tuple(Tuple { types }))
1361 }
1362
1363 ComponentDefinedType::Option { ty, .. } => {
1364 let t = self.convert_valtype(ty)?;
1365 Ok(TypeDefKind::Option(t))
1366 }
1367
1368 ComponentDefinedType::Result { ok, err, .. } => {
1369 let ok = match ok {
1370 Some(t) => Some(self.convert_valtype(t)?),
1371 None => None,
1372 };
1373 let err = match err {
1374 Some(t) => Some(self.convert_valtype(t)?),
1375 None => None,
1376 };
1377 Ok(TypeDefKind::Result(Result_ { ok, err }))
1378 }
1379
1380 ComponentDefinedType::Record(r) => {
1381 let fields = r
1382 .fields
1383 .iter()
1384 .map(|(name, ty)| {
1385 Ok(Field {
1386 name: name.to_string(),
1387 ty: self.convert_valtype(ty).with_context(|| {
1388 format!("failed to convert record field '{name}'")
1389 })?,
1390 docs: Default::default(),
1391 span: Default::default(),
1392 })
1393 })
1394 .collect::<Result<_>>()?;
1395 Ok(TypeDefKind::Record(Record { fields }))
1396 }
1397
1398 ComponentDefinedType::Variant(v) => {
1399 let cases = v
1400 .cases
1401 .iter()
1402 .map(|(name, case)| {
1403 Ok(Case {
1404 name: name.to_string(),
1405 ty: match &case.ty {
1406 Some(ty) => Some(self.convert_valtype(ty)?),
1407 None => None,
1408 },
1409 docs: Default::default(),
1410 span: Default::default(),
1411 })
1412 })
1413 .collect::<Result<_>>()?;
1414 Ok(TypeDefKind::Variant(Variant { cases }))
1415 }
1416
1417 ComponentDefinedType::Flags(f) => {
1418 let flags = f
1419 .iter()
1420 .map(|name| Flag {
1421 name: name.to_string(),
1422 docs: Default::default(),
1423 span: Default::default(),
1424 })
1425 .collect();
1426 Ok(TypeDefKind::Flags(Flags { flags }))
1427 }
1428
1429 ComponentDefinedType::Enum(e) => {
1430 let cases = e
1431 .iter()
1432 .cloned()
1433 .map(|name| EnumCase {
1434 name: name.into(),
1435 docs: Default::default(),
1436 span: Default::default(),
1437 })
1438 .collect();
1439 Ok(TypeDefKind::Enum(Enum { cases }))
1440 }
1441
1442 ComponentDefinedType::Own(id) => {
1443 let key: ComponentAnyTypeId = (*id).into();
1444 let id = self.type_map[&key];
1445 Ok(TypeDefKind::Handle(Handle::Own(id)))
1446 }
1447
1448 ComponentDefinedType::Borrow(id) => {
1449 let key: ComponentAnyTypeId = (*id).into();
1450 let id = self.type_map[&key];
1451 Ok(TypeDefKind::Handle(Handle::Borrow(id)))
1452 }
1453
1454 ComponentDefinedType::Future { ty, .. } => Ok(TypeDefKind::Future(
1455 ty.as_ref().map(|ty| self.convert_valtype(ty)).transpose()?,
1456 )),
1457
1458 ComponentDefinedType::Stream { ty, .. } => Ok(TypeDefKind::Stream(
1459 ty.as_ref().map(|ty| self.convert_valtype(ty)).transpose()?,
1460 )),
1461 }
1462 }
1463
1464 fn convert_primitive(&self, ty: PrimitiveValType) -> Type {
1465 match ty {
1466 PrimitiveValType::U8 => Type::U8,
1467 PrimitiveValType::S8 => Type::S8,
1468 PrimitiveValType::U16 => Type::U16,
1469 PrimitiveValType::S16 => Type::S16,
1470 PrimitiveValType::U32 => Type::U32,
1471 PrimitiveValType::S32 => Type::S32,
1472 PrimitiveValType::U64 => Type::U64,
1473 PrimitiveValType::S64 => Type::S64,
1474 PrimitiveValType::Bool => Type::Bool,
1475 PrimitiveValType::Char => Type::Char,
1476 PrimitiveValType::String => Type::String,
1477 PrimitiveValType::F32 => Type::F32,
1478 PrimitiveValType::F64 => Type::F64,
1479 PrimitiveValType::ErrorContext => Type::ErrorContext,
1480 }
1481 }
1482
1483 fn register_defined(&mut self, id: TypeId, def: &ComponentDefinedType) -> Result<()> {
1484 Registrar {
1485 types: &self.types,
1486 type_map: &mut self.type_map,
1487 resolve: &self.resolve,
1488 }
1489 .defined(id, def)
1490 }
1491
1492 fn finish(mut self, package: Package) -> (Resolve, PackageId) {
1497 let mut order = IndexSet::default();
1500 for i in 0..self.foreign_packages.len() {
1501 self.visit_package(i, &mut order);
1502 }
1503
1504 let mut idx_to_pos = vec![0; self.foreign_packages.len()];
1507 for (pos, idx) in order.iter().enumerate() {
1508 idx_to_pos[*idx] = pos;
1509 }
1510 let mut deps = mem::take(&mut self.foreign_packages)
1513 .into_iter()
1514 .enumerate()
1515 .collect::<Vec<_>>();
1516 deps.sort_by_key(|(idx, _)| idx_to_pos[*idx]);
1517
1518 for (_idx, (_url, pkg)) in deps {
1521 self.insert_package(pkg);
1522 }
1523
1524 let id = self.insert_package(package);
1525 assert!(self.resolve.worlds.iter().all(|(_, w)| w.package.is_some()));
1526 assert!(
1527 self.resolve
1528 .interfaces
1529 .iter()
1530 .all(|(_, i)| i.package.is_some())
1531 );
1532 (self.resolve, id)
1533 }
1534
1535 fn insert_package(&mut self, package: Package) -> PackageId {
1536 let Package {
1537 name,
1538 interfaces,
1539 worlds,
1540 docs,
1541 } = package;
1542
1543 let pkg = self
1549 .resolve
1550 .package_names
1551 .get(&name)
1552 .copied()
1553 .unwrap_or_else(|| {
1554 let id = self.resolve.packages.alloc(Package {
1555 name: name.clone(),
1556 interfaces: Default::default(),
1557 worlds: Default::default(),
1558 docs,
1559 });
1560 let prev = self.resolve.package_names.insert(name, id);
1561 assert!(prev.is_none());
1562 id
1563 });
1564
1565 for (name, id) in interfaces {
1566 let prev = self.resolve.packages[pkg].interfaces.insert(name, id);
1567 assert!(prev.is_none());
1568 self.resolve.interfaces[id].package = Some(pkg);
1569 }
1570
1571 for (name, id) in worlds {
1572 let prev = self.resolve.packages[pkg].worlds.insert(name, id);
1573 assert!(prev.is_none());
1574 let world = &mut self.resolve.worlds[id];
1575 world.package = Some(pkg);
1576 for (name, item) in world.imports.iter().chain(world.exports.iter()) {
1577 if let WorldKey::Name(_) = name {
1578 if let WorldItem::Interface { id, .. } = item {
1579 let iface = &mut self.resolve.interfaces[*id];
1580 if iface.name.is_none() {
1581 iface.package = Some(pkg);
1582 }
1583 }
1584 }
1585 }
1586 }
1587
1588 pkg
1589 }
1590
1591 fn visit_package(&self, idx: usize, order: &mut IndexSet<usize>) {
1592 if order.contains(&idx) {
1593 return;
1594 }
1595
1596 let (_name, pkg) = self.foreign_packages.get_index(idx).unwrap();
1597 let interfaces = pkg.interfaces.values().copied().chain(
1598 pkg.worlds
1599 .values()
1600 .flat_map(|w| {
1601 let world = &self.resolve.worlds[*w];
1602 world.imports.values().chain(world.exports.values())
1603 })
1604 .filter_map(|item| match item {
1605 WorldItem::Interface { id, .. } => Some(*id),
1606 WorldItem::Function(_) | WorldItem::Type { .. } => None,
1607 }),
1608 );
1609 for iface in interfaces {
1610 for dep in self.resolve.interface_direct_deps(iface) {
1611 let dep_idx = self.iface_to_package_index[&dep];
1612 if dep_idx != idx {
1613 self.visit_package(dep_idx, order);
1614 }
1615 }
1616 }
1617
1618 assert!(order.insert(idx));
1619 }
1620}
1621
1622struct Registrar<'a> {
1625 types: &'a Types,
1626 type_map: &'a mut HashMap<ComponentAnyTypeId, TypeId>,
1627 resolve: &'a Resolve,
1628}
1629
1630impl Registrar<'_> {
1631 fn defined(&mut self, id: TypeId, def: &ComponentDefinedType) -> Result<()> {
1634 match def {
1635 ComponentDefinedType::Primitive(_) => Ok(()),
1636
1637 ComponentDefinedType::List { element, .. } => {
1638 let ty = match &self.resolve.types[id].kind {
1639 TypeDefKind::List(r) => r,
1640 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1648 _ => bail!("expected a list"),
1649 };
1650 self.valtype(element, ty)
1651 }
1652
1653 ComponentDefinedType::Map { key, value, .. } => {
1654 let (key_ty, value_ty) = match &self.resolve.types[id].kind {
1655 TypeDefKind::Map(k, v) => (k, v),
1656 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1657 _ => bail!("expected a map"),
1658 };
1659 self.valtype(key, key_ty)?;
1660 self.valtype(value, value_ty)
1661 }
1662
1663 ComponentDefinedType::FixedLengthList {
1664 element, length, ..
1665 } => {
1666 let ty = match &self.resolve.types[id].kind {
1667 TypeDefKind::FixedLengthList(r, elements2) if elements2 == length => r,
1668 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1669 _ => bail!("expected a fixed-length {length} list"),
1670 };
1671 self.valtype(element, ty)
1672 }
1673
1674 ComponentDefinedType::Tuple(t) => {
1675 let ty = match &self.resolve.types[id].kind {
1676 TypeDefKind::Tuple(r) => r,
1677 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1678 _ => bail!("expected a tuple"),
1679 };
1680 if ty.types.len() != t.types.len() {
1681 bail!("mismatched number of tuple fields");
1682 }
1683 for (a, b) in t.types.iter().zip(ty.types.iter()) {
1684 self.valtype(a, b)?;
1685 }
1686 Ok(())
1687 }
1688
1689 ComponentDefinedType::Option { ty: t, .. } => {
1690 let ty = match &self.resolve.types[id].kind {
1691 TypeDefKind::Option(r) => r,
1692 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1693 _ => bail!("expected an option"),
1694 };
1695 self.valtype(t, ty)
1696 }
1697
1698 ComponentDefinedType::Result { ok, err, .. } => {
1699 let ty = match &self.resolve.types[id].kind {
1700 TypeDefKind::Result(r) => r,
1701 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1702 _ => bail!("expected a result"),
1703 };
1704 match (ok, &ty.ok) {
1705 (Some(a), Some(b)) => self.valtype(a, b)?,
1706 (None, None) => {}
1707 _ => bail!("disagreement on result structure"),
1708 }
1709 match (err, &ty.err) {
1710 (Some(a), Some(b)) => self.valtype(a, b)?,
1711 (None, None) => {}
1712 _ => bail!("disagreement on result structure"),
1713 }
1714 Ok(())
1715 }
1716
1717 ComponentDefinedType::Record(def) => {
1718 let ty = match &self.resolve.types[id].kind {
1719 TypeDefKind::Record(r) => r,
1720 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1721 _ => bail!("expected a record"),
1722 };
1723 if def.fields.len() != ty.fields.len() {
1724 bail!("mismatched number of record fields");
1725 }
1726 for ((name, ty), field) in def.fields.iter().zip(&ty.fields) {
1727 if name.as_str() != field.name {
1728 bail!("mismatched field order");
1729 }
1730 self.valtype(ty, &field.ty)?;
1731 }
1732 Ok(())
1733 }
1734
1735 ComponentDefinedType::Variant(def) => {
1736 let ty = match &self.resolve.types[id].kind {
1737 TypeDefKind::Variant(r) => r,
1738 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1739 _ => bail!("expected a variant"),
1740 };
1741 if def.cases.len() != ty.cases.len() {
1742 bail!("mismatched number of variant cases");
1743 }
1744 for ((name, ty), case) in def.cases.iter().zip(&ty.cases) {
1745 if name.as_str() != case.name {
1746 bail!("mismatched case order");
1747 }
1748 match (&ty.ty, &case.ty) {
1749 (Some(a), Some(b)) => self.valtype(a, b)?,
1750 (None, None) => {}
1751 _ => bail!("disagreement on case type"),
1752 }
1753 }
1754 Ok(())
1755 }
1756
1757 ComponentDefinedType::Future { ty: payload, .. } => {
1758 let ty = match &self.resolve.types[id].kind {
1759 TypeDefKind::Future(p) => p,
1760 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1761 _ => bail!("expected a future"),
1762 };
1763 match (payload, ty) {
1764 (Some(a), Some(b)) => self.valtype(a, b),
1765 (None, None) => Ok(()),
1766 _ => bail!("disagreement on future payload"),
1767 }
1768 }
1769
1770 ComponentDefinedType::Stream { ty: payload, .. } => {
1771 let ty = match &self.resolve.types[id].kind {
1772 TypeDefKind::Stream(p) => p,
1773 TypeDefKind::Type(Type::Id(_)) => return Ok(()),
1774 _ => bail!("expected a stream"),
1775 };
1776 match (payload, ty) {
1777 (Some(a), Some(b)) => self.valtype(a, b),
1778 (None, None) => Ok(()),
1779 _ => bail!("disagreement on stream payload"),
1780 }
1781 }
1782
1783 ComponentDefinedType::Flags(_)
1785 | ComponentDefinedType::Enum(_)
1786 | ComponentDefinedType::Own(_)
1787 | ComponentDefinedType::Borrow(_) => Ok(()),
1788 }
1789 }
1790
1791 fn valtype(&mut self, wasm: &ComponentValType, wit: &Type) -> Result<()> {
1792 let wasm = match wasm {
1793 ComponentValType::Type(wasm) => *wasm,
1794 ComponentValType::Primitive(_wasm) => {
1795 assert!(!matches!(wit, Type::Id(_)));
1796 return Ok(());
1797 }
1798 };
1799 let wit = match wit {
1800 Type::Id(id) => *id,
1801 _ => bail!("expected id-based type"),
1802 };
1803 let prev = match self.type_map.insert(wasm.into(), wit) {
1804 Some(prev) => prev,
1805 None => {
1806 let wasm = &self.types[wasm];
1807 return self.defined(wit, wasm);
1808 }
1809 };
1810 let _ = prev;
1893 Ok(())
1894 }
1895}
1896
1897pub(crate) trait InterfaceNameExt {
1898 fn to_package_name(&self, item: &ComponentItem) -> Result<PackageName>;
1899}
1900
1901impl InterfaceNameExt for wasmparser::names::InterfaceName<'_> {
1902 fn to_package_name(&self, item: &ComponentItem) -> Result<PackageName> {
1903 Ok(PackageName {
1904 namespace: self.namespace().to_string(),
1905 name: self.package().to_string(),
1906 version: self.version(item.version_suffix.as_deref())?,
1907 })
1908 }
1909}