generated: ./hack/update-vendor.sh

This commit is contained in:
Jiahui Feng
2024-04-22 10:54:32 -07:00
parent 51af569512
commit 350fcf957e
189 changed files with 14707 additions and 9152 deletions

View File

@@ -16,74 +16,361 @@
package ast
import (
"fmt"
"github.com/google/cel-go/common"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
structpb "google.golang.org/protobuf/types/known/structpb"
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
)
// CheckedAST contains a protobuf expression and source info along with CEL-native type and reference information.
type CheckedAST struct {
Expr *exprpb.Expr
SourceInfo *exprpb.SourceInfo
TypeMap map[int64]*types.Type
ReferenceMap map[int64]*ReferenceInfo
// AST contains a protobuf expression and source info along with CEL-native type and reference information.
type AST struct {
expr Expr
sourceInfo *SourceInfo
typeMap map[int64]*types.Type
refMap map[int64]*ReferenceInfo
}
// CheckedASTToCheckedExpr converts a CheckedAST to a CheckedExpr protobouf.
func CheckedASTToCheckedExpr(ast *CheckedAST) (*exprpb.CheckedExpr, error) {
refMap := make(map[int64]*exprpb.Reference, len(ast.ReferenceMap))
for id, ref := range ast.ReferenceMap {
r, err := ReferenceInfoToReferenceExpr(ref)
if err != nil {
return nil, err
}
refMap[id] = r
// Expr returns the root ast.Expr value in the AST.
func (a *AST) Expr() Expr {
if a == nil {
return nilExpr
}
typeMap := make(map[int64]*exprpb.Type, len(ast.TypeMap))
for id, typ := range ast.TypeMap {
t, err := types.TypeToExprType(typ)
if err != nil {
return nil, err
}
typeMap[id] = t
}
return &exprpb.CheckedExpr{
Expr: ast.Expr,
SourceInfo: ast.SourceInfo,
ReferenceMap: refMap,
TypeMap: typeMap,
}, nil
return a.expr
}
// CheckedExprToCheckedAST converts a CheckedExpr protobuf to a CheckedAST instance.
func CheckedExprToCheckedAST(checked *exprpb.CheckedExpr) (*CheckedAST, error) {
refMap := make(map[int64]*ReferenceInfo, len(checked.GetReferenceMap()))
for id, ref := range checked.GetReferenceMap() {
r, err := ReferenceExprToReferenceInfo(ref)
if err != nil {
return nil, err
}
refMap[id] = r
// SourceInfo returns the source metadata associated with the parse / type-check passes.
func (a *AST) SourceInfo() *SourceInfo {
if a == nil {
return nil
}
typeMap := make(map[int64]*types.Type, len(checked.GetTypeMap()))
for id, typ := range checked.GetTypeMap() {
t, err := types.ExprTypeToType(typ)
if err != nil {
return nil, err
}
typeMap[id] = t
return a.sourceInfo
}
// GetType returns the type for the expression at the given id, if one exists, else types.DynType.
func (a *AST) GetType(id int64) *types.Type {
if t, found := a.TypeMap()[id]; found {
return t
}
return &CheckedAST{
Expr: checked.GetExpr(),
SourceInfo: checked.GetSourceInfo(),
ReferenceMap: refMap,
TypeMap: typeMap,
}, nil
return types.DynType
}
// SetType sets the type of the expression node at the given id.
func (a *AST) SetType(id int64, t *types.Type) {
if a == nil {
return
}
a.typeMap[id] = t
}
// TypeMap returns the map of expression ids to type-checked types.
//
// If the AST is not type-checked, the map will be empty.
func (a *AST) TypeMap() map[int64]*types.Type {
if a == nil {
return map[int64]*types.Type{}
}
return a.typeMap
}
// GetOverloadIDs returns the set of overload function names for a given expression id.
//
// If the expression id is not a function call, or the AST is not type-checked, the result will be empty.
func (a *AST) GetOverloadIDs(id int64) []string {
if ref, found := a.ReferenceMap()[id]; found {
return ref.OverloadIDs
}
return []string{}
}
// ReferenceMap returns the map of expression id to identifier, constant, and function references.
func (a *AST) ReferenceMap() map[int64]*ReferenceInfo {
if a == nil {
return map[int64]*ReferenceInfo{}
}
return a.refMap
}
// SetReference adds a reference to the checked AST type map.
func (a *AST) SetReference(id int64, r *ReferenceInfo) {
if a == nil {
return
}
a.refMap[id] = r
}
// IsChecked returns whether the AST is type-checked.
func (a *AST) IsChecked() bool {
return a != nil && len(a.TypeMap()) > 0
}
// NewAST creates a base AST instance with an ast.Expr and ast.SourceInfo value.
func NewAST(e Expr, sourceInfo *SourceInfo) *AST {
if e == nil {
e = nilExpr
}
return &AST{
expr: e,
sourceInfo: sourceInfo,
typeMap: make(map[int64]*types.Type),
refMap: make(map[int64]*ReferenceInfo),
}
}
// NewCheckedAST wraps an parsed AST and augments it with type and reference metadata.
func NewCheckedAST(parsed *AST, typeMap map[int64]*types.Type, refMap map[int64]*ReferenceInfo) *AST {
return &AST{
expr: parsed.Expr(),
sourceInfo: parsed.SourceInfo(),
typeMap: typeMap,
refMap: refMap,
}
}
// Copy creates a deep copy of the Expr and SourceInfo values in the input AST.
//
// Copies of the Expr value are generated using an internal default ExprFactory.
func Copy(a *AST) *AST {
if a == nil {
return nil
}
e := defaultFactory.CopyExpr(a.expr)
if !a.IsChecked() {
return NewAST(e, CopySourceInfo(a.SourceInfo()))
}
typesCopy := make(map[int64]*types.Type, len(a.typeMap))
for id, t := range a.typeMap {
typesCopy[id] = t
}
refsCopy := make(map[int64]*ReferenceInfo, len(a.refMap))
for id, r := range a.refMap {
refsCopy[id] = r
}
return NewCheckedAST(NewAST(e, CopySourceInfo(a.SourceInfo())), typesCopy, refsCopy)
}
// MaxID returns the upper-bound, non-inclusive, of ids present within the AST's Expr value.
func MaxID(a *AST) int64 {
visitor := &maxIDVisitor{maxID: 1}
PostOrderVisit(a.Expr(), visitor)
for id, call := range a.SourceInfo().MacroCalls() {
PostOrderVisit(call, visitor)
if id > visitor.maxID {
visitor.maxID = id + 1
}
}
return visitor.maxID + 1
}
// NewSourceInfo creates a simple SourceInfo object from an input common.Source value.
func NewSourceInfo(src common.Source) *SourceInfo {
var lineOffsets []int32
var desc string
baseLine := int32(0)
baseCol := int32(0)
if src != nil {
desc = src.Description()
lineOffsets = src.LineOffsets()
// Determine whether the source metadata should be computed relative
// to a base line and column value. This can be determined by requesting
// the location for offset 0 from the source object.
if loc, found := src.OffsetLocation(0); found {
baseLine = int32(loc.Line()) - 1
baseCol = int32(loc.Column())
}
}
return &SourceInfo{
desc: desc,
lines: lineOffsets,
baseLine: baseLine,
baseCol: baseCol,
offsetRanges: make(map[int64]OffsetRange),
macroCalls: make(map[int64]Expr),
}
}
// CopySourceInfo creates a deep copy of the MacroCalls within the input SourceInfo.
//
// Copies of macro Expr values are generated using an internal default ExprFactory.
func CopySourceInfo(info *SourceInfo) *SourceInfo {
if info == nil {
return nil
}
rangesCopy := make(map[int64]OffsetRange, len(info.offsetRanges))
for id, off := range info.offsetRanges {
rangesCopy[id] = off
}
callsCopy := make(map[int64]Expr, len(info.macroCalls))
for id, call := range info.macroCalls {
callsCopy[id] = defaultFactory.CopyExpr(call)
}
return &SourceInfo{
syntax: info.syntax,
desc: info.desc,
lines: info.lines,
baseLine: info.baseLine,
baseCol: info.baseCol,
offsetRanges: rangesCopy,
macroCalls: callsCopy,
}
}
// SourceInfo records basic information about the expression as a textual input and
// as a parsed expression value.
type SourceInfo struct {
syntax string
desc string
lines []int32
baseLine int32
baseCol int32
offsetRanges map[int64]OffsetRange
macroCalls map[int64]Expr
}
// SyntaxVersion returns the syntax version associated with the text expression.
func (s *SourceInfo) SyntaxVersion() string {
if s == nil {
return ""
}
return s.syntax
}
// Description provides information about where the expression came from.
func (s *SourceInfo) Description() string {
if s == nil {
return ""
}
return s.desc
}
// LineOffsets returns a list of the 0-based character offsets in the input text where newlines appear.
func (s *SourceInfo) LineOffsets() []int32 {
if s == nil {
return []int32{}
}
return s.lines
}
// MacroCalls returns a map of expression id to ast.Expr value where the id represents the expression
// node where the macro was inserted into the AST, and the ast.Expr value represents the original call
// signature which was replaced.
func (s *SourceInfo) MacroCalls() map[int64]Expr {
if s == nil {
return map[int64]Expr{}
}
return s.macroCalls
}
// GetMacroCall returns the original ast.Expr value for the given expression if it was generated via
// a macro replacement.
//
// Note, parsing options must be enabled to track macro calls before this method will return a value.
func (s *SourceInfo) GetMacroCall(id int64) (Expr, bool) {
e, found := s.MacroCalls()[id]
return e, found
}
// SetMacroCall records a macro call at a specific location.
func (s *SourceInfo) SetMacroCall(id int64, e Expr) {
if s != nil {
s.macroCalls[id] = e
}
}
// ClearMacroCall removes the macro call at the given expression id.
func (s *SourceInfo) ClearMacroCall(id int64) {
if s != nil {
delete(s.macroCalls, id)
}
}
// OffsetRanges returns a map of expression id to OffsetRange values where the range indicates either:
// the start and end position in the input stream where the expression occurs, or the start position
// only. If the range only captures start position, the stop position of the range will be equal to
// the start.
func (s *SourceInfo) OffsetRanges() map[int64]OffsetRange {
if s == nil {
return map[int64]OffsetRange{}
}
return s.offsetRanges
}
// GetOffsetRange retrieves an OffsetRange for the given expression id if one exists.
func (s *SourceInfo) GetOffsetRange(id int64) (OffsetRange, bool) {
if s == nil {
return OffsetRange{}, false
}
o, found := s.offsetRanges[id]
return o, found
}
// SetOffsetRange sets the OffsetRange for the given expression id.
func (s *SourceInfo) SetOffsetRange(id int64, o OffsetRange) {
if s == nil {
return
}
s.offsetRanges[id] = o
}
// GetStartLocation calculates the human-readable 1-based line and 0-based column of the first character
// of the expression node at the id.
func (s *SourceInfo) GetStartLocation(id int64) common.Location {
if o, found := s.GetOffsetRange(id); found {
line := 1
col := int(o.Start)
for _, lineOffset := range s.LineOffsets() {
if lineOffset < o.Start {
line++
col = int(o.Start - lineOffset)
} else {
break
}
}
return common.NewLocation(line, col)
}
return common.NoLocation
}
// GetStopLocation calculates the human-readable 1-based line and 0-based column of the last character for
// the expression node at the given id.
//
// If the SourceInfo was generated from a serialized protobuf representation, the stop location will
// be identical to the start location for the expression.
func (s *SourceInfo) GetStopLocation(id int64) common.Location {
if o, found := s.GetOffsetRange(id); found {
line := 1
col := int(o.Stop)
for _, lineOffset := range s.LineOffsets() {
if lineOffset < o.Stop {
line++
col = int(o.Stop - lineOffset)
} else {
break
}
}
return common.NewLocation(line, col)
}
return common.NoLocation
}
// ComputeOffset calculates the 0-based character offset from a 1-based line and 0-based column.
func (s *SourceInfo) ComputeOffset(line, col int32) int32 {
if s != nil {
line = s.baseLine + line
col = s.baseCol + col
}
if line == 1 {
return col
}
if line < 1 || line > int32(len(s.LineOffsets())) {
return -1
}
offset := s.LineOffsets()[line-2]
return offset + col
}
// OffsetRange captures the start and stop positions of a section of text in the input expression.
type OffsetRange struct {
Start int32
Stop int32
}
// ReferenceInfo contains a CEL native representation of an identifier reference which may refer to
@@ -149,78 +436,21 @@ func (r *ReferenceInfo) Equals(other *ReferenceInfo) bool {
return true
}
// ReferenceInfoToReferenceExpr converts a ReferenceInfo instance to a protobuf Reference suitable for serialization.
func ReferenceInfoToReferenceExpr(info *ReferenceInfo) (*exprpb.Reference, error) {
c, err := ValToConstant(info.Value)
if err != nil {
return nil, err
}
return &exprpb.Reference{
Name: info.Name,
OverloadId: info.OverloadIDs,
Value: c,
}, nil
type maxIDVisitor struct {
maxID int64
*baseVisitor
}
// ReferenceExprToReferenceInfo converts a protobuf Reference into a CEL-native ReferenceInfo instance.
func ReferenceExprToReferenceInfo(ref *exprpb.Reference) (*ReferenceInfo, error) {
v, err := ConstantToVal(ref.GetValue())
if err != nil {
return nil, err
// VisitExpr updates the max identifier if the incoming expression id is greater than previously observed.
func (v *maxIDVisitor) VisitExpr(e Expr) {
if v.maxID < e.ID() {
v.maxID = e.ID()
}
return &ReferenceInfo{
Name: ref.GetName(),
OverloadIDs: ref.GetOverloadId(),
Value: v,
}, nil
}
// ValToConstant converts a CEL-native ref.Val to a protobuf Constant.
//
// Only simple scalar types are supported by this method.
func ValToConstant(v ref.Val) (*exprpb.Constant, error) {
if v == nil {
return nil, nil
// VisitEntryExpr updates the max identifier if the incoming entry id is greater than previously observed.
func (v *maxIDVisitor) VisitEntryExpr(e EntryExpr) {
if v.maxID < e.ID() {
v.maxID = e.ID()
}
switch v.Type() {
case types.BoolType:
return &exprpb.Constant{ConstantKind: &exprpb.Constant_BoolValue{BoolValue: v.Value().(bool)}}, nil
case types.BytesType:
return &exprpb.Constant{ConstantKind: &exprpb.Constant_BytesValue{BytesValue: v.Value().([]byte)}}, nil
case types.DoubleType:
return &exprpb.Constant{ConstantKind: &exprpb.Constant_DoubleValue{DoubleValue: v.Value().(float64)}}, nil
case types.IntType:
return &exprpb.Constant{ConstantKind: &exprpb.Constant_Int64Value{Int64Value: v.Value().(int64)}}, nil
case types.NullType:
return &exprpb.Constant{ConstantKind: &exprpb.Constant_NullValue{NullValue: structpb.NullValue_NULL_VALUE}}, nil
case types.StringType:
return &exprpb.Constant{ConstantKind: &exprpb.Constant_StringValue{StringValue: v.Value().(string)}}, nil
case types.UintType:
return &exprpb.Constant{ConstantKind: &exprpb.Constant_Uint64Value{Uint64Value: v.Value().(uint64)}}, nil
}
return nil, fmt.Errorf("unsupported constant kind: %v", v.Type())
}
// ConstantToVal converts a protobuf Constant to a CEL-native ref.Val.
func ConstantToVal(c *exprpb.Constant) (ref.Val, error) {
if c == nil {
return nil, nil
}
switch c.GetConstantKind().(type) {
case *exprpb.Constant_BoolValue:
return types.Bool(c.GetBoolValue()), nil
case *exprpb.Constant_BytesValue:
return types.Bytes(c.GetBytesValue()), nil
case *exprpb.Constant_DoubleValue:
return types.Double(c.GetDoubleValue()), nil
case *exprpb.Constant_Int64Value:
return types.Int(c.GetInt64Value()), nil
case *exprpb.Constant_NullValue:
return types.NullValue, nil
case *exprpb.Constant_StringValue:
return types.String(c.GetStringValue()), nil
case *exprpb.Constant_Uint64Value:
return types.Uint(c.GetUint64Value()), nil
}
return nil, fmt.Errorf("unsupported constant kind: %v", c.GetConstantKind())
}