2023-04-12 16:09:12 +01:00
|
|
|
/*
|
|
|
|
* Copyright 2023 Fluence Labs Limited
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
use super::RcSecurityTetraplets;
|
|
|
|
use super::Resolvable;
|
|
|
|
use crate::execution_step::execution_context::ExecutionCtx;
|
|
|
|
use crate::execution_step::lambda_applier::select_by_lambda_from_scalar;
|
2023-08-07 20:00:02 +03:00
|
|
|
use crate::execution_step::value_types::JValuable;
|
2023-04-12 16:09:12 +01:00
|
|
|
use crate::execution_step::ExecutionResult;
|
|
|
|
use crate::JValue;
|
|
|
|
use crate::SecurityTetraplet;
|
|
|
|
|
2023-05-08 19:42:41 +07:00
|
|
|
use air_interpreter_data::Provenance;
|
2023-09-04 22:57:51 +03:00
|
|
|
use air_lambda_ast::LambdaAST;
|
2023-04-12 16:09:12 +01:00
|
|
|
use air_parser::ast;
|
|
|
|
|
2023-09-04 22:57:51 +03:00
|
|
|
use air_parser::ast::InstructionErrorAST;
|
2023-04-12 16:09:12 +01:00
|
|
|
use serde_json::json;
|
|
|
|
use std::rc::Rc;
|
|
|
|
|
|
|
|
/// Resolve value to called function arguments.
|
|
|
|
impl Resolvable for ast::ImmutableValue<'_> {
|
2023-05-08 19:42:41 +07:00
|
|
|
fn resolve(&self, ctx: &ExecutionCtx<'_>) -> ExecutionResult<(JValue, RcSecurityTetraplets, Provenance)> {
|
2023-04-12 16:09:12 +01:00
|
|
|
use ast::ImmutableValue::*;
|
|
|
|
|
|
|
|
match self {
|
2023-05-08 19:42:41 +07:00
|
|
|
InitPeerId => resolve_const(ctx.run_parameters.init_peer_id.as_ref(), ctx),
|
2023-09-04 22:57:51 +03:00
|
|
|
Error(error_accessor) => error_accessor.resolve(ctx),
|
2023-04-12 16:09:12 +01:00
|
|
|
LastError(error_accessor) => error_accessor.resolve(ctx),
|
|
|
|
Literal(value) => resolve_const(value.to_string(), ctx),
|
|
|
|
Timestamp => resolve_const(ctx.run_parameters.timestamp, ctx),
|
|
|
|
TTL => resolve_const(ctx.run_parameters.ttl, ctx),
|
|
|
|
Boolean(value) => resolve_const(*value, ctx),
|
|
|
|
Number(value) => resolve_const(value, ctx),
|
|
|
|
EmptyArray => resolve_const(json!([]), ctx),
|
|
|
|
Variable(variable) => variable.resolve(ctx),
|
|
|
|
VariableWithLambda(variable) => variable.resolve(ctx),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn resolve_const(
|
|
|
|
arg: impl Into<JValue>,
|
|
|
|
ctx: &ExecutionCtx<'_>,
|
2023-05-08 19:42:41 +07:00
|
|
|
) -> ExecutionResult<(JValue, RcSecurityTetraplets, Provenance)> {
|
2023-04-12 16:09:12 +01:00
|
|
|
let jvalue = arg.into();
|
|
|
|
let tetraplet = SecurityTetraplet::literal_tetraplet(ctx.run_parameters.init_peer_id.as_ref());
|
|
|
|
let tetraplet = Rc::new(tetraplet);
|
|
|
|
|
2023-05-08 19:42:41 +07:00
|
|
|
Ok((jvalue, vec![tetraplet], Provenance::literal()))
|
2023-04-12 16:09:12 +01:00
|
|
|
}
|
|
|
|
|
2023-09-04 22:57:51 +03:00
|
|
|
fn resolve_errors(
|
|
|
|
instruction_error: &crate::InstructionError,
|
|
|
|
lens: &Option<LambdaAST<'_>>,
|
|
|
|
ctx: &ExecutionCtx<'_>,
|
|
|
|
) -> Result<(serde_json::Value, Vec<Rc<SecurityTetraplet>>, Provenance), crate::ExecutionError> {
|
|
|
|
use crate::execution_step::InstructionError;
|
|
|
|
|
|
|
|
let InstructionError {
|
|
|
|
error,
|
|
|
|
tetraplet,
|
|
|
|
provenance,
|
|
|
|
} = instruction_error;
|
|
|
|
|
|
|
|
let jvalue = match lens {
|
|
|
|
Some(error_accessor) => select_by_lambda_from_scalar(error.as_ref(), error_accessor, ctx)?.into_owned(),
|
|
|
|
None => error.as_ref().clone(),
|
|
|
|
};
|
|
|
|
|
|
|
|
let tetraplets = match tetraplet {
|
|
|
|
Some(tetraplet) => vec![tetraplet.clone()],
|
|
|
|
None => {
|
|
|
|
let tetraplet = SecurityTetraplet::literal_tetraplet(ctx.run_parameters.init_peer_id.as_ref());
|
|
|
|
let tetraplet = Rc::new(tetraplet);
|
|
|
|
vec![tetraplet]
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok((jvalue, tetraplets, provenance.clone()))
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'lens> Resolvable for InstructionErrorAST<'lens> {
|
|
|
|
fn resolve(&self, ctx: &ExecutionCtx<'_>) -> ExecutionResult<(JValue, RcSecurityTetraplets, Provenance)> {
|
|
|
|
let instruction_error = ctx.error();
|
|
|
|
resolve_errors(instruction_error, &self.lens, ctx)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-12 16:09:12 +01:00
|
|
|
impl Resolvable for Option<LambdaAST<'_>> {
|
2023-05-08 19:42:41 +07:00
|
|
|
fn resolve(&self, ctx: &ExecutionCtx<'_>) -> ExecutionResult<(JValue, RcSecurityTetraplets, Provenance)> {
|
2023-09-04 22:57:51 +03:00
|
|
|
let instruction_error = ctx.last_error();
|
|
|
|
resolve_errors(instruction_error, self, ctx)
|
2023-04-12 16:09:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Resolvable for ast::Scalar<'_> {
|
2023-05-08 19:42:41 +07:00
|
|
|
fn resolve(&self, ctx: &ExecutionCtx<'_>) -> ExecutionResult<(JValue, RcSecurityTetraplets, Provenance)> {
|
|
|
|
let (value, provenance) = ctx.scalars.get_value(self.name)?.into_jvaluable();
|
2023-04-12 16:09:12 +01:00
|
|
|
let tetraplets = value.as_tetraplets();
|
2023-05-08 19:42:41 +07:00
|
|
|
Ok((value.into_jvalue(), tetraplets, provenance))
|
2023-04-12 16:09:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Resolvable for ast::CanonStream<'_> {
|
2023-05-08 19:42:41 +07:00
|
|
|
fn resolve(&self, ctx: &ExecutionCtx<'_>) -> ExecutionResult<(JValue, RcSecurityTetraplets, Provenance)> {
|
|
|
|
let canon = ctx.scalars.get_canon_stream(self.name)?;
|
|
|
|
let value: &dyn JValuable = &&canon.canon_stream;
|
2023-04-12 16:09:12 +01:00
|
|
|
let tetraplets = value.as_tetraplets();
|
2023-05-08 19:42:41 +07:00
|
|
|
Ok((
|
|
|
|
value.as_jvalue().into_owned(),
|
|
|
|
tetraplets,
|
|
|
|
Provenance::canon(canon.cid.clone()),
|
|
|
|
))
|
2023-04-12 16:09:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Resolvable for ast::ImmutableVariable<'_> {
|
2023-05-08 19:42:41 +07:00
|
|
|
fn resolve(&self, ctx: &ExecutionCtx<'_>) -> ExecutionResult<(JValue, RcSecurityTetraplets, Provenance)> {
|
2023-04-12 16:09:12 +01:00
|
|
|
match self {
|
|
|
|
Self::Scalar(scalar) => scalar.resolve(ctx),
|
|
|
|
Self::CanonStream(canon_stream) => canon_stream.resolve(ctx),
|
2023-09-07 11:30:24 +03:00
|
|
|
Self::CanonStreamMap(canon_stream_map) => canon_stream_map.resolve(ctx),
|
2023-04-12 16:09:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Resolvable for ast::ScalarWithLambda<'_> {
|
2023-05-08 19:42:41 +07:00
|
|
|
fn resolve(&self, ctx: &ExecutionCtx<'_>) -> ExecutionResult<(JValue, RcSecurityTetraplets, Provenance)> {
|
|
|
|
let (value, root_provenance) = ctx.scalars.get_value(self.name)?.into_jvaluable();
|
|
|
|
let (value, tetraplet, provenance) = value.apply_lambda_with_tetraplets(&self.lambda, ctx, &root_provenance)?;
|
2023-04-12 16:09:12 +01:00
|
|
|
let tetraplet = Rc::new(tetraplet);
|
2023-05-08 19:42:41 +07:00
|
|
|
Ok((value.into_owned(), vec![tetraplet], provenance))
|
2023-04-12 16:09:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Resolvable for ast::CanonStreamWithLambda<'_> {
|
2023-05-08 19:42:41 +07:00
|
|
|
fn resolve(&self, ctx: &ExecutionCtx<'_>) -> ExecutionResult<(JValue, RcSecurityTetraplets, Provenance)> {
|
|
|
|
let canon = ctx.scalars.get_canon_stream(self.name)?;
|
|
|
|
let value: &dyn JValuable = &&canon.canon_stream;
|
|
|
|
let (value, tetraplet, provenance) =
|
|
|
|
value.apply_lambda_with_tetraplets(&self.lambda, ctx, &Provenance::canon(canon.cid.clone()))?;
|
2023-04-12 16:09:12 +01:00
|
|
|
let tetraplet = Rc::new(tetraplet);
|
2023-05-08 19:42:41 +07:00
|
|
|
Ok((value.into_owned(), vec![tetraplet], provenance))
|
2023-04-12 16:09:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Resolvable for ast::ImmutableVariableWithLambda<'_> {
|
2023-05-08 19:42:41 +07:00
|
|
|
fn resolve(&self, ctx: &ExecutionCtx<'_>) -> ExecutionResult<(JValue, RcSecurityTetraplets, Provenance)> {
|
2023-04-12 16:09:12 +01:00
|
|
|
match self {
|
|
|
|
Self::Scalar(scalar) => scalar.resolve(ctx),
|
|
|
|
Self::CanonStream(canon_stream) => canon_stream.resolve(ctx),
|
2023-09-07 11:30:24 +03:00
|
|
|
Self::CanonStreamMap(canon_stream_map) => canon_stream_map.resolve(ctx),
|
2023-04-12 16:09:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-09-07 11:30:24 +03:00
|
|
|
|
|
|
|
impl Resolvable for ast::StreamMapKeyClause<'_> {
|
|
|
|
fn resolve(&self, ctx: &ExecutionCtx<'_>) -> ExecutionResult<(JValue, RcSecurityTetraplets, Provenance)> {
|
|
|
|
match self {
|
|
|
|
ast::StreamMapKeyClause::Literal(value) => resolve_const(value.to_string(), ctx),
|
|
|
|
ast::StreamMapKeyClause::Int(value) => resolve_const(*value, ctx),
|
|
|
|
ast::StreamMapKeyClause::Scalar(scalar) => scalar.resolve(ctx),
|
|
|
|
ast::StreamMapKeyClause::ScalarWithLambda(scalar_with_lambda) => scalar_with_lambda.resolve(ctx),
|
|
|
|
ast::StreamMapKeyClause::CanonStreamWithLambda(canon_with_lambda) => canon_with_lambda.resolve(ctx),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Resolvable for ast::CanonStreamMap<'_> {
|
|
|
|
fn resolve(&self, ctx: &ExecutionCtx<'_>) -> ExecutionResult<(JValue, RcSecurityTetraplets, Provenance)> {
|
|
|
|
let canon_stream_map_name = self.name;
|
|
|
|
let canon_stream_map_with_prov = ctx.scalars.get_canon_map(canon_stream_map_name)?;
|
|
|
|
let canon_stream_map = &canon_stream_map_with_prov.canon_stream_map;
|
|
|
|
let value: &dyn JValuable = &canon_stream_map;
|
|
|
|
let tetraplets = value.as_tetraplets();
|
|
|
|
let provenance = Provenance::canon(canon_stream_map_with_prov.cid.clone());
|
|
|
|
|
|
|
|
Ok((value.as_jvalue().into_owned(), tetraplets, provenance))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Resolvable for ast::CanonStreamMapWithLambda<'_> {
|
|
|
|
fn resolve(&self, ctx: &ExecutionCtx<'_>) -> ExecutionResult<(JValue, RcSecurityTetraplets, Provenance)> {
|
|
|
|
let canon_stream_map_name = self.name;
|
|
|
|
let canon_stream_map_with_prov = ctx.scalars.get_canon_map(canon_stream_map_name)?;
|
|
|
|
let canon_stream_map = &canon_stream_map_with_prov.canon_stream_map;
|
|
|
|
let root_provenance = Provenance::canon(canon_stream_map_with_prov.cid.clone());
|
|
|
|
let (value, tetraplet, provenance) =
|
|
|
|
canon_stream_map.apply_lambda_with_tetraplets(&self.lambda, ctx, &root_provenance)?;
|
|
|
|
|
|
|
|
let tetraplet = Rc::new(tetraplet);
|
|
|
|
|
|
|
|
Ok((value.into_owned(), vec![tetraplet], provenance))
|
|
|
|
}
|
|
|
|
}
|