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