func NewCustomEnv(opts ...EnvOption) (*Env, error) {
	registry, err := types.NewRegistry()
	if err != nil {
		return nil, err
	}
	return (&Env{
		declarations: []*exprpb.Decl{},
		macros:       []parser.Macro{},
		Container:    containers.DefaultContainer,
		adapter:      registry,
		provider:     registry,
		features:     map[int]bool{},
		progOpts:     []ProgramOption{},
	}).configure(opts)
}
NewCustomEnv creates a custom program environment which is not automatically configured with the
standard library of functions and macros documented in the CEL spec.

The purpose for using a custom environment might be for subsetting the standard library produced
by the cel.StdLib() function. Subsetting CEL is a core aspect of its design that allows users to
limit the compute and memory impact of a CEL program by controlling the functions and macros
that may appear in a given expression.

See the EnvOption helper functions for the options that can be used to configure the
environment.
package cel
import (
	"errors"
	"sync"
	"github.com/google/cel-go/checker"
	"github.com/google/cel-go/checker/decls"
	"github.com/google/cel-go/common"
	"github.com/google/cel-go/common/containers"
	"github.com/google/cel-go/common/types"
	"github.com/google/cel-go/common/types/ref"
	"github.com/google/cel-go/interpreter"
	"github.com/google/cel-go/parser"
	exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
)
type Source interface {
	common.Source
}
type Ast struct {
	expr    *exprpb.Expr
	info    *exprpb.SourceInfo
	source  Source
	refMap  map[int64]*exprpb.Reference
	typeMap map[int64]*exprpb.Type
}
func (ast *Ast) Expr() *exprpb.Expr {
	return ast.expr
}
func (ast *Ast) IsChecked() bool {
	return ast.typeMap != nil && len(ast.typeMap) > 0
}
func (ast *Ast) SourceInfo() *exprpb.SourceInfo {
	return ast.info
}
func (ast *Ast) ResultType() *exprpb.Type {
	if !ast.IsChecked() {
		return decls.Dyn
	}
	return ast.typeMap[ast.expr.Id]
}
func (ast *Ast) Source() Source {
	return ast.source
}
func FormatType(t *exprpb.Type) string {
	return checker.FormatCheckedType(t)
}
type Env struct {
	Container    *containers.Container
	declarations []*exprpb.Decl
	macros       []parser.Macro
	adapter      ref.TypeAdapter
	provider     ref.TypeProvider
	features     map[int]bool
	progOpts []ProgramOption
	chk    *checker.Env
	chkErr error
	once   sync.Once
}
func NewEnv(opts ...EnvOption) (*Env, error) {
	stdOpts := append([]EnvOption{StdLib()}, opts...)
	return NewCustomEnv(stdOpts...)
}