MCPcopy Create free account
hub / github.com/cel-expr/cel-go / compileRule

Method compileRule

policy/compiler.go:313–413  ·  view source on GitHub ↗
(r *Rule, p *Policy, ruleEnv *cel.Env, iss *cel.Issues)

Source from the content-addressed store, hash-verified

311}
312
313func (c *compiler) compileRule(r *Rule, p *Policy, ruleEnv *cel.Env, iss *cel.Issues) (*CompiledRule, *cel.Issues) {
314 compiledVars := make([]*CompiledVariable, len(r.Variables()))
315 for i, v := range r.Variables() {
316 exprSrc := c.relSource(v.Expression())
317 varAST, exprIss := ruleEnv.CompileSource(exprSrc)
318 varName := v.Name().Value
319
320 // Determine the variable type. If the expression is an error then record the error and
321 // mark the variable type as dyn to permit compilation to continue.
322 varType := types.DynType
323 if exprIss.Err() != nil {
324 iss = iss.Append(exprIss)
325 } else {
326 // Otherwise, the expression compiled successfully and we use its output type.
327 varType = varAST.OutputType()
328 }
329
330 // Introduce the variable into the environment. By extending the environment, the variables
331 // are effectively scoped such that they must be declared before use.
332 varDecl := decls.NewVariable(fmt.Sprintf("%s.%s", variablePrefix, varName), varType)
333 varEnv, err := ruleEnv.Extend(cel.Variable(varDecl.Name(), varDecl.Type()))
334 if err != nil {
335 iss.ReportErrorAtID(v.exprID, "invalid variable declaration: %s", err.Error())
336 } else {
337 ruleEnv = varEnv
338 }
339 compiledVar := &CompiledVariable{
340 exprID: v.name.ID,
341 name: v.name.Value,
342 expr: varAST,
343 varDecl: varDecl,
344 }
345 compiledVars[i] = compiledVar
346
347 // Increment the nesting count post-compile.
348 c.nestedCount++
349 if c.nestedCount == c.maxNestedExpressions+1 {
350 iss.ReportErrorAtID(compiledVar.SourceID(), "variable exceeds nested expression limit")
351 }
352 }
353
354 // Compile the set of match conditions under the rule.
355 compiledMatches := []*CompiledMatch{}
356 for _, m := range r.Matches() {
357 condSrc := c.relSource(m.Condition())
358 condAST, condIss := ruleEnv.CompileSource(condSrc)
359 iss = iss.Append(condIss)
360 // This case cannot happen when the Policy object is parsed from yaml, but could happen
361 // with a non-YAML generation of the Policy object.
362 // TODO: Test this case once there's an alternative method of constructing Policy objects
363 if m.HasOutput() && m.HasRule() {
364 iss.ReportErrorAtID(m.Condition().ID, "either output or rule may be set but not both")
365 continue
366 }
367 if m.HasOutput() {
368 mc := &matchCompilerImpl{env: ruleEnv, c: c, iss: iss}
369 outAST, outIss := c.compileMatchOutput(mc, m, p)
370 iss = iss.Append(outIss)

Callers 1

CompileRuleFunction · 0.95

Calls 15

relSourceMethod · 0.95
NameMethod · 0.95
SourceIDMethod · 0.95
checkUnreachableCodeMethod · 0.95
NewVariableFunction · 0.92
VariableFunction · 0.92
ExpressionMethod · 0.80
CompileSourceMethod · 0.80
ErrMethod · 0.80
HasOutputMethod · 0.80
HasRuleMethod · 0.80

Tested by

no test coverage detected