Skip to content

Commit fb02c9a

Browse files
authored
Init function bindings on environment init (#1199)
* Init function bindings on environment init * Move calculation of function bindings under sync.Once call in new program creation
1 parent cf932c7 commit fb02c9a

File tree

2 files changed

+36
-21
lines changed

2 files changed

+36
-21
lines changed

cel/env.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/google/cel-go/common/containers"
2828
"github.com/google/cel-go/common/decls"
2929
"github.com/google/cel-go/common/env"
30+
"github.com/google/cel-go/common/functions"
3031
"github.com/google/cel-go/common/stdlib"
3132
"github.com/google/cel-go/common/types"
3233
"github.com/google/cel-go/common/types/ref"
@@ -142,6 +143,9 @@ type Env struct {
142143
validators []ASTValidator
143144
costOptions []checker.CostOption
144145

146+
funcBindOnce sync.Once
147+
functionBindings []*functions.Overload
148+
145149
// Internal parser representation
146150
prsr *parser.Parser
147151
prsrOpts []parser.Option
@@ -320,18 +324,19 @@ func NewCustomEnv(opts ...EnvOption) (*Env, error) {
320324
return nil, err
321325
}
322326
return (&Env{
323-
variables: []*decls.VariableDecl{},
324-
functions: map[string]*decls.FunctionDecl{},
325-
macros: []parser.Macro{},
326-
Container: containers.DefaultContainer,
327-
adapter: registry,
328-
provider: registry,
329-
features: map[int]bool{},
330-
appliedFeatures: map[int]bool{},
331-
libraries: map[string]SingletonLibrary{},
332-
validators: []ASTValidator{},
333-
progOpts: []ProgramOption{},
334-
costOptions: []checker.CostOption{},
327+
variables: []*decls.VariableDecl{},
328+
functions: map[string]*decls.FunctionDecl{},
329+
functionBindings: []*functions.Overload{},
330+
macros: []parser.Macro{},
331+
Container: containers.DefaultContainer,
332+
adapter: registry,
333+
provider: registry,
334+
features: map[int]bool{},
335+
appliedFeatures: map[int]bool{},
336+
libraries: map[string]SingletonLibrary{},
337+
validators: []ASTValidator{},
338+
progOpts: []ProgramOption{},
339+
costOptions: []checker.CostOption{},
335340
}).configure(opts)
336341
}
337342

cel/program.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"sync"
2121

2222
"github.com/google/cel-go/common/ast"
23+
"github.com/google/cel-go/common/functions"
2324
"github.com/google/cel-go/common/types"
2425
"github.com/google/cel-go/common/types/ref"
2526
"github.com/google/cel-go/interpreter"
@@ -191,16 +192,25 @@ func newProgram(e *Env, a *ast.AST, opts []ProgramOption) (Program, error) {
191192
}
192193
}
193194

194-
// Add the function bindings created via Function() options.
195-
for _, fn := range e.functions {
196-
bindings, err := fn.Bindings()
197-
if err != nil {
198-
return nil, err
199-
}
200-
err = disp.Add(bindings...)
201-
if err != nil {
202-
return nil, err
195+
e.funcBindOnce.Do(func() {
196+
var bindings []*functions.Overload
197+
e.functionBindings = []*functions.Overload{}
198+
for _, fn := range e.functions {
199+
bindings, err = fn.Bindings()
200+
if err != nil {
201+
return
202+
}
203+
e.functionBindings = append(e.functionBindings, bindings...)
203204
}
205+
})
206+
if err != nil {
207+
return nil, err
208+
}
209+
210+
// Add the function bindings created via Function() options.
211+
err = disp.Add(e.functionBindings...)
212+
if err != nil {
213+
return nil, err
204214
}
205215

206216
// Set the attribute factory after the options have been set.

0 commit comments

Comments
 (0)