wit_bindgen_rust/
lib.rs

1use crate::interface::InterfaceGenerator;
2use anyhow::{Result, bail};
3use core::panic;
4use heck::*;
5use indexmap::{IndexMap, IndexSet};
6use std::collections::{BTreeMap, HashMap, HashSet};
7use std::fmt::{self, Write as _};
8use std::mem;
9use std::path::{Path, PathBuf};
10use std::str::FromStr;
11use wit_bindgen_core::abi::{Bitcast, WasmType};
12use wit_bindgen_core::{
13    AsyncFilterSet, Files, InterfaceGenerator as _, Source, Types, WorldGenerator, dealias,
14    name_package_module, uwrite, uwriteln, wit_parser::*,
15};
16
17mod bindgen;
18mod interface;
19
20struct InterfaceName {
21    /// True when this interface name has been remapped through the use of `with` in the `bindgen!`
22    /// macro invocation.
23    remapped: bool,
24
25    /// The string name for this interface.
26    path: String,
27}
28
29#[derive(Default)]
30pub struct RustWasm {
31    types: Types,
32    src_preamble: Source,
33    src: Source,
34    opts: Opts,
35    import_modules: Vec<(String, Vec<String>)>,
36    export_modules: Vec<(String, Vec<String>)>,
37    skip: HashSet<String>,
38    interface_names: HashMap<InterfaceId, InterfaceName>,
39    /// Each imported and exported interface is stored in this map. Value indicates if last use was import.
40    interface_last_seen_as_import: HashMap<InterfaceId, bool>,
41    import_funcs_called: bool,
42    with_name_counter: usize,
43    // Track which interfaces and types are generated. Remapped interfaces and types provided via `with`
44    // are required to be used.
45    generated_types: HashSet<String>,
46    world: Option<WorldId>,
47
48    rt_module: IndexSet<RuntimeItem>,
49    export_macros: Vec<(String, String)>,
50
51    /// Maps wit interface and type names to their Rust identifiers
52    with: GenerationConfiguration,
53
54    future_payloads: IndexMap<String, String>,
55    stream_payloads: IndexMap<String, String>,
56}
57
58#[derive(Default)]
59struct GenerationConfiguration {
60    map: HashMap<String, TypeGeneration>,
61    generate_by_default: bool,
62}
63
64impl GenerationConfiguration {
65    fn get(&self, key: &str) -> Option<&TypeGeneration> {
66        self.map.get(key).or_else(|| {
67            self.generate_by_default
68                .then_some(&TypeGeneration::Generate)
69        })
70    }
71
72    fn insert(&mut self, name: String, generate: TypeGeneration) {
73        self.map.insert(name, generate);
74    }
75
76    fn iter(&self) -> impl Iterator<Item = (&String, &TypeGeneration)> {
77        self.map.iter()
78    }
79}
80
81/// How a wit interface or type should be rendered in Rust
82enum TypeGeneration {
83    /// Uses a Rust identifier defined elsewhere
84    Remap(String),
85    /// Define the interface or type with this bindgen invocation
86    Generate,
87}
88
89impl TypeGeneration {
90    /// Returns true if the interface or type should be defined with this bindgen invocation
91    fn generated(&self) -> bool {
92        match self {
93            TypeGeneration::Generate => true,
94            TypeGeneration::Remap(_) => false,
95        }
96    }
97}
98
99#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
100enum RuntimeItem {
101    AllocCrate,
102    StringType,
103    StdAllocModule,
104    VecType,
105    StringLift,
106    InvalidEnumDiscriminant,
107    CharLift,
108    BoolLift,
109    CabiDealloc,
110    RunCtorsOnce,
111    AsI32,
112    AsI64,
113    AsF32,
114    AsF64,
115    ResourceType,
116    BoxType,
117}
118
119#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
120#[cfg_attr(
121    feature = "serde",
122    derive(serde::Deserialize),
123    serde(rename_all = "kebab-case")
124)]
125pub enum ExportKey {
126    World,
127    Name(String),
128}
129
130#[cfg(feature = "clap")]
131fn parse_with(s: &str) -> Result<(String, WithOption), String> {
132    let (k, v) = s.split_once('=').ok_or_else(|| {
133        format!("expected string of form `<key>=<value>[,<key>=<value>...]`; got `{s}`")
134    })?;
135    let v = match v {
136        "generate" => WithOption::Generate,
137        other => WithOption::Path(other.to_string()),
138    };
139    Ok((k.to_string(), v))
140}
141
142#[derive(Default, Debug, Clone)]
143#[cfg_attr(feature = "clap", derive(clap::Parser))]
144#[cfg_attr(
145    feature = "serde",
146    derive(serde::Deserialize),
147    serde(default, rename_all = "kebab-case")
148)]
149pub struct Opts {
150    /// Whether or not a formatter is executed to format generated code.
151    #[cfg_attr(feature = "clap", arg(long))]
152    pub format: bool,
153
154    /// If true, code generation should qualify any features that depend on
155    /// `std` with `cfg(feature = "std")`.
156    #[cfg_attr(feature = "clap", arg(long))]
157    pub std_feature: bool,
158
159    /// If true, code generation should pass borrowed string arguments as
160    /// `&[u8]` instead of `&str`. Strings are still required to be valid
161    /// UTF-8, but this avoids the need for Rust code to do its own UTF-8
162    /// validation if it doesn't already have a `&str`.
163    #[cfg_attr(feature = "clap", arg(long))]
164    pub raw_strings: bool,
165
166    /// Names of functions to skip generating bindings for.
167    #[cfg_attr(feature = "clap", arg(long, value_name = "NAME"))]
168    pub skip: Vec<String>,
169
170    /// If true, generate stub implementations for any exported functions,
171    /// interfaces, and/or resources.
172    #[cfg_attr(feature = "clap", arg(long))]
173    pub stubs: bool,
174
175    /// Optionally prefix any export names with the specified value.
176    ///
177    /// This is useful to avoid name conflicts when testing.
178    #[cfg_attr(feature = "clap", arg(long, value_name = "STRING"))]
179    pub export_prefix: Option<String>,
180
181    /// Whether to generate owning or borrowing type definitions.
182    ///
183    /// Valid values include:
184    ///
185    /// - `owning`: Generated types will be composed entirely of owning fields,
186    /// regardless of whether they are used as parameters to imports or not.
187    ///
188    /// - `borrowing`: Generated types used as parameters to imports will be
189    /// "deeply borrowing", i.e. contain references rather than owned values
190    /// when applicable.
191    ///
192    /// - `borrowing-duplicate-if-necessary`: As above, but generating distinct
193    /// types for borrowing and owning, if necessary.
194    #[cfg_attr(feature = "clap", arg(long, default_value_t = Ownership::Owning))]
195    pub ownership: Ownership,
196
197    /// The optional path to the wit-bindgen runtime module to use.
198    ///
199    /// This defaults to `wit_bindgen::rt`.
200    #[cfg_attr(feature = "clap", arg(long, value_name = "PATH"))]
201    pub runtime_path: Option<String>,
202
203    /// The optional path to the bitflags crate to use.
204    ///
205    /// This defaults to `wit_bindgen::bitflags`.
206    #[cfg_attr(feature = "clap", arg(long))]
207    pub bitflags_path: Option<String>,
208
209    /// Additional derive attributes to add to generated types. If using in a CLI, this flag can be
210    /// specified multiple times to add multiple attributes.
211    ///
212    /// These derive attributes will be added to any generated structs or enums
213    #[cfg_attr(feature = "clap", arg(long, short = 'd', value_name = "DERIVE"))]
214    pub additional_derive_attributes: Vec<String>,
215
216    /// Variants and records to ignore when applying additional derive attributes.
217    ///
218    /// These names are specified as they are listed in the wit file, i.e. in kebab case.
219    /// This feature allows some variants and records to use types for which adding traits will cause
220    /// compilation to fail, such as serde::Deserialize on wasi:io/streams.
221    ///
222    #[cfg_attr(feature = "clap", arg(long, value_name = "NAME"))]
223    pub additional_derive_ignore: Vec<String>,
224
225    /// Remapping of wit import interface and type names to Rust module names
226    /// and types.
227    ///
228    /// Argument must be of the form `k=v` and this option can be passed
229    /// multiple times or one option can be comma separated, for example
230    /// `k1=v1,k2=v2`.
231    #[cfg_attr(feature = "clap", arg(long, value_parser = parse_with, value_delimiter = ','))]
232    pub with: Vec<(String, WithOption)>,
233
234    /// Indicates that all interfaces not specified in `with` should be
235    /// generated.
236    #[cfg_attr(feature = "clap", arg(long))]
237    pub generate_all: bool,
238
239    /// Add the specified suffix to the name of the custome section containing
240    /// the component type.
241    #[cfg_attr(feature = "clap", arg(long, value_name = "STRING"))]
242    pub type_section_suffix: Option<String>,
243
244    /// Disable a workaround used to prevent libc ctors/dtors from being invoked
245    /// too much.
246    #[cfg_attr(feature = "clap", arg(long))]
247    pub disable_run_ctors_once_workaround: bool,
248
249    /// Changes the default module used in the generated `export!` macro to
250    /// something other than `self`.
251    #[cfg_attr(feature = "clap", arg(long, value_name = "NAME"))]
252    pub default_bindings_module: Option<String>,
253
254    /// Alternative name to use for the `export!` macro if one is generated.
255    #[cfg_attr(feature = "clap", arg(long, value_name = "NAME"))]
256    pub export_macro_name: Option<String>,
257
258    /// Ensures that the `export!` macro will be defined as `pub` so it is a
259    /// candidate for being exported outside of the crate.
260    #[cfg_attr(feature = "clap", arg(long))]
261    pub pub_export_macro: bool,
262
263    /// Whether to generate unused structures, not generated by default (false)
264    #[cfg_attr(feature = "clap", arg(long))]
265    pub generate_unused_types: bool,
266
267    /// Whether or not to generate helper function/constants to help link custom
268    /// sections into the final output.
269    ///
270    /// Disabling this can shave a few bytes off a binary but makes
271    /// library-based usage of `generate!` prone to breakage.
272    #[cfg_attr(feature = "clap", arg(long))]
273    pub disable_custom_section_link_helpers: bool,
274
275    #[cfg_attr(feature = "clap", clap(flatten))]
276    #[cfg_attr(feature = "serde", serde(flatten))]
277    pub async_: AsyncFilterSet,
278}
279
280impl Opts {
281    pub fn build(self) -> RustWasm {
282        let mut r = RustWasm::new();
283        r.skip = self.skip.iter().cloned().collect();
284        r.opts = self;
285        r
286    }
287}
288
289impl RustWasm {
290    /// Generates Rust bindings from the `wit/` directory and writes
291    /// the result into Cargo’s `OUT_DIR`. Intended for use in `build.rs`.
292    ///
293    /// The `world` parameter specifies the world name to select.
294    /// It must be provided unless the main package contains exactly one world.
295    ///
296    /// Returns the full path to the generated bindings file.
297    pub fn generate_to_out_dir(mut self, world: Option<&str>) -> Result<PathBuf> {
298        let mut resolve = Resolve::default();
299        println!("cargo:rerun-if-changed=wit/");
300        let (pkg, _files) = resolve.push_path("wit")?;
301        let main_packages = vec![pkg];
302        let world = resolve.select_world(&main_packages, world)?;
303
304        let mut files = Files::default();
305        self.generate(&resolve, world, &mut files)?;
306        let out_dir = std::env::var("OUT_DIR").expect("cargo sets OUT_DIR");
307        let (name, contents) = files
308            .iter()
309            .next()
310            .expect("exactly one file should be generated");
311        let dst = Path::new(&out_dir).join(name);
312        std::fs::write(&dst, contents)?;
313        Ok(dst)
314    }
315
316    fn new() -> RustWasm {
317        RustWasm::default()
318    }
319
320    fn interface<'a>(
321        &'a mut self,
322        identifier: Identifier<'a>,
323        wasm_import_module: &'a str,
324        resolve: &'a Resolve,
325        in_import: bool,
326    ) -> InterfaceGenerator<'a> {
327        let mut sizes = SizeAlign::default();
328        sizes.fill(resolve);
329
330        InterfaceGenerator {
331            identifier,
332            wasm_import_module,
333            src: Source::default(),
334            in_import,
335            r#gen: self,
336            sizes,
337            resolve,
338            return_pointer_area_size: Default::default(),
339            return_pointer_area_align: Default::default(),
340            needs_runtime_module: false,
341        }
342    }
343
344    fn emit_modules(&mut self, modules: Vec<(String, Vec<String>)>) {
345        #[derive(Default)]
346        struct Module {
347            submodules: BTreeMap<String, Module>,
348            contents: Vec<String>,
349        }
350        let mut map = Module::default();
351        for (module, path) in modules {
352            let mut cur = &mut map;
353            for name in path[..path.len() - 1].iter() {
354                cur = cur
355                    .submodules
356                    .entry(name.clone())
357                    .or_insert(Module::default());
358            }
359            cur.contents.push(module);
360        }
361
362        emit(&mut self.src, map, &self.opts, true);
363        fn emit(me: &mut Source, module: Module, opts: &Opts, toplevel: bool) {
364            for (name, submodule) in module.submodules {
365                if toplevel {
366                    // Disable rustfmt. By default we already format the code
367                    // using prettyplease, so we don't want `cargo fmt` to create
368                    // extra diffs for users to deal with.
369                    if opts.format {
370                        uwriteln!(me, "#[rustfmt::skip]");
371                    }
372
373                    // Ignore dead-code and clippy warnings. If the bindings are
374                    // only used within a crate, and not exported to a different
375                    // crate, some parts may be unused, and that's ok.
376                    uwriteln!(me, "#[allow(dead_code, clippy::all)]");
377                }
378
379                uwriteln!(me, "pub mod {name} {{");
380                emit(me, submodule, opts, false);
381                uwriteln!(me, "}}");
382            }
383            for submodule in module.contents {
384                uwriteln!(me, "{submodule}");
385            }
386        }
387    }
388
389    fn runtime_path(&self) -> &str {
390        self.opts
391            .runtime_path
392            .as_deref()
393            .unwrap_or("wit_bindgen::rt")
394    }
395
396    fn bitflags_path(&self) -> String {
397        self.opts
398            .bitflags_path
399            .to_owned()
400            .unwrap_or(format!("{}::bitflags", self.runtime_path()))
401    }
402
403    fn async_support_path(&self) -> String {
404        format!("{}::async_support", self.runtime_path())
405    }
406
407    fn name_interface(
408        &mut self,
409        resolve: &Resolve,
410        id: InterfaceId,
411        name: &WorldKey,
412        is_export: bool,
413    ) -> Result<bool> {
414        let with_name = resolve.name_world_key(name);
415        let remapping = if is_export {
416            &TypeGeneration::Generate
417        } else {
418            match self.with.get(&with_name) {
419                Some(remapping) => remapping,
420                None => bail!(MissingWith(with_name)),
421            }
422        };
423        self.generated_types.insert(with_name);
424        let entry = match remapping {
425            TypeGeneration::Remap(remapped_path) => {
426                let name = format!("__with_name{}", self.with_name_counter);
427                self.with_name_counter += 1;
428                uwriteln!(
429                    self.src,
430                    "#[allow(unfulfilled_lint_expectations, unused_imports)]"
431                );
432                uwriteln!(self.src, "use {remapped_path} as {name};");
433                InterfaceName {
434                    remapped: true,
435                    path: name,
436                }
437            }
438            TypeGeneration::Generate => {
439                let path = compute_module_path(name, resolve, is_export).join("::");
440
441                InterfaceName {
442                    remapped: false,
443                    path,
444                }
445            }
446        };
447
448        let remapped = entry.remapped;
449        self.interface_names.insert(id, entry);
450
451        Ok(remapped)
452    }
453
454    fn finish_runtime_module(&mut self) {
455        if !self.rt_module.is_empty() {
456            // As above, disable rustfmt, as we use prettyplease.
457            if self.opts.format {
458                uwriteln!(self.src, "#[rustfmt::skip]");
459            }
460
461            self.src.push_str("mod _rt {\n");
462            self.src
463                .push_str("#![allow(dead_code, unused_imports, clippy::all)]\n");
464            let mut emitted = IndexSet::new();
465            while !self.rt_module.is_empty() {
466                for item in mem::take(&mut self.rt_module) {
467                    if emitted.insert(item) {
468                        self.emit_runtime_item(item);
469                    }
470                }
471            }
472            self.src.push_str("}\n");
473        }
474
475        if !self.future_payloads.is_empty() {
476            let async_support = self.async_support_path();
477            self.src.push_str(&format!(
478                "\
479pub mod wit_future {{
480    #![allow(dead_code, unused_variables, clippy::all)]
481
482    #[doc(hidden)]
483    pub trait FuturePayload: Unpin + Sized + 'static {{
484        const VTABLE: &'static {async_support}::FutureVtable<Self>;
485    }}"
486            ));
487            for code in self.future_payloads.values() {
488                self.src.push_str(code);
489            }
490            self.src.push_str(&format!(
491                "\
492    /// Creates a new Component Model `future` with the specified payload type.
493    ///
494    /// The `default` function provided computes the default value to be sent in
495    /// this future if no other value was otherwise sent.
496    pub fn new<T: FuturePayload>(default: fn() -> T) -> ({async_support}::FutureWriter<T>, {async_support}::FutureReader<T>) {{
497        unsafe {{ {async_support}::future_new::<T>(default, T::VTABLE) }}
498    }}
499}}
500                ",
501            ));
502        }
503
504        if !self.stream_payloads.is_empty() {
505            let async_support = self.async_support_path();
506            self.src.push_str(&format!(
507                "\
508pub mod wit_stream {{
509    #![allow(dead_code, unused_variables, clippy::all)]
510
511    pub trait StreamPayload: Unpin + Sized + 'static {{
512        const VTABLE: &'static {async_support}::StreamVtable<Self>;
513    }}"
514            ));
515            for code in self.stream_payloads.values() {
516                self.src.push_str(code);
517            }
518            self.src.push_str(
519                &format!("\
520    /// Creates a new Component Model `stream` with the specified payload type.
521    pub fn new<T: StreamPayload>() -> ({async_support}::StreamWriter<T>, {async_support}::StreamReader<T>) {{
522        unsafe {{ {async_support}::stream_new::<T>(T::VTABLE) }}
523    }}
524}}
525                "),
526            );
527        }
528    }
529
530    fn emit_runtime_item(&mut self, item: RuntimeItem) {
531        match item {
532            RuntimeItem::AllocCrate => {
533                uwriteln!(self.src, "extern crate alloc as alloc_crate;");
534            }
535            RuntimeItem::StdAllocModule => {
536                self.rt_module.insert(RuntimeItem::AllocCrate);
537                uwriteln!(self.src, "pub use alloc_crate::alloc;");
538            }
539            RuntimeItem::StringType => {
540                self.rt_module.insert(RuntimeItem::AllocCrate);
541                uwriteln!(self.src, "pub use alloc_crate::string::String;");
542            }
543            RuntimeItem::BoxType => {
544                self.rt_module.insert(RuntimeItem::AllocCrate);
545                uwriteln!(self.src, "pub use alloc_crate::boxed::Box;");
546            }
547            RuntimeItem::VecType => {
548                self.rt_module.insert(RuntimeItem::AllocCrate);
549                uwriteln!(self.src, "pub use alloc_crate::vec::Vec;");
550            }
551            RuntimeItem::CabiDealloc => {
552                self.rt_module.insert(RuntimeItem::StdAllocModule);
553                self.src.push_str(
554                    "\
555pub unsafe fn cabi_dealloc(ptr: *mut u8, size: usize, align: usize) {
556    if size == 0 {
557        return;
558    }
559    unsafe {
560        let layout = alloc::Layout::from_size_align_unchecked(size, align);
561        alloc::dealloc(ptr, layout);
562    }
563}
564                    ",
565                );
566            }
567
568            RuntimeItem::StringLift => {
569                self.rt_module.insert(RuntimeItem::StringType);
570                self.src.push_str(
571                    "\
572pub unsafe fn string_lift(bytes: Vec<u8>) -> String {
573    if cfg!(debug_assertions) {
574        String::from_utf8(bytes).unwrap()
575    } else {
576        unsafe { String::from_utf8_unchecked(bytes) }
577    }
578}
579                    ",
580                );
581            }
582
583            RuntimeItem::InvalidEnumDiscriminant => {
584                self.src.push_str(
585                    "\
586pub unsafe fn invalid_enum_discriminant<T>() -> T {
587    if cfg!(debug_assertions) {
588        panic!(\"invalid enum discriminant\")
589    } else {
590        unsafe { core::hint::unreachable_unchecked() }
591    }
592}
593                    ",
594                );
595            }
596
597            RuntimeItem::CharLift => {
598                self.src.push_str(
599                    "\
600pub unsafe fn char_lift(val: u32) -> char {
601    if cfg!(debug_assertions) {
602        core::char::from_u32(val).unwrap()
603    } else {
604        unsafe { core::char::from_u32_unchecked(val) }
605    }
606}
607                    ",
608                );
609            }
610
611            RuntimeItem::BoolLift => {
612                self.src.push_str(
613                    "\
614pub unsafe fn bool_lift(val: u8) -> bool {
615    if cfg!(debug_assertions) {
616        match val {
617            0 => false,
618            1 => true,
619            _ => panic!(\"invalid bool discriminant\"),
620        }
621    } else {
622        val != 0
623    }
624}
625                    ",
626                );
627            }
628
629            RuntimeItem::RunCtorsOnce => {
630                let rt = self.runtime_path();
631                self.src.push_str(&format!(
632                    r#"
633#[cfg(target_arch = "wasm32")]
634pub fn run_ctors_once() {{
635    {rt}::run_ctors_once();
636}}
637                    "#,
638                ));
639            }
640
641            RuntimeItem::AsI32 => {
642                self.emit_runtime_as_trait(
643                    "i32",
644                    &["i32", "u32", "i16", "u16", "i8", "u8", "char", "usize"],
645                );
646            }
647
648            RuntimeItem::AsI64 => {
649                self.emit_runtime_as_trait("i64", &["i64", "u64"]);
650            }
651
652            RuntimeItem::AsF32 => {
653                self.emit_runtime_as_trait("f32", &["f32"]);
654            }
655
656            RuntimeItem::AsF64 => {
657                self.emit_runtime_as_trait("f64", &["f64"]);
658            }
659
660            RuntimeItem::ResourceType => {
661                self.src.push_str(
662                    r#"
663
664use core::fmt;
665use core::marker;
666use core::sync::atomic::{AtomicU32, Ordering::Relaxed};
667
668/// A type which represents a component model resource, either imported or
669/// exported into this component.
670///
671/// This is a low-level wrapper which handles the lifetime of the resource
672/// (namely this has a destructor). The `T` provided defines the component model
673/// intrinsics that this wrapper uses.
674///
675/// One of the chief purposes of this type is to provide `Deref` implementations
676/// to access the underlying data when it is owned.
677///
678/// This type is primarily used in generated code for exported and imported
679/// resources.
680#[repr(transparent)]
681pub struct Resource<T: WasmResource> {
682    // NB: This would ideally be `u32` but it is not. The fact that this has
683    // interior mutability is not exposed in the API of this type except for the
684    // `take_handle` method which is supposed to in theory be private.
685    //
686    // This represents, almost all the time, a valid handle value. When it's
687    // invalid it's stored as `u32::MAX`.
688    handle: AtomicU32,
689    _marker: marker::PhantomData<T>,
690}
691
692/// A trait which all wasm resources implement, namely providing the ability to
693/// drop a resource.
694///
695/// This generally is implemented by generated code, not user-facing code.
696#[allow(clippy::missing_safety_doc)]
697pub unsafe trait WasmResource {
698    /// Invokes the `[resource-drop]...` intrinsic.
699    unsafe fn drop(handle: u32);
700}
701
702impl<T: WasmResource> Resource<T> {
703    #[doc(hidden)]
704    pub unsafe fn from_handle(handle: u32) -> Self {
705        debug_assert!(handle != 0 && handle != u32::MAX);
706        Self {
707            handle: AtomicU32::new(handle),
708            _marker: marker::PhantomData,
709        }
710    }
711
712    /// Takes ownership of the handle owned by `resource`.
713    ///
714    /// Note that this ideally would be `into_handle` taking `Resource<T>` by
715    /// ownership. The code generator does not enable that in all situations,
716    /// unfortunately, so this is provided instead.
717    ///
718    /// Also note that `take_handle` is in theory only ever called on values
719    /// owned by a generated function. For example a generated function might
720    /// take `Resource<T>` as an argument but then call `take_handle` on a
721    /// reference to that argument. In that sense the dynamic nature of
722    /// `take_handle` should only be exposed internally to generated code, not
723    /// to user code.
724    #[doc(hidden)]
725    pub fn take_handle(resource: &Resource<T>) -> u32 {
726        resource.handle.swap(u32::MAX, Relaxed)
727    }
728
729    #[doc(hidden)]
730    pub fn handle(resource: &Resource<T>) -> u32 {
731        resource.handle.load(Relaxed)
732    }
733}
734
735impl<T: WasmResource> fmt::Debug for Resource<T> {
736    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
737        f.debug_struct("Resource")
738            .field("handle", &self.handle)
739            .finish()
740    }
741}
742
743impl<T: WasmResource> Drop for Resource<T> {
744    fn drop(&mut self) {
745        unsafe {
746            match self.handle.load(Relaxed) {
747                // If this handle was "taken" then don't do anything in the
748                // destructor.
749                u32::MAX => {}
750
751                // ... but otherwise do actually destroy it with the imported
752                // component model intrinsic as defined through `T`.
753                other => T::drop(other),
754            }
755        }
756    }
757}
758                    "#,
759                );
760            }
761        }
762    }
763
764    // This is a workaround for in the bindings sometimes we've got `&i32` and
765    // sometimes we've got `i32` but that should all be able to be worked with
766    // as `i32`, so these helper functions are used to boil away the
767    // indirection.
768    fn emit_runtime_as_trait(&mut self, ty: &str, to_convert: &[&str]) {
769        let upcase = ty.to_uppercase();
770        self.src.push_str(&format!(
771            r#"
772pub fn as_{ty}<T: As{upcase}>(t: T) -> {ty} {{
773    t.as_{ty}()
774}}
775
776pub trait As{upcase} {{
777    fn as_{ty}(self) -> {ty};
778}}
779
780impl<'a, T: Copy + As{upcase}> As{upcase} for &'a T {{
781    fn as_{ty}(self) -> {ty} {{
782        (*self).as_{ty}()
783    }}
784}}
785            "#
786        ));
787
788        for to_convert in to_convert {
789            self.src.push_str(&format!(
790                r#"
791impl As{upcase} for {to_convert} {{
792    #[inline]
793    fn as_{ty}(self) -> {ty} {{
794        self as {ty}
795    }}
796}}
797                "#
798            ));
799        }
800    }
801
802    /// Generates an `export!` macro for the `world_id` specified.
803    ///
804    /// This will generate a macro which will then itself invoke all the
805    /// other macros collected in `self.export_macros` prior. All these macros
806    /// are woven together in this single invocation.
807    fn finish_export_macro(&mut self, resolve: &Resolve, world_id: WorldId) {
808        if self.export_macros.is_empty() {
809            return;
810        }
811        let world = &resolve.worlds[world_id];
812        let world_name = world.name.to_snake_case();
813
814        let default_bindings_module = self
815            .opts
816            .default_bindings_module
817            .clone()
818            .unwrap_or("self".to_string());
819        let (macro_export, use_vis) = if self.opts.pub_export_macro {
820            ("#[macro_export]", "pub")
821        } else {
822            ("", "pub(crate)")
823        };
824        let export_macro_name = self
825            .opts
826            .export_macro_name
827            .as_deref()
828            .unwrap_or("export")
829            .to_string();
830        uwriteln!(
831            self.src,
832            r#"
833/// Generates `#[unsafe(no_mangle)]` functions to export the specified type as
834/// the root implementation of all generated traits.
835///
836/// For more information see the documentation of `wit_bindgen::generate!`.
837///
838/// ```rust
839/// # macro_rules! {export_macro_name} {{ ($($t:tt)*) => (); }}
840/// # trait Guest {{}}
841/// struct MyType;
842///
843/// impl Guest for MyType {{
844///     // ...
845/// }}
846///
847/// {export_macro_name}!(MyType);
848/// ```
849#[allow(unused_macros)]
850#[doc(hidden)]
851{macro_export}
852macro_rules! __export_{world_name}_impl {{
853    ($ty:ident) => ({default_bindings_module}::{export_macro_name}!($ty with_types_in {default_bindings_module}););
854    ($ty:ident with_types_in $($path_to_types_root:tt)*) => ("#
855        );
856        for (name, path_to_types) in self.export_macros.iter() {
857            let mut path = "$($path_to_types_root)*".to_string();
858            if !path_to_types.is_empty() {
859                path.push_str("::");
860                path.push_str(path_to_types)
861            }
862            uwriteln!(self.src, "{path}::{name}!($ty with_types_in {path});");
863        }
864
865        // See comments in `finish` for why this conditionally happens here.
866        if self.opts.pub_export_macro {
867            uwriteln!(self.src, "const _: () = {{");
868            self.emit_custom_section(resolve, world_id, "imports and exports", None);
869            uwriteln!(self.src, "}};");
870        }
871
872        uwriteln!(self.src, ")\n}}");
873
874        uwriteln!(
875            self.src,
876            "#[doc(inline)]\n\
877            {use_vis} use __export_{world_name}_impl as {export_macro_name};"
878        );
879
880        if self.opts.stubs {
881            uwriteln!(self.src, "export!(Stub);");
882        }
883    }
884
885    /// Generates a `#[link_section]` custom section to get smuggled through
886    /// `wasm-ld`.
887    ///
888    /// This custom section is an encoding of the component metadata and will be
889    /// used as part of the `wit-component`-based componentization process.
890    ///
891    /// The `section_suffix` here is used to distinguish the multiple sections
892    /// that this generator emits, and `func_name` is an optional function to
893    /// generate next to this which is used to force rustc to at least visit
894    /// this `static` and codegen it.
895    fn emit_custom_section(
896        &mut self,
897        resolve: &Resolve,
898        world_id: WorldId,
899        section_suffix: &str,
900        func_name: Option<&str>,
901    ) {
902        // As above, disable rustfmt, as we use prettyplease.
903        if self.opts.format {
904            uwriteln!(self.src, "#[rustfmt::skip]");
905        }
906        self.src.push_str("\n#[cfg(target_arch = \"wasm32\")]\n");
907
908        // The custom section name here must start with "component-type" but
909        // otherwise is attempted to be unique here to ensure that this doesn't get
910        // concatenated to other custom sections by LLD by accident since LLD will
911        // concatenate custom sections of the same name.
912        let opts_suffix = self.opts.type_section_suffix.as_deref().unwrap_or("");
913        let world = &resolve.worlds[world_id];
914        let world_name = &world.name;
915        let pkg = &resolve.packages[world.package.unwrap()].name;
916        let version = env!("CARGO_PKG_VERSION");
917        self.src.push_str(&format!(
918            "#[unsafe(link_section = \"component-type:wit-bindgen:{version}:\
919             {pkg}:{world_name}:{section_suffix}{opts_suffix}\")]\n"
920        ));
921
922        let mut producers = wasm_metadata::Producers::empty();
923        producers.add(
924            "processed-by",
925            env!("CARGO_PKG_NAME"),
926            env!("CARGO_PKG_VERSION"),
927        );
928
929        let component_type = wit_component::metadata::encode(
930            resolve,
931            world_id,
932            wit_component::StringEncoding::UTF8,
933            Some(&producers),
934        )
935        .unwrap();
936
937        self.src.push_str("#[doc(hidden)]\n");
938        self.src.push_str("#[allow(clippy::octal_escapes)]\n");
939        self.src.push_str(&format!(
940            "pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; {}] = *b\"\\\n",
941            component_type.len()
942        ));
943        let old_indent = self.src.set_indent(0);
944        let mut line_length = 0;
945        let s = self.src.as_mut_string();
946        for byte in component_type.iter() {
947            if line_length >= 80 {
948                s.push_str("\\\n");
949                line_length = 0;
950            }
951            match byte {
952                b'\\' => {
953                    s.push_str("\\\\");
954                    line_length += 2;
955                }
956                b'"' => {
957                    s.push_str("\\\"");
958                    line_length += 2;
959                }
960                b if b.is_ascii_alphanumeric() || b.is_ascii_punctuation() => {
961                    s.push(char::from(*byte));
962                    line_length += 1;
963                }
964                0 => {
965                    s.push_str("\\0");
966                    line_length += 2;
967                }
968                _ => {
969                    uwrite!(s, "\\x{:02x}", byte);
970                    line_length += 4;
971                }
972            }
973        }
974
975        self.src.push_str("\";\n");
976        self.src.set_indent(old_indent);
977
978        if let Some(func_name) = func_name {
979            let rt = self.runtime_path().to_string();
980            uwriteln!(
981                self.src,
982                "
983                #[inline(never)]
984                #[doc(hidden)]
985                pub fn {func_name}() {{
986                    {rt}::maybe_link_cabi_realloc();
987                }}
988            ",
989            );
990        }
991    }
992
993    fn is_async(
994        &mut self,
995        resolve: &Resolve,
996        interface: Option<&WorldKey>,
997        func: &Function,
998        is_import: bool,
999    ) -> bool {
1000        self.opts
1001            .async_
1002            .is_async(resolve, interface, func, is_import)
1003    }
1004}
1005
1006impl WorldGenerator for RustWasm {
1007    fn preprocess(&mut self, resolve: &Resolve, world: WorldId) {
1008        wit_bindgen_core::generated_preamble(&mut self.src_preamble, env!("CARGO_PKG_VERSION"));
1009
1010        // Render some generator options to assist with debugging and/or to help
1011        // recreate it if the original generation command is lost.
1012        uwriteln!(self.src_preamble, "// Options used:");
1013        if self.opts.std_feature {
1014            uwriteln!(self.src_preamble, "//   * std_feature");
1015        }
1016        if self.opts.raw_strings {
1017            uwriteln!(self.src_preamble, "//   * raw_strings");
1018        }
1019        if !self.opts.skip.is_empty() {
1020            uwriteln!(self.src_preamble, "//   * skip: {:?}", self.opts.skip);
1021        }
1022        if self.opts.stubs {
1023            uwriteln!(self.src_preamble, "//   * stubs");
1024        }
1025        if let Some(export_prefix) = &self.opts.export_prefix {
1026            uwriteln!(
1027                self.src_preamble,
1028                "//   * export_prefix: {:?}",
1029                export_prefix
1030            );
1031        }
1032        if let Some(runtime_path) = &self.opts.runtime_path {
1033            uwriteln!(self.src_preamble, "//   * runtime_path: {:?}", runtime_path);
1034        }
1035        if let Some(bitflags_path) = &self.opts.bitflags_path {
1036            uwriteln!(
1037                self.src_preamble,
1038                "//   * bitflags_path: {:?}",
1039                bitflags_path
1040            );
1041        }
1042        if !matches!(self.opts.ownership, Ownership::Owning) {
1043            uwriteln!(
1044                self.src_preamble,
1045                "//   * ownership: {:?}",
1046                self.opts.ownership
1047            );
1048        }
1049        if !self.opts.additional_derive_attributes.is_empty() {
1050            uwriteln!(
1051                self.src_preamble,
1052                "//   * additional derives {:?}",
1053                self.opts.additional_derive_attributes
1054            );
1055        }
1056        if !self.opts.additional_derive_ignore.is_empty() {
1057            uwriteln!(
1058                self.src_preamble,
1059                "//   * additional derives ignored {:?}",
1060                self.opts.additional_derive_ignore
1061            );
1062        }
1063        for (k, v) in self.opts.with.iter() {
1064            uwriteln!(self.src_preamble, "//   * with {k:?} = {v}");
1065        }
1066        if let Some(type_section_suffix) = &self.opts.type_section_suffix {
1067            uwriteln!(
1068                self.src_preamble,
1069                "//   * type_section_suffix: {:?}",
1070                type_section_suffix
1071            );
1072        }
1073        if let Some(default) = &self.opts.default_bindings_module {
1074            uwriteln!(
1075                self.src_preamble,
1076                "//   * default-bindings-module: {default:?}"
1077            );
1078        }
1079        if self.opts.disable_run_ctors_once_workaround {
1080            uwriteln!(
1081                self.src_preamble,
1082                "//   * disable-run-ctors-once-workaround"
1083            );
1084        }
1085        if let Some(s) = &self.opts.export_macro_name {
1086            uwriteln!(self.src_preamble, "//   * export-macro-name: {s}");
1087        }
1088        if self.opts.pub_export_macro {
1089            uwriteln!(self.src_preamble, "//   * pub-export-macro");
1090        }
1091        if self.opts.generate_unused_types {
1092            uwriteln!(self.src_preamble, "//   * generate_unused_types");
1093        }
1094        if self.opts.disable_custom_section_link_helpers {
1095            uwriteln!(
1096                self.src_preamble,
1097                "//   * disable_custom_section_link_helpers"
1098            );
1099        }
1100        for opt in self.opts.async_.debug_opts() {
1101            uwriteln!(self.src_preamble, "//   * async: {opt}");
1102        }
1103        self.types.analyze(resolve);
1104        self.world = Some(world);
1105
1106        let world = &resolve.worlds[world];
1107        // Specify that all imports local to the world's package should be
1108        // generated
1109        for (key, item) in world.imports.iter() {
1110            if let WorldItem::Interface { id, .. } = item {
1111                if resolve.interfaces[*id].package == world.package {
1112                    let name = resolve.name_world_key(key);
1113                    if self.with.get(&name).is_none() {
1114                        self.with.insert(name, TypeGeneration::Generate);
1115                    }
1116                }
1117            }
1118        }
1119
1120        for (k, v) in self.opts.with.iter() {
1121            self.with.insert(k.clone(), v.clone().into());
1122        }
1123        self.with.generate_by_default = self.opts.generate_all;
1124    }
1125
1126    fn import_interface(
1127        &mut self,
1128        resolve: &Resolve,
1129        name: &WorldKey,
1130        id: InterfaceId,
1131        _files: &mut Files,
1132    ) -> Result<()> {
1133        let mut to_define = Vec::new();
1134        for (name, ty_id) in resolve.interfaces[id].types.iter() {
1135            let full_name = full_wit_type_name(resolve, *ty_id);
1136            if let Some(type_gen) = self.with.get(&full_name) {
1137                // skip type definition generation for remapped types
1138                if type_gen.generated() {
1139                    to_define.push((name, ty_id));
1140                }
1141            } else {
1142                to_define.push((name, ty_id));
1143            }
1144            self.generated_types.insert(full_name);
1145        }
1146
1147        self.interface_last_seen_as_import.insert(id, true);
1148        let wasm_import_module = resolve.name_world_key(name);
1149        let mut r#gen = self.interface(
1150            Identifier::Interface(id, name),
1151            &wasm_import_module,
1152            resolve,
1153            true,
1154        );
1155        let (snake, module_path) = r#gen.start_append_submodule(name);
1156        if r#gen.r#gen.name_interface(resolve, id, name, false)? {
1157            return Ok(());
1158        }
1159
1160        for (name, ty_id) in to_define {
1161            r#gen.define_type(&name, *ty_id);
1162        }
1163
1164        r#gen.generate_imports(resolve.interfaces[id].functions.values(), Some(name));
1165
1166        let docs = &resolve.interfaces[id].docs;
1167
1168        r#gen.finish_append_submodule(&snake, module_path, docs);
1169
1170        Ok(())
1171    }
1172
1173    fn import_funcs(
1174        &mut self,
1175        resolve: &Resolve,
1176        world: WorldId,
1177        funcs: &[(&str, &Function)],
1178        _files: &mut Files,
1179    ) {
1180        self.import_funcs_called = true;
1181
1182        let mut r#gen = self.interface(Identifier::World(world), "$root", resolve, true);
1183
1184        r#gen.generate_imports(funcs.iter().map(|(_, func)| *func), None);
1185
1186        let src = r#gen.finish();
1187        self.src.push_str(&src);
1188    }
1189
1190    fn export_interface(
1191        &mut self,
1192        resolve: &Resolve,
1193        name: &WorldKey,
1194        id: InterfaceId,
1195        _files: &mut Files,
1196    ) -> Result<()> {
1197        let mut to_define = Vec::new();
1198        for (name, ty_id) in resolve.interfaces[id].types.iter() {
1199            let full_name = full_wit_type_name(resolve, *ty_id);
1200            to_define.push((name, ty_id));
1201            self.generated_types.insert(full_name);
1202        }
1203
1204        self.interface_last_seen_as_import.insert(id, false);
1205        let wasm_import_module = format!("[export]{}", resolve.name_world_key(name));
1206        let mut r#gen = self.interface(
1207            Identifier::Interface(id, name),
1208            &wasm_import_module,
1209            resolve,
1210            false,
1211        );
1212        let (snake, module_path) = r#gen.start_append_submodule(name);
1213        if r#gen.r#gen.name_interface(resolve, id, name, true)? {
1214            return Ok(());
1215        }
1216
1217        for (name, ty_id) in to_define {
1218            r#gen.define_type(&name, *ty_id);
1219        }
1220
1221        let macro_name =
1222            r#gen.generate_exports(Some((id, name)), resolve.interfaces[id].functions.values())?;
1223
1224        let docs = &resolve.interfaces[id].docs;
1225
1226        r#gen.finish_append_submodule(&snake, module_path, docs);
1227        self.export_macros
1228            .push((macro_name, self.interface_names[&id].path.clone()));
1229
1230        if self.opts.stubs {
1231            let world_id = self.world.unwrap();
1232            let mut r#gen = self.interface(
1233                Identifier::World(world_id),
1234                &wasm_import_module,
1235                resolve,
1236                false,
1237            );
1238            r#gen.generate_stub(Some((id, name)), resolve.interfaces[id].functions.values());
1239            let stub = r#gen.finish();
1240            self.src.push_str(&stub);
1241        }
1242        Ok(())
1243    }
1244
1245    fn export_funcs(
1246        &mut self,
1247        resolve: &Resolve,
1248        world: WorldId,
1249        funcs: &[(&str, &Function)],
1250        _files: &mut Files,
1251    ) -> Result<()> {
1252        let mut r#gen = self.interface(Identifier::World(world), "[export]$root", resolve, false);
1253        let macro_name = r#gen.generate_exports(None, funcs.iter().map(|f| f.1))?;
1254        let src = r#gen.finish();
1255        self.src.push_str(&src);
1256        self.export_macros.push((macro_name, String::new()));
1257
1258        if self.opts.stubs {
1259            let mut r#gen =
1260                self.interface(Identifier::World(world), "[export]$root", resolve, false);
1261            r#gen.generate_stub(None, funcs.iter().map(|f| f.1));
1262            let stub = r#gen.finish();
1263            self.src.push_str(&stub);
1264        }
1265        Ok(())
1266    }
1267
1268    fn import_types(
1269        &mut self,
1270        resolve: &Resolve,
1271        world: WorldId,
1272        types: &[(&str, TypeId)],
1273        _files: &mut Files,
1274    ) {
1275        let mut to_define = Vec::new();
1276        for (name, ty_id) in types {
1277            let full_name = full_wit_type_name(resolve, *ty_id);
1278            if let Some(type_gen) = self.with.get(&full_name) {
1279                // skip type definition generation for remapped types
1280                if type_gen.generated() {
1281                    to_define.push((name, ty_id));
1282                }
1283            } else {
1284                to_define.push((name, ty_id));
1285            }
1286            self.generated_types.insert(full_name);
1287        }
1288        let mut r#gen = self.interface(Identifier::World(world), "$root", resolve, true);
1289        for (name, ty) in to_define {
1290            r#gen.define_type(name, *ty);
1291        }
1292        let src = r#gen.finish();
1293        self.src.push_str(&src);
1294    }
1295
1296    fn finish_imports(&mut self, resolve: &Resolve, world: WorldId, files: &mut Files) {
1297        if !self.import_funcs_called {
1298            // We call `import_funcs` even if the world doesn't import any
1299            // functions since one of the side effects of that method is to
1300            // generate `struct`s for any imported resources.
1301            self.import_funcs(resolve, world, &[], files);
1302        }
1303    }
1304
1305    fn finish(&mut self, resolve: &Resolve, world: WorldId, files: &mut Files) -> Result<()> {
1306        let name = &resolve.worlds[world].name;
1307
1308        let imports = mem::take(&mut self.import_modules);
1309        self.emit_modules(imports);
1310        let exports = mem::take(&mut self.export_modules);
1311        self.emit_modules(exports);
1312
1313        self.finish_runtime_module();
1314        self.finish_export_macro(resolve, world);
1315
1316        // This is a bit tricky, but we sometimes want to "split" the `world` in
1317        // two and only encode the imports here.
1318        //
1319        // First, a primer. Each invocation of `generate!` has a WIT world as
1320        // input. This is one of the first steps in the build process as wasm
1321        // hasn't even been produced yet. One of the later stages of the build
1322        // process will be to emit a component, currently through the
1323        // `wit-component` crate. That crate relies on custom sections being
1324        // present to describe what WIT worlds were present in the wasm binary.
1325        //
1326        // Additionally a `generate!` macro is not the only thing in a binary.
1327        // There might be multiple `generate!` macros, perhaps even across
1328        // different languages. To handle all this `wit-component` will decode
1329        // each custom section and "union" everything together. Unioning in
1330        // general should work so long as everything has the same structure and
1331        // came from the same source.
1332        //
1333        // The problem here is that if `pub_export_macros` is turned on, meaning
1334        // that the macros are supposed to be used across crates, then neither
1335        // the imports nor the exports of this world are guaranteed to be used.
1336        // For imports that's ok because `wit-component` will drop any unused
1337        // imports automatically. For exports that's a problem because
1338        // `wit-component` unconditionally looks for a definition for all
1339        // exports.
1340        //
1341        // When `pub_export_macros` is turned on, and cross-crate usage of the
1342        // macro is expected, this is solved by emitting two custom sections:
1343        //
1344        // 1. The first section emitted here only has the imports of the world.
1345        //    This slimmed down world should be able to be unioned with the
1346        //    first world trivially and will be GC'd by `wit-component` if not
1347        //    used.
1348        // 2. The second section is emitted as part of the generated `export!`
1349        //    macro invocation. That world has all the export information as
1350        //    well as all the import information.
1351        //
1352        // In the end this is hoped to ensure that usage of crates like `wasi`
1353        // don't accidentally try to export things, for example.
1354        let mut resolve_copy;
1355        let (resolve_to_encode, world_to_encode) = if self.opts.pub_export_macro {
1356            resolve_copy = resolve.clone();
1357            let world_copy = resolve_copy.worlds.alloc(World {
1358                exports: Default::default(),
1359                name: format!("{name}-with-all-of-its-exports-removed"),
1360                ..resolve.worlds[world].clone()
1361            });
1362            (&resolve_copy, world_copy)
1363        } else {
1364            (resolve, world)
1365        };
1366        self.emit_custom_section(
1367            resolve_to_encode,
1368            world_to_encode,
1369            "encoded world",
1370            if self.opts.disable_custom_section_link_helpers {
1371                None
1372            } else {
1373                Some("__link_custom_section_describing_imports")
1374            },
1375        );
1376
1377        if self.opts.stubs {
1378            self.src.push_str("\n#[derive(Debug)]\npub struct Stub;\n");
1379        }
1380
1381        let mut src = mem::take(&mut self.src);
1382        if self.opts.format {
1383            let syntax_tree = syn::parse_file(src.as_str()).unwrap();
1384            *src.as_mut_string() = prettyplease::unparse(&syntax_tree);
1385        }
1386
1387        // Prepend the preamble. We do this after formatting because
1388        // `syn::parse_file` + `prettyplease::unparse` does not preserve comments.
1389        let src_preamble = mem::take(&mut self.src_preamble);
1390        *src.as_mut_string() = format!("{}{}", src_preamble.as_str(), src.as_str());
1391
1392        let module_name = name.to_snake_case();
1393        files.push(&format!("{module_name}.rs"), src.as_bytes());
1394
1395        let remapped_keys = self
1396            .with
1397            .iter()
1398            .map(|(k, _)| k)
1399            .cloned()
1400            .collect::<HashSet<String>>();
1401
1402        let mut unused_keys = remapped_keys
1403            .difference(&self.generated_types)
1404            .collect::<Vec<&String>>();
1405
1406        unused_keys.sort();
1407
1408        if !unused_keys.is_empty() {
1409            bail!("unused remappings provided via `with`: {unused_keys:?}");
1410        }
1411
1412        // Error about unused async configuration to help catch configuration
1413        // errors.
1414        self.opts.async_.ensure_all_used()?;
1415
1416        Ok(())
1417    }
1418}
1419
1420fn compute_module_path(name: &WorldKey, resolve: &Resolve, is_export: bool) -> Vec<String> {
1421    let mut path = Vec::new();
1422    if is_export {
1423        path.push("exports".to_string());
1424    }
1425    match name {
1426        WorldKey::Name(name) => {
1427            path.push(to_rust_ident(name));
1428        }
1429        WorldKey::Interface(id) => {
1430            let iface = &resolve.interfaces[*id];
1431            let pkg = iface.package.unwrap();
1432            let pkgname = resolve.packages[pkg].name.clone();
1433            path.push(to_rust_ident(&pkgname.namespace));
1434            path.push(name_package_module(resolve, pkg));
1435            path.push(to_rust_ident(iface.name.as_ref().unwrap()));
1436        }
1437    }
1438    path
1439}
1440
1441enum Identifier<'a> {
1442    World(WorldId),
1443    Interface(InterfaceId, &'a WorldKey),
1444    StreamOrFuturePayload,
1445}
1446
1447fn group_by_resource<'a>(
1448    funcs: impl Iterator<Item = &'a Function>,
1449) -> BTreeMap<Option<TypeId>, Vec<&'a Function>> {
1450    let mut by_resource = BTreeMap::<_, Vec<_>>::new();
1451    for func in funcs {
1452        by_resource
1453            .entry(func.kind.resource())
1454            .or_default()
1455            .push(func);
1456    }
1457    by_resource
1458}
1459
1460#[derive(Default, Debug, Clone, Copy)]
1461#[cfg_attr(
1462    feature = "serde",
1463    derive(serde::Deserialize),
1464    serde(rename_all = "kebab-case")
1465)]
1466pub enum Ownership {
1467    /// Generated types will be composed entirely of owning fields, regardless
1468    /// of whether they are used as parameters to imports or not.
1469    #[default]
1470    Owning,
1471
1472    /// Generated types used as parameters to imports will be "deeply
1473    /// borrowing", i.e. contain references rather than owned values when
1474    /// applicable.
1475    Borrowing {
1476        /// Whether or not to generate "duplicate" type definitions for a single
1477        /// WIT type if necessary, for example if it's used as both an import
1478        /// and an export, or if it's used both as a parameter to an import and
1479        /// a return value from an import.
1480        duplicate_if_necessary: bool,
1481    },
1482}
1483
1484impl FromStr for Ownership {
1485    type Err = String;
1486
1487    fn from_str(s: &str) -> Result<Self, Self::Err> {
1488        match s {
1489            "owning" => Ok(Self::Owning),
1490            "borrowing" => Ok(Self::Borrowing {
1491                duplicate_if_necessary: false,
1492            }),
1493            "borrowing-duplicate-if-necessary" => Ok(Self::Borrowing {
1494                duplicate_if_necessary: true,
1495            }),
1496            _ => Err(format!(
1497                "unrecognized ownership: `{s}`; \
1498                 expected `owning`, `borrowing`, or `borrowing-duplicate-if-necessary`"
1499            )),
1500        }
1501    }
1502}
1503
1504impl fmt::Display for Ownership {
1505    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1506        f.write_str(match self {
1507            Ownership::Owning => "owning",
1508            Ownership::Borrowing {
1509                duplicate_if_necessary: false,
1510            } => "borrowing",
1511            Ownership::Borrowing {
1512                duplicate_if_necessary: true,
1513            } => "borrowing-duplicate-if-necessary",
1514        })
1515    }
1516}
1517
1518/// Options for with "with" remappings.
1519#[derive(Debug, Clone)]
1520#[cfg_attr(
1521    feature = "serde",
1522    derive(serde::Deserialize),
1523    serde(rename_all = "kebab-case")
1524)]
1525pub enum WithOption {
1526    Path(String),
1527    Generate,
1528}
1529
1530impl std::fmt::Display for WithOption {
1531    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1532        match self {
1533            WithOption::Path(p) => f.write_fmt(format_args!("\"{p}\"")),
1534            WithOption::Generate => f.write_str("generate"),
1535        }
1536    }
1537}
1538
1539impl From<WithOption> for TypeGeneration {
1540    fn from(opt: WithOption) -> Self {
1541        match opt {
1542            WithOption::Path(p) => TypeGeneration::Remap(p),
1543            WithOption::Generate => TypeGeneration::Generate,
1544        }
1545    }
1546}
1547
1548#[derive(Default)]
1549struct FnSig {
1550    async_: bool,
1551    unsafe_: bool,
1552    private: bool,
1553    use_item_name: bool,
1554    generics: Option<String>,
1555    self_arg: Option<String>,
1556    self_is_first_param: bool,
1557}
1558
1559impl FnSig {
1560    fn update_for_func(&mut self, func: &Function) {
1561        if let FunctionKind::Method(_) | FunctionKind::AsyncMethod(_) = &func.kind {
1562            self.self_arg = Some("&self".into());
1563            self.self_is_first_param = true;
1564        }
1565    }
1566}
1567
1568pub fn to_rust_ident(name: &str) -> String {
1569    match name {
1570        // Escape Rust keywords.
1571        // Source: https://doc.rust-lang.org/reference/keywords.html
1572        "as" => "as_".into(),
1573        "break" => "break_".into(),
1574        "const" => "const_".into(),
1575        "continue" => "continue_".into(),
1576        "crate" => "crate_".into(),
1577        "else" => "else_".into(),
1578        "enum" => "enum_".into(),
1579        "extern" => "extern_".into(),
1580        "false" => "false_".into(),
1581        "fn" => "fn_".into(),
1582        "for" => "for_".into(),
1583        "if" => "if_".into(),
1584        "impl" => "impl_".into(),
1585        "in" => "in_".into(),
1586        "let" => "let_".into(),
1587        "loop" => "loop_".into(),
1588        "match" => "match_".into(),
1589        "mod" => "mod_".into(),
1590        "move" => "move_".into(),
1591        "mut" => "mut_".into(),
1592        "pub" => "pub_".into(),
1593        "ref" => "ref_".into(),
1594        "return" => "return_".into(),
1595        "self" => "self_".into(),
1596        "static" => "static_".into(),
1597        "struct" => "struct_".into(),
1598        "super" => "super_".into(),
1599        "trait" => "trait_".into(),
1600        "true" => "true_".into(),
1601        "type" => "type_".into(),
1602        "unsafe" => "unsafe_".into(),
1603        "use" => "use_".into(),
1604        "where" => "where_".into(),
1605        "while" => "while_".into(),
1606        "async" => "async_".into(),
1607        "await" => "await_".into(),
1608        "dyn" => "dyn_".into(),
1609        "abstract" => "abstract_".into(),
1610        "become" => "become_".into(),
1611        "box" => "box_".into(),
1612        "do" => "do_".into(),
1613        "final" => "final_".into(),
1614        "macro" => "macro_".into(),
1615        "override" => "override_".into(),
1616        "priv" => "priv_".into(),
1617        "typeof" => "typeof_".into(),
1618        "unsized" => "unsized_".into(),
1619        "virtual" => "virtual_".into(),
1620        "yield" => "yield_".into(),
1621        "try" => "try_".into(),
1622        s => s.to_snake_case(),
1623    }
1624}
1625
1626fn to_upper_camel_case(name: &str) -> String {
1627    match name {
1628        // The name "Guest" is reserved for traits generated by exported
1629        // interfaces, so remap types defined in wit to something else.
1630        "guest" => "Guest_".to_string(),
1631        s => s.to_upper_camel_case(),
1632    }
1633}
1634
1635fn wasm_type(ty: WasmType) -> &'static str {
1636    match ty {
1637        WasmType::I32 => "i32",
1638        WasmType::I64 => "i64",
1639        WasmType::F32 => "f32",
1640        WasmType::F64 => "f64",
1641        WasmType::Pointer => "*mut u8",
1642        WasmType::Length => "usize",
1643
1644        // `PointerOrI64` can hold either a `u64` or a pointer with provenance.
1645        // Neither a `u64` nor a pointer type can portably do both, so we use
1646        // `MaybeUninit<u64>`, since `MaybeUninit` is [documented] to preserve
1647        // provenance.
1648        // [documented]: https://github.com/rust-lang/rfcs/blob/master/text/3559-rust-has-provenance.md#reference-level-explanation
1649        WasmType::PointerOrI64 => "::core::mem::MaybeUninit::<u64>",
1650    }
1651}
1652
1653fn declare_import(
1654    wasm_import_module: &str,
1655    wasm_import_name: &str,
1656    rust_name: &str,
1657    params: &[WasmType],
1658    results: &[WasmType],
1659) -> String {
1660    let mut sig = "(".to_owned();
1661    for param in params.iter() {
1662        sig.push_str("_: ");
1663        sig.push_str(wasm_type(*param));
1664        sig.push_str(", ");
1665    }
1666    sig.push(')');
1667    assert!(results.len() < 2);
1668    for result in results.iter() {
1669        sig.push_str(" -> ");
1670        sig.push_str(wasm_type(*result));
1671    }
1672    format!(
1673        "
1674            #[cfg(target_arch = \"wasm32\")]
1675            #[link(wasm_import_module = \"{wasm_import_module}\")]
1676            unsafe extern \"C\" {{
1677                #[link_name = \"{wasm_import_name}\"]
1678                fn {rust_name}{sig};
1679            }}
1680
1681            #[cfg(not(target_arch = \"wasm32\"))]
1682            unsafe extern \"C\" fn {rust_name}{sig} {{ unreachable!() }}
1683        "
1684    )
1685}
1686
1687fn int_repr(repr: Int) -> &'static str {
1688    match repr {
1689        Int::U8 => "u8",
1690        Int::U16 => "u16",
1691        Int::U32 => "u32",
1692        Int::U64 => "u64",
1693    }
1694}
1695
1696fn bitcast(casts: &[Bitcast], operands: &[String], results: &mut Vec<String>) {
1697    for (cast, operand) in casts.iter().zip(operands) {
1698        results.push(perform_cast(operand, cast));
1699    }
1700}
1701
1702fn perform_cast(operand: &str, cast: &Bitcast) -> String {
1703    match cast {
1704        Bitcast::None => operand.to_owned(),
1705        Bitcast::I32ToI64 => format!("i64::from({})", operand),
1706        Bitcast::F32ToI32 => format!("({}).to_bits() as i32", operand),
1707        Bitcast::F64ToI64 => format!("({}).to_bits() as i64", operand),
1708        Bitcast::I64ToI32 => format!("{} as i32", operand),
1709        Bitcast::I32ToF32 => format!("f32::from_bits({} as u32)", operand),
1710        Bitcast::I64ToF64 => format!("f64::from_bits({} as u64)", operand),
1711        Bitcast::F32ToI64 => format!("i64::from(({}).to_bits())", operand),
1712        Bitcast::I64ToF32 => format!("f32::from_bits({} as u32)", operand),
1713
1714        // Convert an `i64` into a `MaybeUninit<u64>`.
1715        Bitcast::I64ToP64 => format!("::core::mem::MaybeUninit::new({} as u64)", operand),
1716        // Convert a `MaybeUninit<u64>` holding an `i64` value back into
1717        // the `i64` value.
1718        Bitcast::P64ToI64 => format!("{}.assume_init() as i64", operand),
1719
1720        // Convert a pointer value into a `MaybeUninit<u64>`.
1721        Bitcast::PToP64 => {
1722            format!(
1723                "{{
1724                        let mut t = ::core::mem::MaybeUninit::<u64>::uninit();
1725                        t.as_mut_ptr().cast::<*mut u8>().write({});
1726                        t
1727                    }}",
1728                operand
1729            )
1730        }
1731        // Convert a `MaybeUninit<u64>` holding a pointer value back into
1732        // the pointer value.
1733        Bitcast::P64ToP => {
1734            format!("{}.as_ptr().cast::<*mut u8>().read()", operand)
1735        }
1736        // Convert an `i32` or a `usize` into a pointer.
1737        Bitcast::I32ToP | Bitcast::LToP => {
1738            format!("{} as *mut u8", operand)
1739        }
1740        // Convert a pointer or length holding an `i32` value back into the `i32`.
1741        Bitcast::PToI32 | Bitcast::LToI32 => {
1742            format!("{} as i32", operand)
1743        }
1744        // Convert an `i32`, `i64`, or pointer holding a `usize` value back into the `usize`.
1745        Bitcast::I32ToL | Bitcast::I64ToL | Bitcast::PToL => {
1746            format!("{} as usize", operand)
1747        }
1748        // Convert a `usize` into an `i64`.
1749        Bitcast::LToI64 => {
1750            format!("{} as i64", operand)
1751        }
1752        Bitcast::Sequence(sequence) => {
1753            let [first, second] = &**sequence;
1754            perform_cast(&perform_cast(operand, first), second)
1755        }
1756    }
1757}
1758
1759enum RustFlagsRepr {
1760    U8,
1761    U16,
1762    U32,
1763    U64,
1764    U128,
1765}
1766
1767impl RustFlagsRepr {
1768    fn new(f: &Flags) -> RustFlagsRepr {
1769        match f.repr() {
1770            FlagsRepr::U8 => RustFlagsRepr::U8,
1771            FlagsRepr::U16 => RustFlagsRepr::U16,
1772            FlagsRepr::U32(1) => RustFlagsRepr::U32,
1773            FlagsRepr::U32(2) => RustFlagsRepr::U64,
1774            FlagsRepr::U32(3 | 4) => RustFlagsRepr::U128,
1775            FlagsRepr::U32(n) => panic!("unsupported number of flags: {}", n * 32),
1776        }
1777    }
1778}
1779
1780impl fmt::Display for RustFlagsRepr {
1781    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1782        match self {
1783            RustFlagsRepr::U8 => "u8".fmt(f),
1784            RustFlagsRepr::U16 => "u16".fmt(f),
1785            RustFlagsRepr::U32 => "u32".fmt(f),
1786            RustFlagsRepr::U64 => "u64".fmt(f),
1787            RustFlagsRepr::U128 => "u128".fmt(f),
1788        }
1789    }
1790}
1791
1792#[derive(Debug, Clone)]
1793pub struct MissingWith(pub String);
1794
1795impl fmt::Display for MissingWith {
1796    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1797        write!(f, "missing `with` mapping for the key `{}`", self.0)
1798    }
1799}
1800
1801impl std::error::Error for MissingWith {}
1802
1803// bail!("no remapping found for {with_name:?} - use the `generate!` macro's `with` option to force the interface to be generated or specify where it is already defined:
1804// ```
1805// with: {{\n\t{with_name:?}: generate\n}}
1806// ```")
1807
1808/// Returns the full WIT type name with fully qualified interface name
1809fn full_wit_type_name(resolve: &Resolve, id: TypeId) -> String {
1810    let id = dealias(resolve, id);
1811    let type_def = &resolve.types[id];
1812    let interface_name = match type_def.owner {
1813        TypeOwner::World(w) => Some(resolve.worlds[w].name.clone()),
1814        TypeOwner::Interface(id) => resolve.id_of(id),
1815        TypeOwner::None => None,
1816    };
1817    match interface_name {
1818        Some(interface_name) => format!("{}/{}", interface_name, type_def.name.clone().unwrap()),
1819        None => type_def.name.clone().unwrap(),
1820    }
1821}
1822
1823enum ConstructorReturnType {
1824    /// Resource constructor is infallible. E.g.:
1825    /// ```wit
1826    /// resource R {
1827    ///    constructor(..);
1828    /// }
1829    /// ```
1830    Self_,
1831
1832    /// Resource constructor is fallible. E.g.:
1833    /// ```wit
1834    /// resource R {
1835    ///    constructor(..) -> result<R, err>;
1836    /// }
1837    /// ```
1838    Result { err: Option<Type> },
1839}
1840
1841fn classify_constructor_return_type(
1842    resolve: &Resolve,
1843    resource_id: TypeId,
1844    result: &Option<Type>,
1845) -> ConstructorReturnType {
1846    fn classify(
1847        resolve: &Resolve,
1848        resource_id: TypeId,
1849        result: &Option<Type>,
1850    ) -> Option<ConstructorReturnType> {
1851        let resource_id = dealias(resolve, resource_id);
1852        let typedef = match result.as_ref()? {
1853            Type::Id(id) => &resolve.types[dealias(resolve, *id)],
1854            _ => return None,
1855        };
1856
1857        match &typedef.kind {
1858            TypeDefKind::Handle(Handle::Own(id)) if dealias(resolve, *id) == resource_id => {
1859                Some(ConstructorReturnType::Self_)
1860            }
1861            TypeDefKind::Result(Result_ { ok, err }) => {
1862                let ok_typedef = match ok.as_ref()? {
1863                    Type::Id(id) => &resolve.types[dealias(resolve, *id)],
1864                    _ => return None,
1865                };
1866
1867                match &ok_typedef.kind {
1868                    TypeDefKind::Handle(Handle::Own(id))
1869                        if dealias(resolve, *id) == resource_id =>
1870                    {
1871                        Some(ConstructorReturnType::Result { err: *err })
1872                    }
1873                    _ => None,
1874                }
1875            }
1876            _ => None,
1877        }
1878    }
1879
1880    classify(resolve, resource_id, result).expect("invalid constructor")
1881}