1use crate::interpreter::interpreter_stack_value::RibInterpreterStackValue;
16use crate::{
17 ComponentDependencyKey, EvaluatedFnArgs, EvaluatedFqFn, EvaluatedWorkerName, InstructionId,
18 RibComponentFunctionInvoke, RibInput, VariableId,
19};
20use golem_wasm_ast::analysis::AnalysedType;
21use golem_wasm_rpc::ValueAndType;
22use std::collections::HashMap;
23use std::fmt::Debug;
24use std::sync::Arc;
25
26pub struct InterpreterEnv {
27 pub env: HashMap<EnvironmentKey, RibInterpreterStackValue>,
28 pub call_worker_function_async: Arc<dyn RibComponentFunctionInvoke + Sync + Send>,
29}
30
31impl Debug for InterpreterEnv {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 f.debug_struct("InterpreterEnv")
34 .field("env", &self.env.iter())
35 .finish()
36 }
37}
38
39impl Default for InterpreterEnv {
40 fn default() -> Self {
41 InterpreterEnv {
42 env: HashMap::new(),
43 call_worker_function_async: Arc::new(internal::NoopRibFunctionInvoke),
44 }
45 }
46}
47
48impl InterpreterEnv {
49 pub async fn invoke_worker_function_async(
50 &self,
51 component_dependency_key: ComponentDependencyKey,
52 instruction_id: &InstructionId,
53 worker_name: String,
54 function_name: String,
55 args: Vec<ValueAndType>,
56 return_type: Option<AnalysedType>,
57 ) -> Result<Option<ValueAndType>, Box<dyn std::error::Error + Send + Sync>> {
58 self.call_worker_function_async
59 .invoke(
60 component_dependency_key,
61 instruction_id,
62 EvaluatedWorkerName(worker_name),
63 EvaluatedFqFn(function_name),
64 EvaluatedFnArgs(args),
65 return_type,
66 )
67 .await
68 }
69
70 pub fn from_input(env: &RibInput) -> Self {
71 let env = env
72 .input
73 .clone()
74 .into_iter()
75 .map(|(k, v)| {
76 (
77 EnvironmentKey::from_global(k),
78 RibInterpreterStackValue::Val(v),
79 )
80 })
81 .collect();
82
83 InterpreterEnv {
84 env,
85 call_worker_function_async: Arc::new(internal::NoopRibFunctionInvoke),
86 }
87 }
88
89 pub fn from(
90 input: &RibInput,
91 call_worker_function_async: &Arc<dyn RibComponentFunctionInvoke + Sync + Send>,
92 ) -> Self {
93 let mut env = Self::from_input(input);
94 env.call_worker_function_async = call_worker_function_async.clone();
95 env
96 }
97
98 pub fn insert(&mut self, key: EnvironmentKey, value: RibInterpreterStackValue) {
99 self.env.insert(key, value);
100 }
101
102 pub fn lookup(&self, key: &EnvironmentKey) -> Option<&RibInterpreterStackValue> {
103 self.env.get(key)
104 }
105}
106
107#[derive(Debug, Hash, Eq, PartialEq, Clone)]
108pub struct EnvironmentKey {
109 pub variable_id: VariableId,
110}
111
112impl EnvironmentKey {
113 pub fn from(variable_id: VariableId) -> Self {
114 EnvironmentKey { variable_id }
115 }
116
117 pub fn from_global(key: String) -> Self {
118 EnvironmentKey {
119 variable_id: VariableId::global(key),
120 }
121 }
122}
123
124mod internal {
125 use crate::interpreter::env::RibComponentFunctionInvoke;
126 use crate::{
127 ComponentDependencyKey, EvaluatedFnArgs, EvaluatedFqFn, EvaluatedWorkerName, InstructionId,
128 RibFunctionInvokeResult,
129 };
130 use async_trait::async_trait;
131 use golem_wasm_ast::analysis::AnalysedType;
132
133 pub(crate) struct NoopRibFunctionInvoke;
134
135 #[async_trait]
136 impl RibComponentFunctionInvoke for NoopRibFunctionInvoke {
137 async fn invoke(
138 &self,
139 _component_info: ComponentDependencyKey,
140 _instruction_id: &InstructionId,
141 _worker_name: EvaluatedWorkerName,
142 _function_name: EvaluatedFqFn,
143 _args: EvaluatedFnArgs,
144 _return_type: Option<AnalysedType>,
145 ) -> RibFunctionInvokeResult {
146 Ok(None)
147 }
148 }
149}