mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
rebase: bump the golang-dependencies group with 1 update
Bumps the golang-dependencies group with 1 update: [golang.org/x/crypto](https://github.com/golang/crypto). Updates `golang.org/x/crypto` from 0.16.0 to 0.17.0 - [Commits](https://github.com/golang/crypto/compare/v0.16.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor dependency-group: golang-dependencies ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
mergify[bot]
parent
1ad79314f9
commit
e5d9b68d36
52
vendor/github.com/google/cel-go/common/ast/BUILD.bazel
generated
vendored
Normal file
52
vendor/github.com/google/cel-go/common/ast/BUILD.bazel
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
package(
|
||||
default_visibility = [
|
||||
"//cel:__subpackages__",
|
||||
"//checker:__subpackages__",
|
||||
"//common:__subpackages__",
|
||||
"//interpreter:__subpackages__",
|
||||
],
|
||||
licenses = ["notice"], # Apache 2.0
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"ast.go",
|
||||
"expr.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/ast",
|
||||
deps = [
|
||||
"//common/types:go_default_library",
|
||||
"//common/types/ref:go_default_library",
|
||||
"@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/structpb:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"ast_test.go",
|
||||
"expr_test.go",
|
||||
],
|
||||
embed = [
|
||||
":go_default_library",
|
||||
],
|
||||
deps = [
|
||||
"//checker:go_default_library",
|
||||
"//checker/decls:go_default_library",
|
||||
"//common:go_default_library",
|
||||
"//common/containers:go_default_library",
|
||||
"//common/decls:go_default_library",
|
||||
"//common/overloads:go_default_library",
|
||||
"//common/stdlib:go_default_library",
|
||||
"//common/types:go_default_library",
|
||||
"//common/types/ref:go_default_library",
|
||||
"//parser:go_default_library",
|
||||
"//test/proto3pb:go_default_library",
|
||||
"@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
226
vendor/github.com/google/cel-go/common/ast/ast.go
generated
vendored
Normal file
226
vendor/github.com/google/cel-go/common/ast/ast.go
generated
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package ast declares data structures useful for parsed and checked abstract syntax trees
|
||||
package ast
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
)
|
||||
|
||||
// CheckedAST contains a protobuf expression and source info along with CEL-native type and reference information.
|
||||
type CheckedAST struct {
|
||||
Expr *exprpb.Expr
|
||||
SourceInfo *exprpb.SourceInfo
|
||||
TypeMap map[int64]*types.Type
|
||||
ReferenceMap map[int64]*ReferenceInfo
|
||||
}
|
||||
|
||||
// CheckedASTToCheckedExpr converts a CheckedAST to a CheckedExpr protobouf.
|
||||
func CheckedASTToCheckedExpr(ast *CheckedAST) (*exprpb.CheckedExpr, error) {
|
||||
refMap := make(map[int64]*exprpb.Reference, len(ast.ReferenceMap))
|
||||
for id, ref := range ast.ReferenceMap {
|
||||
r, err := ReferenceInfoToReferenceExpr(ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
refMap[id] = r
|
||||
}
|
||||
typeMap := make(map[int64]*exprpb.Type, len(ast.TypeMap))
|
||||
for id, typ := range ast.TypeMap {
|
||||
t, err := types.TypeToExprType(typ)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
typeMap[id] = t
|
||||
}
|
||||
return &exprpb.CheckedExpr{
|
||||
Expr: ast.Expr,
|
||||
SourceInfo: ast.SourceInfo,
|
||||
ReferenceMap: refMap,
|
||||
TypeMap: typeMap,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CheckedExprToCheckedAST converts a CheckedExpr protobuf to a CheckedAST instance.
|
||||
func CheckedExprToCheckedAST(checked *exprpb.CheckedExpr) (*CheckedAST, error) {
|
||||
refMap := make(map[int64]*ReferenceInfo, len(checked.GetReferenceMap()))
|
||||
for id, ref := range checked.GetReferenceMap() {
|
||||
r, err := ReferenceExprToReferenceInfo(ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
refMap[id] = r
|
||||
}
|
||||
typeMap := make(map[int64]*types.Type, len(checked.GetTypeMap()))
|
||||
for id, typ := range checked.GetTypeMap() {
|
||||
t, err := types.ExprTypeToType(typ)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
typeMap[id] = t
|
||||
}
|
||||
return &CheckedAST{
|
||||
Expr: checked.GetExpr(),
|
||||
SourceInfo: checked.GetSourceInfo(),
|
||||
ReferenceMap: refMap,
|
||||
TypeMap: typeMap,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ReferenceInfo contains a CEL native representation of an identifier reference which may refer to
|
||||
// either a qualified identifier name, a set of overload ids, or a constant value from an enum.
|
||||
type ReferenceInfo struct {
|
||||
Name string
|
||||
OverloadIDs []string
|
||||
Value ref.Val
|
||||
}
|
||||
|
||||
// NewIdentReference creates a ReferenceInfo instance for an identifier with an optional constant value.
|
||||
func NewIdentReference(name string, value ref.Val) *ReferenceInfo {
|
||||
return &ReferenceInfo{Name: name, Value: value}
|
||||
}
|
||||
|
||||
// NewFunctionReference creates a ReferenceInfo instance for a set of function overloads.
|
||||
func NewFunctionReference(overloads ...string) *ReferenceInfo {
|
||||
info := &ReferenceInfo{}
|
||||
for _, id := range overloads {
|
||||
info.AddOverload(id)
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
// AddOverload appends a function overload ID to the ReferenceInfo.
|
||||
func (r *ReferenceInfo) AddOverload(overloadID string) {
|
||||
for _, id := range r.OverloadIDs {
|
||||
if id == overloadID {
|
||||
return
|
||||
}
|
||||
}
|
||||
r.OverloadIDs = append(r.OverloadIDs, overloadID)
|
||||
}
|
||||
|
||||
// Equals returns whether two references are identical to each other.
|
||||
func (r *ReferenceInfo) Equals(other *ReferenceInfo) bool {
|
||||
if r.Name != other.Name {
|
||||
return false
|
||||
}
|
||||
if len(r.OverloadIDs) != len(other.OverloadIDs) {
|
||||
return false
|
||||
}
|
||||
if len(r.OverloadIDs) != 0 {
|
||||
overloadMap := make(map[string]struct{}, len(r.OverloadIDs))
|
||||
for _, id := range r.OverloadIDs {
|
||||
overloadMap[id] = struct{}{}
|
||||
}
|
||||
for _, id := range other.OverloadIDs {
|
||||
_, found := overloadMap[id]
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
if r.Value == nil && other.Value == nil {
|
||||
return true
|
||||
}
|
||||
if r.Value == nil && other.Value != nil ||
|
||||
r.Value != nil && other.Value == nil ||
|
||||
r.Value.Equal(other.Value) != types.True {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ReferenceInfoToReferenceExpr converts a ReferenceInfo instance to a protobuf Reference suitable for serialization.
|
||||
func ReferenceInfoToReferenceExpr(info *ReferenceInfo) (*exprpb.Reference, error) {
|
||||
c, err := ValToConstant(info.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &exprpb.Reference{
|
||||
Name: info.Name,
|
||||
OverloadId: info.OverloadIDs,
|
||||
Value: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ReferenceExprToReferenceInfo converts a protobuf Reference into a CEL-native ReferenceInfo instance.
|
||||
func ReferenceExprToReferenceInfo(ref *exprpb.Reference) (*ReferenceInfo, error) {
|
||||
v, err := ConstantToVal(ref.GetValue())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ReferenceInfo{
|
||||
Name: ref.GetName(),
|
||||
OverloadIDs: ref.GetOverloadId(),
|
||||
Value: v,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ValToConstant converts a CEL-native ref.Val to a protobuf Constant.
|
||||
//
|
||||
// Only simple scalar types are supported by this method.
|
||||
func ValToConstant(v ref.Val) (*exprpb.Constant, error) {
|
||||
if v == nil {
|
||||
return nil, nil
|
||||
}
|
||||
switch v.Type() {
|
||||
case types.BoolType:
|
||||
return &exprpb.Constant{ConstantKind: &exprpb.Constant_BoolValue{BoolValue: v.Value().(bool)}}, nil
|
||||
case types.BytesType:
|
||||
return &exprpb.Constant{ConstantKind: &exprpb.Constant_BytesValue{BytesValue: v.Value().([]byte)}}, nil
|
||||
case types.DoubleType:
|
||||
return &exprpb.Constant{ConstantKind: &exprpb.Constant_DoubleValue{DoubleValue: v.Value().(float64)}}, nil
|
||||
case types.IntType:
|
||||
return &exprpb.Constant{ConstantKind: &exprpb.Constant_Int64Value{Int64Value: v.Value().(int64)}}, nil
|
||||
case types.NullType:
|
||||
return &exprpb.Constant{ConstantKind: &exprpb.Constant_NullValue{NullValue: structpb.NullValue_NULL_VALUE}}, nil
|
||||
case types.StringType:
|
||||
return &exprpb.Constant{ConstantKind: &exprpb.Constant_StringValue{StringValue: v.Value().(string)}}, nil
|
||||
case types.UintType:
|
||||
return &exprpb.Constant{ConstantKind: &exprpb.Constant_Uint64Value{Uint64Value: v.Value().(uint64)}}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported constant kind: %v", v.Type())
|
||||
}
|
||||
|
||||
// ConstantToVal converts a protobuf Constant to a CEL-native ref.Val.
|
||||
func ConstantToVal(c *exprpb.Constant) (ref.Val, error) {
|
||||
if c == nil {
|
||||
return nil, nil
|
||||
}
|
||||
switch c.GetConstantKind().(type) {
|
||||
case *exprpb.Constant_BoolValue:
|
||||
return types.Bool(c.GetBoolValue()), nil
|
||||
case *exprpb.Constant_BytesValue:
|
||||
return types.Bytes(c.GetBytesValue()), nil
|
||||
case *exprpb.Constant_DoubleValue:
|
||||
return types.Double(c.GetDoubleValue()), nil
|
||||
case *exprpb.Constant_Int64Value:
|
||||
return types.Int(c.GetInt64Value()), nil
|
||||
case *exprpb.Constant_NullValue:
|
||||
return types.NullValue, nil
|
||||
case *exprpb.Constant_StringValue:
|
||||
return types.String(c.GetStringValue()), nil
|
||||
case *exprpb.Constant_Uint64Value:
|
||||
return types.Uint(c.GetUint64Value()), nil
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported constant kind: %v", c.GetConstantKind())
|
||||
}
|
709
vendor/github.com/google/cel-go/common/ast/expr.go
generated
vendored
Normal file
709
vendor/github.com/google/cel-go/common/ast/expr.go
generated
vendored
Normal file
@ -0,0 +1,709 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ast
|
||||
|
||||
import (
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
)
|
||||
|
||||
// ExprKind represents the expression node kind.
|
||||
type ExprKind int
|
||||
|
||||
const (
|
||||
// UnspecifiedKind represents an unset expression with no specified properties.
|
||||
UnspecifiedKind ExprKind = iota
|
||||
|
||||
// LiteralKind represents a primitive scalar literal.
|
||||
LiteralKind
|
||||
|
||||
// IdentKind represents a simple variable, constant, or type identifier.
|
||||
IdentKind
|
||||
|
||||
// SelectKind represents a field selection expression.
|
||||
SelectKind
|
||||
|
||||
// CallKind represents a function call.
|
||||
CallKind
|
||||
|
||||
// ListKind represents a list literal expression.
|
||||
ListKind
|
||||
|
||||
// MapKind represents a map literal expression.
|
||||
MapKind
|
||||
|
||||
// StructKind represents a struct literal expression.
|
||||
StructKind
|
||||
|
||||
// ComprehensionKind represents a comprehension expression generated by a macro.
|
||||
ComprehensionKind
|
||||
)
|
||||
|
||||
// NavigateCheckedAST converts a CheckedAST to a NavigableExpr
|
||||
func NavigateCheckedAST(ast *CheckedAST) NavigableExpr {
|
||||
return newNavigableExpr(nil, ast.Expr, ast.TypeMap)
|
||||
}
|
||||
|
||||
// ExprMatcher takes a NavigableExpr in and indicates whether the value is a match.
|
||||
//
|
||||
// This function type should be use with the `Match` and `MatchList` calls.
|
||||
type ExprMatcher func(NavigableExpr) bool
|
||||
|
||||
// ConstantValueMatcher returns an ExprMatcher which will return true if the input NavigableExpr
|
||||
// is comprised of all constant values, such as a simple literal or even list and map literal.
|
||||
func ConstantValueMatcher() ExprMatcher {
|
||||
return matchIsConstantValue
|
||||
}
|
||||
|
||||
// KindMatcher returns an ExprMatcher which will return true if the input NavigableExpr.Kind() matches
|
||||
// the specified `kind`.
|
||||
func KindMatcher(kind ExprKind) ExprMatcher {
|
||||
return func(e NavigableExpr) bool {
|
||||
return e.Kind() == kind
|
||||
}
|
||||
}
|
||||
|
||||
// FunctionMatcher returns an ExprMatcher which will match NavigableExpr nodes of CallKind type whose
|
||||
// function name is equal to `funcName`.
|
||||
func FunctionMatcher(funcName string) ExprMatcher {
|
||||
return func(e NavigableExpr) bool {
|
||||
if e.Kind() != CallKind {
|
||||
return false
|
||||
}
|
||||
return e.AsCall().FunctionName() == funcName
|
||||
}
|
||||
}
|
||||
|
||||
// AllMatcher returns true for all descendants of a NavigableExpr, effectively flattening them into a list.
|
||||
//
|
||||
// Such a result would work well with subsequent MatchList calls.
|
||||
func AllMatcher() ExprMatcher {
|
||||
return func(NavigableExpr) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// MatchDescendants takes a NavigableExpr and ExprMatcher and produces a list of NavigableExpr values of the
|
||||
// descendants which match.
|
||||
func MatchDescendants(expr NavigableExpr, matcher ExprMatcher) []NavigableExpr {
|
||||
return matchListInternal([]NavigableExpr{expr}, matcher, true)
|
||||
}
|
||||
|
||||
// MatchSubset applies an ExprMatcher to a list of NavigableExpr values and their descendants, producing a
|
||||
// subset of NavigableExpr values which match.
|
||||
func MatchSubset(exprs []NavigableExpr, matcher ExprMatcher) []NavigableExpr {
|
||||
visit := make([]NavigableExpr, len(exprs))
|
||||
copy(visit, exprs)
|
||||
return matchListInternal(visit, matcher, false)
|
||||
}
|
||||
|
||||
func matchListInternal(visit []NavigableExpr, matcher ExprMatcher, visitDescendants bool) []NavigableExpr {
|
||||
var matched []NavigableExpr
|
||||
for len(visit) != 0 {
|
||||
e := visit[0]
|
||||
if matcher(e) {
|
||||
matched = append(matched, e)
|
||||
}
|
||||
if visitDescendants {
|
||||
visit = append(visit[1:], e.Children()...)
|
||||
} else {
|
||||
visit = visit[1:]
|
||||
}
|
||||
}
|
||||
return matched
|
||||
}
|
||||
|
||||
func matchIsConstantValue(e NavigableExpr) bool {
|
||||
if e.Kind() == LiteralKind {
|
||||
return true
|
||||
}
|
||||
if e.Kind() == StructKind || e.Kind() == MapKind || e.Kind() == ListKind {
|
||||
for _, child := range e.Children() {
|
||||
if !matchIsConstantValue(child) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NavigableExpr represents the base navigable expression value.
|
||||
//
|
||||
// Depending on the `Kind()` value, the NavigableExpr may be converted to a concrete expression types
|
||||
// as indicated by the `As<Kind>` methods.
|
||||
//
|
||||
// NavigableExpr values and their concrete expression types should be nil-safe. Conversion of an expr
|
||||
// to the wrong kind should produce a nil value.
|
||||
type NavigableExpr interface {
|
||||
// ID of the expression as it appears in the AST
|
||||
ID() int64
|
||||
|
||||
// Kind of the expression node. See ExprKind for the valid enum values.
|
||||
Kind() ExprKind
|
||||
|
||||
// Type of the expression node.
|
||||
Type() *types.Type
|
||||
|
||||
// Parent returns the parent expression node, if one exists.
|
||||
Parent() (NavigableExpr, bool)
|
||||
|
||||
// Children returns a list of child expression nodes.
|
||||
Children() []NavigableExpr
|
||||
|
||||
// ToExpr adapts this NavigableExpr to a protobuf representation.
|
||||
ToExpr() *exprpb.Expr
|
||||
|
||||
// AsCall adapts the expr into a NavigableCallExpr
|
||||
//
|
||||
// The Kind() must be equal to a CallKind for the conversion to be well-defined.
|
||||
AsCall() NavigableCallExpr
|
||||
|
||||
// AsComprehension adapts the expr into a NavigableComprehensionExpr.
|
||||
//
|
||||
// The Kind() must be equal to a ComprehensionKind for the conversion to be well-defined.
|
||||
AsComprehension() NavigableComprehensionExpr
|
||||
|
||||
// AsIdent adapts the expr into an identifier string.
|
||||
//
|
||||
// The Kind() must be equal to an IdentKind for the conversion to be well-defined.
|
||||
AsIdent() string
|
||||
|
||||
// AsLiteral adapts the expr into a constant ref.Val.
|
||||
//
|
||||
// The Kind() must be equal to a LiteralKind for the conversion to be well-defined.
|
||||
AsLiteral() ref.Val
|
||||
|
||||
// AsList adapts the expr into a NavigableListExpr.
|
||||
//
|
||||
// The Kind() must be equal to a ListKind for the conversion to be well-defined.
|
||||
AsList() NavigableListExpr
|
||||
|
||||
// AsMap adapts the expr into a NavigableMapExpr.
|
||||
//
|
||||
// The Kind() must be equal to a MapKind for the conversion to be well-defined.
|
||||
AsMap() NavigableMapExpr
|
||||
|
||||
// AsSelect adapts the expr into a NavigableSelectExpr.
|
||||
//
|
||||
// The Kind() must be equal to a SelectKind for the conversion to be well-defined.
|
||||
AsSelect() NavigableSelectExpr
|
||||
|
||||
// AsStruct adapts the expr into a NavigableStructExpr.
|
||||
//
|
||||
// The Kind() must be equal to a StructKind for the conversion to be well-defined.
|
||||
AsStruct() NavigableStructExpr
|
||||
|
||||
// marker interface method
|
||||
isNavigable()
|
||||
}
|
||||
|
||||
// NavigableCallExpr defines an interface for inspecting a function call and its arugments.
|
||||
type NavigableCallExpr interface {
|
||||
// FunctionName returns the name of the function.
|
||||
FunctionName() string
|
||||
|
||||
// Target returns the target of the expression if one is present.
|
||||
Target() NavigableExpr
|
||||
|
||||
// Args returns the list of call arguments, excluding the target.
|
||||
Args() []NavigableExpr
|
||||
|
||||
// ReturnType returns the result type of the call.
|
||||
ReturnType() *types.Type
|
||||
|
||||
// marker interface method
|
||||
isNavigable()
|
||||
}
|
||||
|
||||
// NavigableListExpr defines an interface for inspecting a list literal expression.
|
||||
type NavigableListExpr interface {
|
||||
// Elements returns the list elements as navigable expressions.
|
||||
Elements() []NavigableExpr
|
||||
|
||||
// OptionalIndicies returns the list of optional indices in the list literal.
|
||||
OptionalIndices() []int32
|
||||
|
||||
// Size returns the number of elements in the list.
|
||||
Size() int
|
||||
|
||||
// marker interface method
|
||||
isNavigable()
|
||||
}
|
||||
|
||||
// NavigableSelectExpr defines an interface for inspecting a select expression.
|
||||
type NavigableSelectExpr interface {
|
||||
// Operand returns the selection operand expression.
|
||||
Operand() NavigableExpr
|
||||
|
||||
// FieldName returns the field name being selected from the operand.
|
||||
FieldName() string
|
||||
|
||||
// IsTestOnly indicates whether the select expression is a presence test generated by a macro.
|
||||
IsTestOnly() bool
|
||||
|
||||
// marker interface method
|
||||
isNavigable()
|
||||
}
|
||||
|
||||
// NavigableMapExpr defines an interface for inspecting a map expression.
|
||||
type NavigableMapExpr interface {
|
||||
// Entries returns the map key value pairs as NavigableEntry values.
|
||||
Entries() []NavigableEntry
|
||||
|
||||
// Size returns the number of entries in the map.
|
||||
Size() int
|
||||
|
||||
// marker interface method
|
||||
isNavigable()
|
||||
}
|
||||
|
||||
// NavigableEntry defines an interface for inspecting a map entry.
|
||||
type NavigableEntry interface {
|
||||
// Key returns the map entry key expression.
|
||||
Key() NavigableExpr
|
||||
|
||||
// Value returns the map entry value expression.
|
||||
Value() NavigableExpr
|
||||
|
||||
// IsOptional returns whether the entry is optional.
|
||||
IsOptional() bool
|
||||
|
||||
// marker interface method
|
||||
isNavigable()
|
||||
}
|
||||
|
||||
// NavigableStructExpr defines an interfaces for inspecting a struct and its field initializers.
|
||||
type NavigableStructExpr interface {
|
||||
// TypeName returns the struct type name.
|
||||
TypeName() string
|
||||
|
||||
// Fields returns the set of field initializers in the struct expression as NavigableField values.
|
||||
Fields() []NavigableField
|
||||
|
||||
// marker interface method
|
||||
isNavigable()
|
||||
}
|
||||
|
||||
// NavigableField defines an interface for inspecting a struct field initialization.
|
||||
type NavigableField interface {
|
||||
// FieldName returns the name of the field.
|
||||
FieldName() string
|
||||
|
||||
// Value returns the field initialization expression.
|
||||
Value() NavigableExpr
|
||||
|
||||
// IsOptional returns whether the field is optional.
|
||||
IsOptional() bool
|
||||
|
||||
// marker interface method
|
||||
isNavigable()
|
||||
}
|
||||
|
||||
// NavigableComprehensionExpr defines an interface for inspecting a comprehension expression.
|
||||
type NavigableComprehensionExpr interface {
|
||||
// IterRange returns the iteration range expression.
|
||||
IterRange() NavigableExpr
|
||||
|
||||
// IterVar returns the iteration variable name.
|
||||
IterVar() string
|
||||
|
||||
// AccuVar returns the accumulation variable name.
|
||||
AccuVar() string
|
||||
|
||||
// AccuInit returns the accumulation variable initialization expression.
|
||||
AccuInit() NavigableExpr
|
||||
|
||||
// LoopCondition returns the loop condition expression.
|
||||
LoopCondition() NavigableExpr
|
||||
|
||||
// LoopStep returns the loop step expression.
|
||||
LoopStep() NavigableExpr
|
||||
|
||||
// Result returns the comprehension result expression.
|
||||
Result() NavigableExpr
|
||||
|
||||
// marker interface method
|
||||
isNavigable()
|
||||
}
|
||||
|
||||
func newNavigableExpr(parent NavigableExpr, expr *exprpb.Expr, typeMap map[int64]*types.Type) NavigableExpr {
|
||||
kind, factory := kindOf(expr)
|
||||
nav := &navigableExprImpl{
|
||||
parent: parent,
|
||||
kind: kind,
|
||||
expr: expr,
|
||||
typeMap: typeMap,
|
||||
createChildren: factory,
|
||||
}
|
||||
return nav
|
||||
}
|
||||
|
||||
type navigableExprImpl struct {
|
||||
parent NavigableExpr
|
||||
kind ExprKind
|
||||
expr *exprpb.Expr
|
||||
typeMap map[int64]*types.Type
|
||||
createChildren childFactory
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) ID() int64 {
|
||||
return nav.ToExpr().GetId()
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) Kind() ExprKind {
|
||||
return nav.kind
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) Type() *types.Type {
|
||||
if t, found := nav.typeMap[nav.ID()]; found {
|
||||
return t
|
||||
}
|
||||
return types.DynType
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) Parent() (NavigableExpr, bool) {
|
||||
if nav.parent != nil {
|
||||
return nav.parent, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) Children() []NavigableExpr {
|
||||
return nav.createChildren(nav)
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) ToExpr() *exprpb.Expr {
|
||||
return nav.expr
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) AsCall() NavigableCallExpr {
|
||||
return navigableCallImpl{navigableExprImpl: nav}
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) AsComprehension() NavigableComprehensionExpr {
|
||||
return navigableComprehensionImpl{navigableExprImpl: nav}
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) AsIdent() string {
|
||||
return nav.ToExpr().GetIdentExpr().GetName()
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) AsLiteral() ref.Val {
|
||||
if nav.Kind() != LiteralKind {
|
||||
return nil
|
||||
}
|
||||
val, err := ConstantToVal(nav.ToExpr().GetConstExpr())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) AsList() NavigableListExpr {
|
||||
return navigableListImpl{navigableExprImpl: nav}
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) AsMap() NavigableMapExpr {
|
||||
return navigableMapImpl{navigableExprImpl: nav}
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) AsSelect() NavigableSelectExpr {
|
||||
return navigableSelectImpl{navigableExprImpl: nav}
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) AsStruct() NavigableStructExpr {
|
||||
return navigableStructImpl{navigableExprImpl: nav}
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) createChild(e *exprpb.Expr) NavigableExpr {
|
||||
return newNavigableExpr(nav, e, nav.typeMap)
|
||||
}
|
||||
|
||||
func (nav *navigableExprImpl) isNavigable() {}
|
||||
|
||||
type navigableCallImpl struct {
|
||||
*navigableExprImpl
|
||||
}
|
||||
|
||||
func (call navigableCallImpl) FunctionName() string {
|
||||
return call.ToExpr().GetCallExpr().GetFunction()
|
||||
}
|
||||
|
||||
func (call navigableCallImpl) Target() NavigableExpr {
|
||||
t := call.ToExpr().GetCallExpr().GetTarget()
|
||||
if t != nil {
|
||||
return call.createChild(t)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (call navigableCallImpl) Args() []NavigableExpr {
|
||||
args := call.ToExpr().GetCallExpr().GetArgs()
|
||||
navArgs := make([]NavigableExpr, len(args))
|
||||
for i, a := range args {
|
||||
navArgs[i] = call.createChild(a)
|
||||
}
|
||||
return navArgs
|
||||
}
|
||||
|
||||
func (call navigableCallImpl) ReturnType() *types.Type {
|
||||
return call.Type()
|
||||
}
|
||||
|
||||
type navigableComprehensionImpl struct {
|
||||
*navigableExprImpl
|
||||
}
|
||||
|
||||
func (comp navigableComprehensionImpl) IterRange() NavigableExpr {
|
||||
return comp.createChild(comp.ToExpr().GetComprehensionExpr().GetIterRange())
|
||||
}
|
||||
|
||||
func (comp navigableComprehensionImpl) IterVar() string {
|
||||
return comp.ToExpr().GetComprehensionExpr().GetIterVar()
|
||||
}
|
||||
|
||||
func (comp navigableComprehensionImpl) AccuVar() string {
|
||||
return comp.ToExpr().GetComprehensionExpr().GetAccuVar()
|
||||
}
|
||||
|
||||
func (comp navigableComprehensionImpl) AccuInit() NavigableExpr {
|
||||
return comp.createChild(comp.ToExpr().GetComprehensionExpr().GetAccuInit())
|
||||
}
|
||||
|
||||
func (comp navigableComprehensionImpl) LoopCondition() NavigableExpr {
|
||||
return comp.createChild(comp.ToExpr().GetComprehensionExpr().GetLoopCondition())
|
||||
}
|
||||
|
||||
func (comp navigableComprehensionImpl) LoopStep() NavigableExpr {
|
||||
return comp.createChild(comp.ToExpr().GetComprehensionExpr().GetLoopStep())
|
||||
}
|
||||
|
||||
func (comp navigableComprehensionImpl) Result() NavigableExpr {
|
||||
return comp.createChild(comp.ToExpr().GetComprehensionExpr().GetResult())
|
||||
}
|
||||
|
||||
type navigableListImpl struct {
|
||||
*navigableExprImpl
|
||||
}
|
||||
|
||||
func (l navigableListImpl) Elements() []NavigableExpr {
|
||||
return l.Children()
|
||||
}
|
||||
|
||||
func (l navigableListImpl) OptionalIndices() []int32 {
|
||||
return l.ToExpr().GetListExpr().GetOptionalIndices()
|
||||
}
|
||||
|
||||
func (l navigableListImpl) Size() int {
|
||||
return len(l.ToExpr().GetListExpr().GetElements())
|
||||
}
|
||||
|
||||
type navigableMapImpl struct {
|
||||
*navigableExprImpl
|
||||
}
|
||||
|
||||
func (m navigableMapImpl) Entries() []NavigableEntry {
|
||||
mapExpr := m.ToExpr().GetStructExpr()
|
||||
entries := make([]NavigableEntry, len(mapExpr.GetEntries()))
|
||||
for i, e := range mapExpr.GetEntries() {
|
||||
entries[i] = navigableEntryImpl{
|
||||
key: m.createChild(e.GetMapKey()),
|
||||
val: m.createChild(e.GetValue()),
|
||||
isOpt: e.GetOptionalEntry(),
|
||||
}
|
||||
}
|
||||
return entries
|
||||
}
|
||||
|
||||
func (m navigableMapImpl) Size() int {
|
||||
return len(m.ToExpr().GetStructExpr().GetEntries())
|
||||
}
|
||||
|
||||
type navigableEntryImpl struct {
|
||||
key NavigableExpr
|
||||
val NavigableExpr
|
||||
isOpt bool
|
||||
}
|
||||
|
||||
func (e navigableEntryImpl) Key() NavigableExpr {
|
||||
return e.key
|
||||
}
|
||||
|
||||
func (e navigableEntryImpl) Value() NavigableExpr {
|
||||
return e.val
|
||||
}
|
||||
|
||||
func (e navigableEntryImpl) IsOptional() bool {
|
||||
return e.isOpt
|
||||
}
|
||||
|
||||
func (e navigableEntryImpl) isNavigable() {}
|
||||
|
||||
type navigableSelectImpl struct {
|
||||
*navigableExprImpl
|
||||
}
|
||||
|
||||
func (sel navigableSelectImpl) FieldName() string {
|
||||
return sel.ToExpr().GetSelectExpr().GetField()
|
||||
}
|
||||
|
||||
func (sel navigableSelectImpl) IsTestOnly() bool {
|
||||
return sel.ToExpr().GetSelectExpr().GetTestOnly()
|
||||
}
|
||||
|
||||
func (sel navigableSelectImpl) Operand() NavigableExpr {
|
||||
return sel.createChild(sel.ToExpr().GetSelectExpr().GetOperand())
|
||||
}
|
||||
|
||||
type navigableStructImpl struct {
|
||||
*navigableExprImpl
|
||||
}
|
||||
|
||||
func (s navigableStructImpl) TypeName() string {
|
||||
return s.ToExpr().GetStructExpr().GetMessageName()
|
||||
}
|
||||
|
||||
func (s navigableStructImpl) Fields() []NavigableField {
|
||||
fieldInits := s.ToExpr().GetStructExpr().GetEntries()
|
||||
fields := make([]NavigableField, len(fieldInits))
|
||||
for i, f := range fieldInits {
|
||||
fields[i] = navigableFieldImpl{
|
||||
name: f.GetFieldKey(),
|
||||
val: s.createChild(f.GetValue()),
|
||||
isOpt: f.GetOptionalEntry(),
|
||||
}
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
type navigableFieldImpl struct {
|
||||
name string
|
||||
val NavigableExpr
|
||||
isOpt bool
|
||||
}
|
||||
|
||||
func (f navigableFieldImpl) FieldName() string {
|
||||
return f.name
|
||||
}
|
||||
|
||||
func (f navigableFieldImpl) Value() NavigableExpr {
|
||||
return f.val
|
||||
}
|
||||
|
||||
func (f navigableFieldImpl) IsOptional() bool {
|
||||
return f.isOpt
|
||||
}
|
||||
|
||||
func (f navigableFieldImpl) isNavigable() {}
|
||||
|
||||
func kindOf(expr *exprpb.Expr) (ExprKind, childFactory) {
|
||||
switch expr.GetExprKind().(type) {
|
||||
case *exprpb.Expr_ConstExpr:
|
||||
return LiteralKind, noopFactory
|
||||
case *exprpb.Expr_IdentExpr:
|
||||
return IdentKind, noopFactory
|
||||
case *exprpb.Expr_SelectExpr:
|
||||
return SelectKind, selectFactory
|
||||
case *exprpb.Expr_CallExpr:
|
||||
return CallKind, callArgFactory
|
||||
case *exprpb.Expr_ListExpr:
|
||||
return ListKind, listElemFactory
|
||||
case *exprpb.Expr_StructExpr:
|
||||
if expr.GetStructExpr().GetMessageName() != "" {
|
||||
return StructKind, structEntryFactory
|
||||
}
|
||||
return MapKind, mapEntryFactory
|
||||
case *exprpb.Expr_ComprehensionExpr:
|
||||
return ComprehensionKind, comprehensionFactory
|
||||
default:
|
||||
return UnspecifiedKind, noopFactory
|
||||
}
|
||||
}
|
||||
|
||||
type childFactory func(*navigableExprImpl) []NavigableExpr
|
||||
|
||||
func noopFactory(*navigableExprImpl) []NavigableExpr {
|
||||
return nil
|
||||
}
|
||||
|
||||
func selectFactory(nav *navigableExprImpl) []NavigableExpr {
|
||||
return []NavigableExpr{
|
||||
nav.createChild(nav.ToExpr().GetSelectExpr().GetOperand()),
|
||||
}
|
||||
}
|
||||
|
||||
func callArgFactory(nav *navigableExprImpl) []NavigableExpr {
|
||||
call := nav.ToExpr().GetCallExpr()
|
||||
argCount := len(call.GetArgs())
|
||||
if call.GetTarget() != nil {
|
||||
argCount++
|
||||
}
|
||||
navExprs := make([]NavigableExpr, argCount)
|
||||
i := 0
|
||||
if call.GetTarget() != nil {
|
||||
navExprs[i] = nav.createChild(call.GetTarget())
|
||||
i++
|
||||
}
|
||||
for _, arg := range call.GetArgs() {
|
||||
navExprs[i] = nav.createChild(arg)
|
||||
i++
|
||||
}
|
||||
return navExprs
|
||||
}
|
||||
|
||||
func listElemFactory(nav *navigableExprImpl) []NavigableExpr {
|
||||
l := nav.ToExpr().GetListExpr()
|
||||
navExprs := make([]NavigableExpr, len(l.GetElements()))
|
||||
for i, e := range l.GetElements() {
|
||||
navExprs[i] = nav.createChild(e)
|
||||
}
|
||||
return navExprs
|
||||
}
|
||||
|
||||
func structEntryFactory(nav *navigableExprImpl) []NavigableExpr {
|
||||
s := nav.ToExpr().GetStructExpr()
|
||||
entries := make([]NavigableExpr, len(s.GetEntries()))
|
||||
for i, e := range s.GetEntries() {
|
||||
|
||||
entries[i] = nav.createChild(e.GetValue())
|
||||
}
|
||||
return entries
|
||||
}
|
||||
|
||||
func mapEntryFactory(nav *navigableExprImpl) []NavigableExpr {
|
||||
s := nav.ToExpr().GetStructExpr()
|
||||
entries := make([]NavigableExpr, len(s.GetEntries())*2)
|
||||
j := 0
|
||||
for _, e := range s.GetEntries() {
|
||||
entries[j] = nav.createChild(e.GetMapKey())
|
||||
entries[j+1] = nav.createChild(e.GetValue())
|
||||
j += 2
|
||||
}
|
||||
return entries
|
||||
}
|
||||
|
||||
func comprehensionFactory(nav *navigableExprImpl) []NavigableExpr {
|
||||
compre := nav.ToExpr().GetComprehensionExpr()
|
||||
return []NavigableExpr{
|
||||
nav.createChild(compre.GetIterRange()),
|
||||
nav.createChild(compre.GetAccuInit()),
|
||||
nav.createChild(compre.GetLoopCondition()),
|
||||
nav.createChild(compre.GetLoopStep()),
|
||||
nav.createChild(compre.GetResult()),
|
||||
}
|
||||
}
|
39
vendor/github.com/google/cel-go/common/decls/BUILD.bazel
generated
vendored
Normal file
39
vendor/github.com/google/cel-go/common/decls/BUILD.bazel
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
package(
|
||||
default_visibility = ["//visibility:public"],
|
||||
licenses = ["notice"], # Apache 2.0
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"decls.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/decls",
|
||||
deps = [
|
||||
"//checker/decls:go_default_library",
|
||||
"//common/functions:go_default_library",
|
||||
"//common/types:go_default_library",
|
||||
"//common/types/ref:go_default_library",
|
||||
"//common/types/traits:go_default_library",
|
||||
"@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"decls_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//checker/decls:go_default_library",
|
||||
"//common/overloads:go_default_library",
|
||||
"//common/types:go_default_library",
|
||||
"//common/types/ref:go_default_library",
|
||||
"//common/types/traits:go_default_library",
|
||||
"@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
844
vendor/github.com/google/cel-go/common/decls/decls.go
generated
vendored
Normal file
844
vendor/github.com/google/cel-go/common/decls/decls.go
generated
vendored
Normal file
@ -0,0 +1,844 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package decls contains function and variable declaration structs and helper methods.
|
||||
package decls
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
chkdecls "github.com/google/cel-go/checker/decls"
|
||||
"github.com/google/cel-go/common/functions"
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
)
|
||||
|
||||
// NewFunction creates a new function declaration with a set of function options to configure overloads
|
||||
// and function definitions (implementations).
|
||||
//
|
||||
// Functions are checked for name collisions and singleton redefinition.
|
||||
func NewFunction(name string, opts ...FunctionOpt) (*FunctionDecl, error) {
|
||||
fn := &FunctionDecl{
|
||||
name: name,
|
||||
overloads: map[string]*OverloadDecl{},
|
||||
overloadOrdinals: []string{},
|
||||
}
|
||||
var err error
|
||||
for _, opt := range opts {
|
||||
fn, err = opt(fn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(fn.overloads) == 0 {
|
||||
return nil, fmt.Errorf("function %s must have at least one overload", name)
|
||||
}
|
||||
return fn, nil
|
||||
}
|
||||
|
||||
// FunctionDecl defines a function name, overload set, and optionally a singleton definition for all
|
||||
// overload instances.
|
||||
type FunctionDecl struct {
|
||||
name string
|
||||
|
||||
// overloads associated with the function name.
|
||||
overloads map[string]*OverloadDecl
|
||||
|
||||
// singleton implementation of the function for all overloads.
|
||||
//
|
||||
// If this option is set, an error will occur if any overloads specify a per-overload implementation
|
||||
// or if another function with the same name attempts to redefine the singleton.
|
||||
singleton *functions.Overload
|
||||
|
||||
// disableTypeGuards is a performance optimization to disable detailed runtime type checks which could
|
||||
// add overhead on common operations. Setting this option true leaves error checks and argument checks
|
||||
// intact.
|
||||
disableTypeGuards bool
|
||||
|
||||
// state indicates that the binding should be provided as a declaration, as a runtime binding, or both.
|
||||
state declarationState
|
||||
|
||||
// overloadOrdinals indicates the order in which the overload was declared.
|
||||
overloadOrdinals []string
|
||||
}
|
||||
|
||||
type declarationState int
|
||||
|
||||
const (
|
||||
declarationStateUnset declarationState = iota
|
||||
declarationDisabled
|
||||
declarationEnabled
|
||||
)
|
||||
|
||||
// Name returns the function name in human-readable terms, e.g. 'contains' of 'math.least'
|
||||
func (f *FunctionDecl) Name() string {
|
||||
if f == nil {
|
||||
return ""
|
||||
}
|
||||
return f.name
|
||||
}
|
||||
|
||||
// IsDeclarationDisabled indicates that the function implementation should be added to the dispatcher, but the
|
||||
// declaration should not be exposed for use in expressions.
|
||||
func (f *FunctionDecl) IsDeclarationDisabled() bool {
|
||||
return f.state == declarationDisabled
|
||||
}
|
||||
|
||||
// Merge combines an existing function declaration with another.
|
||||
//
|
||||
// If a function is extended, by say adding new overloads to an existing function, then it is merged with the
|
||||
// prior definition of the function at which point its overloads must not collide with pre-existing overloads
|
||||
// and its bindings (singleton, or per-overload) must not conflict with previous definitions either.
|
||||
func (f *FunctionDecl) Merge(other *FunctionDecl) (*FunctionDecl, error) {
|
||||
if f == other {
|
||||
return f, nil
|
||||
}
|
||||
if f.Name() != other.Name() {
|
||||
return nil, fmt.Errorf("cannot merge unrelated functions. %s and %s", f.Name(), other.Name())
|
||||
}
|
||||
merged := &FunctionDecl{
|
||||
name: f.Name(),
|
||||
overloads: make(map[string]*OverloadDecl, len(f.overloads)),
|
||||
singleton: f.singleton,
|
||||
overloadOrdinals: make([]string, len(f.overloads)),
|
||||
// if one function is expecting type-guards and the other is not, then they
|
||||
// must not be disabled.
|
||||
disableTypeGuards: f.disableTypeGuards && other.disableTypeGuards,
|
||||
// default to the current functions declaration state.
|
||||
state: f.state,
|
||||
}
|
||||
// If the other state indicates that the declaration should be explicitly enabled or
|
||||
// disabled, then update the merged state with the most recent value.
|
||||
if other.state != declarationStateUnset {
|
||||
merged.state = other.state
|
||||
}
|
||||
// baseline copy of the overloads and their ordinals
|
||||
copy(merged.overloadOrdinals, f.overloadOrdinals)
|
||||
for oID, o := range f.overloads {
|
||||
merged.overloads[oID] = o
|
||||
}
|
||||
// overloads and their ordinals are added from the left
|
||||
for _, oID := range other.overloadOrdinals {
|
||||
o := other.overloads[oID]
|
||||
err := merged.AddOverload(o)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("function declaration merge failed: %v", err)
|
||||
}
|
||||
}
|
||||
if other.singleton != nil {
|
||||
if merged.singleton != nil && merged.singleton != other.singleton {
|
||||
return nil, fmt.Errorf("function already has a singleton binding: %s", f.Name())
|
||||
}
|
||||
merged.singleton = other.singleton
|
||||
}
|
||||
return merged, nil
|
||||
}
|
||||
|
||||
// AddOverload ensures that the new overload does not collide with an existing overload signature;
|
||||
// however, if the function signatures are identical, the implementation may be rewritten as its
|
||||
// difficult to compare functions by object identity.
|
||||
func (f *FunctionDecl) AddOverload(overload *OverloadDecl) error {
|
||||
if f == nil {
|
||||
return fmt.Errorf("nil function cannot add overload: %s", overload.ID())
|
||||
}
|
||||
for oID, o := range f.overloads {
|
||||
if oID != overload.ID() && o.SignatureOverlaps(overload) {
|
||||
return fmt.Errorf("overload signature collision in function %s: %s collides with %s", f.Name(), oID, overload.ID())
|
||||
}
|
||||
if oID == overload.ID() {
|
||||
if o.SignatureEquals(overload) && o.IsNonStrict() == overload.IsNonStrict() {
|
||||
// Allow redefinition of an overload implementation so long as the signatures match.
|
||||
f.overloads[oID] = overload
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("overload redefinition in function. %s: %s has multiple definitions", f.Name(), oID)
|
||||
}
|
||||
}
|
||||
f.overloadOrdinals = append(f.overloadOrdinals, overload.ID())
|
||||
f.overloads[overload.ID()] = overload
|
||||
return nil
|
||||
}
|
||||
|
||||
// OverloadDecls returns the overload declarations in the order in which they were declared.
|
||||
func (f *FunctionDecl) OverloadDecls() []*OverloadDecl {
|
||||
if f == nil {
|
||||
return []*OverloadDecl{}
|
||||
}
|
||||
overloads := make([]*OverloadDecl, 0, len(f.overloads))
|
||||
for _, oID := range f.overloadOrdinals {
|
||||
overloads = append(overloads, f.overloads[oID])
|
||||
}
|
||||
return overloads
|
||||
}
|
||||
|
||||
// Bindings produces a set of function bindings, if any are defined.
|
||||
func (f *FunctionDecl) Bindings() ([]*functions.Overload, error) {
|
||||
if f == nil {
|
||||
return []*functions.Overload{}, nil
|
||||
}
|
||||
overloads := []*functions.Overload{}
|
||||
nonStrict := false
|
||||
for _, oID := range f.overloadOrdinals {
|
||||
o := f.overloads[oID]
|
||||
if o.hasBinding() {
|
||||
overload := &functions.Overload{
|
||||
Operator: o.ID(),
|
||||
Unary: o.guardedUnaryOp(f.Name(), f.disableTypeGuards),
|
||||
Binary: o.guardedBinaryOp(f.Name(), f.disableTypeGuards),
|
||||
Function: o.guardedFunctionOp(f.Name(), f.disableTypeGuards),
|
||||
OperandTrait: o.OperandTrait(),
|
||||
NonStrict: o.IsNonStrict(),
|
||||
}
|
||||
overloads = append(overloads, overload)
|
||||
nonStrict = nonStrict || o.IsNonStrict()
|
||||
}
|
||||
}
|
||||
if f.singleton != nil {
|
||||
if len(overloads) != 0 {
|
||||
return nil, fmt.Errorf("singleton function incompatible with specialized overloads: %s", f.Name())
|
||||
}
|
||||
overloads = []*functions.Overload{
|
||||
{
|
||||
Operator: f.Name(),
|
||||
Unary: f.singleton.Unary,
|
||||
Binary: f.singleton.Binary,
|
||||
Function: f.singleton.Function,
|
||||
OperandTrait: f.singleton.OperandTrait,
|
||||
},
|
||||
}
|
||||
// fall-through to return single overload case.
|
||||
}
|
||||
if len(overloads) == 0 {
|
||||
return overloads, nil
|
||||
}
|
||||
// Single overload. Replicate an entry for it using the function name as well.
|
||||
if len(overloads) == 1 {
|
||||
if overloads[0].Operator == f.Name() {
|
||||
return overloads, nil
|
||||
}
|
||||
return append(overloads, &functions.Overload{
|
||||
Operator: f.Name(),
|
||||
Unary: overloads[0].Unary,
|
||||
Binary: overloads[0].Binary,
|
||||
Function: overloads[0].Function,
|
||||
NonStrict: overloads[0].NonStrict,
|
||||
OperandTrait: overloads[0].OperandTrait,
|
||||
}), nil
|
||||
}
|
||||
// All of the defined overloads are wrapped into a top-level function which
|
||||
// performs dynamic dispatch to the proper overload based on the argument types.
|
||||
bindings := append([]*functions.Overload{}, overloads...)
|
||||
funcDispatch := func(args ...ref.Val) ref.Val {
|
||||
for _, oID := range f.overloadOrdinals {
|
||||
o := f.overloads[oID]
|
||||
// During dynamic dispatch over multiple functions, signature agreement checks
|
||||
// are preserved in order to assist with the function resolution step.
|
||||
switch len(args) {
|
||||
case 1:
|
||||
if o.unaryOp != nil && o.matchesRuntimeSignature( /* disableTypeGuards=*/ false, args...) {
|
||||
return o.unaryOp(args[0])
|
||||
}
|
||||
case 2:
|
||||
if o.binaryOp != nil && o.matchesRuntimeSignature( /* disableTypeGuards=*/ false, args...) {
|
||||
return o.binaryOp(args[0], args[1])
|
||||
}
|
||||
}
|
||||
if o.functionOp != nil && o.matchesRuntimeSignature( /* disableTypeGuards=*/ false, args...) {
|
||||
return o.functionOp(args...)
|
||||
}
|
||||
// eventually this will fall through to the noSuchOverload below.
|
||||
}
|
||||
return MaybeNoSuchOverload(f.Name(), args...)
|
||||
}
|
||||
function := &functions.Overload{
|
||||
Operator: f.Name(),
|
||||
Function: funcDispatch,
|
||||
NonStrict: nonStrict,
|
||||
}
|
||||
return append(bindings, function), nil
|
||||
}
|
||||
|
||||
// MaybeNoSuchOverload determines whether to propagate an error if one is provided as an argument, or
|
||||
// to return an unknown set, or to produce a new error for a missing function signature.
|
||||
func MaybeNoSuchOverload(funcName string, args ...ref.Val) ref.Val {
|
||||
argTypes := make([]string, len(args))
|
||||
var unk *types.Unknown = nil
|
||||
for i, arg := range args {
|
||||
if types.IsError(arg) {
|
||||
return arg
|
||||
}
|
||||
if types.IsUnknown(arg) {
|
||||
unk = types.MergeUnknowns(arg.(*types.Unknown), unk)
|
||||
}
|
||||
argTypes[i] = arg.Type().TypeName()
|
||||
}
|
||||
if unk != nil {
|
||||
return unk
|
||||
}
|
||||
signature := strings.Join(argTypes, ", ")
|
||||
return types.NewErr("no such overload: %s(%s)", funcName, signature)
|
||||
}
|
||||
|
||||
// FunctionOpt defines a functional option for mutating a function declaration.
|
||||
type FunctionOpt func(*FunctionDecl) (*FunctionDecl, error)
|
||||
|
||||
// DisableTypeGuards disables automatically generated function invocation guards on direct overload calls.
|
||||
// Type guards remain on during dynamic dispatch for parsed-only expressions.
|
||||
func DisableTypeGuards(value bool) FunctionOpt {
|
||||
return func(fn *FunctionDecl) (*FunctionDecl, error) {
|
||||
fn.disableTypeGuards = value
|
||||
return fn, nil
|
||||
}
|
||||
}
|
||||
|
||||
// DisableDeclaration indicates that the function declaration should be disabled, but the runtime function
|
||||
// binding should be provided. Marking a function as runtime-only is a safe way to manage deprecations
|
||||
// of function declarations while still preserving the runtime behavior for previously compiled expressions.
|
||||
func DisableDeclaration(value bool) FunctionOpt {
|
||||
return func(fn *FunctionDecl) (*FunctionDecl, error) {
|
||||
if value {
|
||||
fn.state = declarationDisabled
|
||||
} else {
|
||||
fn.state = declarationEnabled
|
||||
}
|
||||
return fn, nil
|
||||
}
|
||||
}
|
||||
|
||||
// SingletonUnaryBinding creates a singleton function definition to be used for all function overloads.
|
||||
//
|
||||
// Note, this approach works well if operand is expected to have a specific trait which it implements,
|
||||
// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings.
|
||||
func SingletonUnaryBinding(fn functions.UnaryOp, traits ...int) FunctionOpt {
|
||||
trait := 0
|
||||
for _, t := range traits {
|
||||
trait = trait | t
|
||||
}
|
||||
return func(f *FunctionDecl) (*FunctionDecl, error) {
|
||||
if f.singleton != nil {
|
||||
return nil, fmt.Errorf("function already has a singleton binding: %s", f.Name())
|
||||
}
|
||||
f.singleton = &functions.Overload{
|
||||
Operator: f.Name(),
|
||||
Unary: fn,
|
||||
OperandTrait: trait,
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
}
|
||||
|
||||
// SingletonBinaryBinding creates a singleton function definition to be used with all function overloads.
|
||||
//
|
||||
// Note, this approach works well if operand is expected to have a specific trait which it implements,
|
||||
// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings.
|
||||
func SingletonBinaryBinding(fn functions.BinaryOp, traits ...int) FunctionOpt {
|
||||
trait := 0
|
||||
for _, t := range traits {
|
||||
trait = trait | t
|
||||
}
|
||||
return func(f *FunctionDecl) (*FunctionDecl, error) {
|
||||
if f.singleton != nil {
|
||||
return nil, fmt.Errorf("function already has a singleton binding: %s", f.Name())
|
||||
}
|
||||
f.singleton = &functions.Overload{
|
||||
Operator: f.Name(),
|
||||
Binary: fn,
|
||||
OperandTrait: trait,
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
}
|
||||
|
||||
// SingletonFunctionBinding creates a singleton function definition to be used with all function overloads.
|
||||
//
|
||||
// Note, this approach works well if operand is expected to have a specific trait which it implements,
|
||||
// e.g. traits.ContainerType. Otherwise, prefer per-overload function bindings.
|
||||
func SingletonFunctionBinding(fn functions.FunctionOp, traits ...int) FunctionOpt {
|
||||
trait := 0
|
||||
for _, t := range traits {
|
||||
trait = trait | t
|
||||
}
|
||||
return func(f *FunctionDecl) (*FunctionDecl, error) {
|
||||
if f.singleton != nil {
|
||||
return nil, fmt.Errorf("function already has a singleton binding: %s", f.Name())
|
||||
}
|
||||
f.singleton = &functions.Overload{
|
||||
Operator: f.Name(),
|
||||
Function: fn,
|
||||
OperandTrait: trait,
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Overload defines a new global overload with an overload id, argument types, and result type. Through the
|
||||
// use of OverloadOpt options, the overload may also be configured with a binding, an operand trait, and to
|
||||
// be non-strict.
|
||||
//
|
||||
// Note: function bindings should be commonly configured with Overload instances whereas operand traits and
|
||||
// strict-ness should be rare occurrences.
|
||||
func Overload(overloadID string,
|
||||
args []*types.Type, resultType *types.Type,
|
||||
opts ...OverloadOpt) FunctionOpt {
|
||||
return newOverload(overloadID, false, args, resultType, opts...)
|
||||
}
|
||||
|
||||
// MemberOverload defines a new receiver-style overload (or member function) with an overload id, argument types,
|
||||
// and result type. Through the use of OverloadOpt options, the overload may also be configured with a binding,
|
||||
// an operand trait, and to be non-strict.
|
||||
//
|
||||
// Note: function bindings should be commonly configured with Overload instances whereas operand traits and
|
||||
// strict-ness should be rare occurrences.
|
||||
func MemberOverload(overloadID string,
|
||||
args []*types.Type, resultType *types.Type,
|
||||
opts ...OverloadOpt) FunctionOpt {
|
||||
return newOverload(overloadID, true, args, resultType, opts...)
|
||||
}
|
||||
|
||||
func newOverload(overloadID string,
|
||||
memberFunction bool, args []*types.Type, resultType *types.Type,
|
||||
opts ...OverloadOpt) FunctionOpt {
|
||||
return func(f *FunctionDecl) (*FunctionDecl, error) {
|
||||
overload, err := newOverloadInternal(overloadID, memberFunction, args, resultType, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = f.AddOverload(overload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
}
|
||||
|
||||
func newOverloadInternal(overloadID string,
|
||||
memberFunction bool, args []*types.Type, resultType *types.Type,
|
||||
opts ...OverloadOpt) (*OverloadDecl, error) {
|
||||
overload := &OverloadDecl{
|
||||
id: overloadID,
|
||||
argTypes: args,
|
||||
resultType: resultType,
|
||||
isMemberFunction: memberFunction,
|
||||
}
|
||||
var err error
|
||||
for _, opt := range opts {
|
||||
overload, err = opt(overload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return overload, nil
|
||||
}
|
||||
|
||||
// OverloadDecl contains the definition of a single overload id with a specific signature, and an optional
|
||||
// implementation.
|
||||
type OverloadDecl struct {
|
||||
id string
|
||||
argTypes []*types.Type
|
||||
resultType *types.Type
|
||||
isMemberFunction bool
|
||||
// nonStrict indicates that the function will accept error and unknown arguments as inputs.
|
||||
nonStrict bool
|
||||
// operandTrait indicates whether the member argument should have a specific type-trait.
|
||||
//
|
||||
// This is useful for creating overloads which operate on a type-interface rather than a concrete type.
|
||||
operandTrait int
|
||||
|
||||
// Function implementation options. Optional, but encouraged.
|
||||
// unaryOp is a function binding that takes a single argument.
|
||||
unaryOp functions.UnaryOp
|
||||
// binaryOp is a function binding that takes two arguments.
|
||||
binaryOp functions.BinaryOp
|
||||
// functionOp is a catch-all for zero-arity and three-plus arity functions.
|
||||
functionOp functions.FunctionOp
|
||||
}
|
||||
|
||||
// ID mirrors the overload signature and provides a unique id which may be referenced within the type-checker
|
||||
// and interpreter to optimize performance.
|
||||
//
|
||||
// The ID format is usually one of two styles:
|
||||
// global: <functionName>_<argType>_<argTypeN>
|
||||
// member: <memberType>_<functionName>_<argType>_<argTypeN>
|
||||
func (o *OverloadDecl) ID() string {
|
||||
if o == nil {
|
||||
return ""
|
||||
}
|
||||
return o.id
|
||||
}
|
||||
|
||||
// ArgTypes contains the set of argument types expected by the overload.
|
||||
//
|
||||
// For member functions ArgTypes[0] represents the member operand type.
|
||||
func (o *OverloadDecl) ArgTypes() []*types.Type {
|
||||
if o == nil {
|
||||
return emptyArgs
|
||||
}
|
||||
return o.argTypes
|
||||
}
|
||||
|
||||
// IsMemberFunction indicates whether the overload is a member function
|
||||
func (o *OverloadDecl) IsMemberFunction() bool {
|
||||
if o == nil {
|
||||
return false
|
||||
}
|
||||
return o.isMemberFunction
|
||||
}
|
||||
|
||||
// IsNonStrict returns whether the overload accepts errors and unknown values as arguments.
|
||||
func (o *OverloadDecl) IsNonStrict() bool {
|
||||
if o == nil {
|
||||
return false
|
||||
}
|
||||
return o.nonStrict
|
||||
}
|
||||
|
||||
// OperandTrait returns the trait mask of the first operand to the overload call, e.g.
|
||||
// `traits.Indexer`
|
||||
func (o *OverloadDecl) OperandTrait() int {
|
||||
if o == nil {
|
||||
return 0
|
||||
}
|
||||
return o.operandTrait
|
||||
}
|
||||
|
||||
// ResultType indicates the output type from calling the function.
|
||||
func (o *OverloadDecl) ResultType() *types.Type {
|
||||
if o == nil {
|
||||
// *types.Type is nil-safe
|
||||
return nil
|
||||
}
|
||||
return o.resultType
|
||||
}
|
||||
|
||||
// TypeParams returns the type parameter names associated with the overload.
|
||||
func (o *OverloadDecl) TypeParams() []string {
|
||||
typeParams := map[string]struct{}{}
|
||||
collectParamNames(typeParams, o.ResultType())
|
||||
for _, arg := range o.ArgTypes() {
|
||||
collectParamNames(typeParams, arg)
|
||||
}
|
||||
params := make([]string, 0, len(typeParams))
|
||||
for param := range typeParams {
|
||||
params = append(params, param)
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
// SignatureEquals determines whether the incoming overload declaration signature is equal to the current signature.
|
||||
//
|
||||
// Result type, operand trait, and strict-ness are not considered as part of signature equality.
|
||||
func (o *OverloadDecl) SignatureEquals(other *OverloadDecl) bool {
|
||||
if o == other {
|
||||
return true
|
||||
}
|
||||
if o.ID() != other.ID() || o.IsMemberFunction() != other.IsMemberFunction() || len(o.ArgTypes()) != len(other.ArgTypes()) {
|
||||
return false
|
||||
}
|
||||
for i, at := range o.ArgTypes() {
|
||||
oat := other.ArgTypes()[i]
|
||||
if !at.IsEquivalentType(oat) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return o.ResultType().IsEquivalentType(other.ResultType())
|
||||
}
|
||||
|
||||
// SignatureOverlaps indicates whether two functions have non-equal, but overloapping function signatures.
|
||||
//
|
||||
// For example, list(dyn) collides with list(string) since the 'dyn' type can contain a 'string' type.
|
||||
func (o *OverloadDecl) SignatureOverlaps(other *OverloadDecl) bool {
|
||||
if o.IsMemberFunction() != other.IsMemberFunction() || len(o.ArgTypes()) != len(other.ArgTypes()) {
|
||||
return false
|
||||
}
|
||||
argsOverlap := true
|
||||
for i, argType := range o.ArgTypes() {
|
||||
otherArgType := other.ArgTypes()[i]
|
||||
argsOverlap = argsOverlap &&
|
||||
(argType.IsAssignableType(otherArgType) ||
|
||||
otherArgType.IsAssignableType(argType))
|
||||
}
|
||||
return argsOverlap
|
||||
}
|
||||
|
||||
// hasBinding indicates whether the overload already has a definition.
|
||||
func (o *OverloadDecl) hasBinding() bool {
|
||||
return o != nil && (o.unaryOp != nil || o.binaryOp != nil || o.functionOp != nil)
|
||||
}
|
||||
|
||||
// guardedUnaryOp creates an invocation guard around the provided unary operator, if one is defined.
|
||||
func (o *OverloadDecl) guardedUnaryOp(funcName string, disableTypeGuards bool) functions.UnaryOp {
|
||||
if o.unaryOp == nil {
|
||||
return nil
|
||||
}
|
||||
return func(arg ref.Val) ref.Val {
|
||||
if !o.matchesRuntimeUnarySignature(disableTypeGuards, arg) {
|
||||
return MaybeNoSuchOverload(funcName, arg)
|
||||
}
|
||||
return o.unaryOp(arg)
|
||||
}
|
||||
}
|
||||
|
||||
// guardedBinaryOp creates an invocation guard around the provided binary operator, if one is defined.
|
||||
func (o *OverloadDecl) guardedBinaryOp(funcName string, disableTypeGuards bool) functions.BinaryOp {
|
||||
if o.binaryOp == nil {
|
||||
return nil
|
||||
}
|
||||
return func(arg1, arg2 ref.Val) ref.Val {
|
||||
if !o.matchesRuntimeBinarySignature(disableTypeGuards, arg1, arg2) {
|
||||
return MaybeNoSuchOverload(funcName, arg1, arg2)
|
||||
}
|
||||
return o.binaryOp(arg1, arg2)
|
||||
}
|
||||
}
|
||||
|
||||
// guardedFunctionOp creates an invocation guard around the provided variadic function binding, if one is provided.
|
||||
func (o *OverloadDecl) guardedFunctionOp(funcName string, disableTypeGuards bool) functions.FunctionOp {
|
||||
if o.functionOp == nil {
|
||||
return nil
|
||||
}
|
||||
return func(args ...ref.Val) ref.Val {
|
||||
if !o.matchesRuntimeSignature(disableTypeGuards, args...) {
|
||||
return MaybeNoSuchOverload(funcName, args...)
|
||||
}
|
||||
return o.functionOp(args...)
|
||||
}
|
||||
}
|
||||
|
||||
// matchesRuntimeUnarySignature indicates whether the argument type is runtime assiganble to the overload's expected argument.
|
||||
func (o *OverloadDecl) matchesRuntimeUnarySignature(disableTypeGuards bool, arg ref.Val) bool {
|
||||
return matchRuntimeArgType(o.IsNonStrict(), disableTypeGuards, o.ArgTypes()[0], arg) &&
|
||||
matchOperandTrait(o.OperandTrait(), arg)
|
||||
}
|
||||
|
||||
// matchesRuntimeBinarySignature indicates whether the argument types are runtime assiganble to the overload's expected arguments.
|
||||
func (o *OverloadDecl) matchesRuntimeBinarySignature(disableTypeGuards bool, arg1, arg2 ref.Val) bool {
|
||||
return matchRuntimeArgType(o.IsNonStrict(), disableTypeGuards, o.ArgTypes()[0], arg1) &&
|
||||
matchRuntimeArgType(o.IsNonStrict(), disableTypeGuards, o.ArgTypes()[1], arg2) &&
|
||||
matchOperandTrait(o.OperandTrait(), arg1)
|
||||
}
|
||||
|
||||
// matchesRuntimeSignature indicates whether the argument types are runtime assiganble to the overload's expected arguments.
|
||||
func (o *OverloadDecl) matchesRuntimeSignature(disableTypeGuards bool, args ...ref.Val) bool {
|
||||
if len(args) != len(o.ArgTypes()) {
|
||||
return false
|
||||
}
|
||||
if len(args) == 0 {
|
||||
return true
|
||||
}
|
||||
for i, arg := range args {
|
||||
if !matchRuntimeArgType(o.IsNonStrict(), disableTypeGuards, o.ArgTypes()[i], arg) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return matchOperandTrait(o.OperandTrait(), args[0])
|
||||
}
|
||||
|
||||
func matchRuntimeArgType(nonStrict, disableTypeGuards bool, argType *types.Type, arg ref.Val) bool {
|
||||
if nonStrict && (disableTypeGuards || types.IsUnknownOrError(arg)) {
|
||||
return true
|
||||
}
|
||||
if types.IsUnknownOrError(arg) {
|
||||
return false
|
||||
}
|
||||
return disableTypeGuards || argType.IsAssignableRuntimeType(arg)
|
||||
}
|
||||
|
||||
func matchOperandTrait(trait int, arg ref.Val) bool {
|
||||
return trait == 0 || arg.Type().HasTrait(trait) || types.IsUnknownOrError(arg)
|
||||
}
|
||||
|
||||
// OverloadOpt is a functional option for configuring a function overload.
|
||||
type OverloadOpt func(*OverloadDecl) (*OverloadDecl, error)
|
||||
|
||||
// UnaryBinding provides the implementation of a unary overload. The provided function is protected by a runtime
|
||||
// type-guard which ensures runtime type agreement between the overload signature and runtime argument types.
|
||||
func UnaryBinding(binding functions.UnaryOp) OverloadOpt {
|
||||
return func(o *OverloadDecl) (*OverloadDecl, error) {
|
||||
if o.hasBinding() {
|
||||
return nil, fmt.Errorf("overload already has a binding: %s", o.ID())
|
||||
}
|
||||
if len(o.ArgTypes()) != 1 {
|
||||
return nil, fmt.Errorf("unary function bound to non-unary overload: %s", o.ID())
|
||||
}
|
||||
o.unaryOp = binding
|
||||
return o, nil
|
||||
}
|
||||
}
|
||||
|
||||
// BinaryBinding provides the implementation of a binary overload. The provided function is protected by a runtime
|
||||
// type-guard which ensures runtime type agreement between the overload signature and runtime argument types.
|
||||
func BinaryBinding(binding functions.BinaryOp) OverloadOpt {
|
||||
return func(o *OverloadDecl) (*OverloadDecl, error) {
|
||||
if o.hasBinding() {
|
||||
return nil, fmt.Errorf("overload already has a binding: %s", o.ID())
|
||||
}
|
||||
if len(o.ArgTypes()) != 2 {
|
||||
return nil, fmt.Errorf("binary function bound to non-binary overload: %s", o.ID())
|
||||
}
|
||||
o.binaryOp = binding
|
||||
return o, nil
|
||||
}
|
||||
}
|
||||
|
||||
// FunctionBinding provides the implementation of a variadic overload. The provided function is protected by a runtime
|
||||
// type-guard which ensures runtime type agreement between the overload signature and runtime argument types.
|
||||
func FunctionBinding(binding functions.FunctionOp) OverloadOpt {
|
||||
return func(o *OverloadDecl) (*OverloadDecl, error) {
|
||||
if o.hasBinding() {
|
||||
return nil, fmt.Errorf("overload already has a binding: %s", o.ID())
|
||||
}
|
||||
o.functionOp = binding
|
||||
return o, nil
|
||||
}
|
||||
}
|
||||
|
||||
// OverloadIsNonStrict enables the function to be called with error and unknown argument values.
|
||||
//
|
||||
// Note: do not use this option unless absoluately necessary as it should be an uncommon feature.
|
||||
func OverloadIsNonStrict() OverloadOpt {
|
||||
return func(o *OverloadDecl) (*OverloadDecl, error) {
|
||||
o.nonStrict = true
|
||||
return o, nil
|
||||
}
|
||||
}
|
||||
|
||||
// OverloadOperandTrait configures a set of traits which the first argument to the overload must implement in order to be
|
||||
// successfully invoked.
|
||||
func OverloadOperandTrait(trait int) OverloadOpt {
|
||||
return func(o *OverloadDecl) (*OverloadDecl, error) {
|
||||
o.operandTrait = trait
|
||||
return o, nil
|
||||
}
|
||||
}
|
||||
|
||||
// NewConstant creates a new constant declaration.
|
||||
func NewConstant(name string, t *types.Type, v ref.Val) *VariableDecl {
|
||||
return &VariableDecl{name: name, varType: t, value: v}
|
||||
}
|
||||
|
||||
// NewVariable creates a new variable declaration.
|
||||
func NewVariable(name string, t *types.Type) *VariableDecl {
|
||||
return &VariableDecl{name: name, varType: t}
|
||||
}
|
||||
|
||||
// VariableDecl defines a variable declaration which may optionally have a constant value.
|
||||
type VariableDecl struct {
|
||||
name string
|
||||
varType *types.Type
|
||||
value ref.Val
|
||||
}
|
||||
|
||||
// Name returns the fully-qualified variable name
|
||||
func (v *VariableDecl) Name() string {
|
||||
if v == nil {
|
||||
return ""
|
||||
}
|
||||
return v.name
|
||||
}
|
||||
|
||||
// Type returns the types.Type value associated with the variable.
|
||||
func (v *VariableDecl) Type() *types.Type {
|
||||
if v == nil {
|
||||
// types.Type is nil-safe
|
||||
return nil
|
||||
}
|
||||
return v.varType
|
||||
}
|
||||
|
||||
// Value returns the constant value associated with the declaration.
|
||||
func (v *VariableDecl) Value() ref.Val {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
return v.value
|
||||
}
|
||||
|
||||
// DeclarationIsEquivalent returns true if one variable declaration has the same name and same type as the input.
|
||||
func (v *VariableDecl) DeclarationIsEquivalent(other *VariableDecl) bool {
|
||||
if v == other {
|
||||
return true
|
||||
}
|
||||
return v.Name() == other.Name() && v.Type().IsEquivalentType(other.Type())
|
||||
}
|
||||
|
||||
// VariableDeclToExprDecl converts a go-native variable declaration into a protobuf-type variable declaration.
|
||||
func VariableDeclToExprDecl(v *VariableDecl) (*exprpb.Decl, error) {
|
||||
varType, err := types.TypeToExprType(v.Type())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return chkdecls.NewVar(v.Name(), varType), nil
|
||||
}
|
||||
|
||||
// TypeVariable creates a new type identifier for use within a types.Provider
|
||||
func TypeVariable(t *types.Type) *VariableDecl {
|
||||
return NewVariable(t.TypeName(), types.NewTypeTypeWithParam(t))
|
||||
}
|
||||
|
||||
// FunctionDeclToExprDecl converts a go-native function declaration into a protobuf-typed function declaration.
|
||||
func FunctionDeclToExprDecl(f *FunctionDecl) (*exprpb.Decl, error) {
|
||||
overloads := make([]*exprpb.Decl_FunctionDecl_Overload, len(f.overloads))
|
||||
for i, oID := range f.overloadOrdinals {
|
||||
o := f.overloads[oID]
|
||||
paramNames := map[string]struct{}{}
|
||||
argTypes := make([]*exprpb.Type, len(o.ArgTypes()))
|
||||
for j, a := range o.ArgTypes() {
|
||||
collectParamNames(paramNames, a)
|
||||
at, err := types.TypeToExprType(a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
argTypes[j] = at
|
||||
}
|
||||
collectParamNames(paramNames, o.ResultType())
|
||||
resultType, err := types.TypeToExprType(o.ResultType())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(paramNames) == 0 {
|
||||
if o.IsMemberFunction() {
|
||||
overloads[i] = chkdecls.NewInstanceOverload(oID, argTypes, resultType)
|
||||
} else {
|
||||
overloads[i] = chkdecls.NewOverload(oID, argTypes, resultType)
|
||||
}
|
||||
} else {
|
||||
params := []string{}
|
||||
for pn := range paramNames {
|
||||
params = append(params, pn)
|
||||
}
|
||||
if o.IsMemberFunction() {
|
||||
overloads[i] = chkdecls.NewParameterizedInstanceOverload(oID, argTypes, resultType, params)
|
||||
} else {
|
||||
overloads[i] = chkdecls.NewParameterizedOverload(oID, argTypes, resultType, params)
|
||||
}
|
||||
}
|
||||
}
|
||||
return chkdecls.NewFunction(f.Name(), overloads...), nil
|
||||
}
|
||||
|
||||
func collectParamNames(paramNames map[string]struct{}, arg *types.Type) {
|
||||
if arg.Kind() == types.TypeParamKind {
|
||||
paramNames[arg.TypeName()] = struct{}{}
|
||||
}
|
||||
for _, param := range arg.Parameters() {
|
||||
collectParamNames(paramNames, param)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
emptyArgs = []*types.Type{}
|
||||
)
|
8
vendor/github.com/google/cel-go/common/error.go
generated
vendored
8
vendor/github.com/google/cel-go/common/error.go
generated
vendored
@ -22,10 +22,16 @@ import (
|
||||
"golang.org/x/text/width"
|
||||
)
|
||||
|
||||
// Error type which references a location within source and a message.
|
||||
// NewError creates an error associated with an expression id with the given message at the given location.
|
||||
func NewError(id int64, message string, location Location) *Error {
|
||||
return &Error{Message: message, Location: location, ExprID: id}
|
||||
}
|
||||
|
||||
// Error type which references an expression id, a location within source, and a message.
|
||||
type Error struct {
|
||||
Location Location
|
||||
Message string
|
||||
ExprID int64
|
||||
}
|
||||
|
||||
const (
|
||||
|
16
vendor/github.com/google/cel-go/common/errors.go
generated
vendored
16
vendor/github.com/google/cel-go/common/errors.go
generated
vendored
@ -22,7 +22,7 @@ import (
|
||||
|
||||
// Errors type which contains a list of errors observed during parsing.
|
||||
type Errors struct {
|
||||
errors []Error
|
||||
errors []*Error
|
||||
source Source
|
||||
numErrors int
|
||||
maxErrorsToReport int
|
||||
@ -31,7 +31,7 @@ type Errors struct {
|
||||
// NewErrors creates a new instance of the Errors type.
|
||||
func NewErrors(source Source) *Errors {
|
||||
return &Errors{
|
||||
errors: []Error{},
|
||||
errors: []*Error{},
|
||||
source: source,
|
||||
maxErrorsToReport: 100,
|
||||
}
|
||||
@ -39,11 +39,17 @@ func NewErrors(source Source) *Errors {
|
||||
|
||||
// ReportError records an error at a source location.
|
||||
func (e *Errors) ReportError(l Location, format string, args ...any) {
|
||||
e.ReportErrorAtID(0, l, format, args...)
|
||||
}
|
||||
|
||||
// ReportErrorAtID records an error at a source location and expression id.
|
||||
func (e *Errors) ReportErrorAtID(id int64, l Location, format string, args ...any) {
|
||||
e.numErrors++
|
||||
if e.numErrors > e.maxErrorsToReport {
|
||||
return
|
||||
}
|
||||
err := Error{
|
||||
err := &Error{
|
||||
ExprID: id,
|
||||
Location: l,
|
||||
Message: fmt.Sprintf(format, args...),
|
||||
}
|
||||
@ -51,12 +57,12 @@ func (e *Errors) ReportError(l Location, format string, args ...any) {
|
||||
}
|
||||
|
||||
// GetErrors returns the list of observed errors.
|
||||
func (e *Errors) GetErrors() []Error {
|
||||
func (e *Errors) GetErrors() []*Error {
|
||||
return e.errors[:]
|
||||
}
|
||||
|
||||
// Append creates a new Errors object with the current and input errors.
|
||||
func (e *Errors) Append(errs []Error) *Errors {
|
||||
func (e *Errors) Append(errs []*Error) *Errors {
|
||||
return &Errors{
|
||||
errors: append(e.errors, errs...),
|
||||
source: e.source,
|
||||
|
17
vendor/github.com/google/cel-go/common/functions/BUILD.bazel
generated
vendored
Normal file
17
vendor/github.com/google/cel-go/common/functions/BUILD.bazel
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
package(
|
||||
default_visibility = ["//visibility:public"],
|
||||
licenses = ["notice"], # Apache 2.0
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"functions.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/functions",
|
||||
deps = [
|
||||
"//common/types/ref:go_default_library",
|
||||
],
|
||||
)
|
61
vendor/github.com/google/cel-go/common/functions/functions.go
generated
vendored
Normal file
61
vendor/github.com/google/cel-go/common/functions/functions.go
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package functions defines the standard builtin functions supported by the interpreter
|
||||
package functions
|
||||
|
||||
import "github.com/google/cel-go/common/types/ref"
|
||||
|
||||
// Overload defines a named overload of a function, indicating an operand trait
|
||||
// which must be present on the first argument to the overload as well as one
|
||||
// of either a unary, binary, or function implementation.
|
||||
//
|
||||
// The majority of operators within the expression language are unary or binary
|
||||
// and the specializations simplify the call contract for implementers of
|
||||
// types with operator overloads. Any added complexity is assumed to be handled
|
||||
// by the generic FunctionOp.
|
||||
type Overload struct {
|
||||
// Operator name as written in an expression or defined within
|
||||
// operators.go.
|
||||
Operator string
|
||||
|
||||
// Operand trait used to dispatch the call. The zero-value indicates a
|
||||
// global function overload or that one of the Unary / Binary / Function
|
||||
// definitions should be used to execute the call.
|
||||
OperandTrait int
|
||||
|
||||
// Unary defines the overload with a UnaryOp implementation. May be nil.
|
||||
Unary UnaryOp
|
||||
|
||||
// Binary defines the overload with a BinaryOp implementation. May be nil.
|
||||
Binary BinaryOp
|
||||
|
||||
// Function defines the overload with a FunctionOp implementation. May be
|
||||
// nil.
|
||||
Function FunctionOp
|
||||
|
||||
// NonStrict specifies whether the Overload will tolerate arguments that
|
||||
// are types.Err or types.Unknown.
|
||||
NonStrict bool
|
||||
}
|
||||
|
||||
// UnaryOp is a function that takes a single value and produces an output.
|
||||
type UnaryOp func(value ref.Val) ref.Val
|
||||
|
||||
// BinaryOp is a function that takes two values and produces an output.
|
||||
type BinaryOp func(lhs ref.Val, rhs ref.Val) ref.Val
|
||||
|
||||
// FunctionOp is a function with accepts zero or more arguments and produces
|
||||
// a value or error as a result.
|
||||
type FunctionOp func(values ...ref.Val) ref.Val
|
3
vendor/github.com/google/cel-go/common/source.go
generated
vendored
3
vendor/github.com/google/cel-go/common/source.go
generated
vendored
@ -64,7 +64,6 @@ type sourceImpl struct {
|
||||
runes.Buffer
|
||||
description string
|
||||
lineOffsets []int32
|
||||
idOffsets map[int64]int32
|
||||
}
|
||||
|
||||
var _ runes.Buffer = &sourceImpl{}
|
||||
@ -92,7 +91,6 @@ func NewStringSource(contents string, description string) Source {
|
||||
Buffer: runes.NewBuffer(contents),
|
||||
description: description,
|
||||
lineOffsets: offsets,
|
||||
idOffsets: map[int64]int32{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,7 +100,6 @@ func NewInfoSource(info *exprpb.SourceInfo) Source {
|
||||
Buffer: runes.NewBuffer(""),
|
||||
description: info.GetLocation(),
|
||||
lineOffsets: info.GetLineOffsets(),
|
||||
idOffsets: info.GetPositions(),
|
||||
}
|
||||
}
|
||||
|
||||
|
25
vendor/github.com/google/cel-go/common/stdlib/BUILD.bazel
generated
vendored
Normal file
25
vendor/github.com/google/cel-go/common/stdlib/BUILD.bazel
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
package(
|
||||
default_visibility = ["//visibility:public"],
|
||||
licenses = ["notice"], # Apache 2.0
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"standard.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/stdlib",
|
||||
deps = [
|
||||
"//checker/decls:go_default_library",
|
||||
"//common/decls:go_default_library",
|
||||
"//common/functions:go_default_library",
|
||||
"//common/operators:go_default_library",
|
||||
"//common/overloads:go_default_library",
|
||||
"//common/types:go_default_library",
|
||||
"//common/types/ref:go_default_library",
|
||||
"//common/types/traits:go_default_library",
|
||||
"@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
|
||||
],
|
||||
)
|
661
vendor/github.com/google/cel-go/common/stdlib/standard.go
generated
vendored
Normal file
661
vendor/github.com/google/cel-go/common/stdlib/standard.go
generated
vendored
Normal file
@ -0,0 +1,661 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package stdlib contains all of the standard library function declarations and definitions for CEL.
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"github.com/google/cel-go/common/decls"
|
||||
"github.com/google/cel-go/common/functions"
|
||||
"github.com/google/cel-go/common/operators"
|
||||
"github.com/google/cel-go/common/overloads"
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
)
|
||||
|
||||
var (
|
||||
stdFunctions []*decls.FunctionDecl
|
||||
stdFnDecls []*exprpb.Decl
|
||||
stdTypes []*decls.VariableDecl
|
||||
stdTypeDecls []*exprpb.Decl
|
||||
)
|
||||
|
||||
func init() {
|
||||
paramA := types.NewTypeParamType("A")
|
||||
paramB := types.NewTypeParamType("B")
|
||||
listOfA := types.NewListType(paramA)
|
||||
mapOfAB := types.NewMapType(paramA, paramB)
|
||||
|
||||
stdTypes = []*decls.VariableDecl{
|
||||
decls.TypeVariable(types.BoolType),
|
||||
decls.TypeVariable(types.BytesType),
|
||||
decls.TypeVariable(types.DoubleType),
|
||||
decls.TypeVariable(types.DurationType),
|
||||
decls.TypeVariable(types.IntType),
|
||||
decls.TypeVariable(listOfA),
|
||||
decls.TypeVariable(mapOfAB),
|
||||
decls.TypeVariable(types.NullType),
|
||||
decls.TypeVariable(types.StringType),
|
||||
decls.TypeVariable(types.TimestampType),
|
||||
decls.TypeVariable(types.TypeType),
|
||||
decls.TypeVariable(types.UintType),
|
||||
}
|
||||
|
||||
stdTypeDecls = make([]*exprpb.Decl, 0, len(stdTypes))
|
||||
for _, stdType := range stdTypes {
|
||||
typeVar, err := decls.VariableDeclToExprDecl(stdType)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
stdTypeDecls = append(stdTypeDecls, typeVar)
|
||||
}
|
||||
|
||||
stdFunctions = []*decls.FunctionDecl{
|
||||
// Logical operators. Special-cased within the interpreter.
|
||||
// Note, the singleton binding prevents extensions from overriding the operator behavior.
|
||||
function(operators.Conditional,
|
||||
decls.Overload(overloads.Conditional, argTypes(types.BoolType, paramA, paramA), paramA,
|
||||
decls.OverloadIsNonStrict()),
|
||||
decls.SingletonFunctionBinding(noFunctionOverrides)),
|
||||
function(operators.LogicalAnd,
|
||||
decls.Overload(overloads.LogicalAnd, argTypes(types.BoolType, types.BoolType), types.BoolType,
|
||||
decls.OverloadIsNonStrict()),
|
||||
decls.SingletonBinaryBinding(noBinaryOverrides)),
|
||||
function(operators.LogicalOr,
|
||||
decls.Overload(overloads.LogicalOr, argTypes(types.BoolType, types.BoolType), types.BoolType,
|
||||
decls.OverloadIsNonStrict()),
|
||||
decls.SingletonBinaryBinding(noBinaryOverrides)),
|
||||
function(operators.LogicalNot,
|
||||
decls.Overload(overloads.LogicalNot, argTypes(types.BoolType), types.BoolType),
|
||||
decls.SingletonUnaryBinding(func(val ref.Val) ref.Val {
|
||||
b, ok := val.(types.Bool)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(val)
|
||||
}
|
||||
return b.Negate()
|
||||
})),
|
||||
|
||||
// Comprehension short-circuiting related function
|
||||
function(operators.NotStrictlyFalse,
|
||||
decls.Overload(overloads.NotStrictlyFalse, argTypes(types.BoolType), types.BoolType,
|
||||
decls.OverloadIsNonStrict(),
|
||||
decls.UnaryBinding(notStrictlyFalse))),
|
||||
// Deprecated: __not_strictly_false__
|
||||
function(operators.OldNotStrictlyFalse,
|
||||
decls.DisableDeclaration(true), // safe deprecation
|
||||
decls.Overload(operators.OldNotStrictlyFalse, argTypes(types.BoolType), types.BoolType,
|
||||
decls.OverloadIsNonStrict(),
|
||||
decls.UnaryBinding(notStrictlyFalse))),
|
||||
|
||||
// Equality / inequality. Special-cased in the interpreter
|
||||
function(operators.Equals,
|
||||
decls.Overload(overloads.Equals, argTypes(paramA, paramA), types.BoolType),
|
||||
decls.SingletonBinaryBinding(noBinaryOverrides)),
|
||||
function(operators.NotEquals,
|
||||
decls.Overload(overloads.NotEquals, argTypes(paramA, paramA), types.BoolType),
|
||||
decls.SingletonBinaryBinding(noBinaryOverrides)),
|
||||
|
||||
// Mathematical operators
|
||||
function(operators.Add,
|
||||
decls.Overload(overloads.AddBytes,
|
||||
argTypes(types.BytesType, types.BytesType), types.BytesType),
|
||||
decls.Overload(overloads.AddDouble,
|
||||
argTypes(types.DoubleType, types.DoubleType), types.DoubleType),
|
||||
decls.Overload(overloads.AddDurationDuration,
|
||||
argTypes(types.DurationType, types.DurationType), types.DurationType),
|
||||
decls.Overload(overloads.AddDurationTimestamp,
|
||||
argTypes(types.DurationType, types.TimestampType), types.TimestampType),
|
||||
decls.Overload(overloads.AddTimestampDuration,
|
||||
argTypes(types.TimestampType, types.DurationType), types.TimestampType),
|
||||
decls.Overload(overloads.AddInt64,
|
||||
argTypes(types.IntType, types.IntType), types.IntType),
|
||||
decls.Overload(overloads.AddList,
|
||||
argTypes(listOfA, listOfA), listOfA),
|
||||
decls.Overload(overloads.AddString,
|
||||
argTypes(types.StringType, types.StringType), types.StringType),
|
||||
decls.Overload(overloads.AddUint64,
|
||||
argTypes(types.UintType, types.UintType), types.UintType),
|
||||
decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val {
|
||||
return lhs.(traits.Adder).Add(rhs)
|
||||
}, traits.AdderType)),
|
||||
function(operators.Divide,
|
||||
decls.Overload(overloads.DivideDouble,
|
||||
argTypes(types.DoubleType, types.DoubleType), types.DoubleType),
|
||||
decls.Overload(overloads.DivideInt64,
|
||||
argTypes(types.IntType, types.IntType), types.IntType),
|
||||
decls.Overload(overloads.DivideUint64,
|
||||
argTypes(types.UintType, types.UintType), types.UintType),
|
||||
decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val {
|
||||
return lhs.(traits.Divider).Divide(rhs)
|
||||
}, traits.DividerType)),
|
||||
function(operators.Modulo,
|
||||
decls.Overload(overloads.ModuloInt64,
|
||||
argTypes(types.IntType, types.IntType), types.IntType),
|
||||
decls.Overload(overloads.ModuloUint64,
|
||||
argTypes(types.UintType, types.UintType), types.UintType),
|
||||
decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val {
|
||||
return lhs.(traits.Modder).Modulo(rhs)
|
||||
}, traits.ModderType)),
|
||||
function(operators.Multiply,
|
||||
decls.Overload(overloads.MultiplyDouble,
|
||||
argTypes(types.DoubleType, types.DoubleType), types.DoubleType),
|
||||
decls.Overload(overloads.MultiplyInt64,
|
||||
argTypes(types.IntType, types.IntType), types.IntType),
|
||||
decls.Overload(overloads.MultiplyUint64,
|
||||
argTypes(types.UintType, types.UintType), types.UintType),
|
||||
decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val {
|
||||
return lhs.(traits.Multiplier).Multiply(rhs)
|
||||
}, traits.MultiplierType)),
|
||||
function(operators.Negate,
|
||||
decls.Overload(overloads.NegateDouble, argTypes(types.DoubleType), types.DoubleType),
|
||||
decls.Overload(overloads.NegateInt64, argTypes(types.IntType), types.IntType),
|
||||
decls.SingletonUnaryBinding(func(val ref.Val) ref.Val {
|
||||
if types.IsBool(val) {
|
||||
return types.MaybeNoSuchOverloadErr(val)
|
||||
}
|
||||
return val.(traits.Negater).Negate()
|
||||
}, traits.NegatorType)),
|
||||
function(operators.Subtract,
|
||||
decls.Overload(overloads.SubtractDouble,
|
||||
argTypes(types.DoubleType, types.DoubleType), types.DoubleType),
|
||||
decls.Overload(overloads.SubtractDurationDuration,
|
||||
argTypes(types.DurationType, types.DurationType), types.DurationType),
|
||||
decls.Overload(overloads.SubtractInt64,
|
||||
argTypes(types.IntType, types.IntType), types.IntType),
|
||||
decls.Overload(overloads.SubtractTimestampDuration,
|
||||
argTypes(types.TimestampType, types.DurationType), types.TimestampType),
|
||||
decls.Overload(overloads.SubtractTimestampTimestamp,
|
||||
argTypes(types.TimestampType, types.TimestampType), types.DurationType),
|
||||
decls.Overload(overloads.SubtractUint64,
|
||||
argTypes(types.UintType, types.UintType), types.UintType),
|
||||
decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val {
|
||||
return lhs.(traits.Subtractor).Subtract(rhs)
|
||||
}, traits.SubtractorType)),
|
||||
|
||||
// Relations operators
|
||||
|
||||
function(operators.Less,
|
||||
decls.Overload(overloads.LessBool,
|
||||
argTypes(types.BoolType, types.BoolType), types.BoolType),
|
||||
decls.Overload(overloads.LessInt64,
|
||||
argTypes(types.IntType, types.IntType), types.BoolType),
|
||||
decls.Overload(overloads.LessInt64Double,
|
||||
argTypes(types.IntType, types.DoubleType), types.BoolType),
|
||||
decls.Overload(overloads.LessInt64Uint64,
|
||||
argTypes(types.IntType, types.UintType), types.BoolType),
|
||||
decls.Overload(overloads.LessUint64,
|
||||
argTypes(types.UintType, types.UintType), types.BoolType),
|
||||
decls.Overload(overloads.LessUint64Double,
|
||||
argTypes(types.UintType, types.DoubleType), types.BoolType),
|
||||
decls.Overload(overloads.LessUint64Int64,
|
||||
argTypes(types.UintType, types.IntType), types.BoolType),
|
||||
decls.Overload(overloads.LessDouble,
|
||||
argTypes(types.DoubleType, types.DoubleType), types.BoolType),
|
||||
decls.Overload(overloads.LessDoubleInt64,
|
||||
argTypes(types.DoubleType, types.IntType), types.BoolType),
|
||||
decls.Overload(overloads.LessDoubleUint64,
|
||||
argTypes(types.DoubleType, types.UintType), types.BoolType),
|
||||
decls.Overload(overloads.LessString,
|
||||
argTypes(types.StringType, types.StringType), types.BoolType),
|
||||
decls.Overload(overloads.LessBytes,
|
||||
argTypes(types.BytesType, types.BytesType), types.BoolType),
|
||||
decls.Overload(overloads.LessTimestamp,
|
||||
argTypes(types.TimestampType, types.TimestampType), types.BoolType),
|
||||
decls.Overload(overloads.LessDuration,
|
||||
argTypes(types.DurationType, types.DurationType), types.BoolType),
|
||||
decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val {
|
||||
cmp := lhs.(traits.Comparer).Compare(rhs)
|
||||
if cmp == types.IntNegOne {
|
||||
return types.True
|
||||
}
|
||||
if cmp == types.IntOne || cmp == types.IntZero {
|
||||
return types.False
|
||||
}
|
||||
return cmp
|
||||
}, traits.ComparerType)),
|
||||
|
||||
function(operators.LessEquals,
|
||||
decls.Overload(overloads.LessEqualsBool,
|
||||
argTypes(types.BoolType, types.BoolType), types.BoolType),
|
||||
decls.Overload(overloads.LessEqualsInt64,
|
||||
argTypes(types.IntType, types.IntType), types.BoolType),
|
||||
decls.Overload(overloads.LessEqualsInt64Double,
|
||||
argTypes(types.IntType, types.DoubleType), types.BoolType),
|
||||
decls.Overload(overloads.LessEqualsInt64Uint64,
|
||||
argTypes(types.IntType, types.UintType), types.BoolType),
|
||||
decls.Overload(overloads.LessEqualsUint64,
|
||||
argTypes(types.UintType, types.UintType), types.BoolType),
|
||||
decls.Overload(overloads.LessEqualsUint64Double,
|
||||
argTypes(types.UintType, types.DoubleType), types.BoolType),
|
||||
decls.Overload(overloads.LessEqualsUint64Int64,
|
||||
argTypes(types.UintType, types.IntType), types.BoolType),
|
||||
decls.Overload(overloads.LessEqualsDouble,
|
||||
argTypes(types.DoubleType, types.DoubleType), types.BoolType),
|
||||
decls.Overload(overloads.LessEqualsDoubleInt64,
|
||||
argTypes(types.DoubleType, types.IntType), types.BoolType),
|
||||
decls.Overload(overloads.LessEqualsDoubleUint64,
|
||||
argTypes(types.DoubleType, types.UintType), types.BoolType),
|
||||
decls.Overload(overloads.LessEqualsString,
|
||||
argTypes(types.StringType, types.StringType), types.BoolType),
|
||||
decls.Overload(overloads.LessEqualsBytes,
|
||||
argTypes(types.BytesType, types.BytesType), types.BoolType),
|
||||
decls.Overload(overloads.LessEqualsTimestamp,
|
||||
argTypes(types.TimestampType, types.TimestampType), types.BoolType),
|
||||
decls.Overload(overloads.LessEqualsDuration,
|
||||
argTypes(types.DurationType, types.DurationType), types.BoolType),
|
||||
decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val {
|
||||
cmp := lhs.(traits.Comparer).Compare(rhs)
|
||||
if cmp == types.IntNegOne || cmp == types.IntZero {
|
||||
return types.True
|
||||
}
|
||||
if cmp == types.IntOne {
|
||||
return types.False
|
||||
}
|
||||
return cmp
|
||||
}, traits.ComparerType)),
|
||||
|
||||
function(operators.Greater,
|
||||
decls.Overload(overloads.GreaterBool,
|
||||
argTypes(types.BoolType, types.BoolType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterInt64,
|
||||
argTypes(types.IntType, types.IntType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterInt64Double,
|
||||
argTypes(types.IntType, types.DoubleType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterInt64Uint64,
|
||||
argTypes(types.IntType, types.UintType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterUint64,
|
||||
argTypes(types.UintType, types.UintType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterUint64Double,
|
||||
argTypes(types.UintType, types.DoubleType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterUint64Int64,
|
||||
argTypes(types.UintType, types.IntType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterDouble,
|
||||
argTypes(types.DoubleType, types.DoubleType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterDoubleInt64,
|
||||
argTypes(types.DoubleType, types.IntType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterDoubleUint64,
|
||||
argTypes(types.DoubleType, types.UintType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterString,
|
||||
argTypes(types.StringType, types.StringType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterBytes,
|
||||
argTypes(types.BytesType, types.BytesType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterTimestamp,
|
||||
argTypes(types.TimestampType, types.TimestampType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterDuration,
|
||||
argTypes(types.DurationType, types.DurationType), types.BoolType),
|
||||
decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val {
|
||||
cmp := lhs.(traits.Comparer).Compare(rhs)
|
||||
if cmp == types.IntOne {
|
||||
return types.True
|
||||
}
|
||||
if cmp == types.IntNegOne || cmp == types.IntZero {
|
||||
return types.False
|
||||
}
|
||||
return cmp
|
||||
}, traits.ComparerType)),
|
||||
|
||||
function(operators.GreaterEquals,
|
||||
decls.Overload(overloads.GreaterEqualsBool,
|
||||
argTypes(types.BoolType, types.BoolType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterEqualsInt64,
|
||||
argTypes(types.IntType, types.IntType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterEqualsInt64Double,
|
||||
argTypes(types.IntType, types.DoubleType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterEqualsInt64Uint64,
|
||||
argTypes(types.IntType, types.UintType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterEqualsUint64,
|
||||
argTypes(types.UintType, types.UintType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterEqualsUint64Double,
|
||||
argTypes(types.UintType, types.DoubleType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterEqualsUint64Int64,
|
||||
argTypes(types.UintType, types.IntType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterEqualsDouble,
|
||||
argTypes(types.DoubleType, types.DoubleType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterEqualsDoubleInt64,
|
||||
argTypes(types.DoubleType, types.IntType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterEqualsDoubleUint64,
|
||||
argTypes(types.DoubleType, types.UintType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterEqualsString,
|
||||
argTypes(types.StringType, types.StringType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterEqualsBytes,
|
||||
argTypes(types.BytesType, types.BytesType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterEqualsTimestamp,
|
||||
argTypes(types.TimestampType, types.TimestampType), types.BoolType),
|
||||
decls.Overload(overloads.GreaterEqualsDuration,
|
||||
argTypes(types.DurationType, types.DurationType), types.BoolType),
|
||||
decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val {
|
||||
cmp := lhs.(traits.Comparer).Compare(rhs)
|
||||
if cmp == types.IntOne || cmp == types.IntZero {
|
||||
return types.True
|
||||
}
|
||||
if cmp == types.IntNegOne {
|
||||
return types.False
|
||||
}
|
||||
return cmp
|
||||
}, traits.ComparerType)),
|
||||
|
||||
// Indexing
|
||||
function(operators.Index,
|
||||
decls.Overload(overloads.IndexList, argTypes(listOfA, types.IntType), paramA),
|
||||
decls.Overload(overloads.IndexMap, argTypes(mapOfAB, paramA), paramB),
|
||||
decls.SingletonBinaryBinding(func(lhs, rhs ref.Val) ref.Val {
|
||||
return lhs.(traits.Indexer).Get(rhs)
|
||||
}, traits.IndexerType)),
|
||||
|
||||
// Collections operators
|
||||
function(operators.In,
|
||||
decls.Overload(overloads.InList, argTypes(paramA, listOfA), types.BoolType),
|
||||
decls.Overload(overloads.InMap, argTypes(paramA, mapOfAB), types.BoolType),
|
||||
decls.SingletonBinaryBinding(inAggregate)),
|
||||
function(operators.OldIn,
|
||||
decls.DisableDeclaration(true), // safe deprecation
|
||||
decls.Overload(overloads.InList, argTypes(paramA, listOfA), types.BoolType),
|
||||
decls.Overload(overloads.InMap, argTypes(paramA, mapOfAB), types.BoolType),
|
||||
decls.SingletonBinaryBinding(inAggregate)),
|
||||
function(overloads.DeprecatedIn,
|
||||
decls.DisableDeclaration(true), // safe deprecation
|
||||
decls.Overload(overloads.InList, argTypes(paramA, listOfA), types.BoolType),
|
||||
decls.Overload(overloads.InMap, argTypes(paramA, mapOfAB), types.BoolType),
|
||||
decls.SingletonBinaryBinding(inAggregate)),
|
||||
function(overloads.Size,
|
||||
decls.Overload(overloads.SizeBytes, argTypes(types.BytesType), types.IntType),
|
||||
decls.MemberOverload(overloads.SizeBytesInst, argTypes(types.BytesType), types.IntType),
|
||||
decls.Overload(overloads.SizeList, argTypes(listOfA), types.IntType),
|
||||
decls.MemberOverload(overloads.SizeListInst, argTypes(listOfA), types.IntType),
|
||||
decls.Overload(overloads.SizeMap, argTypes(mapOfAB), types.IntType),
|
||||
decls.MemberOverload(overloads.SizeMapInst, argTypes(mapOfAB), types.IntType),
|
||||
decls.Overload(overloads.SizeString, argTypes(types.StringType), types.IntType),
|
||||
decls.MemberOverload(overloads.SizeStringInst, argTypes(types.StringType), types.IntType),
|
||||
decls.SingletonUnaryBinding(func(val ref.Val) ref.Val {
|
||||
return val.(traits.Sizer).Size()
|
||||
}, traits.SizerType)),
|
||||
|
||||
// Type conversions
|
||||
function(overloads.TypeConvertType,
|
||||
decls.Overload(overloads.TypeConvertType, argTypes(paramA), types.NewTypeTypeWithParam(paramA)),
|
||||
decls.SingletonUnaryBinding(convertToType(types.TypeType))),
|
||||
|
||||
// Bool conversions
|
||||
function(overloads.TypeConvertBool,
|
||||
decls.Overload(overloads.BoolToBool, argTypes(types.BoolType), types.BoolType,
|
||||
decls.UnaryBinding(identity)),
|
||||
decls.Overload(overloads.StringToBool, argTypes(types.StringType), types.BoolType,
|
||||
decls.UnaryBinding(convertToType(types.BoolType)))),
|
||||
|
||||
// Bytes conversions
|
||||
function(overloads.TypeConvertBytes,
|
||||
decls.Overload(overloads.BytesToBytes, argTypes(types.BytesType), types.BytesType,
|
||||
decls.UnaryBinding(identity)),
|
||||
decls.Overload(overloads.StringToBytes, argTypes(types.StringType), types.BytesType,
|
||||
decls.UnaryBinding(convertToType(types.BytesType)))),
|
||||
|
||||
// Double conversions
|
||||
function(overloads.TypeConvertDouble,
|
||||
decls.Overload(overloads.DoubleToDouble, argTypes(types.DoubleType), types.DoubleType,
|
||||
decls.UnaryBinding(identity)),
|
||||
decls.Overload(overloads.IntToDouble, argTypes(types.IntType), types.DoubleType,
|
||||
decls.UnaryBinding(convertToType(types.DoubleType))),
|
||||
decls.Overload(overloads.StringToDouble, argTypes(types.StringType), types.DoubleType,
|
||||
decls.UnaryBinding(convertToType(types.DoubleType))),
|
||||
decls.Overload(overloads.UintToDouble, argTypes(types.UintType), types.DoubleType,
|
||||
decls.UnaryBinding(convertToType(types.DoubleType)))),
|
||||
|
||||
// Duration conversions
|
||||
function(overloads.TypeConvertDuration,
|
||||
decls.Overload(overloads.DurationToDuration, argTypes(types.DurationType), types.DurationType,
|
||||
decls.UnaryBinding(identity)),
|
||||
decls.Overload(overloads.IntToDuration, argTypes(types.IntType), types.DurationType,
|
||||
decls.UnaryBinding(convertToType(types.DurationType))),
|
||||
decls.Overload(overloads.StringToDuration, argTypes(types.StringType), types.DurationType,
|
||||
decls.UnaryBinding(convertToType(types.DurationType)))),
|
||||
|
||||
// Dyn conversions
|
||||
function(overloads.TypeConvertDyn,
|
||||
decls.Overload(overloads.ToDyn, argTypes(paramA), types.DynType),
|
||||
decls.SingletonUnaryBinding(identity)),
|
||||
|
||||
// Int conversions
|
||||
function(overloads.TypeConvertInt,
|
||||
decls.Overload(overloads.IntToInt, argTypes(types.IntType), types.IntType,
|
||||
decls.UnaryBinding(identity)),
|
||||
decls.Overload(overloads.DoubleToInt, argTypes(types.DoubleType), types.IntType,
|
||||
decls.UnaryBinding(convertToType(types.IntType))),
|
||||
decls.Overload(overloads.DurationToInt, argTypes(types.DurationType), types.IntType,
|
||||
decls.UnaryBinding(convertToType(types.IntType))),
|
||||
decls.Overload(overloads.StringToInt, argTypes(types.StringType), types.IntType,
|
||||
decls.UnaryBinding(convertToType(types.IntType))),
|
||||
decls.Overload(overloads.TimestampToInt, argTypes(types.TimestampType), types.IntType,
|
||||
decls.UnaryBinding(convertToType(types.IntType))),
|
||||
decls.Overload(overloads.UintToInt, argTypes(types.UintType), types.IntType,
|
||||
decls.UnaryBinding(convertToType(types.IntType))),
|
||||
),
|
||||
|
||||
// String conversions
|
||||
function(overloads.TypeConvertString,
|
||||
decls.Overload(overloads.StringToString, argTypes(types.StringType), types.StringType,
|
||||
decls.UnaryBinding(identity)),
|
||||
decls.Overload(overloads.BoolToString, argTypes(types.BoolType), types.StringType,
|
||||
decls.UnaryBinding(convertToType(types.StringType))),
|
||||
decls.Overload(overloads.BytesToString, argTypes(types.BytesType), types.StringType,
|
||||
decls.UnaryBinding(convertToType(types.StringType))),
|
||||
decls.Overload(overloads.DoubleToString, argTypes(types.DoubleType), types.StringType,
|
||||
decls.UnaryBinding(convertToType(types.StringType))),
|
||||
decls.Overload(overloads.DurationToString, argTypes(types.DurationType), types.StringType,
|
||||
decls.UnaryBinding(convertToType(types.StringType))),
|
||||
decls.Overload(overloads.IntToString, argTypes(types.IntType), types.StringType,
|
||||
decls.UnaryBinding(convertToType(types.StringType))),
|
||||
decls.Overload(overloads.TimestampToString, argTypes(types.TimestampType), types.StringType,
|
||||
decls.UnaryBinding(convertToType(types.StringType))),
|
||||
decls.Overload(overloads.UintToString, argTypes(types.UintType), types.StringType,
|
||||
decls.UnaryBinding(convertToType(types.StringType)))),
|
||||
|
||||
// Timestamp conversions
|
||||
function(overloads.TypeConvertTimestamp,
|
||||
decls.Overload(overloads.TimestampToTimestamp, argTypes(types.TimestampType), types.TimestampType,
|
||||
decls.UnaryBinding(identity)),
|
||||
decls.Overload(overloads.IntToTimestamp, argTypes(types.IntType), types.TimestampType,
|
||||
decls.UnaryBinding(convertToType(types.TimestampType))),
|
||||
decls.Overload(overloads.StringToTimestamp, argTypes(types.StringType), types.TimestampType,
|
||||
decls.UnaryBinding(convertToType(types.TimestampType)))),
|
||||
|
||||
// Uint conversions
|
||||
function(overloads.TypeConvertUint,
|
||||
decls.Overload(overloads.UintToUint, argTypes(types.UintType), types.UintType,
|
||||
decls.UnaryBinding(identity)),
|
||||
decls.Overload(overloads.DoubleToUint, argTypes(types.DoubleType), types.UintType,
|
||||
decls.UnaryBinding(convertToType(types.UintType))),
|
||||
decls.Overload(overloads.IntToUint, argTypes(types.IntType), types.UintType,
|
||||
decls.UnaryBinding(convertToType(types.UintType))),
|
||||
decls.Overload(overloads.StringToUint, argTypes(types.StringType), types.UintType,
|
||||
decls.UnaryBinding(convertToType(types.UintType)))),
|
||||
|
||||
// String functions
|
||||
function(overloads.Contains,
|
||||
decls.MemberOverload(overloads.ContainsString,
|
||||
argTypes(types.StringType, types.StringType), types.BoolType,
|
||||
decls.BinaryBinding(types.StringContains)),
|
||||
decls.DisableTypeGuards(true)),
|
||||
function(overloads.EndsWith,
|
||||
decls.MemberOverload(overloads.EndsWithString,
|
||||
argTypes(types.StringType, types.StringType), types.BoolType,
|
||||
decls.BinaryBinding(types.StringEndsWith)),
|
||||
decls.DisableTypeGuards(true)),
|
||||
function(overloads.StartsWith,
|
||||
decls.MemberOverload(overloads.StartsWithString,
|
||||
argTypes(types.StringType, types.StringType), types.BoolType,
|
||||
decls.BinaryBinding(types.StringStartsWith)),
|
||||
decls.DisableTypeGuards(true)),
|
||||
function(overloads.Matches,
|
||||
decls.Overload(overloads.Matches, argTypes(types.StringType, types.StringType), types.BoolType),
|
||||
decls.MemberOverload(overloads.MatchesString,
|
||||
argTypes(types.StringType, types.StringType), types.BoolType),
|
||||
decls.SingletonBinaryBinding(func(str, pat ref.Val) ref.Val {
|
||||
return str.(traits.Matcher).Match(pat)
|
||||
}, traits.MatcherType)),
|
||||
|
||||
// Timestamp / duration functions
|
||||
function(overloads.TimeGetFullYear,
|
||||
decls.MemberOverload(overloads.TimestampToYear,
|
||||
argTypes(types.TimestampType), types.IntType),
|
||||
decls.MemberOverload(overloads.TimestampToYearWithTz,
|
||||
argTypes(types.TimestampType, types.StringType), types.IntType)),
|
||||
|
||||
function(overloads.TimeGetMonth,
|
||||
decls.MemberOverload(overloads.TimestampToMonth,
|
||||
argTypes(types.TimestampType), types.IntType),
|
||||
decls.MemberOverload(overloads.TimestampToMonthWithTz,
|
||||
argTypes(types.TimestampType, types.StringType), types.IntType)),
|
||||
|
||||
function(overloads.TimeGetDayOfYear,
|
||||
decls.MemberOverload(overloads.TimestampToDayOfYear,
|
||||
argTypes(types.TimestampType), types.IntType),
|
||||
decls.MemberOverload(overloads.TimestampToDayOfYearWithTz,
|
||||
argTypes(types.TimestampType, types.StringType), types.IntType)),
|
||||
|
||||
function(overloads.TimeGetDayOfMonth,
|
||||
decls.MemberOverload(overloads.TimestampToDayOfMonthZeroBased,
|
||||
argTypes(types.TimestampType), types.IntType),
|
||||
decls.MemberOverload(overloads.TimestampToDayOfMonthZeroBasedWithTz,
|
||||
argTypes(types.TimestampType, types.StringType), types.IntType)),
|
||||
|
||||
function(overloads.TimeGetDate,
|
||||
decls.MemberOverload(overloads.TimestampToDayOfMonthOneBased,
|
||||
argTypes(types.TimestampType), types.IntType),
|
||||
decls.MemberOverload(overloads.TimestampToDayOfMonthOneBasedWithTz,
|
||||
argTypes(types.TimestampType, types.StringType), types.IntType)),
|
||||
|
||||
function(overloads.TimeGetDayOfWeek,
|
||||
decls.MemberOverload(overloads.TimestampToDayOfWeek,
|
||||
argTypes(types.TimestampType), types.IntType),
|
||||
decls.MemberOverload(overloads.TimestampToDayOfWeekWithTz,
|
||||
argTypes(types.TimestampType, types.StringType), types.IntType)),
|
||||
|
||||
function(overloads.TimeGetHours,
|
||||
decls.MemberOverload(overloads.TimestampToHours,
|
||||
argTypes(types.TimestampType), types.IntType),
|
||||
decls.MemberOverload(overloads.TimestampToHoursWithTz,
|
||||
argTypes(types.TimestampType, types.StringType), types.IntType),
|
||||
decls.MemberOverload(overloads.DurationToHours,
|
||||
argTypes(types.DurationType), types.IntType)),
|
||||
|
||||
function(overloads.TimeGetMinutes,
|
||||
decls.MemberOverload(overloads.TimestampToMinutes,
|
||||
argTypes(types.TimestampType), types.IntType),
|
||||
decls.MemberOverload(overloads.TimestampToMinutesWithTz,
|
||||
argTypes(types.TimestampType, types.StringType), types.IntType),
|
||||
decls.MemberOverload(overloads.DurationToMinutes,
|
||||
argTypes(types.DurationType), types.IntType)),
|
||||
|
||||
function(overloads.TimeGetSeconds,
|
||||
decls.MemberOverload(overloads.TimestampToSeconds,
|
||||
argTypes(types.TimestampType), types.IntType),
|
||||
decls.MemberOverload(overloads.TimestampToSecondsWithTz,
|
||||
argTypes(types.TimestampType, types.StringType), types.IntType),
|
||||
decls.MemberOverload(overloads.DurationToSeconds,
|
||||
argTypes(types.DurationType), types.IntType)),
|
||||
|
||||
function(overloads.TimeGetMilliseconds,
|
||||
decls.MemberOverload(overloads.TimestampToMilliseconds,
|
||||
argTypes(types.TimestampType), types.IntType),
|
||||
decls.MemberOverload(overloads.TimestampToMillisecondsWithTz,
|
||||
argTypes(types.TimestampType, types.StringType), types.IntType),
|
||||
decls.MemberOverload(overloads.DurationToMilliseconds,
|
||||
argTypes(types.DurationType), types.IntType)),
|
||||
}
|
||||
|
||||
stdFnDecls = make([]*exprpb.Decl, 0, len(stdFunctions))
|
||||
for _, fn := range stdFunctions {
|
||||
if fn.IsDeclarationDisabled() {
|
||||
continue
|
||||
}
|
||||
ed, err := decls.FunctionDeclToExprDecl(fn)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
stdFnDecls = append(stdFnDecls, ed)
|
||||
}
|
||||
}
|
||||
|
||||
// Functions returns the set of standard library function declarations and definitions for CEL.
|
||||
func Functions() []*decls.FunctionDecl {
|
||||
return stdFunctions
|
||||
}
|
||||
|
||||
// FunctionExprDecls returns the legacy style protobuf-typed declarations for all functions and overloads
|
||||
// in the CEL standard environment.
|
||||
//
|
||||
// Deprecated: use Functions
|
||||
func FunctionExprDecls() []*exprpb.Decl {
|
||||
return stdFnDecls
|
||||
}
|
||||
|
||||
// Types returns the set of standard library types for CEL.
|
||||
func Types() []*decls.VariableDecl {
|
||||
return stdTypes
|
||||
}
|
||||
|
||||
// TypeExprDecls returns the legacy style protobuf-typed declarations for all types in the CEL
|
||||
// standard environment.
|
||||
//
|
||||
// Deprecated: use Types
|
||||
func TypeExprDecls() []*exprpb.Decl {
|
||||
return stdTypeDecls
|
||||
}
|
||||
|
||||
func notStrictlyFalse(value ref.Val) ref.Val {
|
||||
if types.IsBool(value) {
|
||||
return value
|
||||
}
|
||||
return types.True
|
||||
}
|
||||
|
||||
func inAggregate(lhs ref.Val, rhs ref.Val) ref.Val {
|
||||
if rhs.Type().HasTrait(traits.ContainerType) {
|
||||
return rhs.(traits.Container).Contains(lhs)
|
||||
}
|
||||
return types.ValOrErr(rhs, "no such overload")
|
||||
}
|
||||
|
||||
func function(name string, opts ...decls.FunctionOpt) *decls.FunctionDecl {
|
||||
fn, err := decls.NewFunction(name, opts...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return fn
|
||||
}
|
||||
|
||||
func argTypes(args ...*types.Type) []*types.Type {
|
||||
return args
|
||||
}
|
||||
|
||||
func noBinaryOverrides(rhs, lhs ref.Val) ref.Val {
|
||||
return types.NoSuchOverloadErr()
|
||||
}
|
||||
|
||||
func noFunctionOverrides(args ...ref.Val) ref.Val {
|
||||
return types.NoSuchOverloadErr()
|
||||
}
|
||||
|
||||
func identity(val ref.Val) ref.Val {
|
||||
return val
|
||||
}
|
||||
|
||||
func convertToType(t ref.Type) functions.UnaryOp {
|
||||
return func(val ref.Val) ref.Val {
|
||||
return val.ConvertToType(t)
|
||||
}
|
||||
}
|
7
vendor/github.com/google/cel-go/common/types/BUILD.bazel
generated
vendored
7
vendor/github.com/google/cel-go/common/types/BUILD.bazel
generated
vendored
@ -27,20 +27,20 @@ go_library(
|
||||
"provider.go",
|
||||
"string.go",
|
||||
"timestamp.go",
|
||||
"type.go",
|
||||
"types.go",
|
||||
"uint.go",
|
||||
"unknown.go",
|
||||
"util.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/types",
|
||||
deps = [
|
||||
"//checker/decls:go_default_library",
|
||||
"//common/overloads:go_default_library",
|
||||
"//common/types/pb:go_default_library",
|
||||
"//common/types/ref:go_default_library",
|
||||
"//common/types/traits:go_default_library",
|
||||
"@com_github_stoewer_go_strcase//:go_default_library",
|
||||
"@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library",
|
||||
"@org_golang_google_genproto_googleapis_rpc//status:go_default_library",
|
||||
"@org_golang_google_protobuf//encoding/protojson:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
"@org_golang_google_protobuf//reflect/protoreflect:go_default_library",
|
||||
@ -71,8 +71,9 @@ go_test(
|
||||
"provider_test.go",
|
||||
"string_test.go",
|
||||
"timestamp_test.go",
|
||||
"type_test.go",
|
||||
"types_test.go",
|
||||
"uint_test.go",
|
||||
"unknown_test.go",
|
||||
"util_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
|
6
vendor/github.com/google/cel-go/common/types/bool.go
generated
vendored
6
vendor/github.com/google/cel-go/common/types/bool.go
generated
vendored
@ -20,7 +20,6 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
@ -31,11 +30,6 @@ import (
|
||||
type Bool bool
|
||||
|
||||
var (
|
||||
// BoolType singleton.
|
||||
BoolType = NewTypeValue("bool",
|
||||
traits.ComparerType,
|
||||
traits.NegatorType)
|
||||
|
||||
// boolWrapperType golang reflected type for protobuf bool wrapper type.
|
||||
boolWrapperType = reflect.TypeOf(&wrapperspb.BoolValue{})
|
||||
)
|
||||
|
7
vendor/github.com/google/cel-go/common/types/bytes.go
generated
vendored
7
vendor/github.com/google/cel-go/common/types/bytes.go
generated
vendored
@ -22,7 +22,6 @@ import (
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
@ -34,12 +33,6 @@ import (
|
||||
type Bytes []byte
|
||||
|
||||
var (
|
||||
// BytesType singleton.
|
||||
BytesType = NewTypeValue("bytes",
|
||||
traits.AdderType,
|
||||
traits.ComparerType,
|
||||
traits.SizerType)
|
||||
|
||||
// byteWrapperType golang reflected type for protobuf bytes wrapper type.
|
||||
byteWrapperType = reflect.TypeOf(&wrapperspb.BytesValue{})
|
||||
)
|
||||
|
10
vendor/github.com/google/cel-go/common/types/double.go
generated
vendored
10
vendor/github.com/google/cel-go/common/types/double.go
generated
vendored
@ -20,7 +20,6 @@ import (
|
||||
"reflect"
|
||||
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
@ -32,15 +31,6 @@ import (
|
||||
type Double float64
|
||||
|
||||
var (
|
||||
// DoubleType singleton.
|
||||
DoubleType = NewTypeValue("double",
|
||||
traits.AdderType,
|
||||
traits.ComparerType,
|
||||
traits.DividerType,
|
||||
traits.MultiplierType,
|
||||
traits.NegatorType,
|
||||
traits.SubtractorType)
|
||||
|
||||
// doubleWrapperType reflected type for protobuf double wrapper type.
|
||||
doubleWrapperType = reflect.TypeOf(&wrapperspb.DoubleValue{})
|
||||
|
||||
|
68
vendor/github.com/google/cel-go/common/types/duration.go
generated
vendored
68
vendor/github.com/google/cel-go/common/types/duration.go
generated
vendored
@ -22,7 +22,6 @@ import (
|
||||
|
||||
"github.com/google/cel-go/common/overloads"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
dpb "google.golang.org/protobuf/types/known/durationpb"
|
||||
@ -41,13 +40,14 @@ func durationOf(d time.Duration) Duration {
|
||||
}
|
||||
|
||||
var (
|
||||
// DurationType singleton.
|
||||
DurationType = NewTypeValue("google.protobuf.Duration",
|
||||
traits.AdderType,
|
||||
traits.ComparerType,
|
||||
traits.NegatorType,
|
||||
traits.ReceiverType,
|
||||
traits.SubtractorType)
|
||||
durationValueType = reflect.TypeOf(&dpb.Duration{})
|
||||
|
||||
durationZeroArgOverloads = map[string]func(ref.Val) ref.Val{
|
||||
overloads.TimeGetHours: DurationGetHours,
|
||||
overloads.TimeGetMinutes: DurationGetMinutes,
|
||||
overloads.TimeGetSeconds: DurationGetSeconds,
|
||||
overloads.TimeGetMilliseconds: DurationGetMilliseconds,
|
||||
}
|
||||
)
|
||||
|
||||
// Add implements traits.Adder.Add.
|
||||
@ -156,7 +156,7 @@ func (d Duration) Negate() ref.Val {
|
||||
func (d Duration) Receive(function string, overload string, args []ref.Val) ref.Val {
|
||||
if len(args) == 0 {
|
||||
if f, found := durationZeroArgOverloads[function]; found {
|
||||
return f(d.Duration)
|
||||
return f(d)
|
||||
}
|
||||
}
|
||||
return NoSuchOverloadErr()
|
||||
@ -185,20 +185,38 @@ func (d Duration) Value() any {
|
||||
return d.Duration
|
||||
}
|
||||
|
||||
var (
|
||||
durationValueType = reflect.TypeOf(&dpb.Duration{})
|
||||
// DurationGetHours returns the duration in hours.
|
||||
func DurationGetHours(val ref.Val) ref.Val {
|
||||
dur, ok := val.(Duration)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(val)
|
||||
}
|
||||
return Int(dur.Hours())
|
||||
}
|
||||
|
||||
durationZeroArgOverloads = map[string]func(time.Duration) ref.Val{
|
||||
overloads.TimeGetHours: func(dur time.Duration) ref.Val {
|
||||
return Int(dur.Hours())
|
||||
},
|
||||
overloads.TimeGetMinutes: func(dur time.Duration) ref.Val {
|
||||
return Int(dur.Minutes())
|
||||
},
|
||||
overloads.TimeGetSeconds: func(dur time.Duration) ref.Val {
|
||||
return Int(dur.Seconds())
|
||||
},
|
||||
overloads.TimeGetMilliseconds: func(dur time.Duration) ref.Val {
|
||||
return Int(dur.Milliseconds())
|
||||
}}
|
||||
)
|
||||
// DurationGetMinutes returns duration in minutes.
|
||||
func DurationGetMinutes(val ref.Val) ref.Val {
|
||||
dur, ok := val.(Duration)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(val)
|
||||
}
|
||||
return Int(dur.Minutes())
|
||||
}
|
||||
|
||||
// DurationGetSeconds returns duration in seconds.
|
||||
func DurationGetSeconds(val ref.Val) ref.Val {
|
||||
dur, ok := val.(Duration)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(val)
|
||||
}
|
||||
return Int(dur.Seconds())
|
||||
}
|
||||
|
||||
// DurationGetMilliseconds returns duration in milliseconds.
|
||||
func DurationGetMilliseconds(val ref.Val) ref.Val {
|
||||
dur, ok := val.(Duration)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(val)
|
||||
}
|
||||
return Int(dur.Milliseconds())
|
||||
}
|
||||
|
7
vendor/github.com/google/cel-go/common/types/err.go
generated
vendored
7
vendor/github.com/google/cel-go/common/types/err.go
generated
vendored
@ -35,7 +35,7 @@ type Err struct {
|
||||
|
||||
var (
|
||||
// ErrType singleton.
|
||||
ErrType = NewTypeValue("error")
|
||||
ErrType = NewOpaqueType("error")
|
||||
|
||||
// errDivideByZero is an error indicating a division by zero of an integer value.
|
||||
errDivideByZero = errors.New("division by zero")
|
||||
@ -129,6 +129,11 @@ func (e *Err) Is(target error) bool {
|
||||
return e.error.Error() == target.Error()
|
||||
}
|
||||
|
||||
// Unwrap implements errors.Unwrap.
|
||||
func (e *Err) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// IsError returns whether the input element ref.Type or ref.Val is equal to
|
||||
// the ErrType singleton.
|
||||
func IsError(val ref.Val) bool {
|
||||
|
11
vendor/github.com/google/cel-go/common/types/int.go
generated
vendored
11
vendor/github.com/google/cel-go/common/types/int.go
generated
vendored
@ -22,7 +22,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
@ -41,16 +40,6 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
// IntType singleton.
|
||||
IntType = NewTypeValue("int",
|
||||
traits.AdderType,
|
||||
traits.ComparerType,
|
||||
traits.DividerType,
|
||||
traits.ModderType,
|
||||
traits.MultiplierType,
|
||||
traits.NegatorType,
|
||||
traits.SubtractorType)
|
||||
|
||||
// int32WrapperType reflected type for protobuf int32 wrapper type.
|
||||
int32WrapperType = reflect.TypeOf(&wrapperspb.Int32Value{})
|
||||
|
||||
|
2
vendor/github.com/google/cel-go/common/types/iterator.go
generated
vendored
2
vendor/github.com/google/cel-go/common/types/iterator.go
generated
vendored
@ -24,7 +24,7 @@ import (
|
||||
|
||||
var (
|
||||
// IteratorType singleton.
|
||||
IteratorType = NewTypeValue("iterator", traits.IteratorType)
|
||||
IteratorType = NewObjectType("iterator", traits.IteratorType)
|
||||
)
|
||||
|
||||
// baseIterator is the basis for list, map, and object iterators.
|
||||
|
90
vendor/github.com/google/cel-go/common/types/list.go
generated
vendored
90
vendor/github.com/google/cel-go/common/types/list.go
generated
vendored
@ -29,25 +29,15 @@ import (
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
var (
|
||||
// ListType singleton.
|
||||
ListType = NewTypeValue("list",
|
||||
traits.AdderType,
|
||||
traits.ContainerType,
|
||||
traits.IndexerType,
|
||||
traits.IterableType,
|
||||
traits.SizerType)
|
||||
)
|
||||
|
||||
// NewDynamicList returns a traits.Lister with heterogenous elements.
|
||||
// value should be an array of "native" types, i.e. any type that
|
||||
// NativeToValue() can convert to a ref.Val.
|
||||
func NewDynamicList(adapter ref.TypeAdapter, value any) traits.Lister {
|
||||
func NewDynamicList(adapter Adapter, value any) traits.Lister {
|
||||
refValue := reflect.ValueOf(value)
|
||||
return &baseList{
|
||||
TypeAdapter: adapter,
|
||||
value: value,
|
||||
size: refValue.Len(),
|
||||
Adapter: adapter,
|
||||
value: value,
|
||||
size: refValue.Len(),
|
||||
get: func(i int) any {
|
||||
return refValue.Index(i).Interface()
|
||||
},
|
||||
@ -55,56 +45,56 @@ func NewDynamicList(adapter ref.TypeAdapter, value any) traits.Lister {
|
||||
}
|
||||
|
||||
// NewStringList returns a traits.Lister containing only strings.
|
||||
func NewStringList(adapter ref.TypeAdapter, elems []string) traits.Lister {
|
||||
func NewStringList(adapter Adapter, elems []string) traits.Lister {
|
||||
return &baseList{
|
||||
TypeAdapter: adapter,
|
||||
value: elems,
|
||||
size: len(elems),
|
||||
get: func(i int) any { return elems[i] },
|
||||
Adapter: adapter,
|
||||
value: elems,
|
||||
size: len(elems),
|
||||
get: func(i int) any { return elems[i] },
|
||||
}
|
||||
}
|
||||
|
||||
// NewRefValList returns a traits.Lister with ref.Val elements.
|
||||
//
|
||||
// This type specialization is used with list literals within CEL expressions.
|
||||
func NewRefValList(adapter ref.TypeAdapter, elems []ref.Val) traits.Lister {
|
||||
func NewRefValList(adapter Adapter, elems []ref.Val) traits.Lister {
|
||||
return &baseList{
|
||||
TypeAdapter: adapter,
|
||||
value: elems,
|
||||
size: len(elems),
|
||||
get: func(i int) any { return elems[i] },
|
||||
Adapter: adapter,
|
||||
value: elems,
|
||||
size: len(elems),
|
||||
get: func(i int) any { return elems[i] },
|
||||
}
|
||||
}
|
||||
|
||||
// NewProtoList returns a traits.Lister based on a pb.List instance.
|
||||
func NewProtoList(adapter ref.TypeAdapter, list protoreflect.List) traits.Lister {
|
||||
func NewProtoList(adapter Adapter, list protoreflect.List) traits.Lister {
|
||||
return &baseList{
|
||||
TypeAdapter: adapter,
|
||||
value: list,
|
||||
size: list.Len(),
|
||||
get: func(i int) any { return list.Get(i).Interface() },
|
||||
Adapter: adapter,
|
||||
value: list,
|
||||
size: list.Len(),
|
||||
get: func(i int) any { return list.Get(i).Interface() },
|
||||
}
|
||||
}
|
||||
|
||||
// NewJSONList returns a traits.Lister based on structpb.ListValue instance.
|
||||
func NewJSONList(adapter ref.TypeAdapter, l *structpb.ListValue) traits.Lister {
|
||||
func NewJSONList(adapter Adapter, l *structpb.ListValue) traits.Lister {
|
||||
vals := l.GetValues()
|
||||
return &baseList{
|
||||
TypeAdapter: adapter,
|
||||
value: l,
|
||||
size: len(vals),
|
||||
get: func(i int) any { return vals[i] },
|
||||
Adapter: adapter,
|
||||
value: l,
|
||||
size: len(vals),
|
||||
get: func(i int) any { return vals[i] },
|
||||
}
|
||||
}
|
||||
|
||||
// NewMutableList creates a new mutable list whose internal state can be modified.
|
||||
func NewMutableList(adapter ref.TypeAdapter) traits.MutableLister {
|
||||
func NewMutableList(adapter Adapter) traits.MutableLister {
|
||||
var mutableValues []ref.Val
|
||||
l := &mutableList{
|
||||
baseList: &baseList{
|
||||
TypeAdapter: adapter,
|
||||
value: mutableValues,
|
||||
size: 0,
|
||||
Adapter: adapter,
|
||||
value: mutableValues,
|
||||
size: 0,
|
||||
},
|
||||
mutableValues: mutableValues,
|
||||
}
|
||||
@ -116,9 +106,9 @@ func NewMutableList(adapter ref.TypeAdapter) traits.MutableLister {
|
||||
|
||||
// baseList points to a list containing elements of any type.
|
||||
// The `value` is an array of native values, and refValue is its reflection object.
|
||||
// The `ref.TypeAdapter` enables native type to CEL type conversions.
|
||||
// The `Adapter` enables native type to CEL type conversions.
|
||||
type baseList struct {
|
||||
ref.TypeAdapter
|
||||
Adapter
|
||||
value any
|
||||
|
||||
// size indicates the number of elements within the list.
|
||||
@ -143,9 +133,9 @@ func (l *baseList) Add(other ref.Val) ref.Val {
|
||||
return l
|
||||
}
|
||||
return &concatList{
|
||||
TypeAdapter: l.TypeAdapter,
|
||||
prevList: l,
|
||||
nextList: otherList}
|
||||
Adapter: l.Adapter,
|
||||
prevList: l,
|
||||
nextList: otherList}
|
||||
}
|
||||
|
||||
// Contains implements the traits.Container interface method.
|
||||
@ -322,13 +312,13 @@ func (l *mutableList) Add(other ref.Val) ref.Val {
|
||||
func (l *mutableList) ToImmutableList() traits.Lister {
|
||||
// The reference to internal state is guaranteed to be safe as this call is only performed
|
||||
// when mutations have been completed.
|
||||
return NewRefValList(l.TypeAdapter, l.mutableValues)
|
||||
return NewRefValList(l.Adapter, l.mutableValues)
|
||||
}
|
||||
|
||||
// concatList combines two list implementations together into a view.
|
||||
// The `ref.TypeAdapter` enables native type to CEL type conversions.
|
||||
// The `Adapter` enables native type to CEL type conversions.
|
||||
type concatList struct {
|
||||
ref.TypeAdapter
|
||||
Adapter
|
||||
value any
|
||||
prevList traits.Lister
|
||||
nextList traits.Lister
|
||||
@ -347,9 +337,9 @@ func (l *concatList) Add(other ref.Val) ref.Val {
|
||||
return l
|
||||
}
|
||||
return &concatList{
|
||||
TypeAdapter: l.TypeAdapter,
|
||||
prevList: l,
|
||||
nextList: otherList}
|
||||
Adapter: l.Adapter,
|
||||
prevList: l,
|
||||
nextList: otherList}
|
||||
}
|
||||
|
||||
// Contains implements the traits.Container interface method.
|
||||
@ -376,7 +366,7 @@ func (l *concatList) Contains(elem ref.Val) ref.Val {
|
||||
|
||||
// ConvertToNative implements the ref.Val interface method.
|
||||
func (l *concatList) ConvertToNative(typeDesc reflect.Type) (any, error) {
|
||||
combined := NewDynamicList(l.TypeAdapter, l.Value().([]any))
|
||||
combined := NewDynamicList(l.Adapter, l.Value().([]any))
|
||||
return combined.ConvertToNative(typeDesc)
|
||||
}
|
||||
|
||||
|
87
vendor/github.com/google/cel-go/common/types/map.go
generated
vendored
87
vendor/github.com/google/cel-go/common/types/map.go
generated
vendored
@ -32,10 +32,10 @@ import (
|
||||
)
|
||||
|
||||
// NewDynamicMap returns a traits.Mapper value with dynamic key, value pairs.
|
||||
func NewDynamicMap(adapter ref.TypeAdapter, value any) traits.Mapper {
|
||||
func NewDynamicMap(adapter Adapter, value any) traits.Mapper {
|
||||
refValue := reflect.ValueOf(value)
|
||||
return &baseMap{
|
||||
TypeAdapter: adapter,
|
||||
Adapter: adapter,
|
||||
mapAccessor: newReflectMapAccessor(adapter, refValue),
|
||||
value: value,
|
||||
size: refValue.Len(),
|
||||
@ -46,10 +46,10 @@ func NewDynamicMap(adapter ref.TypeAdapter, value any) traits.Mapper {
|
||||
// encoded in protocol buffer form.
|
||||
//
|
||||
// The `adapter` argument provides type adaptation capabilities from proto to CEL.
|
||||
func NewJSONStruct(adapter ref.TypeAdapter, value *structpb.Struct) traits.Mapper {
|
||||
func NewJSONStruct(adapter Adapter, value *structpb.Struct) traits.Mapper {
|
||||
fields := value.GetFields()
|
||||
return &baseMap{
|
||||
TypeAdapter: adapter,
|
||||
Adapter: adapter,
|
||||
mapAccessor: newJSONStructAccessor(adapter, fields),
|
||||
value: value,
|
||||
size: len(fields),
|
||||
@ -57,9 +57,9 @@ func NewJSONStruct(adapter ref.TypeAdapter, value *structpb.Struct) traits.Mappe
|
||||
}
|
||||
|
||||
// NewRefValMap returns a specialized traits.Mapper with CEL valued keys and values.
|
||||
func NewRefValMap(adapter ref.TypeAdapter, value map[ref.Val]ref.Val) traits.Mapper {
|
||||
func NewRefValMap(adapter Adapter, value map[ref.Val]ref.Val) traits.Mapper {
|
||||
return &baseMap{
|
||||
TypeAdapter: adapter,
|
||||
Adapter: adapter,
|
||||
mapAccessor: newRefValMapAccessor(value),
|
||||
value: value,
|
||||
size: len(value),
|
||||
@ -67,9 +67,9 @@ func NewRefValMap(adapter ref.TypeAdapter, value map[ref.Val]ref.Val) traits.Map
|
||||
}
|
||||
|
||||
// NewStringInterfaceMap returns a specialized traits.Mapper with string keys and interface values.
|
||||
func NewStringInterfaceMap(adapter ref.TypeAdapter, value map[string]any) traits.Mapper {
|
||||
func NewStringInterfaceMap(adapter Adapter, value map[string]any) traits.Mapper {
|
||||
return &baseMap{
|
||||
TypeAdapter: adapter,
|
||||
Adapter: adapter,
|
||||
mapAccessor: newStringIfaceMapAccessor(adapter, value),
|
||||
value: value,
|
||||
size: len(value),
|
||||
@ -77,9 +77,9 @@ func NewStringInterfaceMap(adapter ref.TypeAdapter, value map[string]any) traits
|
||||
}
|
||||
|
||||
// NewStringStringMap returns a specialized traits.Mapper with string keys and values.
|
||||
func NewStringStringMap(adapter ref.TypeAdapter, value map[string]string) traits.Mapper {
|
||||
func NewStringStringMap(adapter Adapter, value map[string]string) traits.Mapper {
|
||||
return &baseMap{
|
||||
TypeAdapter: adapter,
|
||||
Adapter: adapter,
|
||||
mapAccessor: newStringMapAccessor(value),
|
||||
value: value,
|
||||
size: len(value),
|
||||
@ -87,22 +87,13 @@ func NewStringStringMap(adapter ref.TypeAdapter, value map[string]string) traits
|
||||
}
|
||||
|
||||
// NewProtoMap returns a specialized traits.Mapper for handling protobuf map values.
|
||||
func NewProtoMap(adapter ref.TypeAdapter, value *pb.Map) traits.Mapper {
|
||||
func NewProtoMap(adapter Adapter, value *pb.Map) traits.Mapper {
|
||||
return &protoMap{
|
||||
TypeAdapter: adapter,
|
||||
value: value,
|
||||
Adapter: adapter,
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// MapType singleton.
|
||||
MapType = NewTypeValue("map",
|
||||
traits.ContainerType,
|
||||
traits.IndexerType,
|
||||
traits.IterableType,
|
||||
traits.SizerType)
|
||||
)
|
||||
|
||||
// mapAccessor is a private interface for finding values within a map and iterating over the keys.
|
||||
// This interface implements portions of the API surface area required by the traits.Mapper
|
||||
// interface.
|
||||
@ -121,7 +112,7 @@ type mapAccessor interface {
|
||||
// Since CEL is side-effect free, the base map represents an immutable object.
|
||||
type baseMap struct {
|
||||
// TypeAdapter used to convert keys and values accessed within the map.
|
||||
ref.TypeAdapter
|
||||
Adapter
|
||||
|
||||
// mapAccessor interface implementation used to find and iterate over map keys.
|
||||
mapAccessor
|
||||
@ -316,15 +307,15 @@ func (m *baseMap) Value() any {
|
||||
return m.value
|
||||
}
|
||||
|
||||
func newJSONStructAccessor(adapter ref.TypeAdapter, st map[string]*structpb.Value) mapAccessor {
|
||||
func newJSONStructAccessor(adapter Adapter, st map[string]*structpb.Value) mapAccessor {
|
||||
return &jsonStructAccessor{
|
||||
TypeAdapter: adapter,
|
||||
st: st,
|
||||
Adapter: adapter,
|
||||
st: st,
|
||||
}
|
||||
}
|
||||
|
||||
type jsonStructAccessor struct {
|
||||
ref.TypeAdapter
|
||||
Adapter
|
||||
st map[string]*structpb.Value
|
||||
}
|
||||
|
||||
@ -359,17 +350,17 @@ func (a *jsonStructAccessor) Iterator() traits.Iterator {
|
||||
}
|
||||
}
|
||||
|
||||
func newReflectMapAccessor(adapter ref.TypeAdapter, value reflect.Value) mapAccessor {
|
||||
func newReflectMapAccessor(adapter Adapter, value reflect.Value) mapAccessor {
|
||||
keyType := value.Type().Key()
|
||||
return &reflectMapAccessor{
|
||||
TypeAdapter: adapter,
|
||||
refValue: value,
|
||||
keyType: keyType,
|
||||
Adapter: adapter,
|
||||
refValue: value,
|
||||
keyType: keyType,
|
||||
}
|
||||
}
|
||||
|
||||
type reflectMapAccessor struct {
|
||||
ref.TypeAdapter
|
||||
Adapter
|
||||
refValue reflect.Value
|
||||
keyType reflect.Type
|
||||
}
|
||||
@ -427,9 +418,9 @@ func (m *reflectMapAccessor) findInternal(key ref.Val) (ref.Val, bool) {
|
||||
// Iterator creates a Golang reflection based traits.Iterator.
|
||||
func (m *reflectMapAccessor) Iterator() traits.Iterator {
|
||||
return &mapIterator{
|
||||
TypeAdapter: m.TypeAdapter,
|
||||
mapKeys: m.refValue.MapRange(),
|
||||
len: m.refValue.Len(),
|
||||
Adapter: m.Adapter,
|
||||
mapKeys: m.refValue.MapRange(),
|
||||
len: m.refValue.Len(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,9 +471,9 @@ func (a *refValMapAccessor) Find(key ref.Val) (ref.Val, bool) {
|
||||
// Iterator produces a new traits.Iterator which iterates over the map keys via Golang reflection.
|
||||
func (a *refValMapAccessor) Iterator() traits.Iterator {
|
||||
return &mapIterator{
|
||||
TypeAdapter: DefaultTypeAdapter,
|
||||
mapKeys: reflect.ValueOf(a.mapVal).MapRange(),
|
||||
len: len(a.mapVal),
|
||||
Adapter: DefaultTypeAdapter,
|
||||
mapKeys: reflect.ValueOf(a.mapVal).MapRange(),
|
||||
len: len(a.mapVal),
|
||||
}
|
||||
}
|
||||
|
||||
@ -524,15 +515,15 @@ func (a *stringMapAccessor) Iterator() traits.Iterator {
|
||||
}
|
||||
}
|
||||
|
||||
func newStringIfaceMapAccessor(adapter ref.TypeAdapter, mapVal map[string]any) mapAccessor {
|
||||
func newStringIfaceMapAccessor(adapter Adapter, mapVal map[string]any) mapAccessor {
|
||||
return &stringIfaceMapAccessor{
|
||||
TypeAdapter: adapter,
|
||||
mapVal: mapVal,
|
||||
Adapter: adapter,
|
||||
mapVal: mapVal,
|
||||
}
|
||||
}
|
||||
|
||||
type stringIfaceMapAccessor struct {
|
||||
ref.TypeAdapter
|
||||
Adapter
|
||||
mapVal map[string]any
|
||||
}
|
||||
|
||||
@ -569,7 +560,7 @@ func (a *stringIfaceMapAccessor) Iterator() traits.Iterator {
|
||||
// protoMap is a specialized, separate implementation of the traits.Mapper interfaces tailored to
|
||||
// accessing protoreflect.Map values.
|
||||
type protoMap struct {
|
||||
ref.TypeAdapter
|
||||
Adapter
|
||||
value *pb.Map
|
||||
}
|
||||
|
||||
@ -772,9 +763,9 @@ func (m *protoMap) Iterator() traits.Iterator {
|
||||
return true
|
||||
})
|
||||
return &protoMapIterator{
|
||||
TypeAdapter: m.TypeAdapter,
|
||||
mapKeys: mapKeys,
|
||||
len: m.value.Len(),
|
||||
Adapter: m.Adapter,
|
||||
mapKeys: mapKeys,
|
||||
len: m.value.Len(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -795,7 +786,7 @@ func (m *protoMap) Value() any {
|
||||
|
||||
type mapIterator struct {
|
||||
*baseIterator
|
||||
ref.TypeAdapter
|
||||
Adapter
|
||||
mapKeys *reflect.MapIter
|
||||
cursor int
|
||||
len int
|
||||
@ -818,7 +809,7 @@ func (it *mapIterator) Next() ref.Val {
|
||||
|
||||
type protoMapIterator struct {
|
||||
*baseIterator
|
||||
ref.TypeAdapter
|
||||
Adapter
|
||||
mapKeys []protoreflect.MapKey
|
||||
cursor int
|
||||
len int
|
||||
|
2
vendor/github.com/google/cel-go/common/types/null.go
generated
vendored
2
vendor/github.com/google/cel-go/common/types/null.go
generated
vendored
@ -30,8 +30,6 @@ import (
|
||||
type Null structpb.NullValue
|
||||
|
||||
var (
|
||||
// NullType singleton.
|
||||
NullType = NewTypeValue("null_type")
|
||||
// NullValue singleton.
|
||||
NullValue = Null(structpb.NullValue_NULL_VALUE)
|
||||
|
||||
|
18
vendor/github.com/google/cel-go/common/types/object.go
generated
vendored
18
vendor/github.com/google/cel-go/common/types/object.go
generated
vendored
@ -29,10 +29,10 @@ import (
|
||||
)
|
||||
|
||||
type protoObj struct {
|
||||
ref.TypeAdapter
|
||||
Adapter
|
||||
value proto.Message
|
||||
typeDesc *pb.TypeDescription
|
||||
typeValue *TypeValue
|
||||
typeValue ref.Val
|
||||
}
|
||||
|
||||
// NewObject returns an object based on a proto.Message value which handles
|
||||
@ -42,15 +42,15 @@ type protoObj struct {
|
||||
// Note: the type value is pulled from the list of registered types within the
|
||||
// type provider. If the proto type is not registered within the type provider,
|
||||
// then this will result in an error within the type adapter / provider.
|
||||
func NewObject(adapter ref.TypeAdapter,
|
||||
func NewObject(adapter Adapter,
|
||||
typeDesc *pb.TypeDescription,
|
||||
typeValue *TypeValue,
|
||||
typeValue ref.Val,
|
||||
value proto.Message) ref.Val {
|
||||
return &protoObj{
|
||||
TypeAdapter: adapter,
|
||||
value: value,
|
||||
typeDesc: typeDesc,
|
||||
typeValue: typeValue}
|
||||
Adapter: adapter,
|
||||
value: value,
|
||||
typeDesc: typeDesc,
|
||||
typeValue: typeValue}
|
||||
}
|
||||
|
||||
func (o *protoObj) ConvertToNative(typeDesc reflect.Type) (any, error) {
|
||||
@ -157,7 +157,7 @@ func (o *protoObj) Get(index ref.Val) ref.Val {
|
||||
}
|
||||
|
||||
func (o *protoObj) Type() ref.Type {
|
||||
return o.typeValue
|
||||
return o.typeValue.(ref.Type)
|
||||
}
|
||||
|
||||
func (o *protoObj) Value() any {
|
||||
|
2
vendor/github.com/google/cel-go/common/types/optional.go
generated
vendored
2
vendor/github.com/google/cel-go/common/types/optional.go
generated
vendored
@ -24,7 +24,7 @@ import (
|
||||
|
||||
var (
|
||||
// OptionalType indicates the runtime type of an optional value.
|
||||
OptionalType = NewTypeValue("optional")
|
||||
OptionalType = NewOpaqueType("optional")
|
||||
|
||||
// OptionalNone is a sentinel value which is used to indicate an empty optional value.
|
||||
OptionalNone = &Optional{}
|
||||
|
23
vendor/github.com/google/cel-go/common/types/pb/type.go
generated
vendored
23
vendor/github.com/google/cel-go/common/types/pb/type.go
generated
vendored
@ -285,7 +285,7 @@ func (fd *FieldDescription) GetFrom(target any) (any, error) {
|
||||
|
||||
// IsEnum returns true if the field type refers to an enum value.
|
||||
func (fd *FieldDescription) IsEnum() bool {
|
||||
return fd.desc.Kind() == protoreflect.EnumKind
|
||||
return fd.ProtoKind() == protoreflect.EnumKind
|
||||
}
|
||||
|
||||
// IsMap returns true if the field is of map type.
|
||||
@ -295,7 +295,7 @@ func (fd *FieldDescription) IsMap() bool {
|
||||
|
||||
// IsMessage returns true if the field is of message type.
|
||||
func (fd *FieldDescription) IsMessage() bool {
|
||||
kind := fd.desc.Kind()
|
||||
kind := fd.ProtoKind()
|
||||
return kind == protoreflect.MessageKind || kind == protoreflect.GroupKind
|
||||
}
|
||||
|
||||
@ -326,6 +326,11 @@ func (fd *FieldDescription) Name() string {
|
||||
return string(fd.desc.Name())
|
||||
}
|
||||
|
||||
// ProtoKind returns the protobuf reflected kind of the field.
|
||||
func (fd *FieldDescription) ProtoKind() protoreflect.Kind {
|
||||
return fd.desc.Kind()
|
||||
}
|
||||
|
||||
// ReflectType returns the Golang reflect.Type for this field.
|
||||
func (fd *FieldDescription) ReflectType() reflect.Type {
|
||||
return fd.reflectType
|
||||
@ -345,17 +350,17 @@ func (fd *FieldDescription) Zero() proto.Message {
|
||||
}
|
||||
|
||||
func (fd *FieldDescription) typeDefToType() *exprpb.Type {
|
||||
if fd.desc.Kind() == protoreflect.MessageKind || fd.desc.Kind() == protoreflect.GroupKind {
|
||||
if fd.IsMessage() {
|
||||
msgType := string(fd.desc.Message().FullName())
|
||||
if wk, found := CheckedWellKnowns[msgType]; found {
|
||||
return wk
|
||||
}
|
||||
return checkedMessageType(msgType)
|
||||
}
|
||||
if fd.desc.Kind() == protoreflect.EnumKind {
|
||||
if fd.IsEnum() {
|
||||
return checkedInt
|
||||
}
|
||||
return CheckedPrimitives[fd.desc.Kind()]
|
||||
return CheckedPrimitives[fd.ProtoKind()]
|
||||
}
|
||||
|
||||
// Map wraps the protoreflect.Map object with a key and value FieldDescription for use in
|
||||
@ -463,13 +468,13 @@ func unwrapDynamic(desc description, refMsg protoreflect.Message) (any, bool, er
|
||||
unwrappedAny := &anypb.Any{}
|
||||
err := Merge(unwrappedAny, msg)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
return nil, false, fmt.Errorf("unwrap dynamic field failed: %v", err)
|
||||
}
|
||||
dynMsg, err := unwrappedAny.UnmarshalNew()
|
||||
if err != nil {
|
||||
// Allow the error to move further up the stack as it should result in an type
|
||||
// conversion error if the caller does not recover it somehow.
|
||||
return nil, false, err
|
||||
return nil, false, fmt.Errorf("unmarshal dynamic any failed: %v", err)
|
||||
}
|
||||
// Attempt to unwrap the dynamic type, otherwise return the dynamic message.
|
||||
unwrapped, nested, err := unwrapDynamic(desc, dynMsg.ProtoReflect())
|
||||
@ -560,8 +565,10 @@ func zeroValueOf(msg proto.Message) proto.Message {
|
||||
}
|
||||
|
||||
var (
|
||||
jsonValueTypeURL = "types.googleapis.com/google.protobuf.Value"
|
||||
|
||||
zeroValueMap = map[string]proto.Message{
|
||||
"google.protobuf.Any": &anypb.Any{},
|
||||
"google.protobuf.Any": &anypb.Any{TypeUrl: jsonValueTypeURL},
|
||||
"google.protobuf.Duration": &dpb.Duration{},
|
||||
"google.protobuf.ListValue": &structpb.ListValue{},
|
||||
"google.protobuf.Struct": &structpb.Struct{},
|
||||
|
244
vendor/github.com/google/cel-go/common/types/provider.go
generated
vendored
244
vendor/github.com/google/cel-go/common/types/provider.go
generated
vendored
@ -33,17 +33,64 @@ import (
|
||||
tpb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
type protoTypeRegistry struct {
|
||||
revTypeMap map[string]ref.Type
|
||||
// Adapter converts native Go values of varying type and complexity to equivalent CEL values.
|
||||
type Adapter = ref.TypeAdapter
|
||||
|
||||
// Provider specifies functions for creating new object instances and for resolving
|
||||
// enum values by name.
|
||||
type Provider interface {
|
||||
// EnumValue returns the numeric value of the given enum value name.
|
||||
EnumValue(enumName string) ref.Val
|
||||
|
||||
// FindIdent takes a qualified identifier name and returns a ref.Val if one exists.
|
||||
FindIdent(identName string) (ref.Val, bool)
|
||||
|
||||
// FindStructType returns the Type give a qualified type name.
|
||||
//
|
||||
// For historical reasons, only struct types are expected to be returned through this
|
||||
// method, and the type values are expected to be wrapped in a TypeType instance using
|
||||
// TypeTypeWithParam(<structType>).
|
||||
//
|
||||
// Returns false if not found.
|
||||
FindStructType(structType string) (*Type, bool)
|
||||
|
||||
// FieldStructFieldType returns the field type for a checked type value. Returns
|
||||
// false if the field could not be found.
|
||||
FindStructFieldType(structType, fieldName string) (*FieldType, bool)
|
||||
|
||||
// NewValue creates a new type value from a qualified name and map of field
|
||||
// name to value.
|
||||
//
|
||||
// Note, for each value, the Val.ConvertToNative function will be invoked
|
||||
// to convert the Val to the field's native type. If an error occurs during
|
||||
// conversion, the NewValue will be a types.Err.
|
||||
NewValue(structType string, fields map[string]ref.Val) ref.Val
|
||||
}
|
||||
|
||||
// FieldType represents a field's type value and whether that field supports presence detection.
|
||||
type FieldType struct {
|
||||
// Type of the field as a CEL native type value.
|
||||
Type *Type
|
||||
|
||||
// IsSet indicates whether the field is set on an input object.
|
||||
IsSet ref.FieldTester
|
||||
|
||||
// GetFrom retrieves the field value on the input object, if set.
|
||||
GetFrom ref.FieldGetter
|
||||
}
|
||||
|
||||
// Registry provides type information for a set of registered types.
|
||||
type Registry struct {
|
||||
revTypeMap map[string]*Type
|
||||
pbdb *pb.Db
|
||||
}
|
||||
|
||||
// NewRegistry accepts a list of proto message instances and returns a type
|
||||
// provider which can create new instances of the provided message or any
|
||||
// message that proto depends upon in its FileDescriptor.
|
||||
func NewRegistry(types ...proto.Message) (ref.TypeRegistry, error) {
|
||||
p := &protoTypeRegistry{
|
||||
revTypeMap: make(map[string]ref.Type),
|
||||
func NewRegistry(types ...proto.Message) (*Registry, error) {
|
||||
p := &Registry{
|
||||
revTypeMap: make(map[string]*Type),
|
||||
pbdb: pb.NewDb(),
|
||||
}
|
||||
err := p.RegisterType(
|
||||
@ -79,18 +126,17 @@ func NewRegistry(types ...proto.Message) (ref.TypeRegistry, error) {
|
||||
}
|
||||
|
||||
// NewEmptyRegistry returns a registry which is completely unconfigured.
|
||||
func NewEmptyRegistry() ref.TypeRegistry {
|
||||
return &protoTypeRegistry{
|
||||
revTypeMap: make(map[string]ref.Type),
|
||||
func NewEmptyRegistry() *Registry {
|
||||
return &Registry{
|
||||
revTypeMap: make(map[string]*Type),
|
||||
pbdb: pb.NewDb(),
|
||||
}
|
||||
}
|
||||
|
||||
// Copy implements the ref.TypeRegistry interface method which copies the current state of the
|
||||
// registry into its own memory space.
|
||||
func (p *protoTypeRegistry) Copy() ref.TypeRegistry {
|
||||
copy := &protoTypeRegistry{
|
||||
revTypeMap: make(map[string]ref.Type),
|
||||
// Copy copies the current state of the registry into its own memory space.
|
||||
func (p *Registry) Copy() *Registry {
|
||||
copy := &Registry{
|
||||
revTypeMap: make(map[string]*Type),
|
||||
pbdb: p.pbdb.Copy(),
|
||||
}
|
||||
for k, v := range p.revTypeMap {
|
||||
@ -99,7 +145,8 @@ func (p *protoTypeRegistry) Copy() ref.TypeRegistry {
|
||||
return copy
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) EnumValue(enumName string) ref.Val {
|
||||
// EnumValue returns the numeric value of the given enum value name.
|
||||
func (p *Registry) EnumValue(enumName string) ref.Val {
|
||||
enumVal, found := p.pbdb.DescribeEnum(enumName)
|
||||
if !found {
|
||||
return NewErr("unknown enum name '%s'", enumName)
|
||||
@ -107,9 +154,12 @@ func (p *protoTypeRegistry) EnumValue(enumName string) ref.Val {
|
||||
return Int(enumVal.Value())
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) FindFieldType(messageType string,
|
||||
fieldName string) (*ref.FieldType, bool) {
|
||||
msgType, found := p.pbdb.DescribeType(messageType)
|
||||
// FieldFieldType returns the field type for a checked type value. Returns false if
|
||||
// the field could not be found.
|
||||
//
|
||||
// Deprecated: use FindStructFieldType
|
||||
func (p *Registry) FindFieldType(structType, fieldName string) (*ref.FieldType, bool) {
|
||||
msgType, found := p.pbdb.DescribeType(structType)
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
@ -118,15 +168,32 @@ func (p *protoTypeRegistry) FindFieldType(messageType string,
|
||||
return nil, false
|
||||
}
|
||||
return &ref.FieldType{
|
||||
Type: field.CheckedType(),
|
||||
IsSet: field.IsSet,
|
||||
GetFrom: field.GetFrom},
|
||||
true
|
||||
Type: field.CheckedType(),
|
||||
IsSet: field.IsSet,
|
||||
GetFrom: field.GetFrom}, true
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) FindIdent(identName string) (ref.Val, bool) {
|
||||
// FieldStructFieldType returns the field type for a checked type value. Returns
|
||||
// false if the field could not be found.
|
||||
func (p *Registry) FindStructFieldType(structType, fieldName string) (*FieldType, bool) {
|
||||
msgType, found := p.pbdb.DescribeType(structType)
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
field, found := msgType.FieldByName(fieldName)
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
return &FieldType{
|
||||
Type: fieldDescToCELType(field),
|
||||
IsSet: field.IsSet,
|
||||
GetFrom: field.GetFrom}, true
|
||||
}
|
||||
|
||||
// FindIdent takes a qualified identifier name and returns a ref.Val if one exists.
|
||||
func (p *Registry) FindIdent(identName string) (ref.Val, bool) {
|
||||
if t, found := p.revTypeMap[identName]; found {
|
||||
return t.(ref.Val), true
|
||||
return t, true
|
||||
}
|
||||
if enumVal, found := p.pbdb.DescribeEnum(identName); found {
|
||||
return Int(enumVal.Value()), true
|
||||
@ -134,24 +201,50 @@ func (p *protoTypeRegistry) FindIdent(identName string) (ref.Val, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) FindType(typeName string) (*exprpb.Type, bool) {
|
||||
if _, found := p.pbdb.DescribeType(typeName); !found {
|
||||
// FindType looks up the Type given a qualified typeName. Returns false if not found.
|
||||
//
|
||||
// Deprecated: use FindStructType
|
||||
func (p *Registry) FindType(structType string) (*exprpb.Type, bool) {
|
||||
if _, found := p.pbdb.DescribeType(structType); !found {
|
||||
return nil, false
|
||||
}
|
||||
if typeName != "" && typeName[0] == '.' {
|
||||
typeName = typeName[1:]
|
||||
if structType != "" && structType[0] == '.' {
|
||||
structType = structType[1:]
|
||||
}
|
||||
return &exprpb.Type{
|
||||
TypeKind: &exprpb.Type_Type{
|
||||
Type: &exprpb.Type{
|
||||
TypeKind: &exprpb.Type_MessageType{
|
||||
MessageType: typeName}}}}, true
|
||||
MessageType: structType}}}}, true
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) NewValue(typeName string, fields map[string]ref.Val) ref.Val {
|
||||
td, found := p.pbdb.DescribeType(typeName)
|
||||
// FindStructType returns the Type give a qualified type name.
|
||||
//
|
||||
// For historical reasons, only struct types are expected to be returned through this
|
||||
// method, and the type values are expected to be wrapped in a TypeType instance using
|
||||
// TypeTypeWithParam(<structType>).
|
||||
//
|
||||
// Returns false if not found.
|
||||
func (p *Registry) FindStructType(structType string) (*Type, bool) {
|
||||
if _, found := p.pbdb.DescribeType(structType); !found {
|
||||
return nil, false
|
||||
}
|
||||
if structType != "" && structType[0] == '.' {
|
||||
structType = structType[1:]
|
||||
}
|
||||
return NewTypeTypeWithParam(NewObjectType(structType)), true
|
||||
}
|
||||
|
||||
// NewValue creates a new type value from a qualified name and map of field
|
||||
// name to value.
|
||||
//
|
||||
// Note, for each value, the Val.ConvertToNative function will be invoked
|
||||
// to convert the Val to the field's native type. If an error occurs during
|
||||
// conversion, the NewValue will be a types.Err.
|
||||
func (p *Registry) NewValue(structType string, fields map[string]ref.Val) ref.Val {
|
||||
td, found := p.pbdb.DescribeType(structType)
|
||||
if !found {
|
||||
return NewErr("unknown type '%s'", typeName)
|
||||
return NewErr("unknown type '%s'", structType)
|
||||
}
|
||||
msg := td.New()
|
||||
fieldMap := td.FieldMap()
|
||||
@ -168,7 +261,8 @@ func (p *protoTypeRegistry) NewValue(typeName string, fields map[string]ref.Val)
|
||||
return p.NativeToValue(msg.Interface())
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) RegisterDescriptor(fileDesc protoreflect.FileDescriptor) error {
|
||||
// RegisterDescriptor registers the contents of a protocol buffer `FileDescriptor`.
|
||||
func (p *Registry) RegisterDescriptor(fileDesc protoreflect.FileDescriptor) error {
|
||||
fd, err := p.pbdb.RegisterDescriptor(fileDesc)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -176,7 +270,8 @@ func (p *protoTypeRegistry) RegisterDescriptor(fileDesc protoreflect.FileDescrip
|
||||
return p.registerAllTypes(fd)
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) RegisterMessage(message proto.Message) error {
|
||||
// RegisterMessage registers a protocol buffer message and its dependencies.
|
||||
func (p *Registry) RegisterMessage(message proto.Message) error {
|
||||
fd, err := p.pbdb.RegisterMessage(message)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -184,11 +279,32 @@ func (p *protoTypeRegistry) RegisterMessage(message proto.Message) error {
|
||||
return p.registerAllTypes(fd)
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) RegisterType(types ...ref.Type) error {
|
||||
// RegisterType registers a type value with the provider which ensures the provider is aware of how to
|
||||
// map the type to an identifier.
|
||||
//
|
||||
// If the `ref.Type` value is a `*types.Type` it will be registered directly by its runtime type name.
|
||||
// If the `ref.Type` value is not a `*types.Type` instance, a `*types.Type` instance which reflects the
|
||||
// traits present on the input and the runtime type name. By default this foreign type will be treated
|
||||
// as a types.StructKind. To avoid potential issues where the `ref.Type` values does not match the
|
||||
// generated `*types.Type` instance, consider always using the `*types.Type` to represent type extensions
|
||||
// to CEL, even when they're not based on protobuf types.
|
||||
func (p *Registry) RegisterType(types ...ref.Type) error {
|
||||
for _, t := range types {
|
||||
p.revTypeMap[t.TypeName()] = t
|
||||
celType := maybeForeignType(t)
|
||||
existing, found := p.revTypeMap[t.TypeName()]
|
||||
if !found {
|
||||
p.revTypeMap[t.TypeName()] = celType
|
||||
continue
|
||||
}
|
||||
if !existing.IsEquivalentType(celType) {
|
||||
return fmt.Errorf("type registration conflict. found: %v, input: %v", existing, celType)
|
||||
}
|
||||
if existing.traitMask != celType.traitMask {
|
||||
return fmt.Errorf(
|
||||
"type registered with conflicting traits: %v with traits %v, input: %v",
|
||||
existing.TypeName(), existing.traitMask, celType.traitMask)
|
||||
}
|
||||
}
|
||||
// TODO: generate an error when the type name is registered more than once.
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -196,7 +312,7 @@ func (p *protoTypeRegistry) RegisterType(types ...ref.Type) error {
|
||||
// providing support for custom proto-based types.
|
||||
//
|
||||
// This method should be the inverse of ref.Val.ConvertToNative.
|
||||
func (p *protoTypeRegistry) NativeToValue(value any) ref.Val {
|
||||
func (p *Registry) NativeToValue(value any) ref.Val {
|
||||
if val, found := nativeToValue(p, value); found {
|
||||
return val
|
||||
}
|
||||
@ -218,7 +334,7 @@ func (p *protoTypeRegistry) NativeToValue(value any) ref.Val {
|
||||
if !found {
|
||||
return NewErr("unknown type: '%s'", typeName)
|
||||
}
|
||||
return NewObject(p, td, typeVal.(*TypeValue), v)
|
||||
return NewObject(p, td, typeVal, v)
|
||||
case *pb.Map:
|
||||
return NewProtoMap(p, v)
|
||||
case protoreflect.List:
|
||||
@ -231,8 +347,13 @@ func (p *protoTypeRegistry) NativeToValue(value any) ref.Val {
|
||||
return UnsupportedRefValConversionErr(value)
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) registerAllTypes(fd *pb.FileDescription) error {
|
||||
func (p *Registry) registerAllTypes(fd *pb.FileDescription) error {
|
||||
for _, typeName := range fd.GetTypeNames() {
|
||||
// skip well-known type names since they're automatically sanitized
|
||||
// during NewObjectType() calls.
|
||||
if _, found := checkedWellKnowns[typeName]; found {
|
||||
continue
|
||||
}
|
||||
err := p.RegisterType(NewObjectTypeValue(typeName))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -241,6 +362,28 @@ func (p *protoTypeRegistry) registerAllTypes(fd *pb.FileDescription) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func fieldDescToCELType(field *pb.FieldDescription) *Type {
|
||||
if field.IsMap() {
|
||||
return NewMapType(
|
||||
singularFieldDescToCELType(field.KeyType),
|
||||
singularFieldDescToCELType(field.ValueType))
|
||||
}
|
||||
if field.IsList() {
|
||||
return NewListType(singularFieldDescToCELType(field))
|
||||
}
|
||||
return singularFieldDescToCELType(field)
|
||||
}
|
||||
|
||||
func singularFieldDescToCELType(field *pb.FieldDescription) *Type {
|
||||
if field.IsMessage() {
|
||||
return NewObjectType(string(field.Descriptor().Message().FullName()))
|
||||
}
|
||||
if field.IsEnum() {
|
||||
return IntType
|
||||
}
|
||||
return ProtoCELPrimitives[field.ProtoKind()]
|
||||
}
|
||||
|
||||
// defaultTypeAdapter converts go native types to CEL values.
|
||||
type defaultTypeAdapter struct{}
|
||||
|
||||
@ -259,7 +402,7 @@ func (a *defaultTypeAdapter) NativeToValue(value any) ref.Val {
|
||||
|
||||
// nativeToValue returns the converted (ref.Val, true) of a conversion is found,
|
||||
// otherwise (nil, false)
|
||||
func nativeToValue(a ref.TypeAdapter, value any) (ref.Val, bool) {
|
||||
func nativeToValue(a Adapter, value any) (ref.Val, bool) {
|
||||
switch v := value.(type) {
|
||||
case nil:
|
||||
return NullValue, true
|
||||
@ -547,3 +690,24 @@ func fieldTypeConversionError(field *pb.FieldDescription, err error) error {
|
||||
msgName := field.Descriptor().ContainingMessage().FullName()
|
||||
return fmt.Errorf("field type conversion error for %v.%v value type: %v", msgName, field.Name(), err)
|
||||
}
|
||||
|
||||
var (
|
||||
// ProtoCELPrimitives provides a map from the protoreflect Kind to the equivalent CEL type.
|
||||
ProtoCELPrimitives = map[protoreflect.Kind]*Type{
|
||||
protoreflect.BoolKind: BoolType,
|
||||
protoreflect.BytesKind: BytesType,
|
||||
protoreflect.DoubleKind: DoubleType,
|
||||
protoreflect.FloatKind: DoubleType,
|
||||
protoreflect.Int32Kind: IntType,
|
||||
protoreflect.Int64Kind: IntType,
|
||||
protoreflect.Sint32Kind: IntType,
|
||||
protoreflect.Sint64Kind: IntType,
|
||||
protoreflect.Uint32Kind: UintType,
|
||||
protoreflect.Uint64Kind: UintType,
|
||||
protoreflect.Fixed32Kind: UintType,
|
||||
protoreflect.Fixed64Kind: UintType,
|
||||
protoreflect.Sfixed32Kind: IntType,
|
||||
protoreflect.Sfixed64Kind: IntType,
|
||||
protoreflect.StringKind: StringType,
|
||||
}
|
||||
)
|
||||
|
37
vendor/github.com/google/cel-go/common/types/ref/provider.go
generated
vendored
37
vendor/github.com/google/cel-go/common/types/ref/provider.go
generated
vendored
@ -23,34 +23,34 @@ import (
|
||||
|
||||
// TypeProvider specifies functions for creating new object instances and for
|
||||
// resolving enum values by name.
|
||||
//
|
||||
// Deprecated: use types.Provider
|
||||
type TypeProvider interface {
|
||||
// EnumValue returns the numeric value of the given enum value name.
|
||||
EnumValue(enumName string) Val
|
||||
|
||||
// FindIdent takes a qualified identifier name and returns a Value if one
|
||||
// exists.
|
||||
// FindIdent takes a qualified identifier name and returns a Value if one exists.
|
||||
FindIdent(identName string) (Val, bool)
|
||||
|
||||
// FindType looks up the Type given a qualified typeName. Returns false
|
||||
// if not found.
|
||||
//
|
||||
// Used during type-checking only.
|
||||
// FindType looks up the Type given a qualified typeName. Returns false if not found.
|
||||
FindType(typeName string) (*exprpb.Type, bool)
|
||||
|
||||
// FieldFieldType returns the field type for a checked type value. Returns
|
||||
// false if the field could not be found.
|
||||
FindFieldType(messageType string, fieldName string) (*FieldType, bool)
|
||||
// FieldFieldType returns the field type for a checked type value. Returns false if
|
||||
// the field could not be found.
|
||||
FindFieldType(messageType, fieldName string) (*FieldType, bool)
|
||||
|
||||
// NewValue creates a new type value from a qualified name and map of field
|
||||
// name to value.
|
||||
// NewValue creates a new type value from a qualified name and map of field name
|
||||
// to value.
|
||||
//
|
||||
// Note, for each value, the Val.ConvertToNative function will be invoked
|
||||
// to convert the Val to the field's native type. If an error occurs during
|
||||
// conversion, the NewValue will be a types.Err.
|
||||
// Note, for each value, the Val.ConvertToNative function will be invoked to convert
|
||||
// the Val to the field's native type. If an error occurs during conversion, the
|
||||
// NewValue will be a types.Err.
|
||||
NewValue(typeName string, fields map[string]Val) Val
|
||||
}
|
||||
|
||||
// TypeAdapter converts native Go values of varying type and complexity to equivalent CEL values.
|
||||
//
|
||||
// Deprecated: use types.Adapter
|
||||
type TypeAdapter interface {
|
||||
// NativeToValue converts the input `value` to a CEL `ref.Val`.
|
||||
NativeToValue(value any) Val
|
||||
@ -60,6 +60,8 @@ type TypeAdapter interface {
|
||||
// implementations support type-customization, so these features are optional. However, a
|
||||
// `TypeRegistry` should be a `TypeProvider` and a `TypeAdapter` to ensure that types
|
||||
// which are registered can be converted to CEL representations.
|
||||
//
|
||||
// Deprecated: use types.Registry
|
||||
type TypeRegistry interface {
|
||||
TypeAdapter
|
||||
TypeProvider
|
||||
@ -76,15 +78,14 @@ type TypeRegistry interface {
|
||||
// If a type is provided more than once with an alternative definition, the
|
||||
// call will result in an error.
|
||||
RegisterType(types ...Type) error
|
||||
|
||||
// Copy the TypeRegistry and return a new registry whose mutable state is isolated.
|
||||
Copy() TypeRegistry
|
||||
}
|
||||
|
||||
// FieldType represents a field's type value and whether that field supports
|
||||
// presence detection.
|
||||
//
|
||||
// Deprecated: use types.FieldType
|
||||
type FieldType struct {
|
||||
// Type of the field.
|
||||
// Type of the field as a protobuf type value.
|
||||
Type *exprpb.Type
|
||||
|
||||
// IsSet indicates whether the field is set on an input object.
|
||||
|
44
vendor/github.com/google/cel-go/common/types/string.go
generated
vendored
44
vendor/github.com/google/cel-go/common/types/string.go
generated
vendored
@ -24,7 +24,6 @@ import (
|
||||
|
||||
"github.com/google/cel-go/common/overloads"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
@ -36,18 +35,10 @@ import (
|
||||
type String string
|
||||
|
||||
var (
|
||||
// StringType singleton.
|
||||
StringType = NewTypeValue("string",
|
||||
traits.AdderType,
|
||||
traits.ComparerType,
|
||||
traits.MatcherType,
|
||||
traits.ReceiverType,
|
||||
traits.SizerType)
|
||||
|
||||
stringOneArgOverloads = map[string]func(String, ref.Val) ref.Val{
|
||||
overloads.Contains: stringContains,
|
||||
overloads.EndsWith: stringEndsWith,
|
||||
overloads.StartsWith: stringStartsWith,
|
||||
stringOneArgOverloads = map[string]func(ref.Val, ref.Val) ref.Val{
|
||||
overloads.Contains: StringContains,
|
||||
overloads.EndsWith: StringEndsWith,
|
||||
overloads.StartsWith: StringStartsWith,
|
||||
}
|
||||
|
||||
stringWrapperType = reflect.TypeOf(&wrapperspb.StringValue{})
|
||||
@ -198,26 +189,41 @@ func (s String) Value() any {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func stringContains(s String, sub ref.Val) ref.Val {
|
||||
// StringContains returns whether the string contains a substring.
|
||||
func StringContains(s, sub ref.Val) ref.Val {
|
||||
str, ok := s.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(s)
|
||||
}
|
||||
subStr, ok := sub.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(sub)
|
||||
}
|
||||
return Bool(strings.Contains(string(s), string(subStr)))
|
||||
return Bool(strings.Contains(string(str), string(subStr)))
|
||||
}
|
||||
|
||||
func stringEndsWith(s String, suf ref.Val) ref.Val {
|
||||
// StringEndsWith returns whether the target string contains the input suffix.
|
||||
func StringEndsWith(s, suf ref.Val) ref.Val {
|
||||
str, ok := s.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(s)
|
||||
}
|
||||
sufStr, ok := suf.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(suf)
|
||||
}
|
||||
return Bool(strings.HasSuffix(string(s), string(sufStr)))
|
||||
return Bool(strings.HasSuffix(string(str), string(sufStr)))
|
||||
}
|
||||
|
||||
func stringStartsWith(s String, pre ref.Val) ref.Val {
|
||||
// StringStartsWith returns whether the target string contains the input prefix.
|
||||
func StringStartsWith(s, pre ref.Val) ref.Val {
|
||||
str, ok := s.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(s)
|
||||
}
|
||||
preStr, ok := pre.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(pre)
|
||||
}
|
||||
return Bool(strings.HasPrefix(string(s), string(preStr)))
|
||||
return Bool(strings.HasPrefix(string(str), string(preStr)))
|
||||
}
|
||||
|
10
vendor/github.com/google/cel-go/common/types/timestamp.go
generated
vendored
10
vendor/github.com/google/cel-go/common/types/timestamp.go
generated
vendored
@ -23,7 +23,6 @@ import (
|
||||
|
||||
"github.com/google/cel-go/common/overloads"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
@ -53,15 +52,6 @@ const (
|
||||
maxUnixTime int64 = 253402300799
|
||||
)
|
||||
|
||||
var (
|
||||
// TimestampType singleton.
|
||||
TimestampType = NewTypeValue("google.protobuf.Timestamp",
|
||||
traits.AdderType,
|
||||
traits.ComparerType,
|
||||
traits.ReceiverType,
|
||||
traits.SubtractorType)
|
||||
)
|
||||
|
||||
// Add implements traits.Adder.Add.
|
||||
func (t Timestamp) Add(other ref.Val) ref.Val {
|
||||
switch other.Type() {
|
||||
|
102
vendor/github.com/google/cel-go/common/types/type.go
generated
vendored
102
vendor/github.com/google/cel-go/common/types/type.go
generated
vendored
@ -1,102 +0,0 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
)
|
||||
|
||||
var (
|
||||
// TypeType is the type of a TypeValue.
|
||||
TypeType = NewTypeValue("type")
|
||||
)
|
||||
|
||||
// TypeValue is an instance of a Value that describes a value's type.
|
||||
type TypeValue struct {
|
||||
name string
|
||||
traitMask int
|
||||
}
|
||||
|
||||
// NewTypeValue returns *TypeValue which is both a ref.Type and ref.Val.
|
||||
func NewTypeValue(name string, traits ...int) *TypeValue {
|
||||
traitMask := 0
|
||||
for _, trait := range traits {
|
||||
traitMask |= trait
|
||||
}
|
||||
return &TypeValue{
|
||||
name: name,
|
||||
traitMask: traitMask}
|
||||
}
|
||||
|
||||
// NewObjectTypeValue returns a *TypeValue based on the input name, which is
|
||||
// annotated with the traits relevant to all objects.
|
||||
func NewObjectTypeValue(name string) *TypeValue {
|
||||
return NewTypeValue(name,
|
||||
traits.FieldTesterType,
|
||||
traits.IndexerType)
|
||||
}
|
||||
|
||||
// ConvertToNative implements ref.Val.ConvertToNative.
|
||||
func (t *TypeValue) ConvertToNative(typeDesc reflect.Type) (any, error) {
|
||||
// TODO: replace the internal type representation with a proto-value.
|
||||
return nil, fmt.Errorf("type conversion not supported for 'type'")
|
||||
}
|
||||
|
||||
// ConvertToType implements ref.Val.ConvertToType.
|
||||
func (t *TypeValue) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case TypeType:
|
||||
return TypeType
|
||||
case StringType:
|
||||
return String(t.TypeName())
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", TypeType, typeVal)
|
||||
}
|
||||
|
||||
// Equal implements ref.Val.Equal.
|
||||
func (t *TypeValue) Equal(other ref.Val) ref.Val {
|
||||
otherType, ok := other.(ref.Type)
|
||||
return Bool(ok && t.TypeName() == otherType.TypeName())
|
||||
}
|
||||
|
||||
// HasTrait indicates whether the type supports the given trait.
|
||||
// Trait codes are defined in the traits package, e.g. see traits.AdderType.
|
||||
func (t *TypeValue) HasTrait(trait int) bool {
|
||||
return trait&t.traitMask == trait
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
func (t *TypeValue) String() string {
|
||||
return t.name
|
||||
}
|
||||
|
||||
// Type implements ref.Val.Type.
|
||||
func (t *TypeValue) Type() ref.Type {
|
||||
return TypeType
|
||||
}
|
||||
|
||||
// TypeName gives the type's name as a string.
|
||||
func (t *TypeValue) TypeName() string {
|
||||
return t.name
|
||||
}
|
||||
|
||||
// Value implements ref.Val.Value.
|
||||
func (t *TypeValue) Value() any {
|
||||
return t.name
|
||||
}
|
806
vendor/github.com/google/cel-go/common/types/types.go
generated
vendored
Normal file
806
vendor/github.com/google/cel-go/common/types/types.go
generated
vendored
Normal file
@ -0,0 +1,806 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
chkdecls "github.com/google/cel-go/checker/decls"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
)
|
||||
|
||||
// Kind indicates a CEL type's kind which is used to differentiate quickly between simple
|
||||
// and complex types.
|
||||
type Kind uint
|
||||
|
||||
const (
|
||||
// UnspecifiedKind is returned when the type is nil or its kind is not specified.
|
||||
UnspecifiedKind Kind = iota
|
||||
|
||||
// DynKind represents a dynamic type. This kind only exists at type-check time.
|
||||
DynKind
|
||||
|
||||
// AnyKind represents a google.protobuf.Any type. This kind only exists at type-check time.
|
||||
// Prefer DynKind to AnyKind as AnyKind has a specific meaning which is based on protobuf
|
||||
// well-known types.
|
||||
AnyKind
|
||||
|
||||
// BoolKind represents a boolean type.
|
||||
BoolKind
|
||||
|
||||
// BytesKind represents a bytes type.
|
||||
BytesKind
|
||||
|
||||
// DoubleKind represents a double type.
|
||||
DoubleKind
|
||||
|
||||
// DurationKind represents a CEL duration type.
|
||||
DurationKind
|
||||
|
||||
// ErrorKind represents a CEL error type.
|
||||
ErrorKind
|
||||
|
||||
// IntKind represents an integer type.
|
||||
IntKind
|
||||
|
||||
// ListKind represents a list type.
|
||||
ListKind
|
||||
|
||||
// MapKind represents a map type.
|
||||
MapKind
|
||||
|
||||
// NullTypeKind represents a null type.
|
||||
NullTypeKind
|
||||
|
||||
// OpaqueKind represents an abstract type which has no accessible fields.
|
||||
OpaqueKind
|
||||
|
||||
// StringKind represents a string type.
|
||||
StringKind
|
||||
|
||||
// StructKind represents a structured object with typed fields.
|
||||
StructKind
|
||||
|
||||
// TimestampKind represents a a CEL time type.
|
||||
TimestampKind
|
||||
|
||||
// TypeKind represents the CEL type.
|
||||
TypeKind
|
||||
|
||||
// TypeParamKind represents a parameterized type whose type name will be resolved at type-check time, if possible.
|
||||
TypeParamKind
|
||||
|
||||
// UintKind represents a uint type.
|
||||
UintKind
|
||||
|
||||
// UnknownKind represents an unknown value type.
|
||||
UnknownKind
|
||||
)
|
||||
|
||||
var (
|
||||
// AnyType represents the google.protobuf.Any type.
|
||||
AnyType = &Type{
|
||||
kind: AnyKind,
|
||||
runtimeTypeName: "google.protobuf.Any",
|
||||
traitMask: traits.FieldTesterType |
|
||||
traits.IndexerType,
|
||||
}
|
||||
// BoolType represents the bool type.
|
||||
BoolType = &Type{
|
||||
kind: BoolKind,
|
||||
runtimeTypeName: "bool",
|
||||
traitMask: traits.ComparerType |
|
||||
traits.NegatorType,
|
||||
}
|
||||
// BytesType represents the bytes type.
|
||||
BytesType = &Type{
|
||||
kind: BytesKind,
|
||||
runtimeTypeName: "bytes",
|
||||
traitMask: traits.AdderType |
|
||||
traits.ComparerType |
|
||||
traits.SizerType,
|
||||
}
|
||||
// DoubleType represents the double type.
|
||||
DoubleType = &Type{
|
||||
kind: DoubleKind,
|
||||
runtimeTypeName: "double",
|
||||
traitMask: traits.AdderType |
|
||||
traits.ComparerType |
|
||||
traits.DividerType |
|
||||
traits.MultiplierType |
|
||||
traits.NegatorType |
|
||||
traits.SubtractorType,
|
||||
}
|
||||
// DurationType represents the CEL duration type.
|
||||
DurationType = &Type{
|
||||
kind: DurationKind,
|
||||
runtimeTypeName: "google.protobuf.Duration",
|
||||
traitMask: traits.AdderType |
|
||||
traits.ComparerType |
|
||||
traits.NegatorType |
|
||||
traits.ReceiverType |
|
||||
traits.SubtractorType,
|
||||
}
|
||||
// DynType represents a dynamic CEL type whose type will be determined at runtime from context.
|
||||
DynType = &Type{
|
||||
kind: DynKind,
|
||||
runtimeTypeName: "dyn",
|
||||
}
|
||||
// ErrorType represents a CEL error value.
|
||||
ErrorType = &Type{
|
||||
kind: ErrorKind,
|
||||
runtimeTypeName: "error",
|
||||
}
|
||||
// IntType represents the int type.
|
||||
IntType = &Type{
|
||||
kind: IntKind,
|
||||
runtimeTypeName: "int",
|
||||
traitMask: traits.AdderType |
|
||||
traits.ComparerType |
|
||||
traits.DividerType |
|
||||
traits.ModderType |
|
||||
traits.MultiplierType |
|
||||
traits.NegatorType |
|
||||
traits.SubtractorType,
|
||||
}
|
||||
// ListType represents the runtime list type.
|
||||
ListType = NewListType(nil)
|
||||
// MapType represents the runtime map type.
|
||||
MapType = NewMapType(nil, nil)
|
||||
// NullType represents the type of a null value.
|
||||
NullType = &Type{
|
||||
kind: NullTypeKind,
|
||||
runtimeTypeName: "null_type",
|
||||
}
|
||||
// StringType represents the string type.
|
||||
StringType = &Type{
|
||||
kind: StringKind,
|
||||
runtimeTypeName: "string",
|
||||
traitMask: traits.AdderType |
|
||||
traits.ComparerType |
|
||||
traits.MatcherType |
|
||||
traits.ReceiverType |
|
||||
traits.SizerType,
|
||||
}
|
||||
// TimestampType represents the time type.
|
||||
TimestampType = &Type{
|
||||
kind: TimestampKind,
|
||||
runtimeTypeName: "google.protobuf.Timestamp",
|
||||
traitMask: traits.AdderType |
|
||||
traits.ComparerType |
|
||||
traits.ReceiverType |
|
||||
traits.SubtractorType,
|
||||
}
|
||||
// TypeType represents a CEL type
|
||||
TypeType = &Type{
|
||||
kind: TypeKind,
|
||||
runtimeTypeName: "type",
|
||||
}
|
||||
// UintType represents a uint type.
|
||||
UintType = &Type{
|
||||
kind: UintKind,
|
||||
runtimeTypeName: "uint",
|
||||
traitMask: traits.AdderType |
|
||||
traits.ComparerType |
|
||||
traits.DividerType |
|
||||
traits.ModderType |
|
||||
traits.MultiplierType |
|
||||
traits.SubtractorType,
|
||||
}
|
||||
// UnknownType represents an unknown value type.
|
||||
UnknownType = &Type{
|
||||
kind: UnknownKind,
|
||||
runtimeTypeName: "unknown",
|
||||
}
|
||||
)
|
||||
|
||||
var _ ref.Type = &Type{}
|
||||
var _ ref.Val = &Type{}
|
||||
|
||||
// Type holds a reference to a runtime type with an optional type-checked set of type parameters.
|
||||
type Type struct {
|
||||
// kind indicates general category of the type.
|
||||
kind Kind
|
||||
|
||||
// parameters holds the optional type-checked set of type Parameters that are used during static analysis.
|
||||
parameters []*Type
|
||||
|
||||
// runtimeTypeName indicates the runtime type name of the type.
|
||||
runtimeTypeName string
|
||||
|
||||
// isAssignableType function determines whether one type is assignable to this type.
|
||||
// A nil value for the isAssignableType function falls back to equality of kind, runtimeType, and parameters.
|
||||
isAssignableType func(other *Type) bool
|
||||
|
||||
// isAssignableRuntimeType function determines whether the runtime type (with erasure) is assignable to this type.
|
||||
// A nil value for the isAssignableRuntimeType function falls back to the equality of the type or type name.
|
||||
isAssignableRuntimeType func(other ref.Val) bool
|
||||
|
||||
// traitMask is a mask of flags which indicate the capabilities of the type.
|
||||
traitMask int
|
||||
}
|
||||
|
||||
// ConvertToNative implements ref.Val.ConvertToNative.
|
||||
func (t *Type) ConvertToNative(typeDesc reflect.Type) (any, error) {
|
||||
return nil, fmt.Errorf("type conversion not supported for 'type'")
|
||||
}
|
||||
|
||||
// ConvertToType implements ref.Val.ConvertToType.
|
||||
func (t *Type) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case TypeType:
|
||||
return TypeType
|
||||
case StringType:
|
||||
return String(t.TypeName())
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", TypeType, typeVal)
|
||||
}
|
||||
|
||||
// Equal indicates whether two types have the same runtime type name.
|
||||
//
|
||||
// The name Equal is a bit of a misnomer, but for historical reasons, this is the
|
||||
// runtime behavior. For a more accurate definition see IsType().
|
||||
func (t *Type) Equal(other ref.Val) ref.Val {
|
||||
otherType, ok := other.(ref.Type)
|
||||
return Bool(ok && t.TypeName() == otherType.TypeName())
|
||||
}
|
||||
|
||||
// HasTrait implements the ref.Type interface method.
|
||||
func (t *Type) HasTrait(trait int) bool {
|
||||
return trait&t.traitMask == trait
|
||||
}
|
||||
|
||||
// IsExactType indicates whether the two types are exactly the same. This check also verifies type parameter type names.
|
||||
func (t *Type) IsExactType(other *Type) bool {
|
||||
return t.isTypeInternal(other, true)
|
||||
}
|
||||
|
||||
// IsEquivalentType indicates whether two types are equivalent. This check ignores type parameter type names.
|
||||
func (t *Type) IsEquivalentType(other *Type) bool {
|
||||
return t.isTypeInternal(other, false)
|
||||
}
|
||||
|
||||
// Kind indicates general category of the type.
|
||||
func (t *Type) Kind() Kind {
|
||||
if t == nil {
|
||||
return UnspecifiedKind
|
||||
}
|
||||
return t.kind
|
||||
}
|
||||
|
||||
// isTypeInternal checks whether the two types are equivalent or exactly the same based on the checkTypeParamName flag.
|
||||
func (t *Type) isTypeInternal(other *Type, checkTypeParamName bool) bool {
|
||||
if t == nil {
|
||||
return false
|
||||
}
|
||||
if t == other {
|
||||
return true
|
||||
}
|
||||
if t.Kind() != other.Kind() || len(t.Parameters()) != len(other.Parameters()) {
|
||||
return false
|
||||
}
|
||||
if (checkTypeParamName || t.Kind() != TypeParamKind) && t.TypeName() != other.TypeName() {
|
||||
return false
|
||||
}
|
||||
for i, p := range t.Parameters() {
|
||||
if !p.isTypeInternal(other.Parameters()[i], checkTypeParamName) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// IsAssignableType determines whether the current type is type-check assignable from the input fromType.
|
||||
func (t *Type) IsAssignableType(fromType *Type) bool {
|
||||
if t == nil {
|
||||
return false
|
||||
}
|
||||
if t.isAssignableType != nil {
|
||||
return t.isAssignableType(fromType)
|
||||
}
|
||||
return t.defaultIsAssignableType(fromType)
|
||||
}
|
||||
|
||||
// IsAssignableRuntimeType determines whether the current type is runtime assignable from the input runtimeType.
|
||||
//
|
||||
// At runtime, parameterized types are erased and so a function which type-checks to support a map(string, string)
|
||||
// will have a runtime assignable type of a map.
|
||||
func (t *Type) IsAssignableRuntimeType(val ref.Val) bool {
|
||||
if t == nil {
|
||||
return false
|
||||
}
|
||||
if t.isAssignableRuntimeType != nil {
|
||||
return t.isAssignableRuntimeType(val)
|
||||
}
|
||||
return t.defaultIsAssignableRuntimeType(val)
|
||||
}
|
||||
|
||||
// Parameters returns the list of type parameters if set.
|
||||
//
|
||||
// For ListKind, Parameters()[0] represents the list element type
|
||||
// For MapKind, Parameters()[0] represents the map key type, and Parameters()[1] represents the map
|
||||
// value type.
|
||||
func (t *Type) Parameters() []*Type {
|
||||
if t == nil {
|
||||
return emptyParams
|
||||
}
|
||||
return t.parameters
|
||||
}
|
||||
|
||||
// DeclaredTypeName indicates the fully qualified and parameterized type-check type name.
|
||||
func (t *Type) DeclaredTypeName() string {
|
||||
// if the type itself is neither null, nor dyn, but is assignable to null, then it's a wrapper type.
|
||||
if t.Kind() != NullTypeKind && !t.isDyn() && t.IsAssignableType(NullType) {
|
||||
return fmt.Sprintf("wrapper(%s)", t.TypeName())
|
||||
}
|
||||
return t.TypeName()
|
||||
}
|
||||
|
||||
// Type implements the ref.Val interface method.
|
||||
func (t *Type) Type() ref.Type {
|
||||
return TypeType
|
||||
}
|
||||
|
||||
// Value implements the ref.Val interface method.
|
||||
func (t *Type) Value() any {
|
||||
return t.TypeName()
|
||||
}
|
||||
|
||||
// TypeName returns the type-erased fully qualified runtime type name.
|
||||
//
|
||||
// TypeName implements the ref.Type interface method.
|
||||
func (t *Type) TypeName() string {
|
||||
if t == nil {
|
||||
return ""
|
||||
}
|
||||
return t.runtimeTypeName
|
||||
}
|
||||
|
||||
// String returns a human-readable definition of the type name.
|
||||
func (t *Type) String() string {
|
||||
if len(t.Parameters()) == 0 {
|
||||
return t.DeclaredTypeName()
|
||||
}
|
||||
params := make([]string, len(t.Parameters()))
|
||||
for i, p := range t.Parameters() {
|
||||
params[i] = p.String()
|
||||
}
|
||||
return fmt.Sprintf("%s(%s)", t.DeclaredTypeName(), strings.Join(params, ", "))
|
||||
}
|
||||
|
||||
// isDyn indicates whether the type is dynamic in any way.
|
||||
func (t *Type) isDyn() bool {
|
||||
k := t.Kind()
|
||||
return k == DynKind || k == AnyKind || k == TypeParamKind
|
||||
}
|
||||
|
||||
// defaultIsAssignableType provides the standard definition of what it means for one type to be assignable to another
|
||||
// where any of the following may return a true result:
|
||||
// - The from types are the same instance
|
||||
// - The target type is dynamic
|
||||
// - The fromType has the same kind and type name as the target type, and all parameters of the target type
|
||||
//
|
||||
// are IsAssignableType() from the parameters of the fromType.
|
||||
func (t *Type) defaultIsAssignableType(fromType *Type) bool {
|
||||
if t == fromType || t.isDyn() {
|
||||
return true
|
||||
}
|
||||
if t.Kind() != fromType.Kind() ||
|
||||
t.TypeName() != fromType.TypeName() ||
|
||||
len(t.Parameters()) != len(fromType.Parameters()) {
|
||||
return false
|
||||
}
|
||||
for i, tp := range t.Parameters() {
|
||||
fp := fromType.Parameters()[i]
|
||||
if !tp.IsAssignableType(fp) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// defaultIsAssignableRuntimeType inspects the type and in the case of list and map elements, the key and element types
|
||||
// to determine whether a ref.Val is assignable to the declared type for a function signature.
|
||||
func (t *Type) defaultIsAssignableRuntimeType(val ref.Val) bool {
|
||||
valType := val.Type()
|
||||
// If the current type and value type don't agree, then return
|
||||
if !(t.isDyn() || t.TypeName() == valType.TypeName()) {
|
||||
return false
|
||||
}
|
||||
switch t.Kind() {
|
||||
case ListKind:
|
||||
elemType := t.Parameters()[0]
|
||||
l := val.(traits.Lister)
|
||||
if l.Size() == IntZero {
|
||||
return true
|
||||
}
|
||||
it := l.Iterator()
|
||||
elemVal := it.Next()
|
||||
return elemType.IsAssignableRuntimeType(elemVal)
|
||||
case MapKind:
|
||||
keyType := t.Parameters()[0]
|
||||
elemType := t.Parameters()[1]
|
||||
m := val.(traits.Mapper)
|
||||
if m.Size() == IntZero {
|
||||
return true
|
||||
}
|
||||
it := m.Iterator()
|
||||
keyVal := it.Next()
|
||||
elemVal := m.Get(keyVal)
|
||||
return keyType.IsAssignableRuntimeType(keyVal) && elemType.IsAssignableRuntimeType(elemVal)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// NewListType creates an instances of a list type value with the provided element type.
|
||||
func NewListType(elemType *Type) *Type {
|
||||
return &Type{
|
||||
kind: ListKind,
|
||||
parameters: []*Type{elemType},
|
||||
runtimeTypeName: "list",
|
||||
traitMask: traits.AdderType |
|
||||
traits.ContainerType |
|
||||
traits.IndexerType |
|
||||
traits.IterableType |
|
||||
traits.SizerType,
|
||||
}
|
||||
}
|
||||
|
||||
// NewMapType creates an instance of a map type value with the provided key and value types.
|
||||
func NewMapType(keyType, valueType *Type) *Type {
|
||||
return &Type{
|
||||
kind: MapKind,
|
||||
parameters: []*Type{keyType, valueType},
|
||||
runtimeTypeName: "map",
|
||||
traitMask: traits.ContainerType |
|
||||
traits.IndexerType |
|
||||
traits.IterableType |
|
||||
traits.SizerType,
|
||||
}
|
||||
}
|
||||
|
||||
// NewNullableType creates an instance of a nullable type with the provided wrapped type.
|
||||
//
|
||||
// Note: only primitive types are supported as wrapped types.
|
||||
func NewNullableType(wrapped *Type) *Type {
|
||||
return &Type{
|
||||
kind: wrapped.Kind(),
|
||||
parameters: wrapped.Parameters(),
|
||||
runtimeTypeName: wrapped.TypeName(),
|
||||
traitMask: wrapped.traitMask,
|
||||
isAssignableType: func(other *Type) bool {
|
||||
return NullType.IsAssignableType(other) || wrapped.IsAssignableType(other)
|
||||
},
|
||||
isAssignableRuntimeType: func(other ref.Val) bool {
|
||||
return NullType.IsAssignableRuntimeType(other) || wrapped.IsAssignableRuntimeType(other)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewOptionalType creates an abstract parameterized type instance corresponding to CEL's notion of optional.
|
||||
func NewOptionalType(param *Type) *Type {
|
||||
return NewOpaqueType("optional", param)
|
||||
}
|
||||
|
||||
// NewOpaqueType creates an abstract parameterized type with a given name.
|
||||
func NewOpaqueType(name string, params ...*Type) *Type {
|
||||
return &Type{
|
||||
kind: OpaqueKind,
|
||||
parameters: params,
|
||||
runtimeTypeName: name,
|
||||
}
|
||||
}
|
||||
|
||||
// NewObjectType creates a type reference to an externally defined type, e.g. a protobuf message type.
|
||||
//
|
||||
// An object type is assumed to support field presence testing and field indexing. Additionally, the
|
||||
// type may also indicate additional traits through the use of the optional traits vararg argument.
|
||||
func NewObjectType(typeName string, traits ...int) *Type {
|
||||
// Function sanitizes object types on the fly
|
||||
if wkt, found := checkedWellKnowns[typeName]; found {
|
||||
return wkt
|
||||
}
|
||||
traitMask := 0
|
||||
for _, trait := range traits {
|
||||
traitMask |= trait
|
||||
}
|
||||
return &Type{
|
||||
kind: StructKind,
|
||||
parameters: emptyParams,
|
||||
runtimeTypeName: typeName,
|
||||
traitMask: structTypeTraitMask | traitMask,
|
||||
}
|
||||
}
|
||||
|
||||
// NewObjectTypeValue creates a type reference to an externally defined type.
|
||||
//
|
||||
// Deprecated: use cel.ObjectType(typeName)
|
||||
func NewObjectTypeValue(typeName string) *Type {
|
||||
return NewObjectType(typeName)
|
||||
}
|
||||
|
||||
// NewTypeValue creates an opaque type which has a set of optional type traits as defined in
|
||||
// the common/types/traits package.
|
||||
//
|
||||
// Deprecated: use cel.ObjectType(typeName, traits)
|
||||
func NewTypeValue(typeName string, traits ...int) *Type {
|
||||
traitMask := 0
|
||||
for _, trait := range traits {
|
||||
traitMask |= trait
|
||||
}
|
||||
return &Type{
|
||||
kind: StructKind,
|
||||
parameters: emptyParams,
|
||||
runtimeTypeName: typeName,
|
||||
traitMask: traitMask,
|
||||
}
|
||||
}
|
||||
|
||||
// NewTypeParamType creates a parameterized type instance.
|
||||
func NewTypeParamType(paramName string) *Type {
|
||||
return &Type{
|
||||
kind: TypeParamKind,
|
||||
runtimeTypeName: paramName,
|
||||
}
|
||||
}
|
||||
|
||||
// NewTypeTypeWithParam creates a type with a type parameter.
|
||||
// Used for type-checking purposes, but equivalent to TypeType otherwise.
|
||||
func NewTypeTypeWithParam(param *Type) *Type {
|
||||
return &Type{
|
||||
kind: TypeKind,
|
||||
runtimeTypeName: "type",
|
||||
parameters: []*Type{param},
|
||||
}
|
||||
}
|
||||
|
||||
// TypeToExprType converts a CEL-native type representation to a protobuf CEL Type representation.
|
||||
func TypeToExprType(t *Type) (*exprpb.Type, error) {
|
||||
switch t.Kind() {
|
||||
case AnyKind:
|
||||
return chkdecls.Any, nil
|
||||
case BoolKind:
|
||||
return maybeWrapper(t, chkdecls.Bool), nil
|
||||
case BytesKind:
|
||||
return maybeWrapper(t, chkdecls.Bytes), nil
|
||||
case DoubleKind:
|
||||
return maybeWrapper(t, chkdecls.Double), nil
|
||||
case DurationKind:
|
||||
return chkdecls.Duration, nil
|
||||
case DynKind:
|
||||
return chkdecls.Dyn, nil
|
||||
case ErrorKind:
|
||||
return chkdecls.Error, nil
|
||||
case IntKind:
|
||||
return maybeWrapper(t, chkdecls.Int), nil
|
||||
case ListKind:
|
||||
if len(t.Parameters()) != 1 {
|
||||
return nil, fmt.Errorf("invalid list, got %d parameters, wanted one", len(t.Parameters()))
|
||||
}
|
||||
et, err := TypeToExprType(t.Parameters()[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return chkdecls.NewListType(et), nil
|
||||
case MapKind:
|
||||
if len(t.Parameters()) != 2 {
|
||||
return nil, fmt.Errorf("invalid map, got %d parameters, wanted two", len(t.Parameters()))
|
||||
}
|
||||
kt, err := TypeToExprType(t.Parameters()[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vt, err := TypeToExprType(t.Parameters()[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return chkdecls.NewMapType(kt, vt), nil
|
||||
case NullTypeKind:
|
||||
return chkdecls.Null, nil
|
||||
case OpaqueKind:
|
||||
params := make([]*exprpb.Type, len(t.Parameters()))
|
||||
for i, p := range t.Parameters() {
|
||||
pt, err := TypeToExprType(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
params[i] = pt
|
||||
}
|
||||
return chkdecls.NewAbstractType(t.TypeName(), params...), nil
|
||||
case StringKind:
|
||||
return maybeWrapper(t, chkdecls.String), nil
|
||||
case StructKind:
|
||||
return chkdecls.NewObjectType(t.TypeName()), nil
|
||||
case TimestampKind:
|
||||
return chkdecls.Timestamp, nil
|
||||
case TypeParamKind:
|
||||
return chkdecls.NewTypeParamType(t.TypeName()), nil
|
||||
case TypeKind:
|
||||
if len(t.Parameters()) == 1 {
|
||||
p, err := TypeToExprType(t.Parameters()[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return chkdecls.NewTypeType(p), nil
|
||||
}
|
||||
return chkdecls.NewTypeType(nil), nil
|
||||
case UintKind:
|
||||
return maybeWrapper(t, chkdecls.Uint), nil
|
||||
}
|
||||
return nil, fmt.Errorf("missing type conversion to proto: %v", t)
|
||||
}
|
||||
|
||||
// ExprTypeToType converts a protobuf CEL type representation to a CEL-native type representation.
|
||||
func ExprTypeToType(t *exprpb.Type) (*Type, error) {
|
||||
switch t.GetTypeKind().(type) {
|
||||
case *exprpb.Type_Dyn:
|
||||
return DynType, nil
|
||||
case *exprpb.Type_AbstractType_:
|
||||
paramTypes := make([]*Type, len(t.GetAbstractType().GetParameterTypes()))
|
||||
for i, p := range t.GetAbstractType().GetParameterTypes() {
|
||||
pt, err := ExprTypeToType(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
paramTypes[i] = pt
|
||||
}
|
||||
return NewOpaqueType(t.GetAbstractType().GetName(), paramTypes...), nil
|
||||
case *exprpb.Type_ListType_:
|
||||
et, err := ExprTypeToType(t.GetListType().GetElemType())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewListType(et), nil
|
||||
case *exprpb.Type_MapType_:
|
||||
kt, err := ExprTypeToType(t.GetMapType().GetKeyType())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vt, err := ExprTypeToType(t.GetMapType().GetValueType())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewMapType(kt, vt), nil
|
||||
case *exprpb.Type_MessageType:
|
||||
return NewObjectType(t.GetMessageType()), nil
|
||||
case *exprpb.Type_Null:
|
||||
return NullType, nil
|
||||
case *exprpb.Type_Primitive:
|
||||
switch t.GetPrimitive() {
|
||||
case exprpb.Type_BOOL:
|
||||
return BoolType, nil
|
||||
case exprpb.Type_BYTES:
|
||||
return BytesType, nil
|
||||
case exprpb.Type_DOUBLE:
|
||||
return DoubleType, nil
|
||||
case exprpb.Type_INT64:
|
||||
return IntType, nil
|
||||
case exprpb.Type_STRING:
|
||||
return StringType, nil
|
||||
case exprpb.Type_UINT64:
|
||||
return UintType, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported primitive type: %v", t)
|
||||
}
|
||||
case *exprpb.Type_TypeParam:
|
||||
return NewTypeParamType(t.GetTypeParam()), nil
|
||||
case *exprpb.Type_Type:
|
||||
if t.GetType().GetTypeKind() != nil {
|
||||
p, err := ExprTypeToType(t.GetType())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewTypeTypeWithParam(p), nil
|
||||
}
|
||||
return TypeType, nil
|
||||
case *exprpb.Type_WellKnown:
|
||||
switch t.GetWellKnown() {
|
||||
case exprpb.Type_ANY:
|
||||
return AnyType, nil
|
||||
case exprpb.Type_DURATION:
|
||||
return DurationType, nil
|
||||
case exprpb.Type_TIMESTAMP:
|
||||
return TimestampType, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported well-known type: %v", t)
|
||||
}
|
||||
case *exprpb.Type_Wrapper:
|
||||
t, err := ExprTypeToType(&exprpb.Type{TypeKind: &exprpb.Type_Primitive{Primitive: t.GetWrapper()}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewNullableType(t), nil
|
||||
case *exprpb.Type_Error:
|
||||
return ErrorType, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported type: %v", t)
|
||||
}
|
||||
}
|
||||
|
||||
func maybeWrapper(t *Type, pbType *exprpb.Type) *exprpb.Type {
|
||||
if t.IsAssignableType(NullType) {
|
||||
return chkdecls.NewWrapperType(pbType)
|
||||
}
|
||||
return pbType
|
||||
}
|
||||
|
||||
func maybeForeignType(t ref.Type) *Type {
|
||||
if celType, ok := t.(*Type); ok {
|
||||
return celType
|
||||
}
|
||||
// Inspect the incoming type to determine its traits. The assumption will be that the incoming
|
||||
// type does not have any field values; however, if the trait mask indicates that field testing
|
||||
// and indexing are supported, the foreign type is marked as a struct.
|
||||
traitMask := 0
|
||||
for _, trait := range allTraits {
|
||||
if t.HasTrait(trait) {
|
||||
traitMask |= trait
|
||||
}
|
||||
}
|
||||
// Treat the value like a struct. If it has no fields, this is harmless to denote the type
|
||||
// as such since it basically becomes an opaque type by convention.
|
||||
return NewObjectType(t.TypeName(), traitMask)
|
||||
}
|
||||
|
||||
var (
|
||||
checkedWellKnowns = map[string]*Type{
|
||||
// Wrapper types.
|
||||
"google.protobuf.BoolValue": NewNullableType(BoolType),
|
||||
"google.protobuf.BytesValue": NewNullableType(BytesType),
|
||||
"google.protobuf.DoubleValue": NewNullableType(DoubleType),
|
||||
"google.protobuf.FloatValue": NewNullableType(DoubleType),
|
||||
"google.protobuf.Int64Value": NewNullableType(IntType),
|
||||
"google.protobuf.Int32Value": NewNullableType(IntType),
|
||||
"google.protobuf.UInt64Value": NewNullableType(UintType),
|
||||
"google.protobuf.UInt32Value": NewNullableType(UintType),
|
||||
"google.protobuf.StringValue": NewNullableType(StringType),
|
||||
// Well-known types.
|
||||
"google.protobuf.Any": AnyType,
|
||||
"google.protobuf.Duration": DurationType,
|
||||
"google.protobuf.Timestamp": TimestampType,
|
||||
// Json types.
|
||||
"google.protobuf.ListValue": NewListType(DynType),
|
||||
"google.protobuf.NullValue": NullType,
|
||||
"google.protobuf.Struct": NewMapType(StringType, DynType),
|
||||
"google.protobuf.Value": DynType,
|
||||
}
|
||||
|
||||
emptyParams = []*Type{}
|
||||
|
||||
allTraits = []int{
|
||||
traits.AdderType,
|
||||
traits.ComparerType,
|
||||
traits.ContainerType,
|
||||
traits.DividerType,
|
||||
traits.FieldTesterType,
|
||||
traits.IndexerType,
|
||||
traits.IterableType,
|
||||
traits.IteratorType,
|
||||
traits.MatcherType,
|
||||
traits.ModderType,
|
||||
traits.MultiplierType,
|
||||
traits.NegatorType,
|
||||
traits.ReceiverType,
|
||||
traits.SizerType,
|
||||
traits.SubtractorType,
|
||||
}
|
||||
|
||||
structTypeTraitMask = traits.FieldTesterType | traits.IndexerType
|
||||
)
|
10
vendor/github.com/google/cel-go/common/types/uint.go
generated
vendored
10
vendor/github.com/google/cel-go/common/types/uint.go
generated
vendored
@ -21,7 +21,6 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
@ -32,15 +31,6 @@ import (
|
||||
type Uint uint64
|
||||
|
||||
var (
|
||||
// UintType singleton.
|
||||
UintType = NewTypeValue("uint",
|
||||
traits.AdderType,
|
||||
traits.ComparerType,
|
||||
traits.DividerType,
|
||||
traits.ModderType,
|
||||
traits.MultiplierType,
|
||||
traits.SubtractorType)
|
||||
|
||||
uint32WrapperType = reflect.TypeOf(&wrapperspb.UInt32Value{})
|
||||
|
||||
uint64WrapperType = reflect.TypeOf(&wrapperspb.UInt64Value{})
|
||||
|
290
vendor/github.com/google/cel-go/common/types/unknown.go
generated
vendored
290
vendor/github.com/google/cel-go/common/types/unknown.go
generated
vendored
@ -15,52 +15,312 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
)
|
||||
|
||||
// Unknown type implementation which collects expression ids which caused the
|
||||
// current value to become unknown.
|
||||
type Unknown []int64
|
||||
|
||||
var (
|
||||
// UnknownType singleton.
|
||||
UnknownType = NewTypeValue("unknown")
|
||||
unspecifiedAttribute = &AttributeTrail{qualifierPath: []any{}}
|
||||
)
|
||||
|
||||
// NewAttributeTrail creates a new simple attribute from a variable name.
|
||||
func NewAttributeTrail(variable string) *AttributeTrail {
|
||||
if variable == "" {
|
||||
return unspecifiedAttribute
|
||||
}
|
||||
return &AttributeTrail{variable: variable}
|
||||
}
|
||||
|
||||
// AttributeTrail specifies a variable with an optional qualifier path. An attribute value is expected to
|
||||
// correspond to an AbsoluteAttribute, meaning a field selection which starts with a top-level variable.
|
||||
//
|
||||
// The qualifer path elements adhere to the AttributeQualifier type constraint.
|
||||
type AttributeTrail struct {
|
||||
variable string
|
||||
qualifierPath []any
|
||||
}
|
||||
|
||||
// Equal returns whether two attribute values have the same variable name and qualifier paths.
|
||||
func (a *AttributeTrail) Equal(other *AttributeTrail) bool {
|
||||
if a.Variable() != other.Variable() || len(a.QualifierPath()) != len(other.QualifierPath()) {
|
||||
return false
|
||||
}
|
||||
for i, q := range a.QualifierPath() {
|
||||
qual := other.QualifierPath()[i]
|
||||
if !qualifiersEqual(q, qual) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func qualifiersEqual(a, b any) bool {
|
||||
if a == b {
|
||||
return true
|
||||
}
|
||||
switch numA := a.(type) {
|
||||
case int64:
|
||||
numB, ok := b.(uint64)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return intUintEqual(numA, numB)
|
||||
case uint64:
|
||||
numB, ok := b.(int64)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return intUintEqual(numB, numA)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func intUintEqual(i int64, u uint64) bool {
|
||||
if i < 0 || u > math.MaxInt64 {
|
||||
return false
|
||||
}
|
||||
return i == int64(u)
|
||||
}
|
||||
|
||||
// Variable returns the variable name associated with the attribute.
|
||||
func (a *AttributeTrail) Variable() string {
|
||||
return a.variable
|
||||
}
|
||||
|
||||
// QualifierPath returns the optional set of qualifying fields or indices applied to the variable.
|
||||
func (a *AttributeTrail) QualifierPath() []any {
|
||||
return a.qualifierPath
|
||||
}
|
||||
|
||||
// String returns the string representation of the Attribute.
|
||||
func (a *AttributeTrail) String() string {
|
||||
if a.variable == "" {
|
||||
return "<unspecified>"
|
||||
}
|
||||
var str strings.Builder
|
||||
str.WriteString(a.variable)
|
||||
for _, q := range a.qualifierPath {
|
||||
switch q := q.(type) {
|
||||
case bool, int64:
|
||||
str.WriteString(fmt.Sprintf("[%v]", q))
|
||||
case uint64:
|
||||
str.WriteString(fmt.Sprintf("[%vu]", q))
|
||||
case string:
|
||||
if isIdentifierCharacter(q) {
|
||||
str.WriteString(fmt.Sprintf(".%v", q))
|
||||
} else {
|
||||
str.WriteString(fmt.Sprintf("[%q]", q))
|
||||
}
|
||||
}
|
||||
}
|
||||
return str.String()
|
||||
}
|
||||
|
||||
func isIdentifierCharacter(str string) bool {
|
||||
for _, c := range str {
|
||||
if unicode.IsLetter(c) || unicode.IsDigit(c) || string(c) == "_" {
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// AttributeQualifier constrains the possible types which may be used to qualify an attribute.
|
||||
type AttributeQualifier interface {
|
||||
bool | int64 | uint64 | string
|
||||
}
|
||||
|
||||
// QualifyAttribute qualifies an attribute using a valid AttributeQualifier type.
|
||||
func QualifyAttribute[T AttributeQualifier](attr *AttributeTrail, qualifier T) *AttributeTrail {
|
||||
attr.qualifierPath = append(attr.qualifierPath, qualifier)
|
||||
return attr
|
||||
}
|
||||
|
||||
// Unknown type which collects expression ids which caused the current value to become unknown.
|
||||
type Unknown struct {
|
||||
attributeTrails map[int64][]*AttributeTrail
|
||||
}
|
||||
|
||||
// NewUnknown creates a new unknown at a given expression id for an attribute.
|
||||
//
|
||||
// If the attribute is nil, the attribute value will be the `unspecifiedAttribute`.
|
||||
func NewUnknown(id int64, attr *AttributeTrail) *Unknown {
|
||||
if attr == nil {
|
||||
attr = unspecifiedAttribute
|
||||
}
|
||||
return &Unknown{
|
||||
attributeTrails: map[int64][]*AttributeTrail{id: {attr}},
|
||||
}
|
||||
}
|
||||
|
||||
// IDs returns the set of unknown expression ids contained by this value.
|
||||
//
|
||||
// Numeric identifiers are guaranteed to be in sorted order.
|
||||
func (u *Unknown) IDs() []int64 {
|
||||
ids := make(int64Slice, len(u.attributeTrails))
|
||||
i := 0
|
||||
for id := range u.attributeTrails {
|
||||
ids[i] = id
|
||||
i++
|
||||
}
|
||||
ids.Sort()
|
||||
return ids
|
||||
}
|
||||
|
||||
// GetAttributeTrails returns the attribute trails, if present, missing for a given expression id.
|
||||
func (u *Unknown) GetAttributeTrails(id int64) ([]*AttributeTrail, bool) {
|
||||
trails, found := u.attributeTrails[id]
|
||||
return trails, found
|
||||
}
|
||||
|
||||
// Contains returns true if the input unknown is a subset of the current unknown.
|
||||
func (u *Unknown) Contains(other *Unknown) bool {
|
||||
for id, otherTrails := range other.attributeTrails {
|
||||
trails, found := u.attributeTrails[id]
|
||||
if !found || len(otherTrails) != len(trails) {
|
||||
return false
|
||||
}
|
||||
for _, ot := range otherTrails {
|
||||
found := false
|
||||
for _, t := range trails {
|
||||
if t.Equal(ot) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ConvertToNative implements ref.Val.ConvertToNative.
|
||||
func (u Unknown) ConvertToNative(typeDesc reflect.Type) (any, error) {
|
||||
func (u *Unknown) ConvertToNative(typeDesc reflect.Type) (any, error) {
|
||||
return u.Value(), nil
|
||||
}
|
||||
|
||||
// ConvertToType is an identity function since unknown values cannot be modified.
|
||||
func (u Unknown) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
func (u *Unknown) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
return u
|
||||
}
|
||||
|
||||
// Equal is an identity function since unknown values cannot be modified.
|
||||
func (u Unknown) Equal(other ref.Val) ref.Val {
|
||||
func (u *Unknown) Equal(other ref.Val) ref.Val {
|
||||
return u
|
||||
}
|
||||
|
||||
// String implements the Stringer interface
|
||||
func (u *Unknown) String() string {
|
||||
var str strings.Builder
|
||||
for id, attrs := range u.attributeTrails {
|
||||
if str.Len() != 0 {
|
||||
str.WriteString(", ")
|
||||
}
|
||||
if len(attrs) == 1 {
|
||||
str.WriteString(fmt.Sprintf("%v (%d)", attrs[0], id))
|
||||
} else {
|
||||
str.WriteString(fmt.Sprintf("%v (%d)", attrs, id))
|
||||
}
|
||||
}
|
||||
return str.String()
|
||||
}
|
||||
|
||||
// Type implements ref.Val.Type.
|
||||
func (u Unknown) Type() ref.Type {
|
||||
func (u *Unknown) Type() ref.Type {
|
||||
return UnknownType
|
||||
}
|
||||
|
||||
// Value implements ref.Val.Value.
|
||||
func (u Unknown) Value() any {
|
||||
return []int64(u)
|
||||
func (u *Unknown) Value() any {
|
||||
return u
|
||||
}
|
||||
|
||||
// IsUnknown returns whether the element ref.Type or ref.Val is equal to the
|
||||
// UnknownType singleton.
|
||||
// IsUnknown returns whether the element ref.Val is in instance of *types.Unknown
|
||||
func IsUnknown(val ref.Val) bool {
|
||||
switch val.(type) {
|
||||
case Unknown:
|
||||
case *Unknown:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// MaybeMergeUnknowns determines whether an input value and another, possibly nil, unknown will produce
|
||||
// an unknown result.
|
||||
//
|
||||
// If the input `val` is another Unknown, then the result will be the merge of the `val` and the input
|
||||
// `unk`. If the `val` is not unknown, then the result will depend on whether the input `unk` is nil.
|
||||
// If both values are non-nil and unknown, then the return value will be a merge of both unknowns.
|
||||
func MaybeMergeUnknowns(val ref.Val, unk *Unknown) (*Unknown, bool) {
|
||||
src, isUnk := val.(*Unknown)
|
||||
if !isUnk {
|
||||
if unk != nil {
|
||||
return unk, true
|
||||
}
|
||||
return unk, false
|
||||
}
|
||||
return MergeUnknowns(src, unk), true
|
||||
}
|
||||
|
||||
// MergeUnknowns combines two unknown values into a new unknown value.
|
||||
func MergeUnknowns(unk1, unk2 *Unknown) *Unknown {
|
||||
if unk1 == nil {
|
||||
return unk2
|
||||
}
|
||||
if unk2 == nil {
|
||||
return unk1
|
||||
}
|
||||
out := &Unknown{
|
||||
attributeTrails: make(map[int64][]*AttributeTrail, len(unk1.attributeTrails)+len(unk2.attributeTrails)),
|
||||
}
|
||||
for id, ats := range unk1.attributeTrails {
|
||||
out.attributeTrails[id] = ats
|
||||
}
|
||||
for id, ats := range unk2.attributeTrails {
|
||||
existing, found := out.attributeTrails[id]
|
||||
if !found {
|
||||
out.attributeTrails[id] = ats
|
||||
continue
|
||||
}
|
||||
|
||||
for _, at := range ats {
|
||||
found := false
|
||||
for _, et := range existing {
|
||||
if at.Equal(et) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
existing = append(existing, at)
|
||||
}
|
||||
}
|
||||
out.attributeTrails[id] = existing
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// int64Slice is an implementation of the sort.Interface
|
||||
type int64Slice []int64
|
||||
|
||||
// Len returns the number of elements in the slice.
|
||||
func (x int64Slice) Len() int { return len(x) }
|
||||
|
||||
// Less indicates whether the value at index i is less than the value at index j.
|
||||
func (x int64Slice) Less(i, j int) bool { return x[i] < x[j] }
|
||||
|
||||
// Swap swaps the values at indices i and j in place.
|
||||
func (x int64Slice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||
|
||||
// Sort is a convenience method: x.Sort() calls Sort(x).
|
||||
func (x int64Slice) Sort() { sort.Sort(x) }
|
||||
|
2
vendor/github.com/google/cel-go/common/types/util.go
generated
vendored
2
vendor/github.com/google/cel-go/common/types/util.go
generated
vendored
@ -21,7 +21,7 @@ import (
|
||||
// IsUnknownOrError returns whether the input element ref.Val is an ErrType or UnknownType.
|
||||
func IsUnknownOrError(val ref.Val) bool {
|
||||
switch val.(type) {
|
||||
case Unknown, *Err:
|
||||
case *Unknown, *Err:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
Reference in New Issue
Block a user