1 use crate::rust::{to_rust_ident, to_rust_upper_camel_case, RustGenerator, TypeMode};
2 use crate::types::{TypeInfo, Types};
3 use anyhow::{bail, Context};
4 use heck::*;
5 use indexmap::{IndexMap, IndexSet};
6 use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
7 use std::fmt::Write as _;
8 use std::io::{Read, Write};
9 use std::mem;
10 use std::process::{Command, Stdio};
11 use wit_parser::*;
12 
13 macro_rules! uwrite {
14     ($dst:expr, $($arg:tt)*) => {
15         write!($dst, $($arg)*).unwrap()
16     };
17 }
18 
19 macro_rules! uwriteln {
20     ($dst:expr, $($arg:tt)*) => {
21         writeln!($dst, $($arg)*).unwrap()
22     };
23 }
24 
25 mod rust;
26 mod source;
27 mod types;
28 use source::Source;
29 
30 #[derive(Clone)]
31 enum InterfaceName {
32     /// This interface was remapped using `with` to some other Rust code.
33     Remapped {
34         name_at_root: String,
35         local_path: Vec<String>,
36     },
37     /// This interface is generated in the module hierarchy specified.
38     Path(Vec<String>),
39 }
40 
41 #[derive(Default)]
42 struct Wasmtime {
43     src: Source,
44     opts: Opts,
45     import_interfaces: Vec<(String, InterfaceName)>,
46     import_functions: Vec<ImportFunction>,
47     exports: Exports,
48     types: Types,
49     sizes: SizeAlign,
50     interface_names: HashMap<InterfaceId, InterfaceName>,
51     interface_last_seen_as_import: HashMap<InterfaceId, bool>,
52     trappable_errors: IndexMap<TypeId, String>,
53     // Track the with options that were used. Remapped interfaces provided via `with`
54     // are required to be used.
55     used_with_opts: HashSet<String>,
56 }
57 
58 struct ImportFunction {
59     add_to_linker: String,
60     sig: String,
61 }
62 
63 #[derive(Default)]
64 struct Exports {
65     fields: BTreeMap<String, (String, String)>,
66     modules: Vec<(String, InterfaceName)>,
67     funcs: Vec<String>,
68 }
69 
70 #[derive(Default, Debug, Clone, Copy)]
71 pub enum Ownership {
72     /// Generated types will be composed entirely of owning fields, regardless
73     /// of whether they are used as parameters to guest exports or not.
74     #[default]
75     Owning,
76 
77     /// Generated types used as parameters to guest exports will be "deeply
78     /// borrowing", i.e. contain references rather than owned values when
79     /// applicable.
80     Borrowing {
81         /// Whether or not to generate "duplicate" type definitions for a single
82         /// WIT type if necessary, for example if it's used as both an import
83         /// and an export, or if it's used both as a parameter to an export and
84         /// a return value from an export.
85         duplicate_if_necessary: bool,
86     },
87 }
88 
89 #[derive(Default, Debug, Clone)]
90 pub struct Opts {
91     /// Whether or not `rustfmt` is executed to format generated code.
92     pub rustfmt: bool,
93 
94     /// Whether or not to emit `tracing` macro calls on function entry/exit.
95     pub tracing: bool,
96 
97     /// Whether or not to use async rust functions and traits.
98     pub async_: AsyncConfig,
99 
100     /// A list of "trappable errors" which are used to replace the `E` in
101     /// `result<T, E>` found in WIT.
102     pub trappable_error_type: Vec<TrappableError>,
103 
104     /// Whether to generate owning or borrowing type definitions.
105     pub ownership: Ownership,
106 
107     /// Whether or not to generate code for only the interfaces of this wit file or not.
108     pub only_interfaces: bool,
109 
110     /// Configuration of which imports are allowed to generate a trap.
111     pub trappable_imports: TrappableImports,
112 
113     /// Remapping of interface names to rust module names.
114     /// TODO: is there a better type to use for the value of this map?
115     pub with: HashMap<String, String>,
116 
117     /// Additional derive attributes to add to generated types. If using in a CLI, this flag can be
118     /// specified multiple times to add multiple attributes.
119     ///
120     /// These derive attributes will be added to any generated structs or enums
121     pub additional_derive_attributes: Vec<String>,
122 
123     /// Evaluate to a string literal containing the generated code rather than the generated tokens
124     /// themselves. Mostly useful for Wasmtime internal debugging and development.
125     pub stringify: bool,
126 }
127 
128 #[derive(Debug, Clone)]
129 pub struct TrappableError {
130     /// Full path to the error, such as `wasi:io/streams/error`.
131     pub wit_path: String,
132 
133     /// The name, in Rust, of the error type to generate.
134     pub rust_type_name: String,
135 }
136 
137 #[derive(Default, Debug, Clone)]
138 pub enum AsyncConfig {
139     /// No functions are `async`.
140     #[default]
141     None,
142     /// All generated functions should be `async`.
143     All,
144     /// These imported functions should not be async, but everything else is.
145     AllExceptImports(HashSet<String>),
146     /// These functions are the only imports that are async, all other imports
147     /// are sync.
148     ///
149     /// Note that all exports are still async in this situation.
150     OnlyImports(HashSet<String>),
151 }
152 
153 impl AsyncConfig {
154     pub fn is_import_async(&self, f: &str) -> bool {
155         match self {
156             AsyncConfig::None => false,
157             AsyncConfig::All => true,
158             AsyncConfig::AllExceptImports(set) => !set.contains(f),
159             AsyncConfig::OnlyImports(set) => set.contains(f),
160         }
161     }
162 
163     pub fn maybe_async(&self) -> bool {
164         match self {
165             AsyncConfig::None => false,
166             AsyncConfig::All | AsyncConfig::AllExceptImports(_) | AsyncConfig::OnlyImports(_) => {
167                 true
168             }
169         }
170     }
171 }
172 
173 #[derive(Default, Debug, Clone)]
174 pub enum TrappableImports {
175     /// No imports are allowed to trap.
176     #[default]
177     None,
178     /// All imports may trap.
179     All,
180     /// Only the specified set of functions may trap.
181     Only(HashSet<String>),
182 }
183 
184 impl TrappableImports {
185     fn can_trap(&self, f: &Function) -> bool {
186         match self {
187             TrappableImports::None => false,
188             TrappableImports::All => true,
189             TrappableImports::Only(set) => set.contains(&f.name),
190         }
191     }
192 }
193 
194 impl Opts {
195     pub fn generate(&self, resolve: &Resolve, world: WorldId) -> anyhow::Result<String> {
196         let mut r = Wasmtime::default();
197         r.sizes.fill(resolve);
198         r.opts = self.clone();
199         r.generate(resolve, world)
200     }
201 }
202 
203 impl Wasmtime {
204     fn name_interface(
205         &mut self,
206         resolve: &Resolve,
207         id: InterfaceId,
208         name: &WorldKey,
209         is_export: bool,
210     ) -> bool {
211         let mut path = Vec::new();
212         if is_export {
213             path.push("exports".to_string());
214         }
215         match name {
216             WorldKey::Name(name) => {
217                 path.push(name.to_snake_case());
218             }
219             WorldKey::Interface(_) => {
220                 let iface = &resolve.interfaces[id];
221                 let pkgname = &resolve.packages[iface.package.unwrap()].name;
222                 path.push(pkgname.namespace.to_snake_case());
223                 path.push(self.name_package_module(resolve, iface.package.unwrap()));
224                 path.push(to_rust_ident(iface.name.as_ref().unwrap()));
225             }
226         }
227         let entry = if let Some(name_at_root) = self.lookup_replacement(resolve, name, None) {
228             InterfaceName::Remapped {
229                 name_at_root,
230                 local_path: path,
231             }
232         } else {
233             InterfaceName::Path(path)
234         };
235 
236         let remapped = matches!(entry, InterfaceName::Remapped { .. });
237         self.interface_names.insert(id, entry);
238         remapped
239     }
240 
241     /// If the package `id` is the only package with its namespace/name combo
242     /// then pass through the name unmodified. If, however, there are multiple
243     /// versions of this package then the package module is going to get version
244     /// information.
245     fn name_package_module(&self, resolve: &Resolve, id: PackageId) -> String {
246         let pkg = &resolve.packages[id];
247         let versions_with_same_name = resolve
248             .packages
249             .iter()
250             .filter_map(|(_, p)| {
251                 if p.name.namespace == pkg.name.namespace && p.name.name == pkg.name.name {
252                     Some(&p.name.version)
253                 } else {
254                     None
255                 }
256             })
257             .collect::<Vec<_>>();
258         let base = pkg.name.name.to_snake_case();
259         if versions_with_same_name.len() == 1 {
260             return base;
261         }
262 
263         let version = match &pkg.name.version {
264             Some(version) => version,
265             // If this package didn't have a version then don't mangle its name
266             // and other packages with the same name but with versions present
267             // will have their names mangled.
268             None => return base,
269         };
270 
271         // Here there's multiple packages with the same name that differ only in
272         // version, so the version needs to be mangled into the Rust module name
273         // that we're generating. This in theory could look at all of
274         // `versions_with_same_name` and produce a minimal diff, e.g. for 0.1.0
275         // and 0.2.0 this could generate "foo1" and "foo2", but for now
276         // a simpler path is chosen to generate "foo0_1_0" and "foo0_2_0".
277         let version = version
278             .to_string()
279             .replace('.', "_")
280             .replace('-', "_")
281             .replace('+', "_")
282             .to_snake_case();
283         format!("{base}{version}")
284     }
285 
286     fn generate(&mut self, resolve: &Resolve, id: WorldId) -> anyhow::Result<String> {
287         self.types.analyze(resolve, id);
288         for (i, te) in self.opts.trappable_error_type.iter().enumerate() {
289             let id = resolve_type_in_package(resolve, &te.wit_path)
290                 .context(format!("resolving {:?}", te))
291                 .unwrap();
292             let name = format!("_TrappableError{i}");
293             uwriteln!(self.src, "type {name} = {};", te.rust_type_name);
294             let prev = self.trappable_errors.insert(id, name);
295             assert!(prev.is_none());
296         }
297 
298         // Convert all entries in `with` as relative to the root of where the
299         // macro itself is invoked. This emits a `pub use` to bring the name
300         // into scope under an "anonymous name" which then replaces the `with`
301         // map entry.
302         let mut with = self.opts.with.iter_mut().collect::<Vec<_>>();
303         with.sort();
304         for (i, (_k, v)) in with.into_iter().enumerate() {
305             let name = format!("__with_name{i}");
306             uwriteln!(self.src, "#[doc(hidden)]\npub use {v} as {name};");
307             *v = name;
308         }
309 
310         let world = &resolve.worlds[id];
311         for (name, import) in world.imports.iter() {
312             if !self.opts.only_interfaces || matches!(import, WorldItem::Interface(_)) {
313                 self.import(resolve, id, name, import);
314             }
315         }
316 
317         for (name, export) in world.exports.iter() {
318             if !self.opts.only_interfaces || matches!(export, WorldItem::Interface(_)) {
319                 self.export(resolve, name, export);
320             }
321         }
322         self.finish(resolve, id)
323     }
324 
325     fn import(&mut self, resolve: &Resolve, world: WorldId, name: &WorldKey, item: &WorldItem) {
326         let mut gen = InterfaceGenerator::new(self, resolve);
327         match item {
328             WorldItem::Function(func) => {
329                 // Only generate a trait signature for free functions since
330                 // resource-related functions get their trait signatures
331                 // during `type_resource`.
332                 if let FunctionKind::Freestanding = func.kind {
333                     gen.generate_function_trait_sig(func);
334                 }
335                 let sig = mem::take(&mut gen.src).into();
336                 gen.generate_add_function_to_linker(TypeOwner::World(world), func, "linker");
337                 let add_to_linker = gen.src.into();
338                 self.import_functions
339                     .push(ImportFunction { sig, add_to_linker });
340             }
341             WorldItem::Interface(id) => {
342                 gen.gen.interface_last_seen_as_import.insert(*id, true);
343                 if gen.gen.name_interface(resolve, *id, name, false) {
344                     return;
345                 }
346                 gen.current_interface = Some((*id, name, false));
347                 gen.types(*id);
348                 let key_name = resolve.name_world_key(name);
349 
350                 gen.generate_add_to_linker(*id, &key_name);
351 
352                 let module = &gen.src[..];
353 
354                 let snake = match name {
355                     WorldKey::Name(s) => s.to_snake_case(),
356                     WorldKey::Interface(id) => resolve.interfaces[*id]
357                         .name
358                         .as_ref()
359                         .unwrap()
360                         .to_snake_case(),
361                 };
362                 let module = format!(
363                     "
364                         #[allow(clippy::all)]
365                         pub mod {snake} {{
366                             #[allow(unused_imports)]
367                             use wasmtime::component::__internal::anyhow;
368 
369                             {module}
370                         }}
371                     "
372                 );
373                 self.import_interfaces
374                     .push((module, self.interface_names[id].clone()));
375             }
376             WorldItem::Type(ty) => {
377                 let name = match name {
378                     WorldKey::Name(name) => name,
379                     WorldKey::Interface(_) => unreachable!(),
380                 };
381                 gen.define_type(name, *ty);
382                 let body = mem::take(&mut gen.src);
383                 self.src.push_str(&body);
384             }
385         };
386     }
387 
388     fn export(&mut self, resolve: &Resolve, name: &WorldKey, item: &WorldItem) {
389         let mut gen = InterfaceGenerator::new(self, resolve);
390         let (field, ty, getter) = match item {
391             WorldItem::Function(func) => {
392                 gen.define_rust_guest_export(resolve, None, func);
393                 let body = mem::take(&mut gen.src).into();
394                 let (_name, getter) = gen.extract_typed_function(func);
395                 assert!(gen.src.is_empty());
396                 self.exports.funcs.push(body);
397                 (
398                     func_field_name(resolve, func),
399                     "wasmtime::component::Func".to_string(),
400                     getter,
401                 )
402             }
403             WorldItem::Type(_) => unreachable!(),
404             WorldItem::Interface(id) => {
405                 gen.gen.interface_last_seen_as_import.insert(*id, false);
406                 gen.gen.name_interface(resolve, *id, name, true);
407                 gen.current_interface = Some((*id, name, true));
408                 gen.types(*id);
409                 let struct_name = "Guest";
410                 let iface = &resolve.interfaces[*id];
411                 let iface_name = match name {
412                     WorldKey::Name(name) => name,
413                     WorldKey::Interface(_) => iface.name.as_ref().unwrap(),
414                 };
415                 uwriteln!(gen.src, "pub struct {struct_name} {{");
416                 for (_, func) in iface.functions.iter() {
417                     uwriteln!(
418                         gen.src,
419                         "{}: wasmtime::component::Func,",
420                         func_field_name(resolve, func)
421                     );
422                 }
423                 uwriteln!(gen.src, "}}");
424 
425                 uwriteln!(gen.src, "impl {struct_name} {{");
426                 uwrite!(
427                     gen.src,
428                     "
429                         pub fn new(
430                             __exports: &mut wasmtime::component::ExportInstance<'_, '_>,
431                         ) -> wasmtime::Result<{struct_name}> {{
432                     "
433                 );
434                 let mut fields = Vec::new();
435                 for (_, func) in iface.functions.iter() {
436                     let (name, getter) = gen.extract_typed_function(func);
437                     uwriteln!(gen.src, "let {name} = {getter};");
438                     fields.push(name);
439                 }
440                 uwriteln!(gen.src, "Ok({struct_name} {{");
441                 for name in fields {
442                     uwriteln!(gen.src, "{name},");
443                 }
444                 uwriteln!(gen.src, "}})");
445                 uwriteln!(gen.src, "}}");
446 
447                 let mut resource_methods = IndexMap::new();
448 
449                 for (_, func) in iface.functions.iter() {
450                     match func.kind {
451                         FunctionKind::Freestanding => {
452                             gen.define_rust_guest_export(resolve, Some(name), func);
453                         }
454                         FunctionKind::Method(id)
455                         | FunctionKind::Constructor(id)
456                         | FunctionKind::Static(id) => {
457                             resource_methods.entry(id).or_insert(Vec::new()).push(func);
458                         }
459                     }
460                 }
461 
462                 for (id, _) in resource_methods.iter() {
463                     let name = resolve.types[*id].name.as_ref().unwrap();
464                     let snake = name.to_snake_case();
465                     let camel = name.to_upper_camel_case();
466                     uwriteln!(
467                         gen.src,
468                         "pub fn {snake}(&self) -> Guest{camel}<'_> {{
469                             Guest{camel} {{ funcs: self }}
470                         }}"
471                     );
472                 }
473 
474                 uwriteln!(gen.src, "}}");
475 
476                 for (id, methods) in resource_methods {
477                     let resource_name = resolve.types[id].name.as_ref().unwrap();
478                     let camel = resource_name.to_upper_camel_case();
479                     uwriteln!(gen.src, "impl Guest{camel}<'_> {{");
480                     for method in methods {
481                         gen.define_rust_guest_export(resolve, Some(name), method);
482                     }
483                     uwriteln!(gen.src, "}}");
484                 }
485 
486                 let module = &gen.src[..];
487                 let snake = to_rust_ident(iface_name);
488 
489                 let module = format!(
490                     "
491                         #[allow(clippy::all)]
492                         pub mod {snake} {{
493                             #[allow(unused_imports)]
494                             use wasmtime::component::__internal::anyhow;
495 
496                             {module}
497                         }}
498                     "
499                 );
500                 let pkgname = match name {
501                     WorldKey::Name(_) => None,
502                     WorldKey::Interface(_) => {
503                         Some(resolve.packages[iface.package.unwrap()].name.clone())
504                     }
505                 };
506                 self.exports
507                     .modules
508                     .push((module, self.interface_names[id].clone()));
509 
510                 let name = resolve.name_world_key(name);
511                 let (path, method_name) = match pkgname {
512                     Some(pkgname) => (
513                         format!(
514                             "exports::{}::{}::{snake}::{struct_name}",
515                             pkgname.namespace.to_snake_case(),
516                             self.name_package_module(resolve, iface.package.unwrap()),
517                         ),
518                         format!(
519                             "{}_{}_{snake}",
520                             pkgname.namespace.to_snake_case(),
521                             self.name_package_module(resolve, iface.package.unwrap())
522                         ),
523                     ),
524                     None => (format!("exports::{snake}::{struct_name}"), snake.clone()),
525                 };
526                 let getter = format!(
527                     "\
528                         {path}::new(
529                             &mut __exports.instance(\"{name}\")
530                                 .ok_or_else(|| anyhow::anyhow!(\"exported instance `{name}` not present\"))?
531                         )?\
532                     "
533                 );
534                 let field = format!("interface{}", self.exports.fields.len());
535                 self.exports.funcs.push(format!(
536                     "
537                         pub fn {method_name}(&self) -> &{path} {{
538                             &self.{field}
539                         }}
540                     ",
541                 ));
542                 (field, path, getter)
543             }
544         };
545         let prev = self.exports.fields.insert(field, (ty, getter));
546         assert!(prev.is_none());
547     }
548 
549     fn build_struct(&mut self, resolve: &Resolve, world: WorldId) {
550         let camel = to_rust_upper_camel_case(&resolve.worlds[world].name);
551         uwriteln!(self.src, "pub struct {camel} {{");
552         for (name, (ty, _)) in self.exports.fields.iter() {
553             uwriteln!(self.src, "{name}: {ty},");
554         }
555         self.src.push_str("}\n");
556 
557         let (async_, async__, send, await_) = if self.opts.async_.maybe_async() {
558             ("async", "_async", ":Send", ".await")
559         } else {
560             ("", "", "", "")
561         };
562 
563         self.toplevel_import_trait(resolve, world);
564 
565         uwriteln!(self.src, "const _: () = {{");
566         uwriteln!(
567             self.src,
568             "
569                 #[allow(unused_imports)]
570                 use wasmtime::component::__internal::anyhow;
571             "
572         );
573 
574         uwriteln!(self.src, "impl {camel} {{");
575         self.toplevel_add_to_linker(resolve, world);
576         uwriteln!(
577             self.src,
578             "
579                 /// Instantiates the provided `module` using the specified
580                 /// parameters, wrapping up the result in a structure that
581                 /// translates between wasm and the host.
582                 pub {async_} fn instantiate{async__}<T {send}>(
583                     mut store: impl wasmtime::AsContextMut<Data = T>,
584                     component: &wasmtime::component::Component,
585                     linker: &wasmtime::component::Linker<T>,
586                 ) -> wasmtime::Result<(Self, wasmtime::component::Instance)> {{
587                     let instance = linker.instantiate{async__}(&mut store, component){await_}?;
588                     Ok((Self::new(store, &instance)?, instance))
589                 }}
590 
591                 /// Instantiates a pre-instantiated module using the specified
592                 /// parameters, wrapping up the result in a structure that
593                 /// translates between wasm and the host.
594                 pub {async_} fn instantiate_pre<T {send}>(
595                     mut store: impl wasmtime::AsContextMut<Data = T>,
596                     instance_pre: &wasmtime::component::InstancePre<T>,
597                 ) -> wasmtime::Result<(Self, wasmtime::component::Instance)> {{
598                     let instance = instance_pre.instantiate{async__}(&mut store){await_}?;
599                     Ok((Self::new(store, &instance)?, instance))
600                 }}
601 
602                 /// Low-level creation wrapper for wrapping up the exports
603                 /// of the `instance` provided in this structure of wasm
604                 /// exports.
605                 ///
606                 /// This function will extract exports from the `instance`
607                 /// defined within `store` and wrap them all up in the
608                 /// returned structure which can be used to interact with
609                 /// the wasm module.
610                 pub fn new(
611                     mut store: impl wasmtime::AsContextMut,
612                     instance: &wasmtime::component::Instance,
613                 ) -> wasmtime::Result<Self> {{
614                     let mut store = store.as_context_mut();
615                     let mut exports = instance.exports(&mut store);
616                     let mut __exports = exports.root();
617             ",
618         );
619         for (name, (_, get)) in self.exports.fields.iter() {
620             uwriteln!(self.src, "let {name} = {get};");
621         }
622         uwriteln!(self.src, "Ok({camel} {{");
623         for (name, _) in self.exports.fields.iter() {
624             uwriteln!(self.src, "{name},");
625         }
626         uwriteln!(self.src, "}})");
627         uwriteln!(self.src, "}}"); // close `fn new`
628 
629         for func in self.exports.funcs.iter() {
630             self.src.push_str(func);
631         }
632 
633         uwriteln!(self.src, "}}"); // close `impl {camel}`
634 
635         uwriteln!(self.src, "}};"); // close `const _: () = ...
636     }
637 
638     fn finish(&mut self, resolve: &Resolve, world: WorldId) -> anyhow::Result<String> {
639         let remapping_keys = self.opts.with.keys().cloned().collect::<HashSet<String>>();
640 
641         let mut unused_keys = remapping_keys
642             .difference(&self.used_with_opts)
643             .map(|s| s.as_str())
644             .collect::<Vec<&str>>();
645 
646         unused_keys.sort();
647 
648         if !unused_keys.is_empty() {
649             anyhow::bail!("interfaces were specified in the `with` config option but are not referenced in the target world: {unused_keys:?}");
650         }
651 
652         if !self.opts.only_interfaces {
653             self.build_struct(resolve, world)
654         }
655 
656         let imports = mem::take(&mut self.import_interfaces);
657         self.emit_modules(imports);
658 
659         let exports = mem::take(&mut self.exports.modules);
660         self.emit_modules(exports);
661 
662         let mut src = mem::take(&mut self.src);
663         if self.opts.rustfmt {
664             let mut child = Command::new("rustfmt")
665                 .arg("--edition=2018")
666                 .stdin(Stdio::piped())
667                 .stdout(Stdio::piped())
668                 .spawn()
669                 .expect("failed to spawn `rustfmt`");
670             child
671                 .stdin
672                 .take()
673                 .unwrap()
674                 .write_all(src.as_bytes())
675                 .unwrap();
676             src.as_mut_string().truncate(0);
677             child
678                 .stdout
679                 .take()
680                 .unwrap()
681                 .read_to_string(src.as_mut_string())
682                 .unwrap();
683             let status = child.wait().unwrap();
684             assert!(status.success());
685         }
686 
687         Ok(src.into())
688     }
689 
690     fn emit_modules(&mut self, modules: Vec<(String, InterfaceName)>) {
691         #[derive(Default)]
692         struct Module {
693             submodules: BTreeMap<String, Module>,
694             contents: Vec<String>,
695         }
696         let mut map = Module::default();
697         for (module, name) in modules {
698             let path = match name {
699                 InterfaceName::Remapped { local_path, .. } => local_path,
700                 InterfaceName::Path(path) => path,
701             };
702             let mut cur = &mut map;
703             for name in path[..path.len() - 1].iter() {
704                 cur = cur
705                     .submodules
706                     .entry(name.clone())
707                     .or_insert(Module::default());
708             }
709             cur.contents.push(module);
710         }
711 
712         emit(&mut self.src, map);
713 
714         fn emit(me: &mut Source, module: Module) {
715             for (name, submodule) in module.submodules {
716                 uwriteln!(me, "pub mod {name} {{");
717                 emit(me, submodule);
718                 uwriteln!(me, "}}");
719             }
720             for submodule in module.contents {
721                 uwriteln!(me, "{submodule}");
722             }
723         }
724     }
725 
726     /// Attempts to find the `key`, possibly with the resource projection
727     /// `item`, within the `with` map provided to bindings configuration.
728     fn lookup_replacement(
729         &mut self,
730         resolve: &Resolve,
731         key: &WorldKey,
732         item: Option<&str>,
733     ) -> Option<String> {
734         struct Name<'a> {
735             prefix: Prefix,
736             item: Option<&'a str>,
737         }
738 
739         #[derive(Copy, Clone)]
740         enum Prefix {
741             Namespace(PackageId),
742             UnversionedPackage(PackageId),
743             VersionedPackage(PackageId),
744             UnversionedInterface(InterfaceId),
745             VersionedInterface(InterfaceId),
746         }
747 
748         let prefix = match key {
749             WorldKey::Interface(id) => Prefix::VersionedInterface(*id),
750 
751             // Non-interface-keyed names don't get the lookup logic below,
752             // they're relatively uncommon so only lookup the precise key here.
753             WorldKey::Name(key) => {
754                 let to_lookup = match item {
755                     Some(item) => format!("{key}/{item}"),
756                     None => key.to_string(),
757                 };
758                 let result = self.opts.with.get(&to_lookup).cloned();
759                 if result.is_some() {
760                     self.used_with_opts.insert(to_lookup.clone());
761                 }
762                 return result;
763             }
764         };
765 
766         // Here names are iteratively attempted as `key` + `item` is "walked to
767         // its root" and each attempt is consulted in `self.opts.with`. This
768         // loop will start at the leaf, the most specific path, and then walk to
769         // the root, popping items, trying to find a result.
770         //
771         // Each time a name is "popped" the projection from the next path is
772         // pushed onto `projection`. This means that if we actually find a match
773         // then `projection` is a collection of namespaces that results in the
774         // final replacement name.
775         let mut name = Name { prefix, item };
776         let mut projection = Vec::new();
777         loop {
778             let lookup = name.lookup_key(resolve);
779             if let Some(renamed) = self.opts.with.get(&lookup) {
780                 projection.push(renamed.clone());
781                 projection.reverse();
782                 self.used_with_opts.insert(lookup);
783                 return Some(projection.join("::"));
784             }
785             if !name.pop(resolve, &mut projection) {
786                 return None;
787             }
788         }
789 
790         impl<'a> Name<'a> {
791             fn lookup_key(&self, resolve: &Resolve) -> String {
792                 let mut s = self.prefix.lookup_key(resolve);
793                 if let Some(item) = self.item {
794                     s.push_str("/");
795                     s.push_str(item);
796                 }
797                 s
798             }
799 
800             fn pop(&mut self, resolve: &'a Resolve, projection: &mut Vec<String>) -> bool {
801                 match (self.item, self.prefix) {
802                     // If this is a versioned resource name, try the unversioned
803                     // resource name next.
804                     (Some(_), Prefix::VersionedInterface(id)) => {
805                         self.prefix = Prefix::UnversionedInterface(id);
806                         true
807                     }
808                     // If this is an unversioned resource name then time to
809                     // ignore the resource itself and move on to the next most
810                     // specific item, versioned interface names.
811                     (Some(item), Prefix::UnversionedInterface(id)) => {
812                         self.prefix = Prefix::VersionedInterface(id);
813                         self.item = None;
814                         projection.push(item.to_upper_camel_case());
815                         true
816                     }
817                     (Some(_), _) => unreachable!(),
818                     (None, _) => self.prefix.pop(resolve, projection),
819                 }
820             }
821         }
822 
823         impl Prefix {
824             fn lookup_key(&self, resolve: &Resolve) -> String {
825                 match *self {
826                     Prefix::Namespace(id) => resolve.packages[id].name.namespace.clone(),
827                     Prefix::UnversionedPackage(id) => {
828                         let mut name = resolve.packages[id].name.clone();
829                         name.version = None;
830                         name.to_string()
831                     }
832                     Prefix::VersionedPackage(id) => resolve.packages[id].name.to_string(),
833                     Prefix::UnversionedInterface(id) => {
834                         let id = resolve.id_of(id).unwrap();
835                         match id.find('@') {
836                             Some(i) => id[..i].to_string(),
837                             None => id,
838                         }
839                     }
840                     Prefix::VersionedInterface(id) => resolve.id_of(id).unwrap(),
841                 }
842             }
843 
844             fn pop(&mut self, resolve: &Resolve, projection: &mut Vec<String>) -> bool {
845                 *self = match *self {
846                     // try the unversioned interface next
847                     Prefix::VersionedInterface(id) => Prefix::UnversionedInterface(id),
848                     // try this interface's versioned package next
849                     Prefix::UnversionedInterface(id) => {
850                         let iface = &resolve.interfaces[id];
851                         let name = iface.name.as_ref().unwrap();
852                         projection.push(to_rust_ident(name));
853                         Prefix::VersionedPackage(iface.package.unwrap())
854                     }
855                     // try the unversioned package next
856                     Prefix::VersionedPackage(id) => Prefix::UnversionedPackage(id),
857                     // try this package's namespace next
858                     Prefix::UnversionedPackage(id) => {
859                         let name = &resolve.packages[id].name;
860                         projection.push(to_rust_ident(&name.name));
861                         Prefix::Namespace(id)
862                     }
863                     // nothing left to try any more
864                     Prefix::Namespace(_) => return false,
865                 };
866                 true
867             }
868         }
869     }
870 }
871 
872 impl Wasmtime {
873     fn has_world_trait(&self, resolve: &Resolve, world: WorldId) -> bool {
874         !self.import_functions.is_empty() || get_world_resources(resolve, world).count() > 0
875     }
876 
877     fn toplevel_import_trait(&mut self, resolve: &Resolve, world: WorldId) {
878         if !self.has_world_trait(resolve, world) {
879             return;
880         }
881 
882         let world_camel = to_rust_upper_camel_case(&resolve.worlds[world].name);
883         if self.opts.async_.maybe_async() {
884             uwriteln!(self.src, "#[wasmtime::component::__internal::async_trait]")
885         }
886         uwrite!(self.src, "pub trait {world_camel}Imports");
887         for (i, resource) in get_world_resources(resolve, world).enumerate() {
888             if i == 0 {
889                 uwrite!(self.src, ": ");
890             } else {
891                 uwrite!(self.src, " + ");
892             }
893             uwrite!(self.src, "Host{}", resource.to_upper_camel_case());
894         }
895         uwriteln!(self.src, " {{");
896         for f in self.import_functions.iter() {
897             self.src.push_str(&f.sig);
898             self.src.push_str("\n");
899         }
900         uwriteln!(self.src, "}}");
901     }
902 
903     fn toplevel_add_to_linker(&mut self, resolve: &Resolve, world: WorldId) {
904         let has_world_trait = self.has_world_trait(resolve, world);
905         if self.import_interfaces.is_empty() && !has_world_trait {
906             return;
907         }
908         let mut interfaces = Vec::new();
909         for (_, name) in self.import_interfaces.iter() {
910             let path = match name {
911                 InterfaceName::Remapped { .. } => unreachable!("imported a remapped module"),
912                 InterfaceName::Path(path) => path,
913             };
914             interfaces.push(path.join("::"));
915         }
916 
917         uwrite!(
918             self.src,
919             "
920                 pub fn add_to_linker<T, U>(
921                     linker: &mut wasmtime::component::Linker<T>,
922                     get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static,
923                 ) -> wasmtime::Result<()>
924                     where U: \
925             "
926         );
927         let world_camel = to_rust_upper_camel_case(&resolve.worlds[world].name);
928         let world_trait = format!("{world_camel}Imports");
929         for (i, name) in interfaces
930             .iter()
931             .map(|n| format!("{n}::Host"))
932             .chain(if has_world_trait {
933                 Some(world_trait.clone())
934             } else {
935                 None
936             })
937             .enumerate()
938         {
939             if i > 0 {
940                 self.src.push_str(" + ");
941             }
942             self.src.push_str(&name);
943         }
944 
945         let maybe_send = if self.opts.async_.maybe_async() {
946             " + Send, T: Send"
947         } else {
948             ""
949         };
950 
951         self.src.push_str(maybe_send);
952         self.src.push_str(",\n{\n");
953         for name in interfaces.iter() {
954             uwriteln!(self.src, "{name}::add_to_linker(linker, get)?;");
955         }
956         if has_world_trait {
957             uwriteln!(self.src, "Self::add_root_to_linker(linker, get)?;");
958         }
959         uwriteln!(self.src, "Ok(())\n}}");
960         if !has_world_trait {
961             return;
962         }
963 
964         uwrite!(
965             self.src,
966             "
967                 pub fn add_root_to_linker<T, U>(
968                     linker: &mut wasmtime::component::Linker<T>,
969                     get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static,
970                 ) -> wasmtime::Result<()>
971                     where U: {world_trait}{maybe_send}
972                 {{
973                     let mut linker = linker.root();
974             ",
975         );
976         for name in get_world_resources(resolve, world) {
977             let camel = name.to_upper_camel_case();
978             uwriteln!(
979                 self.src,
980                 "linker.resource(
981                     \"{name}\",
982                     wasmtime::component::ResourceType::host::<{camel}>(),
983                     move |mut store, rep| -> wasmtime::Result<()> {{
984                         Host{camel}::drop(get(store.data_mut()), wasmtime::component::Resource::new_own(rep))
985                     }},
986                 )?;"
987             )
988         }
989 
990         for f in self.import_functions.iter() {
991             self.src.push_str(&f.add_to_linker);
992             self.src.push_str("\n");
993         }
994         uwriteln!(self.src, "Ok(())\n}}");
995     }
996 }
997 
998 fn resolve_type_in_package(resolve: &Resolve, wit_path: &str) -> anyhow::Result<TypeId> {
999     // Build a map, `packages_to_omit_version`, where that package can be
1000     // uniquely identified by its name/namespace combo and as such version
1001     // information is not required.
1002     let mut packages_with_same_name = HashMap::new();
1003     for (id, pkg) in resolve.packages.iter() {
1004         packages_with_same_name
1005             .entry(PackageName {
1006                 version: None,
1007                 ..pkg.name.clone()
1008             })
1009             .or_insert(Vec::new())
1010             .push(id)
1011     }
1012     let packages_to_omit_version = packages_with_same_name
1013         .iter()
1014         .filter_map(
1015             |(_name, list)| {
1016                 if list.len() == 1 {
1017                     Some(list)
1018                 } else {
1019                     None
1020                 }
1021             },
1022         )
1023         .flat_map(|l| l)
1024         .collect::<HashSet<_>>();
1025 
1026     let mut found_interface = false;
1027 
1028     // Look for an interface whose assigned prefix starts `wit_path`. Not
1029     // exactly the most efficient thing ever but is sufficient for now.
1030     for (id, interface) in resolve.interfaces.iter() {
1031         found_interface = true;
1032 
1033         let iface_name = match &interface.name {
1034             Some(name) => name,
1035             None => continue,
1036         };
1037         let pkgid = interface.package.unwrap();
1038         let pkgname = &resolve.packages[pkgid].name;
1039         let prefix = if packages_to_omit_version.contains(&pkgid) {
1040             let mut name = pkgname.clone();
1041             name.version = None;
1042             format!("{name}/{iface_name}")
1043         } else {
1044             resolve.id_of(id).unwrap()
1045         };
1046         let wit_path = match wit_path.strip_prefix(&prefix) {
1047             Some(rest) => rest,
1048             None => continue,
1049         };
1050 
1051         let wit_path = match wit_path.strip_prefix('/') {
1052             Some(rest) => rest,
1053             None => continue,
1054         };
1055 
1056         match interface.types.get(wit_path).copied() {
1057             Some(type_id) => return Ok(type_id),
1058             None => continue,
1059         }
1060     }
1061 
1062     if found_interface {
1063         bail!("no types found to match `{wit_path}` in interface");
1064     }
1065 
1066     bail!("no package/interface found to match `{wit_path}`")
1067 }
1068 
1069 struct InterfaceGenerator<'a> {
1070     src: Source,
1071     gen: &'a mut Wasmtime,
1072     resolve: &'a Resolve,
1073     current_interface: Option<(InterfaceId, &'a WorldKey, bool)>,
1074 }
1075 
1076 impl<'a> InterfaceGenerator<'a> {
1077     fn new(gen: &'a mut Wasmtime, resolve: &'a Resolve) -> InterfaceGenerator<'a> {
1078         InterfaceGenerator {
1079             src: Source::default(),
1080             gen,
1081             resolve,
1082             current_interface: None,
1083         }
1084     }
1085 
1086     fn types_imported(&self) -> bool {
1087         match self.current_interface {
1088             Some((_, _, is_export)) => !is_export,
1089             None => true,
1090         }
1091     }
1092 
1093     fn types(&mut self, id: InterfaceId) {
1094         for (name, id) in self.resolve.interfaces[id].types.iter() {
1095             self.define_type(name, *id);
1096         }
1097     }
1098 
1099     fn define_type(&mut self, name: &str, id: TypeId) {
1100         let ty = &self.resolve.types[id];
1101         match &ty.kind {
1102             TypeDefKind::Record(record) => self.type_record(id, name, record, &ty.docs),
1103             TypeDefKind::Flags(flags) => self.type_flags(id, name, flags, &ty.docs),
1104             TypeDefKind::Tuple(tuple) => self.type_tuple(id, name, tuple, &ty.docs),
1105             TypeDefKind::Enum(enum_) => self.type_enum(id, name, enum_, &ty.docs),
1106             TypeDefKind::Variant(variant) => self.type_variant(id, name, variant, &ty.docs),
1107             TypeDefKind::Option(t) => self.type_option(id, name, t, &ty.docs),
1108             TypeDefKind::Result(r) => self.type_result(id, name, r, &ty.docs),
1109             TypeDefKind::List(t) => self.type_list(id, name, t, &ty.docs),
1110             TypeDefKind::Type(t) => self.type_alias(id, name, t, &ty.docs),
1111             TypeDefKind::Future(_) => todo!("generate for future"),
1112             TypeDefKind::Stream(_) => todo!("generate for stream"),
1113             TypeDefKind::Handle(handle) => self.type_handle(id, name, handle, &ty.docs),
1114             TypeDefKind::Resource => self.type_resource(id, name, ty, &ty.docs),
1115             TypeDefKind::Unknown => unreachable!(),
1116         }
1117     }
1118 
1119     fn type_handle(&mut self, id: TypeId, name: &str, handle: &Handle, docs: &Docs) {
1120         self.rustdoc(docs);
1121         let name = name.to_upper_camel_case();
1122         uwriteln!(self.src, "pub type {name} = ");
1123         self.print_handle(handle);
1124         self.push_str(";\n");
1125         self.assert_type(id, &name);
1126     }
1127 
1128     fn type_resource(&mut self, id: TypeId, name: &str, resource: &TypeDef, docs: &Docs) {
1129         let camel = name.to_upper_camel_case();
1130 
1131         if self.types_imported() {
1132             self.rustdoc(docs);
1133 
1134             let replacement = match self.current_interface {
1135                 Some((_, key, _)) => self.gen.lookup_replacement(self.resolve, key, Some(name)),
1136                 None => {
1137                     self.gen.used_with_opts.insert(name.into());
1138                     self.gen.opts.with.get(name).cloned()
1139                 }
1140             };
1141             match replacement {
1142                 Some(path) => {
1143                     uwriteln!(
1144                         self.src,
1145                         "pub use {}{path} as {camel};",
1146                         self.path_to_root()
1147                     );
1148                 }
1149                 None => {
1150                     uwriteln!(self.src, "pub enum {camel} {{}}");
1151                 }
1152             }
1153 
1154             if self.gen.opts.async_.maybe_async() {
1155                 uwriteln!(self.src, "#[wasmtime::component::__internal::async_trait]")
1156             }
1157 
1158             uwriteln!(self.src, "pub trait Host{camel} {{");
1159 
1160             let functions = match resource.owner {
1161                 TypeOwner::World(id) => self.resolve.worlds[id]
1162                     .imports
1163                     .values()
1164                     .filter_map(|item| match item {
1165                         WorldItem::Function(f) => Some(f),
1166                         _ => None,
1167                     })
1168                     .collect(),
1169                 TypeOwner::Interface(id) => self.resolve.interfaces[id]
1170                     .functions
1171                     .values()
1172                     .collect::<Vec<_>>(),
1173                 TypeOwner::None => {
1174                     panic!("A resource must be owned by a world or interface");
1175                 }
1176             };
1177 
1178             for func in functions {
1179                 match func.kind {
1180                     FunctionKind::Method(resource)
1181                     | FunctionKind::Static(resource)
1182                     | FunctionKind::Constructor(resource)
1183                         if id == resource => {}
1184                     _ => continue,
1185                 }
1186 
1187                 self.generate_function_trait_sig(func);
1188             }
1189 
1190             uwrite!(
1191                 self.src,
1192                 "fn drop(&mut self, rep: wasmtime::component::Resource<{camel}>) -> wasmtime::Result<()>;");
1193 
1194             uwriteln!(self.src, "}}");
1195         } else {
1196             self.rustdoc(docs);
1197             uwriteln!(
1198                 self.src,
1199                 "
1200                     pub type {camel} = wasmtime::component::ResourceAny;
1201 
1202                     pub struct Guest{camel}<'a> {{
1203                         funcs: &'a Guest,
1204                     }}
1205                 "
1206             );
1207         }
1208     }
1209 
1210     fn type_record(&mut self, id: TypeId, _name: &str, record: &Record, docs: &Docs) {
1211         let info = self.info(id);
1212 
1213         // We use a BTree set to make sure we don't have any duplicates and we have a stable order
1214         let additional_derives: BTreeSet<String> = self
1215             .gen
1216             .opts
1217             .additional_derive_attributes
1218             .iter()
1219             .cloned()
1220             .collect();
1221 
1222         for (name, mode) in self.modes_of(id) {
1223             let lt = self.lifetime_for(&info, mode);
1224             self.rustdoc(docs);
1225 
1226             let mut derives = additional_derives.clone();
1227 
1228             self.push_str("#[derive(wasmtime::component::ComponentType)]\n");
1229             if lt.is_none() {
1230                 self.push_str("#[derive(wasmtime::component::Lift)]\n");
1231             }
1232             self.push_str("#[derive(wasmtime::component::Lower)]\n");
1233             self.push_str("#[component(record)]\n");
1234 
1235             if info.is_copy() {
1236                 derives.extend(["Copy", "Clone"].into_iter().map(|s| s.to_string()));
1237             } else if info.is_clone() {
1238                 derives.insert("Clone".to_string());
1239             }
1240 
1241             if !derives.is_empty() {
1242                 self.push_str("#[derive(");
1243                 self.push_str(&derives.into_iter().collect::<Vec<_>>().join(", "));
1244                 self.push_str(")]\n")
1245             }
1246 
1247             self.push_str(&format!("pub struct {}", name));
1248             self.print_generics(lt);
1249             self.push_str(" {\n");
1250             for field in record.fields.iter() {
1251                 self.rustdoc(&field.docs);
1252                 self.push_str(&format!("#[component(name = \"{}\")]\n", field.name));
1253                 self.push_str("pub ");
1254                 self.push_str(&to_rust_ident(&field.name));
1255                 self.push_str(": ");
1256                 self.print_ty(&field.ty, mode);
1257                 self.push_str(",\n");
1258             }
1259             self.push_str("}\n");
1260 
1261             self.push_str("impl");
1262             self.print_generics(lt);
1263             self.push_str(" core::fmt::Debug for ");
1264             self.push_str(&name);
1265             self.print_generics(lt);
1266             self.push_str(" {\n");
1267             self.push_str(
1268                 "fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
1269             );
1270             self.push_str(&format!("f.debug_struct(\"{}\")", name));
1271             for field in record.fields.iter() {
1272                 self.push_str(&format!(
1273                     ".field(\"{}\", &self.{})",
1274                     field.name,
1275                     to_rust_ident(&field.name)
1276                 ));
1277             }
1278             self.push_str(".finish()\n");
1279             self.push_str("}\n");
1280             self.push_str("}\n");
1281 
1282             if info.error {
1283                 self.push_str("impl");
1284                 self.print_generics(lt);
1285                 self.push_str(" core::fmt::Display for ");
1286                 self.push_str(&name);
1287                 self.print_generics(lt);
1288                 self.push_str(" {\n");
1289                 self.push_str(
1290                     "fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
1291                 );
1292                 self.push_str("write!(f, \"{:?}\", self)\n");
1293                 self.push_str("}\n");
1294                 self.push_str("}\n");
1295 
1296                 if cfg!(feature = "std") {
1297                     self.push_str("impl std::error::Error for ");
1298                     self.push_str(&name);
1299                     self.push_str("{}\n");
1300                 }
1301             }
1302             self.assert_type(id, &name);
1303         }
1304     }
1305 
1306     fn type_tuple(&mut self, id: TypeId, _name: &str, tuple: &Tuple, docs: &Docs) {
1307         let info = self.info(id);
1308         for (name, mode) in self.modes_of(id) {
1309             let lt = self.lifetime_for(&info, mode);
1310             self.rustdoc(docs);
1311             self.push_str(&format!("pub type {}", name));
1312             self.print_generics(lt);
1313             self.push_str(" = (");
1314             for ty in tuple.types.iter() {
1315                 self.print_ty(ty, mode);
1316                 self.push_str(",");
1317             }
1318             self.push_str(");\n");
1319             self.assert_type(id, &name);
1320         }
1321     }
1322 
1323     fn type_flags(&mut self, id: TypeId, name: &str, flags: &Flags, docs: &Docs) {
1324         self.rustdoc(docs);
1325         let rust_name = to_rust_upper_camel_case(name);
1326         self.src.push_str("wasmtime::component::flags!(\n");
1327         self.src.push_str(&format!("{rust_name} {{\n"));
1328         for flag in flags.flags.iter() {
1329             // TODO wasmtime-component-macro doesnt support docs for flags rn
1330             uwrite!(
1331                 self.src,
1332                 "#[component(name=\"{}\")] const {};\n",
1333                 flag.name,
1334                 flag.name.to_shouty_snake_case()
1335             );
1336         }
1337         self.src.push_str("}\n");
1338         self.src.push_str(");\n\n");
1339         self.assert_type(id, &rust_name);
1340     }
1341 
1342     fn type_variant(&mut self, id: TypeId, _name: &str, variant: &Variant, docs: &Docs) {
1343         self.print_rust_enum(
1344             id,
1345             variant.cases.iter().map(|c| {
1346                 (
1347                     c.name.to_upper_camel_case(),
1348                     Some(c.name.clone()),
1349                     &c.docs,
1350                     c.ty.as_ref(),
1351                 )
1352             }),
1353             docs,
1354             "variant",
1355         );
1356     }
1357 
1358     fn type_option(&mut self, id: TypeId, _name: &str, payload: &Type, docs: &Docs) {
1359         let info = self.info(id);
1360 
1361         for (name, mode) in self.modes_of(id) {
1362             self.rustdoc(docs);
1363             let lt = self.lifetime_for(&info, mode);
1364             self.push_str(&format!("pub type {}", name));
1365             self.print_generics(lt);
1366             self.push_str("= Option<");
1367             self.print_ty(payload, mode);
1368             self.push_str(">;\n");
1369             self.assert_type(id, &name);
1370         }
1371     }
1372 
1373     // Emit a double-check that the wit-parser-understood size of a type agrees
1374     // with the Wasmtime-understood size of a type.
1375     fn assert_type(&mut self, id: TypeId, name: &str) {
1376         self.push_str("const _: () = {\n");
1377         uwriteln!(
1378             self.src,
1379             "assert!({} == <{name} as wasmtime::component::ComponentType>::SIZE32);",
1380             self.gen.sizes.size(&Type::Id(id)),
1381         );
1382         uwriteln!(
1383             self.src,
1384             "assert!({} == <{name} as wasmtime::component::ComponentType>::ALIGN32);",
1385             self.gen.sizes.align(&Type::Id(id)),
1386         );
1387         self.push_str("};\n");
1388     }
1389 
1390     fn print_rust_enum<'b>(
1391         &mut self,
1392         id: TypeId,
1393         cases: impl IntoIterator<Item = (String, Option<String>, &'b Docs, Option<&'b Type>)> + Clone,
1394         docs: &Docs,
1395         derive_component: &str,
1396     ) where
1397         Self: Sized,
1398     {
1399         let info = self.info(id);
1400 
1401         // We use a BTree set to make sure we don't have any duplicates and we have a stable order
1402         let additional_derives: BTreeSet<String> = self
1403             .gen
1404             .opts
1405             .additional_derive_attributes
1406             .iter()
1407             .cloned()
1408             .collect();
1409 
1410         for (name, mode) in self.modes_of(id) {
1411             let name = to_rust_upper_camel_case(&name);
1412 
1413             let mut derives = additional_derives.clone();
1414 
1415             self.rustdoc(docs);
1416             let lt = self.lifetime_for(&info, mode);
1417             self.push_str("#[derive(wasmtime::component::ComponentType)]\n");
1418             if lt.is_none() {
1419                 self.push_str("#[derive(wasmtime::component::Lift)]\n");
1420             }
1421             self.push_str("#[derive(wasmtime::component::Lower)]\n");
1422             self.push_str(&format!("#[component({})]\n", derive_component));
1423             if info.is_copy() {
1424                 derives.extend(["Copy", "Clone"].into_iter().map(|s| s.to_string()));
1425             } else if info.is_clone() {
1426                 derives.insert("Clone".to_string());
1427             }
1428 
1429             if !derives.is_empty() {
1430                 self.push_str("#[derive(");
1431                 self.push_str(&derives.into_iter().collect::<Vec<_>>().join(", "));
1432                 self.push_str(")]\n")
1433             }
1434 
1435             self.push_str(&format!("pub enum {name}"));
1436             self.print_generics(lt);
1437             self.push_str("{\n");
1438             for (case_name, component_name, docs, payload) in cases.clone() {
1439                 self.rustdoc(docs);
1440                 if let Some(n) = component_name {
1441                     self.push_str(&format!("#[component(name = \"{}\")] ", n));
1442                 }
1443                 self.push_str(&case_name);
1444                 if let Some(ty) = payload {
1445                     self.push_str("(");
1446                     self.print_ty(ty, mode);
1447                     self.push_str(")")
1448                 }
1449                 self.push_str(",\n");
1450             }
1451             self.push_str("}\n");
1452 
1453             self.print_rust_enum_debug(
1454                 id,
1455                 mode,
1456                 &name,
1457                 cases
1458                     .clone()
1459                     .into_iter()
1460                     .map(|(name, _attr, _docs, ty)| (name, ty)),
1461             );
1462 
1463             if info.error {
1464                 self.push_str("impl");
1465                 self.print_generics(lt);
1466                 self.push_str(" core::fmt::Display for ");
1467                 self.push_str(&name);
1468                 self.print_generics(lt);
1469                 self.push_str(" {\n");
1470                 self.push_str(
1471                     "fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
1472                 );
1473                 self.push_str("write!(f, \"{:?}\", self)");
1474                 self.push_str("}\n");
1475                 self.push_str("}\n");
1476                 self.push_str("\n");
1477 
1478                 if cfg!(feature = "std") {
1479                     self.push_str("impl");
1480                     self.print_generics(lt);
1481                     self.push_str(" std::error::Error for ");
1482                     self.push_str(&name);
1483                     self.print_generics(lt);
1484                     self.push_str(" {}\n");
1485                 }
1486             }
1487 
1488             self.assert_type(id, &name);
1489         }
1490     }
1491 
1492     fn print_rust_enum_debug<'b>(
1493         &mut self,
1494         id: TypeId,
1495         mode: TypeMode,
1496         name: &str,
1497         cases: impl IntoIterator<Item = (String, Option<&'b Type>)>,
1498     ) where
1499         Self: Sized,
1500     {
1501         let info = self.info(id);
1502         let lt = self.lifetime_for(&info, mode);
1503         self.push_str("impl");
1504         self.print_generics(lt);
1505         self.push_str(" core::fmt::Debug for ");
1506         self.push_str(name);
1507         self.print_generics(lt);
1508         self.push_str(" {\n");
1509         self.push_str("fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n");
1510         self.push_str("match self {\n");
1511         for (case_name, payload) in cases {
1512             self.push_str(name);
1513             self.push_str("::");
1514             self.push_str(&case_name);
1515             if payload.is_some() {
1516                 self.push_str("(e)");
1517             }
1518             self.push_str(" => {\n");
1519             self.push_str(&format!("f.debug_tuple(\"{}::{}\")", name, case_name));
1520             if payload.is_some() {
1521                 self.push_str(".field(e)");
1522             }
1523             self.push_str(".finish()\n");
1524             self.push_str("}\n");
1525         }
1526         self.push_str("}\n");
1527         self.push_str("}\n");
1528         self.push_str("}\n");
1529     }
1530 
1531     fn type_result(&mut self, id: TypeId, _name: &str, result: &Result_, docs: &Docs) {
1532         let info = self.info(id);
1533 
1534         for (name, mode) in self.modes_of(id) {
1535             self.rustdoc(docs);
1536             let lt = self.lifetime_for(&info, mode);
1537             self.push_str(&format!("pub type {}", name));
1538             self.print_generics(lt);
1539             self.push_str("= Result<");
1540             self.print_optional_ty(result.ok.as_ref(), mode);
1541             self.push_str(",");
1542             self.print_optional_ty(result.err.as_ref(), mode);
1543             self.push_str(">;\n");
1544             self.assert_type(id, &name);
1545         }
1546     }
1547 
1548     fn type_enum(&mut self, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) {
1549         let info = self.info(id);
1550 
1551         // We use a BTree set to make sure we don't have any duplicates and have a stable order
1552         let mut derives: BTreeSet<String> = self
1553             .gen
1554             .opts
1555             .additional_derive_attributes
1556             .iter()
1557             .cloned()
1558             .collect();
1559 
1560         derives.extend(
1561             ["Clone", "Copy", "PartialEq", "Eq"]
1562                 .into_iter()
1563                 .map(|s| s.to_string()),
1564         );
1565 
1566         let name = to_rust_upper_camel_case(name);
1567         self.rustdoc(docs);
1568         self.push_str("#[derive(wasmtime::component::ComponentType)]\n");
1569         self.push_str("#[derive(wasmtime::component::Lift)]\n");
1570         self.push_str("#[derive(wasmtime::component::Lower)]\n");
1571         self.push_str("#[component(enum)]\n");
1572 
1573         self.push_str("#[derive(");
1574         self.push_str(&derives.into_iter().collect::<Vec<_>>().join(", "));
1575         self.push_str(")]\n");
1576 
1577         self.push_str(&format!("pub enum {} {{\n", name));
1578         for case in enum_.cases.iter() {
1579             self.rustdoc(&case.docs);
1580             self.push_str(&format!("#[component(name = \"{}\")]", case.name));
1581             self.push_str(&case.name.to_upper_camel_case());
1582             self.push_str(",\n");
1583         }
1584         self.push_str("}\n");
1585 
1586         // Auto-synthesize an implementation of the standard `Error` trait for
1587         // error-looking types based on their name.
1588         if info.error {
1589             self.push_str("impl ");
1590             self.push_str(&name);
1591             self.push_str("{\n");
1592 
1593             self.push_str("pub fn name(&self) -> &'static str {\n");
1594             self.push_str("match self {\n");
1595             for case in enum_.cases.iter() {
1596                 self.push_str(&name);
1597                 self.push_str("::");
1598                 self.push_str(&case.name.to_upper_camel_case());
1599                 self.push_str(" => \"");
1600                 self.push_str(case.name.as_str());
1601                 self.push_str("\",\n");
1602             }
1603             self.push_str("}\n");
1604             self.push_str("}\n");
1605 
1606             self.push_str("pub fn message(&self) -> &'static str {\n");
1607             self.push_str("match self {\n");
1608             for case in enum_.cases.iter() {
1609                 self.push_str(&name);
1610                 self.push_str("::");
1611                 self.push_str(&case.name.to_upper_camel_case());
1612                 self.push_str(" => \"");
1613                 if let Some(contents) = &case.docs.contents {
1614                     self.push_str(contents.trim());
1615                 }
1616                 self.push_str("\",\n");
1617             }
1618             self.push_str("}\n");
1619             self.push_str("}\n");
1620 
1621             self.push_str("}\n");
1622 
1623             self.push_str("impl core::fmt::Debug for ");
1624             self.push_str(&name);
1625             self.push_str(
1626                 "{\nfn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
1627             );
1628             self.push_str("f.debug_struct(\"");
1629             self.push_str(&name);
1630             self.push_str("\")\n");
1631             self.push_str(".field(\"code\", &(*self as i32))\n");
1632             self.push_str(".field(\"name\", &self.name())\n");
1633             self.push_str(".field(\"message\", &self.message())\n");
1634             self.push_str(".finish()\n");
1635             self.push_str("}\n");
1636             self.push_str("}\n");
1637 
1638             self.push_str("impl core::fmt::Display for ");
1639             self.push_str(&name);
1640             self.push_str(
1641                 "{\nfn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
1642             );
1643             self.push_str("write!(f, \"{} (error {})\", self.name(), *self as i32)");
1644             self.push_str("}\n");
1645             self.push_str("}\n");
1646             self.push_str("\n");
1647             if cfg!(feature = "std") {
1648                 self.push_str("impl std::error::Error for ");
1649                 self.push_str(&name);
1650                 self.push_str("{}\n");
1651             }
1652         } else {
1653             self.print_rust_enum_debug(
1654                 id,
1655                 TypeMode::Owned,
1656                 &name,
1657                 enum_
1658                     .cases
1659                     .iter()
1660                     .map(|c| (c.name.to_upper_camel_case(), None)),
1661             )
1662         }
1663         self.assert_type(id, &name);
1664     }
1665 
1666     fn type_alias(&mut self, id: TypeId, _name: &str, ty: &Type, docs: &Docs) {
1667         let info = self.info(id);
1668         for (name, mode) in self.modes_of(id) {
1669             self.rustdoc(docs);
1670             self.push_str(&format!("pub type {}", name));
1671             let lt = self.lifetime_for(&info, mode);
1672             self.print_generics(lt);
1673             self.push_str(" = ");
1674             self.print_ty(ty, mode);
1675             self.push_str(";\n");
1676             let def_id = resolve_type_definition_id(self.resolve, id);
1677             if !matches!(self.resolve().types[def_id].kind, TypeDefKind::Resource) {
1678                 self.assert_type(id, &name);
1679             }
1680         }
1681     }
1682 
1683     fn type_list(&mut self, id: TypeId, _name: &str, ty: &Type, docs: &Docs) {
1684         let info = self.info(id);
1685         for (name, mode) in self.modes_of(id) {
1686             let lt = self.lifetime_for(&info, mode);
1687             self.rustdoc(docs);
1688             self.push_str(&format!("pub type {}", name));
1689             self.print_generics(lt);
1690             self.push_str(" = ");
1691             self.print_list(ty, mode);
1692             self.push_str(";\n");
1693             self.assert_type(id, &name);
1694         }
1695     }
1696 
1697     fn print_result_ty(&mut self, results: &Results, mode: TypeMode) {
1698         match results {
1699             Results::Named(rs) => match rs.len() {
1700                 0 => self.push_str("()"),
1701                 1 => self.print_ty(&rs[0].1, mode),
1702                 _ => {
1703                     self.push_str("(");
1704                     for (i, (_, ty)) in rs.iter().enumerate() {
1705                         if i > 0 {
1706                             self.push_str(", ")
1707                         }
1708                         self.print_ty(ty, mode)
1709                     }
1710                     self.push_str(")");
1711                 }
1712             },
1713             Results::Anon(ty) => self.print_ty(ty, mode),
1714         }
1715     }
1716 
1717     fn special_case_trappable_error(
1718         &self,
1719         results: &Results,
1720     ) -> Option<(&'a Result_, TypeId, String)> {
1721         // We fillin a special trappable error type in the case when a function has just one
1722         // result, which is itself a `result<a, e>`, and the `e` is *not* a primitive
1723         // (i.e. defined in std) type, and matches the typename given by the user.
1724         let mut i = results.iter_types();
1725         let id = match i.next()? {
1726             Type::Id(id) => id,
1727             _ => return None,
1728         };
1729         if i.next().is_some() {
1730             return None;
1731         }
1732         let result = match &self.resolve.types[*id].kind {
1733             TypeDefKind::Result(r) => r,
1734             _ => return None,
1735         };
1736         let error_typeid = match result.err? {
1737             Type::Id(id) => resolve_type_definition_id(&self.resolve, id),
1738             _ => return None,
1739         };
1740 
1741         let name = self.gen.trappable_errors.get(&error_typeid)?;
1742 
1743         let mut path = self.path_to_root();
1744         uwrite!(path, "{name}");
1745         Some((result, error_typeid, path))
1746     }
1747 
1748     fn generate_add_to_linker(&mut self, id: InterfaceId, name: &str) {
1749         let iface = &self.resolve.interfaces[id];
1750         let owner = TypeOwner::Interface(id);
1751 
1752         if self.gen.opts.async_.maybe_async() {
1753             uwriteln!(self.src, "#[wasmtime::component::__internal::async_trait]")
1754         }
1755         // Generate the `pub trait` which represents the host functionality for
1756         // this import which additionally inherits from all resource traits
1757         // for this interface defined by `type_resource`.
1758         uwrite!(self.src, "pub trait Host");
1759         for (i, resource) in get_resources(self.resolve, id).enumerate() {
1760             if i == 0 {
1761                 uwrite!(self.src, ": ");
1762             } else {
1763                 uwrite!(self.src, " + ");
1764             }
1765             uwrite!(self.src, "Host{}", resource.to_upper_camel_case());
1766         }
1767         uwriteln!(self.src, " {{");
1768         for (_, func) in iface.functions.iter() {
1769             match func.kind {
1770                 FunctionKind::Freestanding => {}
1771                 _ => continue,
1772             }
1773             self.generate_function_trait_sig(func);
1774         }
1775 
1776         // Generate `convert_*` functions to convert custom trappable errors
1777         // into the representation required by Wasmtime's component API.
1778         let mut required_conversion_traits = IndexSet::new();
1779         let mut errors_converted = IndexSet::new();
1780         let my_error_types = iface
1781             .types
1782             .iter()
1783             .filter(|(_, id)| self.gen.trappable_errors.contains_key(*id))
1784             .map(|(_, id)| *id);
1785         let used_error_types = iface
1786             .functions
1787             .iter()
1788             .filter_map(|(_, func)| self.special_case_trappable_error(&func.results))
1789             .map(|(_, id, _)| id);
1790         for err in my_error_types.chain(used_error_types).collect::<Vec<_>>() {
1791             let custom_name = &self.gen.trappable_errors[&err];
1792             let err = &self.resolve.types[resolve_type_definition_id(self.resolve, err)];
1793             let err_name = err.name.as_ref().unwrap();
1794             let err_snake = err_name.to_snake_case();
1795             let err_camel = err_name.to_upper_camel_case();
1796             let owner = match err.owner {
1797                 TypeOwner::Interface(i) => i,
1798                 _ => unimplemented!(),
1799             };
1800             match self.path_to_interface(owner) {
1801                 Some(path) => {
1802                     required_conversion_traits.insert(format!("{path}::Host"));
1803                 }
1804                 None => {
1805                     if errors_converted.insert(err_name) {
1806                         let root = self.path_to_root();
1807                         uwriteln!(
1808                             self.src,
1809                             "fn convert_{err_snake}(&mut self, err: {root}{custom_name}) -> wasmtime::Result<{err_camel}>;"
1810                         );
1811                     }
1812                 }
1813             }
1814         }
1815         uwriteln!(self.src, "}}");
1816 
1817         let mut where_clause = if self.gen.opts.async_.maybe_async() {
1818             "T: Send, U: Host + Send".to_string()
1819         } else {
1820             "U: Host".to_string()
1821         };
1822 
1823         for t in required_conversion_traits {
1824             where_clause.push_str(" + ");
1825             where_clause.push_str(&t);
1826         }
1827 
1828         uwriteln!(
1829             self.src,
1830             "
1831                 pub fn add_to_linker<T, U>(
1832                     linker: &mut wasmtime::component::Linker<T>,
1833                     get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static,
1834                 ) -> wasmtime::Result<()>
1835                     where {where_clause}
1836                 {{
1837             "
1838         );
1839         uwriteln!(self.src, "let mut inst = linker.instance(\"{name}\")?;");
1840 
1841         for name in get_resources(self.resolve, id) {
1842             let camel = name.to_upper_camel_case();
1843             uwriteln!(
1844                 self.src,
1845                 "inst.resource(
1846                     \"{name}\",
1847                     wasmtime::component::ResourceType::host::<{camel}>(),
1848                     move |mut store, rep| -> wasmtime::Result<()> {{
1849                         Host{camel}::drop(get(store.data_mut()), wasmtime::component::Resource::new_own(rep))
1850                     }},
1851                 )?;"
1852             )
1853         }
1854 
1855         for (_, func) in iface.functions.iter() {
1856             self.generate_add_function_to_linker(owner, func, "inst");
1857         }
1858         uwriteln!(self.src, "Ok(())");
1859         uwriteln!(self.src, "}}");
1860     }
1861 
1862     fn generate_add_function_to_linker(&mut self, owner: TypeOwner, func: &Function, linker: &str) {
1863         uwrite!(
1864             self.src,
1865             "{linker}.{}(\"{}\", ",
1866             if self.gen.opts.async_.is_import_async(&func.name) {
1867                 "func_wrap_async"
1868             } else {
1869                 "func_wrap"
1870             },
1871             func.name
1872         );
1873         self.generate_guest_import_closure(owner, func);
1874         uwriteln!(self.src, ")?;")
1875     }
1876 
1877     fn generate_guest_import_closure(&mut self, owner: TypeOwner, func: &Function) {
1878         // Generate the closure that's passed to a `Linker`, the final piece of
1879         // codegen here.
1880 
1881         self.src
1882             .push_str("move |mut caller: wasmtime::StoreContextMut<'_, T>, (");
1883         for (i, _param) in func.params.iter().enumerate() {
1884             uwrite!(self.src, "arg{},", i);
1885         }
1886         self.src.push_str(") : (");
1887 
1888         for (_, ty) in func.params.iter() {
1889             // Lift is required to be impled for this type, so we can't use
1890             // a borrowed type:
1891             self.print_ty(ty, TypeMode::Owned);
1892             self.src.push_str(", ");
1893         }
1894         self.src.push_str(") |");
1895         if self.gen.opts.async_.is_import_async(&func.name) {
1896             self.src
1897                 .push_str(" wasmtime::component::__internal::Box::new(async move { \n");
1898         } else {
1899             self.src.push_str(" { \n");
1900         }
1901 
1902         if self.gen.opts.tracing {
1903             uwrite!(
1904                 self.src,
1905                 "
1906                    let span = tracing::span!(
1907                        tracing::Level::TRACE,
1908                        \"wit-bindgen import\",
1909                        module = \"{}\",
1910                        function = \"{}\",
1911                    );
1912                    let _enter = span.enter();
1913                ",
1914                 match owner {
1915                     TypeOwner::Interface(id) => self.resolve.interfaces[id]
1916                         .name
1917                         .as_deref()
1918                         .unwrap_or("<no module>"),
1919                     TypeOwner::World(id) => &self.resolve.worlds[id].name,
1920                     TypeOwner::None => "<no owner>",
1921                 },
1922                 func.name,
1923             );
1924             let mut event_fields = func
1925                 .params
1926                 .iter()
1927                 .enumerate()
1928                 .map(|(i, (name, _ty))| {
1929                     let name = to_rust_ident(&name);
1930                     format!("{name} = tracing::field::debug(&arg{i})")
1931                 })
1932                 .collect::<Vec<String>>();
1933             event_fields.push(format!("\"call\""));
1934             uwrite!(
1935                 self.src,
1936                 "tracing::event!(tracing::Level::TRACE, {});\n",
1937                 event_fields.join(", ")
1938             );
1939         }
1940 
1941         self.src.push_str("let host = get(caller.data_mut());\n");
1942         let func_name = rust_function_name(func);
1943         let host_trait = match func.kind {
1944             FunctionKind::Freestanding => match owner {
1945                 TypeOwner::World(id) => format!(
1946                     "{}Imports",
1947                     self.resolve.worlds[id].name.to_upper_camel_case()
1948                 ),
1949                 _ => "Host".to_string(),
1950             },
1951             FunctionKind::Method(id) | FunctionKind::Static(id) | FunctionKind::Constructor(id) => {
1952                 let resource = self.resolve.types[id]
1953                     .name
1954                     .as_ref()
1955                     .unwrap()
1956                     .to_upper_camel_case();
1957                 format!("Host{resource}")
1958             }
1959         };
1960         uwrite!(self.src, "let r = {host_trait}::{func_name}(host, ");
1961 
1962         for (i, _) in func.params.iter().enumerate() {
1963             uwrite!(self.src, "arg{},", i);
1964         }
1965         if self.gen.opts.async_.is_import_async(&func.name) {
1966             uwrite!(self.src, ").await;\n");
1967         } else {
1968             uwrite!(self.src, ");\n");
1969         }
1970 
1971         if self.gen.opts.tracing {
1972             uwrite!(
1973                 self.src,
1974                 "tracing::event!(tracing::Level::TRACE, result = tracing::field::debug(&r), \"return\");"
1975             );
1976         }
1977 
1978         if !self.gen.opts.trappable_imports.can_trap(&func) {
1979             if func.results.iter_types().len() == 1 {
1980                 uwrite!(self.src, "Ok((r,))\n");
1981             } else {
1982                 uwrite!(self.src, "Ok(r)\n");
1983             }
1984         } else if let Some((_, err, _)) = self.special_case_trappable_error(&func.results) {
1985             let err = &self.resolve.types[resolve_type_definition_id(self.resolve, err)];
1986             let err_name = err.name.as_ref().unwrap();
1987             let owner = match err.owner {
1988                 TypeOwner::Interface(i) => i,
1989                 _ => unimplemented!(),
1990             };
1991             let convert_trait = match self.path_to_interface(owner) {
1992                 Some(path) => format!("{path}::Host"),
1993                 None => format!("Host"),
1994             };
1995             let convert = format!("{}::convert_{}", convert_trait, err_name.to_snake_case());
1996             uwrite!(
1997                 self.src,
1998                 "Ok((match r {{
1999                     Ok(a) => Ok(a),
2000                     Err(e) => Err({convert}(host, e)?),
2001                 }},))"
2002             );
2003         } else if func.results.iter_types().len() == 1 {
2004             uwrite!(self.src, "Ok((r?,))\n");
2005         } else {
2006             uwrite!(self.src, "r\n");
2007         }
2008 
2009         if self.gen.opts.async_.is_import_async(&func.name) {
2010             // Need to close Box::new and async block
2011             self.src.push_str("})");
2012         } else {
2013             self.src.push_str("}");
2014         }
2015     }
2016 
2017     fn generate_function_trait_sig(&mut self, func: &Function) {
2018         self.rustdoc(&func.docs);
2019 
2020         if self.gen.opts.async_.is_import_async(&func.name) {
2021             self.push_str("async ");
2022         }
2023         self.push_str("fn ");
2024         self.push_str(&rust_function_name(func));
2025         self.push_str("(&mut self, ");
2026         for (name, param) in func.params.iter() {
2027             let name = to_rust_ident(name);
2028             self.push_str(&name);
2029             self.push_str(": ");
2030             self.print_ty(param, TypeMode::Owned);
2031             self.push_str(",");
2032         }
2033         self.push_str(")");
2034         self.push_str(" -> ");
2035 
2036         if !self.gen.opts.trappable_imports.can_trap(func) {
2037             self.print_result_ty(&func.results, TypeMode::Owned);
2038         } else if let Some((r, _id, error_typename)) =
2039             self.special_case_trappable_error(&func.results)
2040         {
2041             // Functions which have a single result `result<ok,err>` get special
2042             // cased to use the host_wasmtime_rust::Error<err>, making it possible
2043             // for them to trap or use `?` to propogate their errors
2044             self.push_str("Result<");
2045             if let Some(ok) = r.ok {
2046                 self.print_ty(&ok, TypeMode::Owned);
2047             } else {
2048                 self.push_str("()");
2049             }
2050             self.push_str(",");
2051             self.push_str(&error_typename);
2052             self.push_str(">");
2053         } else {
2054             // All other functions get their return values wrapped in an wasmtime::Result.
2055             // Returning the anyhow::Error case can be used to trap.
2056             self.push_str("wasmtime::Result<");
2057             self.print_result_ty(&func.results, TypeMode::Owned);
2058             self.push_str(">");
2059         }
2060 
2061         self.push_str(";\n");
2062     }
2063 
2064     fn extract_typed_function(&mut self, func: &Function) -> (String, String) {
2065         let prev = mem::take(&mut self.src);
2066         let snake = func_field_name(self.resolve, func);
2067         uwrite!(self.src, "*__exports.typed_func::<(");
2068         for (_, ty) in func.params.iter() {
2069             self.print_ty(ty, TypeMode::AllBorrowed("'_"));
2070             self.push_str(", ");
2071         }
2072         self.src.push_str("), (");
2073         for ty in func.results.iter_types() {
2074             self.print_ty(ty, TypeMode::Owned);
2075             self.push_str(", ");
2076         }
2077         self.src.push_str(")>(\"");
2078         self.src.push_str(&func.name);
2079         self.src.push_str("\")?.func()");
2080 
2081         let ret = (snake, mem::take(&mut self.src).to_string());
2082         self.src = prev;
2083         ret
2084     }
2085 
2086     fn define_rust_guest_export(
2087         &mut self,
2088         resolve: &Resolve,
2089         ns: Option<&WorldKey>,
2090         func: &Function,
2091     ) {
2092         // Exports must be async if anything could be async, it's just imports
2093         // that get to be optionally async/sync.
2094         let is_async = self.gen.opts.async_.maybe_async();
2095 
2096         let (async_, async__, await_) = if is_async {
2097             ("async", "_async", ".await")
2098         } else {
2099             ("", "", "")
2100         };
2101 
2102         self.rustdoc(&func.docs);
2103 
2104         uwrite!(
2105             self.src,
2106             "pub {async_} fn call_{}<S: wasmtime::AsContextMut>(&self, mut store: S, ",
2107             func.item_name().to_snake_case(),
2108         );
2109 
2110         for (i, param) in func.params.iter().enumerate() {
2111             uwrite!(self.src, "arg{}: ", i);
2112             self.print_ty(&param.1, TypeMode::AllBorrowed("'_"));
2113             self.push_str(",");
2114         }
2115 
2116         self.src.push_str(") -> wasmtime::Result<");
2117         self.print_result_ty(&func.results, TypeMode::Owned);
2118 
2119         if is_async {
2120             self.src
2121                 .push_str("> where <S as wasmtime::AsContext>::Data: Send {\n");
2122         } else {
2123             self.src.push_str("> {\n");
2124         }
2125 
2126         if self.gen.opts.tracing {
2127             let ns = match ns {
2128                 Some(key) => resolve.name_world_key(key),
2129                 None => "default".to_string(),
2130             };
2131             self.src.push_str(&format!(
2132                 "
2133                    let span = tracing::span!(
2134                        tracing::Level::TRACE,
2135                        \"wit-bindgen export\",
2136                        module = \"{ns}\",
2137                        function = \"{}\",
2138                    );
2139                    let _enter = span.enter();
2140                ",
2141                 func.name,
2142             ));
2143         }
2144 
2145         self.src.push_str("let callee = unsafe {\n");
2146         self.src.push_str("wasmtime::component::TypedFunc::<(");
2147         for (_, ty) in func.params.iter() {
2148             self.print_ty(ty, TypeMode::AllBorrowed("'_"));
2149             self.push_str(", ");
2150         }
2151         self.src.push_str("), (");
2152         for ty in func.results.iter_types() {
2153             self.print_ty(ty, TypeMode::Owned);
2154             self.push_str(", ");
2155         }
2156         let projection_to_func = match &func.kind {
2157             FunctionKind::Freestanding => "",
2158             _ => ".funcs",
2159         };
2160         uwriteln!(
2161             self.src,
2162             ")>::new_unchecked(self{projection_to_func}.{})",
2163             func_field_name(self.resolve, func),
2164         );
2165         self.src.push_str("};\n");
2166         self.src.push_str("let (");
2167         for (i, _) in func.results.iter_types().enumerate() {
2168             uwrite!(self.src, "ret{},", i);
2169         }
2170         uwrite!(
2171             self.src,
2172             ") = callee.call{async__}(store.as_context_mut(), ("
2173         );
2174         for (i, _) in func.params.iter().enumerate() {
2175             uwrite!(self.src, "arg{}, ", i);
2176         }
2177         uwriteln!(self.src, ")){await_}?;");
2178 
2179         uwriteln!(
2180             self.src,
2181             "callee.post_return{async__}(store.as_context_mut()){await_}?;"
2182         );
2183 
2184         self.src.push_str("Ok(");
2185         if func.results.iter_types().len() == 1 {
2186             self.src.push_str("ret0");
2187         } else {
2188             self.src.push_str("(");
2189             for (i, _) in func.results.iter_types().enumerate() {
2190                 uwrite!(self.src, "ret{},", i);
2191             }
2192             self.src.push_str(")");
2193         }
2194         self.src.push_str(")\n");
2195 
2196         // End function body
2197         self.src.push_str("}\n");
2198     }
2199 
2200     fn rustdoc(&mut self, docs: &Docs) {
2201         let docs = match &docs.contents {
2202             Some(docs) => docs,
2203             None => return,
2204         };
2205         for line in docs.trim().lines() {
2206             self.push_str("/// ");
2207             self.push_str(line);
2208             self.push_str("\n");
2209         }
2210     }
2211 
2212     fn path_to_root(&self) -> String {
2213         let mut path_to_root = String::new();
2214         if let Some((_, key, is_export)) = self.current_interface {
2215             match key {
2216                 WorldKey::Name(_) => {
2217                     path_to_root.push_str("super::");
2218                 }
2219                 WorldKey::Interface(_) => {
2220                     path_to_root.push_str("super::super::super::");
2221                 }
2222             }
2223             if is_export {
2224                 path_to_root.push_str("super::");
2225             }
2226         }
2227         path_to_root
2228     }
2229 }
2230 
2231 impl<'a> RustGenerator<'a> for InterfaceGenerator<'a> {
2232     fn resolve(&self) -> &'a Resolve {
2233         self.resolve
2234     }
2235 
2236     fn ownership(&self) -> Ownership {
2237         self.gen.opts.ownership
2238     }
2239 
2240     fn path_to_interface(&self, interface: InterfaceId) -> Option<String> {
2241         if let Some((cur, _, _)) = self.current_interface {
2242             if cur == interface {
2243                 return None;
2244             }
2245         }
2246         let mut path_to_root = self.path_to_root();
2247         match &self.gen.interface_names[&interface] {
2248             InterfaceName::Remapped { name_at_root, .. } => path_to_root.push_str(name_at_root),
2249             InterfaceName::Path(path) => {
2250                 for (i, name) in path.iter().enumerate() {
2251                     if i > 0 {
2252                         path_to_root.push_str("::");
2253                     }
2254                     path_to_root.push_str(name);
2255                 }
2256             }
2257         }
2258         Some(path_to_root)
2259     }
2260 
2261     fn push_str(&mut self, s: &str) {
2262         self.src.push_str(s);
2263     }
2264 
2265     fn info(&self, ty: TypeId) -> TypeInfo {
2266         self.gen.types.get(ty)
2267     }
2268 
2269     fn is_imported_interface(&self, interface: InterfaceId) -> bool {
2270         self.gen.interface_last_seen_as_import[&interface]
2271     }
2272 }
2273 
2274 /// When an interface `use`s a type from another interface, it creates a new TypeId
2275 /// referring to the definition TypeId. Chase this chain of references down to
2276 /// a TypeId for type's definition.
2277 fn resolve_type_definition_id(resolve: &Resolve, mut id: TypeId) -> TypeId {
2278     loop {
2279         match resolve.types[id].kind {
2280             TypeDefKind::Type(Type::Id(def_id)) => id = def_id,
2281             _ => return id,
2282         }
2283     }
2284 }
2285 
2286 fn rust_function_name(func: &Function) -> String {
2287     match func.kind {
2288         FunctionKind::Method(_) | FunctionKind::Static(_) => to_rust_ident(func.item_name()),
2289         FunctionKind::Constructor(_) => "new".to_string(),
2290         FunctionKind::Freestanding => to_rust_ident(&func.name),
2291     }
2292 }
2293 
2294 fn func_field_name(resolve: &Resolve, func: &Function) -> String {
2295     let mut name = String::new();
2296     match func.kind {
2297         FunctionKind::Method(id) => {
2298             name.push_str("method-");
2299             name.push_str(resolve.types[id].name.as_ref().unwrap());
2300             name.push_str("-");
2301         }
2302         FunctionKind::Static(id) => {
2303             name.push_str("static-");
2304             name.push_str(resolve.types[id].name.as_ref().unwrap());
2305             name.push_str("-");
2306         }
2307         FunctionKind::Constructor(id) => {
2308             name.push_str("constructor-");
2309             name.push_str(resolve.types[id].name.as_ref().unwrap());
2310             name.push_str("-");
2311         }
2312         FunctionKind::Freestanding => {}
2313     }
2314     name.push_str(func.item_name());
2315     name.to_snake_case()
2316 }
2317 
2318 fn get_resources<'a>(resolve: &'a Resolve, id: InterfaceId) -> impl Iterator<Item = &'a str> + 'a {
2319     resolve.interfaces[id]
2320         .types
2321         .iter()
2322         .filter_map(move |(name, ty)| match resolve.types[*ty].kind {
2323             TypeDefKind::Resource => Some(name.as_str()),
2324             _ => None,
2325         })
2326 }
2327 
2328 fn get_world_resources<'a>(
2329     resolve: &'a Resolve,
2330     id: WorldId,
2331 ) -> impl Iterator<Item = &'a str> + 'a {
2332     resolve.worlds[id]
2333         .imports
2334         .iter()
2335         .filter_map(move |(name, item)| match item {
2336             WorldItem::Type(id) => match resolve.types[*id].kind {
2337                 TypeDefKind::Resource => Some(match name {
2338                     WorldKey::Name(s) => s.as_str(),
2339                     WorldKey::Interface(_) => unreachable!(),
2340                 }),
2341                 _ => None,
2342             },
2343             _ => None,
2344         })
2345 }
2346