Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 43 additions & 12 deletions crates/go/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ fn remote_pkg(name: &str) -> String {
format!(r#""github.com/bytecodealliance/wit-bindgen/{name}""#)
}

/// Adds the bindings module prefix to a package name.
fn mod_pkg(name: &str) -> String {
format!(r#""wit_component/{name}""#)
}

/// This is the literal location of the Go package.
const REPLACEMENT_PKG: &str = concat!(
"github.com/bytecodealliance/wit-bindgen/crates/go/src/package v",
Expand Down Expand Up @@ -105,6 +100,11 @@ pub struct Opts {
/// resources.
#[cfg_attr(feature = "clap", clap(long))]
pub generate_stubs: bool,

/// The name of the Go module housing the generated bindings
/// (or "wit_component" if `None`).
#[cfg_attr(feature = "clap", clap(long))]
pub mod_name: Option<String>,
}

impl Opts {
Expand Down Expand Up @@ -193,6 +193,12 @@ struct Go {
}

impl Go {
/// Adds the bindings module prefix to a package name.
fn mod_pkg(&self, name: &str) -> String {
let prefix = self.opts.mod_name.as_deref().unwrap_or("wit_component");
format!(r#""{prefix}/{name}""#)
}

fn package_for_owner(
&mut self,
resolve: &Resolve,
Expand All @@ -214,7 +220,7 @@ impl Go {
package
};
let prefix = format!("{package}.");
imports.insert(mod_pkg(&package));
imports.insert(self.mod_pkg(&package));
prefix
}
}
Expand Down Expand Up @@ -843,13 +849,31 @@ impl WorldGenerator for Go {
.collect::<Vec<_>>()
.join("\n");

// When a custom module name is provided, the generated bindings use package name
// "wit_component" so they can be imported into another package. Without a custom
// module name, the bindings use package "main" for standalone execution.
let package_name = if self.opts.mod_name.is_some() {
"wit_component"
} else {
"main"
};

// If the package name isn't "main", a main function isn't required.
let main_func = if self.opts.mod_name.is_some() {
""
} else {
r#"// Unused, but present to make the compiler happy
func main() {}
"#
};

files.push(
"wit_bindings.go",
&maybe_gofmt(
self.opts.format,
format!(
r#"{header}
package main
package {package_name}

import (
"runtime"
Expand All @@ -862,14 +886,21 @@ var {SYNC_EXPORT_PINNER} = runtime.Pinner{{}}

{src}

// Unused, but present to make the compiler happy
func main() {{}}
{main_func}
"#
)
.as_bytes(),
),
);
files.push("go.mod", format!("module wit_component\n\ngo 1.25\n\nreplace github.com/bytecodealliance/wit-bindgen => {REPLACEMENT_PKG}").as_bytes());
files.push(
"go.mod",
format!(
"module {}\n\ngo 1.25\n\nreplace github.com/bytecodealliance/wit-bindgen => {}",
self.opts.mod_name.as_deref().unwrap_or("wit_component"),
REPLACEMENT_PKG
)
.as_bytes(),
);

for (prefix, interfaces) in [("export_", &self.export_interfaces), ("", &self.interfaces)] {
for (name, data) in interfaces {
Expand Down Expand Up @@ -1707,7 +1738,7 @@ for index := 0; index < int({length}); index++ {{
FunctionKind::Freestanding | FunctionKind::AsyncFreestanding => {
let args = operands.join(", ");
let call = format!("{package}.{name}({args})");
self.imports.insert(mod_pkg(&package));
self.imports.insert(self.generator.mod_pkg(&package));
call
}
FunctionKind::Constructor(ty) => {
Expand All @@ -1718,7 +1749,7 @@ for index := 0; index < int({length}); index++ {{
.unwrap()
.to_upper_camel_case();
let call = format!("{package}.Make{ty}({args})");
self.imports.insert(mod_pkg(&package));
self.imports.insert(self.generator.mod_pkg(&package));
call
}
FunctionKind::Method(_) | FunctionKind::AsyncMethod(_) => {
Expand Down
Loading