//! Schema 8 engineering definitions and static admission. No expression evaluation. mod admission; mod expression_lifecycle; pub(crate) mod expression_serde; pub mod references; mod resolve; mod typecheck; mod types; pub(crate) use admission::admit_structure_checked; pub use admission::{AdmissionLimits, AdmissionUsage, admit}; pub use resolve::{EffectiveBinding, KindHandle, ResolvedAnalysis, ResolvedScalar, ResolvedType}; pub use types::*; /// Ratified semantic bounds. Aggregate admission work is a separate caller policy. pub const MAX_EXPRESSION_DEPTH: usize = 128; pub const MAX_CLOSURE_NODES: usize = 65_536; pub const MAX_LIST_LENGTH: usize = 1_024; pub const MAX_CALL_DEPTH: usize = 32; /// Additional persisted records for existing transport ParseLimits. Definitions /// themselves count as graph objects there; this counts parameters, overrides, /// and every stored expression node, with saturating arithmetic and no recursion. pub(crate) fn nested_record_count(project: &crate::Project) -> usize { let mut count = 0usize; fn binding(value: &Binding, count: &mut usize) { if let Binding::Expression(expression) = value { references::walk(expression, &mut |_| { *count = count.saturating_add(1); }); } } for definition in project.definitions.values() { if let DefinitionBody::Calculation(calculation) = &definition.body { count = count.saturating_add(calculation.parameters.len()); binding(&calculation.body, &mut count); } } for element in project.elements.values() { match element.shared() { Some(crate::SharedBody::EngineeringProperty { base, .. }) => binding(base, &mut count), Some(crate::SharedBody::AnalysisCase { overrides, .. }) => { count = count.saturating_add(overrides.len()); for value in overrides.values() { binding(value, &mut count); } } Some(crate::SharedBody::AnalysisCheck { predicate, .. }) => { binding(predicate, &mut count) } _ => {} } } count } #[cfg(test)] mod tests;