rib/interpreter/
env.rs

1// Copyright 2024-2025 Golem Cloud
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::interpreter::interpreter_stack_value::RibInterpreterStackValue;
16use crate::{
17    EvaluatedFnArgs, EvaluatedFqFn, EvaluatedWorkerName, RibFunctionInvoke, RibInput, VariableId,
18};
19use golem_wasm_rpc::ValueAndType;
20use std::collections::HashMap;
21use std::fmt::Debug;
22use std::sync::Arc;
23
24pub struct InterpreterEnv {
25    pub env: HashMap<EnvironmentKey, RibInterpreterStackValue>,
26    pub call_worker_function_async: Arc<dyn RibFunctionInvoke + Sync + Send>,
27}
28
29impl Debug for InterpreterEnv {
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        f.debug_struct("InterpreterEnv")
32            .field("env", &self.env.iter())
33            .finish()
34    }
35}
36
37impl Default for InterpreterEnv {
38    fn default() -> Self {
39        InterpreterEnv {
40            env: HashMap::new(),
41            call_worker_function_async: Arc::new(internal::NoopRibFunctionInvoke),
42        }
43    }
44}
45
46impl InterpreterEnv {
47    pub async fn invoke_worker_function_async(
48        &self,
49        worker_name: Option<String>,
50        function_name: String,
51        args: Vec<ValueAndType>,
52    ) -> Result<ValueAndType, String> {
53        self.call_worker_function_async
54            .invoke(
55                worker_name.map(EvaluatedWorkerName),
56                EvaluatedFqFn(function_name),
57                EvaluatedFnArgs(args),
58            )
59            .await
60    }
61
62    pub fn from_input(env: &RibInput) -> Self {
63        let env = env
64            .input
65            .clone()
66            .into_iter()
67            .map(|(k, v)| {
68                (
69                    EnvironmentKey::from_global(k),
70                    RibInterpreterStackValue::Val(v),
71                )
72            })
73            .collect();
74
75        InterpreterEnv {
76            env,
77            call_worker_function_async: Arc::new(internal::NoopRibFunctionInvoke),
78        }
79    }
80
81    pub fn from(
82        input: &RibInput,
83        call_worker_function_async: &Arc<dyn RibFunctionInvoke + Sync + Send>,
84    ) -> Self {
85        let mut env = Self::from_input(input);
86        env.call_worker_function_async = call_worker_function_async.clone();
87        env
88    }
89
90    pub fn insert(&mut self, key: EnvironmentKey, value: RibInterpreterStackValue) {
91        self.env.insert(key, value);
92    }
93
94    pub fn lookup(&self, key: &EnvironmentKey) -> Option<&RibInterpreterStackValue> {
95        self.env.get(key)
96    }
97}
98
99#[derive(Debug, Hash, Eq, PartialEq, Clone)]
100pub struct EnvironmentKey {
101    pub variable_id: VariableId,
102}
103
104impl EnvironmentKey {
105    pub fn from(variable_id: VariableId) -> Self {
106        EnvironmentKey { variable_id }
107    }
108
109    pub fn from_global(key: String) -> Self {
110        EnvironmentKey {
111            variable_id: VariableId::global(key),
112        }
113    }
114}
115
116mod internal {
117    use crate::interpreter::env::RibFunctionInvoke;
118    use crate::{EvaluatedFnArgs, EvaluatedFqFn, EvaluatedWorkerName};
119    use async_trait::async_trait;
120    use golem_wasm_ast::analysis::analysed_type::tuple;
121    use golem_wasm_rpc::{Value, ValueAndType};
122
123    pub(crate) struct NoopRibFunctionInvoke;
124
125    #[async_trait]
126    impl RibFunctionInvoke for NoopRibFunctionInvoke {
127        async fn invoke(
128            &self,
129            _worker_name: Option<EvaluatedWorkerName>,
130            _function_name: EvaluatedFqFn,
131            _args: EvaluatedFnArgs,
132        ) -> Result<ValueAndType, String> {
133            Ok(ValueAndType::new(Value::Tuple(vec![]), tuple(vec![])))
134        }
135    }
136}