mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 10:53:34 +00:00
rebase: bump k8s.io/kubernetes from 1.26.2 to 1.27.2
Bumps [k8s.io/kubernetes](https://github.com/kubernetes/kubernetes) from 1.26.2 to 1.27.2. - [Release notes](https://github.com/kubernetes/kubernetes/releases) - [Commits](https://github.com/kubernetes/kubernetes/compare/v1.26.2...v1.27.2) --- updated-dependencies: - dependency-name: k8s.io/kubernetes dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
mergify[bot]
parent
0e79135419
commit
07b05616a0
35
vendor/github.com/google/cel-go/common/BUILD.bazel
generated
vendored
Normal file
35
vendor/github.com/google/cel-go/common/BUILD.bazel
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
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 = [
|
||||
"cost.go",
|
||||
"error.go",
|
||||
"errors.go",
|
||||
"location.go",
|
||||
"source.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common",
|
||||
deps = [
|
||||
"//common/runes:go_default_library",
|
||||
"@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
|
||||
"@org_golang_x_text//width:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"errors_test.go",
|
||||
"source_test.go",
|
||||
],
|
||||
embed = [
|
||||
":go_default_library",
|
||||
],
|
||||
)
|
31
vendor/github.com/google/cel-go/common/containers/BUILD.bazel
generated
vendored
Normal file
31
vendor/github.com/google/cel-go/common/containers/BUILD.bazel
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
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 = [
|
||||
"container.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/containers",
|
||||
deps = [
|
||||
"@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"container_test.go",
|
||||
],
|
||||
embed = [
|
||||
":go_default_library",
|
||||
],
|
||||
deps = [
|
||||
"@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
|
||||
],
|
||||
)
|
316
vendor/github.com/google/cel-go/common/containers/container.go
generated
vendored
Normal file
316
vendor/github.com/google/cel-go/common/containers/container.go
generated
vendored
Normal file
@ -0,0 +1,316 @@
|
||||
// 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 containers defines types and functions for resolving qualified names within a namespace
|
||||
// or type provided to CEL.
|
||||
package containers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
)
|
||||
|
||||
var (
|
||||
// DefaultContainer has an empty container name.
|
||||
DefaultContainer *Container = nil
|
||||
|
||||
// Empty map to search for aliases when needed.
|
||||
noAliases = make(map[string]string)
|
||||
)
|
||||
|
||||
// NewContainer creates a new Container with the fully-qualified name.
|
||||
func NewContainer(opts ...ContainerOption) (*Container, error) {
|
||||
var c *Container
|
||||
var err error
|
||||
for _, opt := range opts {
|
||||
c, err = opt(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Container holds a reference to an optional qualified container name and set of aliases.
|
||||
//
|
||||
// The program container can be used to simplify variable, function, and type specification within
|
||||
// CEL programs and behaves more or less like a C++ namespace. See ResolveCandidateNames for more
|
||||
// details.
|
||||
type Container struct {
|
||||
name string
|
||||
aliases map[string]string
|
||||
}
|
||||
|
||||
// Extend creates a new Container with the existing settings and applies a series of
|
||||
// ContainerOptions to further configure the new container.
|
||||
func (c *Container) Extend(opts ...ContainerOption) (*Container, error) {
|
||||
if c == nil {
|
||||
return NewContainer(opts...)
|
||||
}
|
||||
// Copy the name and aliases of the existing container.
|
||||
ext := &Container{name: c.Name()}
|
||||
if len(c.aliasSet()) > 0 {
|
||||
aliasSet := make(map[string]string, len(c.aliasSet()))
|
||||
for k, v := range c.aliasSet() {
|
||||
aliasSet[k] = v
|
||||
}
|
||||
ext.aliases = aliasSet
|
||||
}
|
||||
// Apply the new options to the container.
|
||||
var err error
|
||||
for _, opt := range opts {
|
||||
ext, err = opt(ext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return ext, nil
|
||||
}
|
||||
|
||||
// Name returns the fully-qualified name of the container.
|
||||
//
|
||||
// The name may conceptually be a namespace, package, or type.
|
||||
func (c *Container) Name() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
return c.name
|
||||
}
|
||||
|
||||
// ResolveCandidateNames returns the candidates name of namespaced identifiers in C++ resolution
|
||||
// order.
|
||||
//
|
||||
// Names which shadow other names are returned first. If a name includes a leading dot ('.'),
|
||||
// the name is treated as an absolute identifier which cannot be shadowed.
|
||||
//
|
||||
// Given a container name a.b.c.M.N and a type name R.s, this will deliver in order:
|
||||
//
|
||||
// a.b.c.M.N.R.s
|
||||
// a.b.c.M.R.s
|
||||
// a.b.c.R.s
|
||||
// a.b.R.s
|
||||
// a.R.s
|
||||
// R.s
|
||||
//
|
||||
// If aliases or abbreviations are configured for the container, then alias names will take
|
||||
// precedence over containerized names.
|
||||
func (c *Container) ResolveCandidateNames(name string) []string {
|
||||
if strings.HasPrefix(name, ".") {
|
||||
qn := name[1:]
|
||||
alias, isAlias := c.findAlias(qn)
|
||||
if isAlias {
|
||||
return []string{alias}
|
||||
}
|
||||
return []string{qn}
|
||||
}
|
||||
alias, isAlias := c.findAlias(name)
|
||||
if isAlias {
|
||||
return []string{alias}
|
||||
}
|
||||
if c.Name() == "" {
|
||||
return []string{name}
|
||||
}
|
||||
nextCont := c.Name()
|
||||
candidates := []string{nextCont + "." + name}
|
||||
for i := strings.LastIndex(nextCont, "."); i >= 0; i = strings.LastIndex(nextCont, ".") {
|
||||
nextCont = nextCont[:i]
|
||||
candidates = append(candidates, nextCont+"."+name)
|
||||
}
|
||||
return append(candidates, name)
|
||||
}
|
||||
|
||||
// aliasSet returns the alias to fully-qualified name mapping stored in the container.
|
||||
func (c *Container) aliasSet() map[string]string {
|
||||
if c == nil || c.aliases == nil {
|
||||
return noAliases
|
||||
}
|
||||
return c.aliases
|
||||
}
|
||||
|
||||
// findAlias takes a name as input and returns an alias expansion if one exists.
|
||||
//
|
||||
// If the name is qualified, the first component of the qualified name is checked against known
|
||||
// aliases. Any alias that is found in a qualified name is expanded in the result:
|
||||
//
|
||||
// alias: R -> my.alias.R
|
||||
// name: R.S.T
|
||||
// output: my.alias.R.S.T
|
||||
//
|
||||
// Note, the name must not have a leading dot.
|
||||
func (c *Container) findAlias(name string) (string, bool) {
|
||||
// If an alias exists for the name, ensure it is searched last.
|
||||
simple := name
|
||||
qualifier := ""
|
||||
dot := strings.Index(name, ".")
|
||||
if dot >= 0 {
|
||||
simple = name[0:dot]
|
||||
qualifier = name[dot:]
|
||||
}
|
||||
alias, found := c.aliasSet()[simple]
|
||||
if !found {
|
||||
return "", false
|
||||
}
|
||||
return alias + qualifier, true
|
||||
}
|
||||
|
||||
// ContainerOption specifies a functional configuration option for a Container.
|
||||
//
|
||||
// Note, ContainerOption implementations must be able to handle nil container inputs.
|
||||
type ContainerOption func(*Container) (*Container, error)
|
||||
|
||||
// Abbrevs configures a set of simple names as abbreviations for fully-qualified names.
|
||||
//
|
||||
// An abbreviation (abbrev for short) is a simple name that expands to a fully-qualified name.
|
||||
// Abbreviations can be useful when working with variables, functions, and especially types from
|
||||
// multiple namespaces:
|
||||
//
|
||||
// // CEL object construction
|
||||
// qual.pkg.version.ObjTypeName{
|
||||
// field: alt.container.ver.FieldTypeName{value: ...}
|
||||
// }
|
||||
//
|
||||
// Only one the qualified names above may be used as the CEL container, so at least one of these
|
||||
// references must be a long qualified name within an otherwise short CEL program. Using the
|
||||
// following abbreviations, the program becomes much simpler:
|
||||
//
|
||||
// // CEL Go option
|
||||
// Abbrevs("qual.pkg.version.ObjTypeName", "alt.container.ver.FieldTypeName")
|
||||
// // Simplified Object construction
|
||||
// ObjTypeName{field: FieldTypeName{value: ...}}
|
||||
//
|
||||
// There are a few rules for the qualified names and the simple abbreviations generated from them:
|
||||
// - Qualified names must be dot-delimited, e.g. `package.subpkg.name`.
|
||||
// - The last element in the qualified name is the abbreviation.
|
||||
// - Abbreviations must not collide with each other.
|
||||
// - The abbreviation must not collide with unqualified names in use.
|
||||
//
|
||||
// Abbreviations are distinct from container-based references in the following important ways:
|
||||
// - Abbreviations must expand to a fully-qualified name.
|
||||
// - Expanded abbreviations do not participate in namespace resolution.
|
||||
// - Abbreviation expansion is done instead of the container search for a matching identifier.
|
||||
// - Containers follow C++ namespace resolution rules with searches from the most qualified name
|
||||
// to the least qualified name.
|
||||
// - Container references within the CEL program may be relative, and are resolved to fully
|
||||
// qualified names at either type-check time or program plan time, whichever comes first.
|
||||
//
|
||||
// If there is ever a case where an identifier could be in both the container and as an
|
||||
// abbreviation, the abbreviation wins as this will ensure that the meaning of a program is
|
||||
// preserved between compilations even as the container evolves.
|
||||
func Abbrevs(qualifiedNames ...string) ContainerOption {
|
||||
return func(c *Container) (*Container, error) {
|
||||
for _, qn := range qualifiedNames {
|
||||
ind := strings.LastIndex(qn, ".")
|
||||
if ind <= 0 || ind >= len(qn)-1 {
|
||||
return nil, fmt.Errorf(
|
||||
"invalid qualified name: %s, wanted name of the form 'qualified.name'", qn)
|
||||
}
|
||||
alias := qn[ind+1:]
|
||||
var err error
|
||||
c, err = aliasAs("abbreviation", qn, alias)(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Alias associates a fully-qualified name with a user-defined alias.
|
||||
//
|
||||
// In general, Abbrevs is preferred to Alias since the names generated from the Abbrevs option
|
||||
// are more easily traced back to source code. The Alias option is useful for propagating alias
|
||||
// configuration from one Container instance to another, and may also be useful for remapping
|
||||
// poorly chosen protobuf message / package names.
|
||||
//
|
||||
// Note: all of the rules that apply to Abbrevs also apply to Alias.
|
||||
func Alias(qualifiedName, alias string) ContainerOption {
|
||||
return aliasAs("alias", qualifiedName, alias)
|
||||
}
|
||||
|
||||
func aliasAs(kind, qualifiedName, alias string) ContainerOption {
|
||||
return func(c *Container) (*Container, error) {
|
||||
if len(alias) == 0 || strings.Contains(alias, ".") {
|
||||
return nil, fmt.Errorf(
|
||||
"%s must be non-empty and simple (not qualified): %s=%s", kind, kind, alias)
|
||||
}
|
||||
|
||||
if qualifiedName[0:1] == "." {
|
||||
return nil, fmt.Errorf("qualified name must not begin with a leading '.': %s",
|
||||
qualifiedName)
|
||||
}
|
||||
ind := strings.LastIndex(qualifiedName, ".")
|
||||
if ind <= 0 || ind == len(qualifiedName)-1 {
|
||||
return nil, fmt.Errorf("%s must refer to a valid qualified name: %s",
|
||||
kind, qualifiedName)
|
||||
}
|
||||
aliasRef, found := c.aliasSet()[alias]
|
||||
if found {
|
||||
return nil, fmt.Errorf(
|
||||
"%s collides with existing reference: name=%s, %s=%s, existing=%s",
|
||||
kind, qualifiedName, kind, alias, aliasRef)
|
||||
}
|
||||
if strings.HasPrefix(c.Name(), alias+".") || c.Name() == alias {
|
||||
return nil, fmt.Errorf(
|
||||
"%s collides with container name: name=%s, %s=%s, container=%s",
|
||||
kind, qualifiedName, kind, alias, c.Name())
|
||||
}
|
||||
if c == nil {
|
||||
c = &Container{}
|
||||
}
|
||||
if c.aliases == nil {
|
||||
c.aliases = make(map[string]string)
|
||||
}
|
||||
c.aliases[alias] = qualifiedName
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Name sets the fully-qualified name of the Container.
|
||||
func Name(name string) ContainerOption {
|
||||
return func(c *Container) (*Container, error) {
|
||||
if len(name) > 0 && name[0:1] == "." {
|
||||
return nil, fmt.Errorf("container name must not contain a leading '.': %s", name)
|
||||
}
|
||||
if c.Name() == name {
|
||||
return c, nil
|
||||
}
|
||||
if c == nil {
|
||||
return &Container{name: name}, nil
|
||||
}
|
||||
c.name = name
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ToQualifiedName converts an expression AST into a qualified name if possible, with a boolean
|
||||
// 'found' value that indicates if the conversion is successful.
|
||||
func ToQualifiedName(e *exprpb.Expr) (string, bool) {
|
||||
switch e.GetExprKind().(type) {
|
||||
case *exprpb.Expr_IdentExpr:
|
||||
id := e.GetIdentExpr()
|
||||
return id.GetName(), true
|
||||
case *exprpb.Expr_SelectExpr:
|
||||
sel := e.GetSelectExpr()
|
||||
// Test only expressions are not valid as qualified names.
|
||||
if sel.GetTestOnly() {
|
||||
return "", false
|
||||
}
|
||||
if qual, found := ToQualifiedName(sel.GetOperand()); found {
|
||||
return qual + "." + sel.GetField(), true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
40
vendor/github.com/google/cel-go/common/cost.go
generated
vendored
Normal file
40
vendor/github.com/google/cel-go/common/cost.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2022 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 common
|
||||
|
||||
const (
|
||||
// SelectAndIdentCost is the cost of an operation that accesses an identifier or performs a select.
|
||||
SelectAndIdentCost = 1
|
||||
|
||||
// ConstCost is the cost of an operation that accesses a constant.
|
||||
ConstCost = 0
|
||||
|
||||
// ListCreateBaseCost is the base cost of any operation that creates a new list.
|
||||
ListCreateBaseCost = 10
|
||||
|
||||
// MapCreateBaseCost is the base cost of any operation that creates a new map.
|
||||
MapCreateBaseCost = 30
|
||||
|
||||
// StructCreateBaseCost is the base cost of any operation that creates a new struct.
|
||||
StructCreateBaseCost = 40
|
||||
|
||||
// StringTraversalCostFactor is multiplied to a length of a string when computing the cost of traversing the entire
|
||||
// string once.
|
||||
StringTraversalCostFactor = 0.1
|
||||
|
||||
// RegexStringLengthCostFactor is multiplied ot the length of a regex string pattern when computing the cost of
|
||||
// applying the regex to a string of unit cost.
|
||||
RegexStringLengthCostFactor = 0.25
|
||||
)
|
18
vendor/github.com/google/cel-go/common/debug/BUILD.bazel
generated
vendored
Normal file
18
vendor/github.com/google/cel-go/common/debug/BUILD.bazel
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
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 = [
|
||||
"debug.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/debug",
|
||||
deps = [
|
||||
"//common:go_default_library",
|
||||
"@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
|
||||
],
|
||||
)
|
305
vendor/github.com/google/cel-go/common/debug/debug.go
generated
vendored
Normal file
305
vendor/github.com/google/cel-go/common/debug/debug.go
generated
vendored
Normal file
@ -0,0 +1,305 @@
|
||||
// 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 debug provides tools to print a parsed expression graph and
|
||||
// adorn each expression element with additional metadata.
|
||||
package debug
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
)
|
||||
|
||||
// Adorner returns debug metadata that will be tacked on to the string
|
||||
// representation of an expression.
|
||||
type Adorner interface {
|
||||
// GetMetadata for the input context.
|
||||
GetMetadata(ctx interface{}) string
|
||||
}
|
||||
|
||||
// Writer manages writing expressions to an internal string.
|
||||
type Writer interface {
|
||||
fmt.Stringer
|
||||
|
||||
// Buffer pushes an expression into an internal queue of expressions to
|
||||
// write to a string.
|
||||
Buffer(e *exprpb.Expr)
|
||||
}
|
||||
|
||||
type emptyDebugAdorner struct {
|
||||
}
|
||||
|
||||
var emptyAdorner Adorner = &emptyDebugAdorner{}
|
||||
|
||||
func (a *emptyDebugAdorner) GetMetadata(e interface{}) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// ToDebugString gives the unadorned string representation of the Expr.
|
||||
func ToDebugString(e *exprpb.Expr) string {
|
||||
return ToAdornedDebugString(e, emptyAdorner)
|
||||
}
|
||||
|
||||
// ToAdornedDebugString gives the adorned string representation of the Expr.
|
||||
func ToAdornedDebugString(e *exprpb.Expr, adorner Adorner) string {
|
||||
w := newDebugWriter(adorner)
|
||||
w.Buffer(e)
|
||||
return w.String()
|
||||
}
|
||||
|
||||
// debugWriter is used to print out pretty-printed debug strings.
|
||||
type debugWriter struct {
|
||||
adorner Adorner
|
||||
buffer bytes.Buffer
|
||||
indent int
|
||||
lineStart bool
|
||||
}
|
||||
|
||||
func newDebugWriter(a Adorner) *debugWriter {
|
||||
return &debugWriter{
|
||||
adorner: a,
|
||||
indent: 0,
|
||||
lineStart: true,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *debugWriter) Buffer(e *exprpb.Expr) {
|
||||
if e == nil {
|
||||
return
|
||||
}
|
||||
switch e.ExprKind.(type) {
|
||||
case *exprpb.Expr_ConstExpr:
|
||||
w.append(formatLiteral(e.GetConstExpr()))
|
||||
case *exprpb.Expr_IdentExpr:
|
||||
w.append(e.GetIdentExpr().Name)
|
||||
case *exprpb.Expr_SelectExpr:
|
||||
w.appendSelect(e.GetSelectExpr())
|
||||
case *exprpb.Expr_CallExpr:
|
||||
w.appendCall(e.GetCallExpr())
|
||||
case *exprpb.Expr_ListExpr:
|
||||
w.appendList(e.GetListExpr())
|
||||
case *exprpb.Expr_StructExpr:
|
||||
w.appendStruct(e.GetStructExpr())
|
||||
case *exprpb.Expr_ComprehensionExpr:
|
||||
w.appendComprehension(e.GetComprehensionExpr())
|
||||
}
|
||||
w.adorn(e)
|
||||
}
|
||||
|
||||
func (w *debugWriter) appendSelect(sel *exprpb.Expr_Select) {
|
||||
w.Buffer(sel.GetOperand())
|
||||
w.append(".")
|
||||
w.append(sel.GetField())
|
||||
if sel.TestOnly {
|
||||
w.append("~test-only~")
|
||||
}
|
||||
}
|
||||
|
||||
func (w *debugWriter) appendCall(call *exprpb.Expr_Call) {
|
||||
if call.Target != nil {
|
||||
w.Buffer(call.GetTarget())
|
||||
w.append(".")
|
||||
}
|
||||
w.append(call.GetFunction())
|
||||
w.append("(")
|
||||
if len(call.GetArgs()) > 0 {
|
||||
w.addIndent()
|
||||
w.appendLine()
|
||||
for i, arg := range call.GetArgs() {
|
||||
if i > 0 {
|
||||
w.append(",")
|
||||
w.appendLine()
|
||||
}
|
||||
w.Buffer(arg)
|
||||
}
|
||||
w.removeIndent()
|
||||
w.appendLine()
|
||||
}
|
||||
w.append(")")
|
||||
}
|
||||
|
||||
func (w *debugWriter) appendList(list *exprpb.Expr_CreateList) {
|
||||
w.append("[")
|
||||
if len(list.GetElements()) > 0 {
|
||||
w.appendLine()
|
||||
w.addIndent()
|
||||
for i, elem := range list.GetElements() {
|
||||
if i > 0 {
|
||||
w.append(",")
|
||||
w.appendLine()
|
||||
}
|
||||
w.Buffer(elem)
|
||||
}
|
||||
w.removeIndent()
|
||||
w.appendLine()
|
||||
}
|
||||
w.append("]")
|
||||
}
|
||||
|
||||
func (w *debugWriter) appendStruct(obj *exprpb.Expr_CreateStruct) {
|
||||
if obj.MessageName != "" {
|
||||
w.appendObject(obj)
|
||||
} else {
|
||||
w.appendMap(obj)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *debugWriter) appendObject(obj *exprpb.Expr_CreateStruct) {
|
||||
w.append(obj.GetMessageName())
|
||||
w.append("{")
|
||||
if len(obj.GetEntries()) > 0 {
|
||||
w.appendLine()
|
||||
w.addIndent()
|
||||
for i, entry := range obj.GetEntries() {
|
||||
if i > 0 {
|
||||
w.append(",")
|
||||
w.appendLine()
|
||||
}
|
||||
w.append(entry.GetFieldKey())
|
||||
w.append(":")
|
||||
w.Buffer(entry.GetValue())
|
||||
w.adorn(entry)
|
||||
}
|
||||
w.removeIndent()
|
||||
w.appendLine()
|
||||
}
|
||||
w.append("}")
|
||||
}
|
||||
|
||||
func (w *debugWriter) appendMap(obj *exprpb.Expr_CreateStruct) {
|
||||
w.append("{")
|
||||
if len(obj.GetEntries()) > 0 {
|
||||
w.appendLine()
|
||||
w.addIndent()
|
||||
for i, entry := range obj.GetEntries() {
|
||||
if i > 0 {
|
||||
w.append(",")
|
||||
w.appendLine()
|
||||
}
|
||||
w.Buffer(entry.GetMapKey())
|
||||
w.append(":")
|
||||
w.Buffer(entry.GetValue())
|
||||
w.adorn(entry)
|
||||
}
|
||||
w.removeIndent()
|
||||
w.appendLine()
|
||||
}
|
||||
w.append("}")
|
||||
}
|
||||
|
||||
func (w *debugWriter) appendComprehension(comprehension *exprpb.Expr_Comprehension) {
|
||||
w.append("__comprehension__(")
|
||||
w.addIndent()
|
||||
w.appendLine()
|
||||
w.append("// Variable")
|
||||
w.appendLine()
|
||||
w.append(comprehension.GetIterVar())
|
||||
w.append(",")
|
||||
w.appendLine()
|
||||
w.append("// Target")
|
||||
w.appendLine()
|
||||
w.Buffer(comprehension.GetIterRange())
|
||||
w.append(",")
|
||||
w.appendLine()
|
||||
w.append("// Accumulator")
|
||||
w.appendLine()
|
||||
w.append(comprehension.GetAccuVar())
|
||||
w.append(",")
|
||||
w.appendLine()
|
||||
w.append("// Init")
|
||||
w.appendLine()
|
||||
w.Buffer(comprehension.GetAccuInit())
|
||||
w.append(",")
|
||||
w.appendLine()
|
||||
w.append("// LoopCondition")
|
||||
w.appendLine()
|
||||
w.Buffer(comprehension.GetLoopCondition())
|
||||
w.append(",")
|
||||
w.appendLine()
|
||||
w.append("// LoopStep")
|
||||
w.appendLine()
|
||||
w.Buffer(comprehension.GetLoopStep())
|
||||
w.append(",")
|
||||
w.appendLine()
|
||||
w.append("// Result")
|
||||
w.appendLine()
|
||||
w.Buffer(comprehension.GetResult())
|
||||
w.append(")")
|
||||
w.removeIndent()
|
||||
}
|
||||
|
||||
func formatLiteral(c *exprpb.Constant) string {
|
||||
switch c.GetConstantKind().(type) {
|
||||
case *exprpb.Constant_BoolValue:
|
||||
return fmt.Sprintf("%t", c.GetBoolValue())
|
||||
case *exprpb.Constant_BytesValue:
|
||||
return fmt.Sprintf("b\"%s\"", string(c.GetBytesValue()))
|
||||
case *exprpb.Constant_DoubleValue:
|
||||
return fmt.Sprintf("%v", c.GetDoubleValue())
|
||||
case *exprpb.Constant_Int64Value:
|
||||
return fmt.Sprintf("%d", c.GetInt64Value())
|
||||
case *exprpb.Constant_StringValue:
|
||||
return strconv.Quote(c.GetStringValue())
|
||||
case *exprpb.Constant_Uint64Value:
|
||||
return fmt.Sprintf("%du", c.GetUint64Value())
|
||||
case *exprpb.Constant_NullValue:
|
||||
return "null"
|
||||
default:
|
||||
panic("Unknown constant type")
|
||||
}
|
||||
}
|
||||
|
||||
func (w *debugWriter) append(s string) {
|
||||
w.doIndent()
|
||||
w.buffer.WriteString(s)
|
||||
}
|
||||
|
||||
func (w *debugWriter) appendFormat(f string, args ...interface{}) {
|
||||
w.append(fmt.Sprintf(f, args...))
|
||||
}
|
||||
|
||||
func (w *debugWriter) doIndent() {
|
||||
if w.lineStart {
|
||||
w.lineStart = false
|
||||
w.buffer.WriteString(strings.Repeat(" ", w.indent))
|
||||
}
|
||||
}
|
||||
|
||||
func (w *debugWriter) adorn(e interface{}) {
|
||||
w.append(w.adorner.GetMetadata(e))
|
||||
}
|
||||
|
||||
func (w *debugWriter) appendLine() {
|
||||
w.buffer.WriteString("\n")
|
||||
w.lineStart = true
|
||||
}
|
||||
|
||||
func (w *debugWriter) addIndent() {
|
||||
w.indent++
|
||||
}
|
||||
|
||||
func (w *debugWriter) removeIndent() {
|
||||
w.indent--
|
||||
if w.indent < 0 {
|
||||
panic("negative indent")
|
||||
}
|
||||
}
|
||||
|
||||
func (w *debugWriter) String() string {
|
||||
return w.buffer.String()
|
||||
}
|
17
vendor/github.com/google/cel-go/common/doc.go
generated
vendored
Normal file
17
vendor/github.com/google/cel-go/common/doc.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// 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 common defines types and utilities common to expression parsing,
|
||||
// checking, and interpretation
|
||||
package common
|
73
vendor/github.com/google/cel-go/common/error.go
generated
vendored
Normal file
73
vendor/github.com/google/cel-go/common/error.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
// 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 common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"golang.org/x/text/width"
|
||||
)
|
||||
|
||||
// Error type which references a location within source and a message.
|
||||
type Error struct {
|
||||
Location Location
|
||||
Message string
|
||||
}
|
||||
|
||||
const (
|
||||
dot = "."
|
||||
ind = "^"
|
||||
|
||||
// maxSnippetLength is the largest number of characters which can be rendered in an error message snippet.
|
||||
maxSnippetLength = 16384
|
||||
)
|
||||
|
||||
var (
|
||||
wideDot = width.Widen.String(dot)
|
||||
wideInd = width.Widen.String(ind)
|
||||
)
|
||||
|
||||
// ToDisplayString decorates the error message with the source location.
|
||||
func (e *Error) ToDisplayString(source Source) string {
|
||||
var result = fmt.Sprintf("ERROR: %s:%d:%d: %s",
|
||||
source.Description(),
|
||||
e.Location.Line(),
|
||||
e.Location.Column()+1, // add one to the 0-based column for display
|
||||
e.Message)
|
||||
if snippet, found := source.Snippet(e.Location.Line()); found && len(snippet) <= maxSnippetLength {
|
||||
snippet := strings.Replace(snippet, "\t", " ", -1)
|
||||
srcLine := "\n | " + snippet
|
||||
var bytes = []byte(snippet)
|
||||
var indLine = "\n | "
|
||||
for i := 0; i < e.Location.Column() && len(bytes) > 0; i++ {
|
||||
_, sz := utf8.DecodeRune(bytes)
|
||||
bytes = bytes[sz:]
|
||||
if sz > 1 {
|
||||
indLine += wideDot
|
||||
} else {
|
||||
indLine += dot
|
||||
}
|
||||
}
|
||||
if _, sz := utf8.DecodeRune(bytes); sz > 1 {
|
||||
indLine += wideInd
|
||||
} else {
|
||||
indLine += ind
|
||||
}
|
||||
result += srcLine + indLine
|
||||
}
|
||||
return result
|
||||
}
|
97
vendor/github.com/google/cel-go/common/errors.go
generated
vendored
Normal file
97
vendor/github.com/google/cel-go/common/errors.go
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
// 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 common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Errors type which contains a list of errors observed during parsing.
|
||||
type Errors struct {
|
||||
errors []Error
|
||||
source Source
|
||||
numErrors int
|
||||
maxErrorsToReport int
|
||||
}
|
||||
|
||||
// NewErrors creates a new instance of the Errors type.
|
||||
func NewErrors(source Source) *Errors {
|
||||
return &Errors{
|
||||
errors: []Error{},
|
||||
source: source,
|
||||
maxErrorsToReport: 100,
|
||||
}
|
||||
}
|
||||
|
||||
// ReportError records an error at a source location.
|
||||
func (e *Errors) ReportError(l Location, format string, args ...interface{}) {
|
||||
e.numErrors++
|
||||
if e.numErrors > e.maxErrorsToReport {
|
||||
return
|
||||
}
|
||||
err := Error{
|
||||
Location: l,
|
||||
Message: fmt.Sprintf(format, args...),
|
||||
}
|
||||
e.errors = append(e.errors, err)
|
||||
}
|
||||
|
||||
// GetErrors returns the list of observed errors.
|
||||
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 {
|
||||
return &Errors{
|
||||
errors: append(e.errors, errs...),
|
||||
source: e.source,
|
||||
numErrors: e.numErrors + len(errs),
|
||||
maxErrorsToReport: e.maxErrorsToReport,
|
||||
}
|
||||
}
|
||||
|
||||
// ToDisplayString returns the error set to a newline delimited string.
|
||||
func (e *Errors) ToDisplayString() string {
|
||||
errorsInString := e.maxErrorsToReport
|
||||
if e.numErrors > e.maxErrorsToReport {
|
||||
// add one more error to indicate the number of errors truncated.
|
||||
errorsInString++
|
||||
} else {
|
||||
// otherwise the error set will just contain the number of errors.
|
||||
errorsInString = e.numErrors
|
||||
}
|
||||
|
||||
result := make([]string, errorsInString)
|
||||
sort.SliceStable(e.errors, func(i, j int) bool {
|
||||
ei := e.errors[i].Location
|
||||
ej := e.errors[j].Location
|
||||
return ei.Line() < ej.Line() ||
|
||||
(ei.Line() == ej.Line() && ei.Column() < ej.Column())
|
||||
})
|
||||
for i, err := range e.errors {
|
||||
// This can happen during the append of two errors objects
|
||||
if i >= e.maxErrorsToReport {
|
||||
break
|
||||
}
|
||||
result[i] = err.ToDisplayString(e.source)
|
||||
}
|
||||
if e.numErrors > e.maxErrorsToReport {
|
||||
result[e.maxErrorsToReport] = fmt.Sprintf("%d more errors were truncated", e.numErrors-e.maxErrorsToReport)
|
||||
}
|
||||
return strings.Join(result, "\n")
|
||||
}
|
51
vendor/github.com/google/cel-go/common/location.go
generated
vendored
Normal file
51
vendor/github.com/google/cel-go/common/location.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
// 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 common
|
||||
|
||||
// Location interface to represent a location within Source.
|
||||
type Location interface {
|
||||
Line() int // 1-based line number within source.
|
||||
Column() int // 0-based column number within source.
|
||||
}
|
||||
|
||||
// SourceLocation helper type to manually construct a location.
|
||||
type SourceLocation struct {
|
||||
line int
|
||||
column int
|
||||
}
|
||||
|
||||
var (
|
||||
// Location implements the SourceLocation interface.
|
||||
_ Location = &SourceLocation{}
|
||||
// NoLocation is a particular illegal location.
|
||||
NoLocation = &SourceLocation{-1, -1}
|
||||
)
|
||||
|
||||
// NewLocation creates a new location.
|
||||
func NewLocation(line, column int) Location {
|
||||
return &SourceLocation{
|
||||
line: line,
|
||||
column: column}
|
||||
}
|
||||
|
||||
// Line returns the 1-based line of the location.
|
||||
func (l *SourceLocation) Line() int {
|
||||
return l.line
|
||||
}
|
||||
|
||||
// Column returns the 0-based column number of the location.
|
||||
func (l *SourceLocation) Column() int {
|
||||
return l.column
|
||||
}
|
14
vendor/github.com/google/cel-go/common/operators/BUILD.bazel
generated
vendored
Normal file
14
vendor/github.com/google/cel-go/common/operators/BUILD.bazel
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
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 = [
|
||||
"operators.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/operators",
|
||||
)
|
153
vendor/github.com/google/cel-go/common/operators/operators.go
generated
vendored
Normal file
153
vendor/github.com/google/cel-go/common/operators/operators.go
generated
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
// 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 operators defines the internal function names of operators.
|
||||
//
|
||||
// All operators in the expression language are modelled as function calls.
|
||||
package operators
|
||||
|
||||
// String "names" for CEL operators.
|
||||
const (
|
||||
// Symbolic operators.
|
||||
Conditional = "_?_:_"
|
||||
LogicalAnd = "_&&_"
|
||||
LogicalOr = "_||_"
|
||||
LogicalNot = "!_"
|
||||
Equals = "_==_"
|
||||
NotEquals = "_!=_"
|
||||
Less = "_<_"
|
||||
LessEquals = "_<=_"
|
||||
Greater = "_>_"
|
||||
GreaterEquals = "_>=_"
|
||||
Add = "_+_"
|
||||
Subtract = "_-_"
|
||||
Multiply = "_*_"
|
||||
Divide = "_/_"
|
||||
Modulo = "_%_"
|
||||
Negate = "-_"
|
||||
Index = "_[_]"
|
||||
|
||||
// Macros, must have a valid identifier.
|
||||
Has = "has"
|
||||
All = "all"
|
||||
Exists = "exists"
|
||||
ExistsOne = "exists_one"
|
||||
Map = "map"
|
||||
Filter = "filter"
|
||||
|
||||
// Named operators, must not have be valid identifiers.
|
||||
NotStrictlyFalse = "@not_strictly_false"
|
||||
In = "@in"
|
||||
|
||||
// Deprecated: named operators with valid identifiers.
|
||||
OldNotStrictlyFalse = "__not_strictly_false__"
|
||||
OldIn = "_in_"
|
||||
)
|
||||
|
||||
var (
|
||||
operators = map[string]string{
|
||||
"+": Add,
|
||||
"/": Divide,
|
||||
"==": Equals,
|
||||
">": Greater,
|
||||
">=": GreaterEquals,
|
||||
"in": In,
|
||||
"<": Less,
|
||||
"<=": LessEquals,
|
||||
"%": Modulo,
|
||||
"*": Multiply,
|
||||
"!=": NotEquals,
|
||||
"-": Subtract,
|
||||
}
|
||||
// operatorMap of the operator symbol which refers to a struct containing the display name,
|
||||
// if applicable, the operator precedence, and the arity.
|
||||
//
|
||||
// If the symbol does not have a display name listed in the map, it is only because it requires
|
||||
// special casing to render properly as text.
|
||||
operatorMap = map[string]struct {
|
||||
displayName string
|
||||
precedence int
|
||||
arity int
|
||||
}{
|
||||
Conditional: {displayName: "", precedence: 8, arity: 3},
|
||||
LogicalOr: {displayName: "||", precedence: 7, arity: 2},
|
||||
LogicalAnd: {displayName: "&&", precedence: 6, arity: 2},
|
||||
Equals: {displayName: "==", precedence: 5, arity: 2},
|
||||
Greater: {displayName: ">", precedence: 5, arity: 2},
|
||||
GreaterEquals: {displayName: ">=", precedence: 5, arity: 2},
|
||||
In: {displayName: "in", precedence: 5, arity: 2},
|
||||
Less: {displayName: "<", precedence: 5, arity: 2},
|
||||
LessEquals: {displayName: "<=", precedence: 5, arity: 2},
|
||||
NotEquals: {displayName: "!=", precedence: 5, arity: 2},
|
||||
OldIn: {displayName: "in", precedence: 5, arity: 2},
|
||||
Add: {displayName: "+", precedence: 4, arity: 2},
|
||||
Subtract: {displayName: "-", precedence: 4, arity: 2},
|
||||
Divide: {displayName: "/", precedence: 3, arity: 2},
|
||||
Modulo: {displayName: "%", precedence: 3, arity: 2},
|
||||
Multiply: {displayName: "*", precedence: 3, arity: 2},
|
||||
LogicalNot: {displayName: "!", precedence: 2, arity: 1},
|
||||
Negate: {displayName: "-", precedence: 2, arity: 1},
|
||||
Index: {displayName: "", precedence: 1, arity: 2},
|
||||
}
|
||||
)
|
||||
|
||||
// Find the internal function name for an operator, if the input text is one.
|
||||
func Find(text string) (string, bool) {
|
||||
op, found := operators[text]
|
||||
return op, found
|
||||
}
|
||||
|
||||
// FindReverse returns the unmangled, text representation of the operator.
|
||||
func FindReverse(symbol string) (string, bool) {
|
||||
op, found := operatorMap[symbol]
|
||||
if !found {
|
||||
return "", false
|
||||
}
|
||||
return op.displayName, true
|
||||
}
|
||||
|
||||
// FindReverseBinaryOperator returns the unmangled, text representation of a binary operator.
|
||||
//
|
||||
// If the symbol does refer to an operator, but the operator does not have a display name the
|
||||
// result is false.
|
||||
func FindReverseBinaryOperator(symbol string) (string, bool) {
|
||||
op, found := operatorMap[symbol]
|
||||
if !found || op.arity != 2 {
|
||||
return "", false
|
||||
}
|
||||
if op.displayName == "" {
|
||||
return "", false
|
||||
}
|
||||
return op.displayName, true
|
||||
}
|
||||
|
||||
// Precedence returns the operator precedence, where the higher the number indicates
|
||||
// higher precedence operations.
|
||||
func Precedence(symbol string) int {
|
||||
op, found := operatorMap[symbol]
|
||||
if !found {
|
||||
return 0
|
||||
}
|
||||
return op.precedence
|
||||
}
|
||||
|
||||
// Arity returns the number of argument the operator takes
|
||||
// -1 is returned if an undefined symbol is provided
|
||||
func Arity(symbol string) int {
|
||||
op, found := operatorMap[symbol]
|
||||
if !found {
|
||||
return -1
|
||||
}
|
||||
return op.arity
|
||||
}
|
14
vendor/github.com/google/cel-go/common/overloads/BUILD.bazel
generated
vendored
Normal file
14
vendor/github.com/google/cel-go/common/overloads/BUILD.bazel
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
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 = [
|
||||
"overloads.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/overloads",
|
||||
)
|
317
vendor/github.com/google/cel-go/common/overloads/overloads.go
generated
vendored
Normal file
317
vendor/github.com/google/cel-go/common/overloads/overloads.go
generated
vendored
Normal file
@ -0,0 +1,317 @@
|
||||
// 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 overloads defines the internal overload identifiers for function and
|
||||
// operator overloads.
|
||||
package overloads
|
||||
|
||||
// Boolean logic overloads
|
||||
const (
|
||||
Conditional = "conditional"
|
||||
LogicalAnd = "logical_and"
|
||||
LogicalOr = "logical_or"
|
||||
LogicalNot = "logical_not"
|
||||
NotStrictlyFalse = "not_strictly_false"
|
||||
Equals = "equals"
|
||||
NotEquals = "not_equals"
|
||||
LessBool = "less_bool"
|
||||
LessInt64 = "less_int64"
|
||||
LessInt64Double = "less_int64_double"
|
||||
LessInt64Uint64 = "less_int64_uint64"
|
||||
LessUint64 = "less_uint64"
|
||||
LessUint64Double = "less_uint64_double"
|
||||
LessUint64Int64 = "less_uint64_int64"
|
||||
LessDouble = "less_double"
|
||||
LessDoubleInt64 = "less_double_int64"
|
||||
LessDoubleUint64 = "less_double_uint64"
|
||||
LessString = "less_string"
|
||||
LessBytes = "less_bytes"
|
||||
LessTimestamp = "less_timestamp"
|
||||
LessDuration = "less_duration"
|
||||
LessEqualsBool = "less_equals_bool"
|
||||
LessEqualsInt64 = "less_equals_int64"
|
||||
LessEqualsInt64Double = "less_equals_int64_double"
|
||||
LessEqualsInt64Uint64 = "less_equals_int64_uint64"
|
||||
LessEqualsUint64 = "less_equals_uint64"
|
||||
LessEqualsUint64Double = "less_equals_uint64_double"
|
||||
LessEqualsUint64Int64 = "less_equals_uint64_int64"
|
||||
LessEqualsDouble = "less_equals_double"
|
||||
LessEqualsDoubleInt64 = "less_equals_double_int64"
|
||||
LessEqualsDoubleUint64 = "less_equals_double_uint64"
|
||||
LessEqualsString = "less_equals_string"
|
||||
LessEqualsBytes = "less_equals_bytes"
|
||||
LessEqualsTimestamp = "less_equals_timestamp"
|
||||
LessEqualsDuration = "less_equals_duration"
|
||||
GreaterBool = "greater_bool"
|
||||
GreaterInt64 = "greater_int64"
|
||||
GreaterInt64Double = "greater_int64_double"
|
||||
GreaterInt64Uint64 = "greater_int64_uint64"
|
||||
GreaterUint64 = "greater_uint64"
|
||||
GreaterUint64Double = "greater_uint64_double"
|
||||
GreaterUint64Int64 = "greater_uint64_int64"
|
||||
GreaterDouble = "greater_double"
|
||||
GreaterDoubleInt64 = "greater_double_int64"
|
||||
GreaterDoubleUint64 = "greater_double_uint64"
|
||||
GreaterString = "greater_string"
|
||||
GreaterBytes = "greater_bytes"
|
||||
GreaterTimestamp = "greater_timestamp"
|
||||
GreaterDuration = "greater_duration"
|
||||
GreaterEqualsBool = "greater_equals_bool"
|
||||
GreaterEqualsInt64 = "greater_equals_int64"
|
||||
GreaterEqualsInt64Double = "greater_equals_int64_double"
|
||||
GreaterEqualsInt64Uint64 = "greater_equals_int64_uint64"
|
||||
GreaterEqualsUint64 = "greater_equals_uint64"
|
||||
GreaterEqualsUint64Double = "greater_equals_uint64_double"
|
||||
GreaterEqualsUint64Int64 = "greater_equals_uint64_int64"
|
||||
GreaterEqualsDouble = "greater_equals_double"
|
||||
GreaterEqualsDoubleInt64 = "greater_equals_double_int64"
|
||||
GreaterEqualsDoubleUint64 = "greater_equals_double_uint64"
|
||||
GreaterEqualsString = "greater_equals_string"
|
||||
GreaterEqualsBytes = "greater_equals_bytes"
|
||||
GreaterEqualsTimestamp = "greater_equals_timestamp"
|
||||
GreaterEqualsDuration = "greater_equals_duration"
|
||||
)
|
||||
|
||||
// Math overloads
|
||||
const (
|
||||
AddInt64 = "add_int64"
|
||||
AddUint64 = "add_uint64"
|
||||
AddDouble = "add_double"
|
||||
AddString = "add_string"
|
||||
AddBytes = "add_bytes"
|
||||
AddList = "add_list"
|
||||
AddTimestampDuration = "add_timestamp_duration"
|
||||
AddDurationTimestamp = "add_duration_timestamp"
|
||||
AddDurationDuration = "add_duration_duration"
|
||||
SubtractInt64 = "subtract_int64"
|
||||
SubtractUint64 = "subtract_uint64"
|
||||
SubtractDouble = "subtract_double"
|
||||
SubtractTimestampTimestamp = "subtract_timestamp_timestamp"
|
||||
SubtractTimestampDuration = "subtract_timestamp_duration"
|
||||
SubtractDurationDuration = "subtract_duration_duration"
|
||||
MultiplyInt64 = "multiply_int64"
|
||||
MultiplyUint64 = "multiply_uint64"
|
||||
MultiplyDouble = "multiply_double"
|
||||
DivideInt64 = "divide_int64"
|
||||
DivideUint64 = "divide_uint64"
|
||||
DivideDouble = "divide_double"
|
||||
ModuloInt64 = "modulo_int64"
|
||||
ModuloUint64 = "modulo_uint64"
|
||||
NegateInt64 = "negate_int64"
|
||||
NegateDouble = "negate_double"
|
||||
)
|
||||
|
||||
// Index overloads
|
||||
const (
|
||||
IndexList = "index_list"
|
||||
IndexMap = "index_map"
|
||||
IndexMessage = "index_message" // TODO: introduce concept of types.Message
|
||||
)
|
||||
|
||||
// In operators
|
||||
const (
|
||||
DeprecatedIn = "in"
|
||||
InList = "in_list"
|
||||
InMap = "in_map"
|
||||
InMessage = "in_message" // TODO: introduce concept of types.Message
|
||||
)
|
||||
|
||||
// Size overloads
|
||||
const (
|
||||
Size = "size"
|
||||
SizeString = "size_string"
|
||||
SizeBytes = "size_bytes"
|
||||
SizeList = "size_list"
|
||||
SizeMap = "size_map"
|
||||
SizeStringInst = "string_size"
|
||||
SizeBytesInst = "bytes_size"
|
||||
SizeListInst = "list_size"
|
||||
SizeMapInst = "map_size"
|
||||
)
|
||||
|
||||
// String function names.
|
||||
const (
|
||||
Contains = "contains"
|
||||
EndsWith = "endsWith"
|
||||
Matches = "matches"
|
||||
StartsWith = "startsWith"
|
||||
)
|
||||
|
||||
// String function overload names.
|
||||
const (
|
||||
ContainsString = "contains_string"
|
||||
EndsWithString = "ends_with_string"
|
||||
MatchesString = "matches_string"
|
||||
StartsWithString = "starts_with_string"
|
||||
)
|
||||
|
||||
// Time-based functions.
|
||||
const (
|
||||
TimeGetFullYear = "getFullYear"
|
||||
TimeGetMonth = "getMonth"
|
||||
TimeGetDayOfYear = "getDayOfYear"
|
||||
TimeGetDate = "getDate"
|
||||
TimeGetDayOfMonth = "getDayOfMonth"
|
||||
TimeGetDayOfWeek = "getDayOfWeek"
|
||||
TimeGetHours = "getHours"
|
||||
TimeGetMinutes = "getMinutes"
|
||||
TimeGetSeconds = "getSeconds"
|
||||
TimeGetMilliseconds = "getMilliseconds"
|
||||
)
|
||||
|
||||
// Timestamp overloads for time functions without timezones.
|
||||
const (
|
||||
TimestampToYear = "timestamp_to_year"
|
||||
TimestampToMonth = "timestamp_to_month"
|
||||
TimestampToDayOfYear = "timestamp_to_day_of_year"
|
||||
TimestampToDayOfMonthZeroBased = "timestamp_to_day_of_month"
|
||||
TimestampToDayOfMonthOneBased = "timestamp_to_day_of_month_1_based"
|
||||
TimestampToDayOfWeek = "timestamp_to_day_of_week"
|
||||
TimestampToHours = "timestamp_to_hours"
|
||||
TimestampToMinutes = "timestamp_to_minutes"
|
||||
TimestampToSeconds = "timestamp_to_seconds"
|
||||
TimestampToMilliseconds = "timestamp_to_milliseconds"
|
||||
)
|
||||
|
||||
// Timestamp overloads for time functions with timezones.
|
||||
const (
|
||||
TimestampToYearWithTz = "timestamp_to_year_with_tz"
|
||||
TimestampToMonthWithTz = "timestamp_to_month_with_tz"
|
||||
TimestampToDayOfYearWithTz = "timestamp_to_day_of_year_with_tz"
|
||||
TimestampToDayOfMonthZeroBasedWithTz = "timestamp_to_day_of_month_with_tz"
|
||||
TimestampToDayOfMonthOneBasedWithTz = "timestamp_to_day_of_month_1_based_with_tz"
|
||||
TimestampToDayOfWeekWithTz = "timestamp_to_day_of_week_with_tz"
|
||||
TimestampToHoursWithTz = "timestamp_to_hours_with_tz"
|
||||
TimestampToMinutesWithTz = "timestamp_to_minutes_with_tz"
|
||||
TimestampToSecondsWithTz = "timestamp_to_seconds_tz"
|
||||
TimestampToMillisecondsWithTz = "timestamp_to_milliseconds_with_tz"
|
||||
)
|
||||
|
||||
// Duration overloads for time functions.
|
||||
const (
|
||||
DurationToHours = "duration_to_hours"
|
||||
DurationToMinutes = "duration_to_minutes"
|
||||
DurationToSeconds = "duration_to_seconds"
|
||||
DurationToMilliseconds = "duration_to_milliseconds"
|
||||
)
|
||||
|
||||
// Type conversion methods and overloads
|
||||
const (
|
||||
TypeConvertInt = "int"
|
||||
TypeConvertUint = "uint"
|
||||
TypeConvertDouble = "double"
|
||||
TypeConvertBool = "bool"
|
||||
TypeConvertString = "string"
|
||||
TypeConvertBytes = "bytes"
|
||||
TypeConvertTimestamp = "timestamp"
|
||||
TypeConvertDuration = "duration"
|
||||
TypeConvertType = "type"
|
||||
TypeConvertDyn = "dyn"
|
||||
)
|
||||
|
||||
// Int conversion functions.
|
||||
const (
|
||||
IntToInt = "int64_to_int64"
|
||||
UintToInt = "uint64_to_int64"
|
||||
DoubleToInt = "double_to_int64"
|
||||
StringToInt = "string_to_int64"
|
||||
TimestampToInt = "timestamp_to_int64"
|
||||
DurationToInt = "duration_to_int64"
|
||||
)
|
||||
|
||||
// Uint conversion functions.
|
||||
const (
|
||||
UintToUint = "uint64_to_uint64"
|
||||
IntToUint = "int64_to_uint64"
|
||||
DoubleToUint = "double_to_uint64"
|
||||
StringToUint = "string_to_uint64"
|
||||
)
|
||||
|
||||
// Double conversion functions.
|
||||
const (
|
||||
DoubleToDouble = "double_to_double"
|
||||
IntToDouble = "int64_to_double"
|
||||
UintToDouble = "uint64_to_double"
|
||||
StringToDouble = "string_to_double"
|
||||
)
|
||||
|
||||
// Bool conversion functions.
|
||||
const (
|
||||
BoolToBool = "bool_to_bool"
|
||||
StringToBool = "string_to_bool"
|
||||
)
|
||||
|
||||
// Bytes conversion functions.
|
||||
const (
|
||||
BytesToBytes = "bytes_to_bytes"
|
||||
StringToBytes = "string_to_bytes"
|
||||
)
|
||||
|
||||
// String conversion functions.
|
||||
const (
|
||||
StringToString = "string_to_string"
|
||||
BoolToString = "bool_to_string"
|
||||
IntToString = "int64_to_string"
|
||||
UintToString = "uint64_to_string"
|
||||
DoubleToString = "double_to_string"
|
||||
BytesToString = "bytes_to_string"
|
||||
TimestampToString = "timestamp_to_string"
|
||||
DurationToString = "duration_to_string"
|
||||
)
|
||||
|
||||
// Timestamp conversion functions
|
||||
const (
|
||||
TimestampToTimestamp = "timestamp_to_timestamp"
|
||||
StringToTimestamp = "string_to_timestamp"
|
||||
IntToTimestamp = "int64_to_timestamp"
|
||||
)
|
||||
|
||||
// Convert duration from string
|
||||
const (
|
||||
DurationToDuration = "duration_to_duration"
|
||||
StringToDuration = "string_to_duration"
|
||||
IntToDuration = "int64_to_duration"
|
||||
)
|
||||
|
||||
// Convert to dyn
|
||||
const (
|
||||
ToDyn = "to_dyn"
|
||||
)
|
||||
|
||||
// Comprehensions helper methods, not directly accessible via a developer.
|
||||
const (
|
||||
Iterator = "@iterator"
|
||||
HasNext = "@hasNext"
|
||||
Next = "@next"
|
||||
)
|
||||
|
||||
// IsTypeConversionFunction returns whether the input function is a standard library type
|
||||
// conversion function.
|
||||
func IsTypeConversionFunction(function string) bool {
|
||||
switch function {
|
||||
case TypeConvertBool,
|
||||
TypeConvertBytes,
|
||||
TypeConvertDouble,
|
||||
TypeConvertDuration,
|
||||
TypeConvertDyn,
|
||||
TypeConvertInt,
|
||||
TypeConvertString,
|
||||
TypeConvertTimestamp,
|
||||
TypeConvertType,
|
||||
TypeConvertUint:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
25
vendor/github.com/google/cel-go/common/runes/BUILD.bazel
generated
vendored
Normal file
25
vendor/github.com/google/cel-go/common/runes/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 = [
|
||||
"buffer.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/runes",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"buffer_test.go",
|
||||
],
|
||||
embed = [
|
||||
":go_default_library",
|
||||
],
|
||||
)
|
194
vendor/github.com/google/cel-go/common/runes/buffer.go
generated
vendored
Normal file
194
vendor/github.com/google/cel-go/common/runes/buffer.go
generated
vendored
Normal file
@ -0,0 +1,194 @@
|
||||
// Copyright 2021 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 runes provides interfaces and utilities for working with runes.
|
||||
package runes
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// Buffer is an interface for accessing a contiguous array of code points.
|
||||
type Buffer interface {
|
||||
Get(i int) rune
|
||||
Slice(i, j int) string
|
||||
Len() int
|
||||
}
|
||||
|
||||
type emptyBuffer struct{}
|
||||
|
||||
func (e *emptyBuffer) Get(i int) rune {
|
||||
panic("slice index out of bounds")
|
||||
}
|
||||
|
||||
func (e *emptyBuffer) Slice(i, j int) string {
|
||||
if i != 0 || i != j {
|
||||
panic("slice index out of bounds")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (e *emptyBuffer) Len() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
var _ Buffer = &emptyBuffer{}
|
||||
|
||||
// asciiBuffer is an implementation for an array of code points that contain code points only from
|
||||
// the ASCII character set.
|
||||
type asciiBuffer struct {
|
||||
arr []byte
|
||||
}
|
||||
|
||||
func (a *asciiBuffer) Get(i int) rune {
|
||||
return rune(uint32(a.arr[i]))
|
||||
}
|
||||
|
||||
func (a *asciiBuffer) Slice(i, j int) string {
|
||||
return string(a.arr[i:j])
|
||||
}
|
||||
|
||||
func (a *asciiBuffer) Len() int {
|
||||
return len(a.arr)
|
||||
}
|
||||
|
||||
var _ Buffer = &asciiBuffer{}
|
||||
|
||||
// basicBuffer is an implementation for an array of code points that contain code points from both
|
||||
// the Latin-1 character set and Basic Multilingual Plane.
|
||||
type basicBuffer struct {
|
||||
arr []uint16
|
||||
}
|
||||
|
||||
func (b *basicBuffer) Get(i int) rune {
|
||||
return rune(uint32(b.arr[i]))
|
||||
}
|
||||
|
||||
func (b *basicBuffer) Slice(i, j int) string {
|
||||
var str strings.Builder
|
||||
str.Grow((j - i) * 3) // Worst case encoding size for 0xffff is 3.
|
||||
for ; i < j; i++ {
|
||||
str.WriteRune(rune(uint32(b.arr[i])))
|
||||
}
|
||||
return str.String()
|
||||
}
|
||||
|
||||
func (b *basicBuffer) Len() int {
|
||||
return len(b.arr)
|
||||
}
|
||||
|
||||
var _ Buffer = &basicBuffer{}
|
||||
|
||||
// supplementalBuffer is an implementation for an array of code points that contain code points from
|
||||
// the Latin-1 character set, Basic Multilingual Plane, or the Supplemental Multilingual Plane.
|
||||
type supplementalBuffer struct {
|
||||
arr []rune
|
||||
}
|
||||
|
||||
func (s *supplementalBuffer) Get(i int) rune {
|
||||
return rune(uint32(s.arr[i]))
|
||||
}
|
||||
|
||||
func (s *supplementalBuffer) Slice(i, j int) string {
|
||||
return string(s.arr[i:j])
|
||||
}
|
||||
|
||||
func (s *supplementalBuffer) Len() int {
|
||||
return len(s.arr)
|
||||
}
|
||||
|
||||
var _ Buffer = &supplementalBuffer{}
|
||||
|
||||
var nilBuffer = &emptyBuffer{}
|
||||
|
||||
// NewBuffer returns an efficient implementation of Buffer for the given text based on the ranges of
|
||||
// the encoded code points contained within.
|
||||
//
|
||||
// Code points are represented as an array of byte, uint16, or rune. This approach ensures that
|
||||
// each index represents a code point by itself without needing to use an array of rune. At first
|
||||
// we assume all code points are less than or equal to '\u007f'. If this holds true, the
|
||||
// underlying storage is a byte array containing only ASCII characters. If we encountered a code
|
||||
// point above this range but less than or equal to '\uffff' we allocate a uint16 array, copy the
|
||||
// elements of previous byte array to the uint16 array, and continue. If this holds true, the
|
||||
// underlying storage is a uint16 array containing only Unicode characters in the Basic Multilingual
|
||||
// Plane. If we encounter a code point above '\uffff' we allocate an rune array, copy the previous
|
||||
// elements of the byte or uint16 array, and continue. The underlying storage is an rune array
|
||||
// containing any Unicode character.
|
||||
func NewBuffer(data string) Buffer {
|
||||
if len(data) == 0 {
|
||||
return nilBuffer
|
||||
}
|
||||
var (
|
||||
idx = 0
|
||||
buf8 = make([]byte, 0, len(data))
|
||||
buf16 []uint16
|
||||
buf32 []rune
|
||||
)
|
||||
for idx < len(data) {
|
||||
r, s := utf8.DecodeRuneInString(data[idx:])
|
||||
idx += s
|
||||
if r < utf8.RuneSelf {
|
||||
buf8 = append(buf8, byte(r))
|
||||
continue
|
||||
}
|
||||
if r <= 0xffff {
|
||||
buf16 = make([]uint16, len(buf8), len(data))
|
||||
for i, v := range buf8 {
|
||||
buf16[i] = uint16(v)
|
||||
}
|
||||
buf8 = nil
|
||||
buf16 = append(buf16, uint16(r))
|
||||
goto copy16
|
||||
}
|
||||
buf32 = make([]rune, len(buf8), len(data))
|
||||
for i, v := range buf8 {
|
||||
buf32[i] = rune(uint32(v))
|
||||
}
|
||||
buf8 = nil
|
||||
buf32 = append(buf32, r)
|
||||
goto copy32
|
||||
}
|
||||
return &asciiBuffer{
|
||||
arr: buf8,
|
||||
}
|
||||
copy16:
|
||||
for idx < len(data) {
|
||||
r, s := utf8.DecodeRuneInString(data[idx:])
|
||||
idx += s
|
||||
if r <= 0xffff {
|
||||
buf16 = append(buf16, uint16(r))
|
||||
continue
|
||||
}
|
||||
buf32 = make([]rune, len(buf16), len(data))
|
||||
for i, v := range buf16 {
|
||||
buf32[i] = rune(uint32(v))
|
||||
}
|
||||
buf16 = nil
|
||||
buf32 = append(buf32, r)
|
||||
goto copy32
|
||||
}
|
||||
return &basicBuffer{
|
||||
arr: buf16,
|
||||
}
|
||||
copy32:
|
||||
for idx < len(data) {
|
||||
r, s := utf8.DecodeRuneInString(data[idx:])
|
||||
idx += s
|
||||
buf32 = append(buf32, r)
|
||||
}
|
||||
return &supplementalBuffer{
|
||||
arr: buf32,
|
||||
}
|
||||
}
|
186
vendor/github.com/google/cel-go/common/source.go
generated
vendored
Normal file
186
vendor/github.com/google/cel-go/common/source.go
generated
vendored
Normal file
@ -0,0 +1,186 @@
|
||||
// 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 common
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/google/cel-go/common/runes"
|
||||
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
)
|
||||
|
||||
// Source interface for filter source contents.
|
||||
type Source interface {
|
||||
// Content returns the source content represented as a string.
|
||||
// Examples contents are the single file contents, textbox field,
|
||||
// or url parameter.
|
||||
Content() string
|
||||
|
||||
// Description gives a brief description of the source.
|
||||
// Example descriptions are a file name or ui element.
|
||||
Description() string
|
||||
|
||||
// LineOffsets gives the character offsets at which lines occur.
|
||||
// The zero-th entry should refer to the break between the first
|
||||
// and second line, or EOF if there is only one line of source.
|
||||
LineOffsets() []int32
|
||||
|
||||
// LocationOffset translates a Location to an offset.
|
||||
// Given the line and column of the Location returns the
|
||||
// Location's character offset in the Source, and a bool
|
||||
// indicating whether the Location was found.
|
||||
LocationOffset(location Location) (int32, bool)
|
||||
|
||||
// OffsetLocation translates a character offset to a Location, or
|
||||
// false if the conversion was not feasible.
|
||||
OffsetLocation(offset int32) (Location, bool)
|
||||
|
||||
// NewLocation takes an input line and column and produces a Location.
|
||||
// The default behavior is to treat the line and column as absolute,
|
||||
// but concrete derivations may use this method to convert a relative
|
||||
// line and column position into an absolute location.
|
||||
NewLocation(line, col int) Location
|
||||
|
||||
// Snippet returns a line of content and whether the line was found.
|
||||
Snippet(line int) (string, bool)
|
||||
}
|
||||
|
||||
// The sourceImpl type implementation of the Source interface.
|
||||
type sourceImpl struct {
|
||||
runes.Buffer
|
||||
description string
|
||||
lineOffsets []int32
|
||||
idOffsets map[int64]int32
|
||||
}
|
||||
|
||||
var _ runes.Buffer = &sourceImpl{}
|
||||
|
||||
// TODO(jimlarson) "Character offsets" should index the code points
|
||||
// within the UTF-8 encoded string. It currently indexes bytes.
|
||||
// Can be accomplished by using rune[] instead of string for contents.
|
||||
|
||||
// NewTextSource creates a new Source from the input text string.
|
||||
func NewTextSource(text string) Source {
|
||||
return NewStringSource(text, "<input>")
|
||||
}
|
||||
|
||||
// NewStringSource creates a new Source from the given contents and description.
|
||||
func NewStringSource(contents string, description string) Source {
|
||||
// Compute line offsets up front as they are referred to frequently.
|
||||
lines := strings.Split(contents, "\n")
|
||||
offsets := make([]int32, len(lines))
|
||||
var offset int32
|
||||
for i, line := range lines {
|
||||
offset = offset + int32(utf8.RuneCountInString(line)) + 1
|
||||
offsets[int32(i)] = offset
|
||||
}
|
||||
return &sourceImpl{
|
||||
Buffer: runes.NewBuffer(contents),
|
||||
description: description,
|
||||
lineOffsets: offsets,
|
||||
idOffsets: map[int64]int32{},
|
||||
}
|
||||
}
|
||||
|
||||
// NewInfoSource creates a new Source from a SourceInfo.
|
||||
func NewInfoSource(info *exprpb.SourceInfo) Source {
|
||||
return &sourceImpl{
|
||||
Buffer: runes.NewBuffer(""),
|
||||
description: info.GetLocation(),
|
||||
lineOffsets: info.GetLineOffsets(),
|
||||
idOffsets: info.GetPositions(),
|
||||
}
|
||||
}
|
||||
|
||||
// Content implements the Source interface method.
|
||||
func (s *sourceImpl) Content() string {
|
||||
return s.Slice(0, s.Len())
|
||||
}
|
||||
|
||||
// Description implements the Source interface method.
|
||||
func (s *sourceImpl) Description() string {
|
||||
return s.description
|
||||
}
|
||||
|
||||
// LineOffsets implements the Source interface method.
|
||||
func (s *sourceImpl) LineOffsets() []int32 {
|
||||
return s.lineOffsets
|
||||
}
|
||||
|
||||
// LocationOffset implements the Source interface method.
|
||||
func (s *sourceImpl) LocationOffset(location Location) (int32, bool) {
|
||||
if lineOffset, found := s.findLineOffset(location.Line()); found {
|
||||
return lineOffset + int32(location.Column()), true
|
||||
}
|
||||
return -1, false
|
||||
}
|
||||
|
||||
// NewLocation implements the Source interface method.
|
||||
func (s *sourceImpl) NewLocation(line, col int) Location {
|
||||
return NewLocation(line, col)
|
||||
}
|
||||
|
||||
// OffsetLocation implements the Source interface method.
|
||||
func (s *sourceImpl) OffsetLocation(offset int32) (Location, bool) {
|
||||
line, lineOffset := s.findLine(offset)
|
||||
return NewLocation(int(line), int(offset-lineOffset)), true
|
||||
}
|
||||
|
||||
// Snippet implements the Source interface method.
|
||||
func (s *sourceImpl) Snippet(line int) (string, bool) {
|
||||
charStart, found := s.findLineOffset(line)
|
||||
if !found || s.Len() == 0 {
|
||||
return "", false
|
||||
}
|
||||
charEnd, found := s.findLineOffset(line + 1)
|
||||
if found {
|
||||
return s.Slice(int(charStart), int(charEnd-1)), true
|
||||
}
|
||||
return s.Slice(int(charStart), s.Len()), true
|
||||
}
|
||||
|
||||
// findLineOffset returns the offset where the (1-indexed) line begins,
|
||||
// or false if line doesn't exist.
|
||||
func (s *sourceImpl) findLineOffset(line int) (int32, bool) {
|
||||
if line == 1 {
|
||||
return 0, true
|
||||
}
|
||||
if line > 1 && line <= int(len(s.lineOffsets)) {
|
||||
offset := s.lineOffsets[line-2]
|
||||
return offset, true
|
||||
}
|
||||
return -1, false
|
||||
}
|
||||
|
||||
// findLine finds the line that contains the given character offset and
|
||||
// returns the line number and offset of the beginning of that line.
|
||||
// Note that the last line is treated as if it contains all offsets
|
||||
// beyond the end of the actual source.
|
||||
func (s *sourceImpl) findLine(characterOffset int32) (int32, int32) {
|
||||
var line int32 = 1
|
||||
for _, lineOffset := range s.lineOffsets {
|
||||
if lineOffset > characterOffset {
|
||||
break
|
||||
} else {
|
||||
line++
|
||||
}
|
||||
}
|
||||
if line == 1 {
|
||||
return line, 0
|
||||
}
|
||||
return line, s.lineOffsets[line-2]
|
||||
}
|
89
vendor/github.com/google/cel-go/common/types/BUILD.bazel
generated
vendored
Normal file
89
vendor/github.com/google/cel-go/common/types/BUILD.bazel
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
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 = [
|
||||
"any_value.go",
|
||||
"bool.go",
|
||||
"bytes.go",
|
||||
"compare.go",
|
||||
"double.go",
|
||||
"duration.go",
|
||||
"err.go",
|
||||
"int.go",
|
||||
"iterator.go",
|
||||
"json_value.go",
|
||||
"list.go",
|
||||
"map.go",
|
||||
"null.go",
|
||||
"object.go",
|
||||
"overflow.go",
|
||||
"provider.go",
|
||||
"string.go",
|
||||
"timestamp.go",
|
||||
"type.go",
|
||||
"uint.go",
|
||||
"unknown.go",
|
||||
"util.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/types",
|
||||
deps = [
|
||||
"//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_grpc//codes:go_default_library",
|
||||
"@org_golang_google_grpc//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",
|
||||
"@org_golang_google_protobuf//types/known/anypb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/durationpb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/structpb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/timestamppb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/wrapperspb:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"bool_test.go",
|
||||
"bytes_test.go",
|
||||
"double_test.go",
|
||||
"duration_test.go",
|
||||
"int_test.go",
|
||||
"json_list_test.go",
|
||||
"json_struct_test.go",
|
||||
"list_test.go",
|
||||
"map_test.go",
|
||||
"null_test.go",
|
||||
"object_test.go",
|
||||
"provider_test.go",
|
||||
"string_test.go",
|
||||
"timestamp_test.go",
|
||||
"type_test.go",
|
||||
"uint_test.go",
|
||||
"util_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//common/types/ref:go_default_library",
|
||||
"//test:go_default_library",
|
||||
"//test/proto3pb:test_all_types_go_proto",
|
||||
"@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
|
||||
"@org_golang_google_protobuf//encoding/protojson:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/anypb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/durationpb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/timestamppb:go_default_library",
|
||||
],
|
||||
)
|
24
vendor/github.com/google/cel-go/common/types/any_value.go
generated
vendored
Normal file
24
vendor/github.com/google/cel-go/common/types/any_value.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
// 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 (
|
||||
"reflect"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
)
|
||||
|
||||
// anyValueType constant representing the reflected type of google.protobuf.Any.
|
||||
var anyValueType = reflect.TypeOf(&anypb.Any{})
|
142
vendor/github.com/google/cel-go/common/types/bool.go
generated
vendored
Normal file
142
vendor/github.com/google/cel-go/common/types/bool.go
generated
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
// 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"
|
||||
"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"
|
||||
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
|
||||
)
|
||||
|
||||
// Bool type that implements ref.Val and supports comparison and negation.
|
||||
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{})
|
||||
)
|
||||
|
||||
// Boolean constants
|
||||
const (
|
||||
False = Bool(false)
|
||||
True = Bool(true)
|
||||
)
|
||||
|
||||
// Compare implements the traits.Comparer interface method.
|
||||
func (b Bool) Compare(other ref.Val) ref.Val {
|
||||
otherBool, ok := other.(Bool)
|
||||
if !ok {
|
||||
return ValOrErr(other, "no such overload")
|
||||
}
|
||||
if b == otherBool {
|
||||
return IntZero
|
||||
}
|
||||
if !b && otherBool {
|
||||
return IntNegOne
|
||||
}
|
||||
return IntOne
|
||||
}
|
||||
|
||||
// ConvertToNative implements the ref.Val interface method.
|
||||
func (b Bool) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
switch typeDesc.Kind() {
|
||||
case reflect.Bool:
|
||||
return reflect.ValueOf(b).Convert(typeDesc).Interface(), nil
|
||||
case reflect.Ptr:
|
||||
switch typeDesc {
|
||||
case anyValueType:
|
||||
// Primitives must be wrapped to a wrapperspb.BoolValue before being packed into an Any.
|
||||
return anypb.New(wrapperspb.Bool(bool(b)))
|
||||
case boolWrapperType:
|
||||
// Convert the bool to a wrapperspb.BoolValue.
|
||||
return wrapperspb.Bool(bool(b)), nil
|
||||
case jsonValueType:
|
||||
// Return the bool as a new structpb.Value.
|
||||
return structpb.NewBoolValue(bool(b)), nil
|
||||
default:
|
||||
if typeDesc.Elem().Kind() == reflect.Bool {
|
||||
p := bool(b)
|
||||
return &p, nil
|
||||
}
|
||||
}
|
||||
case reflect.Interface:
|
||||
bv := b.Value()
|
||||
if reflect.TypeOf(bv).Implements(typeDesc) {
|
||||
return bv, nil
|
||||
}
|
||||
if reflect.TypeOf(b).Implements(typeDesc) {
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("type conversion error from bool to '%v'", typeDesc)
|
||||
}
|
||||
|
||||
// ConvertToType implements the ref.Val interface method.
|
||||
func (b Bool) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case StringType:
|
||||
return String(strconv.FormatBool(bool(b)))
|
||||
case BoolType:
|
||||
return b
|
||||
case TypeType:
|
||||
return BoolType
|
||||
}
|
||||
return NewErr("type conversion error from '%v' to '%v'", BoolType, typeVal)
|
||||
}
|
||||
|
||||
// Equal implements the ref.Val interface method.
|
||||
func (b Bool) Equal(other ref.Val) ref.Val {
|
||||
otherBool, ok := other.(Bool)
|
||||
return Bool(ok && b == otherBool)
|
||||
}
|
||||
|
||||
// Negate implements the traits.Negater interface method.
|
||||
func (b Bool) Negate() ref.Val {
|
||||
return !b
|
||||
}
|
||||
|
||||
// Type implements the ref.Val interface method.
|
||||
func (b Bool) Type() ref.Type {
|
||||
return BoolType
|
||||
}
|
||||
|
||||
// Value implements the ref.Val interface method.
|
||||
func (b Bool) Value() interface{} {
|
||||
return bool(b)
|
||||
}
|
||||
|
||||
// IsBool returns whether the input ref.Val or ref.Type is equal to BoolType.
|
||||
func IsBool(elem ref.Val) bool {
|
||||
switch v := elem.(type) {
|
||||
case Bool:
|
||||
return true
|
||||
case ref.Val:
|
||||
return v.Type() == BoolType
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
132
vendor/github.com/google/cel-go/common/types/bytes.go
generated
vendored
Normal file
132
vendor/github.com/google/cel-go/common/types/bytes.go
generated
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
// 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 (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"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"
|
||||
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
|
||||
)
|
||||
|
||||
// Bytes type that implements ref.Val and supports add, compare, and size
|
||||
// operations.
|
||||
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{})
|
||||
)
|
||||
|
||||
// Add implements traits.Adder interface method by concatenating byte sequences.
|
||||
func (b Bytes) Add(other ref.Val) ref.Val {
|
||||
otherBytes, ok := other.(Bytes)
|
||||
if !ok {
|
||||
return ValOrErr(other, "no such overload")
|
||||
}
|
||||
return append(b, otherBytes...)
|
||||
}
|
||||
|
||||
// Compare implements traits.Comparer interface method by lexicographic ordering.
|
||||
func (b Bytes) Compare(other ref.Val) ref.Val {
|
||||
otherBytes, ok := other.(Bytes)
|
||||
if !ok {
|
||||
return ValOrErr(other, "no such overload")
|
||||
}
|
||||
return Int(bytes.Compare(b, otherBytes))
|
||||
}
|
||||
|
||||
// ConvertToNative implements the ref.Val interface method.
|
||||
func (b Bytes) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
switch typeDesc.Kind() {
|
||||
case reflect.Array, reflect.Slice:
|
||||
return reflect.ValueOf(b).Convert(typeDesc).Interface(), nil
|
||||
case reflect.Ptr:
|
||||
switch typeDesc {
|
||||
case anyValueType:
|
||||
// Primitives must be wrapped before being set on an Any field.
|
||||
return anypb.New(wrapperspb.Bytes([]byte(b)))
|
||||
case byteWrapperType:
|
||||
// Convert the bytes to a wrapperspb.BytesValue.
|
||||
return wrapperspb.Bytes([]byte(b)), nil
|
||||
case jsonValueType:
|
||||
// CEL follows the proto3 to JSON conversion by encoding bytes to a string via base64.
|
||||
// The encoding below matches the golang 'encoding/json' behavior during marshaling,
|
||||
// which uses base64.StdEncoding.
|
||||
str := base64.StdEncoding.EncodeToString([]byte(b))
|
||||
return structpb.NewStringValue(str), nil
|
||||
}
|
||||
case reflect.Interface:
|
||||
bv := b.Value()
|
||||
if reflect.TypeOf(bv).Implements(typeDesc) {
|
||||
return bv, nil
|
||||
}
|
||||
if reflect.TypeOf(b).Implements(typeDesc) {
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("type conversion error from Bytes to '%v'", typeDesc)
|
||||
}
|
||||
|
||||
// ConvertToType implements the ref.Val interface method.
|
||||
func (b Bytes) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case StringType:
|
||||
if !utf8.Valid(b) {
|
||||
return NewErr("invalid UTF-8 in bytes, cannot convert to string")
|
||||
}
|
||||
return String(b)
|
||||
case BytesType:
|
||||
return b
|
||||
case TypeType:
|
||||
return BytesType
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", BytesType, typeVal)
|
||||
}
|
||||
|
||||
// Equal implements the ref.Val interface method.
|
||||
func (b Bytes) Equal(other ref.Val) ref.Val {
|
||||
otherBytes, ok := other.(Bytes)
|
||||
return Bool(ok && bytes.Equal(b, otherBytes))
|
||||
}
|
||||
|
||||
// Size implements the traits.Sizer interface method.
|
||||
func (b Bytes) Size() ref.Val {
|
||||
return Int(len(b))
|
||||
}
|
||||
|
||||
// Type implements the ref.Val interface method.
|
||||
func (b Bytes) Type() ref.Type {
|
||||
return BytesType
|
||||
}
|
||||
|
||||
// Value implements the ref.Val interface method.
|
||||
func (b Bytes) Value() interface{} {
|
||||
return []byte(b)
|
||||
}
|
97
vendor/github.com/google/cel-go/common/types/compare.go
generated
vendored
Normal file
97
vendor/github.com/google/cel-go/common/types/compare.go
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
// Copyright 2021 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 (
|
||||
"math"
|
||||
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
)
|
||||
|
||||
func compareDoubleInt(d Double, i Int) Int {
|
||||
if d < math.MinInt64 {
|
||||
return IntNegOne
|
||||
}
|
||||
if d > math.MaxInt64 {
|
||||
return IntOne
|
||||
}
|
||||
return compareDouble(d, Double(i))
|
||||
}
|
||||
|
||||
func compareIntDouble(i Int, d Double) Int {
|
||||
return -compareDoubleInt(d, i)
|
||||
}
|
||||
|
||||
func compareDoubleUint(d Double, u Uint) Int {
|
||||
if d < 0 {
|
||||
return IntNegOne
|
||||
}
|
||||
if d > math.MaxUint64 {
|
||||
return IntOne
|
||||
}
|
||||
return compareDouble(d, Double(u))
|
||||
}
|
||||
|
||||
func compareUintDouble(u Uint, d Double) Int {
|
||||
return -compareDoubleUint(d, u)
|
||||
}
|
||||
|
||||
func compareIntUint(i Int, u Uint) Int {
|
||||
if i < 0 || u > math.MaxInt64 {
|
||||
return IntNegOne
|
||||
}
|
||||
cmp := i - Int(u)
|
||||
if cmp < 0 {
|
||||
return IntNegOne
|
||||
}
|
||||
if cmp > 0 {
|
||||
return IntOne
|
||||
}
|
||||
return IntZero
|
||||
}
|
||||
|
||||
func compareUintInt(u Uint, i Int) Int {
|
||||
return -compareIntUint(i, u)
|
||||
}
|
||||
|
||||
func compareDouble(a, b Double) Int {
|
||||
if a < b {
|
||||
return IntNegOne
|
||||
}
|
||||
if a > b {
|
||||
return IntOne
|
||||
}
|
||||
return IntZero
|
||||
}
|
||||
|
||||
func compareInt(a, b Int) ref.Val {
|
||||
if a < b {
|
||||
return IntNegOne
|
||||
}
|
||||
if a > b {
|
||||
return IntOne
|
||||
}
|
||||
return IntZero
|
||||
}
|
||||
|
||||
func compareUint(a, b Uint) ref.Val {
|
||||
if a < b {
|
||||
return IntNegOne
|
||||
}
|
||||
if a > b {
|
||||
return IntOne
|
||||
}
|
||||
return IntZero
|
||||
}
|
17
vendor/github.com/google/cel-go/common/types/doc.go
generated
vendored
Normal file
17
vendor/github.com/google/cel-go/common/types/doc.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// 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 contains the types, traits, and utilities common to all
|
||||
// components of expression handling.
|
||||
package types
|
216
vendor/github.com/google/cel-go/common/types/double.go
generated
vendored
Normal file
216
vendor/github.com/google/cel-go/common/types/double.go
generated
vendored
Normal file
@ -0,0 +1,216 @@
|
||||
// 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"
|
||||
"math"
|
||||
"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"
|
||||
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
|
||||
)
|
||||
|
||||
// Double type that implements ref.Val, comparison, and mathematical
|
||||
// operations.
|
||||
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{})
|
||||
|
||||
// floatWrapperType reflected type for protobuf float wrapper type.
|
||||
floatWrapperType = reflect.TypeOf(&wrapperspb.FloatValue{})
|
||||
)
|
||||
|
||||
// Add implements traits.Adder.Add.
|
||||
func (d Double) Add(other ref.Val) ref.Val {
|
||||
otherDouble, ok := other.(Double)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
return d + otherDouble
|
||||
}
|
||||
|
||||
// Compare implements traits.Comparer.Compare.
|
||||
func (d Double) Compare(other ref.Val) ref.Val {
|
||||
if math.IsNaN(float64(d)) {
|
||||
return NewErr("NaN values cannot be ordered")
|
||||
}
|
||||
switch ov := other.(type) {
|
||||
case Double:
|
||||
if math.IsNaN(float64(ov)) {
|
||||
return NewErr("NaN values cannot be ordered")
|
||||
}
|
||||
return compareDouble(d, ov)
|
||||
case Int:
|
||||
return compareDoubleInt(d, ov)
|
||||
case Uint:
|
||||
return compareDoubleUint(d, ov)
|
||||
default:
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertToNative implements ref.Val.ConvertToNative.
|
||||
func (d Double) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
switch typeDesc.Kind() {
|
||||
case reflect.Float32:
|
||||
v := float32(d)
|
||||
return reflect.ValueOf(v).Convert(typeDesc).Interface(), nil
|
||||
case reflect.Float64:
|
||||
v := float64(d)
|
||||
return reflect.ValueOf(v).Convert(typeDesc).Interface(), nil
|
||||
case reflect.Ptr:
|
||||
switch typeDesc {
|
||||
case anyValueType:
|
||||
// Primitives must be wrapped before being set on an Any field.
|
||||
return anypb.New(wrapperspb.Double(float64(d)))
|
||||
case doubleWrapperType:
|
||||
// Convert to a wrapperspb.DoubleValue
|
||||
return wrapperspb.Double(float64(d)), nil
|
||||
case floatWrapperType:
|
||||
// Convert to a wrapperspb.FloatValue (with truncation).
|
||||
return wrapperspb.Float(float32(d)), nil
|
||||
case jsonValueType:
|
||||
// Note, there are special cases for proto3 to json conversion that
|
||||
// expect the floating point value to be converted to a NaN,
|
||||
// Infinity, or -Infinity string values, but the jsonpb string
|
||||
// marshaling of the protobuf.Value will handle this conversion.
|
||||
return structpb.NewNumberValue(float64(d)), nil
|
||||
}
|
||||
switch typeDesc.Elem().Kind() {
|
||||
case reflect.Float32:
|
||||
v := float32(d)
|
||||
p := reflect.New(typeDesc.Elem())
|
||||
p.Elem().Set(reflect.ValueOf(v).Convert(typeDesc.Elem()))
|
||||
return p.Interface(), nil
|
||||
case reflect.Float64:
|
||||
v := float64(d)
|
||||
p := reflect.New(typeDesc.Elem())
|
||||
p.Elem().Set(reflect.ValueOf(v).Convert(typeDesc.Elem()))
|
||||
return p.Interface(), nil
|
||||
}
|
||||
case reflect.Interface:
|
||||
dv := d.Value()
|
||||
if reflect.TypeOf(dv).Implements(typeDesc) {
|
||||
return dv, nil
|
||||
}
|
||||
if reflect.TypeOf(d).Implements(typeDesc) {
|
||||
return d, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("type conversion error from Double to '%v'", typeDesc)
|
||||
}
|
||||
|
||||
// ConvertToType implements ref.Val.ConvertToType.
|
||||
func (d Double) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case IntType:
|
||||
i, err := doubleToInt64Checked(float64(d))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Int(i)
|
||||
case UintType:
|
||||
i, err := doubleToUint64Checked(float64(d))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Uint(i)
|
||||
case DoubleType:
|
||||
return d
|
||||
case StringType:
|
||||
return String(fmt.Sprintf("%g", float64(d)))
|
||||
case TypeType:
|
||||
return DoubleType
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", DoubleType, typeVal)
|
||||
}
|
||||
|
||||
// Divide implements traits.Divider.Divide.
|
||||
func (d Double) Divide(other ref.Val) ref.Val {
|
||||
otherDouble, ok := other.(Double)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
return d / otherDouble
|
||||
}
|
||||
|
||||
// Equal implements ref.Val.Equal.
|
||||
func (d Double) Equal(other ref.Val) ref.Val {
|
||||
if math.IsNaN(float64(d)) {
|
||||
return False
|
||||
}
|
||||
switch ov := other.(type) {
|
||||
case Double:
|
||||
if math.IsNaN(float64(ov)) {
|
||||
return False
|
||||
}
|
||||
return Bool(d == ov)
|
||||
case Int:
|
||||
return Bool(compareDoubleInt(d, ov) == 0)
|
||||
case Uint:
|
||||
return Bool(compareDoubleUint(d, ov) == 0)
|
||||
default:
|
||||
return False
|
||||
}
|
||||
}
|
||||
|
||||
// Multiply implements traits.Multiplier.Multiply.
|
||||
func (d Double) Multiply(other ref.Val) ref.Val {
|
||||
otherDouble, ok := other.(Double)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
return d * otherDouble
|
||||
}
|
||||
|
||||
// Negate implements traits.Negater.Negate.
|
||||
func (d Double) Negate() ref.Val {
|
||||
return -d
|
||||
}
|
||||
|
||||
// Subtract implements traits.Subtractor.Subtract.
|
||||
func (d Double) Subtract(subtrahend ref.Val) ref.Val {
|
||||
subtraDouble, ok := subtrahend.(Double)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(subtrahend)
|
||||
}
|
||||
return d - subtraDouble
|
||||
}
|
||||
|
||||
// Type implements ref.Val.Type.
|
||||
func (d Double) Type() ref.Type {
|
||||
return DoubleType
|
||||
}
|
||||
|
||||
// Value implements ref.Val.Value.
|
||||
func (d Double) Value() interface{} {
|
||||
return float64(d)
|
||||
}
|
199
vendor/github.com/google/cel-go/common/types/duration.go
generated
vendored
Normal file
199
vendor/github.com/google/cel-go/common/types/duration.go
generated
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
// 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"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"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"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
// Duration type that implements ref.Val and supports add, compare, negate,
|
||||
// and subtract operators. This type is also a receiver which means it can
|
||||
// participate in dispatch to receiver functions.
|
||||
type Duration struct {
|
||||
time.Duration
|
||||
}
|
||||
|
||||
func durationOf(d time.Duration) Duration {
|
||||
return Duration{Duration: d}
|
||||
}
|
||||
|
||||
var (
|
||||
// DurationType singleton.
|
||||
DurationType = NewTypeValue("google.protobuf.Duration",
|
||||
traits.AdderType,
|
||||
traits.ComparerType,
|
||||
traits.NegatorType,
|
||||
traits.ReceiverType,
|
||||
traits.SubtractorType)
|
||||
)
|
||||
|
||||
// Add implements traits.Adder.Add.
|
||||
func (d Duration) Add(other ref.Val) ref.Val {
|
||||
switch other.Type() {
|
||||
case DurationType:
|
||||
dur2 := other.(Duration)
|
||||
val, err := addDurationChecked(d.Duration, dur2.Duration)
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return durationOf(val)
|
||||
case TimestampType:
|
||||
ts := other.(Timestamp).Time
|
||||
val, err := addTimeDurationChecked(ts, d.Duration)
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return timestampOf(val)
|
||||
}
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
|
||||
// Compare implements traits.Comparer.Compare.
|
||||
func (d Duration) Compare(other ref.Val) ref.Val {
|
||||
otherDur, ok := other.(Duration)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
d1 := d.Duration
|
||||
d2 := otherDur.Duration
|
||||
switch {
|
||||
case d1 < d2:
|
||||
return IntNegOne
|
||||
case d1 > d2:
|
||||
return IntOne
|
||||
default:
|
||||
return IntZero
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertToNative implements ref.Val.ConvertToNative.
|
||||
func (d Duration) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
// If the duration is already assignable to the desired type return it.
|
||||
if reflect.TypeOf(d.Duration).AssignableTo(typeDesc) {
|
||||
return d.Duration, nil
|
||||
}
|
||||
if reflect.TypeOf(d).AssignableTo(typeDesc) {
|
||||
return d, nil
|
||||
}
|
||||
switch typeDesc {
|
||||
case anyValueType:
|
||||
// Pack the duration as a dpb.Duration into an Any value.
|
||||
return anypb.New(dpb.New(d.Duration))
|
||||
case durationValueType:
|
||||
// Unwrap the CEL value to its underlying proto value.
|
||||
return dpb.New(d.Duration), nil
|
||||
case jsonValueType:
|
||||
// CEL follows the proto3 to JSON conversion.
|
||||
// Note, using jsonpb would wrap the result in extra double quotes.
|
||||
v := d.ConvertToType(StringType)
|
||||
if IsError(v) {
|
||||
return nil, v.(*Err)
|
||||
}
|
||||
return structpb.NewStringValue(string(v.(String))), nil
|
||||
}
|
||||
return nil, fmt.Errorf("type conversion error from 'Duration' to '%v'", typeDesc)
|
||||
}
|
||||
|
||||
// ConvertToType implements ref.Val.ConvertToType.
|
||||
func (d Duration) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case StringType:
|
||||
return String(strconv.FormatFloat(d.Seconds(), 'f', -1, 64) + "s")
|
||||
case IntType:
|
||||
return Int(d.Duration)
|
||||
case DurationType:
|
||||
return d
|
||||
case TypeType:
|
||||
return DurationType
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", DurationType, typeVal)
|
||||
}
|
||||
|
||||
// Equal implements ref.Val.Equal.
|
||||
func (d Duration) Equal(other ref.Val) ref.Val {
|
||||
otherDur, ok := other.(Duration)
|
||||
return Bool(ok && d.Duration == otherDur.Duration)
|
||||
}
|
||||
|
||||
// Negate implements traits.Negater.Negate.
|
||||
func (d Duration) Negate() ref.Val {
|
||||
val, err := negateDurationChecked(d.Duration)
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return durationOf(val)
|
||||
}
|
||||
|
||||
// Receive implements traits.Receiver.Receive.
|
||||
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 NoSuchOverloadErr()
|
||||
}
|
||||
|
||||
// Subtract implements traits.Subtractor.Subtract.
|
||||
func (d Duration) Subtract(subtrahend ref.Val) ref.Val {
|
||||
subtraDur, ok := subtrahend.(Duration)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(subtrahend)
|
||||
}
|
||||
val, err := subtractDurationChecked(d.Duration, subtraDur.Duration)
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return durationOf(val)
|
||||
}
|
||||
|
||||
// Type implements ref.Val.Type.
|
||||
func (d Duration) Type() ref.Type {
|
||||
return DurationType
|
||||
}
|
||||
|
||||
// Value implements ref.Val.Value.
|
||||
func (d Duration) Value() interface{} {
|
||||
return d.Duration
|
||||
}
|
||||
|
||||
var (
|
||||
durationValueType = reflect.TypeOf(&dpb.Duration{})
|
||||
|
||||
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())
|
||||
}}
|
||||
)
|
130
vendor/github.com/google/cel-go/common/types/err.go
generated
vendored
Normal file
130
vendor/github.com/google/cel-go/common/types/err.go
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
// 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 (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
)
|
||||
|
||||
// Err type which extends the built-in go error and implements ref.Val.
|
||||
type Err struct {
|
||||
error
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrType singleton.
|
||||
ErrType = NewTypeValue("error")
|
||||
|
||||
// errDivideByZero is an error indicating a division by zero of an integer value.
|
||||
errDivideByZero = errors.New("division by zero")
|
||||
// errModulusByZero is an error indicating a modulus by zero of an integer value.
|
||||
errModulusByZero = errors.New("modulus by zero")
|
||||
// errIntOverflow is an error representing integer overflow.
|
||||
errIntOverflow = errors.New("integer overflow")
|
||||
// errUintOverflow is an error representing unsigned integer overflow.
|
||||
errUintOverflow = errors.New("unsigned integer overflow")
|
||||
// errDurationOverflow is an error representing duration overflow.
|
||||
errDurationOverflow = errors.New("duration overflow")
|
||||
// errTimestampOverflow is an error representing timestamp overflow.
|
||||
errTimestampOverflow = errors.New("timestamp overflow")
|
||||
celErrTimestampOverflow = &Err{error: errTimestampOverflow}
|
||||
|
||||
// celErrNoSuchOverload indicates that the call arguments did not match a supported method signature.
|
||||
celErrNoSuchOverload = NewErr("no such overload")
|
||||
)
|
||||
|
||||
// NewErr creates a new Err described by the format string and args.
|
||||
// TODO: Audit the use of this function and standardize the error messages and codes.
|
||||
func NewErr(format string, args ...interface{}) ref.Val {
|
||||
return &Err{fmt.Errorf(format, args...)}
|
||||
}
|
||||
|
||||
// NoSuchOverloadErr returns a new types.Err instance with a no such overload message.
|
||||
func NoSuchOverloadErr() ref.Val {
|
||||
return celErrNoSuchOverload
|
||||
}
|
||||
|
||||
// UnsupportedRefValConversionErr returns a types.NewErr instance with a no such conversion
|
||||
// message that indicates that the native value could not be converted to a CEL ref.Val.
|
||||
func UnsupportedRefValConversionErr(val interface{}) ref.Val {
|
||||
return NewErr("unsupported conversion to ref.Val: (%T)%v", val, val)
|
||||
}
|
||||
|
||||
// MaybeNoSuchOverloadErr returns the error or unknown if the input ref.Val is one of these types,
|
||||
// else a new no such overload error.
|
||||
func MaybeNoSuchOverloadErr(val ref.Val) ref.Val {
|
||||
return ValOrErr(val, "no such overload")
|
||||
}
|
||||
|
||||
// ValOrErr either returns the existing error or creates a new one.
|
||||
// TODO: Audit the use of this function and standardize the error messages and codes.
|
||||
func ValOrErr(val ref.Val, format string, args ...interface{}) ref.Val {
|
||||
if val == nil || !IsUnknownOrError(val) {
|
||||
return NewErr(format, args...)
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// wrapErr wraps an existing Go error value into a CEL Err value.
|
||||
func wrapErr(err error) ref.Val {
|
||||
return &Err{error: err}
|
||||
}
|
||||
|
||||
// ConvertToNative implements ref.Val.ConvertToNative.
|
||||
func (e *Err) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
return nil, e.error
|
||||
}
|
||||
|
||||
// ConvertToType implements ref.Val.ConvertToType.
|
||||
func (e *Err) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
// Errors are not convertible to other representations.
|
||||
return e
|
||||
}
|
||||
|
||||
// Equal implements ref.Val.Equal.
|
||||
func (e *Err) Equal(other ref.Val) ref.Val {
|
||||
// An error cannot be equal to any other value, so it returns itself.
|
||||
return e
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
func (e *Err) String() string {
|
||||
return e.error.Error()
|
||||
}
|
||||
|
||||
// Type implements ref.Val.Type.
|
||||
func (e *Err) Type() ref.Type {
|
||||
return ErrType
|
||||
}
|
||||
|
||||
// Value implements ref.Val.Value.
|
||||
func (e *Err) Value() interface{} {
|
||||
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 {
|
||||
switch val.(type) {
|
||||
case *Err:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
297
vendor/github.com/google/cel-go/common/types/int.go
generated
vendored
Normal file
297
vendor/github.com/google/cel-go/common/types/int.go
generated
vendored
Normal file
@ -0,0 +1,297 @@
|
||||
// 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"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"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"
|
||||
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
|
||||
)
|
||||
|
||||
// Int type that implements ref.Val as well as comparison and math operators.
|
||||
type Int int64
|
||||
|
||||
// Int constants used for comparison results.
|
||||
const (
|
||||
// IntZero is the zero-value for Int
|
||||
IntZero = Int(0)
|
||||
IntOne = Int(1)
|
||||
IntNegOne = Int(-1)
|
||||
)
|
||||
|
||||
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{})
|
||||
|
||||
// int64WrapperType reflected type for protobuf int64 wrapper type.
|
||||
int64WrapperType = reflect.TypeOf(&wrapperspb.Int64Value{})
|
||||
)
|
||||
|
||||
// Add implements traits.Adder.Add.
|
||||
func (i Int) Add(other ref.Val) ref.Val {
|
||||
otherInt, ok := other.(Int)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
val, err := addInt64Checked(int64(i), int64(otherInt))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Int(val)
|
||||
}
|
||||
|
||||
// Compare implements traits.Comparer.Compare.
|
||||
func (i Int) Compare(other ref.Val) ref.Val {
|
||||
switch ov := other.(type) {
|
||||
case Double:
|
||||
if math.IsNaN(float64(ov)) {
|
||||
return NewErr("NaN values cannot be ordered")
|
||||
}
|
||||
return compareIntDouble(i, ov)
|
||||
case Int:
|
||||
return compareInt(i, ov)
|
||||
case Uint:
|
||||
return compareIntUint(i, ov)
|
||||
default:
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertToNative implements ref.Val.ConvertToNative.
|
||||
func (i Int) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
switch typeDesc.Kind() {
|
||||
case reflect.Int, reflect.Int32:
|
||||
// Enums are also mapped as int32 derivations.
|
||||
// Note, the code doesn't convert to the enum value directly since this is not known, but
|
||||
// the net effect with respect to proto-assignment is handled correctly by the reflection
|
||||
// Convert method.
|
||||
v, err := int64ToInt32Checked(int64(i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return reflect.ValueOf(v).Convert(typeDesc).Interface(), nil
|
||||
case reflect.Int64:
|
||||
return reflect.ValueOf(i).Convert(typeDesc).Interface(), nil
|
||||
case reflect.Ptr:
|
||||
switch typeDesc {
|
||||
case anyValueType:
|
||||
// Primitives must be wrapped before being set on an Any field.
|
||||
return anypb.New(wrapperspb.Int64(int64(i)))
|
||||
case int32WrapperType:
|
||||
// Convert the value to a wrapperspb.Int32Value, error on overflow.
|
||||
v, err := int64ToInt32Checked(int64(i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return wrapperspb.Int32(v), nil
|
||||
case int64WrapperType:
|
||||
// Convert the value to a wrapperspb.Int64Value.
|
||||
return wrapperspb.Int64(int64(i)), nil
|
||||
case jsonValueType:
|
||||
// The proto-to-JSON conversion rules would convert all 64-bit integer values to JSON
|
||||
// decimal strings. Because CEL ints might come from the automatic widening of 32-bit
|
||||
// values in protos, the JSON type is chosen dynamically based on the value.
|
||||
//
|
||||
// - Integers -2^53-1 < n < 2^53-1 are encoded as JSON numbers.
|
||||
// - Integers outside this range are encoded as JSON strings.
|
||||
//
|
||||
// The integer to float range represents the largest interval where such a conversion
|
||||
// can round-trip accurately. Thus, conversions from a 32-bit source can expect a JSON
|
||||
// number as with protobuf. Those consuming JSON from a 64-bit source must be able to
|
||||
// handle either a JSON number or a JSON decimal string. To handle these cases safely
|
||||
// the string values must be explicitly converted to int() within a CEL expression;
|
||||
// however, it is best to simply stay within the JSON number range when building JSON
|
||||
// objects in CEL.
|
||||
if i.isJSONSafe() {
|
||||
return structpb.NewNumberValue(float64(i)), nil
|
||||
}
|
||||
// Proto3 to JSON conversion requires string-formatted int64 values
|
||||
// since the conversion to floating point would result in truncation.
|
||||
return structpb.NewStringValue(strconv.FormatInt(int64(i), 10)), nil
|
||||
}
|
||||
switch typeDesc.Elem().Kind() {
|
||||
case reflect.Int32:
|
||||
// Convert the value to a wrapperspb.Int32Value, error on overflow.
|
||||
v, err := int64ToInt32Checked(int64(i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p := reflect.New(typeDesc.Elem())
|
||||
p.Elem().Set(reflect.ValueOf(v).Convert(typeDesc.Elem()))
|
||||
return p.Interface(), nil
|
||||
case reflect.Int64:
|
||||
v := int64(i)
|
||||
p := reflect.New(typeDesc.Elem())
|
||||
p.Elem().Set(reflect.ValueOf(v).Convert(typeDesc.Elem()))
|
||||
return p.Interface(), nil
|
||||
}
|
||||
case reflect.Interface:
|
||||
iv := i.Value()
|
||||
if reflect.TypeOf(iv).Implements(typeDesc) {
|
||||
return iv, nil
|
||||
}
|
||||
if reflect.TypeOf(i).Implements(typeDesc) {
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported type conversion from 'int' to %v", typeDesc)
|
||||
}
|
||||
|
||||
// ConvertToType implements ref.Val.ConvertToType.
|
||||
func (i Int) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case IntType:
|
||||
return i
|
||||
case UintType:
|
||||
u, err := int64ToUint64Checked(int64(i))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Uint(u)
|
||||
case DoubleType:
|
||||
return Double(i)
|
||||
case StringType:
|
||||
return String(fmt.Sprintf("%d", int64(i)))
|
||||
case TimestampType:
|
||||
// The maximum positive value that can be passed to time.Unix is math.MaxInt64 minus the number
|
||||
// of seconds between year 1 and year 1970. See comments on unixToInternal.
|
||||
if int64(i) < minUnixTime || int64(i) > maxUnixTime {
|
||||
return celErrTimestampOverflow
|
||||
}
|
||||
return timestampOf(time.Unix(int64(i), 0).UTC())
|
||||
case TypeType:
|
||||
return IntType
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", IntType, typeVal)
|
||||
}
|
||||
|
||||
// Divide implements traits.Divider.Divide.
|
||||
func (i Int) Divide(other ref.Val) ref.Val {
|
||||
otherInt, ok := other.(Int)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
val, err := divideInt64Checked(int64(i), int64(otherInt))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Int(val)
|
||||
}
|
||||
|
||||
// Equal implements ref.Val.Equal.
|
||||
func (i Int) Equal(other ref.Val) ref.Val {
|
||||
switch ov := other.(type) {
|
||||
case Double:
|
||||
if math.IsNaN(float64(ov)) {
|
||||
return False
|
||||
}
|
||||
return Bool(compareIntDouble(i, ov) == 0)
|
||||
case Int:
|
||||
return Bool(i == ov)
|
||||
case Uint:
|
||||
return Bool(compareIntUint(i, ov) == 0)
|
||||
default:
|
||||
return False
|
||||
}
|
||||
}
|
||||
|
||||
// Modulo implements traits.Modder.Modulo.
|
||||
func (i Int) Modulo(other ref.Val) ref.Val {
|
||||
otherInt, ok := other.(Int)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
val, err := moduloInt64Checked(int64(i), int64(otherInt))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Int(val)
|
||||
}
|
||||
|
||||
// Multiply implements traits.Multiplier.Multiply.
|
||||
func (i Int) Multiply(other ref.Val) ref.Val {
|
||||
otherInt, ok := other.(Int)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
val, err := multiplyInt64Checked(int64(i), int64(otherInt))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Int(val)
|
||||
}
|
||||
|
||||
// Negate implements traits.Negater.Negate.
|
||||
func (i Int) Negate() ref.Val {
|
||||
val, err := negateInt64Checked(int64(i))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Int(val)
|
||||
}
|
||||
|
||||
// Subtract implements traits.Subtractor.Subtract.
|
||||
func (i Int) Subtract(subtrahend ref.Val) ref.Val {
|
||||
subtraInt, ok := subtrahend.(Int)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(subtrahend)
|
||||
}
|
||||
val, err := subtractInt64Checked(int64(i), int64(subtraInt))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Int(val)
|
||||
}
|
||||
|
||||
// Type implements ref.Val.Type.
|
||||
func (i Int) Type() ref.Type {
|
||||
return IntType
|
||||
}
|
||||
|
||||
// Value implements ref.Val.Value.
|
||||
func (i Int) Value() interface{} {
|
||||
return int64(i)
|
||||
}
|
||||
|
||||
// isJSONSafe indicates whether the int is safely representable as a floating point value in JSON.
|
||||
func (i Int) isJSONSafe() bool {
|
||||
return i >= minIntJSON && i <= maxIntJSON
|
||||
}
|
||||
|
||||
const (
|
||||
// maxIntJSON is defined as the Number.MAX_SAFE_INTEGER value per EcmaScript 6.
|
||||
maxIntJSON = 1<<53 - 1
|
||||
// minIntJSON is defined as the Number.MIN_SAFE_INTEGER value per EcmaScript 6.
|
||||
minIntJSON = -maxIntJSON
|
||||
)
|
55
vendor/github.com/google/cel-go/common/types/iterator.go
generated
vendored
Normal file
55
vendor/github.com/google/cel-go/common/types/iterator.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
// 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 (
|
||||
// IteratorType singleton.
|
||||
IteratorType = NewTypeValue("iterator", traits.IteratorType)
|
||||
)
|
||||
|
||||
// baseIterator is the basis for list, map, and object iterators.
|
||||
//
|
||||
// An iterator in and of itself should not be a valid value for comparison, but must implement the
|
||||
// `ref.Val` methods in order to be well-supported within instruction arguments processed by the
|
||||
// interpreter.
|
||||
type baseIterator struct{}
|
||||
|
||||
func (*baseIterator) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
return nil, fmt.Errorf("type conversion on iterators not supported")
|
||||
}
|
||||
|
||||
func (*baseIterator) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
return NewErr("no such overload")
|
||||
}
|
||||
|
||||
func (*baseIterator) Equal(other ref.Val) ref.Val {
|
||||
return NewErr("no such overload")
|
||||
}
|
||||
|
||||
func (*baseIterator) Type() ref.Type {
|
||||
return IteratorType
|
||||
}
|
||||
|
||||
func (*baseIterator) Value() interface{} {
|
||||
return nil
|
||||
}
|
28
vendor/github.com/google/cel-go/common/types/json_value.go
generated
vendored
Normal file
28
vendor/github.com/google/cel-go/common/types/json_value.go
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
// 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 (
|
||||
"reflect"
|
||||
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
// JSON type constants representing the reflected types of protobuf JSON values.
|
||||
var (
|
||||
jsonValueType = reflect.TypeOf(&structpb.Value{})
|
||||
jsonListValueType = reflect.TypeOf(&structpb.ListValue{})
|
||||
jsonStructType = reflect.TypeOf(&structpb.Struct{})
|
||||
)
|
489
vendor/github.com/google/cel-go/common/types/list.go
generated
vendored
Normal file
489
vendor/github.com/google/cel-go/common/types/list.go
generated
vendored
Normal file
@ -0,0 +1,489 @@
|
||||
// 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"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
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 interface{}) traits.Lister {
|
||||
refValue := reflect.ValueOf(value)
|
||||
return &baseList{
|
||||
TypeAdapter: adapter,
|
||||
value: value,
|
||||
size: refValue.Len(),
|
||||
get: func(i int) interface{} {
|
||||
return refValue.Index(i).Interface()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewStringList returns a traits.Lister containing only strings.
|
||||
func NewStringList(adapter ref.TypeAdapter, elems []string) traits.Lister {
|
||||
return &baseList{
|
||||
TypeAdapter: adapter,
|
||||
value: elems,
|
||||
size: len(elems),
|
||||
get: func(i int) interface{} { 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 {
|
||||
return &baseList{
|
||||
TypeAdapter: adapter,
|
||||
value: elems,
|
||||
size: len(elems),
|
||||
get: func(i int) interface{} { return elems[i] },
|
||||
}
|
||||
}
|
||||
|
||||
// NewProtoList returns a traits.Lister based on a pb.List instance.
|
||||
func NewProtoList(adapter ref.TypeAdapter, list protoreflect.List) traits.Lister {
|
||||
return &baseList{
|
||||
TypeAdapter: adapter,
|
||||
value: list,
|
||||
size: list.Len(),
|
||||
get: func(i int) interface{} { 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 {
|
||||
vals := l.GetValues()
|
||||
return &baseList{
|
||||
TypeAdapter: adapter,
|
||||
value: l,
|
||||
size: len(vals),
|
||||
get: func(i int) interface{} { return vals[i] },
|
||||
}
|
||||
}
|
||||
|
||||
// NewMutableList creates a new mutable list whose internal state can be modified.
|
||||
func NewMutableList(adapter ref.TypeAdapter) traits.MutableLister {
|
||||
var mutableValues []ref.Val
|
||||
return &mutableList{
|
||||
baseList: &baseList{
|
||||
TypeAdapter: adapter,
|
||||
value: mutableValues,
|
||||
size: 0,
|
||||
get: func(i int) interface{} { return mutableValues[i] },
|
||||
},
|
||||
mutableValues: mutableValues,
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
type baseList struct {
|
||||
ref.TypeAdapter
|
||||
value interface{}
|
||||
|
||||
// size indicates the number of elements within the list.
|
||||
// Since objects are immutable the size of a list is static.
|
||||
size int
|
||||
|
||||
// get returns a value at the specified integer index.
|
||||
// The index is guaranteed to be checked against the list index range.
|
||||
get func(int) interface{}
|
||||
}
|
||||
|
||||
// Add implements the traits.Adder interface method.
|
||||
func (l *baseList) Add(other ref.Val) ref.Val {
|
||||
otherList, ok := other.(traits.Lister)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
if l.Size() == IntZero {
|
||||
return other
|
||||
}
|
||||
if otherList.Size() == IntZero {
|
||||
return l
|
||||
}
|
||||
return &concatList{
|
||||
TypeAdapter: l.TypeAdapter,
|
||||
prevList: l,
|
||||
nextList: otherList}
|
||||
}
|
||||
|
||||
// Contains implements the traits.Container interface method.
|
||||
func (l *baseList) Contains(elem ref.Val) ref.Val {
|
||||
for i := 0; i < l.size; i++ {
|
||||
val := l.NativeToValue(l.get(i))
|
||||
cmp := elem.Equal(val)
|
||||
b, ok := cmp.(Bool)
|
||||
if ok && b == True {
|
||||
return True
|
||||
}
|
||||
}
|
||||
return False
|
||||
}
|
||||
|
||||
// ConvertToNative implements the ref.Val interface method.
|
||||
func (l *baseList) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
// If the underlying list value is assignable to the reflected type return it.
|
||||
if reflect.TypeOf(l.value).AssignableTo(typeDesc) {
|
||||
return l.value, nil
|
||||
}
|
||||
// If the list wrapper is assignable to the desired type return it.
|
||||
if reflect.TypeOf(l).AssignableTo(typeDesc) {
|
||||
return l, nil
|
||||
}
|
||||
// Attempt to convert the list to a set of well known protobuf types.
|
||||
switch typeDesc {
|
||||
case anyValueType:
|
||||
json, err := l.ConvertToNative(jsonListValueType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return anypb.New(json.(proto.Message))
|
||||
case jsonValueType, jsonListValueType:
|
||||
jsonValues, err :=
|
||||
l.ConvertToNative(reflect.TypeOf([]*structpb.Value{}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jsonList := &structpb.ListValue{Values: jsonValues.([]*structpb.Value)}
|
||||
if typeDesc == jsonListValueType {
|
||||
return jsonList, nil
|
||||
}
|
||||
return structpb.NewListValue(jsonList), nil
|
||||
}
|
||||
// Non-list conversion.
|
||||
if typeDesc.Kind() != reflect.Slice && typeDesc.Kind() != reflect.Array {
|
||||
return nil, fmt.Errorf("type conversion error from list to '%v'", typeDesc)
|
||||
}
|
||||
|
||||
// List conversion.
|
||||
// Allow the element ConvertToNative() function to determine whether conversion is possible.
|
||||
otherElemType := typeDesc.Elem()
|
||||
elemCount := l.size
|
||||
nativeList := reflect.MakeSlice(typeDesc, elemCount, elemCount)
|
||||
for i := 0; i < elemCount; i++ {
|
||||
elem := l.NativeToValue(l.get(i))
|
||||
nativeElemVal, err := elem.ConvertToNative(otherElemType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nativeList.Index(i).Set(reflect.ValueOf(nativeElemVal))
|
||||
}
|
||||
return nativeList.Interface(), nil
|
||||
}
|
||||
|
||||
// ConvertToType implements the ref.Val interface method.
|
||||
func (l *baseList) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case ListType:
|
||||
return l
|
||||
case TypeType:
|
||||
return ListType
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", ListType, typeVal)
|
||||
}
|
||||
|
||||
// Equal implements the ref.Val interface method.
|
||||
func (l *baseList) Equal(other ref.Val) ref.Val {
|
||||
otherList, ok := other.(traits.Lister)
|
||||
if !ok {
|
||||
return False
|
||||
}
|
||||
if l.Size() != otherList.Size() {
|
||||
return False
|
||||
}
|
||||
for i := IntZero; i < l.Size().(Int); i++ {
|
||||
thisElem := l.Get(i)
|
||||
otherElem := otherList.Get(i)
|
||||
elemEq := Equal(thisElem, otherElem)
|
||||
if elemEq == False {
|
||||
return False
|
||||
}
|
||||
}
|
||||
return True
|
||||
}
|
||||
|
||||
// Get implements the traits.Indexer interface method.
|
||||
func (l *baseList) Get(index ref.Val) ref.Val {
|
||||
ind, err := indexOrError(index)
|
||||
if err != nil {
|
||||
return ValOrErr(index, err.Error())
|
||||
}
|
||||
if ind < 0 || ind >= l.size {
|
||||
return NewErr("index '%d' out of range in list size '%d'", ind, l.Size())
|
||||
}
|
||||
return l.NativeToValue(l.get(ind))
|
||||
}
|
||||
|
||||
// Iterator implements the traits.Iterable interface method.
|
||||
func (l *baseList) Iterator() traits.Iterator {
|
||||
return newListIterator(l)
|
||||
}
|
||||
|
||||
// Size implements the traits.Sizer interface method.
|
||||
func (l *baseList) Size() ref.Val {
|
||||
return Int(l.size)
|
||||
}
|
||||
|
||||
// Type implements the ref.Val interface method.
|
||||
func (l *baseList) Type() ref.Type {
|
||||
return ListType
|
||||
}
|
||||
|
||||
// Value implements the ref.Val interface method.
|
||||
func (l *baseList) Value() interface{} {
|
||||
return l.value
|
||||
}
|
||||
|
||||
// mutableList aggregates values into its internal storage. For use with internal CEL variables only.
|
||||
type mutableList struct {
|
||||
*baseList
|
||||
mutableValues []ref.Val
|
||||
}
|
||||
|
||||
// Add copies elements from the other list into the internal storage of the mutable list.
|
||||
// The ref.Val returned by Add is the receiver.
|
||||
func (l *mutableList) Add(other ref.Val) ref.Val {
|
||||
switch otherList := other.(type) {
|
||||
case *mutableList:
|
||||
l.mutableValues = append(l.mutableValues, otherList.mutableValues...)
|
||||
l.size += len(otherList.mutableValues)
|
||||
case traits.Lister:
|
||||
for i := IntZero; i < otherList.Size().(Int); i++ {
|
||||
l.size++
|
||||
l.mutableValues = append(l.mutableValues, otherList.Get(i))
|
||||
}
|
||||
default:
|
||||
return MaybeNoSuchOverloadErr(otherList)
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// ToImmutableList returns an immutable list based on the internal storage of the mutable list.
|
||||
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)
|
||||
}
|
||||
|
||||
// concatList combines two list implementations together into a view.
|
||||
// The `ref.TypeAdapter` enables native type to CEL type conversions.
|
||||
type concatList struct {
|
||||
ref.TypeAdapter
|
||||
value interface{}
|
||||
prevList traits.Lister
|
||||
nextList traits.Lister
|
||||
}
|
||||
|
||||
// Add implements the traits.Adder interface method.
|
||||
func (l *concatList) Add(other ref.Val) ref.Val {
|
||||
otherList, ok := other.(traits.Lister)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
if l.Size() == IntZero {
|
||||
return other
|
||||
}
|
||||
if otherList.Size() == IntZero {
|
||||
return l
|
||||
}
|
||||
return &concatList{
|
||||
TypeAdapter: l.TypeAdapter,
|
||||
prevList: l,
|
||||
nextList: otherList}
|
||||
}
|
||||
|
||||
// Contains implements the traits.Container interface method.
|
||||
func (l *concatList) Contains(elem ref.Val) ref.Val {
|
||||
// The concat list relies on the IsErrorOrUnknown checks against the input element to be
|
||||
// performed by the `prevList` and/or `nextList`.
|
||||
prev := l.prevList.Contains(elem)
|
||||
// Short-circuit the return if the elem was found in the prev list.
|
||||
if prev == True {
|
||||
return prev
|
||||
}
|
||||
// Return if the elem was found in the next list.
|
||||
next := l.nextList.Contains(elem)
|
||||
if next == True {
|
||||
return next
|
||||
}
|
||||
// Handle the case where an error or unknown was encountered before checking next.
|
||||
if IsUnknownOrError(prev) {
|
||||
return prev
|
||||
}
|
||||
// Otherwise, rely on the next value as the representative result.
|
||||
return next
|
||||
}
|
||||
|
||||
// ConvertToNative implements the ref.Val interface method.
|
||||
func (l *concatList) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
combined := NewDynamicList(l.TypeAdapter, l.Value().([]interface{}))
|
||||
return combined.ConvertToNative(typeDesc)
|
||||
}
|
||||
|
||||
// ConvertToType implements the ref.Val interface method.
|
||||
func (l *concatList) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case ListType:
|
||||
return l
|
||||
case TypeType:
|
||||
return ListType
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", ListType, typeVal)
|
||||
}
|
||||
|
||||
// Equal implements the ref.Val interface method.
|
||||
func (l *concatList) Equal(other ref.Val) ref.Val {
|
||||
otherList, ok := other.(traits.Lister)
|
||||
if !ok {
|
||||
return False
|
||||
}
|
||||
if l.Size() != otherList.Size() {
|
||||
return False
|
||||
}
|
||||
var maybeErr ref.Val
|
||||
for i := IntZero; i < l.Size().(Int); i++ {
|
||||
thisElem := l.Get(i)
|
||||
otherElem := otherList.Get(i)
|
||||
elemEq := Equal(thisElem, otherElem)
|
||||
if elemEq == False {
|
||||
return False
|
||||
}
|
||||
if maybeErr == nil && IsUnknownOrError(elemEq) {
|
||||
maybeErr = elemEq
|
||||
}
|
||||
}
|
||||
if maybeErr != nil {
|
||||
return maybeErr
|
||||
}
|
||||
return True
|
||||
}
|
||||
|
||||
// Get implements the traits.Indexer interface method.
|
||||
func (l *concatList) Get(index ref.Val) ref.Val {
|
||||
ind, err := indexOrError(index)
|
||||
if err != nil {
|
||||
return ValOrErr(index, err.Error())
|
||||
}
|
||||
i := Int(ind)
|
||||
if i < l.prevList.Size().(Int) {
|
||||
return l.prevList.Get(i)
|
||||
}
|
||||
offset := i - l.prevList.Size().(Int)
|
||||
return l.nextList.Get(offset)
|
||||
}
|
||||
|
||||
// Iterator implements the traits.Iterable interface method.
|
||||
func (l *concatList) Iterator() traits.Iterator {
|
||||
return newListIterator(l)
|
||||
}
|
||||
|
||||
// Size implements the traits.Sizer interface method.
|
||||
func (l *concatList) Size() ref.Val {
|
||||
return l.prevList.Size().(Int).Add(l.nextList.Size())
|
||||
}
|
||||
|
||||
// Type implements the ref.Val interface method.
|
||||
func (l *concatList) Type() ref.Type {
|
||||
return ListType
|
||||
}
|
||||
|
||||
// Value implements the ref.Val interface method.
|
||||
func (l *concatList) Value() interface{} {
|
||||
if l.value == nil {
|
||||
merged := make([]interface{}, l.Size().(Int))
|
||||
prevLen := l.prevList.Size().(Int)
|
||||
for i := Int(0); i < prevLen; i++ {
|
||||
merged[i] = l.prevList.Get(i).Value()
|
||||
}
|
||||
nextLen := l.nextList.Size().(Int)
|
||||
for j := Int(0); j < nextLen; j++ {
|
||||
merged[prevLen+j] = l.nextList.Get(j).Value()
|
||||
}
|
||||
l.value = merged
|
||||
}
|
||||
return l.value
|
||||
}
|
||||
|
||||
func newListIterator(listValue traits.Lister) traits.Iterator {
|
||||
return &listIterator{
|
||||
listValue: listValue,
|
||||
len: listValue.Size().(Int),
|
||||
}
|
||||
}
|
||||
|
||||
type listIterator struct {
|
||||
*baseIterator
|
||||
listValue traits.Lister
|
||||
cursor Int
|
||||
len Int
|
||||
}
|
||||
|
||||
// HasNext implements the traits.Iterator interface method.
|
||||
func (it *listIterator) HasNext() ref.Val {
|
||||
return Bool(it.cursor < it.len)
|
||||
}
|
||||
|
||||
// Next implements the traits.Iterator interface method.
|
||||
func (it *listIterator) Next() ref.Val {
|
||||
if it.HasNext() == True {
|
||||
index := it.cursor
|
||||
it.cursor++
|
||||
return it.listValue.Get(index)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func indexOrError(index ref.Val) (int, error) {
|
||||
switch iv := index.(type) {
|
||||
case Int:
|
||||
return int(iv), nil
|
||||
case Double:
|
||||
if ik, ok := doubleToInt64Lossless(float64(iv)); ok {
|
||||
return int(ik), nil
|
||||
}
|
||||
return -1, fmt.Errorf("unsupported index value %v in list", index)
|
||||
case Uint:
|
||||
if ik, ok := uint64ToInt64Lossless(uint64(iv)); ok {
|
||||
return int(ik), nil
|
||||
}
|
||||
return -1, fmt.Errorf("unsupported index value %v in list", index)
|
||||
default:
|
||||
return -1, fmt.Errorf("unsupported index type '%s' in list", index.Type())
|
||||
}
|
||||
}
|
832
vendor/github.com/google/cel-go/common/types/map.go
generated
vendored
Normal file
832
vendor/github.com/google/cel-go/common/types/map.go
generated
vendored
Normal file
@ -0,0 +1,832 @@
|
||||
// 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/pb"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
"github.com/stoewer/go-strcase"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
// NewDynamicMap returns a traits.Mapper value with dynamic key, value pairs.
|
||||
func NewDynamicMap(adapter ref.TypeAdapter, value interface{}) traits.Mapper {
|
||||
refValue := reflect.ValueOf(value)
|
||||
return &baseMap{
|
||||
TypeAdapter: adapter,
|
||||
mapAccessor: newReflectMapAccessor(adapter, refValue),
|
||||
value: value,
|
||||
size: refValue.Len(),
|
||||
}
|
||||
}
|
||||
|
||||
// NewJSONStruct creates a traits.Mapper implementation backed by a JSON struct that has been
|
||||
// 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 {
|
||||
fields := value.GetFields()
|
||||
return &baseMap{
|
||||
TypeAdapter: adapter,
|
||||
mapAccessor: newJSONStructAccessor(adapter, fields),
|
||||
value: value,
|
||||
size: len(fields),
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return &baseMap{
|
||||
TypeAdapter: adapter,
|
||||
mapAccessor: newRefValMapAccessor(value),
|
||||
value: value,
|
||||
size: len(value),
|
||||
}
|
||||
}
|
||||
|
||||
// NewStringInterfaceMap returns a specialized traits.Mapper with string keys and interface values.
|
||||
func NewStringInterfaceMap(adapter ref.TypeAdapter, value map[string]interface{}) traits.Mapper {
|
||||
return &baseMap{
|
||||
TypeAdapter: adapter,
|
||||
mapAccessor: newStringIfaceMapAccessor(adapter, value),
|
||||
value: value,
|
||||
size: len(value),
|
||||
}
|
||||
}
|
||||
|
||||
// NewStringStringMap returns a specialized traits.Mapper with string keys and values.
|
||||
func NewStringStringMap(adapter ref.TypeAdapter, value map[string]string) traits.Mapper {
|
||||
return &baseMap{
|
||||
TypeAdapter: adapter,
|
||||
mapAccessor: newStringMapAccessor(value),
|
||||
value: value,
|
||||
size: len(value),
|
||||
}
|
||||
}
|
||||
|
||||
// NewProtoMap returns a specialized traits.Mapper for handling protobuf map values.
|
||||
func NewProtoMap(adapter ref.TypeAdapter, value *pb.Map) traits.Mapper {
|
||||
return &protoMap{
|
||||
TypeAdapter: 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.
|
||||
type mapAccessor interface {
|
||||
// Find returns a value, if one exists, for the input key.
|
||||
//
|
||||
// If the key is not found the function returns (nil, false).
|
||||
Find(ref.Val) (ref.Val, bool)
|
||||
|
||||
// Iterator returns an Iterator over the map key set.
|
||||
Iterator() traits.Iterator
|
||||
}
|
||||
|
||||
// baseMap is a reflection based map implementation designed to handle a variety of map-like types.
|
||||
//
|
||||
// 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
|
||||
|
||||
// mapAccessor interface implementation used to find and iterate over map keys.
|
||||
mapAccessor
|
||||
|
||||
// value is the native Go value upon which the map type operators.
|
||||
value interface{}
|
||||
|
||||
// size is the number of entries in the map.
|
||||
size int
|
||||
}
|
||||
|
||||
// Contains implements the traits.Container interface method.
|
||||
func (m *baseMap) Contains(index ref.Val) ref.Val {
|
||||
_, found := m.Find(index)
|
||||
return Bool(found)
|
||||
}
|
||||
|
||||
// ConvertToNative implements the ref.Val interface method.
|
||||
func (m *baseMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
// If the map is already assignable to the desired type return it, e.g. interfaces and
|
||||
// maps with the same key value types.
|
||||
if reflect.TypeOf(m.value).AssignableTo(typeDesc) {
|
||||
return m.value, nil
|
||||
}
|
||||
if reflect.TypeOf(m).AssignableTo(typeDesc) {
|
||||
return m, nil
|
||||
}
|
||||
switch typeDesc {
|
||||
case anyValueType:
|
||||
json, err := m.ConvertToNative(jsonStructType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return anypb.New(json.(proto.Message))
|
||||
case jsonValueType, jsonStructType:
|
||||
jsonEntries, err :=
|
||||
m.ConvertToNative(reflect.TypeOf(map[string]*structpb.Value{}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jsonMap := &structpb.Struct{Fields: jsonEntries.(map[string]*structpb.Value)}
|
||||
if typeDesc == jsonStructType {
|
||||
return jsonMap, nil
|
||||
}
|
||||
return structpb.NewStructValue(jsonMap), nil
|
||||
}
|
||||
|
||||
// Unwrap pointers, but track their use.
|
||||
isPtr := false
|
||||
if typeDesc.Kind() == reflect.Ptr {
|
||||
tk := typeDesc
|
||||
typeDesc = typeDesc.Elem()
|
||||
if typeDesc.Kind() == reflect.Ptr {
|
||||
return nil, fmt.Errorf("unsupported type conversion to '%v'", tk)
|
||||
}
|
||||
isPtr = true
|
||||
}
|
||||
switch typeDesc.Kind() {
|
||||
// Map conversion.
|
||||
case reflect.Map:
|
||||
otherKey := typeDesc.Key()
|
||||
otherElem := typeDesc.Elem()
|
||||
nativeMap := reflect.MakeMapWithSize(typeDesc, m.size)
|
||||
it := m.Iterator()
|
||||
for it.HasNext() == True {
|
||||
key := it.Next()
|
||||
refKeyValue, err := key.ConvertToNative(otherKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
refElemValue, err := m.Get(key).ConvertToNative(otherElem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nativeMap.SetMapIndex(reflect.ValueOf(refKeyValue), reflect.ValueOf(refElemValue))
|
||||
}
|
||||
return nativeMap.Interface(), nil
|
||||
case reflect.Struct:
|
||||
nativeStructPtr := reflect.New(typeDesc)
|
||||
nativeStruct := nativeStructPtr.Elem()
|
||||
it := m.Iterator()
|
||||
for it.HasNext() == True {
|
||||
key := it.Next()
|
||||
// Ensure the field name being referenced is exported.
|
||||
// Only exported (public) field names can be set by reflection, where the name
|
||||
// must be at least one character in length and start with an upper-case letter.
|
||||
fieldName := key.ConvertToType(StringType)
|
||||
if IsError(fieldName) {
|
||||
return nil, fieldName.(*Err)
|
||||
}
|
||||
name := string(fieldName.(String))
|
||||
name = strcase.UpperCamelCase(name)
|
||||
fieldRef := nativeStruct.FieldByName(name)
|
||||
if !fieldRef.IsValid() {
|
||||
return nil, fmt.Errorf("type conversion error, no such field '%s' in type '%v'", name, typeDesc)
|
||||
}
|
||||
fieldValue, err := m.Get(key).ConvertToNative(fieldRef.Type())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldRef.Set(reflect.ValueOf(fieldValue))
|
||||
}
|
||||
if isPtr {
|
||||
return nativeStructPtr.Interface(), nil
|
||||
}
|
||||
return nativeStruct.Interface(), nil
|
||||
}
|
||||
return nil, fmt.Errorf("type conversion error from map to '%v'", typeDesc)
|
||||
}
|
||||
|
||||
// ConvertToType implements the ref.Val interface method.
|
||||
func (m *baseMap) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case MapType:
|
||||
return m
|
||||
case TypeType:
|
||||
return MapType
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", MapType, typeVal)
|
||||
}
|
||||
|
||||
// Equal implements the ref.Val interface method.
|
||||
func (m *baseMap) Equal(other ref.Val) ref.Val {
|
||||
otherMap, ok := other.(traits.Mapper)
|
||||
if !ok {
|
||||
return False
|
||||
}
|
||||
if m.Size() != otherMap.Size() {
|
||||
return False
|
||||
}
|
||||
it := m.Iterator()
|
||||
for it.HasNext() == True {
|
||||
key := it.Next()
|
||||
thisVal, _ := m.Find(key)
|
||||
otherVal, found := otherMap.Find(key)
|
||||
if !found {
|
||||
return False
|
||||
}
|
||||
valEq := Equal(thisVal, otherVal)
|
||||
if valEq == False {
|
||||
return False
|
||||
}
|
||||
}
|
||||
return True
|
||||
}
|
||||
|
||||
// Get implements the traits.Indexer interface method.
|
||||
func (m *baseMap) Get(key ref.Val) ref.Val {
|
||||
v, found := m.Find(key)
|
||||
if !found {
|
||||
return ValOrErr(v, "no such key: %v", key)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Size implements the traits.Sizer interface method.
|
||||
func (m *baseMap) Size() ref.Val {
|
||||
return Int(m.size)
|
||||
}
|
||||
|
||||
// Type implements the ref.Val interface method.
|
||||
func (m *baseMap) Type() ref.Type {
|
||||
return MapType
|
||||
}
|
||||
|
||||
// Value implements the ref.Val interface method.
|
||||
func (m *baseMap) Value() interface{} {
|
||||
return m.value
|
||||
}
|
||||
|
||||
func newJSONStructAccessor(adapter ref.TypeAdapter, st map[string]*structpb.Value) mapAccessor {
|
||||
return &jsonStructAccessor{
|
||||
TypeAdapter: adapter,
|
||||
st: st,
|
||||
}
|
||||
}
|
||||
|
||||
type jsonStructAccessor struct {
|
||||
ref.TypeAdapter
|
||||
st map[string]*structpb.Value
|
||||
}
|
||||
|
||||
// Find searches the json struct field map for the input key value and returns (value, true) if
|
||||
// found.
|
||||
//
|
||||
// If the key is not found the function returns (nil, false).
|
||||
func (a *jsonStructAccessor) Find(key ref.Val) (ref.Val, bool) {
|
||||
strKey, ok := key.(String)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
keyVal, found := a.st[string(strKey)]
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
return a.NativeToValue(keyVal), true
|
||||
}
|
||||
|
||||
// Iterator creates a new traits.Iterator from the set of JSON struct field names.
|
||||
func (a *jsonStructAccessor) Iterator() traits.Iterator {
|
||||
// Copy the keys to make their order stable.
|
||||
mapKeys := make([]string, len(a.st))
|
||||
i := 0
|
||||
for k := range a.st {
|
||||
mapKeys[i] = k
|
||||
i++
|
||||
}
|
||||
return &stringKeyIterator{
|
||||
mapKeys: mapKeys,
|
||||
len: len(mapKeys),
|
||||
}
|
||||
}
|
||||
|
||||
func newReflectMapAccessor(adapter ref.TypeAdapter, value reflect.Value) mapAccessor {
|
||||
keyType := value.Type().Key()
|
||||
return &reflectMapAccessor{
|
||||
TypeAdapter: adapter,
|
||||
refValue: value,
|
||||
keyType: keyType,
|
||||
}
|
||||
}
|
||||
|
||||
type reflectMapAccessor struct {
|
||||
ref.TypeAdapter
|
||||
refValue reflect.Value
|
||||
keyType reflect.Type
|
||||
}
|
||||
|
||||
// Find converts the input key to a native Golang type and then uses reflection to find the key,
|
||||
// returning (value, true) if present.
|
||||
//
|
||||
// If the key is not found the function returns (nil, false).
|
||||
func (m *reflectMapAccessor) Find(key ref.Val) (ref.Val, bool) {
|
||||
if m.refValue.Len() == 0 {
|
||||
return nil, false
|
||||
}
|
||||
if keyVal, found := m.findInternal(key); found {
|
||||
return keyVal, true
|
||||
}
|
||||
switch k := key.(type) {
|
||||
// Double is not a valid proto map key type, so check for the key as an int or uint.
|
||||
case Double:
|
||||
if ik, ok := doubleToInt64Lossless(float64(k)); ok {
|
||||
if keyVal, found := m.findInternal(Int(ik)); found {
|
||||
return keyVal, true
|
||||
}
|
||||
}
|
||||
if uk, ok := doubleToUint64Lossless(float64(k)); ok {
|
||||
return m.findInternal(Uint(uk))
|
||||
}
|
||||
// map keys of type double are not supported.
|
||||
case Int:
|
||||
if uk, ok := int64ToUint64Lossless(int64(k)); ok {
|
||||
return m.findInternal(Uint(uk))
|
||||
}
|
||||
case Uint:
|
||||
if ik, ok := uint64ToInt64Lossless(uint64(k)); ok {
|
||||
return m.findInternal(Int(ik))
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// findInternal attempts to convert the incoming key to the map's internal native type
|
||||
// and then returns the value, if found.
|
||||
func (m *reflectMapAccessor) findInternal(key ref.Val) (ref.Val, bool) {
|
||||
k, err := key.ConvertToNative(m.keyType)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
refKey := reflect.ValueOf(k)
|
||||
val := m.refValue.MapIndex(refKey)
|
||||
if val.IsValid() {
|
||||
return m.NativeToValue(val.Interface()), true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// 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(),
|
||||
}
|
||||
}
|
||||
|
||||
func newRefValMapAccessor(mapVal map[ref.Val]ref.Val) mapAccessor {
|
||||
return &refValMapAccessor{mapVal: mapVal}
|
||||
}
|
||||
|
||||
type refValMapAccessor struct {
|
||||
mapVal map[ref.Val]ref.Val
|
||||
}
|
||||
|
||||
// Find uses native map accesses to find the key, returning (value, true) if present.
|
||||
//
|
||||
// If the key is not found the function returns (nil, false).
|
||||
func (a *refValMapAccessor) Find(key ref.Val) (ref.Val, bool) {
|
||||
if len(a.mapVal) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
if keyVal, found := a.mapVal[key]; found {
|
||||
return keyVal, true
|
||||
}
|
||||
switch k := key.(type) {
|
||||
case Double:
|
||||
if ik, ok := doubleToInt64Lossless(float64(k)); ok {
|
||||
if keyVal, found := a.mapVal[Int(ik)]; found {
|
||||
return keyVal, found
|
||||
}
|
||||
}
|
||||
if uk, ok := doubleToUint64Lossless(float64(k)); ok {
|
||||
keyVal, found := a.mapVal[Uint(uk)]
|
||||
return keyVal, found
|
||||
}
|
||||
// map keys of type double are not supported.
|
||||
case Int:
|
||||
if uk, ok := int64ToUint64Lossless(int64(k)); ok {
|
||||
keyVal, found := a.mapVal[Uint(uk)]
|
||||
return keyVal, found
|
||||
}
|
||||
case Uint:
|
||||
if ik, ok := uint64ToInt64Lossless(uint64(k)); ok {
|
||||
keyVal, found := a.mapVal[Int(ik)]
|
||||
return keyVal, found
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// 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),
|
||||
}
|
||||
}
|
||||
|
||||
func newStringMapAccessor(strMap map[string]string) mapAccessor {
|
||||
return &stringMapAccessor{mapVal: strMap}
|
||||
}
|
||||
|
||||
type stringMapAccessor struct {
|
||||
mapVal map[string]string
|
||||
}
|
||||
|
||||
// Find uses native map accesses to find the key, returning (value, true) if present.
|
||||
//
|
||||
// If the key is not found the function returns (nil, false).
|
||||
func (a *stringMapAccessor) Find(key ref.Val) (ref.Val, bool) {
|
||||
strKey, ok := key.(String)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
keyVal, found := a.mapVal[string(strKey)]
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
return String(keyVal), true
|
||||
}
|
||||
|
||||
// Iterator creates a new traits.Iterator from the string key set of the map.
|
||||
func (a *stringMapAccessor) Iterator() traits.Iterator {
|
||||
// Copy the keys to make their order stable.
|
||||
mapKeys := make([]string, len(a.mapVal))
|
||||
i := 0
|
||||
for k := range a.mapVal {
|
||||
mapKeys[i] = k
|
||||
i++
|
||||
}
|
||||
return &stringKeyIterator{
|
||||
mapKeys: mapKeys,
|
||||
len: len(mapKeys),
|
||||
}
|
||||
}
|
||||
|
||||
func newStringIfaceMapAccessor(adapter ref.TypeAdapter, mapVal map[string]interface{}) mapAccessor {
|
||||
return &stringIfaceMapAccessor{
|
||||
TypeAdapter: adapter,
|
||||
mapVal: mapVal,
|
||||
}
|
||||
}
|
||||
|
||||
type stringIfaceMapAccessor struct {
|
||||
ref.TypeAdapter
|
||||
mapVal map[string]interface{}
|
||||
}
|
||||
|
||||
// Find uses native map accesses to find the key, returning (value, true) if present.
|
||||
//
|
||||
// If the key is not found the function returns (nil, false).
|
||||
func (a *stringIfaceMapAccessor) Find(key ref.Val) (ref.Val, bool) {
|
||||
strKey, ok := key.(String)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
keyVal, found := a.mapVal[string(strKey)]
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
return a.NativeToValue(keyVal), true
|
||||
}
|
||||
|
||||
// Iterator creates a new traits.Iterator from the string key set of the map.
|
||||
func (a *stringIfaceMapAccessor) Iterator() traits.Iterator {
|
||||
// Copy the keys to make their order stable.
|
||||
mapKeys := make([]string, len(a.mapVal))
|
||||
i := 0
|
||||
for k := range a.mapVal {
|
||||
mapKeys[i] = k
|
||||
i++
|
||||
}
|
||||
return &stringKeyIterator{
|
||||
mapKeys: mapKeys,
|
||||
len: len(mapKeys),
|
||||
}
|
||||
}
|
||||
|
||||
// protoMap is a specialized, separate implementation of the traits.Mapper interfaces tailored to
|
||||
// accessing protoreflect.Map values.
|
||||
type protoMap struct {
|
||||
ref.TypeAdapter
|
||||
value *pb.Map
|
||||
}
|
||||
|
||||
// Contains returns whether the map contains the given key.
|
||||
func (m *protoMap) Contains(key ref.Val) ref.Val {
|
||||
_, found := m.Find(key)
|
||||
return Bool(found)
|
||||
}
|
||||
|
||||
// ConvertToNative implements the ref.Val interface method.
|
||||
//
|
||||
// Note, assignment to Golang struct types is not yet supported.
|
||||
func (m *protoMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
// If the map is already assignable to the desired type return it, e.g. interfaces and
|
||||
// maps with the same key value types.
|
||||
switch typeDesc {
|
||||
case anyValueType:
|
||||
json, err := m.ConvertToNative(jsonStructType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return anypb.New(json.(proto.Message))
|
||||
case jsonValueType, jsonStructType:
|
||||
jsonEntries, err :=
|
||||
m.ConvertToNative(reflect.TypeOf(map[string]*structpb.Value{}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jsonMap := &structpb.Struct{
|
||||
Fields: jsonEntries.(map[string]*structpb.Value)}
|
||||
if typeDesc == jsonStructType {
|
||||
return jsonMap, nil
|
||||
}
|
||||
return structpb.NewStructValue(jsonMap), nil
|
||||
}
|
||||
switch typeDesc.Kind() {
|
||||
case reflect.Struct, reflect.Ptr:
|
||||
if reflect.TypeOf(m.value).AssignableTo(typeDesc) {
|
||||
return m.value, nil
|
||||
}
|
||||
if reflect.TypeOf(m).AssignableTo(typeDesc) {
|
||||
return m, nil
|
||||
}
|
||||
}
|
||||
if typeDesc.Kind() != reflect.Map {
|
||||
return nil, fmt.Errorf("unsupported type conversion: %v to map", typeDesc)
|
||||
}
|
||||
|
||||
keyType := m.value.KeyType.ReflectType()
|
||||
valType := m.value.ValueType.ReflectType()
|
||||
otherKeyType := typeDesc.Key()
|
||||
otherValType := typeDesc.Elem()
|
||||
mapVal := reflect.MakeMapWithSize(typeDesc, m.value.Len())
|
||||
var err error
|
||||
m.value.Range(func(key protoreflect.MapKey, val protoreflect.Value) bool {
|
||||
ntvKey := key.Interface()
|
||||
ntvVal := val.Interface()
|
||||
switch ntvVal.(type) {
|
||||
case protoreflect.Message:
|
||||
ntvVal = ntvVal.(protoreflect.Message).Interface()
|
||||
}
|
||||
if keyType == otherKeyType && valType == otherValType {
|
||||
mapVal.SetMapIndex(reflect.ValueOf(ntvKey), reflect.ValueOf(ntvVal))
|
||||
return true
|
||||
}
|
||||
celKey := m.NativeToValue(ntvKey)
|
||||
celVal := m.NativeToValue(ntvVal)
|
||||
ntvKey, err = celKey.ConvertToNative(otherKeyType)
|
||||
if err != nil {
|
||||
// early terminate the range loop.
|
||||
return false
|
||||
}
|
||||
ntvVal, err = celVal.ConvertToNative(otherValType)
|
||||
if err != nil {
|
||||
// early terminate the range loop.
|
||||
return false
|
||||
}
|
||||
mapVal.SetMapIndex(reflect.ValueOf(ntvKey), reflect.ValueOf(ntvVal))
|
||||
return true
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mapVal.Interface(), nil
|
||||
}
|
||||
|
||||
// ConvertToType implements the ref.Val interface method.
|
||||
func (m *protoMap) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case MapType:
|
||||
return m
|
||||
case TypeType:
|
||||
return MapType
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", MapType, typeVal)
|
||||
}
|
||||
|
||||
// Equal implements the ref.Val interface method.
|
||||
func (m *protoMap) Equal(other ref.Val) ref.Val {
|
||||
otherMap, ok := other.(traits.Mapper)
|
||||
if !ok {
|
||||
return False
|
||||
}
|
||||
if m.value.Map.Len() != int(otherMap.Size().(Int)) {
|
||||
return False
|
||||
}
|
||||
var retVal ref.Val = True
|
||||
m.value.Range(func(key protoreflect.MapKey, val protoreflect.Value) bool {
|
||||
keyVal := m.NativeToValue(key.Interface())
|
||||
valVal := m.NativeToValue(val)
|
||||
otherVal, found := otherMap.Find(keyVal)
|
||||
if !found {
|
||||
retVal = False
|
||||
return false
|
||||
}
|
||||
valEq := Equal(valVal, otherVal)
|
||||
if valEq != True {
|
||||
retVal = valEq
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
return retVal
|
||||
}
|
||||
|
||||
// Find returns whether the protoreflect.Map contains the input key.
|
||||
//
|
||||
// If the key is not found the function returns (nil, false).
|
||||
func (m *protoMap) Find(key ref.Val) (ref.Val, bool) {
|
||||
if keyVal, found := m.findInternal(key); found {
|
||||
return keyVal, true
|
||||
}
|
||||
switch k := key.(type) {
|
||||
// Double is not a valid proto map key type, so check for the key as an int or uint.
|
||||
case Double:
|
||||
if ik, ok := doubleToInt64Lossless(float64(k)); ok {
|
||||
if keyVal, found := m.findInternal(Int(ik)); found {
|
||||
return keyVal, true
|
||||
}
|
||||
}
|
||||
if uk, ok := doubleToUint64Lossless(float64(k)); ok {
|
||||
return m.findInternal(Uint(uk))
|
||||
}
|
||||
// map keys of type double are not supported.
|
||||
case Int:
|
||||
if uk, ok := int64ToUint64Lossless(int64(k)); ok {
|
||||
return m.findInternal(Uint(uk))
|
||||
}
|
||||
case Uint:
|
||||
if ik, ok := uint64ToInt64Lossless(uint64(k)); ok {
|
||||
return m.findInternal(Int(ik))
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// findInternal attempts to convert the incoming key to the map's internal native type
|
||||
// and then returns the value, if found.
|
||||
func (m *protoMap) findInternal(key ref.Val) (ref.Val, bool) {
|
||||
// Convert the input key to the expected protobuf key type.
|
||||
ntvKey, err := key.ConvertToNative(m.value.KeyType.ReflectType())
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
// Use protoreflection to get the key value.
|
||||
val := m.value.Get(protoreflect.ValueOf(ntvKey).MapKey())
|
||||
if !val.IsValid() {
|
||||
return nil, false
|
||||
}
|
||||
// Perform nominal type unwrapping from the input value.
|
||||
switch v := val.Interface().(type) {
|
||||
case protoreflect.List, protoreflect.Map:
|
||||
// Maps do not support list or map values
|
||||
return nil, false
|
||||
default:
|
||||
return m.NativeToValue(v), true
|
||||
}
|
||||
}
|
||||
|
||||
// Get implements the traits.Indexer interface method.
|
||||
func (m *protoMap) Get(key ref.Val) ref.Val {
|
||||
v, found := m.Find(key)
|
||||
if !found {
|
||||
return ValOrErr(v, "no such key: %v", key)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Iterator implements the traits.Iterable interface method.
|
||||
func (m *protoMap) Iterator() traits.Iterator {
|
||||
// Copy the keys to make their order stable.
|
||||
mapKeys := make([]protoreflect.MapKey, 0, m.value.Len())
|
||||
m.value.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {
|
||||
mapKeys = append(mapKeys, k)
|
||||
return true
|
||||
})
|
||||
return &protoMapIterator{
|
||||
TypeAdapter: m.TypeAdapter,
|
||||
mapKeys: mapKeys,
|
||||
len: m.value.Len(),
|
||||
}
|
||||
}
|
||||
|
||||
// Size returns the number of entries in the protoreflect.Map.
|
||||
func (m *protoMap) Size() ref.Val {
|
||||
return Int(m.value.Len())
|
||||
}
|
||||
|
||||
// Type implements the ref.Val interface method.
|
||||
func (m *protoMap) Type() ref.Type {
|
||||
return MapType
|
||||
}
|
||||
|
||||
// Value implements the ref.Val interface method.
|
||||
func (m *protoMap) Value() interface{} {
|
||||
return m.value
|
||||
}
|
||||
|
||||
type mapIterator struct {
|
||||
*baseIterator
|
||||
ref.TypeAdapter
|
||||
mapKeys *reflect.MapIter
|
||||
cursor int
|
||||
len int
|
||||
}
|
||||
|
||||
// HasNext implements the traits.Iterator interface method.
|
||||
func (it *mapIterator) HasNext() ref.Val {
|
||||
return Bool(it.cursor < it.len)
|
||||
}
|
||||
|
||||
// Next implements the traits.Iterator interface method.
|
||||
func (it *mapIterator) Next() ref.Val {
|
||||
if it.HasNext() == True && it.mapKeys.Next() {
|
||||
it.cursor++
|
||||
refKey := it.mapKeys.Key()
|
||||
return it.NativeToValue(refKey.Interface())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type protoMapIterator struct {
|
||||
*baseIterator
|
||||
ref.TypeAdapter
|
||||
mapKeys []protoreflect.MapKey
|
||||
cursor int
|
||||
len int
|
||||
}
|
||||
|
||||
// HasNext implements the traits.Iterator interface method.
|
||||
func (it *protoMapIterator) HasNext() ref.Val {
|
||||
return Bool(it.cursor < it.len)
|
||||
}
|
||||
|
||||
// Next implements the traits.Iterator interface method.
|
||||
func (it *protoMapIterator) Next() ref.Val {
|
||||
if it.HasNext() == True {
|
||||
index := it.cursor
|
||||
it.cursor++
|
||||
refKey := it.mapKeys[index]
|
||||
return it.NativeToValue(refKey.Interface())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type stringKeyIterator struct {
|
||||
*baseIterator
|
||||
mapKeys []string
|
||||
cursor int
|
||||
len int
|
||||
}
|
||||
|
||||
// HasNext implements the traits.Iterator interface method.
|
||||
func (it *stringKeyIterator) HasNext() ref.Val {
|
||||
return Bool(it.cursor < it.len)
|
||||
}
|
||||
|
||||
// Next implements the traits.Iterator interface method.
|
||||
func (it *stringKeyIterator) Next() ref.Val {
|
||||
if it.HasNext() == True {
|
||||
index := it.cursor
|
||||
it.cursor++
|
||||
return String(it.mapKeys[index])
|
||||
}
|
||||
return nil
|
||||
}
|
97
vendor/github.com/google/cel-go/common/types/null.go
generated
vendored
Normal file
97
vendor/github.com/google/cel-go/common/types/null.go
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
// 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"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
// Null type implementation.
|
||||
type Null structpb.NullValue
|
||||
|
||||
var (
|
||||
// NullType singleton.
|
||||
NullType = NewTypeValue("null_type")
|
||||
// NullValue singleton.
|
||||
NullValue = Null(structpb.NullValue_NULL_VALUE)
|
||||
|
||||
jsonNullType = reflect.TypeOf(structpb.NullValue_NULL_VALUE)
|
||||
)
|
||||
|
||||
// ConvertToNative implements ref.Val.ConvertToNative.
|
||||
func (n Null) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
switch typeDesc.Kind() {
|
||||
case reflect.Int32:
|
||||
return reflect.ValueOf(n).Convert(typeDesc).Interface(), nil
|
||||
case reflect.Ptr:
|
||||
switch typeDesc {
|
||||
case anyValueType:
|
||||
// Convert to a JSON-null before packing to an Any field since the enum value for JSON
|
||||
// null cannot be packed directly.
|
||||
pb, err := n.ConvertToNative(jsonValueType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return anypb.New(pb.(proto.Message))
|
||||
case jsonValueType:
|
||||
return structpb.NewNullValue(), nil
|
||||
}
|
||||
case reflect.Interface:
|
||||
nv := n.Value()
|
||||
if reflect.TypeOf(nv).Implements(typeDesc) {
|
||||
return nv, nil
|
||||
}
|
||||
if reflect.TypeOf(n).Implements(typeDesc) {
|
||||
return n, nil
|
||||
}
|
||||
}
|
||||
// If the type conversion isn't supported return an error.
|
||||
return nil, fmt.Errorf("type conversion error from '%v' to '%v'", NullType, typeDesc)
|
||||
}
|
||||
|
||||
// ConvertToType implements ref.Val.ConvertToType.
|
||||
func (n Null) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case StringType:
|
||||
return String("null")
|
||||
case NullType:
|
||||
return n
|
||||
case TypeType:
|
||||
return NullType
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", NullType, typeVal)
|
||||
}
|
||||
|
||||
// Equal implements ref.Val.Equal.
|
||||
func (n Null) Equal(other ref.Val) ref.Val {
|
||||
return Bool(NullType == other.Type())
|
||||
}
|
||||
|
||||
// Type implements ref.Val.Type.
|
||||
func (n Null) Type() ref.Type {
|
||||
return NullType
|
||||
}
|
||||
|
||||
// Value implements ref.Val.Value.
|
||||
func (n Null) Value() interface{} {
|
||||
return structpb.NullValue_NULL_VALUE
|
||||
}
|
159
vendor/github.com/google/cel-go/common/types/object.go
generated
vendored
Normal file
159
vendor/github.com/google/cel-go/common/types/object.go
generated
vendored
Normal file
@ -0,0 +1,159 @@
|
||||
// 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/pb"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
type protoObj struct {
|
||||
ref.TypeAdapter
|
||||
value proto.Message
|
||||
typeDesc *pb.TypeDescription
|
||||
typeValue *TypeValue
|
||||
}
|
||||
|
||||
// NewObject returns an object based on a proto.Message value which handles
|
||||
// conversion between protobuf type values and expression type values.
|
||||
// Objects support indexing and iteration.
|
||||
//
|
||||
// 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,
|
||||
typeDesc *pb.TypeDescription,
|
||||
typeValue *TypeValue,
|
||||
value proto.Message) ref.Val {
|
||||
return &protoObj{
|
||||
TypeAdapter: adapter,
|
||||
value: value,
|
||||
typeDesc: typeDesc,
|
||||
typeValue: typeValue}
|
||||
}
|
||||
|
||||
func (o *protoObj) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
srcPB := o.value
|
||||
if reflect.TypeOf(srcPB).AssignableTo(typeDesc) {
|
||||
return srcPB, nil
|
||||
}
|
||||
if reflect.TypeOf(o).AssignableTo(typeDesc) {
|
||||
return o, nil
|
||||
}
|
||||
switch typeDesc {
|
||||
case anyValueType:
|
||||
_, isAny := srcPB.(*anypb.Any)
|
||||
if isAny {
|
||||
return srcPB, nil
|
||||
}
|
||||
return anypb.New(srcPB)
|
||||
case jsonValueType:
|
||||
// Marshal the proto to JSON first, and then rehydrate as protobuf.Value as there is no
|
||||
// support for direct conversion from proto.Message to protobuf.Value.
|
||||
bytes, err := protojson.Marshal(srcPB)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
json := &structpb.Value{}
|
||||
err = protojson.Unmarshal(bytes, json)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json, nil
|
||||
default:
|
||||
if typeDesc == o.typeDesc.ReflectType() {
|
||||
return o.value, nil
|
||||
}
|
||||
if typeDesc.Kind() == reflect.Ptr {
|
||||
val := reflect.New(typeDesc.Elem()).Interface()
|
||||
dstPB, ok := val.(proto.Message)
|
||||
if ok {
|
||||
err := pb.Merge(dstPB, srcPB)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("type conversion error: %v", err)
|
||||
}
|
||||
return dstPB, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("type conversion error from '%T' to '%v'", o.value, typeDesc)
|
||||
}
|
||||
|
||||
func (o *protoObj) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
default:
|
||||
if o.Type().TypeName() == typeVal.TypeName() {
|
||||
return o
|
||||
}
|
||||
case TypeType:
|
||||
return o.typeValue
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", o.typeDesc.Name(), typeVal)
|
||||
}
|
||||
|
||||
func (o *protoObj) Equal(other ref.Val) ref.Val {
|
||||
otherPB, ok := other.Value().(proto.Message)
|
||||
return Bool(ok && pb.Equal(o.value, otherPB))
|
||||
}
|
||||
|
||||
// IsSet tests whether a field which is defined is set to a non-default value.
|
||||
func (o *protoObj) IsSet(field ref.Val) ref.Val {
|
||||
protoFieldName, ok := field.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(field)
|
||||
}
|
||||
protoFieldStr := string(protoFieldName)
|
||||
fd, found := o.typeDesc.FieldByName(protoFieldStr)
|
||||
if !found {
|
||||
return NewErr("no such field '%s'", field)
|
||||
}
|
||||
if fd.IsSet(o.value) {
|
||||
return True
|
||||
}
|
||||
return False
|
||||
}
|
||||
|
||||
func (o *protoObj) Get(index ref.Val) ref.Val {
|
||||
protoFieldName, ok := index.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(index)
|
||||
}
|
||||
protoFieldStr := string(protoFieldName)
|
||||
fd, found := o.typeDesc.FieldByName(protoFieldStr)
|
||||
if !found {
|
||||
return NewErr("no such field '%s'", index)
|
||||
}
|
||||
fv, err := fd.GetFrom(o.value)
|
||||
if err != nil {
|
||||
return NewErr(err.Error())
|
||||
}
|
||||
return o.NativeToValue(fv)
|
||||
}
|
||||
|
||||
func (o *protoObj) Type() ref.Type {
|
||||
return o.typeValue
|
||||
}
|
||||
|
||||
func (o *protoObj) Value() interface{} {
|
||||
return o.value
|
||||
}
|
389
vendor/github.com/google/cel-go/common/types/overflow.go
generated
vendored
Normal file
389
vendor/github.com/google/cel-go/common/types/overflow.go
generated
vendored
Normal file
@ -0,0 +1,389 @@
|
||||
// Copyright 2021 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 (
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
doubleTwoTo64 = math.Ldexp(1.0, 64)
|
||||
)
|
||||
|
||||
// addInt64Checked performs addition with overflow detection of two int64 values.
|
||||
//
|
||||
// If the operation fails the error return value will be non-nil.
|
||||
func addInt64Checked(x, y int64) (int64, error) {
|
||||
if (y > 0 && x > math.MaxInt64-y) || (y < 0 && x < math.MinInt64-y) {
|
||||
return 0, errIntOverflow
|
||||
}
|
||||
return x + y, nil
|
||||
}
|
||||
|
||||
// subtractInt64Checked performs subtraction with overflow detection of two int64 values.
|
||||
//
|
||||
// If the operation fails the error return value will be non-nil.
|
||||
func subtractInt64Checked(x, y int64) (int64, error) {
|
||||
if (y < 0 && x > math.MaxInt64+y) || (y > 0 && x < math.MinInt64+y) {
|
||||
return 0, errIntOverflow
|
||||
}
|
||||
return x - y, nil
|
||||
}
|
||||
|
||||
// negateInt64Checked performs negation with overflow detection of an int64.
|
||||
//
|
||||
// If the operation fails the error return value will be non-nil.
|
||||
func negateInt64Checked(x int64) (int64, error) {
|
||||
// In twos complement, negating MinInt64 would result in a valid of MaxInt64+1.
|
||||
if x == math.MinInt64 {
|
||||
return 0, errIntOverflow
|
||||
}
|
||||
return -x, nil
|
||||
}
|
||||
|
||||
// multiplyInt64Checked performs multiplication with overflow detection of two int64 value.
|
||||
//
|
||||
// If the operation fails the error return value will be non-nil.
|
||||
func multiplyInt64Checked(x, y int64) (int64, error) {
|
||||
// Detecting multiplication overflow is more complicated than the others. The first two detect
|
||||
// attempting to negate MinInt64, which would result in MaxInt64+1. The other four detect normal
|
||||
// overflow conditions.
|
||||
if (x == -1 && y == math.MinInt64) || (y == -1 && x == math.MinInt64) ||
|
||||
// x is positive, y is positive
|
||||
(x > 0 && y > 0 && x > math.MaxInt64/y) ||
|
||||
// x is positive, y is negative
|
||||
(x > 0 && y < 0 && y < math.MinInt64/x) ||
|
||||
// x is negative, y is positive
|
||||
(x < 0 && y > 0 && x < math.MinInt64/y) ||
|
||||
// x is negative, y is negative
|
||||
(x < 0 && y < 0 && y < math.MaxInt64/x) {
|
||||
return 0, errIntOverflow
|
||||
}
|
||||
return x * y, nil
|
||||
}
|
||||
|
||||
// divideInt64Checked performs division with overflow detection of two int64 values,
|
||||
// as well as a division by zero check.
|
||||
//
|
||||
// If the operation fails the error return value will be non-nil.
|
||||
func divideInt64Checked(x, y int64) (int64, error) {
|
||||
// Division by zero.
|
||||
if y == 0 {
|
||||
return 0, errDivideByZero
|
||||
}
|
||||
// In twos complement, negating MinInt64 would result in a valid of MaxInt64+1.
|
||||
if x == math.MinInt64 && y == -1 {
|
||||
return 0, errIntOverflow
|
||||
}
|
||||
return x / y, nil
|
||||
}
|
||||
|
||||
// moduloInt64Checked performs modulo with overflow detection of two int64 values
|
||||
// as well as a modulus by zero check.
|
||||
//
|
||||
// If the operation fails the error return value will be non-nil.
|
||||
func moduloInt64Checked(x, y int64) (int64, error) {
|
||||
// Modulus by zero.
|
||||
if y == 0 {
|
||||
return 0, errModulusByZero
|
||||
}
|
||||
// In twos complement, negating MinInt64 would result in a valid of MaxInt64+1.
|
||||
if x == math.MinInt64 && y == -1 {
|
||||
return 0, errIntOverflow
|
||||
}
|
||||
return x % y, nil
|
||||
}
|
||||
|
||||
// addUint64Checked performs addition with overflow detection of two uint64 values.
|
||||
//
|
||||
// If the operation fails due to overflow the error return value will be non-nil.
|
||||
func addUint64Checked(x, y uint64) (uint64, error) {
|
||||
if y > 0 && x > math.MaxUint64-y {
|
||||
return 0, errUintOverflow
|
||||
}
|
||||
return x + y, nil
|
||||
}
|
||||
|
||||
// subtractUint64Checked performs subtraction with overflow detection of two uint64 values.
|
||||
//
|
||||
// If the operation fails due to overflow the error return value will be non-nil.
|
||||
func subtractUint64Checked(x, y uint64) (uint64, error) {
|
||||
if y > x {
|
||||
return 0, errUintOverflow
|
||||
}
|
||||
return x - y, nil
|
||||
}
|
||||
|
||||
// multiplyUint64Checked performs multiplication with overflow detection of two uint64 values.
|
||||
//
|
||||
// If the operation fails due to overflow the error return value will be non-nil.
|
||||
func multiplyUint64Checked(x, y uint64) (uint64, error) {
|
||||
if y != 0 && x > math.MaxUint64/y {
|
||||
return 0, errUintOverflow
|
||||
}
|
||||
return x * y, nil
|
||||
}
|
||||
|
||||
// divideUint64Checked performs division with a test for division by zero.
|
||||
//
|
||||
// If the operation fails the error return value will be non-nil.
|
||||
func divideUint64Checked(x, y uint64) (uint64, error) {
|
||||
if y == 0 {
|
||||
return 0, errDivideByZero
|
||||
}
|
||||
return x / y, nil
|
||||
}
|
||||
|
||||
// moduloUint64Checked performs modulo with a test for modulus by zero.
|
||||
//
|
||||
// If the operation fails the error return value will be non-nil.
|
||||
func moduloUint64Checked(x, y uint64) (uint64, error) {
|
||||
if y == 0 {
|
||||
return 0, errModulusByZero
|
||||
}
|
||||
return x % y, nil
|
||||
}
|
||||
|
||||
// addDurationChecked performs addition with overflow detection of two time.Durations.
|
||||
//
|
||||
// If the operation fails due to overflow the error return value will be non-nil.
|
||||
func addDurationChecked(x, y time.Duration) (time.Duration, error) {
|
||||
val, err := addInt64Checked(int64(x), int64(y))
|
||||
if err != nil {
|
||||
return time.Duration(0), err
|
||||
}
|
||||
return time.Duration(val), nil
|
||||
}
|
||||
|
||||
// subtractDurationChecked performs subtraction with overflow detection of two time.Durations.
|
||||
//
|
||||
// If the operation fails due to overflow the error return value will be non-nil.
|
||||
func subtractDurationChecked(x, y time.Duration) (time.Duration, error) {
|
||||
val, err := subtractInt64Checked(int64(x), int64(y))
|
||||
if err != nil {
|
||||
return time.Duration(0), err
|
||||
}
|
||||
return time.Duration(val), nil
|
||||
}
|
||||
|
||||
// negateDurationChecked performs negation with overflow detection of a time.Duration.
|
||||
//
|
||||
// If the operation fails due to overflow the error return value will be non-nil.
|
||||
func negateDurationChecked(x time.Duration) (time.Duration, error) {
|
||||
val, err := negateInt64Checked(int64(x))
|
||||
if err != nil {
|
||||
return time.Duration(0), err
|
||||
}
|
||||
return time.Duration(val), nil
|
||||
}
|
||||
|
||||
// addDurationChecked performs addition with overflow detection of a time.Time and time.Duration.
|
||||
//
|
||||
// If the operation fails due to overflow the error return value will be non-nil.
|
||||
func addTimeDurationChecked(x time.Time, y time.Duration) (time.Time, error) {
|
||||
// This is tricky. A time is represented as (int64, int32) where the first is seconds and second
|
||||
// is nanoseconds. A duration is int64 representing nanoseconds. We cannot normalize time to int64
|
||||
// as it could potentially overflow. The only way to proceed is to break time and duration into
|
||||
// second and nanosecond components.
|
||||
|
||||
// First we break time into its components by truncating and subtracting.
|
||||
sec1 := x.Truncate(time.Second).Unix() // Truncate to seconds.
|
||||
nsec1 := x.Sub(x.Truncate(time.Second)).Nanoseconds() // Get nanoseconds by truncating and subtracting.
|
||||
|
||||
// Second we break duration into its components by dividing and modulo.
|
||||
sec2 := int64(y) / int64(time.Second) // Truncate to seconds.
|
||||
nsec2 := int64(y) % int64(time.Second) // Get remainder.
|
||||
|
||||
// Add seconds first, detecting any overflow.
|
||||
sec, err := addInt64Checked(sec1, sec2)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
// Nanoseconds cannot overflow as time.Time normalizes them to [0, 999999999].
|
||||
nsec := nsec1 + nsec2
|
||||
|
||||
// We need to normalize nanoseconds to be positive and carry extra nanoseconds to seconds.
|
||||
// Adapted from time.Unix(int64, int64).
|
||||
if nsec < 0 || nsec >= int64(time.Second) {
|
||||
// Add seconds.
|
||||
sec, err = addInt64Checked(sec, nsec/int64(time.Second))
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
|
||||
nsec -= (nsec / int64(time.Second)) * int64(time.Second)
|
||||
if nsec < 0 {
|
||||
// Subtract an extra second
|
||||
sec, err = addInt64Checked(sec, -1)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
nsec += int64(time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the the number of seconds from Unix epoch is within our acceptable range.
|
||||
if sec < minUnixTime || sec > maxUnixTime {
|
||||
return time.Time{}, errTimestampOverflow
|
||||
}
|
||||
|
||||
// Return resulting time and propagate time zone.
|
||||
return time.Unix(sec, nsec).In(x.Location()), nil
|
||||
}
|
||||
|
||||
// subtractTimeChecked performs subtraction with overflow detection of two time.Time.
|
||||
//
|
||||
// If the operation fails due to overflow the error return value will be non-nil.
|
||||
func subtractTimeChecked(x, y time.Time) (time.Duration, error) {
|
||||
// Similar to addTimeDurationOverflow() above.
|
||||
|
||||
// First we break time into its components by truncating and subtracting.
|
||||
sec1 := x.Truncate(time.Second).Unix() // Truncate to seconds.
|
||||
nsec1 := x.Sub(x.Truncate(time.Second)).Nanoseconds() // Get nanoseconds by truncating and subtracting.
|
||||
|
||||
// Second we break duration into its components by truncating and subtracting.
|
||||
sec2 := y.Truncate(time.Second).Unix() // Truncate to seconds.
|
||||
nsec2 := y.Sub(y.Truncate(time.Second)).Nanoseconds() // Get nanoseconds by truncating and subtracting.
|
||||
|
||||
// Subtract seconds first, detecting any overflow.
|
||||
sec, err := subtractInt64Checked(sec1, sec2)
|
||||
if err != nil {
|
||||
return time.Duration(0), err
|
||||
}
|
||||
|
||||
// Nanoseconds cannot overflow as time.Time normalizes them to [0, 999999999].
|
||||
nsec := nsec1 - nsec2
|
||||
|
||||
// Scale seconds to nanoseconds detecting overflow.
|
||||
tsec, err := multiplyInt64Checked(sec, int64(time.Second))
|
||||
if err != nil {
|
||||
return time.Duration(0), err
|
||||
}
|
||||
|
||||
// Lastly we need to add the two nanoseconds together.
|
||||
val, err := addInt64Checked(tsec, nsec)
|
||||
if err != nil {
|
||||
return time.Duration(0), err
|
||||
}
|
||||
|
||||
return time.Duration(val), nil
|
||||
}
|
||||
|
||||
// subtractTimeDurationChecked performs subtraction with overflow detection of a time.Time and
|
||||
// time.Duration.
|
||||
//
|
||||
// If the operation fails due to overflow the error return value will be non-nil.
|
||||
func subtractTimeDurationChecked(x time.Time, y time.Duration) (time.Time, error) {
|
||||
// The easiest way to implement this is to negate y and add them.
|
||||
// x - y = x + -y
|
||||
val, err := negateDurationChecked(y)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
return addTimeDurationChecked(x, val)
|
||||
}
|
||||
|
||||
// doubleToInt64Checked converts a double to an int64 value.
|
||||
//
|
||||
// If the conversion fails due to overflow the error return value will be non-nil.
|
||||
func doubleToInt64Checked(v float64) (int64, error) {
|
||||
if math.IsInf(v, 0) || math.IsNaN(v) || v <= float64(math.MinInt64) || v >= float64(math.MaxInt64) {
|
||||
return 0, errIntOverflow
|
||||
}
|
||||
return int64(v), nil
|
||||
}
|
||||
|
||||
// doubleToInt64Checked converts a double to a uint64 value.
|
||||
//
|
||||
// If the conversion fails due to overflow the error return value will be non-nil.
|
||||
func doubleToUint64Checked(v float64) (uint64, error) {
|
||||
if math.IsInf(v, 0) || math.IsNaN(v) || v < 0 || v >= doubleTwoTo64 {
|
||||
return 0, errUintOverflow
|
||||
}
|
||||
return uint64(v), nil
|
||||
}
|
||||
|
||||
// int64ToUint64Checked converts an int64 to a uint64 value.
|
||||
//
|
||||
// If the conversion fails due to overflow the error return value will be non-nil.
|
||||
func int64ToUint64Checked(v int64) (uint64, error) {
|
||||
if v < 0 {
|
||||
return 0, errUintOverflow
|
||||
}
|
||||
return uint64(v), nil
|
||||
}
|
||||
|
||||
// int64ToInt32Checked converts an int64 to an int32 value.
|
||||
//
|
||||
// If the conversion fails due to overflow the error return value will be non-nil.
|
||||
func int64ToInt32Checked(v int64) (int32, error) {
|
||||
if v < math.MinInt32 || v > math.MaxInt32 {
|
||||
return 0, errIntOverflow
|
||||
}
|
||||
return int32(v), nil
|
||||
}
|
||||
|
||||
// uint64ToUint32Checked converts a uint64 to a uint32 value.
|
||||
//
|
||||
// If the conversion fails due to overflow the error return value will be non-nil.
|
||||
func uint64ToUint32Checked(v uint64) (uint32, error) {
|
||||
if v > math.MaxUint32 {
|
||||
return 0, errUintOverflow
|
||||
}
|
||||
return uint32(v), nil
|
||||
}
|
||||
|
||||
// uint64ToInt64Checked converts a uint64 to an int64 value.
|
||||
//
|
||||
// If the conversion fails due to overflow the error return value will be non-nil.
|
||||
func uint64ToInt64Checked(v uint64) (int64, error) {
|
||||
if v > math.MaxInt64 {
|
||||
return 0, errIntOverflow
|
||||
}
|
||||
return int64(v), nil
|
||||
}
|
||||
|
||||
func doubleToUint64Lossless(v float64) (uint64, bool) {
|
||||
u, err := doubleToUint64Checked(v)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
if float64(u) != v {
|
||||
return 0, false
|
||||
}
|
||||
return u, true
|
||||
}
|
||||
|
||||
func doubleToInt64Lossless(v float64) (int64, bool) {
|
||||
i, err := doubleToInt64Checked(v)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
if float64(i) != v {
|
||||
return 0, false
|
||||
}
|
||||
return i, true
|
||||
}
|
||||
|
||||
func int64ToUint64Lossless(v int64) (uint64, bool) {
|
||||
u, err := int64ToUint64Checked(v)
|
||||
return u, err == nil
|
||||
}
|
||||
|
||||
func uint64ToInt64Lossless(v uint64) (int64, bool) {
|
||||
i, err := uint64ToInt64Checked(v)
|
||||
return i, err == nil
|
||||
}
|
53
vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel
generated
vendored
Normal file
53
vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
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 = [
|
||||
"checked.go",
|
||||
"enum.go",
|
||||
"equal.go",
|
||||
"file.go",
|
||||
"pb.go",
|
||||
"type.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/types/pb",
|
||||
deps = [
|
||||
"@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
|
||||
"@org_golang_google_protobuf//encoding/protowire:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
"@org_golang_google_protobuf//reflect/protoreflect:go_default_library",
|
||||
"@org_golang_google_protobuf//reflect/protoregistry:go_default_library",
|
||||
"@org_golang_google_protobuf//types/dynamicpb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/anypb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/durationpb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/emptypb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/structpb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/timestamppb:go_default_library",
|
||||
"@org_golang_google_protobuf//types/known/wrapperspb:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"equal_test.go",
|
||||
"file_test.go",
|
||||
"pb_test.go",
|
||||
"type_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//checker/decls:go_default_library",
|
||||
"//test/proto2pb:test_all_types_go_proto",
|
||||
"//test/proto3pb:test_all_types_go_proto",
|
||||
"@org_golang_google_protobuf//reflect/protodesc:go_default_library",
|
||||
"@org_golang_google_protobuf//reflect/protoreflect:go_default_library",
|
||||
"@org_golang_google_protobuf//types/descriptorpb:go_default_library",
|
||||
],
|
||||
)
|
93
vendor/github.com/google/cel-go/common/types/pb/checked.go
generated
vendored
Normal file
93
vendor/github.com/google/cel-go/common/types/pb/checked.go
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
// 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 pb
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
var (
|
||||
// CheckedPrimitives map from proto field descriptor type to expr.Type.
|
||||
CheckedPrimitives = map[protoreflect.Kind]*exprpb.Type{
|
||||
protoreflect.BoolKind: checkedBool,
|
||||
protoreflect.BytesKind: checkedBytes,
|
||||
protoreflect.DoubleKind: checkedDouble,
|
||||
protoreflect.FloatKind: checkedDouble,
|
||||
protoreflect.Int32Kind: checkedInt,
|
||||
protoreflect.Int64Kind: checkedInt,
|
||||
protoreflect.Sint32Kind: checkedInt,
|
||||
protoreflect.Sint64Kind: checkedInt,
|
||||
protoreflect.Uint32Kind: checkedUint,
|
||||
protoreflect.Uint64Kind: checkedUint,
|
||||
protoreflect.Fixed32Kind: checkedUint,
|
||||
protoreflect.Fixed64Kind: checkedUint,
|
||||
protoreflect.Sfixed32Kind: checkedInt,
|
||||
protoreflect.Sfixed64Kind: checkedInt,
|
||||
protoreflect.StringKind: checkedString}
|
||||
|
||||
// CheckedWellKnowns map from qualified proto type name to expr.Type for
|
||||
// well-known proto types.
|
||||
CheckedWellKnowns = map[string]*exprpb.Type{
|
||||
// Wrapper types.
|
||||
"google.protobuf.BoolValue": checkedWrap(checkedBool),
|
||||
"google.protobuf.BytesValue": checkedWrap(checkedBytes),
|
||||
"google.protobuf.DoubleValue": checkedWrap(checkedDouble),
|
||||
"google.protobuf.FloatValue": checkedWrap(checkedDouble),
|
||||
"google.protobuf.Int64Value": checkedWrap(checkedInt),
|
||||
"google.protobuf.Int32Value": checkedWrap(checkedInt),
|
||||
"google.protobuf.UInt64Value": checkedWrap(checkedUint),
|
||||
"google.protobuf.UInt32Value": checkedWrap(checkedUint),
|
||||
"google.protobuf.StringValue": checkedWrap(checkedString),
|
||||
// Well-known types.
|
||||
"google.protobuf.Any": checkedAny,
|
||||
"google.protobuf.Duration": checkedDuration,
|
||||
"google.protobuf.Timestamp": checkedTimestamp,
|
||||
// Json types.
|
||||
"google.protobuf.ListValue": checkedListDyn,
|
||||
"google.protobuf.NullValue": checkedNull,
|
||||
"google.protobuf.Struct": checkedMapStringDyn,
|
||||
"google.protobuf.Value": checkedDyn,
|
||||
}
|
||||
|
||||
// common types
|
||||
checkedDyn = &exprpb.Type{TypeKind: &exprpb.Type_Dyn{Dyn: &emptypb.Empty{}}}
|
||||
// Wrapper and primitive types.
|
||||
checkedBool = checkedPrimitive(exprpb.Type_BOOL)
|
||||
checkedBytes = checkedPrimitive(exprpb.Type_BYTES)
|
||||
checkedDouble = checkedPrimitive(exprpb.Type_DOUBLE)
|
||||
checkedInt = checkedPrimitive(exprpb.Type_INT64)
|
||||
checkedString = checkedPrimitive(exprpb.Type_STRING)
|
||||
checkedUint = checkedPrimitive(exprpb.Type_UINT64)
|
||||
// Well-known type equivalents.
|
||||
checkedAny = checkedWellKnown(exprpb.Type_ANY)
|
||||
checkedDuration = checkedWellKnown(exprpb.Type_DURATION)
|
||||
checkedTimestamp = checkedWellKnown(exprpb.Type_TIMESTAMP)
|
||||
// Json-based type equivalents.
|
||||
checkedNull = &exprpb.Type{
|
||||
TypeKind: &exprpb.Type_Null{
|
||||
Null: structpb.NullValue_NULL_VALUE}}
|
||||
checkedListDyn = &exprpb.Type{
|
||||
TypeKind: &exprpb.Type_ListType_{
|
||||
ListType: &exprpb.Type_ListType{ElemType: checkedDyn}}}
|
||||
checkedMapStringDyn = &exprpb.Type{
|
||||
TypeKind: &exprpb.Type_MapType_{
|
||||
MapType: &exprpb.Type_MapType{
|
||||
KeyType: checkedString,
|
||||
ValueType: checkedDyn}}}
|
||||
)
|
44
vendor/github.com/google/cel-go/common/types/pb/enum.go
generated
vendored
Normal file
44
vendor/github.com/google/cel-go/common/types/pb/enum.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
// 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 pb
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
// NewEnumValueDescription produces an enum value description with the fully qualified enum value
|
||||
// name and the enum value descriptor.
|
||||
func NewEnumValueDescription(name string, desc protoreflect.EnumValueDescriptor) *EnumValueDescription {
|
||||
return &EnumValueDescription{
|
||||
enumValueName: name,
|
||||
desc: desc,
|
||||
}
|
||||
}
|
||||
|
||||
// EnumValueDescription maps a fully-qualified enum value name to its numeric value.
|
||||
type EnumValueDescription struct {
|
||||
enumValueName string
|
||||
desc protoreflect.EnumValueDescriptor
|
||||
}
|
||||
|
||||
// Name returns the fully-qualified identifier name for the enum value.
|
||||
func (ed *EnumValueDescription) Name() string {
|
||||
return ed.enumValueName
|
||||
}
|
||||
|
||||
// Value returns the (numeric) value of the enum.
|
||||
func (ed *EnumValueDescription) Value() int32 {
|
||||
return int32(ed.desc.Number())
|
||||
}
|
206
vendor/github.com/google/cel-go/common/types/pb/equal.go
generated
vendored
Normal file
206
vendor/github.com/google/cel-go/common/types/pb/equal.go
generated
vendored
Normal file
@ -0,0 +1,206 @@
|
||||
// Copyright 2022 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 pb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protowire"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
)
|
||||
|
||||
// Equal returns whether two proto.Message instances are equal using the following criteria:
|
||||
//
|
||||
// - Messages must share the same instance of the type descriptor
|
||||
// - Known set fields are compared using semantics equality
|
||||
// - Bytes are compared using bytes.Equal
|
||||
// - Scalar values are compared with operator ==
|
||||
// - List and map types are equal if they have the same length and all elements are equal
|
||||
// - Messages are equal if they share the same descriptor and all set fields are equal
|
||||
// - Unknown fields are compared using byte equality
|
||||
// - NaN values are not equal to each other
|
||||
// - google.protobuf.Any values are unpacked before comparison
|
||||
// - If the type descriptor for a protobuf.Any cannot be found, byte equality is used rather than
|
||||
// semantic equality.
|
||||
//
|
||||
// This method of proto equality mirrors the behavior of the C++ protobuf MessageDifferencer
|
||||
// whereas the golang proto.Equal implementation mirrors the Java protobuf equals() methods
|
||||
// behaviors which needed to treat NaN values as equal due to Java semantics.
|
||||
func Equal(x, y proto.Message) bool {
|
||||
if x == nil || y == nil {
|
||||
return x == nil && y == nil
|
||||
}
|
||||
xRef := x.ProtoReflect()
|
||||
yRef := y.ProtoReflect()
|
||||
return equalMessage(xRef, yRef)
|
||||
}
|
||||
|
||||
func equalMessage(mx, my protoreflect.Message) bool {
|
||||
// Note, the original proto.Equal upon which this implementation is based does not specifically handle the
|
||||
// case when both messages are invalid. It is assumed that the descriptors will be equal and that byte-wise
|
||||
// comparison will be used, though the semantics of validity are neither clear, nor promised within the
|
||||
// proto.Equal implementation.
|
||||
if mx.IsValid() != my.IsValid() || mx.Descriptor() != my.Descriptor() {
|
||||
return false
|
||||
}
|
||||
|
||||
// This is an innovation on the default proto.Equal where protobuf.Any values are unpacked before comparison
|
||||
// as otherwise the Any values are compared by bytes rather than structurally.
|
||||
if isAny(mx) && isAny(my) {
|
||||
ax := mx.Interface().(*anypb.Any)
|
||||
ay := my.Interface().(*anypb.Any)
|
||||
// If the values are not the same type url, return false.
|
||||
if ax.GetTypeUrl() != ay.GetTypeUrl() {
|
||||
return false
|
||||
}
|
||||
// If the values are byte equal, then return true.
|
||||
if bytes.Equal(ax.GetValue(), ay.GetValue()) {
|
||||
return true
|
||||
}
|
||||
// Otherwise fall through to the semantic comparison of the any values.
|
||||
x, err := ax.UnmarshalNew()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
y, err := ay.UnmarshalNew()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
// Recursively compare the unwrapped messages to ensure nested Any values are unwrapped accordingly.
|
||||
return equalMessage(x.ProtoReflect(), y.ProtoReflect())
|
||||
}
|
||||
|
||||
// Walk the set fields to determine field-wise equality
|
||||
nx := 0
|
||||
equal := true
|
||||
mx.Range(func(fd protoreflect.FieldDescriptor, vx protoreflect.Value) bool {
|
||||
nx++
|
||||
equal = my.Has(fd) && equalField(fd, vx, my.Get(fd))
|
||||
return equal
|
||||
})
|
||||
if !equal {
|
||||
return false
|
||||
}
|
||||
// Establish the count of set fields on message y
|
||||
ny := 0
|
||||
my.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool {
|
||||
ny++
|
||||
return true
|
||||
})
|
||||
// If the number of set fields is not equal return false.
|
||||
if nx != ny {
|
||||
return false
|
||||
}
|
||||
|
||||
return equalUnknown(mx.GetUnknown(), my.GetUnknown())
|
||||
}
|
||||
|
||||
func equalField(fd protoreflect.FieldDescriptor, x, y protoreflect.Value) bool {
|
||||
switch {
|
||||
case fd.IsMap():
|
||||
return equalMap(fd, x.Map(), y.Map())
|
||||
case fd.IsList():
|
||||
return equalList(fd, x.List(), y.List())
|
||||
default:
|
||||
return equalValue(fd, x, y)
|
||||
}
|
||||
}
|
||||
|
||||
func equalMap(fd protoreflect.FieldDescriptor, x, y protoreflect.Map) bool {
|
||||
if x.Len() != y.Len() {
|
||||
return false
|
||||
}
|
||||
equal := true
|
||||
x.Range(func(k protoreflect.MapKey, vx protoreflect.Value) bool {
|
||||
vy := y.Get(k)
|
||||
equal = y.Has(k) && equalValue(fd.MapValue(), vx, vy)
|
||||
return equal
|
||||
})
|
||||
return equal
|
||||
}
|
||||
|
||||
func equalList(fd protoreflect.FieldDescriptor, x, y protoreflect.List) bool {
|
||||
if x.Len() != y.Len() {
|
||||
return false
|
||||
}
|
||||
for i := x.Len() - 1; i >= 0; i-- {
|
||||
if !equalValue(fd, x.Get(i), y.Get(i)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func equalValue(fd protoreflect.FieldDescriptor, x, y protoreflect.Value) bool {
|
||||
switch fd.Kind() {
|
||||
case protoreflect.BoolKind:
|
||||
return x.Bool() == y.Bool()
|
||||
case protoreflect.EnumKind:
|
||||
return x.Enum() == y.Enum()
|
||||
case protoreflect.Int32Kind, protoreflect.Sint32Kind,
|
||||
protoreflect.Int64Kind, protoreflect.Sint64Kind,
|
||||
protoreflect.Sfixed32Kind, protoreflect.Sfixed64Kind:
|
||||
return x.Int() == y.Int()
|
||||
case protoreflect.Uint32Kind, protoreflect.Uint64Kind,
|
||||
protoreflect.Fixed32Kind, protoreflect.Fixed64Kind:
|
||||
return x.Uint() == y.Uint()
|
||||
case protoreflect.FloatKind, protoreflect.DoubleKind:
|
||||
return x.Float() == y.Float()
|
||||
case protoreflect.StringKind:
|
||||
return x.String() == y.String()
|
||||
case protoreflect.BytesKind:
|
||||
return bytes.Equal(x.Bytes(), y.Bytes())
|
||||
case protoreflect.MessageKind, protoreflect.GroupKind:
|
||||
return equalMessage(x.Message(), y.Message())
|
||||
default:
|
||||
return x.Interface() == y.Interface()
|
||||
}
|
||||
}
|
||||
|
||||
func equalUnknown(x, y protoreflect.RawFields) bool {
|
||||
lenX := len(x)
|
||||
lenY := len(y)
|
||||
if lenX != lenY {
|
||||
return false
|
||||
}
|
||||
if lenX == 0 {
|
||||
return true
|
||||
}
|
||||
if bytes.Equal([]byte(x), []byte(y)) {
|
||||
return true
|
||||
}
|
||||
|
||||
mx := make(map[protoreflect.FieldNumber]protoreflect.RawFields)
|
||||
my := make(map[protoreflect.FieldNumber]protoreflect.RawFields)
|
||||
for len(x) > 0 {
|
||||
fnum, _, n := protowire.ConsumeField(x)
|
||||
mx[fnum] = append(mx[fnum], x[:n]...)
|
||||
x = x[n:]
|
||||
}
|
||||
for len(y) > 0 {
|
||||
fnum, _, n := protowire.ConsumeField(y)
|
||||
my[fnum] = append(my[fnum], y[:n]...)
|
||||
y = y[n:]
|
||||
}
|
||||
return reflect.DeepEqual(mx, my)
|
||||
}
|
||||
|
||||
func isAny(m protoreflect.Message) bool {
|
||||
return string(m.Descriptor().FullName()) == "google.protobuf.Any"
|
||||
}
|
141
vendor/github.com/google/cel-go/common/types/pb/file.go
generated
vendored
Normal file
141
vendor/github.com/google/cel-go/common/types/pb/file.go
generated
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
// 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 pb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
// NewFileDescription returns a FileDescription instance with a complete listing of all the message
|
||||
// types and enum values declared within any scope in the file.
|
||||
func NewFileDescription(fileDesc protoreflect.FileDescriptor, pbdb *Db) *FileDescription {
|
||||
metadata := collectFileMetadata(fileDesc)
|
||||
enums := make(map[string]*EnumValueDescription)
|
||||
for name, enumVal := range metadata.enumValues {
|
||||
enums[name] = NewEnumValueDescription(name, enumVal)
|
||||
}
|
||||
types := make(map[string]*TypeDescription)
|
||||
for name, msgType := range metadata.msgTypes {
|
||||
types[name] = NewTypeDescription(name, msgType)
|
||||
}
|
||||
return &FileDescription{
|
||||
types: types,
|
||||
enums: enums,
|
||||
}
|
||||
}
|
||||
|
||||
// FileDescription holds a map of all types and enum values declared within a proto file.
|
||||
type FileDescription struct {
|
||||
types map[string]*TypeDescription
|
||||
enums map[string]*EnumValueDescription
|
||||
}
|
||||
|
||||
// GetEnumDescription returns an EnumDescription for a qualified enum value
|
||||
// name declared within the .proto file.
|
||||
func (fd *FileDescription) GetEnumDescription(enumName string) (*EnumValueDescription, bool) {
|
||||
ed, found := fd.enums[sanitizeProtoName(enumName)]
|
||||
return ed, found
|
||||
}
|
||||
|
||||
// GetEnumNames returns the string names of all enum values in the file.
|
||||
func (fd *FileDescription) GetEnumNames() []string {
|
||||
enumNames := make([]string, len(fd.enums))
|
||||
i := 0
|
||||
for _, e := range fd.enums {
|
||||
enumNames[i] = e.Name()
|
||||
i++
|
||||
}
|
||||
return enumNames
|
||||
}
|
||||
|
||||
// GetTypeDescription returns a TypeDescription for a qualified protobuf message type name
|
||||
// declared within the .proto file.
|
||||
func (fd *FileDescription) GetTypeDescription(typeName string) (*TypeDescription, bool) {
|
||||
td, found := fd.types[sanitizeProtoName(typeName)]
|
||||
return td, found
|
||||
}
|
||||
|
||||
// GetTypeNames returns the list of all type names contained within the file.
|
||||
func (fd *FileDescription) GetTypeNames() []string {
|
||||
typeNames := make([]string, len(fd.types))
|
||||
i := 0
|
||||
for _, t := range fd.types {
|
||||
typeNames[i] = t.Name()
|
||||
i++
|
||||
}
|
||||
return typeNames
|
||||
}
|
||||
|
||||
// sanitizeProtoName strips the leading '.' from the proto message name.
|
||||
func sanitizeProtoName(name string) string {
|
||||
if name != "" && name[0] == '.' {
|
||||
return name[1:]
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
// fileMetadata is a flattened view of message types and enum values within a file descriptor.
|
||||
type fileMetadata struct {
|
||||
// msgTypes maps from fully-qualified message name to descriptor.
|
||||
msgTypes map[string]protoreflect.MessageDescriptor
|
||||
// enumValues maps from fully-qualified enum value to enum value descriptor.
|
||||
enumValues map[string]protoreflect.EnumValueDescriptor
|
||||
// TODO: support enum type definitions for use in future type-check enhancements.
|
||||
}
|
||||
|
||||
// collectFileMetadata traverses the proto file object graph to collect message types and enum
|
||||
// values and index them by their fully qualified names.
|
||||
func collectFileMetadata(fileDesc protoreflect.FileDescriptor) *fileMetadata {
|
||||
msgTypes := make(map[string]protoreflect.MessageDescriptor)
|
||||
enumValues := make(map[string]protoreflect.EnumValueDescriptor)
|
||||
collectMsgTypes(fileDesc.Messages(), msgTypes, enumValues)
|
||||
collectEnumValues(fileDesc.Enums(), enumValues)
|
||||
return &fileMetadata{
|
||||
msgTypes: msgTypes,
|
||||
enumValues: enumValues,
|
||||
}
|
||||
}
|
||||
|
||||
// collectMsgTypes recursively collects messages, nested messages, and nested enums into a map of
|
||||
// fully qualified protobuf names to descriptors.
|
||||
func collectMsgTypes(msgTypes protoreflect.MessageDescriptors, msgTypeMap map[string]protoreflect.MessageDescriptor, enumValueMap map[string]protoreflect.EnumValueDescriptor) {
|
||||
for i := 0; i < msgTypes.Len(); i++ {
|
||||
msgType := msgTypes.Get(i)
|
||||
msgTypeMap[string(msgType.FullName())] = msgType
|
||||
nestedMsgTypes := msgType.Messages()
|
||||
if nestedMsgTypes.Len() != 0 {
|
||||
collectMsgTypes(nestedMsgTypes, msgTypeMap, enumValueMap)
|
||||
}
|
||||
nestedEnumTypes := msgType.Enums()
|
||||
if nestedEnumTypes.Len() != 0 {
|
||||
collectEnumValues(nestedEnumTypes, enumValueMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// collectEnumValues accumulates the enum values within an enum declaration.
|
||||
func collectEnumValues(enumTypes protoreflect.EnumDescriptors, enumValueMap map[string]protoreflect.EnumValueDescriptor) {
|
||||
for i := 0; i < enumTypes.Len(); i++ {
|
||||
enumType := enumTypes.Get(i)
|
||||
enumTypeValues := enumType.Values()
|
||||
for j := 0; j < enumTypeValues.Len(); j++ {
|
||||
enumValue := enumTypeValues.Get(j)
|
||||
enumValueName := fmt.Sprintf("%s.%s", string(enumType.FullName()), string(enumValue.Name()))
|
||||
enumValueMap[enumValueName] = enumValue
|
||||
}
|
||||
}
|
||||
}
|
223
vendor/github.com/google/cel-go/common/types/pb/pb.go
generated
vendored
Normal file
223
vendor/github.com/google/cel-go/common/types/pb/pb.go
generated
vendored
Normal file
@ -0,0 +1,223 @@
|
||||
// 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 pb reflects over protocol buffer descriptors to generate objects
|
||||
// that simplify type, enum, and field lookup.
|
||||
package pb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
durpb "google.golang.org/protobuf/types/known/durationpb"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
tspb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
|
||||
)
|
||||
|
||||
// Db maps from file / message / enum name to file description.
|
||||
//
|
||||
// Each Db is isolated from each other, and while information about protobuf descriptors may be
|
||||
// fetched from the global protobuf registry, no descriptors are added to this registry, else
|
||||
// the isolation guarantees of the Db object would be violated.
|
||||
type Db struct {
|
||||
revFileDescriptorMap map[string]*FileDescription
|
||||
// files contains the deduped set of FileDescriptions whose types are contained in the pb.Db.
|
||||
files []*FileDescription
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultDb used at evaluation time or unless overridden at check time.
|
||||
DefaultDb = &Db{
|
||||
revFileDescriptorMap: make(map[string]*FileDescription),
|
||||
files: []*FileDescription{},
|
||||
}
|
||||
)
|
||||
|
||||
// Merge will copy the source proto message into the destination, or error if the merge cannot be completed.
|
||||
//
|
||||
// Unlike the proto.Merge, this method will fallback to proto.Marshal/Unmarshal of the two proto messages do not
|
||||
// share the same instance of their type descriptor.
|
||||
func Merge(dstPB, srcPB proto.Message) error {
|
||||
src, dst := srcPB.ProtoReflect(), dstPB.ProtoReflect()
|
||||
if src.Descriptor() == dst.Descriptor() {
|
||||
proto.Merge(dstPB, srcPB)
|
||||
return nil
|
||||
}
|
||||
if src.Descriptor().FullName() != dst.Descriptor().FullName() {
|
||||
return fmt.Errorf("pb.Merge() arguments must be the same type. got: %v, %v",
|
||||
dst.Descriptor().FullName(), src.Descriptor().FullName())
|
||||
}
|
||||
bytes, err := proto.Marshal(srcPB)
|
||||
if err != nil {
|
||||
return fmt.Errorf("pb.Merge(dstPB, srcPB) failed to marshal source proto: %v", err)
|
||||
}
|
||||
err = proto.Unmarshal(bytes, dstPB)
|
||||
if err != nil {
|
||||
return fmt.Errorf("pb.Merge(dstPB, srcPB) failed to unmarshal to dest proto: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewDb creates a new `pb.Db` with an empty type name to file description map.
|
||||
func NewDb() *Db {
|
||||
pbdb := &Db{
|
||||
revFileDescriptorMap: make(map[string]*FileDescription),
|
||||
files: []*FileDescription{},
|
||||
}
|
||||
// The FileDescription objects in the default db contain lazily initialized TypeDescription
|
||||
// values which may point to the state contained in the DefaultDb irrespective of this shallow
|
||||
// copy; however, the type graph for a field is idempotently computed, and is guaranteed to
|
||||
// only be initialized once thanks to atomic values within the TypeDescription objects, so it
|
||||
// is safe to share these values across instances.
|
||||
for k, v := range DefaultDb.revFileDescriptorMap {
|
||||
pbdb.revFileDescriptorMap[k] = v
|
||||
}
|
||||
pbdb.files = append(pbdb.files, DefaultDb.files...)
|
||||
return pbdb
|
||||
}
|
||||
|
||||
// Copy creates a copy of the current database with its own internal descriptor mapping.
|
||||
func (pbdb *Db) Copy() *Db {
|
||||
copy := NewDb()
|
||||
for k, v := range pbdb.revFileDescriptorMap {
|
||||
copy.revFileDescriptorMap[k] = v
|
||||
}
|
||||
for _, f := range pbdb.files {
|
||||
hasFile := false
|
||||
for _, f2 := range copy.files {
|
||||
if f2 == f {
|
||||
hasFile = true
|
||||
}
|
||||
}
|
||||
if !hasFile {
|
||||
copy.files = append(copy.files, f)
|
||||
}
|
||||
}
|
||||
return copy
|
||||
}
|
||||
|
||||
// FileDescriptions returns the set of file descriptions associated with this db.
|
||||
func (pbdb *Db) FileDescriptions() []*FileDescription {
|
||||
return pbdb.files
|
||||
}
|
||||
|
||||
// RegisterDescriptor produces a `FileDescription` from a `FileDescriptor` and registers the
|
||||
// message and enum types into the `pb.Db`.
|
||||
func (pbdb *Db) RegisterDescriptor(fileDesc protoreflect.FileDescriptor) (*FileDescription, error) {
|
||||
fd, found := pbdb.revFileDescriptorMap[fileDesc.Path()]
|
||||
if found {
|
||||
return fd, nil
|
||||
}
|
||||
// Make sure to search the global registry to see if a protoreflect.FileDescriptor for
|
||||
// the file specified has been linked into the binary. If so, use the copy of the descriptor
|
||||
// from the global cache.
|
||||
//
|
||||
// Note: Proto reflection relies on descriptor values being object equal rather than object
|
||||
// equivalence. This choice means that a FieldDescriptor generated from a FileDescriptorProto
|
||||
// will be incompatible with the FieldDescriptor in the global registry and any message created
|
||||
// from that global registry.
|
||||
globalFD, err := protoregistry.GlobalFiles.FindFileByPath(fileDesc.Path())
|
||||
if err == nil {
|
||||
fileDesc = globalFD
|
||||
}
|
||||
fd = NewFileDescription(fileDesc, pbdb)
|
||||
for _, enumValName := range fd.GetEnumNames() {
|
||||
pbdb.revFileDescriptorMap[enumValName] = fd
|
||||
}
|
||||
for _, msgTypeName := range fd.GetTypeNames() {
|
||||
pbdb.revFileDescriptorMap[msgTypeName] = fd
|
||||
}
|
||||
pbdb.revFileDescriptorMap[fileDesc.Path()] = fd
|
||||
|
||||
// Return the specific file descriptor registered.
|
||||
pbdb.files = append(pbdb.files, fd)
|
||||
return fd, nil
|
||||
}
|
||||
|
||||
// RegisterMessage produces a `FileDescription` from a `message` and registers the message and all
|
||||
// other definitions within the message file into the `pb.Db`.
|
||||
func (pbdb *Db) RegisterMessage(message proto.Message) (*FileDescription, error) {
|
||||
msgDesc := message.ProtoReflect().Descriptor()
|
||||
msgName := msgDesc.FullName()
|
||||
typeName := sanitizeProtoName(string(msgName))
|
||||
if fd, found := pbdb.revFileDescriptorMap[typeName]; found {
|
||||
return fd, nil
|
||||
}
|
||||
return pbdb.RegisterDescriptor(msgDesc.ParentFile())
|
||||
}
|
||||
|
||||
// DescribeEnum takes a qualified enum name and returns an `EnumDescription` if it exists in the
|
||||
// `pb.Db`.
|
||||
func (pbdb *Db) DescribeEnum(enumName string) (*EnumValueDescription, bool) {
|
||||
enumName = sanitizeProtoName(enumName)
|
||||
if fd, found := pbdb.revFileDescriptorMap[enumName]; found {
|
||||
return fd.GetEnumDescription(enumName)
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// DescribeType returns a `TypeDescription` for the `typeName` if it exists in the `pb.Db`.
|
||||
func (pbdb *Db) DescribeType(typeName string) (*TypeDescription, bool) {
|
||||
typeName = sanitizeProtoName(typeName)
|
||||
if fd, found := pbdb.revFileDescriptorMap[typeName]; found {
|
||||
return fd.GetTypeDescription(typeName)
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// CollectFileDescriptorSet builds a file descriptor set associated with the file where the input
|
||||
// message is declared.
|
||||
func CollectFileDescriptorSet(message proto.Message) map[string]protoreflect.FileDescriptor {
|
||||
fdMap := map[string]protoreflect.FileDescriptor{}
|
||||
parentFile := message.ProtoReflect().Descriptor().ParentFile()
|
||||
fdMap[parentFile.Path()] = parentFile
|
||||
// Initialize list of dependencies
|
||||
deps := make([]protoreflect.FileImport, parentFile.Imports().Len())
|
||||
for i := 0; i < parentFile.Imports().Len(); i++ {
|
||||
deps[i] = parentFile.Imports().Get(i)
|
||||
}
|
||||
// Expand list for new dependencies
|
||||
for i := 0; i < len(deps); i++ {
|
||||
dep := deps[i]
|
||||
if _, found := fdMap[dep.Path()]; found {
|
||||
continue
|
||||
}
|
||||
fdMap[dep.Path()] = dep.FileDescriptor
|
||||
for j := 0; j < dep.FileDescriptor.Imports().Len(); j++ {
|
||||
deps = append(deps, dep.FileDescriptor.Imports().Get(j))
|
||||
}
|
||||
}
|
||||
return fdMap
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Describe well-known types to ensure they can always be resolved by the check and interpret
|
||||
// execution phases.
|
||||
//
|
||||
// The following subset of message types is enough to ensure that all well-known types can
|
||||
// resolved in the runtime, since describing the value results in describing the whole file
|
||||
// where the message is declared.
|
||||
DefaultDb.RegisterMessage(&anypb.Any{})
|
||||
DefaultDb.RegisterMessage(&durpb.Duration{})
|
||||
DefaultDb.RegisterMessage(&emptypb.Empty{})
|
||||
DefaultDb.RegisterMessage(&tspb.Timestamp{})
|
||||
DefaultDb.RegisterMessage(&structpb.Value{})
|
||||
DefaultDb.RegisterMessage(&wrapperspb.BoolValue{})
|
||||
}
|
552
vendor/github.com/google/cel-go/common/types/pb/type.go
generated
vendored
Normal file
552
vendor/github.com/google/cel-go/common/types/pb/type.go
generated
vendored
Normal file
@ -0,0 +1,552 @@
|
||||
// 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 pb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
dynamicpb "google.golang.org/protobuf/types/dynamicpb"
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
dpb "google.golang.org/protobuf/types/known/durationpb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
tpb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
|
||||
)
|
||||
|
||||
// description is a private interface used to make it convenient to perform type unwrapping at
|
||||
// the TypeDescription or FieldDescription level.
|
||||
type description interface {
|
||||
// Zero returns an empty immutable protobuf message when the description is a protobuf message
|
||||
// type.
|
||||
Zero() proto.Message
|
||||
}
|
||||
|
||||
// NewTypeDescription produces a TypeDescription value for the fully-qualified proto type name
|
||||
// with a given descriptor.
|
||||
func NewTypeDescription(typeName string, desc protoreflect.MessageDescriptor) *TypeDescription {
|
||||
msgType := dynamicpb.NewMessageType(desc)
|
||||
msgZero := dynamicpb.NewMessage(desc)
|
||||
fieldMap := map[string]*FieldDescription{}
|
||||
fields := desc.Fields()
|
||||
for i := 0; i < fields.Len(); i++ {
|
||||
f := fields.Get(i)
|
||||
fieldMap[string(f.Name())] = NewFieldDescription(f)
|
||||
}
|
||||
return &TypeDescription{
|
||||
typeName: typeName,
|
||||
desc: desc,
|
||||
msgType: msgType,
|
||||
fieldMap: fieldMap,
|
||||
reflectType: reflectTypeOf(msgZero),
|
||||
zeroMsg: zeroValueOf(msgZero),
|
||||
}
|
||||
}
|
||||
|
||||
// TypeDescription is a collection of type metadata relevant to expression
|
||||
// checking and evaluation.
|
||||
type TypeDescription struct {
|
||||
typeName string
|
||||
desc protoreflect.MessageDescriptor
|
||||
msgType protoreflect.MessageType
|
||||
fieldMap map[string]*FieldDescription
|
||||
reflectType reflect.Type
|
||||
zeroMsg proto.Message
|
||||
}
|
||||
|
||||
// FieldMap returns a string field name to FieldDescription map.
|
||||
func (td *TypeDescription) FieldMap() map[string]*FieldDescription {
|
||||
return td.fieldMap
|
||||
}
|
||||
|
||||
// FieldByName returns (FieldDescription, true) if the field name is declared within the type.
|
||||
func (td *TypeDescription) FieldByName(name string) (*FieldDescription, bool) {
|
||||
fd, found := td.fieldMap[name]
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
return fd, true
|
||||
}
|
||||
|
||||
// MaybeUnwrap accepts a proto message as input and unwraps it to a primitive CEL type if possible.
|
||||
//
|
||||
// This method returns the unwrapped value and 'true', else the original value and 'false'.
|
||||
func (td *TypeDescription) MaybeUnwrap(msg proto.Message) (interface{}, bool, error) {
|
||||
return unwrap(td, msg)
|
||||
}
|
||||
|
||||
// Name returns the fully-qualified name of the type.
|
||||
func (td *TypeDescription) Name() string {
|
||||
return string(td.desc.FullName())
|
||||
}
|
||||
|
||||
// New returns a mutable proto message
|
||||
func (td *TypeDescription) New() protoreflect.Message {
|
||||
return td.msgType.New()
|
||||
}
|
||||
|
||||
// ReflectType returns the Golang reflect.Type for this type.
|
||||
func (td *TypeDescription) ReflectType() reflect.Type {
|
||||
return td.reflectType
|
||||
}
|
||||
|
||||
// Zero returns the zero proto.Message value for this type.
|
||||
func (td *TypeDescription) Zero() proto.Message {
|
||||
return td.zeroMsg
|
||||
}
|
||||
|
||||
// NewFieldDescription creates a new field description from a protoreflect.FieldDescriptor.
|
||||
func NewFieldDescription(fieldDesc protoreflect.FieldDescriptor) *FieldDescription {
|
||||
var reflectType reflect.Type
|
||||
var zeroMsg proto.Message
|
||||
switch fieldDesc.Kind() {
|
||||
case protoreflect.EnumKind:
|
||||
reflectType = reflectTypeOf(protoreflect.EnumNumber(0))
|
||||
case protoreflect.GroupKind, protoreflect.MessageKind:
|
||||
zeroMsg = dynamicpb.NewMessage(fieldDesc.Message())
|
||||
reflectType = reflectTypeOf(zeroMsg)
|
||||
default:
|
||||
reflectType = reflectTypeOf(fieldDesc.Default().Interface())
|
||||
if fieldDesc.IsList() {
|
||||
parentMsg := dynamicpb.NewMessage(fieldDesc.ContainingMessage())
|
||||
listField := parentMsg.NewField(fieldDesc).List()
|
||||
elem := listField.NewElement().Interface()
|
||||
switch elemType := elem.(type) {
|
||||
case protoreflect.Message:
|
||||
elem = elemType.Interface()
|
||||
}
|
||||
reflectType = reflectTypeOf(elem)
|
||||
}
|
||||
}
|
||||
// Ensure the list type is appropriately reflected as a Go-native list.
|
||||
if fieldDesc.IsList() {
|
||||
reflectType = reflect.SliceOf(reflectType)
|
||||
}
|
||||
var keyType, valType *FieldDescription
|
||||
if fieldDesc.IsMap() {
|
||||
keyType = NewFieldDescription(fieldDesc.MapKey())
|
||||
valType = NewFieldDescription(fieldDesc.MapValue())
|
||||
}
|
||||
return &FieldDescription{
|
||||
desc: fieldDesc,
|
||||
KeyType: keyType,
|
||||
ValueType: valType,
|
||||
reflectType: reflectType,
|
||||
zeroMsg: zeroValueOf(zeroMsg),
|
||||
}
|
||||
}
|
||||
|
||||
// FieldDescription holds metadata related to fields declared within a type.
|
||||
type FieldDescription struct {
|
||||
// KeyType holds the key FieldDescription for map fields.
|
||||
KeyType *FieldDescription
|
||||
// ValueType holds the value FieldDescription for map fields.
|
||||
ValueType *FieldDescription
|
||||
|
||||
desc protoreflect.FieldDescriptor
|
||||
reflectType reflect.Type
|
||||
zeroMsg proto.Message
|
||||
}
|
||||
|
||||
// CheckedType returns the type-definition used at type-check time.
|
||||
func (fd *FieldDescription) CheckedType() *exprpb.Type {
|
||||
if fd.desc.IsMap() {
|
||||
return &exprpb.Type{
|
||||
TypeKind: &exprpb.Type_MapType_{
|
||||
MapType: &exprpb.Type_MapType{
|
||||
KeyType: fd.KeyType.typeDefToType(),
|
||||
ValueType: fd.ValueType.typeDefToType(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
if fd.desc.IsList() {
|
||||
return &exprpb.Type{
|
||||
TypeKind: &exprpb.Type_ListType_{
|
||||
ListType: &exprpb.Type_ListType{
|
||||
ElemType: fd.typeDefToType()}}}
|
||||
}
|
||||
return fd.typeDefToType()
|
||||
}
|
||||
|
||||
// Descriptor returns the protoreflect.FieldDescriptor for this type.
|
||||
func (fd *FieldDescription) Descriptor() protoreflect.FieldDescriptor {
|
||||
return fd.desc
|
||||
}
|
||||
|
||||
// IsSet returns whether the field is set on the target value, per the proto presence conventions
|
||||
// of proto2 or proto3 accordingly.
|
||||
//
|
||||
// This function implements the FieldType.IsSet function contract which can be used to operate on
|
||||
// more than just protobuf field accesses; however, the target here must be a protobuf.Message.
|
||||
func (fd *FieldDescription) IsSet(target interface{}) bool {
|
||||
switch v := target.(type) {
|
||||
case proto.Message:
|
||||
pbRef := v.ProtoReflect()
|
||||
pbDesc := pbRef.Descriptor()
|
||||
if pbDesc == fd.desc.ContainingMessage() {
|
||||
// When the target protobuf shares the same message descriptor instance as the field
|
||||
// descriptor, use the cached field descriptor value.
|
||||
return pbRef.Has(fd.desc)
|
||||
}
|
||||
// Otherwise, fallback to a dynamic lookup of the field descriptor from the target
|
||||
// instance as an attempt to use the cached field descriptor will result in a panic.
|
||||
return pbRef.Has(pbDesc.Fields().ByName(protoreflect.Name(fd.Name())))
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// GetFrom returns the accessor method associated with the field on the proto generated struct.
|
||||
//
|
||||
// If the field is not set, the proto default value is returned instead.
|
||||
//
|
||||
// This function implements the FieldType.GetFrom function contract which can be used to operate
|
||||
// on more than just protobuf field accesses; however, the target here must be a protobuf.Message.
|
||||
func (fd *FieldDescription) GetFrom(target interface{}) (interface{}, error) {
|
||||
v, ok := target.(proto.Message)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unsupported field selection target: (%T)%v", target, target)
|
||||
}
|
||||
pbRef := v.ProtoReflect()
|
||||
pbDesc := pbRef.Descriptor()
|
||||
var fieldVal interface{}
|
||||
if pbDesc == fd.desc.ContainingMessage() {
|
||||
// When the target protobuf shares the same message descriptor instance as the field
|
||||
// descriptor, use the cached field descriptor value.
|
||||
fieldVal = pbRef.Get(fd.desc).Interface()
|
||||
} else {
|
||||
// Otherwise, fallback to a dynamic lookup of the field descriptor from the target
|
||||
// instance as an attempt to use the cached field descriptor will result in a panic.
|
||||
fieldVal = pbRef.Get(pbDesc.Fields().ByName(protoreflect.Name(fd.Name()))).Interface()
|
||||
}
|
||||
switch fv := fieldVal.(type) {
|
||||
// Fast-path return for primitive types.
|
||||
case bool, []byte, float32, float64, int32, int64, string, uint32, uint64, protoreflect.List:
|
||||
return fv, nil
|
||||
case protoreflect.EnumNumber:
|
||||
return int64(fv), nil
|
||||
case protoreflect.Map:
|
||||
// Return a wrapper around the protobuf-reflected Map types which carries additional
|
||||
// information about the key and value definitions of the map.
|
||||
return &Map{Map: fv, KeyType: fd.KeyType, ValueType: fd.ValueType}, nil
|
||||
case protoreflect.Message:
|
||||
// Make sure to unwrap well-known protobuf types before returning.
|
||||
unwrapped, _, err := fd.MaybeUnwrapDynamic(fv)
|
||||
return unwrapped, err
|
||||
default:
|
||||
return fv, nil
|
||||
}
|
||||
}
|
||||
|
||||
// IsEnum returns true if the field type refers to an enum value.
|
||||
func (fd *FieldDescription) IsEnum() bool {
|
||||
return fd.desc.Kind() == protoreflect.EnumKind
|
||||
}
|
||||
|
||||
// IsMap returns true if the field is of map type.
|
||||
func (fd *FieldDescription) IsMap() bool {
|
||||
return fd.desc.IsMap()
|
||||
}
|
||||
|
||||
// IsMessage returns true if the field is of message type.
|
||||
func (fd *FieldDescription) IsMessage() bool {
|
||||
kind := fd.desc.Kind()
|
||||
return kind == protoreflect.MessageKind || kind == protoreflect.GroupKind
|
||||
}
|
||||
|
||||
// IsOneof returns true if the field is declared within a oneof block.
|
||||
func (fd *FieldDescription) IsOneof() bool {
|
||||
return fd.desc.ContainingOneof() != nil
|
||||
}
|
||||
|
||||
// IsList returns true if the field is a repeated value.
|
||||
//
|
||||
// This method will also return true for map values, so check whether the
|
||||
// field is also a map.
|
||||
func (fd *FieldDescription) IsList() bool {
|
||||
return fd.desc.IsList()
|
||||
}
|
||||
|
||||
// MaybeUnwrapDynamic takes the reflected protoreflect.Message and determines whether the
|
||||
// value can be unwrapped to a more primitive CEL type.
|
||||
//
|
||||
// This function returns the unwrapped value and 'true' on success, or the original value
|
||||
// and 'false' otherwise.
|
||||
func (fd *FieldDescription) MaybeUnwrapDynamic(msg protoreflect.Message) (interface{}, bool, error) {
|
||||
return unwrapDynamic(fd, msg)
|
||||
}
|
||||
|
||||
// Name returns the CamelCase name of the field within the proto-based struct.
|
||||
func (fd *FieldDescription) Name() string {
|
||||
return string(fd.desc.Name())
|
||||
}
|
||||
|
||||
// ReflectType returns the Golang reflect.Type for this field.
|
||||
func (fd *FieldDescription) ReflectType() reflect.Type {
|
||||
return fd.reflectType
|
||||
}
|
||||
|
||||
// String returns the fully qualified name of the field within its type as well as whether the
|
||||
// field occurs within a oneof.
|
||||
func (fd *FieldDescription) String() string {
|
||||
return fmt.Sprintf("%v.%s `oneof=%t`", fd.desc.ContainingMessage().FullName(), fd.Name(), fd.IsOneof())
|
||||
}
|
||||
|
||||
// Zero returns the zero value for the protobuf message represented by this field.
|
||||
//
|
||||
// If the field is not a proto.Message type, the zero value is nil.
|
||||
func (fd *FieldDescription) Zero() proto.Message {
|
||||
return fd.zeroMsg
|
||||
}
|
||||
|
||||
func (fd *FieldDescription) typeDefToType() *exprpb.Type {
|
||||
if fd.desc.Kind() == protoreflect.MessageKind || fd.desc.Kind() == protoreflect.GroupKind {
|
||||
msgType := string(fd.desc.Message().FullName())
|
||||
if wk, found := CheckedWellKnowns[msgType]; found {
|
||||
return wk
|
||||
}
|
||||
return checkedMessageType(msgType)
|
||||
}
|
||||
if fd.desc.Kind() == protoreflect.EnumKind {
|
||||
return checkedInt
|
||||
}
|
||||
return CheckedPrimitives[fd.desc.Kind()]
|
||||
}
|
||||
|
||||
// Map wraps the protoreflect.Map object with a key and value FieldDescription for use in
|
||||
// retrieving individual elements within CEL value data types.
|
||||
type Map struct {
|
||||
protoreflect.Map
|
||||
KeyType *FieldDescription
|
||||
ValueType *FieldDescription
|
||||
}
|
||||
|
||||
func checkedMessageType(name string) *exprpb.Type {
|
||||
return &exprpb.Type{
|
||||
TypeKind: &exprpb.Type_MessageType{MessageType: name}}
|
||||
}
|
||||
|
||||
func checkedPrimitive(primitive exprpb.Type_PrimitiveType) *exprpb.Type {
|
||||
return &exprpb.Type{
|
||||
TypeKind: &exprpb.Type_Primitive{Primitive: primitive}}
|
||||
}
|
||||
|
||||
func checkedWellKnown(wellKnown exprpb.Type_WellKnownType) *exprpb.Type {
|
||||
return &exprpb.Type{
|
||||
TypeKind: &exprpb.Type_WellKnown{WellKnown: wellKnown}}
|
||||
}
|
||||
|
||||
func checkedWrap(t *exprpb.Type) *exprpb.Type {
|
||||
return &exprpb.Type{
|
||||
TypeKind: &exprpb.Type_Wrapper{Wrapper: t.GetPrimitive()}}
|
||||
}
|
||||
|
||||
// unwrap unwraps the provided proto.Message value, potentially based on the description if the
|
||||
// input message is a *dynamicpb.Message which obscures the typing information from Go.
|
||||
//
|
||||
// Returns the unwrapped value and 'true' if unwrapped, otherwise the input value and 'false'.
|
||||
func unwrap(desc description, msg proto.Message) (interface{}, bool, error) {
|
||||
switch v := msg.(type) {
|
||||
case *anypb.Any:
|
||||
dynMsg, err := v.UnmarshalNew()
|
||||
if err != nil {
|
||||
return v, false, err
|
||||
}
|
||||
return unwrapDynamic(desc, dynMsg.ProtoReflect())
|
||||
case *dynamicpb.Message:
|
||||
return unwrapDynamic(desc, v)
|
||||
case *dpb.Duration:
|
||||
return v.AsDuration(), true, nil
|
||||
case *tpb.Timestamp:
|
||||
return v.AsTime(), true, nil
|
||||
case *structpb.Value:
|
||||
switch v.GetKind().(type) {
|
||||
case *structpb.Value_BoolValue:
|
||||
return v.GetBoolValue(), true, nil
|
||||
case *structpb.Value_ListValue:
|
||||
return v.GetListValue(), true, nil
|
||||
case *structpb.Value_NullValue:
|
||||
return structpb.NullValue_NULL_VALUE, true, nil
|
||||
case *structpb.Value_NumberValue:
|
||||
return v.GetNumberValue(), true, nil
|
||||
case *structpb.Value_StringValue:
|
||||
return v.GetStringValue(), true, nil
|
||||
case *structpb.Value_StructValue:
|
||||
return v.GetStructValue(), true, nil
|
||||
default:
|
||||
return structpb.NullValue_NULL_VALUE, true, nil
|
||||
}
|
||||
case *wrapperspb.BoolValue:
|
||||
return v.GetValue(), true, nil
|
||||
case *wrapperspb.BytesValue:
|
||||
return v.GetValue(), true, nil
|
||||
case *wrapperspb.DoubleValue:
|
||||
return v.GetValue(), true, nil
|
||||
case *wrapperspb.FloatValue:
|
||||
return float64(v.GetValue()), true, nil
|
||||
case *wrapperspb.Int32Value:
|
||||
return int64(v.GetValue()), true, nil
|
||||
case *wrapperspb.Int64Value:
|
||||
return v.GetValue(), true, nil
|
||||
case *wrapperspb.StringValue:
|
||||
return v.GetValue(), true, nil
|
||||
case *wrapperspb.UInt32Value:
|
||||
return uint64(v.GetValue()), true, nil
|
||||
case *wrapperspb.UInt64Value:
|
||||
return v.GetValue(), true, nil
|
||||
}
|
||||
return msg, false, nil
|
||||
}
|
||||
|
||||
// unwrapDynamic unwraps a reflected protobuf Message value.
|
||||
//
|
||||
// Returns the unwrapped value and 'true' if unwrapped, otherwise the input value and 'false'.
|
||||
func unwrapDynamic(desc description, refMsg protoreflect.Message) (interface{}, bool, error) {
|
||||
msg := refMsg.Interface()
|
||||
if !refMsg.IsValid() {
|
||||
msg = desc.Zero()
|
||||
}
|
||||
// In order to ensure that these wrapped types match the expectations of the CEL type system
|
||||
// the dynamicpb.Message must be merged with an protobuf instance of the well-known type value.
|
||||
typeName := string(refMsg.Descriptor().FullName())
|
||||
switch typeName {
|
||||
case "google.protobuf.Any":
|
||||
// Note, Any values require further unwrapping; however, this unwrapping may or may not
|
||||
// be to a well-known type. If the unwrapped value is a well-known type it will be further
|
||||
// unwrapped before being returned to the caller. Otherwise, the dynamic protobuf object
|
||||
// represented by the Any will be returned.
|
||||
unwrappedAny := &anypb.Any{}
|
||||
err := Merge(unwrappedAny, msg)
|
||||
if err != nil {
|
||||
return nil, false, 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
|
||||
}
|
||||
// Attempt to unwrap the dynamic type, otherwise return the dynamic message.
|
||||
unwrapped, nested, err := unwrapDynamic(desc, dynMsg.ProtoReflect())
|
||||
if err == nil && nested {
|
||||
return unwrapped, true, nil
|
||||
}
|
||||
return dynMsg, true, err
|
||||
case "google.protobuf.BoolValue",
|
||||
"google.protobuf.BytesValue",
|
||||
"google.protobuf.DoubleValue",
|
||||
"google.protobuf.FloatValue",
|
||||
"google.protobuf.Int32Value",
|
||||
"google.protobuf.Int64Value",
|
||||
"google.protobuf.StringValue",
|
||||
"google.protobuf.UInt32Value",
|
||||
"google.protobuf.UInt64Value":
|
||||
// The msg value is ignored when dealing with wrapper types as they have a null or value
|
||||
// behavior, rather than the standard zero value behavior of other proto message types.
|
||||
if !refMsg.IsValid() {
|
||||
return structpb.NullValue_NULL_VALUE, true, nil
|
||||
}
|
||||
valueField := refMsg.Descriptor().Fields().ByName("value")
|
||||
return refMsg.Get(valueField).Interface(), true, nil
|
||||
case "google.protobuf.Duration":
|
||||
unwrapped := &dpb.Duration{}
|
||||
err := Merge(unwrapped, msg)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return unwrapped.AsDuration(), true, nil
|
||||
case "google.protobuf.ListValue":
|
||||
unwrapped := &structpb.ListValue{}
|
||||
err := Merge(unwrapped, msg)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return unwrapped, true, nil
|
||||
case "google.protobuf.NullValue":
|
||||
return structpb.NullValue_NULL_VALUE, true, nil
|
||||
case "google.protobuf.Struct":
|
||||
unwrapped := &structpb.Struct{}
|
||||
err := Merge(unwrapped, msg)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return unwrapped, true, nil
|
||||
case "google.protobuf.Timestamp":
|
||||
unwrapped := &tpb.Timestamp{}
|
||||
err := Merge(unwrapped, msg)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return unwrapped.AsTime(), true, nil
|
||||
case "google.protobuf.Value":
|
||||
unwrapped := &structpb.Value{}
|
||||
err := Merge(unwrapped, msg)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return unwrap(desc, unwrapped)
|
||||
}
|
||||
return msg, false, nil
|
||||
}
|
||||
|
||||
// reflectTypeOf intercepts the reflect.Type call to ensure that dynamicpb.Message types preserve
|
||||
// well-known protobuf reflected types expected by the CEL type system.
|
||||
func reflectTypeOf(val interface{}) reflect.Type {
|
||||
switch v := val.(type) {
|
||||
case proto.Message:
|
||||
return reflect.TypeOf(zeroValueOf(v))
|
||||
default:
|
||||
return reflect.TypeOf(v)
|
||||
}
|
||||
}
|
||||
|
||||
// zeroValueOf will return the strongest possible proto.Message representing the default protobuf
|
||||
// message value of the input msg type.
|
||||
func zeroValueOf(msg proto.Message) proto.Message {
|
||||
if msg == nil {
|
||||
return nil
|
||||
}
|
||||
typeName := string(msg.ProtoReflect().Descriptor().FullName())
|
||||
zeroVal, found := zeroValueMap[typeName]
|
||||
if found {
|
||||
return zeroVal
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
var (
|
||||
zeroValueMap = map[string]proto.Message{
|
||||
"google.protobuf.Any": &anypb.Any{},
|
||||
"google.protobuf.Duration": &dpb.Duration{},
|
||||
"google.protobuf.ListValue": &structpb.ListValue{},
|
||||
"google.protobuf.Struct": &structpb.Struct{},
|
||||
"google.protobuf.Timestamp": &tpb.Timestamp{},
|
||||
"google.protobuf.Value": &structpb.Value{},
|
||||
"google.protobuf.BoolValue": wrapperspb.Bool(false),
|
||||
"google.protobuf.BytesValue": wrapperspb.Bytes([]byte{}),
|
||||
"google.protobuf.DoubleValue": wrapperspb.Double(0.0),
|
||||
"google.protobuf.FloatValue": wrapperspb.Float(0.0),
|
||||
"google.protobuf.Int32Value": wrapperspb.Int32(0),
|
||||
"google.protobuf.Int64Value": wrapperspb.Int64(0),
|
||||
"google.protobuf.StringValue": wrapperspb.String(""),
|
||||
"google.protobuf.UInt32Value": wrapperspb.UInt32(0),
|
||||
"google.protobuf.UInt64Value": wrapperspb.UInt64(0),
|
||||
}
|
||||
)
|
539
vendor/github.com/google/cel-go/common/types/provider.go
generated
vendored
Normal file
539
vendor/github.com/google/cel-go/common/types/provider.go
generated
vendored
Normal file
@ -0,0 +1,539 @@
|
||||
// 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"
|
||||
"time"
|
||||
|
||||
"github.com/google/cel-go/common/types/pb"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
dpb "google.golang.org/protobuf/types/known/durationpb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
tpb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
type protoTypeRegistry struct {
|
||||
revTypeMap map[string]ref.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),
|
||||
pbdb: pb.NewDb(),
|
||||
}
|
||||
err := p.RegisterType(
|
||||
BoolType,
|
||||
BytesType,
|
||||
DoubleType,
|
||||
DurationType,
|
||||
IntType,
|
||||
ListType,
|
||||
MapType,
|
||||
NullType,
|
||||
StringType,
|
||||
TimestampType,
|
||||
TypeType,
|
||||
UintType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// This block ensures that the well-known protobuf types are registered by default.
|
||||
for _, fd := range p.pbdb.FileDescriptions() {
|
||||
err = p.registerAllTypes(fd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
for _, msgType := range types {
|
||||
err = p.RegisterMessage(msgType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// NewEmptyRegistry returns a registry which is completely unconfigured.
|
||||
func NewEmptyRegistry() ref.TypeRegistry {
|
||||
return &protoTypeRegistry{
|
||||
revTypeMap: make(map[string]ref.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),
|
||||
pbdb: p.pbdb.Copy(),
|
||||
}
|
||||
for k, v := range p.revTypeMap {
|
||||
copy.revTypeMap[k] = v
|
||||
}
|
||||
return copy
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) EnumValue(enumName string) ref.Val {
|
||||
enumVal, found := p.pbdb.DescribeEnum(enumName)
|
||||
if !found {
|
||||
return NewErr("unknown enum name '%s'", enumName)
|
||||
}
|
||||
return Int(enumVal.Value())
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) FindFieldType(messageType string,
|
||||
fieldName string) (*ref.FieldType, bool) {
|
||||
msgType, found := p.pbdb.DescribeType(messageType)
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
field, found := msgType.FieldByName(fieldName)
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
return &ref.FieldType{
|
||||
Type: field.CheckedType(),
|
||||
IsSet: field.IsSet,
|
||||
GetFrom: field.GetFrom},
|
||||
true
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) FindIdent(identName string) (ref.Val, bool) {
|
||||
if t, found := p.revTypeMap[identName]; found {
|
||||
return t.(ref.Val), true
|
||||
}
|
||||
if enumVal, found := p.pbdb.DescribeEnum(identName); found {
|
||||
return Int(enumVal.Value()), true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) FindType(typeName string) (*exprpb.Type, bool) {
|
||||
if _, found := p.pbdb.DescribeType(typeName); !found {
|
||||
return nil, false
|
||||
}
|
||||
if typeName != "" && typeName[0] == '.' {
|
||||
typeName = typeName[1:]
|
||||
}
|
||||
return &exprpb.Type{
|
||||
TypeKind: &exprpb.Type_Type{
|
||||
Type: &exprpb.Type{
|
||||
TypeKind: &exprpb.Type_MessageType{
|
||||
MessageType: typeName}}}}, true
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) NewValue(typeName string, fields map[string]ref.Val) ref.Val {
|
||||
td, found := p.pbdb.DescribeType(typeName)
|
||||
if !found {
|
||||
return NewErr("unknown type '%s'", typeName)
|
||||
}
|
||||
msg := td.New()
|
||||
fieldMap := td.FieldMap()
|
||||
for name, value := range fields {
|
||||
field, found := fieldMap[name]
|
||||
if !found {
|
||||
return NewErr("no such field: %s", name)
|
||||
}
|
||||
err := msgSetField(msg, field, value)
|
||||
if err != nil {
|
||||
return &Err{err}
|
||||
}
|
||||
}
|
||||
return p.NativeToValue(msg.Interface())
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) RegisterDescriptor(fileDesc protoreflect.FileDescriptor) error {
|
||||
fd, err := p.pbdb.RegisterDescriptor(fileDesc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return p.registerAllTypes(fd)
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) RegisterMessage(message proto.Message) error {
|
||||
fd, err := p.pbdb.RegisterMessage(message)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return p.registerAllTypes(fd)
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) RegisterType(types ...ref.Type) error {
|
||||
for _, t := range types {
|
||||
p.revTypeMap[t.TypeName()] = t
|
||||
}
|
||||
// TODO: generate an error when the type name is registered more than once.
|
||||
return nil
|
||||
}
|
||||
|
||||
// NativeToValue converts various "native" types to ref.Val with this specific implementation
|
||||
// providing support for custom proto-based types.
|
||||
//
|
||||
// This method should be the inverse of ref.Val.ConvertToNative.
|
||||
func (p *protoTypeRegistry) NativeToValue(value interface{}) ref.Val {
|
||||
if val, found := nativeToValue(p, value); found {
|
||||
return val
|
||||
}
|
||||
switch v := value.(type) {
|
||||
case proto.Message:
|
||||
typeName := string(v.ProtoReflect().Descriptor().FullName())
|
||||
td, found := p.pbdb.DescribeType(typeName)
|
||||
if !found {
|
||||
return NewErr("unknown type: '%s'", typeName)
|
||||
}
|
||||
unwrapped, isUnwrapped, err := td.MaybeUnwrap(v)
|
||||
if err != nil {
|
||||
return UnsupportedRefValConversionErr(v)
|
||||
}
|
||||
if isUnwrapped {
|
||||
return p.NativeToValue(unwrapped)
|
||||
}
|
||||
typeVal, found := p.FindIdent(typeName)
|
||||
if !found {
|
||||
return NewErr("unknown type: '%s'", typeName)
|
||||
}
|
||||
return NewObject(p, td, typeVal.(*TypeValue), v)
|
||||
case *pb.Map:
|
||||
return NewProtoMap(p, v)
|
||||
case protoreflect.List:
|
||||
return NewProtoList(p, v)
|
||||
case protoreflect.Message:
|
||||
return p.NativeToValue(v.Interface())
|
||||
case protoreflect.Value:
|
||||
return p.NativeToValue(v.Interface())
|
||||
}
|
||||
return UnsupportedRefValConversionErr(value)
|
||||
}
|
||||
|
||||
func (p *protoTypeRegistry) registerAllTypes(fd *pb.FileDescription) error {
|
||||
for _, typeName := range fd.GetTypeNames() {
|
||||
err := p.RegisterType(NewObjectTypeValue(typeName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// defaultTypeAdapter converts go native types to CEL values.
|
||||
type defaultTypeAdapter struct{}
|
||||
|
||||
var (
|
||||
// DefaultTypeAdapter adapts canonical CEL types from their equivalent Go values.
|
||||
DefaultTypeAdapter = &defaultTypeAdapter{}
|
||||
)
|
||||
|
||||
// NativeToValue implements the ref.TypeAdapter interface.
|
||||
func (a *defaultTypeAdapter) NativeToValue(value interface{}) ref.Val {
|
||||
if val, found := nativeToValue(a, value); found {
|
||||
return val
|
||||
}
|
||||
return UnsupportedRefValConversionErr(value)
|
||||
}
|
||||
|
||||
// nativeToValue returns the converted (ref.Val, true) of a conversion is found,
|
||||
// otherwise (nil, false)
|
||||
func nativeToValue(a ref.TypeAdapter, value interface{}) (ref.Val, bool) {
|
||||
switch v := value.(type) {
|
||||
case nil:
|
||||
return NullValue, true
|
||||
case *Bool:
|
||||
if v != nil {
|
||||
return *v, true
|
||||
}
|
||||
case *Bytes:
|
||||
if v != nil {
|
||||
return *v, true
|
||||
}
|
||||
case *Double:
|
||||
if v != nil {
|
||||
return *v, true
|
||||
}
|
||||
case *Int:
|
||||
if v != nil {
|
||||
return *v, true
|
||||
}
|
||||
case *String:
|
||||
if v != nil {
|
||||
return *v, true
|
||||
}
|
||||
case *Uint:
|
||||
if v != nil {
|
||||
return *v, true
|
||||
}
|
||||
case bool:
|
||||
return Bool(v), true
|
||||
case int:
|
||||
return Int(v), true
|
||||
case int32:
|
||||
return Int(v), true
|
||||
case int64:
|
||||
return Int(v), true
|
||||
case uint:
|
||||
return Uint(v), true
|
||||
case uint32:
|
||||
return Uint(v), true
|
||||
case uint64:
|
||||
return Uint(v), true
|
||||
case float32:
|
||||
return Double(v), true
|
||||
case float64:
|
||||
return Double(v), true
|
||||
case string:
|
||||
return String(v), true
|
||||
case *dpb.Duration:
|
||||
return Duration{Duration: v.AsDuration()}, true
|
||||
case time.Duration:
|
||||
return Duration{Duration: v}, true
|
||||
case *tpb.Timestamp:
|
||||
return Timestamp{Time: v.AsTime()}, true
|
||||
case time.Time:
|
||||
return Timestamp{Time: v}, true
|
||||
case *bool:
|
||||
if v != nil {
|
||||
return Bool(*v), true
|
||||
}
|
||||
case *float32:
|
||||
if v != nil {
|
||||
return Double(*v), true
|
||||
}
|
||||
case *float64:
|
||||
if v != nil {
|
||||
return Double(*v), true
|
||||
}
|
||||
case *int:
|
||||
if v != nil {
|
||||
return Int(*v), true
|
||||
}
|
||||
case *int32:
|
||||
if v != nil {
|
||||
return Int(*v), true
|
||||
}
|
||||
case *int64:
|
||||
if v != nil {
|
||||
return Int(*v), true
|
||||
}
|
||||
case *string:
|
||||
if v != nil {
|
||||
return String(*v), true
|
||||
}
|
||||
case *uint:
|
||||
if v != nil {
|
||||
return Uint(*v), true
|
||||
}
|
||||
case *uint32:
|
||||
if v != nil {
|
||||
return Uint(*v), true
|
||||
}
|
||||
case *uint64:
|
||||
if v != nil {
|
||||
return Uint(*v), true
|
||||
}
|
||||
case []byte:
|
||||
return Bytes(v), true
|
||||
// specializations for common lists types.
|
||||
case []string:
|
||||
return NewStringList(a, v), true
|
||||
case []ref.Val:
|
||||
return NewRefValList(a, v), true
|
||||
// specializations for common map types.
|
||||
case map[string]string:
|
||||
return NewStringStringMap(a, v), true
|
||||
case map[string]interface{}:
|
||||
return NewStringInterfaceMap(a, v), true
|
||||
case map[ref.Val]ref.Val:
|
||||
return NewRefValMap(a, v), true
|
||||
// additional specializations may be added upon request / need.
|
||||
case *anypb.Any:
|
||||
if v == nil {
|
||||
return UnsupportedRefValConversionErr(v), true
|
||||
}
|
||||
unpackedAny, err := v.UnmarshalNew()
|
||||
if err != nil {
|
||||
return NewErr("anypb.UnmarshalNew() failed for type %q: %v", v.GetTypeUrl(), err), true
|
||||
}
|
||||
return a.NativeToValue(unpackedAny), true
|
||||
case *structpb.NullValue, structpb.NullValue:
|
||||
return NullValue, true
|
||||
case *structpb.ListValue:
|
||||
return NewJSONList(a, v), true
|
||||
case *structpb.Struct:
|
||||
return NewJSONStruct(a, v), true
|
||||
case ref.Val:
|
||||
return v, true
|
||||
case protoreflect.EnumNumber:
|
||||
return Int(v), true
|
||||
case proto.Message:
|
||||
if v == nil {
|
||||
return UnsupportedRefValConversionErr(v), true
|
||||
}
|
||||
typeName := string(v.ProtoReflect().Descriptor().FullName())
|
||||
td, found := pb.DefaultDb.DescribeType(typeName)
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
val, unwrapped, err := td.MaybeUnwrap(v)
|
||||
if err != nil {
|
||||
return UnsupportedRefValConversionErr(v), true
|
||||
}
|
||||
if !unwrapped {
|
||||
return nil, false
|
||||
}
|
||||
return a.NativeToValue(val), true
|
||||
// Note: dynamicpb.Message implements the proto.Message _and_ protoreflect.Message interfaces
|
||||
// which means that this case must appear after handling a proto.Message type.
|
||||
case protoreflect.Message:
|
||||
return a.NativeToValue(v.Interface()), true
|
||||
default:
|
||||
refValue := reflect.ValueOf(v)
|
||||
if refValue.Kind() == reflect.Ptr {
|
||||
if refValue.IsNil() {
|
||||
return UnsupportedRefValConversionErr(v), true
|
||||
}
|
||||
refValue = refValue.Elem()
|
||||
}
|
||||
refKind := refValue.Kind()
|
||||
switch refKind {
|
||||
case reflect.Array, reflect.Slice:
|
||||
return NewDynamicList(a, v), true
|
||||
case reflect.Map:
|
||||
return NewDynamicMap(a, v), true
|
||||
// type aliases of primitive types cannot be asserted as that type, but rather need
|
||||
// to be downcast to int32 before being converted to a CEL representation.
|
||||
case reflect.Int32:
|
||||
intType := reflect.TypeOf(int32(0))
|
||||
return Int(refValue.Convert(intType).Interface().(int32)), true
|
||||
case reflect.Int64:
|
||||
intType := reflect.TypeOf(int64(0))
|
||||
return Int(refValue.Convert(intType).Interface().(int64)), true
|
||||
case reflect.Uint32:
|
||||
uintType := reflect.TypeOf(uint32(0))
|
||||
return Uint(refValue.Convert(uintType).Interface().(uint32)), true
|
||||
case reflect.Uint64:
|
||||
uintType := reflect.TypeOf(uint64(0))
|
||||
return Uint(refValue.Convert(uintType).Interface().(uint64)), true
|
||||
case reflect.Float32:
|
||||
doubleType := reflect.TypeOf(float32(0))
|
||||
return Double(refValue.Convert(doubleType).Interface().(float32)), true
|
||||
case reflect.Float64:
|
||||
doubleType := reflect.TypeOf(float64(0))
|
||||
return Double(refValue.Convert(doubleType).Interface().(float64)), true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func msgSetField(target protoreflect.Message, field *pb.FieldDescription, val ref.Val) error {
|
||||
if field.IsList() {
|
||||
lv := target.NewField(field.Descriptor())
|
||||
list, ok := val.(traits.Lister)
|
||||
if !ok {
|
||||
return unsupportedTypeConversionError(field, val)
|
||||
}
|
||||
err := msgSetListField(lv.List(), field, list)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
target.Set(field.Descriptor(), lv)
|
||||
return nil
|
||||
}
|
||||
if field.IsMap() {
|
||||
mv := target.NewField(field.Descriptor())
|
||||
mp, ok := val.(traits.Mapper)
|
||||
if !ok {
|
||||
return unsupportedTypeConversionError(field, val)
|
||||
}
|
||||
err := msgSetMapField(mv.Map(), field, mp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
target.Set(field.Descriptor(), mv)
|
||||
return nil
|
||||
}
|
||||
v, err := val.ConvertToNative(field.ReflectType())
|
||||
if err != nil {
|
||||
return fieldTypeConversionError(field, err)
|
||||
}
|
||||
switch v.(type) {
|
||||
case proto.Message:
|
||||
v = v.(proto.Message).ProtoReflect()
|
||||
}
|
||||
target.Set(field.Descriptor(), protoreflect.ValueOf(v))
|
||||
return nil
|
||||
}
|
||||
|
||||
func msgSetListField(target protoreflect.List, listField *pb.FieldDescription, listVal traits.Lister) error {
|
||||
elemReflectType := listField.ReflectType().Elem()
|
||||
for i := Int(0); i < listVal.Size().(Int); i++ {
|
||||
elem := listVal.Get(i)
|
||||
elemVal, err := elem.ConvertToNative(elemReflectType)
|
||||
if err != nil {
|
||||
return fieldTypeConversionError(listField, err)
|
||||
}
|
||||
switch ev := elemVal.(type) {
|
||||
case proto.Message:
|
||||
elemVal = ev.ProtoReflect()
|
||||
}
|
||||
target.Append(protoreflect.ValueOf(elemVal))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func msgSetMapField(target protoreflect.Map, mapField *pb.FieldDescription, mapVal traits.Mapper) error {
|
||||
targetKeyType := mapField.KeyType.ReflectType()
|
||||
targetValType := mapField.ValueType.ReflectType()
|
||||
it := mapVal.Iterator()
|
||||
for it.HasNext() == True {
|
||||
key := it.Next()
|
||||
val := mapVal.Get(key)
|
||||
k, err := key.ConvertToNative(targetKeyType)
|
||||
if err != nil {
|
||||
return fieldTypeConversionError(mapField, err)
|
||||
}
|
||||
v, err := val.ConvertToNative(targetValType)
|
||||
if err != nil {
|
||||
return fieldTypeConversionError(mapField, err)
|
||||
}
|
||||
switch v.(type) {
|
||||
case proto.Message:
|
||||
v = v.(proto.Message).ProtoReflect()
|
||||
}
|
||||
target.Set(protoreflect.ValueOf(k).MapKey(), protoreflect.ValueOf(v))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func unsupportedTypeConversionError(field *pb.FieldDescription, val ref.Val) error {
|
||||
msgName := field.Descriptor().ContainingMessage().FullName()
|
||||
return fmt.Errorf("unsupported field type for %v.%v: %v", msgName, field.Name(), val.Type())
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
20
vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel
generated
vendored
Normal file
20
vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
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 = [
|
||||
"provider.go",
|
||||
"reference.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/types/ref",
|
||||
deps = [
|
||||
"@org_golang_google_genproto//googleapis/api/expr/v1alpha1:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
"@org_golang_google_protobuf//reflect/protoreflect:go_default_library",
|
||||
],
|
||||
)
|
103
vendor/github.com/google/cel-go/common/types/ref/provider.go
generated
vendored
Normal file
103
vendor/github.com/google/cel-go/common/types/ref/provider.go
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
// 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 ref
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
)
|
||||
|
||||
// TypeProvider specifies functions for creating new object instances and for
|
||||
// resolving enum values by name.
|
||||
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(identName string) (Val, bool)
|
||||
|
||||
// FindType looks up the Type given a qualified typeName. Returns false
|
||||
// if not found.
|
||||
//
|
||||
// Used during type-checking only.
|
||||
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.
|
||||
//
|
||||
// Used during type-checking only.
|
||||
FindFieldType(messageType string, 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(typeName string, fields map[string]Val) Val
|
||||
}
|
||||
|
||||
// TypeAdapter converts native Go values of varying type and complexity to equivalent CEL values.
|
||||
type TypeAdapter interface {
|
||||
// NativeToValue converts the input `value` to a CEL `ref.Val`.
|
||||
NativeToValue(value interface{}) Val
|
||||
}
|
||||
|
||||
// TypeRegistry allows third-parties to add custom types to CEL. Not all `TypeProvider`
|
||||
// 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.
|
||||
type TypeRegistry interface {
|
||||
TypeAdapter
|
||||
TypeProvider
|
||||
|
||||
// RegisterDescriptor registers the contents of a protocol buffer `FileDescriptor`.
|
||||
RegisterDescriptor(fileDesc protoreflect.FileDescriptor) error
|
||||
|
||||
// RegisterMessage registers a protocol buffer message and its dependencies.
|
||||
RegisterMessage(message proto.Message) 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 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.
|
||||
type FieldType struct {
|
||||
// Type of the field.
|
||||
Type *exprpb.Type
|
||||
|
||||
// IsSet indicates whether the field is set on an input object.
|
||||
IsSet FieldTester
|
||||
|
||||
// GetFrom retrieves the field value on the input object, if set.
|
||||
GetFrom FieldGetter
|
||||
}
|
||||
|
||||
// FieldTester is used to test field presence on an input object.
|
||||
type FieldTester func(target interface{}) bool
|
||||
|
||||
// FieldGetter is used to get the field value from an input object, if set.
|
||||
type FieldGetter func(target interface{}) (interface{}, error)
|
54
vendor/github.com/google/cel-go/common/types/ref/reference.go
generated
vendored
Normal file
54
vendor/github.com/google/cel-go/common/types/ref/reference.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
// 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 ref contains the reference interfaces used throughout the types components.
|
||||
package ref
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Type interface indicate the name of a given type.
|
||||
type Type interface {
|
||||
// HasTrait returns whether the type has a given trait associated with it.
|
||||
//
|
||||
// See common/types/traits/traits.go for a list of supported traits.
|
||||
HasTrait(trait int) bool
|
||||
|
||||
// TypeName returns the qualified type name of the type.
|
||||
//
|
||||
// The type name is also used as the type's identifier name at type-check and interpretation time.
|
||||
TypeName() string
|
||||
}
|
||||
|
||||
// Val interface defines the functions supported by all expression values.
|
||||
// Val implementations may specialize the behavior of the value through the addition of traits.
|
||||
type Val interface {
|
||||
// ConvertToNative converts the Value to a native Go struct according to the
|
||||
// reflected type description, or error if the conversion is not feasible.
|
||||
ConvertToNative(typeDesc reflect.Type) (interface{}, error)
|
||||
|
||||
// ConvertToType supports type conversions between value types supported by the expression language.
|
||||
ConvertToType(typeValue Type) Val
|
||||
|
||||
// Equal returns true if the `other` value has the same type and content as the implementing struct.
|
||||
Equal(other Val) Val
|
||||
|
||||
// Type returns the TypeValue of the value.
|
||||
Type() Type
|
||||
|
||||
// Value returns the raw value of the instance which may not be directly compatible with the expression
|
||||
// language types.
|
||||
Value() interface{}
|
||||
}
|
218
vendor/github.com/google/cel-go/common/types/string.go
generated
vendored
Normal file
218
vendor/github.com/google/cel-go/common/types/string.go
generated
vendored
Normal file
@ -0,0 +1,218 @@
|
||||
// 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"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"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"
|
||||
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
|
||||
)
|
||||
|
||||
// String type implementation which supports addition, comparison, matching,
|
||||
// and size functions.
|
||||
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,
|
||||
}
|
||||
|
||||
stringWrapperType = reflect.TypeOf(&wrapperspb.StringValue{})
|
||||
)
|
||||
|
||||
// Add implements traits.Adder.Add.
|
||||
func (s String) Add(other ref.Val) ref.Val {
|
||||
otherString, ok := other.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
return s + otherString
|
||||
}
|
||||
|
||||
// Compare implements traits.Comparer.Compare.
|
||||
func (s String) Compare(other ref.Val) ref.Val {
|
||||
otherString, ok := other.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
return Int(strings.Compare(s.Value().(string), otherString.Value().(string)))
|
||||
}
|
||||
|
||||
// ConvertToNative implements ref.Val.ConvertToNative.
|
||||
func (s String) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
switch typeDesc.Kind() {
|
||||
case reflect.String:
|
||||
if reflect.TypeOf(s).AssignableTo(typeDesc) {
|
||||
return s, nil
|
||||
}
|
||||
return s.Value(), nil
|
||||
case reflect.Ptr:
|
||||
switch typeDesc {
|
||||
case anyValueType:
|
||||
// Primitives must be wrapped before being set on an Any field.
|
||||
return anypb.New(wrapperspb.String(string(s)))
|
||||
case jsonValueType:
|
||||
// Convert to a protobuf representation of a JSON String.
|
||||
return structpb.NewStringValue(string(s)), nil
|
||||
case stringWrapperType:
|
||||
// Convert to a wrapperspb.StringValue.
|
||||
return wrapperspb.String(string(s)), nil
|
||||
}
|
||||
if typeDesc.Elem().Kind() == reflect.String {
|
||||
p := s.Value().(string)
|
||||
return &p, nil
|
||||
}
|
||||
case reflect.Interface:
|
||||
sv := s.Value()
|
||||
if reflect.TypeOf(sv).Implements(typeDesc) {
|
||||
return sv, nil
|
||||
}
|
||||
if reflect.TypeOf(s).Implements(typeDesc) {
|
||||
return s, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf(
|
||||
"unsupported native conversion from string to '%v'", typeDesc)
|
||||
}
|
||||
|
||||
// ConvertToType implements ref.Val.ConvertToType.
|
||||
func (s String) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case IntType:
|
||||
if n, err := strconv.ParseInt(s.Value().(string), 10, 64); err == nil {
|
||||
return Int(n)
|
||||
}
|
||||
case UintType:
|
||||
if n, err := strconv.ParseUint(s.Value().(string), 10, 64); err == nil {
|
||||
return Uint(n)
|
||||
}
|
||||
case DoubleType:
|
||||
if n, err := strconv.ParseFloat(s.Value().(string), 64); err == nil {
|
||||
return Double(n)
|
||||
}
|
||||
case BoolType:
|
||||
if b, err := strconv.ParseBool(s.Value().(string)); err == nil {
|
||||
return Bool(b)
|
||||
}
|
||||
case BytesType:
|
||||
return Bytes(s)
|
||||
case DurationType:
|
||||
if d, err := time.ParseDuration(s.Value().(string)); err == nil {
|
||||
return durationOf(d)
|
||||
}
|
||||
case TimestampType:
|
||||
if t, err := time.Parse(time.RFC3339, s.Value().(string)); err == nil {
|
||||
if t.Unix() < minUnixTime || t.Unix() > maxUnixTime {
|
||||
return celErrTimestampOverflow
|
||||
}
|
||||
return timestampOf(t)
|
||||
}
|
||||
case StringType:
|
||||
return s
|
||||
case TypeType:
|
||||
return StringType
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", StringType, typeVal)
|
||||
}
|
||||
|
||||
// Equal implements ref.Val.Equal.
|
||||
func (s String) Equal(other ref.Val) ref.Val {
|
||||
otherString, ok := other.(String)
|
||||
return Bool(ok && s == otherString)
|
||||
}
|
||||
|
||||
// Match implements traits.Matcher.Match.
|
||||
func (s String) Match(pattern ref.Val) ref.Val {
|
||||
pat, ok := pattern.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(pattern)
|
||||
}
|
||||
matched, err := regexp.MatchString(pat.Value().(string), s.Value().(string))
|
||||
if err != nil {
|
||||
return &Err{err}
|
||||
}
|
||||
return Bool(matched)
|
||||
}
|
||||
|
||||
// Receive implements traits.Receiver.Receive.
|
||||
func (s String) Receive(function string, overload string, args []ref.Val) ref.Val {
|
||||
switch len(args) {
|
||||
case 1:
|
||||
if f, found := stringOneArgOverloads[function]; found {
|
||||
return f(s, args[0])
|
||||
}
|
||||
}
|
||||
return NoSuchOverloadErr()
|
||||
}
|
||||
|
||||
// Size implements traits.Sizer.Size.
|
||||
func (s String) Size() ref.Val {
|
||||
return Int(len([]rune(s.Value().(string))))
|
||||
}
|
||||
|
||||
// Type implements ref.Val.Type.
|
||||
func (s String) Type() ref.Type {
|
||||
return StringType
|
||||
}
|
||||
|
||||
// Value implements ref.Val.Value.
|
||||
func (s String) Value() interface{} {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func stringContains(s String, sub ref.Val) ref.Val {
|
||||
subStr, ok := sub.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(sub)
|
||||
}
|
||||
return Bool(strings.Contains(string(s), string(subStr)))
|
||||
}
|
||||
|
||||
func stringEndsWith(s String, suf ref.Val) ref.Val {
|
||||
sufStr, ok := suf.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(suf)
|
||||
}
|
||||
return Bool(strings.HasSuffix(string(s), string(sufStr)))
|
||||
}
|
||||
|
||||
func stringStartsWith(s String, pre ref.Val) ref.Val {
|
||||
preStr, ok := pre.(String)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(pre)
|
||||
}
|
||||
return Bool(strings.HasPrefix(string(s), string(preStr)))
|
||||
}
|
316
vendor/github.com/google/cel-go/common/types/timestamp.go
generated
vendored
Normal file
316
vendor/github.com/google/cel-go/common/types/timestamp.go
generated
vendored
Normal file
@ -0,0 +1,316 @@
|
||||
// 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"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"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"
|
||||
tpb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
// Timestamp type implementation which supports add, compare, and subtract
|
||||
// operations. Timestamps are also capable of participating in dynamic
|
||||
// function dispatch to instance methods.
|
||||
type Timestamp struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
func timestampOf(t time.Time) Timestamp {
|
||||
// Note that this function does not validate that time.Time is in our supported range.
|
||||
return Timestamp{Time: t}
|
||||
}
|
||||
|
||||
const (
|
||||
// The number of seconds between year 1 and year 1970. This is borrowed from
|
||||
// https://golang.org/src/time/time.go.
|
||||
unixToInternal int64 = (1969*365 + 1969/4 - 1969/100 + 1969/400) * (60 * 60 * 24)
|
||||
|
||||
// Number of seconds between `0001-01-01T00:00:00Z` and the Unix epoch.
|
||||
minUnixTime int64 = -62135596800
|
||||
// Number of seconds between `9999-12-31T23:59:59.999999999Z` and the Unix epoch.
|
||||
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() {
|
||||
case DurationType:
|
||||
return other.(Duration).Add(t)
|
||||
}
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
|
||||
// Compare implements traits.Comparer.Compare.
|
||||
func (t Timestamp) Compare(other ref.Val) ref.Val {
|
||||
if TimestampType != other.Type() {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
ts1 := t.Time
|
||||
ts2 := other.(Timestamp).Time
|
||||
switch {
|
||||
case ts1.Before(ts2):
|
||||
return IntNegOne
|
||||
case ts1.After(ts2):
|
||||
return IntOne
|
||||
default:
|
||||
return IntZero
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertToNative implements ref.Val.ConvertToNative.
|
||||
func (t Timestamp) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
// If the timestamp is already assignable to the desired type return it.
|
||||
if reflect.TypeOf(t.Time).AssignableTo(typeDesc) {
|
||||
return t.Time, nil
|
||||
}
|
||||
if reflect.TypeOf(t).AssignableTo(typeDesc) {
|
||||
return t, nil
|
||||
}
|
||||
switch typeDesc {
|
||||
case anyValueType:
|
||||
// Pack the underlying time as a tpb.Timestamp into an Any value.
|
||||
return anypb.New(tpb.New(t.Time))
|
||||
case jsonValueType:
|
||||
// CEL follows the proto3 to JSON conversion which formats as an RFC 3339 encoded JSON
|
||||
// string.
|
||||
v := t.ConvertToType(StringType)
|
||||
if IsError(v) {
|
||||
return nil, v.(*Err)
|
||||
}
|
||||
return structpb.NewStringValue(string(v.(String))), nil
|
||||
case timestampValueType:
|
||||
// Unwrap the underlying tpb.Timestamp.
|
||||
return tpb.New(t.Time), nil
|
||||
}
|
||||
return nil, fmt.Errorf("type conversion error from 'Timestamp' to '%v'", typeDesc)
|
||||
}
|
||||
|
||||
// ConvertToType implements ref.Val.ConvertToType.
|
||||
func (t Timestamp) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case StringType:
|
||||
return String(t.Format(time.RFC3339Nano))
|
||||
case IntType:
|
||||
// Return the Unix time in seconds since 1970
|
||||
return Int(t.Unix())
|
||||
case TimestampType:
|
||||
return t
|
||||
case TypeType:
|
||||
return TimestampType
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", TimestampType, typeVal)
|
||||
}
|
||||
|
||||
// Equal implements ref.Val.Equal.
|
||||
func (t Timestamp) Equal(other ref.Val) ref.Val {
|
||||
otherTime, ok := other.(Timestamp)
|
||||
return Bool(ok && t.Time.Equal(otherTime.Time))
|
||||
}
|
||||
|
||||
// Receive implements traits.Receiver.Receive.
|
||||
func (t Timestamp) Receive(function string, overload string, args []ref.Val) ref.Val {
|
||||
switch len(args) {
|
||||
case 0:
|
||||
if f, found := timestampZeroArgOverloads[function]; found {
|
||||
return f(t.Time)
|
||||
}
|
||||
case 1:
|
||||
if f, found := timestampOneArgOverloads[function]; found {
|
||||
return f(t.Time, args[0])
|
||||
}
|
||||
}
|
||||
return NoSuchOverloadErr()
|
||||
}
|
||||
|
||||
// Subtract implements traits.Subtractor.Subtract.
|
||||
func (t Timestamp) Subtract(subtrahend ref.Val) ref.Val {
|
||||
switch subtrahend.Type() {
|
||||
case DurationType:
|
||||
dur := subtrahend.(Duration)
|
||||
val, err := subtractTimeDurationChecked(t.Time, dur.Duration)
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return timestampOf(val)
|
||||
case TimestampType:
|
||||
t2 := subtrahend.(Timestamp).Time
|
||||
val, err := subtractTimeChecked(t.Time, t2)
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return durationOf(val)
|
||||
}
|
||||
return MaybeNoSuchOverloadErr(subtrahend)
|
||||
}
|
||||
|
||||
// Type implements ref.Val.Type.
|
||||
func (t Timestamp) Type() ref.Type {
|
||||
return TimestampType
|
||||
}
|
||||
|
||||
// Value implements ref.Val.Value.
|
||||
func (t Timestamp) Value() interface{} {
|
||||
return t.Time
|
||||
}
|
||||
|
||||
var (
|
||||
timestampValueType = reflect.TypeOf(&tpb.Timestamp{})
|
||||
|
||||
timestampZeroArgOverloads = map[string]func(time.Time) ref.Val{
|
||||
overloads.TimeGetFullYear: timestampGetFullYear,
|
||||
overloads.TimeGetMonth: timestampGetMonth,
|
||||
overloads.TimeGetDayOfYear: timestampGetDayOfYear,
|
||||
overloads.TimeGetDate: timestampGetDayOfMonthOneBased,
|
||||
overloads.TimeGetDayOfMonth: timestampGetDayOfMonthZeroBased,
|
||||
overloads.TimeGetDayOfWeek: timestampGetDayOfWeek,
|
||||
overloads.TimeGetHours: timestampGetHours,
|
||||
overloads.TimeGetMinutes: timestampGetMinutes,
|
||||
overloads.TimeGetSeconds: timestampGetSeconds,
|
||||
overloads.TimeGetMilliseconds: timestampGetMilliseconds}
|
||||
|
||||
timestampOneArgOverloads = map[string]func(time.Time, ref.Val) ref.Val{
|
||||
overloads.TimeGetFullYear: timestampGetFullYearWithTz,
|
||||
overloads.TimeGetMonth: timestampGetMonthWithTz,
|
||||
overloads.TimeGetDayOfYear: timestampGetDayOfYearWithTz,
|
||||
overloads.TimeGetDate: timestampGetDayOfMonthOneBasedWithTz,
|
||||
overloads.TimeGetDayOfMonth: timestampGetDayOfMonthZeroBasedWithTz,
|
||||
overloads.TimeGetDayOfWeek: timestampGetDayOfWeekWithTz,
|
||||
overloads.TimeGetHours: timestampGetHoursWithTz,
|
||||
overloads.TimeGetMinutes: timestampGetMinutesWithTz,
|
||||
overloads.TimeGetSeconds: timestampGetSecondsWithTz,
|
||||
overloads.TimeGetMilliseconds: timestampGetMillisecondsWithTz}
|
||||
)
|
||||
|
||||
type timestampVisitor func(time.Time) ref.Val
|
||||
|
||||
func timestampGetFullYear(t time.Time) ref.Val {
|
||||
return Int(t.Year())
|
||||
}
|
||||
func timestampGetMonth(t time.Time) ref.Val {
|
||||
// CEL spec indicates that the month should be 0-based, but the Time value
|
||||
// for Month() is 1-based.
|
||||
return Int(t.Month() - 1)
|
||||
}
|
||||
func timestampGetDayOfYear(t time.Time) ref.Val {
|
||||
return Int(t.YearDay() - 1)
|
||||
}
|
||||
func timestampGetDayOfMonthZeroBased(t time.Time) ref.Val {
|
||||
return Int(t.Day() - 1)
|
||||
}
|
||||
func timestampGetDayOfMonthOneBased(t time.Time) ref.Val {
|
||||
return Int(t.Day())
|
||||
}
|
||||
func timestampGetDayOfWeek(t time.Time) ref.Val {
|
||||
return Int(t.Weekday())
|
||||
}
|
||||
func timestampGetHours(t time.Time) ref.Val {
|
||||
return Int(t.Hour())
|
||||
}
|
||||
func timestampGetMinutes(t time.Time) ref.Val {
|
||||
return Int(t.Minute())
|
||||
}
|
||||
func timestampGetSeconds(t time.Time) ref.Val {
|
||||
return Int(t.Second())
|
||||
}
|
||||
func timestampGetMilliseconds(t time.Time) ref.Val {
|
||||
return Int(t.Nanosecond() / 1000000)
|
||||
}
|
||||
|
||||
func timestampGetFullYearWithTz(t time.Time, tz ref.Val) ref.Val {
|
||||
return timeZone(tz, timestampGetFullYear)(t)
|
||||
}
|
||||
func timestampGetMonthWithTz(t time.Time, tz ref.Val) ref.Val {
|
||||
return timeZone(tz, timestampGetMonth)(t)
|
||||
}
|
||||
func timestampGetDayOfYearWithTz(t time.Time, tz ref.Val) ref.Val {
|
||||
return timeZone(tz, timestampGetDayOfYear)(t)
|
||||
}
|
||||
func timestampGetDayOfMonthZeroBasedWithTz(t time.Time, tz ref.Val) ref.Val {
|
||||
return timeZone(tz, timestampGetDayOfMonthZeroBased)(t)
|
||||
}
|
||||
func timestampGetDayOfMonthOneBasedWithTz(t time.Time, tz ref.Val) ref.Val {
|
||||
return timeZone(tz, timestampGetDayOfMonthOneBased)(t)
|
||||
}
|
||||
func timestampGetDayOfWeekWithTz(t time.Time, tz ref.Val) ref.Val {
|
||||
return timeZone(tz, timestampGetDayOfWeek)(t)
|
||||
}
|
||||
func timestampGetHoursWithTz(t time.Time, tz ref.Val) ref.Val {
|
||||
return timeZone(tz, timestampGetHours)(t)
|
||||
}
|
||||
func timestampGetMinutesWithTz(t time.Time, tz ref.Val) ref.Val {
|
||||
return timeZone(tz, timestampGetMinutes)(t)
|
||||
}
|
||||
func timestampGetSecondsWithTz(t time.Time, tz ref.Val) ref.Val {
|
||||
return timeZone(tz, timestampGetSeconds)(t)
|
||||
}
|
||||
func timestampGetMillisecondsWithTz(t time.Time, tz ref.Val) ref.Val {
|
||||
return timeZone(tz, timestampGetMilliseconds)(t)
|
||||
}
|
||||
|
||||
func timeZone(tz ref.Val, visitor timestampVisitor) timestampVisitor {
|
||||
return func(t time.Time) ref.Val {
|
||||
if StringType != tz.Type() {
|
||||
return MaybeNoSuchOverloadErr(tz)
|
||||
}
|
||||
val := string(tz.(String))
|
||||
ind := strings.Index(val, ":")
|
||||
if ind == -1 {
|
||||
loc, err := time.LoadLocation(val)
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return visitor(t.In(loc))
|
||||
}
|
||||
|
||||
// If the input is not the name of a timezone (for example, 'US/Central'), it should be a numerical offset from UTC
|
||||
// in the format ^(+|-)(0[0-9]|1[0-4]):[0-5][0-9]$. The numerical input is parsed in terms of hours and minutes.
|
||||
hr, err := strconv.Atoi(string(val[0:ind]))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
min, err := strconv.Atoi(string(val[ind+1:]))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
var offset int
|
||||
if string(val[0]) == "-" {
|
||||
offset = hr*60 - min
|
||||
} else {
|
||||
offset = hr*60 + min
|
||||
}
|
||||
secondsEastOfUTC := int((time.Duration(offset) * time.Minute).Seconds())
|
||||
timezone := time.FixedZone("", secondsEastOfUTC)
|
||||
return visitor(t.In(timezone))
|
||||
}
|
||||
}
|
28
vendor/github.com/google/cel-go/common/types/traits/BUILD.bazel
generated
vendored
Normal file
28
vendor/github.com/google/cel-go/common/types/traits/BUILD.bazel
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
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 = [
|
||||
"comparer.go",
|
||||
"container.go",
|
||||
"field_tester.go",
|
||||
"indexer.go",
|
||||
"iterator.go",
|
||||
"lister.go",
|
||||
"mapper.go",
|
||||
"matcher.go",
|
||||
"math.go",
|
||||
"receiver.go",
|
||||
"sizer.go",
|
||||
"traits.go",
|
||||
],
|
||||
importpath = "github.com/google/cel-go/common/types/traits",
|
||||
deps = [
|
||||
"//common/types/ref:go_default_library",
|
||||
],
|
||||
)
|
33
vendor/github.com/google/cel-go/common/types/traits/comparer.go
generated
vendored
Normal file
33
vendor/github.com/google/cel-go/common/types/traits/comparer.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// 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 traits
|
||||
|
||||
import (
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
)
|
||||
|
||||
// Comparer interface for ordering comparisons between values in order to
|
||||
// support '<', '<=', '>=', '>' overloads.
|
||||
type Comparer interface {
|
||||
// Compare this value to the input other value, returning an Int:
|
||||
//
|
||||
// this < other -> Int(-1)
|
||||
// this == other -> Int(0)
|
||||
// this > other -> Int(1)
|
||||
//
|
||||
// If the comparison cannot be made or is not supported, an error should
|
||||
// be returned.
|
||||
Compare(other ref.Val) ref.Val
|
||||
}
|
23
vendor/github.com/google/cel-go/common/types/traits/container.go
generated
vendored
Normal file
23
vendor/github.com/google/cel-go/common/types/traits/container.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
// 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 traits
|
||||
|
||||
import "github.com/google/cel-go/common/types/ref"
|
||||
|
||||
// Container interface which permits containment tests such as 'a in b'.
|
||||
type Container interface {
|
||||
// Contains returns true if the value exists within the object.
|
||||
Contains(value ref.Val) ref.Val
|
||||
}
|
30
vendor/github.com/google/cel-go/common/types/traits/field_tester.go
generated
vendored
Normal file
30
vendor/github.com/google/cel-go/common/types/traits/field_tester.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// 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 traits
|
||||
|
||||
import (
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
)
|
||||
|
||||
// FieldTester indicates if a defined field on an object type is set to a
|
||||
// non-default value.
|
||||
//
|
||||
// For use with the `has()` macro.
|
||||
type FieldTester interface {
|
||||
// IsSet returns true if the field is defined and set to a non-default
|
||||
// value. The method will return false if defined and not set, and an error
|
||||
// if the field is not defined.
|
||||
IsSet(field ref.Val) ref.Val
|
||||
}
|
25
vendor/github.com/google/cel-go/common/types/traits/indexer.go
generated
vendored
Normal file
25
vendor/github.com/google/cel-go/common/types/traits/indexer.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// 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 traits
|
||||
|
||||
import (
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
)
|
||||
|
||||
// Indexer permits random access of elements by index 'a[b()]'.
|
||||
type Indexer interface {
|
||||
// Get the value at the specified index or error.
|
||||
Get(index ref.Val) ref.Val
|
||||
}
|
36
vendor/github.com/google/cel-go/common/types/traits/iterator.go
generated
vendored
Normal file
36
vendor/github.com/google/cel-go/common/types/traits/iterator.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
// 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 traits
|
||||
|
||||
import (
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
)
|
||||
|
||||
// Iterable aggregate types permit traversal over their elements.
|
||||
type Iterable interface {
|
||||
// Iterator returns a new iterator view of the struct.
|
||||
Iterator() Iterator
|
||||
}
|
||||
|
||||
// Iterator permits safe traversal over the contents of an aggregate type.
|
||||
type Iterator interface {
|
||||
ref.Val
|
||||
|
||||
// HasNext returns true if there are unvisited elements in the Iterator.
|
||||
HasNext() ref.Val
|
||||
|
||||
// Next returns the next element.
|
||||
Next() ref.Val
|
||||
}
|
33
vendor/github.com/google/cel-go/common/types/traits/lister.go
generated
vendored
Normal file
33
vendor/github.com/google/cel-go/common/types/traits/lister.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// 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 traits
|
||||
|
||||
import "github.com/google/cel-go/common/types/ref"
|
||||
|
||||
// Lister interface which aggregates the traits of a list.
|
||||
type Lister interface {
|
||||
ref.Val
|
||||
Adder
|
||||
Container
|
||||
Indexer
|
||||
Iterable
|
||||
Sizer
|
||||
}
|
||||
|
||||
// MutableLister interface which emits an immutable result after an intermediate computation.
|
||||
type MutableLister interface {
|
||||
Lister
|
||||
ToImmutableList() Lister
|
||||
}
|
33
vendor/github.com/google/cel-go/common/types/traits/mapper.go
generated
vendored
Normal file
33
vendor/github.com/google/cel-go/common/types/traits/mapper.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// 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 traits
|
||||
|
||||
import "github.com/google/cel-go/common/types/ref"
|
||||
|
||||
// Mapper interface which aggregates the traits of a maps.
|
||||
type Mapper interface {
|
||||
ref.Val
|
||||
Container
|
||||
Indexer
|
||||
Iterable
|
||||
Sizer
|
||||
|
||||
// Find returns a value, if one exists, for the input key.
|
||||
//
|
||||
// If the key is not found the function returns (nil, false).
|
||||
// If the input key is not valid for the map, or is Err or Unknown the function returns
|
||||
// (Unknown|Err, false).
|
||||
Find(key ref.Val) (ref.Val, bool)
|
||||
}
|
23
vendor/github.com/google/cel-go/common/types/traits/matcher.go
generated
vendored
Normal file
23
vendor/github.com/google/cel-go/common/types/traits/matcher.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
// 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 traits
|
||||
|
||||
import "github.com/google/cel-go/common/types/ref"
|
||||
|
||||
// Matcher interface for supporting 'matches()' overloads.
|
||||
type Matcher interface {
|
||||
// Match returns true if the pattern matches the current value.
|
||||
Match(pattern ref.Val) ref.Val
|
||||
}
|
62
vendor/github.com/google/cel-go/common/types/traits/math.go
generated
vendored
Normal file
62
vendor/github.com/google/cel-go/common/types/traits/math.go
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
// 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 traits
|
||||
|
||||
import "github.com/google/cel-go/common/types/ref"
|
||||
|
||||
// Adder interface to support '+' operator overloads.
|
||||
type Adder interface {
|
||||
// Add returns a combination of the current value and other value.
|
||||
//
|
||||
// If the other value is an unsupported type, an error is returned.
|
||||
Add(other ref.Val) ref.Val
|
||||
}
|
||||
|
||||
// Divider interface to support '/' operator overloads.
|
||||
type Divider interface {
|
||||
// Divide returns the result of dividing the current value by the input
|
||||
// denominator.
|
||||
//
|
||||
// A denominator value of zero results in an error.
|
||||
Divide(denominator ref.Val) ref.Val
|
||||
}
|
||||
|
||||
// Modder interface to support '%' operator overloads.
|
||||
type Modder interface {
|
||||
// Modulo returns the result of taking the modulus of the current value
|
||||
// by the denominator.
|
||||
//
|
||||
// A denominator value of zero results in an error.
|
||||
Modulo(denominator ref.Val) ref.Val
|
||||
}
|
||||
|
||||
// Multiplier interface to support '*' operator overloads.
|
||||
type Multiplier interface {
|
||||
// Multiply returns the result of multiplying the current and input value.
|
||||
Multiply(other ref.Val) ref.Val
|
||||
}
|
||||
|
||||
// Negater interface to support unary '-' and '!' operator overloads.
|
||||
type Negater interface {
|
||||
// Negate returns the complement of the current value.
|
||||
Negate() ref.Val
|
||||
}
|
||||
|
||||
// Subtractor interface to support binary '-' operator overloads.
|
||||
type Subtractor interface {
|
||||
// Subtract returns the result of subtracting the input from the current
|
||||
// value.
|
||||
Subtract(subtrahend ref.Val) ref.Val
|
||||
}
|
24
vendor/github.com/google/cel-go/common/types/traits/receiver.go
generated
vendored
Normal file
24
vendor/github.com/google/cel-go/common/types/traits/receiver.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
// 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 traits
|
||||
|
||||
import "github.com/google/cel-go/common/types/ref"
|
||||
|
||||
// Receiver interface for routing instance method calls within a value.
|
||||
type Receiver interface {
|
||||
// Receive accepts a function name, overload id, and arguments and returns
|
||||
// a value.
|
||||
Receive(function string, overload string, args []ref.Val) ref.Val
|
||||
}
|
25
vendor/github.com/google/cel-go/common/types/traits/sizer.go
generated
vendored
Normal file
25
vendor/github.com/google/cel-go/common/types/traits/sizer.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// 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 traits
|
||||
|
||||
import (
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
)
|
||||
|
||||
// Sizer interface for supporting 'size()' overloads.
|
||||
type Sizer interface {
|
||||
// Size returns the number of elements or length of the value.
|
||||
Size() ref.Val
|
||||
}
|
64
vendor/github.com/google/cel-go/common/types/traits/traits.go
generated
vendored
Normal file
64
vendor/github.com/google/cel-go/common/types/traits/traits.go
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
// 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 traits defines interfaces that a type may implement to participate
|
||||
// in operator overloads and function dispatch.
|
||||
package traits
|
||||
|
||||
const (
|
||||
// AdderType types provide a '+' operator overload.
|
||||
AdderType = 1 << iota
|
||||
|
||||
// ComparerType types support ordering comparisons '<', '<=', '>', '>='.
|
||||
ComparerType
|
||||
|
||||
// ContainerType types support 'in' operations.
|
||||
ContainerType
|
||||
|
||||
// DividerType types support '/' operations.
|
||||
DividerType
|
||||
|
||||
// FieldTesterType types support the detection of field value presence.
|
||||
FieldTesterType
|
||||
|
||||
// IndexerType types support index access with dynamic values.
|
||||
IndexerType
|
||||
|
||||
// IterableType types can be iterated over in comprehensions.
|
||||
IterableType
|
||||
|
||||
// IteratorType types support iterator semantics.
|
||||
IteratorType
|
||||
|
||||
// MatcherType types support pattern matching via 'matches' method.
|
||||
MatcherType
|
||||
|
||||
// ModderType types support modulus operations '%'
|
||||
ModderType
|
||||
|
||||
// MultiplierType types support '*' operations.
|
||||
MultiplierType
|
||||
|
||||
// NegatorType types support either negation via '!' or '-'
|
||||
NegatorType
|
||||
|
||||
// ReceiverType types support dynamic dispatch to instance methods.
|
||||
ReceiverType
|
||||
|
||||
// SizerType types support the size() method.
|
||||
SizerType
|
||||
|
||||
// SubtractorType type support '-' operations.
|
||||
SubtractorType
|
||||
)
|
102
vendor/github.com/google/cel-go/common/types/type.go
generated
vendored
Normal file
102
vendor/github.com/google/cel-go/common/types/type.go
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
// 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) (interface{}, 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() interface{} {
|
||||
return t.name
|
||||
}
|
249
vendor/github.com/google/cel-go/common/types/uint.go
generated
vendored
Normal file
249
vendor/github.com/google/cel-go/common/types/uint.go
generated
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
// 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"
|
||||
"math"
|
||||
"reflect"
|
||||
"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"
|
||||
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
|
||||
)
|
||||
|
||||
// Uint type implementation which supports comparison and math operators.
|
||||
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{})
|
||||
)
|
||||
|
||||
// Uint constants
|
||||
const (
|
||||
uintZero = Uint(0)
|
||||
)
|
||||
|
||||
// Add implements traits.Adder.Add.
|
||||
func (i Uint) Add(other ref.Val) ref.Val {
|
||||
otherUint, ok := other.(Uint)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
val, err := addUint64Checked(uint64(i), uint64(otherUint))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Uint(val)
|
||||
}
|
||||
|
||||
// Compare implements traits.Comparer.Compare.
|
||||
func (i Uint) Compare(other ref.Val) ref.Val {
|
||||
switch ov := other.(type) {
|
||||
case Double:
|
||||
if math.IsNaN(float64(ov)) {
|
||||
return NewErr("NaN values cannot be ordered")
|
||||
}
|
||||
return compareUintDouble(i, ov)
|
||||
case Int:
|
||||
return compareUintInt(i, ov)
|
||||
case Uint:
|
||||
return compareUint(i, ov)
|
||||
default:
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertToNative implements ref.Val.ConvertToNative.
|
||||
func (i Uint) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
switch typeDesc.Kind() {
|
||||
case reflect.Uint, reflect.Uint32:
|
||||
v, err := uint64ToUint32Checked(uint64(i))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return reflect.ValueOf(v).Convert(typeDesc).Interface(), nil
|
||||
case reflect.Uint64:
|
||||
return reflect.ValueOf(i).Convert(typeDesc).Interface(), nil
|
||||
case reflect.Ptr:
|
||||
switch typeDesc {
|
||||
case anyValueType:
|
||||
// Primitives must be wrapped before being set on an Any field.
|
||||
return anypb.New(wrapperspb.UInt64(uint64(i)))
|
||||
case jsonValueType:
|
||||
// JSON can accurately represent 32-bit uints as floating point values.
|
||||
if i.isJSONSafe() {
|
||||
return structpb.NewNumberValue(float64(i)), nil
|
||||
}
|
||||
// Proto3 to JSON conversion requires string-formatted uint64 values
|
||||
// since the conversion to floating point would result in truncation.
|
||||
return structpb.NewStringValue(strconv.FormatUint(uint64(i), 10)), nil
|
||||
case uint32WrapperType:
|
||||
// Convert the value to a wrapperspb.UInt32Value, error on overflow.
|
||||
v, err := uint64ToUint32Checked(uint64(i))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return wrapperspb.UInt32(v), nil
|
||||
case uint64WrapperType:
|
||||
// Convert the value to a wrapperspb.UInt64Value.
|
||||
return wrapperspb.UInt64(uint64(i)), nil
|
||||
}
|
||||
switch typeDesc.Elem().Kind() {
|
||||
case reflect.Uint32:
|
||||
v, err := uint64ToUint32Checked(uint64(i))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
p := reflect.New(typeDesc.Elem())
|
||||
p.Elem().Set(reflect.ValueOf(v).Convert(typeDesc.Elem()))
|
||||
return p.Interface(), nil
|
||||
case reflect.Uint64:
|
||||
v := uint64(i)
|
||||
p := reflect.New(typeDesc.Elem())
|
||||
p.Elem().Set(reflect.ValueOf(v).Convert(typeDesc.Elem()))
|
||||
return p.Interface(), nil
|
||||
}
|
||||
case reflect.Interface:
|
||||
iv := i.Value()
|
||||
if reflect.TypeOf(iv).Implements(typeDesc) {
|
||||
return iv, nil
|
||||
}
|
||||
if reflect.TypeOf(i).Implements(typeDesc) {
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported type conversion from 'uint' to %v", typeDesc)
|
||||
}
|
||||
|
||||
// ConvertToType implements ref.Val.ConvertToType.
|
||||
func (i Uint) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case IntType:
|
||||
v, err := uint64ToInt64Checked(uint64(i))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Int(v)
|
||||
case UintType:
|
||||
return i
|
||||
case DoubleType:
|
||||
return Double(i)
|
||||
case StringType:
|
||||
return String(fmt.Sprintf("%d", uint64(i)))
|
||||
case TypeType:
|
||||
return UintType
|
||||
}
|
||||
return NewErr("type conversion error from '%s' to '%s'", UintType, typeVal)
|
||||
}
|
||||
|
||||
// Divide implements traits.Divider.Divide.
|
||||
func (i Uint) Divide(other ref.Val) ref.Val {
|
||||
otherUint, ok := other.(Uint)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
div, err := divideUint64Checked(uint64(i), uint64(otherUint))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Uint(div)
|
||||
}
|
||||
|
||||
// Equal implements ref.Val.Equal.
|
||||
func (i Uint) Equal(other ref.Val) ref.Val {
|
||||
switch ov := other.(type) {
|
||||
case Double:
|
||||
if math.IsNaN(float64(ov)) {
|
||||
return False
|
||||
}
|
||||
return Bool(compareUintDouble(i, ov) == 0)
|
||||
case Int:
|
||||
return Bool(compareUintInt(i, ov) == 0)
|
||||
case Uint:
|
||||
return Bool(i == ov)
|
||||
default:
|
||||
return False
|
||||
}
|
||||
}
|
||||
|
||||
// Modulo implements traits.Modder.Modulo.
|
||||
func (i Uint) Modulo(other ref.Val) ref.Val {
|
||||
otherUint, ok := other.(Uint)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
mod, err := moduloUint64Checked(uint64(i), uint64(otherUint))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Uint(mod)
|
||||
}
|
||||
|
||||
// Multiply implements traits.Multiplier.Multiply.
|
||||
func (i Uint) Multiply(other ref.Val) ref.Val {
|
||||
otherUint, ok := other.(Uint)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
val, err := multiplyUint64Checked(uint64(i), uint64(otherUint))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Uint(val)
|
||||
}
|
||||
|
||||
// Subtract implements traits.Subtractor.Subtract.
|
||||
func (i Uint) Subtract(subtrahend ref.Val) ref.Val {
|
||||
subtraUint, ok := subtrahend.(Uint)
|
||||
if !ok {
|
||||
return MaybeNoSuchOverloadErr(subtrahend)
|
||||
}
|
||||
val, err := subtractUint64Checked(uint64(i), uint64(subtraUint))
|
||||
if err != nil {
|
||||
return wrapErr(err)
|
||||
}
|
||||
return Uint(val)
|
||||
}
|
||||
|
||||
// Type implements ref.Val.Type.
|
||||
func (i Uint) Type() ref.Type {
|
||||
return UintType
|
||||
}
|
||||
|
||||
// Value implements ref.Val.Value.
|
||||
func (i Uint) Value() interface{} {
|
||||
return uint64(i)
|
||||
}
|
||||
|
||||
// isJSONSafe indicates whether the uint is safely representable as a floating point value in JSON.
|
||||
func (i Uint) isJSONSafe() bool {
|
||||
return i <= maxIntJSON
|
||||
}
|
66
vendor/github.com/google/cel-go/common/types/unknown.go
generated
vendored
Normal file
66
vendor/github.com/google/cel-go/common/types/unknown.go
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
// 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 (
|
||||
"reflect"
|
||||
|
||||
"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")
|
||||
)
|
||||
|
||||
// ConvertToNative implements ref.Val.ConvertToNative.
|
||||
func (u Unknown) ConvertToNative(typeDesc reflect.Type) (interface{}, 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 {
|
||||
return u
|
||||
}
|
||||
|
||||
// Equal is an identity function since unknown values cannot be modified.
|
||||
func (u Unknown) Equal(other ref.Val) ref.Val {
|
||||
return u
|
||||
}
|
||||
|
||||
// Type implements ref.Val.Type.
|
||||
func (u Unknown) Type() ref.Type {
|
||||
return UnknownType
|
||||
}
|
||||
|
||||
// Value implements ref.Val.Value.
|
||||
func (u Unknown) Value() interface{} {
|
||||
return []int64(u)
|
||||
}
|
||||
|
||||
// IsUnknown returns whether the element ref.Type or ref.Val is equal to the
|
||||
// UnknownType singleton.
|
||||
func IsUnknown(val ref.Val) bool {
|
||||
switch val.(type) {
|
||||
case Unknown:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
48
vendor/github.com/google/cel-go/common/types/util.go
generated
vendored
Normal file
48
vendor/github.com/google/cel-go/common/types/util.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
// 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 (
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
)
|
||||
|
||||
// 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:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsPrimitiveType returns whether the input element ref.Val is a primitive type.
|
||||
// Note, primitive types do not include well-known types such as Duration and Timestamp.
|
||||
func IsPrimitiveType(val ref.Val) bool {
|
||||
switch val.Type() {
|
||||
case BoolType, BytesType, DoubleType, IntType, StringType, UintType:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Equal returns whether the two ref.Value are heterogeneously equivalent.
|
||||
func Equal(lhs ref.Val, rhs ref.Val) ref.Val {
|
||||
lNull := lhs == NullValue
|
||||
rNull := rhs == NullValue
|
||||
if lNull || rNull {
|
||||
return Bool(lNull == rNull)
|
||||
}
|
||||
return lhs.Equal(rhs)
|
||||
}
|
Reference in New Issue
Block a user