diff options
Diffstat (limited to 'vendor/github.com/authzed/cel-go/common/ast/expr.go')
| -rw-r--r-- | vendor/github.com/authzed/cel-go/common/ast/expr.go | 860 |
1 files changed, 860 insertions, 0 deletions
diff --git a/vendor/github.com/authzed/cel-go/common/ast/expr.go b/vendor/github.com/authzed/cel-go/common/ast/expr.go new file mode 100644 index 0000000..a9c09e6 --- /dev/null +++ b/vendor/github.com/authzed/cel-go/common/ast/expr.go @@ -0,0 +1,860 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ast + +import ( + "github.com/authzed/cel-go/common/types/ref" +) + +// ExprKind represents the expression node kind. +type ExprKind int + +const ( + // UnspecifiedExprKind represents an unset expression with no specified properties. + UnspecifiedExprKind ExprKind = iota + + // CallKind represents a function call. + CallKind + + // ComprehensionKind represents a comprehension expression generated by a macro. + ComprehensionKind + + // IdentKind represents a simple variable, constant, or type identifier. + IdentKind + + // ListKind represents a list literal expression. + ListKind + + // LiteralKind represents a primitive scalar literal. + LiteralKind + + // MapKind represents a map literal expression. + MapKind + + // SelectKind represents a field selection expression. + SelectKind + + // StructKind represents a struct literal expression. + StructKind +) + +// Expr represents the base expression node in a CEL abstract syntax tree. +// +// Depending on the `Kind()` value, the Expr may be converted to a concrete expression types +// as indicated by the `As<Kind>` methods. +type Expr interface { + // ID of the expression as it appears in the AST + ID() int64 + + // Kind of the expression node. See ExprKind for the valid enum values. + Kind() ExprKind + + // AsCall adapts the expr into a CallExpr + // + // The Kind() must be equal to a CallKind for the conversion to be well-defined. + AsCall() CallExpr + + // AsComprehension adapts the expr into a ComprehensionExpr. + // + // The Kind() must be equal to a ComprehensionKind for the conversion to be well-defined. + AsComprehension() ComprehensionExpr + + // AsIdent adapts the expr into an identifier string. + // + // The Kind() must be equal to an IdentKind for the conversion to be well-defined. + AsIdent() string + + // AsLiteral adapts the expr into a constant ref.Val. + // + // The Kind() must be equal to a LiteralKind for the conversion to be well-defined. + AsLiteral() ref.Val + + // AsList adapts the expr into a ListExpr. + // + // The Kind() must be equal to a ListKind for the conversion to be well-defined. + AsList() ListExpr + + // AsMap adapts the expr into a MapExpr. + // + // The Kind() must be equal to a MapKind for the conversion to be well-defined. + AsMap() MapExpr + + // AsSelect adapts the expr into a SelectExpr. + // + // The Kind() must be equal to a SelectKind for the conversion to be well-defined. + AsSelect() SelectExpr + + // AsStruct adapts the expr into a StructExpr. + // + // The Kind() must be equal to a StructKind for the conversion to be well-defined. + AsStruct() StructExpr + + // RenumberIDs performs an in-place update of the expression and all of its descendents numeric ids. + RenumberIDs(IDGenerator) + + // SetKindCase replaces the contents of the current expression with the contents of the other. + // + // The SetKindCase takes ownership of any expression instances references within the input Expr. + // A shallow copy is made of the Expr value itself, but not a deep one. + // + // This method should only be used during AST rewrites using temporary Expr values. + SetKindCase(Expr) + + // isExpr is a marker interface. + isExpr() +} + +// EntryExprKind represents the possible EntryExpr kinds. +type EntryExprKind int + +const ( + // UnspecifiedEntryExprKind indicates that the entry expr is not set. + UnspecifiedEntryExprKind EntryExprKind = iota + + // MapEntryKind indicates that the entry is a MapEntry type with key and value expressions. + MapEntryKind + + // StructFieldKind indicates that the entry is a StructField with a field name and initializer + // expression. + StructFieldKind +) + +// EntryExpr represents the base entry expression in a CEL map or struct literal. +type EntryExpr interface { + // ID of the entry as it appears in the AST. + ID() int64 + + // Kind of the entry expression node. See EntryExprKind for valid enum values. + Kind() EntryExprKind + + // AsMapEntry casts the EntryExpr to a MapEntry. + // + // The Kind() must be equal to MapEntryKind for the conversion to be well-defined. + AsMapEntry() MapEntry + + // AsStructField casts the EntryExpr to a StructField + // + // The Kind() must be equal to StructFieldKind for the conversion to be well-defined. + AsStructField() StructField + + // RenumberIDs performs an in-place update of the expression and all of its descendents numeric ids. + RenumberIDs(IDGenerator) + + isEntryExpr() +} + +// IDGenerator produces unique ids suitable for tagging expression nodes +type IDGenerator func(originalID int64) int64 + +// CallExpr defines an interface for inspecting a function call and its arguments. +type CallExpr interface { + // FunctionName returns the name of the function. + FunctionName() string + + // IsMemberFunction returns whether the call has a non-nil target indicating it is a member function + IsMemberFunction() bool + + // Target returns the target of the expression if one is present. + Target() Expr + + // Args returns the list of call arguments, excluding the target. + Args() []Expr + + // marker interface method + isExpr() +} + +// ListExpr defines an interface for inspecting a list literal expression. +type ListExpr interface { + // Elements returns the list elements as navigable expressions. + Elements() []Expr + + // OptionalIndicies returns the list of optional indices in the list literal. + OptionalIndices() []int32 + + // IsOptional indicates whether the given element index is optional. + IsOptional(int32) bool + + // Size returns the number of elements in the list. + Size() int + + // marker interface method + isExpr() +} + +// SelectExpr defines an interface for inspecting a select expression. +type SelectExpr interface { + // Operand returns the selection operand expression. + Operand() Expr + + // FieldName returns the field name being selected from the operand. + FieldName() string + + // IsTestOnly indicates whether the select expression is a presence test generated by a macro. + IsTestOnly() bool + + // marker interface method + isExpr() +} + +// MapExpr defines an interface for inspecting a map expression. +type MapExpr interface { + // Entries returns the map key value pairs as EntryExpr values. + Entries() []EntryExpr + + // Size returns the number of entries in the map. + Size() int + + // marker interface method + isExpr() +} + +// MapEntry defines an interface for inspecting a map entry. +type MapEntry interface { + // Key returns the map entry key expression. + Key() Expr + + // Value returns the map entry value expression. + Value() Expr + + // IsOptional returns whether the entry is optional. + IsOptional() bool + + // marker interface method + isEntryExpr() +} + +// StructExpr defines an interfaces for inspecting a struct and its field initializers. +type StructExpr interface { + // TypeName returns the struct type name. + TypeName() string + + // Fields returns the set of field initializers in the struct expression as EntryExpr values. + Fields() []EntryExpr + + // marker interface method + isExpr() +} + +// StructField defines an interface for inspecting a struct field initialization. +type StructField interface { + // Name returns the name of the field. + Name() string + + // Value returns the field initialization expression. + Value() Expr + + // IsOptional returns whether the field is optional. + IsOptional() bool + + // marker interface method + isEntryExpr() +} + +// ComprehensionExpr defines an interface for inspecting a comprehension expression. +type ComprehensionExpr interface { + // IterRange returns the iteration range expression. + IterRange() Expr + + // IterVar returns the iteration variable name. + IterVar() string + + // AccuVar returns the accumulation variable name. + AccuVar() string + + // AccuInit returns the accumulation variable initialization expression. + AccuInit() Expr + + // LoopCondition returns the loop condition expression. + LoopCondition() Expr + + // LoopStep returns the loop step expression. + LoopStep() Expr + + // Result returns the comprehension result expression. + Result() Expr + + // marker interface method + isExpr() +} + +var _ Expr = &expr{} + +type expr struct { + id int64 + exprKindCase +} + +type exprKindCase interface { + Kind() ExprKind + + renumberIDs(IDGenerator) + + isExpr() +} + +func (e *expr) ID() int64 { + if e == nil { + return 0 + } + return e.id +} + +func (e *expr) Kind() ExprKind { + if e == nil || e.exprKindCase == nil { + return UnspecifiedExprKind + } + return e.exprKindCase.Kind() +} + +func (e *expr) AsCall() CallExpr { + if e.Kind() != CallKind { + return nilCall + } + return e.exprKindCase.(CallExpr) +} + +func (e *expr) AsComprehension() ComprehensionExpr { + if e.Kind() != ComprehensionKind { + return nilCompre + } + return e.exprKindCase.(ComprehensionExpr) +} + +func (e *expr) AsIdent() string { + if e.Kind() != IdentKind { + return "" + } + return string(e.exprKindCase.(baseIdentExpr)) +} + +func (e *expr) AsLiteral() ref.Val { + if e.Kind() != LiteralKind { + return nil + } + return e.exprKindCase.(*baseLiteral).Val +} + +func (e *expr) AsList() ListExpr { + if e.Kind() != ListKind { + return nilList + } + return e.exprKindCase.(ListExpr) +} + +func (e *expr) AsMap() MapExpr { + if e.Kind() != MapKind { + return nilMap + } + return e.exprKindCase.(MapExpr) +} + +func (e *expr) AsSelect() SelectExpr { + if e.Kind() != SelectKind { + return nilSel + } + return e.exprKindCase.(SelectExpr) +} + +func (e *expr) AsStruct() StructExpr { + if e.Kind() != StructKind { + return nilStruct + } + return e.exprKindCase.(StructExpr) +} + +func (e *expr) SetKindCase(other Expr) { + if e == nil { + return + } + if other == nil { + e.exprKindCase = nil + return + } + switch other.Kind() { + case CallKind: + c := other.AsCall() + e.exprKindCase = &baseCallExpr{ + function: c.FunctionName(), + target: c.Target(), + args: c.Args(), + isMember: c.IsMemberFunction(), + } + case ComprehensionKind: + c := other.AsComprehension() + e.exprKindCase = &baseComprehensionExpr{ + iterRange: c.IterRange(), + iterVar: c.IterVar(), + accuVar: c.AccuVar(), + accuInit: c.AccuInit(), + loopCond: c.LoopCondition(), + loopStep: c.LoopStep(), + result: c.Result(), + } + case IdentKind: + e.exprKindCase = baseIdentExpr(other.AsIdent()) + case ListKind: + l := other.AsList() + optIndexMap := make(map[int32]struct{}, len(l.OptionalIndices())) + for _, idx := range l.OptionalIndices() { + optIndexMap[idx] = struct{}{} + } + e.exprKindCase = &baseListExpr{ + elements: l.Elements(), + optIndices: l.OptionalIndices(), + optIndexMap: optIndexMap, + } + case LiteralKind: + e.exprKindCase = &baseLiteral{Val: other.AsLiteral()} + case MapKind: + e.exprKindCase = &baseMapExpr{ + entries: other.AsMap().Entries(), + } + case SelectKind: + s := other.AsSelect() + e.exprKindCase = &baseSelectExpr{ + operand: s.Operand(), + field: s.FieldName(), + testOnly: s.IsTestOnly(), + } + case StructKind: + s := other.AsStruct() + e.exprKindCase = &baseStructExpr{ + typeName: s.TypeName(), + fields: s.Fields(), + } + case UnspecifiedExprKind: + e.exprKindCase = nil + } +} + +func (e *expr) RenumberIDs(idGen IDGenerator) { + if e == nil { + return + } + e.id = idGen(e.id) + if e.exprKindCase != nil { + e.exprKindCase.renumberIDs(idGen) + } +} + +type baseCallExpr struct { + function string + target Expr + args []Expr + isMember bool +} + +func (*baseCallExpr) Kind() ExprKind { + return CallKind +} + +func (e *baseCallExpr) FunctionName() string { + if e == nil { + return "" + } + return e.function +} + +func (e *baseCallExpr) IsMemberFunction() bool { + if e == nil { + return false + } + return e.isMember +} + +func (e *baseCallExpr) Target() Expr { + if e == nil || !e.IsMemberFunction() { + return nilExpr + } + return e.target +} + +func (e *baseCallExpr) Args() []Expr { + if e == nil { + return []Expr{} + } + return e.args +} + +func (e *baseCallExpr) renumberIDs(idGen IDGenerator) { + if e.IsMemberFunction() { + e.Target().RenumberIDs(idGen) + } + for _, arg := range e.Args() { + arg.RenumberIDs(idGen) + } +} + +func (*baseCallExpr) isExpr() {} + +var _ ComprehensionExpr = &baseComprehensionExpr{} + +type baseComprehensionExpr struct { + iterRange Expr + iterVar string + accuVar string + accuInit Expr + loopCond Expr + loopStep Expr + result Expr +} + +func (*baseComprehensionExpr) Kind() ExprKind { + return ComprehensionKind +} + +func (e *baseComprehensionExpr) IterRange() Expr { + if e == nil { + return nilExpr + } + return e.iterRange +} + +func (e *baseComprehensionExpr) IterVar() string { + return e.iterVar +} + +func (e *baseComprehensionExpr) AccuVar() string { + return e.accuVar +} + +func (e *baseComprehensionExpr) AccuInit() Expr { + if e == nil { + return nilExpr + } + return e.accuInit +} + +func (e *baseComprehensionExpr) LoopCondition() Expr { + if e == nil { + return nilExpr + } + return e.loopCond +} + +func (e *baseComprehensionExpr) LoopStep() Expr { + if e == nil { + return nilExpr + } + return e.loopStep +} + +func (e *baseComprehensionExpr) Result() Expr { + if e == nil { + return nilExpr + } + return e.result +} + +func (e *baseComprehensionExpr) renumberIDs(idGen IDGenerator) { + e.IterRange().RenumberIDs(idGen) + e.AccuInit().RenumberIDs(idGen) + e.LoopCondition().RenumberIDs(idGen) + e.LoopStep().RenumberIDs(idGen) + e.Result().RenumberIDs(idGen) +} + +func (*baseComprehensionExpr) isExpr() {} + +var _ exprKindCase = baseIdentExpr("") + +type baseIdentExpr string + +func (baseIdentExpr) Kind() ExprKind { + return IdentKind +} + +func (e baseIdentExpr) renumberIDs(IDGenerator) {} + +func (baseIdentExpr) isExpr() {} + +var _ exprKindCase = &baseLiteral{} +var _ ref.Val = &baseLiteral{} + +type baseLiteral struct { + ref.Val +} + +func (*baseLiteral) Kind() ExprKind { + return LiteralKind +} + +func (l *baseLiteral) renumberIDs(IDGenerator) {} + +func (*baseLiteral) isExpr() {} + +var _ ListExpr = &baseListExpr{} + +type baseListExpr struct { + elements []Expr + optIndices []int32 + optIndexMap map[int32]struct{} +} + +func (*baseListExpr) Kind() ExprKind { + return ListKind +} + +func (e *baseListExpr) Elements() []Expr { + if e == nil { + return []Expr{} + } + return e.elements +} + +func (e *baseListExpr) IsOptional(index int32) bool { + _, found := e.optIndexMap[index] + return found +} + +func (e *baseListExpr) OptionalIndices() []int32 { + if e == nil { + return []int32{} + } + return e.optIndices +} + +func (e *baseListExpr) Size() int { + return len(e.Elements()) +} + +func (e *baseListExpr) renumberIDs(idGen IDGenerator) { + for _, elem := range e.Elements() { + elem.RenumberIDs(idGen) + } +} + +func (*baseListExpr) isExpr() {} + +type baseMapExpr struct { + entries []EntryExpr +} + +func (*baseMapExpr) Kind() ExprKind { + return MapKind +} + +func (e *baseMapExpr) Entries() []EntryExpr { + if e == nil { + return []EntryExpr{} + } + return e.entries +} + +func (e *baseMapExpr) Size() int { + return len(e.Entries()) +} + +func (e *baseMapExpr) renumberIDs(idGen IDGenerator) { + for _, entry := range e.Entries() { + entry.RenumberIDs(idGen) + } +} + +func (*baseMapExpr) isExpr() {} + +type baseSelectExpr struct { + operand Expr + field string + testOnly bool +} + +func (*baseSelectExpr) Kind() ExprKind { + return SelectKind +} + +func (e *baseSelectExpr) Operand() Expr { + if e == nil || e.operand == nil { + return nilExpr + } + return e.operand +} + +func (e *baseSelectExpr) FieldName() string { + if e == nil { + return "" + } + return e.field +} + +func (e *baseSelectExpr) IsTestOnly() bool { + if e == nil { + return false + } + return e.testOnly +} + +func (e *baseSelectExpr) renumberIDs(idGen IDGenerator) { + e.Operand().RenumberIDs(idGen) +} + +func (*baseSelectExpr) isExpr() {} + +type baseStructExpr struct { + typeName string + fields []EntryExpr +} + +func (*baseStructExpr) Kind() ExprKind { + return StructKind +} + +func (e *baseStructExpr) TypeName() string { + if e == nil { + return "" + } + return e.typeName +} + +func (e *baseStructExpr) Fields() []EntryExpr { + if e == nil { + return []EntryExpr{} + } + return e.fields +} + +func (e *baseStructExpr) renumberIDs(idGen IDGenerator) { + for _, f := range e.Fields() { + f.RenumberIDs(idGen) + } +} + +func (*baseStructExpr) isExpr() {} + +type entryExprKindCase interface { + Kind() EntryExprKind + + renumberIDs(IDGenerator) + + isEntryExpr() +} + +var _ EntryExpr = &entryExpr{} + +type entryExpr struct { + id int64 + entryExprKindCase +} + +func (e *entryExpr) ID() int64 { + return e.id +} + +func (e *entryExpr) AsMapEntry() MapEntry { + if e.Kind() != MapEntryKind { + return nilMapEntry + } + return e.entryExprKindCase.(MapEntry) +} + +func (e *entryExpr) AsStructField() StructField { + if e.Kind() != StructFieldKind { + return nilStructField + } + return e.entryExprKindCase.(StructField) +} + +func (e *entryExpr) RenumberIDs(idGen IDGenerator) { + e.id = idGen(e.id) + e.entryExprKindCase.renumberIDs(idGen) +} + +type baseMapEntry struct { + key Expr + value Expr + isOptional bool +} + +func (e *baseMapEntry) Kind() EntryExprKind { + return MapEntryKind +} + +func (e *baseMapEntry) Key() Expr { + if e == nil { + return nilExpr + } + return e.key +} + +func (e *baseMapEntry) Value() Expr { + if e == nil { + return nilExpr + } + return e.value +} + +func (e *baseMapEntry) IsOptional() bool { + if e == nil { + return false + } + return e.isOptional +} + +func (e *baseMapEntry) renumberIDs(idGen IDGenerator) { + e.Key().RenumberIDs(idGen) + e.Value().RenumberIDs(idGen) +} + +func (*baseMapEntry) isEntryExpr() {} + +type baseStructField struct { + field string + value Expr + isOptional bool +} + +func (f *baseStructField) Kind() EntryExprKind { + return StructFieldKind +} + +func (f *baseStructField) Name() string { + if f == nil { + return "" + } + return f.field +} + +func (f *baseStructField) Value() Expr { + if f == nil { + return nilExpr + } + return f.value +} + +func (f *baseStructField) IsOptional() bool { + if f == nil { + return false + } + return f.isOptional +} + +func (f *baseStructField) renumberIDs(idGen IDGenerator) { + f.Value().RenumberIDs(idGen) +} + +func (*baseStructField) isEntryExpr() {} + +var ( + nilExpr *expr = nil + nilCall *baseCallExpr = nil + nilCompre *baseComprehensionExpr = nil + nilList *baseListExpr = nil + nilMap *baseMapExpr = nil + nilMapEntry *baseMapEntry = nil + nilSel *baseSelectExpr = nil + nilStruct *baseStructExpr = nil + nilStructField *baseStructField = nil +) |
