From 73a4fd4a57badc543ffaffbe92252b0ea8f87d4a Mon Sep 17 00:00:00 2001 From: Daniel Vigovszky Date: Wed, 21 Feb 2024 18:01:02 +0100 Subject: [PATCH] GOL-209 Resource support (#3) --- Cargo.lock | 4 +- wasm-rpc-stubgen/example/main.wit | 34 ++ wasm-rpc-stubgen/src/main.rs | 2 +- wasm-rpc-stubgen/src/rust.rs | 269 ++++++++++++++-- wasm-rpc-stubgen/src/stub.rs | 210 ++++++++++-- wasm-rpc-stubgen/src/wit.rs | 89 ++++-- wasm-rpc/Cargo.toml | 2 +- wasm-rpc/proto/wasm/rpc/type.proto | 11 + wasm-rpc/proto/wasm/rpc/val.proto | 6 + wasm-rpc/proto/wasm/rpc/witvalue.proto | 5 + wasm-rpc/src/bindings.rs | 425 +++++++++++++------------ wasm-rpc/src/builder.rs | 26 +- wasm-rpc/src/extractor.rs | 35 +- wasm-rpc/src/json.rs | 41 ++- wasm-rpc/src/lib.rs | 26 +- wasm-rpc/src/protobuf.rs | 19 ++ wasm-rpc/wit/wasm-rpc.wit | 1 + 17 files changed, 925 insertions(+), 280 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5fbbc58..c0c633b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -618,9 +618,9 @@ dependencies = [ [[package]] name = "golem-wasm-ast" -version = "0.1.4" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cba6f849347531c4d4b7808091a5397cc7db8d5da2705a016e6ce3d71c2e20c" +checksum = "1ffc8f75ae9167c79cb48cef72c3d8bdc2e4d58f397a670866e6db95bdc2bc59" dependencies = [ "leb128", "mappable-rc", diff --git a/wasm-rpc-stubgen/example/main.wit b/wasm-rpc-stubgen/example/main.wit index f6af9a4d..04a7b5d2 100644 --- a/wasm-rpc-stubgen/example/main.wit +++ b/wasm-rpc-stubgen/example/main.wit @@ -32,6 +32,40 @@ interface iface1 { new-point: func(x: s32, y: s32, metadata: metadata) -> point; get-metadata: func() -> option; + + record product-item { + product-id: string, + name: string, + price: float32, + quantity: u32, + } + + record order { + order-id: string, + items: list, + total: float32, + timestamp: u64, + } + + record order-confirmation { + order-id: string, + } + + variant checkout-result { + error(string), + success(order-confirmation), + } + + resource cart { + constructor(user-id: string); + add-item: func(item: product-item) -> (); + remove-item: func(product-id: string) -> (); + update-item-quantity: func(product-id: string, quantity: u32) -> (); + checkout: func() -> checkout-result; + get-cart-contents: func() -> list; + merge-with: func(other-cart: borrow) -> (); + merge: static func(cart1: borrow, cart2: borrow) -> cart; + } } world api { diff --git a/wasm-rpc-stubgen/src/main.rs b/wasm-rpc-stubgen/src/main.rs index 051539d5..192bc6b9 100644 --- a/wasm-rpc-stubgen/src/main.rs +++ b/wasm-rpc-stubgen/src/main.rs @@ -60,7 +60,7 @@ fn render_error(result: anyhow::Result) -> Option { match result { Ok(value) => Some(value), Err(err) => { - eprintln!("Error: {}", err); + eprintln!("Error: {:?}", err); None } } diff --git a/wasm-rpc-stubgen/src/rust.rs b/wasm-rpc-stubgen/src/rust.rs index 5044177c..b1114617 100644 --- a/wasm-rpc-stubgen/src/rust.rs +++ b/wasm-rpc-stubgen/src/rust.rs @@ -20,7 +20,8 @@ use quote::quote; use std::fs; use wit_bindgen_rust::to_rust_ident; use wit_parser::{ - Enum, Flags, Record, Resolve, Result_, Tuple, Type, TypeDefKind, TypeOwner, Variant, + Enum, Flags, Handle, Record, Resolve, Result_, Tuple, Type, TypeDefKind, TypeId, TypeOwner, + Variant, }; pub fn generate_stub_source(def: &StubDefinition) -> anyhow::Result<()> { @@ -34,10 +35,38 @@ pub fn generate_stub_source(def: &StubDefinition) -> anyhow::Result<()> { for interface in &def.interfaces { let interface_ident = to_rust_ident(&interface.name).to_upper_camel_case(); let interface_name = Ident::new(&interface_ident, Span::call_site()); + + let additional_fields = if interface.is_resource() { + vec![quote! { + id: u64, + uri: golem_wasm_rpc::Uri + }] + } else { + vec![] + }; + let struct_fns: Vec = if interface.is_resource() { + vec![quote! { + pub fn from_remote_handle(uri: golem_wasm_rpc::Uri, id: u64) -> Self { + Self { + rpc: WasmRpc::new(&uri), + id, + uri, + } + } + }] + } else { + vec![] + }; + struct_defs.push(quote! { pub struct #interface_name { rpc: WasmRpc, - } + #(#additional_fields),* + } + + impl #interface_name { + #(#struct_fns)* + } }); } @@ -58,6 +87,24 @@ pub fn generate_stub_source(def: &StubDefinition) -> anyhow::Result<()> { } else { Some(&interface.name) }, + if interface.is_resource() { + FunctionMode::Method + } else { + FunctionMode::Global + }, + )?); + } + + for function in &interface.static_functions { + fn_impls.push(generate_function_stub_source( + def, + function, + if interface.global { + None + } else { + Some(&interface.name) + }, + FunctionMode::Static, )?); } @@ -67,21 +114,57 @@ pub fn generate_stub_source(def: &StubDefinition) -> anyhow::Result<()> { Span::call_site(), ); - interface_impls.push(quote! { - impl crate::bindings::exports::#root_ns::#root_name::#stub_interface_name::#guest_interface_name for #interface_name { + let constructor = if interface.is_resource() { + let constructor_stub = FunctionStub { + name: "new".to_string(), + params: interface.constructor_params.clone().unwrap_or_default(), + results: FunctionResultStub::SelfType, + }; + generate_function_stub_source( + def, + &constructor_stub, + Some(&interface.name), + FunctionMode::Constructor, + )? + } else { + quote! { fn new(location: crate::bindings::golem::rpc::types::Uri) -> Self { - let location = Uri { value: location.value }; + let location = golem_wasm_rpc::Uri { value: location.value }; Self { rpc: WasmRpc::new(&location) } } + } + }; + + interface_impls.push(quote! { + impl crate::bindings::exports::#root_ns::#root_name::#stub_interface_name::#guest_interface_name for #interface_name { + #constructor #(#fn_impls)* } }); + + if interface.is_resource() { + let remote_function_name = get_remote_function_name(def, "drop", Some(&interface.name)); + interface_impls.push(quote! { + impl Drop for #interface_name { + fn drop(&mut self) { + self.rpc.invoke_and_await( + #remote_function_name, + &[ + WitValue::builder().handle(self.uri.clone(), self.id) + ] + ).expect("Failed to invoke remote drop"); + } + } + }); + } } let lib = quote! { + #![allow(warnings)] + use golem_wasm_rpc::*; #[allow(dead_code)] @@ -104,16 +187,39 @@ pub fn generate_stub_source(def: &StubDefinition) -> anyhow::Result<()> { Ok(()) } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum FunctionMode { + Global, + Static, + Method, + Constructor, +} + fn generate_function_stub_source( def: &StubDefinition, function: &FunctionStub, interface_name: Option<&String>, + mode: FunctionMode, ) -> anyhow::Result { let function_name = Ident::new(&to_rust_ident(&function.name), Span::call_site()); let mut params = Vec::new(); let mut input_values = Vec::new(); let mut output_values = Vec::new(); + if mode != FunctionMode::Static && mode != FunctionMode::Constructor { + params.push(quote! {&self}); + } + + if mode == FunctionMode::Constructor { + params.push(quote! { location: crate::bindings::golem::rpc::types::Uri }); + } + + if mode == FunctionMode::Method { + input_values.push(quote! { + WitValue::builder().handle(self.uri.clone(), self.id) + }); + } + for param in &function.params { let param_name = Ident::new(&to_rust_ident(¶m.name), Span::call_site()); let param_typ = type_to_rust_ident(¶m.typ, &def.resolve)?; @@ -156,6 +262,7 @@ fn generate_function_stub_source( } } } + FunctionResultStub::SelfType => quote! { Self }, }; match &function.results { @@ -175,25 +282,58 @@ fn generate_function_stub_source( )?); } } + FunctionResultStub::SelfType if mode == FunctionMode::Constructor => { + output_values.push(quote! { + { + let (uri, id) = result.handle().expect("handle not found"); + Self { + rpc, + id, + uri + } + } + }); + } + FunctionResultStub::SelfType => { + return Err(anyhow!( + "SelfType result is only supported for constructors" + )); + } } - let remote_function_name = match interface_name { - Some(remote_interface) => format!( - "{}:{}/{}/{}", - def.root_package_name.namespace, - def.root_package_name.name, - remote_interface, - function.name - ), - None => format!( - "{}:{}/{}", - def.root_package_name.namespace, def.root_package_name.name, function.name - ), + let remote_function_name = get_remote_function_name(def, &function.name, interface_name); + + let rpc = match mode { + FunctionMode::Static => { + let first_param = function + .params + .first() + .ok_or(anyhow!("static function has no params"))?; + let first_param_ident = + Ident::new(&to_rust_ident(&first_param.name), Span::call_site()); + quote! { #first_param_ident.rpc } + } + FunctionMode::Constructor => { + quote! { rpc } + } + _ => { + quote! { self.rpc } + } + }; + + let init = if mode == FunctionMode::Constructor { + quote! { + let location = golem_wasm_rpc::Uri { value: location.value }; + let rpc = WasmRpc::new(&location); + } + } else { + quote! {} }; Ok(quote! { - fn #function_name(&self, #(#params),*) -> #result_type { - let result = self.rpc.invoke_and_await( + fn #function_name(#(#params),*) -> #result_type { + #init + let result = #rpc.invoke_and_await( #remote_function_name, &[ #(#input_values),* @@ -204,6 +344,26 @@ fn generate_function_stub_source( }) } +fn get_remote_function_name( + def: &StubDefinition, + function_name: &str, + interface_name: Option<&String>, +) -> String { + match interface_name { + Some(remote_interface) => format!( + "{}:{}/{}/{}", + def.root_package_name.namespace, + def.root_package_name.name, + remote_interface, + function_name + ), + None => format!( + "{}:{}/{}", + def.root_package_name.namespace, def.root_package_name.name, function_name + ), + } +} + fn type_to_rust_ident(typ: &Type, resolve: &Resolve) -> anyhow::Result { match typ { Type::Bool => Ok(quote! { bool }), @@ -253,6 +413,19 @@ fn type_to_rust_ident(typ: &Type, resolve: &Resolve) -> anyhow::Result }) } + TypeDefKind::Handle(handle) => { + let (type_id, is_ref) = match handle { + Handle::Own(type_id) => (type_id, false), + Handle::Borrow(type_id) => (type_id, true), + }; + + let ident = resource_type_ident(type_id, resolve)?; + if is_ref { + Ok(quote! { &#ident }) + } else { + Ok(quote! { wit_bindgen::rt::Resource<#ident> }) + } + } _ => { let typ = Ident::new( &to_rust_ident(typedef.name.as_ref().ok_or(anyhow!("type has no name"))?) @@ -321,6 +494,25 @@ fn type_to_rust_ident(typ: &Type, resolve: &Resolve) -> anyhow::Result anyhow::Result { + let typedef = resolve + .types + .get(*type_id) + .ok_or(anyhow!("type not found"))?; + + let ident = Ident::new( + &to_rust_ident( + typedef + .name + .as_ref() + .ok_or(anyhow!("Handle's inner type has no name"))?, + ) + .to_upper_camel_case(), + Span::call_site(), + ); + Ok(ident) +} + fn wit_value_builder( typ: &Type, name: &TokenStream, @@ -376,8 +568,12 @@ fn wit_value_builder( TypeDefKind::Record(record) => { wit_record_value_builder(record, name, resolve, builder_expr) } - TypeDefKind::Resource => Ok(quote!(todo!("resource support"))), - TypeDefKind::Handle(_) => Ok(quote!(todo!("resource support"))), + TypeDefKind::Resource => Err(anyhow!("Resource cannot directly appear in a function signature, just through a Handle")), + TypeDefKind::Handle(_) => { + Ok(quote! { + #builder_expr.handle(#name.uri.clone(), #name.id) + }) + } TypeDefKind::Flags(flags) => { wit_flags_value_builder(flags, typ, name, resolve, builder_expr) } @@ -693,8 +889,8 @@ fn extract_from_wit_value( TypeDefKind::Record(record) => { extract_from_record_value(record, typ, resolve, base_expr) } - TypeDefKind::Resource => Ok(quote!(todo!("resource support"))), - TypeDefKind::Handle(_) => Ok(quote!(todo!("resource support"))), + TypeDefKind::Resource => Err(anyhow!("Resource cannot directly appear in a function signature, just through a Handle")), + TypeDefKind::Handle(handle) => extract_from_handle_value(handle, resolve, base_expr), TypeDefKind::Flags(flags) => { extract_from_flags_value(flags, typ, resolve, base_expr) } @@ -930,3 +1126,30 @@ fn extract_from_list_value( #base_expr.list_elements(|item| #inner_expr).expect("list not found") }) } + +fn extract_from_handle_value( + handle: &Handle, + resolve: &Resolve, + base_expr: TokenStream, +) -> anyhow::Result { + match handle { + Handle::Own(type_id) => { + let ident = resource_type_ident(type_id, resolve)?; + Ok(quote! { + { + let (uri, id) = #base_expr.handle().expect("handle not found"); + wit_bindgen::rt::Resource::new(#ident::from_remote_handle(uri, id)) + } + }) + } + Handle::Borrow(type_id) => { + let ident = resource_type_ident(type_id, resolve)?; + Ok(quote! { + { + let (uri, id) = #base_expr.handle().expect("handle not found"); + #ident::from_remote_handle(uri, id) + } + }) + } + } +} diff --git a/wasm-rpc-stubgen/src/stub.rs b/wasm-rpc-stubgen/src/stub.rs index 0774c5c9..7465fd36 100644 --- a/wasm-rpc-stubgen/src/stub.rs +++ b/wasm-rpc-stubgen/src/stub.rs @@ -18,7 +18,7 @@ use std::collections::{BTreeMap, HashSet}; use std::fs; use std::path::{Path, PathBuf}; use wit_parser::{ - Function, FunctionKind, PackageName, Resolve, Results, Type, TypeId, TypeOwner, + Function, FunctionKind, PackageName, Resolve, Results, Type, TypeDefKind, TypeId, TypeOwner, UnresolvedPackage, World, WorldId, WorldItem, }; @@ -121,33 +121,88 @@ impl StubDefinition { } } +#[derive(Debug, Clone)] pub struct InterfaceStub { pub name: String, + pub constructor_params: Option>, pub functions: Vec, + pub static_functions: Vec, pub imports: Vec, pub global: bool, } -#[derive(Hash, PartialEq, Eq)] +impl InterfaceStub { + pub fn is_resource(&self) -> bool { + self.constructor_params.is_some() + } +} + +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct InterfaceStubImport { pub name: String, pub path: String, } +#[derive(Debug, Clone)] pub struct FunctionStub { pub name: String, pub params: Vec, pub results: FunctionResultStub, } +impl FunctionStub { + pub fn as_method(&self) -> Option { + self.name.strip_prefix("[method]").and_then(|method_name| { + let parts = method_name.split('.').collect::>(); + if parts.len() != 2 { + None + } else { + Some(FunctionStub { + name: parts[1].to_string(), + params: self + .params + .iter() + .filter(|p| p.name != "self") + .cloned() + .collect(), + results: self.results.clone(), + }) + } + }) + } + + pub fn as_static(&self) -> Option { + self.name.strip_prefix("[static]").and_then(|method_name| { + let parts = method_name.split('.').collect::>(); + if parts.len() != 2 { + None + } else { + Some(FunctionStub { + name: parts[1].to_string(), + params: self + .params + .iter() + .filter(|p| p.name != "self") + .cloned() + .collect(), + results: self.results.clone(), + }) + } + }) + } +} + +#[derive(Debug, Clone)] pub struct FunctionParamStub { pub name: String, pub typ: Type, } +#[derive(Debug, Clone)] pub enum FunctionResultStub { Single(Type), Multi(Vec), + SelfType, } impl FunctionResultStub { @@ -155,6 +210,7 @@ impl FunctionResultStub { match self { FunctionResultStub::Single(_) => false, FunctionResultStub::Multi(params) => params.is_empty(), + FunctionResultStub::SelfType => false, } } } @@ -170,29 +226,32 @@ fn collect_stub_imports<'a>( .types .get(*typ) .ok_or(anyhow!("type {typ:?} not found"))?; - match typ.owner { - TypeOwner::World(world_id) => { - let _world = resolve - .worlds - .get(world_id) - .ok_or(anyhow!("world {world_id:?} not found"))?; - } - TypeOwner::Interface(interface_id) => { - let interface = resolve - .interfaces - .get(interface_id) - .ok_or(anyhow!("interface {interface_id:?} not found"))?; - let package = interface.package.and_then(|id| resolve.packages.get(id)); - let interface_name = interface.name.clone().unwrap_or("unknown".to_string()); - let interface_path = package - .map(|p| p.name.interface_id(&interface_name)) - .unwrap_or(interface_name); - imports.push(InterfaceStubImport { - name: name.clone(), - path: interface_path, - }); + if typ.kind != TypeDefKind::Resource { + // We will redefine resources so no need to import them + match typ.owner { + TypeOwner::World(world_id) => { + let _world = resolve + .worlds + .get(world_id) + .ok_or(anyhow!("world {world_id:?} not found"))?; + } + TypeOwner::Interface(interface_id) => { + let interface = resolve + .interfaces + .get(interface_id) + .ok_or(anyhow!("interface {interface_id:?} not found"))?; + let package = interface.package.and_then(|id| resolve.packages.get(id)); + let interface_name = interface.name.clone().unwrap_or("unknown".to_string()); + let interface_path = package + .map(|p| p.name.interface_id(&interface_name)) + .unwrap_or(interface_name); + imports.push(InterfaceStubImport { + name: name.clone(), + path: interface_path, + }); + } + TypeOwner::None => {} } - TypeOwner::None => {} } } @@ -226,23 +285,39 @@ fn collect_stub_interfaces(resolve: &Resolve, world: &World) -> anyhow::Result( functions: impl Iterator, ) -> anyhow::Result> { Ok(functions - .filter(|f| f.kind == FunctionKind::Freestanding) .map(|f| { let mut params = Vec::new(); for (name, typ) in &f.params { @@ -286,6 +360,88 @@ fn collect_stub_functions<'a>( .collect()) } +fn collect_stub_resources<'a>( + types: impl Iterator, + resolve: &'a Resolve, +) -> anyhow::Result> { + let mut interfaces = Vec::new(); + for (_name, type_id) in types { + let typ = resolve + .types + .get(*type_id) + .ok_or(anyhow!("type {type_id:?} not found"))?; + if typ.kind == TypeDefKind::Resource { + match typ.owner { + TypeOwner::World(_) => {} + TypeOwner::Interface(iface_id) => { + let iface = resolve + .interfaces + .get(iface_id) + .ok_or(anyhow!("interface {iface_id:?} not found"))?; + + let constructors = iface + .functions + .values() + .filter(|f| f.kind == FunctionKind::Constructor(*type_id)) + .collect::>(); + let methods = iface + .functions + .values() + .filter(|f| f.kind == FunctionKind::Method(*type_id)) + .collect::>(); + let statics = iface + .functions + .values() + .filter(|f| f.kind == FunctionKind::Static(*type_id)) + .collect::>(); + + let functions = collect_stub_functions(methods.into_iter())? + .into_iter() + .map(|f| { + f.as_method() + .ok_or(anyhow!("Non-method function found among resource methods")) + }) + .collect::, _>>()?; + let static_functions = collect_stub_functions(statics.into_iter())? + .into_iter() + .map(|f| { + f.as_static() + .ok_or(anyhow!("Non-static function found among resource statics")) + }) + .collect::, _>>()?; + + let imports = collect_stub_imports(iface.types.iter(), resolve)?; + + let constructor_params = constructors.first().map(|c| { + c.params + .iter() + .map(|(n, t)| FunctionParamStub { + name: n.clone(), + typ: *t, + }) + .collect::>() + }); + + interfaces.push(InterfaceStub { + name: typ + .name + .as_ref() + .ok_or(anyhow!("Resource type has no name"))? + .clone(), + functions, + imports, + global: false, + constructor_params, + static_functions, + }); + } + TypeOwner::None => {} + } + } + } + Ok(interfaces) +} + // https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md fn visit<'a>( diff --git a/wasm-rpc-stubgen/src/wit.rs b/wasm-rpc-stubgen/src/wit.rs index c0db8284..0716f47c 100644 --- a/wasm-rpc-stubgen/src/wit.rs +++ b/wasm-rpc-stubgen/src/wit.rs @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::stub::{FunctionResultStub, StubDefinition}; +use crate::stub::{FunctionParamStub, FunctionResultStub, StubDefinition}; use anyhow::{anyhow, bail}; use indexmap::IndexSet; use std::fmt::Write; use std::fs; use std::path::Path; -use wit_parser::{Resolve, Type, TypeDefKind}; +use wit_parser::{Handle, Resolve, Type, TypeDefKind}; pub fn generate_stub_wit(def: &StubDefinition) -> anyhow::Result<()> { let world = def.resolve.worlds.get(def.world_id).unwrap(); @@ -43,20 +43,44 @@ pub fn generate_stub_wit(def: &StubDefinition) -> anyhow::Result<()> { for interface in &def.interfaces { writeln!(out, " resource {} {{", &interface.name)?; - writeln!(out, " constructor(location: uri);")?; + match &interface.constructor_params { + None => { + writeln!(out, " constructor(location: uri);")?; + } + Some(params) => { + write!(out, " constructor(location: uri")?; + if !params.is_empty() { + write!(out, ", ")?; + } + write_param_list(&mut out, def, params)?; + writeln!(out, ");")?; + } + } for function in &interface.functions { write!(out, " {}: func(", function.name)?; - for (idx, param) in function.params.iter().enumerate() { - write!( - out, - "{}: {}", - param.name, - param.typ.wit_type_string(&def.resolve)? - )?; - if idx < function.params.len() - 1 { - write!(out, ", ")?; + write_param_list(&mut out, def, &function.params)?; + write!(out, ")")?; + if !function.results.is_empty() { + write!(out, " -> ")?; + match &function.results { + FunctionResultStub::Single(typ) => { + write!(out, "{}", typ.wit_type_string(&def.resolve)?)?; + } + FunctionResultStub::Multi(params) => { + write!(out, "(")?; + write_param_list(&mut out, def, params)?; + write!(out, ")")?; + } + FunctionResultStub::SelfType => { + return Err(anyhow!("Unexpected return type in wit generator")) + } } } + writeln!(out, ";")?; + } + for function in &interface.static_functions { + write!(out, " {}: static func(", function.name)?; + write_param_list(&mut out, def, &function.params)?; write!(out, ")")?; if !function.results.is_empty() { write!(out, " -> ")?; @@ -66,19 +90,12 @@ pub fn generate_stub_wit(def: &StubDefinition) -> anyhow::Result<()> { } FunctionResultStub::Multi(params) => { write!(out, "(")?; - for (idx, param) in params.iter().enumerate() { - write!( - out, - "{}: {}", - param.name, - param.typ.wit_type_string(&def.resolve)? - )?; - if idx < params.len() - 1 { - write!(out, ", ")?; - } - } + write_param_list(&mut out, def, params)?; write!(out, ")")?; } + FunctionResultStub::SelfType => { + return Err(anyhow!("Unexpected return type in wit generator")) + } } } writeln!(out, ";")?; @@ -103,6 +120,25 @@ pub fn generate_stub_wit(def: &StubDefinition) -> anyhow::Result<()> { Ok(()) } +fn write_param_list( + out: &mut String, + def: &StubDefinition, + params: &[FunctionParamStub], +) -> anyhow::Result<()> { + for (idx, param) in params.iter().enumerate() { + write!( + out, + "{}: {}", + param.name, + param.typ.wit_type_string(&def.resolve)? + )?; + if idx < params.len() - 1 { + write!(out, ", ")?; + } + } + Ok(()) +} + pub fn copy_wit_files(def: &StubDefinition) -> anyhow::Result<()> { let mut all = def.unresolved_deps.clone(); all.push(def.unresolved_root.clone()); @@ -223,6 +259,13 @@ impl TypeExtensions for Type { bail!("result type has no ok or err types") } }, + TypeDefKind::Handle(handle) => match handle { + Handle::Own(type_id) => Type::Id(*type_id).wit_type_string(resolve), + Handle::Borrow(type_id) => Ok(format!( + "borrow<{}>", + Type::Id(*type_id).wit_type_string(resolve)? + )), + }, _ => { let name = typ .name diff --git a/wasm-rpc/Cargo.toml b/wasm-rpc/Cargo.toml index 315ddc23..9e167fb7 100644 --- a/wasm-rpc/Cargo.toml +++ b/wasm-rpc/Cargo.toml @@ -18,7 +18,7 @@ wit-bindgen = { version = "0.17.0", default-features = false, features = ["reall arbitrary = { version = "1.3.2", features = ["derive"], optional = true } bigdecimal = { version = "0.4.2", optional = true } bincode = { version = "2.0.0-rc.3", optional = true } -golem-wasm-ast = { version = "0.1.4", features = ["analysis"], optional = true } +golem-wasm-ast = { version = "0.2.0", features = ["analysis"], optional = true } serde = { version = "1.0.113", optional = true } serde_json = { version = "1.0.113", optional = true } prost = { version = "0.12.3", optional = true } diff --git a/wasm-rpc/proto/wasm/rpc/type.proto b/wasm-rpc/proto/wasm/rpc/type.proto index 995b4575..89dad88a 100644 --- a/wasm-rpc/proto/wasm/rpc/type.proto +++ b/wasm-rpc/proto/wasm/rpc/type.proto @@ -13,6 +13,7 @@ message Type { TypeOption option = 8; TypeResult result = 9; TypeVariant variant = 10; + TypeHandle handle = 11; } } @@ -53,6 +54,11 @@ message TypeVariant { repeated NameOptionTypePair cases = 1; } +message TypeHandle { + uint64 resource_id = 1; + ResourceMode mode = 2; +} + message NameTypePair { string name = 1; Type typ = 2; @@ -78,3 +84,8 @@ enum PrimitiveType { CHR = 11; STR = 12; } + +enum ResourceMode { + BORROWED = 0; + OWNED = 1; +} \ No newline at end of file diff --git a/wasm-rpc/proto/wasm/rpc/val.proto b/wasm-rpc/proto/wasm/rpc/val.proto index 9a2ea5af..a5698ebe 100644 --- a/wasm-rpc/proto/wasm/rpc/val.proto +++ b/wasm-rpc/proto/wasm/rpc/val.proto @@ -25,6 +25,7 @@ message Val { ValOption option = 20; ValResult result = 21; ValFlags flags = 22; + ValHandle handle = 23; } } @@ -62,4 +63,9 @@ message ValResult { message ValFlags { int32 count = 2; repeated int32 value = 3; +} + +message ValHandle { + string uri = 1; + uint64 value = 2; } \ No newline at end of file diff --git a/wasm-rpc/proto/wasm/rpc/witvalue.proto b/wasm-rpc/proto/wasm/rpc/witvalue.proto index eaf1bf9b..706b7051 100644 --- a/wasm-rpc/proto/wasm/rpc/witvalue.proto +++ b/wasm-rpc/proto/wasm/rpc/witvalue.proto @@ -29,6 +29,7 @@ message WitNode { WitPrimCharNode char = 19; WitPrimBoolNode bool = 20; WitPrimStringNode string = 21; + WitHandleNode handle = 22; } } @@ -118,3 +119,7 @@ message WitPrimStringNode { string value = 1; } +message WitHandleNode { + string uri = 1; + uint64 value = 2; +} \ No newline at end of file diff --git a/wasm-rpc/src/bindings.rs b/wasm-rpc/src/bindings.rs index 4f3b578a..ec7a918c 100644 --- a/wasm-rpc/src/bindings.rs +++ b/wasm-rpc/src/bindings.rs @@ -10,6 +10,15 @@ pub mod golem { static __FORCE_SECTION_REF: fn() = super::super::super::__link_section; pub type NodeIndex = i32; #[derive(Clone)] + pub struct Uri { + pub value: wit_bindgen::rt::string::String, + } + impl ::core::fmt::Debug for Uri { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_struct("Uri").field("value", &self.value).finish() + } + } + #[derive(Clone)] pub enum WitNode{ RecordValue(wit_bindgen::rt::vec::Vec::), VariantValue((u32,Option,)), @@ -32,6 +41,7 @@ pub mod golem { PrimChar(char), PrimBool(bool), PrimString(wit_bindgen::rt::string::String), + Handle((Uri,u64,)), } impl ::core::fmt::Debug for WitNode { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { @@ -99,6 +109,9 @@ pub mod golem { WitNode::PrimString(e) => { f.debug_tuple("WitNode::PrimString").field(e).finish() } + WitNode::Handle(e) => { + f.debug_tuple("WitNode::Handle").field(e).finish() + } } } } @@ -112,15 +125,6 @@ pub mod golem { } } #[derive(Clone)] - pub struct Uri { - pub value: wit_bindgen::rt::string::String, - } - impl ::core::fmt::Debug for Uri { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("Uri").field("value", &self.value).finish() - } - } - #[derive(Clone)] pub enum RpcError{ ProtocolError(wit_bindgen::rt::string::String), Denied(wit_bindgen::rt::string::String), @@ -239,40 +243,40 @@ pub mod golem { let vec0 = function_name; let ptr0 = vec0.as_ptr() as i32; let len0 = vec0.len() as i32; - let vec9 = function_params; - let len9 = vec9.len() as i32; - let layout9 = alloc::Layout::from_size_align_unchecked(vec9.len() * 8, 4); - let result9 = if layout9.size() != 0 + let vec12 = function_params; + let len12 = vec12.len() as i32; + let layout12 = alloc::Layout::from_size_align_unchecked(vec12.len() * 8, 4); + let result12 = if layout12.size() != 0 { - let ptr = alloc::alloc(layout9); + let ptr = alloc::alloc(layout12); if ptr.is_null() { - alloc::handle_alloc_error(layout9); + alloc::handle_alloc_error(layout12); } ptr }else {{ ::core::ptr::null_mut() }}; - for (i, e) in vec9.into_iter().enumerate() { - let base = result9 as i32 + (i as i32) * 8; + for (i, e) in vec12.into_iter().enumerate() { + let base = result12 as i32 + (i as i32) * 8; { let WitValue{ nodes:nodes1, } = e; - let vec8 = nodes1; - let len8 = vec8.len() as i32; - let layout8 = alloc::Layout::from_size_align_unchecked(vec8.len() * 24, 8); - let result8 = if layout8.size() != 0 + let vec11 = nodes1; + let len11 = vec11.len() as i32; + let layout11 = alloc::Layout::from_size_align_unchecked(vec11.len() * 24, 8); + let result11 = if layout11.size() != 0 { - let ptr = alloc::alloc(layout8); + let ptr = alloc::alloc(layout11); if ptr.is_null() { - alloc::handle_alloc_error(layout8); + alloc::handle_alloc_error(layout11); } ptr }else {{ ::core::ptr::null_mut() }}; - for (i, e) in vec8.into_iter().enumerate() { - let base = result8 as i32 + (i as i32) * 24; + for (i, e) in vec11.into_iter().enumerate() { + let base = result11 as i32 + (i as i32) * 24; { match e { WitNode::RecordValue(e) => { @@ -443,15 +447,26 @@ pub mod golem { *((base + 12) as *mut i32) = len7; *((base + 8) as *mut i32) = ptr7; }, + WitNode::Handle(e) => { + *((base + 0) as *mut u8) = (21i32) as u8; + let (t8_0, t8_1, ) = e; + let Uri{ value:value9, } = t8_0; + let vec10 = value9; + let ptr10 = vec10.as_ptr() as i32; + let len10 = vec10.len() as i32; + *((base + 12) as *mut i32) = len10; + *((base + 8) as *mut i32) = ptr10; + *((base + 16) as *mut i64) = wit_bindgen::rt::as_i64(t8_1); + }, } } } - *((base + 4) as *mut i32) = len8; - *((base + 0) as *mut i32) = result8 as i32; - cleanup_list.extend_from_slice(&[(result8, layout8),]); + *((base + 4) as *mut i32) = len11; + *((base + 0) as *mut i32) = result11 as i32; + cleanup_list.extend_from_slice(&[(result11, layout11),]); } } - let ptr10 = ret_area.as_mut_ptr() as i32; + let ptr13 = ret_area.as_mut_ptr() as i32; #[cfg(target_arch = "wasm32")] #[link(wasm_import_module = "golem:rpc/types@0.1.0")] extern "C" { @@ -461,10 +476,10 @@ pub mod golem { #[cfg(not(target_arch = "wasm32"))] fn wit_import(_: i32, _: i32, _: i32, _: i32, _: i32, _: i32, ){ unreachable!() } - wit_import((self).handle() as i32, ptr0, len0, result9 as i32, len9, ptr10); - let l11 = i32::from(*((ptr10 + 0) as *const u8)); - if layout9.size() != 0 { - alloc::dealloc(result9, layout9); + wit_import((self).handle() as i32, ptr0, len0, result12 as i32, len12, ptr13); + let l14 = i32::from(*((ptr13 + 0) as *const u8)); + if layout12.size() != 0 { + alloc::dealloc(result12, layout12); } for (ptr, layout) in cleanup_list { @@ -475,134 +490,134 @@ pub mod golem { } } - match l11 { + match l14 { 0 => { let e = { - let l12 = *((ptr10 + 4) as *const i32); - let l13 = *((ptr10 + 8) as *const i32); - let base55 = l12; - let len55 = l13; - let mut result55 = Vec::with_capacity(len55 as usize); - for i in 0..len55 { - let base = base55 + i * 24; - let e55 = { - let l14 = i32::from(*((base + 0) as *const u8)); - let v54 = match l14 { + let l15 = *((ptr13 + 4) as *const i32); + let l16 = *((ptr13 + 8) as *const i32); + let base62 = l15; + let len62 = l16; + let mut result62 = Vec::with_capacity(len62 as usize); + for i in 0..len62 { + let base = base62 + i * 24; + let e62 = { + let l17 = i32::from(*((base + 0) as *const u8)); + let v61 = match l17 { 0 => { - let e54 = { - let l15 = *((base + 8) as *const i32); - let l16 = *((base + 12) as *const i32); - let len17 = l16 as usize; + let e61 = { + let l18 = *((base + 8) as *const i32); + let l19 = *((base + 12) as *const i32); + let len20 = l19 as usize; - Vec::from_raw_parts(l15 as *mut _, len17, len17) + Vec::from_raw_parts(l18 as *mut _, len20, len20) }; - WitNode::RecordValue(e54) + WitNode::RecordValue(e61) } 1 => { - let e54 = { - let l18 = *((base + 8) as *const i32); - let l19 = i32::from(*((base + 12) as *const u8)); + let e61 = { + let l21 = *((base + 8) as *const i32); + let l22 = i32::from(*((base + 12) as *const u8)); - (l18 as u32, match l19 { + (l21 as u32, match l22 { 0 => None, 1 => { let e = { - let l20 = *((base + 16) as *const i32); + let l23 = *((base + 16) as *const i32); - l20 + l23 }; Some(e) } _ => wit_bindgen::rt::invalid_enum_discriminant(), }) }; - WitNode::VariantValue(e54) + WitNode::VariantValue(e61) } 2 => { - let e54 = { - let l21 = *((base + 8) as *const i32); + let e61 = { + let l24 = *((base + 8) as *const i32); - l21 as u32 + l24 as u32 }; - WitNode::EnumValue(e54) + WitNode::EnumValue(e61) } 3 => { - let e54 = { - let l22 = *((base + 8) as *const i32); - let l23 = *((base + 12) as *const i32); - let base25 = l22; - let len25 = l23; - let mut result25 = Vec::with_capacity(len25 as usize); - for i in 0..len25 { - let base = base25 + i * 1; - let e25 = { - let l24 = i32::from(*((base + 0) as *const u8)); + let e61 = { + let l25 = *((base + 8) as *const i32); + let l26 = *((base + 12) as *const i32); + let base28 = l25; + let len28 = l26; + let mut result28 = Vec::with_capacity(len28 as usize); + for i in 0..len28 { + let base = base28 + i * 1; + let e28 = { + let l27 = i32::from(*((base + 0) as *const u8)); - wit_bindgen::rt::bool_lift(l24 as u8) + wit_bindgen::rt::bool_lift(l27 as u8) }; - result25.push(e25); + result28.push(e28); } - wit_bindgen::rt::dealloc(base25, (len25 as usize) * 1, 1); + wit_bindgen::rt::dealloc(base28, (len28 as usize) * 1, 1); - result25 + result28 }; - WitNode::FlagsValue(e54) + WitNode::FlagsValue(e61) } 4 => { - let e54 = { - let l26 = *((base + 8) as *const i32); - let l27 = *((base + 12) as *const i32); - let len28 = l27 as usize; - - Vec::from_raw_parts(l26 as *mut _, len28, len28) - }; - WitNode::TupleValue(e54) - } - 5 => { - let e54 = { + let e61 = { let l29 = *((base + 8) as *const i32); let l30 = *((base + 12) as *const i32); let len31 = l30 as usize; Vec::from_raw_parts(l29 as *mut _, len31, len31) }; - WitNode::ListValue(e54) + WitNode::TupleValue(e61) + } + 5 => { + let e61 = { + let l32 = *((base + 8) as *const i32); + let l33 = *((base + 12) as *const i32); + let len34 = l33 as usize; + + Vec::from_raw_parts(l32 as *mut _, len34, len34) + }; + WitNode::ListValue(e61) } 6 => { - let e54 = { - let l32 = i32::from(*((base + 8) as *const u8)); + let e61 = { + let l35 = i32::from(*((base + 8) as *const u8)); - match l32 { + match l35 { 0 => None, 1 => { let e = { - let l33 = *((base + 12) as *const i32); + let l36 = *((base + 12) as *const i32); - l33 + l36 }; Some(e) } _ => wit_bindgen::rt::invalid_enum_discriminant(), } }; - WitNode::OptionValue(e54) + WitNode::OptionValue(e61) } 7 => { - let e54 = { - let l34 = i32::from(*((base + 8) as *const u8)); + let e61 = { + let l37 = i32::from(*((base + 8) as *const u8)); - match l34 { + match l37 { 0 => { let e = { - let l35 = i32::from(*((base + 12) as *const u8)); + let l38 = i32::from(*((base + 12) as *const u8)); - match l35 { + match l38 { 0 => None, 1 => { let e = { - let l36 = *((base + 16) as *const i32); + let l39 = *((base + 16) as *const i32); - l36 + l39 }; Some(e) } @@ -613,15 +628,15 @@ pub mod golem { } 1 => { let e = { - let l37 = i32::from(*((base + 12) as *const u8)); + let l40 = i32::from(*((base + 12) as *const u8)); - match l37 { + match l40 { 0 => None, 1 => { let e = { - let l38 = *((base + 16) as *const i32); + let l41 = *((base + 16) as *const i32); - l38 + l41 }; Some(e) } @@ -633,182 +648,196 @@ pub mod golem { _ => wit_bindgen::rt::invalid_enum_discriminant(), } }; - WitNode::ResultValue(e54) + WitNode::ResultValue(e61) } 8 => { - let e54 = { - let l39 = i32::from(*((base + 8) as *const u8)); + let e61 = { + let l42 = i32::from(*((base + 8) as *const u8)); - l39 as u8 + l42 as u8 }; - WitNode::PrimU8(e54) + WitNode::PrimU8(e61) } 9 => { - let e54 = { - let l40 = i32::from(*((base + 8) as *const u16)); + let e61 = { + let l43 = i32::from(*((base + 8) as *const u16)); - l40 as u16 + l43 as u16 }; - WitNode::PrimU16(e54) + WitNode::PrimU16(e61) } 10 => { - let e54 = { - let l41 = *((base + 8) as *const i32); + let e61 = { + let l44 = *((base + 8) as *const i32); - l41 as u32 + l44 as u32 }; - WitNode::PrimU32(e54) + WitNode::PrimU32(e61) } 11 => { - let e54 = { - let l42 = *((base + 8) as *const i64); + let e61 = { + let l45 = *((base + 8) as *const i64); - l42 as u64 + l45 as u64 }; - WitNode::PrimU64(e54) + WitNode::PrimU64(e61) } 12 => { - let e54 = { - let l43 = i32::from(*((base + 8) as *const i8)); + let e61 = { + let l46 = i32::from(*((base + 8) as *const i8)); - l43 as i8 + l46 as i8 }; - WitNode::PrimS8(e54) + WitNode::PrimS8(e61) } 13 => { - let e54 = { - let l44 = i32::from(*((base + 8) as *const i16)); + let e61 = { + let l47 = i32::from(*((base + 8) as *const i16)); - l44 as i16 + l47 as i16 }; - WitNode::PrimS16(e54) + WitNode::PrimS16(e61) } 14 => { - let e54 = { - let l45 = *((base + 8) as *const i32); + let e61 = { + let l48 = *((base + 8) as *const i32); - l45 + l48 }; - WitNode::PrimS32(e54) + WitNode::PrimS32(e61) } 15 => { - let e54 = { - let l46 = *((base + 8) as *const i64); + let e61 = { + let l49 = *((base + 8) as *const i64); - l46 + l49 }; - WitNode::PrimS64(e54) + WitNode::PrimS64(e61) } 16 => { - let e54 = { - let l47 = *((base + 8) as *const f32); + let e61 = { + let l50 = *((base + 8) as *const f32); - l47 + l50 }; - WitNode::PrimFloat32(e54) + WitNode::PrimFloat32(e61) } 17 => { - let e54 = { - let l48 = *((base + 8) as *const f64); + let e61 = { + let l51 = *((base + 8) as *const f64); - l48 + l51 }; - WitNode::PrimFloat64(e54) + WitNode::PrimFloat64(e61) } 18 => { - let e54 = { - let l49 = *((base + 8) as *const i32); + let e61 = { + let l52 = *((base + 8) as *const i32); - wit_bindgen::rt::char_lift(l49 as u32) + wit_bindgen::rt::char_lift(l52 as u32) }; - WitNode::PrimChar(e54) + WitNode::PrimChar(e61) } 19 => { - let e54 = { - let l50 = i32::from(*((base + 8) as *const u8)); + let e61 = { + let l53 = i32::from(*((base + 8) as *const u8)); + + wit_bindgen::rt::bool_lift(l53 as u8) + }; + WitNode::PrimBool(e61) + } + 20 => { + let e61 = { + let l54 = *((base + 8) as *const i32); + let l55 = *((base + 12) as *const i32); + let len56 = l55 as usize; + let bytes56 = Vec::from_raw_parts(l54 as *mut _, len56, len56); - wit_bindgen::rt::bool_lift(l50 as u8) + wit_bindgen::rt::string_lift(bytes56) }; - WitNode::PrimBool(e54) + WitNode::PrimString(e61) } n => { - debug_assert_eq!(n, 20, "invalid enum discriminant"); - let e54 = { - let l51 = *((base + 8) as *const i32); - let l52 = *((base + 12) as *const i32); - let len53 = l52 as usize; - let bytes53 = Vec::from_raw_parts(l51 as *mut _, len53, len53); + debug_assert_eq!(n, 21, "invalid enum discriminant"); + let e61 = { + let l57 = *((base + 8) as *const i32); + let l58 = *((base + 12) as *const i32); + let len59 = l58 as usize; + let bytes59 = Vec::from_raw_parts(l57 as *mut _, len59, len59); + let l60 = *((base + 16) as *const i64); - wit_bindgen::rt::string_lift(bytes53) + (Uri{ + value: wit_bindgen::rt::string_lift(bytes59), + }, l60 as u64) }; - WitNode::PrimString(e54) + WitNode::Handle(e61) } }; - v54 + v61 }; - result55.push(e55); + result62.push(e62); } - wit_bindgen::rt::dealloc(base55, (len55 as usize) * 24, 8); + wit_bindgen::rt::dealloc(base62, (len62 as usize) * 24, 8); WitValue{ - nodes: result55, + nodes: result62, } }; Ok(e) } 1 => { let e = { - let l56 = i32::from(*((ptr10 + 4) as *const u8)); - let v69 = match l56 { + let l63 = i32::from(*((ptr13 + 4) as *const u8)); + let v76 = match l63 { 0 => { - let e69 = { - let l57 = *((ptr10 + 8) as *const i32); - let l58 = *((ptr10 + 12) as *const i32); - let len59 = l58 as usize; - let bytes59 = Vec::from_raw_parts(l57 as *mut _, len59, len59); + let e76 = { + let l64 = *((ptr13 + 8) as *const i32); + let l65 = *((ptr13 + 12) as *const i32); + let len66 = l65 as usize; + let bytes66 = Vec::from_raw_parts(l64 as *mut _, len66, len66); - wit_bindgen::rt::string_lift(bytes59) + wit_bindgen::rt::string_lift(bytes66) }; - RpcError::ProtocolError(e69) + RpcError::ProtocolError(e76) } 1 => { - let e69 = { - let l60 = *((ptr10 + 8) as *const i32); - let l61 = *((ptr10 + 12) as *const i32); - let len62 = l61 as usize; - let bytes62 = Vec::from_raw_parts(l60 as *mut _, len62, len62); + let e76 = { + let l67 = *((ptr13 + 8) as *const i32); + let l68 = *((ptr13 + 12) as *const i32); + let len69 = l68 as usize; + let bytes69 = Vec::from_raw_parts(l67 as *mut _, len69, len69); - wit_bindgen::rt::string_lift(bytes62) + wit_bindgen::rt::string_lift(bytes69) }; - RpcError::Denied(e69) + RpcError::Denied(e76) } 2 => { - let e69 = { - let l63 = *((ptr10 + 8) as *const i32); - let l64 = *((ptr10 + 12) as *const i32); - let len65 = l64 as usize; - let bytes65 = Vec::from_raw_parts(l63 as *mut _, len65, len65); + let e76 = { + let l70 = *((ptr13 + 8) as *const i32); + let l71 = *((ptr13 + 12) as *const i32); + let len72 = l71 as usize; + let bytes72 = Vec::from_raw_parts(l70 as *mut _, len72, len72); - wit_bindgen::rt::string_lift(bytes65) + wit_bindgen::rt::string_lift(bytes72) }; - RpcError::NotFound(e69) + RpcError::NotFound(e76) } n => { debug_assert_eq!(n, 3, "invalid enum discriminant"); - let e69 = { - let l66 = *((ptr10 + 8) as *const i32); - let l67 = *((ptr10 + 12) as *const i32); - let len68 = l67 as usize; - let bytes68 = Vec::from_raw_parts(l66 as *mut _, len68, len68); + let e76 = { + let l73 = *((ptr13 + 8) as *const i32); + let l74 = *((ptr13 + 12) as *const i32); + let len75 = l74 as usize; + let bytes75 = Vec::from_raw_parts(l73 as *mut _, len75, len75); - wit_bindgen::rt::string_lift(bytes68) + wit_bindgen::rt::string_lift(bytes75) }; - RpcError::RemoteInternalError(e69) + RpcError::RemoteInternalError(e76) } }; - v69 + v76 }; Err(e) } @@ -826,7 +855,7 @@ pub mod golem { #[cfg(target_arch = "wasm32")] #[link_section = "component-type:wit-value"] #[doc(hidden)] - pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 1495] = [3, 0, 9, 119, 105, 116, 45, 118, 97, 108, 117, 101, 0, 97, 115, 109, 13, 0, 1, 0, 7, 146, 5, 1, 65, 2, 1, 66, 25, 1, 122, 4, 0, 10, 110, 111, 100, 101, 45, 105, 110, 100, 101, 120, 3, 0, 0, 1, 112, 1, 1, 107, 1, 1, 111, 2, 121, 3, 1, 112, 127, 1, 106, 1, 3, 1, 3, 1, 113, 21, 12, 114, 101, 99, 111, 114, 100, 45, 118, 97, 108, 117, 101, 1, 2, 0, 13, 118, 97, 114, 105, 97, 110, 116, 45, 118, 97, 108, 117, 101, 1, 4, 0, 10, 101, 110, 117, 109, 45, 118, 97, 108, 117, 101, 1, 121, 0, 11, 102, 108, 97, 103, 115, 45, 118, 97, 108, 117, 101, 1, 5, 0, 11, 116, 117, 112, 108, 101, 45, 118, 97, 108, 117, 101, 1, 2, 0, 10, 108, 105, 115, 116, 45, 118, 97, 108, 117, 101, 1, 2, 0, 12, 111, 112, 116, 105, 111, 110, 45, 118, 97, 108, 117, 101, 1, 3, 0, 12, 114, 101, 115, 117, 108, 116, 45, 118, 97, 108, 117, 101, 1, 6, 0, 7, 112, 114, 105, 109, 45, 117, 56, 1, 125, 0, 8, 112, 114, 105, 109, 45, 117, 49, 54, 1, 123, 0, 8, 112, 114, 105, 109, 45, 117, 51, 50, 1, 121, 0, 8, 112, 114, 105, 109, 45, 117, 54, 52, 1, 119, 0, 7, 112, 114, 105, 109, 45, 115, 56, 1, 126, 0, 8, 112, 114, 105, 109, 45, 115, 49, 54, 1, 124, 0, 8, 112, 114, 105, 109, 45, 115, 51, 50, 1, 122, 0, 8, 112, 114, 105, 109, 45, 115, 54, 52, 1, 120, 0, 12, 112, 114, 105, 109, 45, 102, 108, 111, 97, 116, 51, 50, 1, 118, 0, 12, 112, 114, 105, 109, 45, 102, 108, 111, 97, 116, 54, 52, 1, 117, 0, 9, 112, 114, 105, 109, 45, 99, 104, 97, 114, 1, 116, 0, 9, 112, 114, 105, 109, 45, 98, 111, 111, 108, 1, 127, 0, 11, 112, 114, 105, 109, 45, 115, 116, 114, 105, 110, 103, 1, 115, 0, 4, 0, 8, 119, 105, 116, 45, 110, 111, 100, 101, 3, 0, 7, 1, 112, 8, 1, 114, 1, 5, 110, 111, 100, 101, 115, 9, 4, 0, 9, 119, 105, 116, 45, 118, 97, 108, 117, 101, 3, 0, 10, 1, 114, 1, 5, 118, 97, 108, 117, 101, 115, 4, 0, 3, 117, 114, 105, 3, 0, 12, 1, 113, 4, 14, 112, 114, 111, 116, 111, 99, 111, 108, 45, 101, 114, 114, 111, 114, 1, 115, 0, 6, 100, 101, 110, 105, 101, 100, 1, 115, 0, 9, 110, 111, 116, 45, 102, 111, 117, 110, 100, 1, 115, 0, 21, 114, 101, 109, 111, 116, 101, 45, 105, 110, 116, 101, 114, 110, 97, 108, 45, 101, 114, 114, 111, 114, 1, 115, 0, 4, 0, 9, 114, 112, 99, 45, 101, 114, 114, 111, 114, 3, 0, 14, 4, 0, 8, 119, 97, 115, 109, 45, 114, 112, 99, 3, 1, 1, 105, 16, 1, 64, 1, 8, 108, 111, 99, 97, 116, 105, 111, 110, 13, 0, 17, 4, 0, 21, 91, 99, 111, 110, 115, 116, 114, 117, 99, 116, 111, 114, 93, 119, 97, 115, 109, 45, 114, 112, 99, 1, 18, 1, 104, 16, 1, 112, 11, 1, 106, 1, 11, 1, 15, 1, 64, 3, 4, 115, 101, 108, 102, 19, 13, 102, 117, 110, 99, 116, 105, 111, 110, 45, 110, 97, 109, 101, 115, 15, 102, 117, 110, 99, 116, 105, 111, 110, 45, 112, 97, 114, 97, 109, 115, 20, 0, 21, 4, 0, 33, 91, 109, 101, 116, 104, 111, 100, 93, 119, 97, 115, 109, 45, 114, 112, 99, 46, 105, 110, 118, 111, 107, 101, 45, 97, 110, 100, 45, 97, 119, 97, 105, 116, 1, 22, 4, 1, 21, 103, 111, 108, 101, 109, 58, 114, 112, 99, 47, 116, 121, 112, 101, 115, 64, 48, 46, 49, 46, 48, 5, 0, 11, 11, 1, 0, 5, 116, 121, 112, 101, 115, 3, 0, 0, 7, 179, 5, 1, 65, 2, 1, 65, 2, 1, 66, 25, 1, 122, 4, 0, 10, 110, 111, 100, 101, 45, 105, 110, 100, 101, 120, 3, 0, 0, 1, 112, 1, 1, 107, 1, 1, 111, 2, 121, 3, 1, 112, 127, 1, 106, 1, 3, 1, 3, 1, 113, 21, 12, 114, 101, 99, 111, 114, 100, 45, 118, 97, 108, 117, 101, 1, 2, 0, 13, 118, 97, 114, 105, 97, 110, 116, 45, 118, 97, 108, 117, 101, 1, 4, 0, 10, 101, 110, 117, 109, 45, 118, 97, 108, 117, 101, 1, 121, 0, 11, 102, 108, 97, 103, 115, 45, 118, 97, 108, 117, 101, 1, 5, 0, 11, 116, 117, 112, 108, 101, 45, 118, 97, 108, 117, 101, 1, 2, 0, 10, 108, 105, 115, 116, 45, 118, 97, 108, 117, 101, 1, 2, 0, 12, 111, 112, 116, 105, 111, 110, 45, 118, 97, 108, 117, 101, 1, 3, 0, 12, 114, 101, 115, 117, 108, 116, 45, 118, 97, 108, 117, 101, 1, 6, 0, 7, 112, 114, 105, 109, 45, 117, 56, 1, 125, 0, 8, 112, 114, 105, 109, 45, 117, 49, 54, 1, 123, 0, 8, 112, 114, 105, 109, 45, 117, 51, 50, 1, 121, 0, 8, 112, 114, 105, 109, 45, 117, 54, 52, 1, 119, 0, 7, 112, 114, 105, 109, 45, 115, 56, 1, 126, 0, 8, 112, 114, 105, 109, 45, 115, 49, 54, 1, 124, 0, 8, 112, 114, 105, 109, 45, 115, 51, 50, 1, 122, 0, 8, 112, 114, 105, 109, 45, 115, 54, 52, 1, 120, 0, 12, 112, 114, 105, 109, 45, 102, 108, 111, 97, 116, 51, 50, 1, 118, 0, 12, 112, 114, 105, 109, 45, 102, 108, 111, 97, 116, 54, 52, 1, 117, 0, 9, 112, 114, 105, 109, 45, 99, 104, 97, 114, 1, 116, 0, 9, 112, 114, 105, 109, 45, 98, 111, 111, 108, 1, 127, 0, 11, 112, 114, 105, 109, 45, 115, 116, 114, 105, 110, 103, 1, 115, 0, 4, 0, 8, 119, 105, 116, 45, 110, 111, 100, 101, 3, 0, 7, 1, 112, 8, 1, 114, 1, 5, 110, 111, 100, 101, 115, 9, 4, 0, 9, 119, 105, 116, 45, 118, 97, 108, 117, 101, 3, 0, 10, 1, 114, 1, 5, 118, 97, 108, 117, 101, 115, 4, 0, 3, 117, 114, 105, 3, 0, 12, 1, 113, 4, 14, 112, 114, 111, 116, 111, 99, 111, 108, 45, 101, 114, 114, 111, 114, 1, 115, 0, 6, 100, 101, 110, 105, 101, 100, 1, 115, 0, 9, 110, 111, 116, 45, 102, 111, 117, 110, 100, 1, 115, 0, 21, 114, 101, 109, 111, 116, 101, 45, 105, 110, 116, 101, 114, 110, 97, 108, 45, 101, 114, 114, 111, 114, 1, 115, 0, 4, 0, 9, 114, 112, 99, 45, 101, 114, 114, 111, 114, 3, 0, 14, 4, 0, 8, 119, 97, 115, 109, 45, 114, 112, 99, 3, 1, 1, 105, 16, 1, 64, 1, 8, 108, 111, 99, 97, 116, 105, 111, 110, 13, 0, 17, 4, 0, 21, 91, 99, 111, 110, 115, 116, 114, 117, 99, 116, 111, 114, 93, 119, 97, 115, 109, 45, 114, 112, 99, 1, 18, 1, 104, 16, 1, 112, 11, 1, 106, 1, 11, 1, 15, 1, 64, 3, 4, 115, 101, 108, 102, 19, 13, 102, 117, 110, 99, 116, 105, 111, 110, 45, 110, 97, 109, 101, 115, 15, 102, 117, 110, 99, 116, 105, 111, 110, 45, 112, 97, 114, 97, 109, 115, 20, 0, 21, 4, 0, 33, 91, 109, 101, 116, 104, 111, 100, 93, 119, 97, 115, 109, 45, 114, 112, 99, 46, 105, 110, 118, 111, 107, 101, 45, 97, 110, 100, 45, 97, 119, 97, 105, 116, 1, 22, 3, 1, 21, 103, 111, 108, 101, 109, 58, 114, 112, 99, 47, 116, 121, 112, 101, 115, 64, 48, 46, 49, 46, 48, 5, 0, 4, 1, 25, 103, 111, 108, 101, 109, 58, 114, 112, 99, 47, 119, 105, 116, 45, 118, 97, 108, 117, 101, 64, 48, 46, 49, 46, 48, 4, 0, 11, 15, 1, 0, 9, 119, 105, 116, 45, 118, 97, 108, 117, 101, 3, 2, 0, 0, 16, 12, 112, 97, 99, 107, 97, 103, 101, 45, 100, 111, 99, 115, 0, 123, 125, 0, 70, 9, 112, 114, 111, 100, 117, 99, 101, 114, 115, 1, 12, 112, 114, 111, 99, 101, 115, 115, 101, 100, 45, 98, 121, 2, 13, 119, 105, 116, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 6, 48, 46, 49, 56, 46, 50, 16, 119, 105, 116, 45, 98, 105, 110, 100, 103, 101, 110, 45, 114, 117, 115, 116, 6, 48, 46, 49, 54, 46, 48]; + pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 1525] = [3, 0, 9, 119, 105, 116, 45, 118, 97, 108, 117, 101, 0, 97, 115, 109, 13, 0, 1, 0, 7, 161, 5, 1, 65, 2, 1, 66, 26, 1, 122, 4, 0, 10, 110, 111, 100, 101, 45, 105, 110, 100, 101, 120, 3, 0, 0, 1, 114, 1, 5, 118, 97, 108, 117, 101, 115, 4, 0, 3, 117, 114, 105, 3, 0, 2, 1, 112, 1, 1, 107, 1, 1, 111, 2, 121, 5, 1, 112, 127, 1, 106, 1, 5, 1, 5, 1, 111, 2, 3, 119, 1, 113, 22, 12, 114, 101, 99, 111, 114, 100, 45, 118, 97, 108, 117, 101, 1, 4, 0, 13, 118, 97, 114, 105, 97, 110, 116, 45, 118, 97, 108, 117, 101, 1, 6, 0, 10, 101, 110, 117, 109, 45, 118, 97, 108, 117, 101, 1, 121, 0, 11, 102, 108, 97, 103, 115, 45, 118, 97, 108, 117, 101, 1, 7, 0, 11, 116, 117, 112, 108, 101, 45, 118, 97, 108, 117, 101, 1, 4, 0, 10, 108, 105, 115, 116, 45, 118, 97, 108, 117, 101, 1, 4, 0, 12, 111, 112, 116, 105, 111, 110, 45, 118, 97, 108, 117, 101, 1, 5, 0, 12, 114, 101, 115, 117, 108, 116, 45, 118, 97, 108, 117, 101, 1, 8, 0, 7, 112, 114, 105, 109, 45, 117, 56, 1, 125, 0, 8, 112, 114, 105, 109, 45, 117, 49, 54, 1, 123, 0, 8, 112, 114, 105, 109, 45, 117, 51, 50, 1, 121, 0, 8, 112, 114, 105, 109, 45, 117, 54, 52, 1, 119, 0, 7, 112, 114, 105, 109, 45, 115, 56, 1, 126, 0, 8, 112, 114, 105, 109, 45, 115, 49, 54, 1, 124, 0, 8, 112, 114, 105, 109, 45, 115, 51, 50, 1, 122, 0, 8, 112, 114, 105, 109, 45, 115, 54, 52, 1, 120, 0, 12, 112, 114, 105, 109, 45, 102, 108, 111, 97, 116, 51, 50, 1, 118, 0, 12, 112, 114, 105, 109, 45, 102, 108, 111, 97, 116, 54, 52, 1, 117, 0, 9, 112, 114, 105, 109, 45, 99, 104, 97, 114, 1, 116, 0, 9, 112, 114, 105, 109, 45, 98, 111, 111, 108, 1, 127, 0, 11, 112, 114, 105, 109, 45, 115, 116, 114, 105, 110, 103, 1, 115, 0, 6, 104, 97, 110, 100, 108, 101, 1, 9, 0, 4, 0, 8, 119, 105, 116, 45, 110, 111, 100, 101, 3, 0, 10, 1, 112, 11, 1, 114, 1, 5, 110, 111, 100, 101, 115, 12, 4, 0, 9, 119, 105, 116, 45, 118, 97, 108, 117, 101, 3, 0, 13, 1, 113, 4, 14, 112, 114, 111, 116, 111, 99, 111, 108, 45, 101, 114, 114, 111, 114, 1, 115, 0, 6, 100, 101, 110, 105, 101, 100, 1, 115, 0, 9, 110, 111, 116, 45, 102, 111, 117, 110, 100, 1, 115, 0, 21, 114, 101, 109, 111, 116, 101, 45, 105, 110, 116, 101, 114, 110, 97, 108, 45, 101, 114, 114, 111, 114, 1, 115, 0, 4, 0, 9, 114, 112, 99, 45, 101, 114, 114, 111, 114, 3, 0, 15, 4, 0, 8, 119, 97, 115, 109, 45, 114, 112, 99, 3, 1, 1, 105, 17, 1, 64, 1, 8, 108, 111, 99, 97, 116, 105, 111, 110, 3, 0, 18, 4, 0, 21, 91, 99, 111, 110, 115, 116, 114, 117, 99, 116, 111, 114, 93, 119, 97, 115, 109, 45, 114, 112, 99, 1, 19, 1, 104, 17, 1, 112, 14, 1, 106, 1, 14, 1, 16, 1, 64, 3, 4, 115, 101, 108, 102, 20, 13, 102, 117, 110, 99, 116, 105, 111, 110, 45, 110, 97, 109, 101, 115, 15, 102, 117, 110, 99, 116, 105, 111, 110, 45, 112, 97, 114, 97, 109, 115, 21, 0, 22, 4, 0, 33, 91, 109, 101, 116, 104, 111, 100, 93, 119, 97, 115, 109, 45, 114, 112, 99, 46, 105, 110, 118, 111, 107, 101, 45, 97, 110, 100, 45, 97, 119, 97, 105, 116, 1, 23, 4, 1, 21, 103, 111, 108, 101, 109, 58, 114, 112, 99, 47, 116, 121, 112, 101, 115, 64, 48, 46, 49, 46, 48, 5, 0, 11, 11, 1, 0, 5, 116, 121, 112, 101, 115, 3, 0, 0, 7, 194, 5, 1, 65, 2, 1, 65, 2, 1, 66, 26, 1, 122, 4, 0, 10, 110, 111, 100, 101, 45, 105, 110, 100, 101, 120, 3, 0, 0, 1, 114, 1, 5, 118, 97, 108, 117, 101, 115, 4, 0, 3, 117, 114, 105, 3, 0, 2, 1, 112, 1, 1, 107, 1, 1, 111, 2, 121, 5, 1, 112, 127, 1, 106, 1, 5, 1, 5, 1, 111, 2, 3, 119, 1, 113, 22, 12, 114, 101, 99, 111, 114, 100, 45, 118, 97, 108, 117, 101, 1, 4, 0, 13, 118, 97, 114, 105, 97, 110, 116, 45, 118, 97, 108, 117, 101, 1, 6, 0, 10, 101, 110, 117, 109, 45, 118, 97, 108, 117, 101, 1, 121, 0, 11, 102, 108, 97, 103, 115, 45, 118, 97, 108, 117, 101, 1, 7, 0, 11, 116, 117, 112, 108, 101, 45, 118, 97, 108, 117, 101, 1, 4, 0, 10, 108, 105, 115, 116, 45, 118, 97, 108, 117, 101, 1, 4, 0, 12, 111, 112, 116, 105, 111, 110, 45, 118, 97, 108, 117, 101, 1, 5, 0, 12, 114, 101, 115, 117, 108, 116, 45, 118, 97, 108, 117, 101, 1, 8, 0, 7, 112, 114, 105, 109, 45, 117, 56, 1, 125, 0, 8, 112, 114, 105, 109, 45, 117, 49, 54, 1, 123, 0, 8, 112, 114, 105, 109, 45, 117, 51, 50, 1, 121, 0, 8, 112, 114, 105, 109, 45, 117, 54, 52, 1, 119, 0, 7, 112, 114, 105, 109, 45, 115, 56, 1, 126, 0, 8, 112, 114, 105, 109, 45, 115, 49, 54, 1, 124, 0, 8, 112, 114, 105, 109, 45, 115, 51, 50, 1, 122, 0, 8, 112, 114, 105, 109, 45, 115, 54, 52, 1, 120, 0, 12, 112, 114, 105, 109, 45, 102, 108, 111, 97, 116, 51, 50, 1, 118, 0, 12, 112, 114, 105, 109, 45, 102, 108, 111, 97, 116, 54, 52, 1, 117, 0, 9, 112, 114, 105, 109, 45, 99, 104, 97, 114, 1, 116, 0, 9, 112, 114, 105, 109, 45, 98, 111, 111, 108, 1, 127, 0, 11, 112, 114, 105, 109, 45, 115, 116, 114, 105, 110, 103, 1, 115, 0, 6, 104, 97, 110, 100, 108, 101, 1, 9, 0, 4, 0, 8, 119, 105, 116, 45, 110, 111, 100, 101, 3, 0, 10, 1, 112, 11, 1, 114, 1, 5, 110, 111, 100, 101, 115, 12, 4, 0, 9, 119, 105, 116, 45, 118, 97, 108, 117, 101, 3, 0, 13, 1, 113, 4, 14, 112, 114, 111, 116, 111, 99, 111, 108, 45, 101, 114, 114, 111, 114, 1, 115, 0, 6, 100, 101, 110, 105, 101, 100, 1, 115, 0, 9, 110, 111, 116, 45, 102, 111, 117, 110, 100, 1, 115, 0, 21, 114, 101, 109, 111, 116, 101, 45, 105, 110, 116, 101, 114, 110, 97, 108, 45, 101, 114, 114, 111, 114, 1, 115, 0, 4, 0, 9, 114, 112, 99, 45, 101, 114, 114, 111, 114, 3, 0, 15, 4, 0, 8, 119, 97, 115, 109, 45, 114, 112, 99, 3, 1, 1, 105, 17, 1, 64, 1, 8, 108, 111, 99, 97, 116, 105, 111, 110, 3, 0, 18, 4, 0, 21, 91, 99, 111, 110, 115, 116, 114, 117, 99, 116, 111, 114, 93, 119, 97, 115, 109, 45, 114, 112, 99, 1, 19, 1, 104, 17, 1, 112, 14, 1, 106, 1, 14, 1, 16, 1, 64, 3, 4, 115, 101, 108, 102, 20, 13, 102, 117, 110, 99, 116, 105, 111, 110, 45, 110, 97, 109, 101, 115, 15, 102, 117, 110, 99, 116, 105, 111, 110, 45, 112, 97, 114, 97, 109, 115, 21, 0, 22, 4, 0, 33, 91, 109, 101, 116, 104, 111, 100, 93, 119, 97, 115, 109, 45, 114, 112, 99, 46, 105, 110, 118, 111, 107, 101, 45, 97, 110, 100, 45, 97, 119, 97, 105, 116, 1, 23, 3, 1, 21, 103, 111, 108, 101, 109, 58, 114, 112, 99, 47, 116, 121, 112, 101, 115, 64, 48, 46, 49, 46, 48, 5, 0, 4, 1, 25, 103, 111, 108, 101, 109, 58, 114, 112, 99, 47, 119, 105, 116, 45, 118, 97, 108, 117, 101, 64, 48, 46, 49, 46, 48, 4, 0, 11, 15, 1, 0, 9, 119, 105, 116, 45, 118, 97, 108, 117, 101, 3, 2, 0, 0, 16, 12, 112, 97, 99, 107, 97, 103, 101, 45, 100, 111, 99, 115, 0, 123, 125, 0, 70, 9, 112, 114, 111, 100, 117, 99, 101, 114, 115, 1, 12, 112, 114, 111, 99, 101, 115, 115, 101, 100, 45, 98, 121, 2, 13, 119, 105, 116, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 6, 48, 46, 49, 56, 46, 50, 16, 119, 105, 116, 45, 98, 105, 110, 100, 103, 101, 110, 45, 114, 117, 115, 116, 6, 48, 46, 49, 54, 46, 48]; #[inline(never)] #[doc(hidden)] diff --git a/wasm-rpc/src/builder.rs b/wasm-rpc/src/builder.rs index 57345fc0..e743f76f 100644 --- a/wasm-rpc/src/builder.rs +++ b/wasm-rpc/src/builder.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{NodeIndex, WitNode, WitValue}; +use crate::{NodeIndex, Uri, WitNode, WitValue}; pub trait WitValueBuilderExtensions { fn builder() -> WitValueBuilder; @@ -123,6 +123,8 @@ pub trait NodeBuilder: Sized { } } + fn handle(self, uri: Uri, handle_value: u64) -> Self::Result; + fn finish(self) -> Self::Result; } @@ -244,6 +246,10 @@ impl WitValueBuilder { self.add(WitNode::ResultValue(Err(None))) } + pub(crate) fn add_handle(&mut self, uri: Uri, handle_value: u64) -> NodeIndex { + self.add(WitNode::Handle((uri, handle_value))) + } + pub(crate) fn finish_child(&mut self, child: NodeIndex, target_idx: NodeIndex) { match &mut self.nodes[target_idx as usize] { WitNode::OptionValue(ref mut result_item) => match result_item { @@ -439,6 +445,11 @@ impl NodeBuilder for WitValueBuilder { self.build() } + fn handle(mut self, uri: Uri, handle_value: u64) -> Self::Result { + let _ = self.add_handle(uri, handle_value); + self.build() + } + fn finish(self) -> Self::Result { self.build() } @@ -659,6 +670,12 @@ impl NodeBuilder for WitValueItemBuilder Self::Result { + let item_type_index = self.parent_builder().add_handle(uri, handle_value); + self.child_items_builder.add_item(item_type_index); + self.child_items_builder + } + fn finish(self) -> Self::Result { self.child_items_builder } @@ -870,6 +887,13 @@ impl NodeBuilder for WitValueChildBuilder Self::Result { + let child_index = self.parent_builder().add_handle(uri, handle_value); + let target_idx = self.target_idx; + self.parent_builder().finish_child(child_index, target_idx); + self.builder + } + fn finish(self) -> Self::Result { self.builder } diff --git a/wasm-rpc/src/extractor.rs b/wasm-rpc/src/extractor.rs index 27188040..af0a7136 100644 --- a/wasm-rpc/src/extractor.rs +++ b/wasm-rpc/src/extractor.rs @@ -1,4 +1,4 @@ -use crate::{WitNode, WitValue}; +use crate::{Uri, WitNode, WitValue}; pub trait WitValueExtractor<'a> { fn u8(&'a self) -> Option; @@ -22,6 +22,8 @@ pub trait WitValueExtractor<'a> { fn list_elements(&'a self, f: impl Fn(WitNodePointer<'a>) -> R) -> Option>; fn option(&'a self) -> Option>>; fn result(&'a self) -> Option>, Option>>>; + + fn handle(&'a self) -> Option<(Uri, u64)>; } impl<'a> WitValueExtractor<'a> for WitValue { @@ -108,6 +110,10 @@ impl<'a> WitValueExtractor<'a> for WitValue { fn result(&'a self) -> Option>, Option>>> { WitNodePointer::new(self, 0).result() } + + fn handle(&'a self) -> Option<(Uri, u64)> { + WitNodePointer::new(self, 0).handle() + } } pub struct WitNodePointer<'a> { @@ -305,6 +311,14 @@ impl<'a> WitNodePointer<'a> { None } } + + pub fn handle(&self) -> Option<(Uri, u64)> { + if let WitNode::Handle((uri, idx)) = self.node() { + Some((uri.clone(), *idx)) + } else { + None + } + } } #[cfg(test)] @@ -456,4 +470,23 @@ mod tests { let value = WitValue::builder().result_err_unit(); assert!(value.result().unwrap().err().unwrap().is_none()); } + + #[test] + fn handle() { + let value = WitValue::builder().handle( + Uri { + value: "wit://test".to_string(), + }, + 42, + ); + assert_eq!( + value.handle().unwrap(), + ( + Uri { + value: "wit://test".to_string() + }, + 42 + ) + ); + } } diff --git a/wasm-rpc/src/json.rs b/wasm-rpc/src/json.rs index a4ccb3f9..a3b89180 100644 --- a/wasm-rpc/src/json.rs +++ b/wasm-rpc/src/json.rs @@ -18,7 +18,7 @@ use serde_json::{Number, Value as JsonValue}; use std::collections::HashMap; use std::str::FromStr; -use crate::Value; +use crate::{Uri, Value}; pub fn function_parameters( value: &JsonValue, @@ -148,6 +148,7 @@ fn validate_function_parameter( }) } AnalysedType::Tuple(elems) => get_tuple(input_json, elems).map(Value::Tuple), + AnalysedType::Resource { .. } => get_handle(input_json), } } @@ -557,6 +558,35 @@ fn get_variant( } } +fn get_handle(value: &JsonValue) -> Result> { + match value.as_str() { + Some(str) => { + // not assuming much about the url format, just checking it ends with a / + let parts: Vec<&str> = str.split('/').collect(); + if parts.len() >= 2 { + match u64::from_str(parts[parts.len() - 1]) { + Ok(resource_id) => { + let uri = parts[0..(parts.len() - 1)].join("/"); + Ok(Value::Handle { uri: Uri { value: uri }, resource_id }) + } + Err(err) => { + Err(vec![format!("Failed to parse resource-id section of the handle value: {}", err)]) + } + } + } else { + Err(vec![format!( + "Expected function parameter type is Handle, represented by a worker-url/resource-id string. But found {}", + str + )]) + } + } + None => Err(vec![format!( + "Expected function parameter type is Handle, represented by a worker-url/resource-id string. But found {}", + type_description(value) + )]), + } +} + fn validate_function_result( val: Value, expected_type: &AnalysedType, @@ -790,6 +820,13 @@ fn validate_function_result( _ => Err(vec!["Unexpected type; expected a Result type.".to_string()]), }, + Value::Handle { uri, resource_id } => match expected_type { + AnalysedType::Resource { .. } => Ok(serde_json::Value::String(format!( + "{}/{}", + uri.value, resource_id + ))), + _ => Err(vec!["Unexpected type; expected a Handle type.".to_string()]), + }, } } @@ -1235,7 +1272,7 @@ mod tests { result, Ok(Value::Record(vec![ Value::String("a".to_string()), - Value::Option(None) + Value::Option(None), ])) ); } diff --git a/wasm-rpc/src/lib.rs b/wasm-rpc/src/lib.rs index e6d11f25..8e3bd9b2 100644 --- a/wasm-rpc/src/lib.rs +++ b/wasm-rpc/src/lib.rs @@ -45,6 +45,7 @@ pub use bindings::golem::rpc::types::{NodeIndex, RpcError, Uri, WasmRpc, WitNode #[cfg(feature = "host")] use ::wasmtime::component::bindgen; + #[cfg(feature = "host")] bindgen!({ path: "wit", @@ -59,13 +60,27 @@ bindgen!({ }); #[cfg(feature = "host")] -pub use golem::rpc::types::{Host, HostWasmRpc, NodeIndex, RpcError, WitNode, WitValue}; +pub use golem::rpc::types::{Host, HostWasmRpc, NodeIndex, RpcError, Uri, WitNode, WitValue}; #[cfg(feature = "host")] pub struct WasmRpcEntry { pub payload: Box, } +#[cfg(feature = "arbitrary")] +impl<'a> arbitrary::Arbitrary<'a> for Uri { + fn arbitrary(u: &mut arbitrary::Unstructured) -> arbitrary::Result { + let uri = u.arbitrary::()?; + Ok(Uri { value: uri }) + } +} + +impl PartialEq for Uri { + fn eq(&self, other: &Self) -> bool { + self.value == other.value + } +} + /// A tree representation of Value - isomorphic to the protobuf Val type but easier to work with in Rust #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] @@ -94,6 +109,10 @@ pub enum Value { Flags(Vec), Option(Option>), Result(Result>, Option>>), + Handle { + uri: Uri, + resource_id: u64, + }, } impl From for WitValue { @@ -190,6 +209,7 @@ fn build_wit_value(value: Value, builder: &mut WitValueBuilder) -> NodeIndex { } Err(None) => builder.add_result_err_unit(), }, + Value::Handle { uri, resource_id } => builder.add_handle(uri, resource_id), } } @@ -267,6 +287,10 @@ fn build_tree(node: &WitNode, nodes: &[WitNode]) -> Value { WitNode::PrimChar(value) => Value::Char(*value), WitNode::PrimBool(value) => Value::Bool(*value), WitNode::PrimString(value) => Value::String(value.clone()), + WitNode::Handle((uri, value)) => Value::Handle { + uri: uri.clone(), + resource_id: *value, + }, } } diff --git a/wasm-rpc/src/protobuf.rs b/wasm-rpc/src/protobuf.rs index 7e670060..a9d7545a 100644 --- a/wasm-rpc/src/protobuf.rs +++ b/wasm-rpc/src/protobuf.rs @@ -111,6 +111,12 @@ impl From for WitNode { super::WitNode::PrimString(value) => WitNode { value: Some(wit_node::Value::String(WitPrimStringNode { value })), }, + super::WitNode::Handle((uri, value)) => WitNode { + value: Some(wit_node::Value::Handle(WitHandleNode { + uri: uri.value, + value, + })), + }, } } } @@ -206,6 +212,9 @@ impl TryFrom for super::WitNode { Some(wit_node::Value::String(WitPrimStringNode { value })) => { Ok(super::WitNode::PrimString(value)) } + Some(wit_node::Value::Handle(WitHandleNode { uri, value })) => { + Ok(super::WitNode::Handle((super::Uri { value: uri }, value))) + } } } } @@ -327,6 +336,12 @@ impl From for Val { value: value.map(|value| Box::new((*value).into())), }))), }, + Value::Handle { uri, resource_id } => Val { + val: Some(val::Val::Handle(ValHandle { + uri: uri.value, + value: resource_id, + })), + }, } } } @@ -428,6 +443,10 @@ impl TryFrom for Value { _ => Err("Protobuf ValResult has invalid discriminant or value".to_string()), } } + Some(val::Val::Handle(ValHandle { uri, value })) => Ok(Value::Handle { + uri: super::Uri { value: uri }, + resource_id: value, + }), } } } diff --git a/wasm-rpc/wit/wasm-rpc.wit b/wasm-rpc/wit/wasm-rpc.wit index f7deff5b..bc34a64c 100644 --- a/wasm-rpc/wit/wasm-rpc.wit +++ b/wasm-rpc/wit/wasm-rpc.wit @@ -29,6 +29,7 @@ interface types { prim-char(char), prim-bool(bool), prim-string(string), + handle(tuple) } record uri {