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