1use crate::{
2 CoreExtern, CoreFuncType, DefinedType, Enum, Flags, FuncType, FuncTypeId, Interface,
3 InterfaceId, ItemKind, ModuleType, ModuleTypeId, Record, Resource, ResourceAlias, ResourceId,
4 Type, Types, UsedType, ValueType, Variant, World, WorldId,
5};
6use anyhow::{bail, Context, Result};
7use indexmap::IndexMap;
8use semver::Version;
9use std::borrow::Borrow;
10use std::fmt;
11use std::{collections::HashMap, path::Path, rc::Rc};
12use wasmparser::{
13 component_types::{self as wasm},
14 names::{ComponentName, ComponentNameKind},
15 Chunk, Encoding, Parser, Payload, ValidPayload, Validator, WasmFeatures,
16};
17
18#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
20pub struct PackageKey {
21 name: String,
23 version: Option<Version>,
25}
26
27impl PackageKey {
28 pub fn new(package: &Package) -> Self {
30 Self {
31 name: package.name.clone(),
32 version: package.version.clone(),
33 }
34 }
35
36 pub fn name(&self) -> &str {
38 &self.name
39 }
40
41 pub fn version(&self) -> Option<&Version> {
43 self.version.as_ref()
44 }
45}
46
47impl fmt::Display for PackageKey {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 write!(f, "{name}", name = self.name)?;
50 if let Some(version) = &self.version {
51 write!(f, "@{version}")?;
52 }
53
54 Ok(())
55 }
56}
57
58#[derive(Copy, Clone, Hash, PartialEq, Eq)]
60pub struct BorrowedPackageKey<'a> {
61 pub name: &'a str,
63 pub version: Option<&'a Version>,
65}
66
67impl<'a> BorrowedPackageKey<'a> {
68 pub fn new(package: &'a Package) -> Self {
70 Self {
71 name: &package.name,
72 version: package.version.as_ref(),
73 }
74 }
75
76 pub fn from_name_and_version(name: &'a str, version: Option<&'a Version>) -> Self {
78 Self { name, version }
79 }
80
81 pub fn into_owned(self) -> PackageKey {
83 PackageKey {
84 name: self.name.to_owned(),
85 version: self.version.cloned(),
86 }
87 }
88}
89
90impl fmt::Display for BorrowedPackageKey<'_> {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 write!(f, "{name}", name = self.name)?;
93 if let Some(version) = self.version {
94 write!(f, "@{version}")?;
95 }
96
97 Ok(())
98 }
99}
100
101pub trait BorrowedKey {
103 fn borrowed_key(&self) -> BorrowedPackageKey<'_>;
105}
106
107impl BorrowedKey for PackageKey {
108 fn borrowed_key(&self) -> BorrowedPackageKey<'_> {
109 BorrowedPackageKey {
110 name: &self.name,
111 version: self.version.as_ref(),
112 }
113 }
114}
115
116impl BorrowedKey for BorrowedPackageKey<'_> {
117 fn borrowed_key(&self) -> BorrowedPackageKey<'_> {
118 *self
119 }
120}
121
122impl<'a> Borrow<dyn BorrowedKey + 'a> for PackageKey {
123 fn borrow(&self) -> &(dyn BorrowedKey + 'a) {
124 self
125 }
126}
127
128impl Eq for dyn BorrowedKey + '_ {}
129
130impl PartialEq for dyn BorrowedKey + '_ {
131 fn eq(&self, other: &dyn BorrowedKey) -> bool {
132 self.borrowed_key().eq(&other.borrowed_key())
133 }
134}
135
136impl std::hash::Hash for dyn BorrowedKey + '_ {
137 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
138 self.borrowed_key().hash(state)
139 }
140}
141
142#[derive(Clone)]
146#[cfg_attr(feature = "serde", derive(serde::Serialize))]
147#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
148pub struct Package {
149 name: String,
151 version: Option<Version>,
153 #[cfg_attr(feature = "serde", serde(skip))]
157 bytes: Vec<u8>,
158 ty: WorldId,
160 instance_type: InterfaceId,
162 definitions: IndexMap<String, ItemKind>,
164}
165
166impl Package {
167 pub fn key(&self) -> BorrowedPackageKey<'_> {
169 BorrowedPackageKey::new(self)
170 }
171
172 pub fn from_file(
176 name: &str,
177 version: Option<&Version>,
178 path: impl AsRef<Path>,
179 types: &mut Types,
180 ) -> Result<Self> {
181 let path = path.as_ref();
182 let bytes = std::fs::read(path)
183 .with_context(|| format!("failed to read `{path}`", path = path.display()))?;
184 Self::from_bytes(name, version, bytes, types)
185 }
186
187 pub fn from_bytes(
191 name: &str,
192 version: Option<&Version>,
193 bytes: impl Into<Vec<u8>>,
194 types: &mut Types,
195 ) -> Result<Self> {
196 let bytes = bytes.into();
197 if !Parser::is_component(&bytes) {
198 bail!("package `{name}` is not a binary-encoded WebAssembly component");
199 }
200
201 let mut parser = Parser::new(0);
202 let mut parsers = Vec::new();
203 let mut validator = Validator::new_with_features(WasmFeatures::all());
204 let mut imports = Vec::new();
205 let mut exports = Vec::new();
206
207 let mut cur = bytes.as_ref();
208 loop {
209 match parser.parse(cur, true)? {
210 Chunk::Parsed { payload, consumed } => {
211 cur = &cur[consumed..];
212
213 match validator.payload(&payload)? {
214 ValidPayload::Ok => {
215 if !parsers.is_empty() {
217 continue;
218 }
219
220 match payload {
221 Payload::Version { encoding, .. } => {
222 assert_eq!(encoding, Encoding::Component);
223 }
224 Payload::ComponentImportSection(s) => {
225 imports.reserve(s.count() as usize);
226 for import in s {
227 imports.push(import?.name.0);
228 }
229 }
230 Payload::ComponentExportSection(s) => {
231 exports.reserve(s.count() as usize);
232 for export in s {
233 exports.push(export?.name.0);
234 }
235 }
236 _ => {}
237 }
238 }
239 ValidPayload::Func(_, _) => {}
240 ValidPayload::Parser(next) => {
241 parsers.push(parser);
242 parser = next;
243 }
244 ValidPayload::End(wasm_types) => match parsers.pop() {
245 Some(parent) => parser = parent,
246 None => {
247 let mut converter = TypeConverter::new(types, wasm_types);
248
249 let imports = imports
250 .into_iter()
251 .map(|i| Ok((i.to_string(), converter.import(i)?)))
252 .collect::<Result<_>>()?;
253
254 let exports: IndexMap<String, ItemKind> = exports
255 .into_iter()
256 .map(|i| Ok((i.to_string(), converter.export(i)?)))
257 .collect::<Result<_>>()?;
258
259 let ty = types.add_world(World {
260 id: None,
261 uses: Default::default(),
262 imports,
263 exports: exports.clone(),
264 });
265
266 let instance_type = types.add_interface(Interface {
267 id: None,
268 uses: Default::default(),
269 exports,
270 });
271
272 let definitions = Self::find_definitions(types, ty);
273
274 return Ok(Self {
275 name: name.to_owned(),
276 version: version.map(ToOwned::to_owned),
277 bytes,
278 ty,
279 instance_type,
280 definitions,
281 });
282 }
283 },
284 }
285 }
286 Chunk::NeedMoreData(_) => panic!("all data should be present"),
287 }
288 }
289 }
290
291 pub fn name(&self) -> &str {
293 &self.name
294 }
295
296 pub fn version(&self) -> Option<&Version> {
298 self.version.as_ref()
299 }
300
301 pub fn bytes(&self) -> &[u8] {
305 &self.bytes
306 }
307
308 pub fn ty(&self) -> WorldId {
310 self.ty
311 }
312
313 pub fn instance_type(&self) -> InterfaceId {
316 self.instance_type
317 }
318
319 pub fn definitions(&self) -> &IndexMap<String, ItemKind> {
321 &self.definitions
322 }
323
324 fn find_definitions(types: &Types, world: WorldId) -> IndexMap<String, ItemKind> {
325 let exports = &types[world].exports;
327 let mut defs = IndexMap::new();
328 for (name, kind) in exports {
329 if let ItemKind::Type(Type::World(id)) = kind {
330 let world = &types[*id];
331 if world.exports.len() != 1 {
332 continue;
333 }
334
335 let (export_name, kind) = world.exports.get_index(0).unwrap();
337 match ComponentName::new(export_name, 0).unwrap().kind() {
338 ComponentNameKind::Interface(_) => {}
339 _ => continue,
340 }
341
342 match kind {
343 ItemKind::Instance(id) => {
344 defs.insert(name.clone(), ItemKind::Type(Type::Interface(*id)));
345 }
346 ItemKind::Component(id) => {
347 defs.insert(name.clone(), ItemKind::Type(Type::World(*id)));
348 }
349 _ => continue,
350 }
351 }
352 }
353
354 defs
355 }
356}
357
358impl fmt::Debug for Package {
359 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
360 f.debug_struct("Package")
361 .field("name", &self.name)
362 .field("version", &self.version)
363 .field("bytes", &"...")
364 .field("ty", &self.ty)
365 .field("instance_type", &self.instance_type)
366 .field("definitions", &self.definitions)
367 .finish()
368 }
369}
370
371#[derive(Debug, Clone, Copy, PartialEq, Eq)]
372enum Owner {
373 Interface(InterfaceId),
375 World(WorldId),
377}
378
379#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
380enum Entity {
381 Type(Type),
383 Resource(ResourceId),
385}
386
387struct TypeConverter<'a> {
390 types: &'a mut Types,
391 wasm_types: Rc<wasmparser::types::Types>,
392 cache: HashMap<wasm::AnyTypeId, Entity>,
393 resource_map: HashMap<wasm::ResourceId, ResourceId>,
394 owners: HashMap<wasm::ComponentAnyTypeId, (Owner, String)>,
395}
396
397impl<'a> TypeConverter<'a> {
398 fn new(types: &'a mut Types, wasm_types: wasmparser::types::Types) -> Self {
399 Self {
400 types,
401 wasm_types: Rc::new(wasm_types),
402 cache: Default::default(),
403 resource_map: Default::default(),
404 owners: Default::default(),
405 }
406 }
407
408 fn import(&mut self, name: &str) -> Result<ItemKind> {
409 let import = self
410 .wasm_types
411 .component_entity_type_of_import(name)
412 .unwrap();
413 self.entity(name, import)
414 }
415
416 fn export(&mut self, name: &str) -> Result<ItemKind> {
417 let export = self
418 .wasm_types
419 .component_entity_type_of_export(name)
420 .unwrap();
421 self.entity(name, export)
422 }
423
424 fn component_func_type(&mut self, id: wasm::ComponentFuncTypeId) -> Result<FuncTypeId> {
425 let key = wasm::AnyTypeId::Component(wasm::ComponentAnyTypeId::Func(id));
426 if let Some(ty) = self.cache.get(&key) {
427 match ty {
428 Entity::Type(Type::Func(id)) => return Ok(*id),
429 _ => panic!("invalid cached type"),
430 }
431 }
432
433 let wasm_types = self.wasm_types.clone();
434 let func_ty = &wasm_types[id];
435 let params = func_ty
436 .params
437 .iter()
438 .map(|(name, ty)| Ok((name.to_string(), self.component_val_type(*ty)?)))
439 .collect::<Result<_>>()?;
440
441 let result = match func_ty.result {
442 Some(ty) => Some(self.component_val_type(ty)?),
443 None => None,
444 };
445
446 let id = self.types.add_func_type(FuncType {
447 params,
448 result,
449 is_async: func_ty.async_,
450 });
451 self.cache.insert(key, Entity::Type(Type::Func(id)));
452 Ok(id)
453 }
454
455 fn module_type(&mut self, id: wasm::ComponentCoreModuleTypeId) -> Result<ModuleTypeId> {
456 let key = wasm::AnyTypeId::Core(wasm::ComponentCoreTypeId::Module(id));
457 if let Some(ty) = self.cache.get(&key) {
458 match ty {
459 Entity::Type(Type::Module(id)) => return Ok(*id),
460 _ => panic!("invalid cached type"),
461 }
462 }
463
464 let module_ty = &self.wasm_types[id];
465
466 let imports = module_ty
467 .imports
468 .iter()
469 .map(|((module, name), ty)| {
470 Ok(((module.clone(), name.clone()), self.entity_type(*ty)?))
471 })
472 .collect::<Result<_>>()?;
473
474 let exports = module_ty
475 .exports
476 .iter()
477 .map(|(name, ty)| Ok((name.clone(), self.entity_type(*ty)?)))
478 .collect::<Result<_>>()?;
479
480 let module_id = self.types.add_module_type(ModuleType { imports, exports });
481 self.cache
482 .insert(key, Entity::Type(Type::Module(module_id)));
483 Ok(module_id)
484 }
485
486 fn ty(&mut self, name: &str, id: wasm::ComponentAnyTypeId) -> Result<Type> {
487 match id {
488 wasm::ComponentAnyTypeId::Defined(id) => {
489 Ok(Type::Value(self.component_defined_type(id)?))
490 }
491 wasm::ComponentAnyTypeId::Func(id) => Ok(Type::Func(self.component_func_type(id)?)),
492 wasm::ComponentAnyTypeId::Component(id) => {
493 Ok(Type::World(self.component_type(None, id)?))
494 }
495 wasm::ComponentAnyTypeId::Instance(id) => {
496 Ok(Type::Interface(self.component_instance_type(None, id)?))
497 }
498 wasm::ComponentAnyTypeId::Resource(id) => Ok(Type::Resource(self.resource(name, id))),
499 }
500 }
501
502 fn component_val_type(&mut self, ty: wasm::ComponentValType) -> Result<ValueType> {
503 match ty {
504 wasm::ComponentValType::Primitive(ty) => Ok(ValueType::Primitive(ty.into())),
505 wasm::ComponentValType::Type(id) => Ok(self.component_defined_type(id)?),
506 }
507 }
508
509 fn component_instance_type(
510 &mut self,
511 name: Option<&str>,
512 id: wasm::ComponentInstanceTypeId,
513 ) -> Result<InterfaceId> {
514 let key = wasm::AnyTypeId::Component(wasm::ComponentAnyTypeId::Instance(id));
515 if let Some(ty) = self.cache.get(&key) {
516 match ty {
517 Entity::Type(Type::Interface(id)) => {
518 return Ok(*id);
519 }
520 _ => panic!("invalid cached type"),
521 }
522 }
523
524 let wasm_types = self.wasm_types.clone();
525 let instance_ty = &wasm_types[id];
526 let id = self.types.add_interface(Interface {
527 id: name.and_then(|n| n.contains(':').then(|| n.to_owned())),
528 uses: Default::default(),
529 exports: IndexMap::with_capacity(instance_ty.exports.len()),
530 });
531
532 for (name, ty) in &instance_ty.exports {
533 let export = self.entity(name, *ty)?;
534
535 if let wasm::ComponentEntityType::Type {
536 referenced,
537 created,
538 } = ty
539 {
540 self.use_or_own(Owner::Interface(id), name, *referenced, *created);
541
542 if let ItemKind::Type(Type::Resource(res)) = export {
544 if let Some(ResourceAlias { owner, .. }) = &mut self.types[res].alias {
545 if let Some(owner_id) = owner {
546 if *owner_id == id {
547 *owner = None;
548 }
549 }
550 }
551 }
552 }
553
554 let prev = self.types[id].exports.insert(name.clone(), export);
555 assert!(prev.is_none());
556 }
557
558 self.cache.insert(key, Entity::Type(Type::Interface(id)));
559 Ok(id)
560 }
561
562 fn entity(&mut self, name: &str, ty: wasm::ComponentEntityType) -> Result<ItemKind> {
563 match ty {
564 wasm::ComponentEntityType::Module(id) => Ok(ItemKind::Module(self.module_type(id)?)),
565 wasm::ComponentEntityType::Value(ty) => {
566 Ok(ItemKind::Value(self.component_val_type(ty)?))
567 }
568 wasm::ComponentEntityType::Type { created, .. } => {
569 Ok(ItemKind::Type(self.ty(name, created)?))
570 }
571 wasm::ComponentEntityType::Func(id) => {
572 Ok(ItemKind::Func(self.component_func_type(id)?))
573 }
574 wasm::ComponentEntityType::Instance(id) => Ok(ItemKind::Instance(
575 self.component_instance_type(Some(name), id)?,
576 )),
577 wasm::ComponentEntityType::Component(id) => {
578 Ok(ItemKind::Component(self.component_type(Some(name), id)?))
579 }
580 }
581 }
582
583 fn use_or_own(
584 &mut self,
585 owner: Owner,
586 name: &str,
587 referenced: wasm::ComponentAnyTypeId,
588 created: wasm::ComponentAnyTypeId,
589 ) {
590 if let Some((other, orig)) = self.find_owner(referenced) {
591 match *other {
592 Owner::Interface(interface) if owner != *other => {
593 let used = UsedType {
594 interface,
595 name: if name != orig {
596 Some(orig.to_string())
597 } else {
598 None
599 },
600 };
601
602 let uses = match owner {
604 Owner::Interface(id) => &mut self.types[id].uses,
605 Owner::World(id) => &mut self.types[id].uses,
606 };
607
608 uses.insert(name.to_string(), used);
609 }
610 _ => {}
611 }
612 return;
613 }
614
615 let prev = self.owners.insert(created, (owner, name.to_string()));
617 assert!(prev.is_none());
618 }
619
620 fn component_type(&mut self, name: Option<&str>, id: wasm::ComponentTypeId) -> Result<WorldId> {
621 let key = wasm::AnyTypeId::Component(wasm::ComponentAnyTypeId::Component(id));
622 if let Some(ty) = self.cache.get(&key) {
623 match ty {
624 Entity::Type(Type::World(id)) => return Ok(*id),
625 _ => panic!("invalid cached type"),
626 }
627 }
628
629 let wasm_types = self.wasm_types.clone();
630 let component_ty = &wasm_types[id];
631 let id = self.types.add_world(World {
632 id: name.and_then(|n| n.contains(':').then(|| n.to_owned())),
633 uses: Default::default(),
634 imports: IndexMap::with_capacity(component_ty.imports.len()),
635 exports: IndexMap::with_capacity(component_ty.exports.len()),
636 });
637
638 for (name, ty) in &component_ty.imports {
639 let import = self.entity(name, *ty)?;
640
641 if let wasm::ComponentEntityType::Type {
642 referenced,
643 created,
644 } = ty
645 {
646 self.use_or_own(Owner::World(id), name, *referenced, *created);
647 }
648
649 let prev = self.types[id].imports.insert(name.clone(), import);
650 assert!(prev.is_none());
651 }
652
653 for (name, ty) in &component_ty.exports {
654 let ty = self.entity(name, *ty)?;
655 let prev = self.types[id].exports.insert(name.clone(), ty);
656 assert!(prev.is_none());
657 }
658
659 self.cache.insert(key, Entity::Type(Type::World(id)));
660 Ok(id)
661 }
662
663 fn component_defined_type(&mut self, id: wasm::ComponentDefinedTypeId) -> Result<ValueType> {
664 let key = wasm::AnyTypeId::Component(wasm::ComponentAnyTypeId::Defined(id));
665 if let Some(ty) = self.cache.get(&key) {
666 match ty {
667 Entity::Type(Type::Value(ty)) => return Ok(*ty),
668 _ => panic!("invalid cached type"),
669 }
670 }
671
672 let wasm_types = self.wasm_types.clone();
673 let ty = match &wasm_types[id] {
674 wasm::ComponentDefinedType::Primitive(ty) => ValueType::Defined(
675 self.types
676 .add_defined_type(DefinedType::Alias(ValueType::Primitive((*ty).into()))),
677 ),
678 wasm::ComponentDefinedType::Record(ty) => {
679 let fields = ty
680 .fields
681 .iter()
682 .map(|(name, ty)| Ok((name.as_str().to_owned(), self.component_val_type(*ty)?)))
683 .collect::<Result<_>>()?;
684
685 ValueType::Defined(
686 self.types
687 .add_defined_type(DefinedType::Record(Record { fields })),
688 )
689 }
690 wasm::ComponentDefinedType::Variant(ty) => {
691 let cases = ty
692 .cases
693 .iter()
694 .map(|(name, case)| {
695 Ok((
696 name.as_str().to_owned(),
697 case.ty.map(|ty| self.component_val_type(ty)).transpose()?,
698 ))
699 })
700 .collect::<Result<_>>()?;
701
702 ValueType::Defined(
703 self.types
704 .add_defined_type(DefinedType::Variant(Variant { cases })),
705 )
706 }
707 wasm::ComponentDefinedType::List(ty) => {
708 let ty = self.component_val_type(*ty)?;
709 ValueType::Defined(self.types.add_defined_type(DefinedType::List(ty)))
710 }
711 wasm::ComponentDefinedType::Tuple(ty) => {
712 let types = ty
713 .types
714 .iter()
715 .map(|ty| self.component_val_type(*ty))
716 .collect::<Result<_>>()?;
717 ValueType::Defined(self.types.add_defined_type(DefinedType::Tuple(types)))
718 }
719 wasm::ComponentDefinedType::Flags(flags) => {
720 let flags = flags.iter().map(|flag| flag.as_str().to_owned()).collect();
721 ValueType::Defined(
722 self.types
723 .add_defined_type(DefinedType::Flags(Flags(flags))),
724 )
725 }
726 wasm::ComponentDefinedType::Enum(cases) => {
727 let cases = cases.iter().map(|case| case.as_str().to_owned()).collect();
728 ValueType::Defined(self.types.add_defined_type(DefinedType::Enum(Enum(cases))))
729 }
730 wasm::ComponentDefinedType::Option(ty) => {
731 let ty = self.component_val_type(*ty)?;
732 ValueType::Defined(self.types.add_defined_type(DefinedType::Option(ty)))
733 }
734 wasm::ComponentDefinedType::Result { ok, err } => {
735 let ok = ok.map(|ty| self.component_val_type(ty)).transpose()?;
736 let err = err.map(|ty| self.component_val_type(ty)).transpose()?;
737 ValueType::Defined(self.types.add_defined_type(DefinedType::Result { ok, err }))
738 }
739 wasm::ComponentDefinedType::Borrow(id) => ValueType::Borrow(
740 match self.cache.get(&wasm::AnyTypeId::Component(
741 wasm::ComponentAnyTypeId::Resource(*id),
742 )) {
743 Some(Entity::Resource(id)) => *id,
744 _ => panic!("expected a resource"),
745 },
746 ),
747 wasm::ComponentDefinedType::Own(id) => ValueType::Own(
748 match self.cache.get(&wasm::AnyTypeId::Component(
749 wasm::ComponentAnyTypeId::Resource(*id),
750 )) {
751 Some(Entity::Resource(id)) => *id,
752 _ => panic!("expected a resource"),
753 },
754 ),
755 wasm::ComponentDefinedType::Stream(ty) => {
756 let stream = ty.map(|ty| self.component_val_type(ty)).transpose()?;
757 ValueType::Defined(self.types.add_defined_type(DefinedType::Stream(stream)))
758 }
759 wasm::ComponentDefinedType::Future(ty) => {
760 let option = ty.map(|ty| self.component_val_type(ty)).transpose()?;
761 ValueType::Defined(self.types.add_defined_type(DefinedType::Future(option)))
762 }
763 wasm::ComponentDefinedType::FixedLengthList(ty, size) => {
764 let ty = self.component_val_type(*ty)?;
765 ValueType::Defined(
766 self.types
767 .add_defined_type(DefinedType::FixedSizeList(ty, *size)),
768 )
769 }
770 wasmparser::component_types::ComponentDefinedType::Map(_, _) => {
771 bail!("ComponentDefinedType::Map is not yet supported");
772 }
773 };
774
775 self.cache.insert(key, Entity::Type(Type::Value(ty)));
776 Ok(ty)
777 }
778
779 fn resource(&mut self, name: &str, id: wasm::AliasableResourceId) -> ResourceId {
780 let key = wasm::AnyTypeId::Component(wasm::ComponentAnyTypeId::Resource(id));
781 if let Some(ty) = self.cache.get(&key) {
782 match ty {
783 Entity::Resource(id) => return *id,
784 _ => panic!("invalid cached type"),
785 }
786 }
787
788 if let Some(resource_id) = self.resource_map.get(&id.resource()) {
790 let alias_id = self.types.add_resource(Resource {
791 name: name.to_owned(),
792 alias: Some(ResourceAlias {
793 owner: match self.find_owner(wasm::ComponentAnyTypeId::Resource(id)) {
794 Some((Owner::Interface(id), _)) => Some(*id),
795 _ => None,
796 },
797 source: *resource_id,
798 }),
799 });
800 self.cache.insert(key, Entity::Resource(alias_id));
801 return alias_id;
802 }
803
804 let resource_id = self.types.add_resource(Resource {
806 name: name.to_owned(),
807 alias: None,
808 });
809
810 self.resource_map.insert(id.resource(), resource_id);
811 self.cache.insert(key, Entity::Resource(resource_id));
812 resource_id
813 }
814
815 fn entity_type(&self, ty: wasmparser::types::EntityType) -> Result<CoreExtern> {
816 Ok(match ty {
817 wasmparser::types::EntityType::Func(ty) => CoreExtern::Func(self.func_type(ty)?),
818 wasmparser::types::EntityType::Table(ty) => ty.try_into()?,
819 wasmparser::types::EntityType::Memory(ty) => ty.into(),
820 wasmparser::types::EntityType::Global(ty) => ty.try_into()?,
821 wasmparser::types::EntityType::Tag(ty) => CoreExtern::Tag(self.func_type(ty)?),
822 wasmparser::types::EntityType::FuncExact(_) => {
823 todo!("wasmparser::types::EntityType::FuncExact")
824 }
825 })
826 }
827
828 fn func_type(&self, ty: wasmparser::types::CoreTypeId) -> Result<CoreFuncType> {
829 let func_ty = self.wasm_types[ty].unwrap_func();
830 Ok(CoreFuncType {
831 params: func_ty
832 .params()
833 .iter()
834 .copied()
835 .map(TryInto::try_into)
836 .collect::<Result<_>>()?,
837 results: func_ty
838 .results()
839 .iter()
840 .copied()
841 .map(TryInto::try_into)
842 .collect::<Result<_>>()?,
843 })
844 }
845
846 fn find_owner(&self, mut id: wasm::ComponentAnyTypeId) -> Option<&(Owner, String)> {
847 let mut prev = None;
848 while prev.is_none() {
849 prev = self.owners.get(&id);
850 id = match self.wasm_types.peel_alias(id) {
851 Some(next) => next,
852 None => break,
853 };
854 }
855 prev
856 }
857}