Files
navidrome-meilisearch/plugins/api/api_host.pb.go
Dongho Kim c251f174ed
Some checks failed
Pipeline: Test, Lint, Build / Get version info (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test JS code (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint i18n files (push) Has been cancelled
Pipeline: Test, Lint, Build / Check Docker configuration (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v5) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v6) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v7) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to GHCR (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to Docker Hub (push) Has been cancelled
Pipeline: Test, Lint, Build / Cleanup digest artifacts (push) Has been cancelled
Pipeline: Test, Lint, Build / Build Windows installers (push) Has been cancelled
Pipeline: Test, Lint, Build / Package/Release (push) Has been cancelled
Pipeline: Test, Lint, Build / Upload Linux PKG (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
POEditor import / update-translations (push) Has been cancelled
update
2025-12-08 16:16:23 +01:00

1689 lines
48 KiB
Go

//go:build !wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: api/api.proto
package api
import (
context "context"
errors "errors"
fmt "fmt"
wazero "github.com/tetratelabs/wazero"
api "github.com/tetratelabs/wazero/api"
sys "github.com/tetratelabs/wazero/sys"
os "os"
)
const MetadataAgentPluginAPIVersion = 1
type MetadataAgentPlugin struct {
newRuntime func(context.Context) (wazero.Runtime, error)
moduleConfig wazero.ModuleConfig
}
func NewMetadataAgentPlugin(ctx context.Context, opts ...wazeroConfigOption) (*MetadataAgentPlugin, error) {
o := &WazeroConfig{
newRuntime: DefaultWazeroRuntime(),
moduleConfig: wazero.NewModuleConfig().WithStartFunctions("_initialize"),
}
for _, opt := range opts {
opt(o)
}
return &MetadataAgentPlugin{
newRuntime: o.newRuntime,
moduleConfig: o.moduleConfig,
}, nil
}
type metadataAgent interface {
Close(ctx context.Context) error
MetadataAgent
}
func (p *MetadataAgentPlugin) Load(ctx context.Context, pluginPath string) (metadataAgent, error) {
b, err := os.ReadFile(pluginPath)
if err != nil {
return nil, err
}
// Create a new runtime so that multiple modules will not conflict
r, err := p.newRuntime(ctx)
if err != nil {
return nil, err
}
// Compile the WebAssembly module using the default configuration.
code, err := r.CompileModule(ctx, b)
if err != nil {
return nil, err
}
// InstantiateModule runs the "_start" function, WASI's "main".
module, err := r.InstantiateModule(ctx, code, p.moduleConfig)
if err != nil {
// Note: Most compilers do not exit the module after running "_start",
// unless there was an Error. This allows you to call exported functions.
if exitErr, ok := err.(*sys.ExitError); ok && exitErr.ExitCode() != 0 {
return nil, fmt.Errorf("unexpected exit_code: %d", exitErr.ExitCode())
} else if !ok {
return nil, err
}
}
// Compare API versions with the loading plugin
apiVersion := module.ExportedFunction("metadata_agent_api_version")
if apiVersion == nil {
return nil, errors.New("metadata_agent_api_version is not exported")
}
results, err := apiVersion.Call(ctx)
if err != nil {
return nil, err
} else if len(results) != 1 {
return nil, errors.New("invalid metadata_agent_api_version signature")
}
if results[0] != MetadataAgentPluginAPIVersion {
return nil, fmt.Errorf("API version mismatch, host: %d, plugin: %d", MetadataAgentPluginAPIVersion, results[0])
}
getartistmbid := module.ExportedFunction("metadata_agent_get_artist_mbid")
if getartistmbid == nil {
return nil, errors.New("metadata_agent_get_artist_mbid is not exported")
}
getartisturl := module.ExportedFunction("metadata_agent_get_artist_url")
if getartisturl == nil {
return nil, errors.New("metadata_agent_get_artist_url is not exported")
}
getartistbiography := module.ExportedFunction("metadata_agent_get_artist_biography")
if getartistbiography == nil {
return nil, errors.New("metadata_agent_get_artist_biography is not exported")
}
getsimilarartists := module.ExportedFunction("metadata_agent_get_similar_artists")
if getsimilarartists == nil {
return nil, errors.New("metadata_agent_get_similar_artists is not exported")
}
getartistimages := module.ExportedFunction("metadata_agent_get_artist_images")
if getartistimages == nil {
return nil, errors.New("metadata_agent_get_artist_images is not exported")
}
getartisttopsongs := module.ExportedFunction("metadata_agent_get_artist_top_songs")
if getartisttopsongs == nil {
return nil, errors.New("metadata_agent_get_artist_top_songs is not exported")
}
getalbuminfo := module.ExportedFunction("metadata_agent_get_album_info")
if getalbuminfo == nil {
return nil, errors.New("metadata_agent_get_album_info is not exported")
}
getalbumimages := module.ExportedFunction("metadata_agent_get_album_images")
if getalbumimages == nil {
return nil, errors.New("metadata_agent_get_album_images is not exported")
}
malloc := module.ExportedFunction("malloc")
if malloc == nil {
return nil, errors.New("malloc is not exported")
}
free := module.ExportedFunction("free")
if free == nil {
return nil, errors.New("free is not exported")
}
return &metadataAgentPlugin{
runtime: r,
module: module,
malloc: malloc,
free: free,
getartistmbid: getartistmbid,
getartisturl: getartisturl,
getartistbiography: getartistbiography,
getsimilarartists: getsimilarartists,
getartistimages: getartistimages,
getartisttopsongs: getartisttopsongs,
getalbuminfo: getalbuminfo,
getalbumimages: getalbumimages,
}, nil
}
func (p *metadataAgentPlugin) Close(ctx context.Context) (err error) {
if r := p.runtime; r != nil {
r.Close(ctx)
}
return
}
type metadataAgentPlugin struct {
runtime wazero.Runtime
module api.Module
malloc api.Function
free api.Function
getartistmbid api.Function
getartisturl api.Function
getartistbiography api.Function
getsimilarartists api.Function
getartistimages api.Function
getartisttopsongs api.Function
getalbuminfo api.Function
getalbumimages api.Function
}
func (p *metadataAgentPlugin) GetArtistMBID(ctx context.Context, request *ArtistMBIDRequest) (*ArtistMBIDResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.getartistmbid.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(ArtistMBIDResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
func (p *metadataAgentPlugin) GetArtistURL(ctx context.Context, request *ArtistURLRequest) (*ArtistURLResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.getartisturl.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(ArtistURLResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
func (p *metadataAgentPlugin) GetArtistBiography(ctx context.Context, request *ArtistBiographyRequest) (*ArtistBiographyResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.getartistbiography.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(ArtistBiographyResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
func (p *metadataAgentPlugin) GetSimilarArtists(ctx context.Context, request *ArtistSimilarRequest) (*ArtistSimilarResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.getsimilarartists.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(ArtistSimilarResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
func (p *metadataAgentPlugin) GetArtistImages(ctx context.Context, request *ArtistImageRequest) (*ArtistImageResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.getartistimages.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(ArtistImageResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
func (p *metadataAgentPlugin) GetArtistTopSongs(ctx context.Context, request *ArtistTopSongsRequest) (*ArtistTopSongsResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.getartisttopsongs.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(ArtistTopSongsResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
func (p *metadataAgentPlugin) GetAlbumInfo(ctx context.Context, request *AlbumInfoRequest) (*AlbumInfoResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.getalbuminfo.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(AlbumInfoResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
func (p *metadataAgentPlugin) GetAlbumImages(ctx context.Context, request *AlbumImagesRequest) (*AlbumImagesResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.getalbumimages.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(AlbumImagesResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
const ScrobblerPluginAPIVersion = 1
type ScrobblerPlugin struct {
newRuntime func(context.Context) (wazero.Runtime, error)
moduleConfig wazero.ModuleConfig
}
func NewScrobblerPlugin(ctx context.Context, opts ...wazeroConfigOption) (*ScrobblerPlugin, error) {
o := &WazeroConfig{
newRuntime: DefaultWazeroRuntime(),
moduleConfig: wazero.NewModuleConfig().WithStartFunctions("_initialize"),
}
for _, opt := range opts {
opt(o)
}
return &ScrobblerPlugin{
newRuntime: o.newRuntime,
moduleConfig: o.moduleConfig,
}, nil
}
type scrobbler interface {
Close(ctx context.Context) error
Scrobbler
}
func (p *ScrobblerPlugin) Load(ctx context.Context, pluginPath string) (scrobbler, error) {
b, err := os.ReadFile(pluginPath)
if err != nil {
return nil, err
}
// Create a new runtime so that multiple modules will not conflict
r, err := p.newRuntime(ctx)
if err != nil {
return nil, err
}
// Compile the WebAssembly module using the default configuration.
code, err := r.CompileModule(ctx, b)
if err != nil {
return nil, err
}
// InstantiateModule runs the "_start" function, WASI's "main".
module, err := r.InstantiateModule(ctx, code, p.moduleConfig)
if err != nil {
// Note: Most compilers do not exit the module after running "_start",
// unless there was an Error. This allows you to call exported functions.
if exitErr, ok := err.(*sys.ExitError); ok && exitErr.ExitCode() != 0 {
return nil, fmt.Errorf("unexpected exit_code: %d", exitErr.ExitCode())
} else if !ok {
return nil, err
}
}
// Compare API versions with the loading plugin
apiVersion := module.ExportedFunction("scrobbler_api_version")
if apiVersion == nil {
return nil, errors.New("scrobbler_api_version is not exported")
}
results, err := apiVersion.Call(ctx)
if err != nil {
return nil, err
} else if len(results) != 1 {
return nil, errors.New("invalid scrobbler_api_version signature")
}
if results[0] != ScrobblerPluginAPIVersion {
return nil, fmt.Errorf("API version mismatch, host: %d, plugin: %d", ScrobblerPluginAPIVersion, results[0])
}
isauthorized := module.ExportedFunction("scrobbler_is_authorized")
if isauthorized == nil {
return nil, errors.New("scrobbler_is_authorized is not exported")
}
nowplaying := module.ExportedFunction("scrobbler_now_playing")
if nowplaying == nil {
return nil, errors.New("scrobbler_now_playing is not exported")
}
scrobble := module.ExportedFunction("scrobbler_scrobble")
if scrobble == nil {
return nil, errors.New("scrobbler_scrobble is not exported")
}
malloc := module.ExportedFunction("malloc")
if malloc == nil {
return nil, errors.New("malloc is not exported")
}
free := module.ExportedFunction("free")
if free == nil {
return nil, errors.New("free is not exported")
}
return &scrobblerPlugin{
runtime: r,
module: module,
malloc: malloc,
free: free,
isauthorized: isauthorized,
nowplaying: nowplaying,
scrobble: scrobble,
}, nil
}
func (p *scrobblerPlugin) Close(ctx context.Context) (err error) {
if r := p.runtime; r != nil {
r.Close(ctx)
}
return
}
type scrobblerPlugin struct {
runtime wazero.Runtime
module api.Module
malloc api.Function
free api.Function
isauthorized api.Function
nowplaying api.Function
scrobble api.Function
}
func (p *scrobblerPlugin) IsAuthorized(ctx context.Context, request *ScrobblerIsAuthorizedRequest) (*ScrobblerIsAuthorizedResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.isauthorized.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(ScrobblerIsAuthorizedResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
func (p *scrobblerPlugin) NowPlaying(ctx context.Context, request *ScrobblerNowPlayingRequest) (*ScrobblerNowPlayingResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.nowplaying.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(ScrobblerNowPlayingResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
func (p *scrobblerPlugin) Scrobble(ctx context.Context, request *ScrobblerScrobbleRequest) (*ScrobblerScrobbleResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.scrobble.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(ScrobblerScrobbleResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
const SchedulerCallbackPluginAPIVersion = 1
type SchedulerCallbackPlugin struct {
newRuntime func(context.Context) (wazero.Runtime, error)
moduleConfig wazero.ModuleConfig
}
func NewSchedulerCallbackPlugin(ctx context.Context, opts ...wazeroConfigOption) (*SchedulerCallbackPlugin, error) {
o := &WazeroConfig{
newRuntime: DefaultWazeroRuntime(),
moduleConfig: wazero.NewModuleConfig().WithStartFunctions("_initialize"),
}
for _, opt := range opts {
opt(o)
}
return &SchedulerCallbackPlugin{
newRuntime: o.newRuntime,
moduleConfig: o.moduleConfig,
}, nil
}
type schedulerCallback interface {
Close(ctx context.Context) error
SchedulerCallback
}
func (p *SchedulerCallbackPlugin) Load(ctx context.Context, pluginPath string) (schedulerCallback, error) {
b, err := os.ReadFile(pluginPath)
if err != nil {
return nil, err
}
// Create a new runtime so that multiple modules will not conflict
r, err := p.newRuntime(ctx)
if err != nil {
return nil, err
}
// Compile the WebAssembly module using the default configuration.
code, err := r.CompileModule(ctx, b)
if err != nil {
return nil, err
}
// InstantiateModule runs the "_start" function, WASI's "main".
module, err := r.InstantiateModule(ctx, code, p.moduleConfig)
if err != nil {
// Note: Most compilers do not exit the module after running "_start",
// unless there was an Error. This allows you to call exported functions.
if exitErr, ok := err.(*sys.ExitError); ok && exitErr.ExitCode() != 0 {
return nil, fmt.Errorf("unexpected exit_code: %d", exitErr.ExitCode())
} else if !ok {
return nil, err
}
}
// Compare API versions with the loading plugin
apiVersion := module.ExportedFunction("scheduler_callback_api_version")
if apiVersion == nil {
return nil, errors.New("scheduler_callback_api_version is not exported")
}
results, err := apiVersion.Call(ctx)
if err != nil {
return nil, err
} else if len(results) != 1 {
return nil, errors.New("invalid scheduler_callback_api_version signature")
}
if results[0] != SchedulerCallbackPluginAPIVersion {
return nil, fmt.Errorf("API version mismatch, host: %d, plugin: %d", SchedulerCallbackPluginAPIVersion, results[0])
}
onschedulercallback := module.ExportedFunction("scheduler_callback_on_scheduler_callback")
if onschedulercallback == nil {
return nil, errors.New("scheduler_callback_on_scheduler_callback is not exported")
}
malloc := module.ExportedFunction("malloc")
if malloc == nil {
return nil, errors.New("malloc is not exported")
}
free := module.ExportedFunction("free")
if free == nil {
return nil, errors.New("free is not exported")
}
return &schedulerCallbackPlugin{
runtime: r,
module: module,
malloc: malloc,
free: free,
onschedulercallback: onschedulercallback,
}, nil
}
func (p *schedulerCallbackPlugin) Close(ctx context.Context) (err error) {
if r := p.runtime; r != nil {
r.Close(ctx)
}
return
}
type schedulerCallbackPlugin struct {
runtime wazero.Runtime
module api.Module
malloc api.Function
free api.Function
onschedulercallback api.Function
}
func (p *schedulerCallbackPlugin) OnSchedulerCallback(ctx context.Context, request *SchedulerCallbackRequest) (*SchedulerCallbackResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.onschedulercallback.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(SchedulerCallbackResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
const LifecycleManagementPluginAPIVersion = 1
type LifecycleManagementPlugin struct {
newRuntime func(context.Context) (wazero.Runtime, error)
moduleConfig wazero.ModuleConfig
}
func NewLifecycleManagementPlugin(ctx context.Context, opts ...wazeroConfigOption) (*LifecycleManagementPlugin, error) {
o := &WazeroConfig{
newRuntime: DefaultWazeroRuntime(),
moduleConfig: wazero.NewModuleConfig().WithStartFunctions("_initialize"),
}
for _, opt := range opts {
opt(o)
}
return &LifecycleManagementPlugin{
newRuntime: o.newRuntime,
moduleConfig: o.moduleConfig,
}, nil
}
type lifecycleManagement interface {
Close(ctx context.Context) error
LifecycleManagement
}
func (p *LifecycleManagementPlugin) Load(ctx context.Context, pluginPath string) (lifecycleManagement, error) {
b, err := os.ReadFile(pluginPath)
if err != nil {
return nil, err
}
// Create a new runtime so that multiple modules will not conflict
r, err := p.newRuntime(ctx)
if err != nil {
return nil, err
}
// Compile the WebAssembly module using the default configuration.
code, err := r.CompileModule(ctx, b)
if err != nil {
return nil, err
}
// InstantiateModule runs the "_start" function, WASI's "main".
module, err := r.InstantiateModule(ctx, code, p.moduleConfig)
if err != nil {
// Note: Most compilers do not exit the module after running "_start",
// unless there was an Error. This allows you to call exported functions.
if exitErr, ok := err.(*sys.ExitError); ok && exitErr.ExitCode() != 0 {
return nil, fmt.Errorf("unexpected exit_code: %d", exitErr.ExitCode())
} else if !ok {
return nil, err
}
}
// Compare API versions with the loading plugin
apiVersion := module.ExportedFunction("lifecycle_management_api_version")
if apiVersion == nil {
return nil, errors.New("lifecycle_management_api_version is not exported")
}
results, err := apiVersion.Call(ctx)
if err != nil {
return nil, err
} else if len(results) != 1 {
return nil, errors.New("invalid lifecycle_management_api_version signature")
}
if results[0] != LifecycleManagementPluginAPIVersion {
return nil, fmt.Errorf("API version mismatch, host: %d, plugin: %d", LifecycleManagementPluginAPIVersion, results[0])
}
oninit := module.ExportedFunction("lifecycle_management_on_init")
if oninit == nil {
return nil, errors.New("lifecycle_management_on_init is not exported")
}
malloc := module.ExportedFunction("malloc")
if malloc == nil {
return nil, errors.New("malloc is not exported")
}
free := module.ExportedFunction("free")
if free == nil {
return nil, errors.New("free is not exported")
}
return &lifecycleManagementPlugin{
runtime: r,
module: module,
malloc: malloc,
free: free,
oninit: oninit,
}, nil
}
func (p *lifecycleManagementPlugin) Close(ctx context.Context) (err error) {
if r := p.runtime; r != nil {
r.Close(ctx)
}
return
}
type lifecycleManagementPlugin struct {
runtime wazero.Runtime
module api.Module
malloc api.Function
free api.Function
oninit api.Function
}
func (p *lifecycleManagementPlugin) OnInit(ctx context.Context, request *InitRequest) (*InitResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.oninit.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(InitResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
const WebSocketCallbackPluginAPIVersion = 1
type WebSocketCallbackPlugin struct {
newRuntime func(context.Context) (wazero.Runtime, error)
moduleConfig wazero.ModuleConfig
}
func NewWebSocketCallbackPlugin(ctx context.Context, opts ...wazeroConfigOption) (*WebSocketCallbackPlugin, error) {
o := &WazeroConfig{
newRuntime: DefaultWazeroRuntime(),
moduleConfig: wazero.NewModuleConfig().WithStartFunctions("_initialize"),
}
for _, opt := range opts {
opt(o)
}
return &WebSocketCallbackPlugin{
newRuntime: o.newRuntime,
moduleConfig: o.moduleConfig,
}, nil
}
type webSocketCallback interface {
Close(ctx context.Context) error
WebSocketCallback
}
func (p *WebSocketCallbackPlugin) Load(ctx context.Context, pluginPath string) (webSocketCallback, error) {
b, err := os.ReadFile(pluginPath)
if err != nil {
return nil, err
}
// Create a new runtime so that multiple modules will not conflict
r, err := p.newRuntime(ctx)
if err != nil {
return nil, err
}
// Compile the WebAssembly module using the default configuration.
code, err := r.CompileModule(ctx, b)
if err != nil {
return nil, err
}
// InstantiateModule runs the "_start" function, WASI's "main".
module, err := r.InstantiateModule(ctx, code, p.moduleConfig)
if err != nil {
// Note: Most compilers do not exit the module after running "_start",
// unless there was an Error. This allows you to call exported functions.
if exitErr, ok := err.(*sys.ExitError); ok && exitErr.ExitCode() != 0 {
return nil, fmt.Errorf("unexpected exit_code: %d", exitErr.ExitCode())
} else if !ok {
return nil, err
}
}
// Compare API versions with the loading plugin
apiVersion := module.ExportedFunction("web_socket_callback_api_version")
if apiVersion == nil {
return nil, errors.New("web_socket_callback_api_version is not exported")
}
results, err := apiVersion.Call(ctx)
if err != nil {
return nil, err
} else if len(results) != 1 {
return nil, errors.New("invalid web_socket_callback_api_version signature")
}
if results[0] != WebSocketCallbackPluginAPIVersion {
return nil, fmt.Errorf("API version mismatch, host: %d, plugin: %d", WebSocketCallbackPluginAPIVersion, results[0])
}
ontextmessage := module.ExportedFunction("web_socket_callback_on_text_message")
if ontextmessage == nil {
return nil, errors.New("web_socket_callback_on_text_message is not exported")
}
onbinarymessage := module.ExportedFunction("web_socket_callback_on_binary_message")
if onbinarymessage == nil {
return nil, errors.New("web_socket_callback_on_binary_message is not exported")
}
onerror := module.ExportedFunction("web_socket_callback_on_error")
if onerror == nil {
return nil, errors.New("web_socket_callback_on_error is not exported")
}
onclose := module.ExportedFunction("web_socket_callback_on_close")
if onclose == nil {
return nil, errors.New("web_socket_callback_on_close is not exported")
}
malloc := module.ExportedFunction("malloc")
if malloc == nil {
return nil, errors.New("malloc is not exported")
}
free := module.ExportedFunction("free")
if free == nil {
return nil, errors.New("free is not exported")
}
return &webSocketCallbackPlugin{
runtime: r,
module: module,
malloc: malloc,
free: free,
ontextmessage: ontextmessage,
onbinarymessage: onbinarymessage,
onerror: onerror,
onclose: onclose,
}, nil
}
func (p *webSocketCallbackPlugin) Close(ctx context.Context) (err error) {
if r := p.runtime; r != nil {
r.Close(ctx)
}
return
}
type webSocketCallbackPlugin struct {
runtime wazero.Runtime
module api.Module
malloc api.Function
free api.Function
ontextmessage api.Function
onbinarymessage api.Function
onerror api.Function
onclose api.Function
}
func (p *webSocketCallbackPlugin) OnTextMessage(ctx context.Context, request *OnTextMessageRequest) (*OnTextMessageResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.ontextmessage.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(OnTextMessageResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
func (p *webSocketCallbackPlugin) OnBinaryMessage(ctx context.Context, request *OnBinaryMessageRequest) (*OnBinaryMessageResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.onbinarymessage.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(OnBinaryMessageResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
func (p *webSocketCallbackPlugin) OnError(ctx context.Context, request *OnErrorRequest) (*OnErrorResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.onerror.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(OnErrorResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}
func (p *webSocketCallbackPlugin) OnClose(ctx context.Context, request *OnCloseRequest) (*OnCloseResponse, error) {
data, err := request.MarshalVT()
if err != nil {
return nil, err
}
dataSize := uint64(len(data))
var dataPtr uint64
// If the input data is not empty, we must allocate the in-Wasm memory to store it, and pass to the plugin.
if dataSize != 0 {
results, err := p.malloc.Call(ctx, dataSize)
if err != nil {
return nil, err
}
dataPtr = results[0]
// This pointer is managed by the Wasm module, which is unaware of external usage.
// So, we have to free it when finished
defer p.free.Call(ctx, dataPtr)
// The pointer is a linear memory offset, which is where we write the name.
if !p.module.Memory().Write(uint32(dataPtr), data) {
return nil, fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", dataPtr, dataSize, p.module.Memory().Size())
}
}
ptrSize, err := p.onclose.Call(ctx, dataPtr, dataSize)
if err != nil {
return nil, err
}
resPtr := uint32(ptrSize[0] >> 32)
resSize := uint32(ptrSize[0])
var isErrResponse bool
if (resSize & (1 << 31)) > 0 {
isErrResponse = true
resSize &^= (1 << 31)
}
// We don't need the memory after deserialization: make sure it is freed.
if resPtr != 0 {
defer p.free.Call(ctx, uint64(resPtr))
}
// The pointer is a linear memory offset, which is where we write the name.
bytes, ok := p.module.Memory().Read(resPtr, resSize)
if !ok {
return nil, fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
resPtr, resSize, p.module.Memory().Size())
}
if isErrResponse {
return nil, errors.New(string(bytes))
}
response := new(OnCloseResponse)
if err = response.UnmarshalVT(bytes); err != nil {
return nil, err
}
return response, nil
}