A Go module that embeds protoc-gen-prost as a WebAssembly module for pure-Go Protocol Buffer code generation.
- aperturerobotics/protoc-gen-prost - Fork with WASI build support
- neoeinstein/protoc-gen-prost - Original protoc-gen-prost repository
- tetratelabs/wazero - Zero-dependency WebAssembly runtime for Go
This module provides the protoc-gen-prost Protocol Buffers code generator compiled to WebAssembly with WASI support. The WASM binary is embedded directly in the Go module, enabling Rust/Prost code generation in Go applications without external dependencies or native binaries.
The WASM module exports the following functions:
prost_malloc(size)- Allocate memory for input dataprost_free(ptr, size)- Free allocated memoryprost_execute(input_ptr, input_len)- Execute the plugin, returns output lengthprost_get_output_ptr()- Get pointer to output bufferprost_get_output_len()- Get output buffer lengthprost_clear_output()- Clear the output buffer
- The host allocates memory in WASM using
prost_malloc - The host writes the serialized
CodeGeneratorRequestto that memory - The host calls
prost_executewith the pointer and length - The plugin processes the request and stores the
CodeGeneratorResponseinternally - The host reads the response using
prost_get_output_ptrandprost_get_output_len - The host calls
prost_clear_outputto free the internal buffer
- Embeds protoc-gen-prost as a ~600KB WASI WebAssembly binary
- Pure Go execution via wazero (no CGO required)
- Thread-safe with mutex protection
- Supports repeated executions without reloading
package main
import (
"context"
"fmt"
"github.com/tetratelabs/wazero"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/pluginpb"
prost "github.com/aperturerobotics/go-protoc-gen-prost"
)
func main() {
ctx := context.Background()
r := wazero.NewRuntime(ctx)
defer r.Close(ctx)
// Create the protoc-gen-prost instance
p, err := prost.NewProtocGenProst(ctx, r)
if err != nil {
panic(err)
}
defer p.Close(ctx)
// Create a CodeGeneratorRequest
req := &pluginpb.CodeGeneratorRequest{
FileToGenerate: []string{"example.proto"},
ProtoFile: []*descriptorpb.FileDescriptorProto{
// ... your proto file descriptors
},
}
// Serialize the request
input, err := proto.Marshal(req)
if err != nil {
panic(err)
}
// Execute the plugin
output, err := p.Execute(ctx, input)
if err != nil {
panic(err)
}
// Parse the response
resp := &pluginpb.CodeGeneratorResponse{}
if err := proto.Unmarshal(output, resp); err != nil {
panic(err)
}
// Process generated files
for _, file := range resp.GetFile() {
fmt.Printf("Generated: %s\n", file.GetName())
}
}To embed the build at a commit of protoc-gen-prost (the wasi branch by default):
./update-prost.bash [ref]This script:
- Resolves the ref in
aperturerobotics/protoc-gen-prostto a full commit - Downloads
dist/protoc-gen-prost.wasmat that commit - Writes
version.gowith the commit and the artifact URL
The WASM binary is built from aperturerobotics/protoc-gen-prost:
# Clone the repository
git clone https://github.com/aperturerobotics/protoc-gen-prost.git
cd protoc-gen-prost
# Build for WASI
./build-wasi.sh
# Output: dist/protoc-gen-prost.wasm- Rust toolchain with
wasm32-wasip1target - binaryen (for
wasm-opt) - wabt (for
wasm-strip)
go test -v ./...MIT
The embedded protoc-gen-prost WASM is covered by the Apache 2.0 license.