#![allow(dead_code)]
mod conditions;
mod conditions_wildcard;
mod core;
mod count;
mod effects;
mod effects_modify_append;
mod expressions;
mod fields;
mod metadata;
mod template_dispatch;
mod utils;
use alloc::string::ToString as _;
use anyhow::Result;
use crate::languages::azure_policy::aliases::AliasRegistry;
use crate::languages::azure_policy::ast::{PolicyDefinition, PolicyRule};
use crate::rvm::program::Program;
use crate::{Rc, Value};
use self::core::Compiler;
fn init_effect_annotation(compiler: &mut Compiler, rule: &PolicyRule) {
compiler.program.metadata.language = "azure_policy".to_string();
let effect = compiler.resolve_effect_annotation(rule);
compiler
.program
.metadata
.annotations
.insert("effect".to_string(), Value::String(effect.as_str().into()));
}
pub fn compile_policy_rule(rule: &PolicyRule) -> Result<Rc<Program>> {
let mut compiler = Compiler::new();
init_effect_annotation(&mut compiler, rule);
compiler.compile(rule)
}
pub fn compile_policy_rule_with_aliases(
rule: &PolicyRule,
registry: Rc<AliasRegistry>,
) -> Result<Rc<Program>> {
let mut compiler = Compiler::new();
compiler.alias_registry = Some(registry);
init_effect_annotation(&mut compiler, rule);
compiler.compile(rule)
}
pub fn compile_policy_definition(defn: &PolicyDefinition) -> Result<Rc<Program>> {
let mut compiler = Compiler::new();
compiler.parameter_defaults = Some(build_parameter_defaults(&defn.parameters)?);
compiler.populate_definition_metadata(defn);
init_effect_annotation(&mut compiler, &defn.policy_rule);
compiler.compile(&defn.policy_rule)
}
pub fn compile_policy_definition_with_aliases(
defn: &PolicyDefinition,
registry: Rc<AliasRegistry>,
) -> Result<Rc<Program>> {
let mut compiler = Compiler::new();
compiler.alias_registry = Some(registry);
compiler.parameter_defaults = Some(build_parameter_defaults(&defn.parameters)?);
compiler.populate_definition_metadata(defn);
init_effect_annotation(&mut compiler, &defn.policy_rule);
compiler.compile(&defn.policy_rule)
}
pub fn compile_policy_definition_with_aliases_opts(
defn: &PolicyDefinition,
registry: Rc<AliasRegistry>,
alias_fallback_to_raw: bool,
) -> Result<Rc<Program>> {
let mut compiler = Compiler::new();
compiler.alias_registry = Some(registry);
compiler.alias_fallback_to_raw = alias_fallback_to_raw;
compiler.parameter_defaults = Some(build_parameter_defaults(&defn.parameters)?);
compiler.populate_definition_metadata(defn);
init_effect_annotation(&mut compiler, &defn.policy_rule);
compiler.compile(&defn.policy_rule)
}
fn build_parameter_defaults(
params: &[crate::languages::azure_policy::ast::ParameterDefinition],
) -> Result<Value> {
use crate::languages::azure_policy::compiler::expressions::check_json_depth;
use crate::languages::azure_policy::compiler::utils::json_value_to_runtime;
use alloc::format;
use anyhow::Context as _;
let mut obj = Value::new_object();
let map = obj.as_object_mut()?;
for param in params {
if let Some(ref default_val) = param.default_value {
check_json_depth(default_val, 0).with_context(|| {
format!(
"invalid defaultValue for parameter '{}': exceeds maximum JSON depth",
param.name
)
})?;
let runtime_val = json_value_to_runtime(default_val)
.with_context(|| format!("invalid defaultValue for parameter '{}'", param.name))?;
map.insert(Value::from(param.name.clone()), runtime_val);
}
}
Ok(obj)
}