feat(azure-policy): implement count/count.where compilation#688
feat(azure-policy): implement count/count.where compilation#688anakrish merged 1 commit intomicrosoft:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new (RVM-backed) Azure Policy AST compiler with initial support for template expressions, field/wildcard resolution, and count/count.where compilation.
Changes:
- Exposes
languages::azure_policy::compilerbehind thervmfeature and adds public compile entry points for rules/definitions (with optional alias resolution/default parameters). - Implements core compilation infrastructure (register allocation, instruction emission, alias resolution) plus template-expression/function dispatch and field path handling (including
[*]wildcard collection). - Implements
countcompilation, including nested-wildcard counts,current()binding resolution, and an “existence pattern” optimization usingLoopMode::Any.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/rvm/vm/machine.rs | Adds clippy allows for a cfg’d no-op memory_check variant. |
| src/languages/azure_policy/mod.rs | Exposes the new Azure Policy compiler module when feature = "rvm" is enabled. |
| src/languages/azure_policy/compiler/mod.rs | New public entry points for compiling policy rules/definitions into RVM programs. |
| src/languages/azure_policy/compiler/core.rs | New compiler core: register allocation, emitting instructions, builtin calls, alias resolution. |
| src/languages/azure_policy/compiler/expressions.rs | Compiles template expressions and selected template functions. |
| src/languages/azure_policy/compiler/template_dispatch.rs | Dispatches ARM template function names to builtins/native instructions. |
| src/languages/azure_policy/compiler/fields.rs | Compiles field kinds and resource-path reads, including wildcard collection. |
| src/languages/azure_policy/compiler/count.rs | Implements count/count.where, nested wildcards, current() resolution, and existence optimization. |
| src/languages/azure_policy/compiler/conditions.rs | Compiles constraints/conditions with short-circuiting and count optimizations. |
| src/languages/azure_policy/compiler/conditions_wildcard.rs | Implements implicit allOf semantics for unbound [*] wildcard fields. |
| src/languages/azure_policy/compiler/utils.rs | Adds helper utilities: JSON→runtime conversion and field-path splitting (+ tests). |
| src/languages/azure_policy/compiler/effects.rs | Stubbed effect compilation (currently always errors). |
| src/languages/azure_policy/compiler/metadata.rs | Stubbed metadata/annotation accumulation hooks. |
| src/languages/azure_policy/compiler/effects_modify_append.rs | Stub module placeholder for Modify/Append effect compilation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
5de39aa to
16ffe10
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
16ffe10 to
b1de3aa
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
b1de3aa to
153e20f
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
153e20f to
8ec9e7c
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
8ec9e7c to
9d69508
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
7c3f94a to
39ae386
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
d36fe69 to
d5ebf13
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
d5ebf13 to
67dcb6f
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
67dcb6f to
ecdc8df
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| where_, | ||
| } => { | ||
| let field_path = self.extract_field_count_path(field, span)?; | ||
| let (_prefix, suffix) = split_count_wildcard_path(&field_path)?; |
There was a problem hiding this comment.
split_count_wildcard_path(&field_path)? can fail for user-authored policies (e.g., count over a field that doesn’t contain [*]). The error returned from split_count_wildcard_path is a plain anyhow message without span context, so it won’t point back to the policy source location like other compiler errors. Consider mapping the error into span.error(...) (or adding a span-aware wrapper) so invalid count field paths produce a source-annotated diagnostic.
| let (_prefix, suffix) = split_count_wildcard_path(&field_path)?; | |
| let (_prefix, suffix) = split_count_wildcard_path(&field_path) | |
| .map_err(|err| span.error(err.to_string()))?; |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Implement the full count loop compiler, replacing the stubs in count.rs, count_any.rs, and count_bindings.rs with a single consolidated module. Handles both field-based and value-based count nodes. Field counts walk the resource via resolve_alias_path then iterate the wildcard array; value counts operate on an arbitrary collection expression. For nested wildcard paths like A[*].B[*].C, the compiler emits recursive ForEach loops, drilling one wildcard level at a time. When an outer count binding already covers a prefix, the inner loop starts from the bound element register instead of re-walking from the resource root. Existence patterns (count > 0, count == 0) are recognized and lowered to LoopMode::Any, which exits on the first match rather than counting every element. Count-binding resolution threads the current-element register through inner field references and current() calls so that nested conditions can address fields relative to the loop variable. Also fixes the bound_len arithmetic in conditions_wildcard.rs with a cleaner strip_prefix call, and removes the nested-wildcard bail in split_count_wildcard_path since the compiler now handles them.
ecdc8df to
f3047c8
Compare
Implement the full count loop compiler, replacing the stubs in count.rs, count_any.rs, and count_bindings.rs with a single consolidated module.
Handles both field-based and value-based count nodes. Field counts walk the resource via
resolve_alias_paththen iterate the wildcard array; value counts operate on an arbitrary collection expression.For nested wildcard paths like
A[*].B[*].C, the compiler emits recursive ForEach loops, drilling one wildcard level at a time. When an outer count binding already covers a prefix, the inner loop starts from the bound element register instead of re-walking from the resource root.Existence patterns (
count > 0,count == 0) are recognized and lowered toLoopMode::Any, which exits on the first match rather than counting every element.Count-binding resolution threads the current-element register through inner field references and
current()calls so that nested conditions can address fields relative to the loop variable.Also fixes the
bound_lenarithmetic inconditions_wildcard.rswith a cleanerstrip_prefixcall, and removes the nested-wildcard bail insplit_count_wildcard_pathsince the compiler now handles them.Changes
compile_count, nested loop emission, existence-pattern optimization, count-binding resolution,current()references.bound_len/saturating_addwithstrip_prefixsplit_count_wildcard_path; update test