123 lines
3.7 KiB
Go
123 lines
3.7 KiB
Go
// Copyright 2019 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 cel
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/google/cel-go/common"
|
|
"github.com/google/cel-go/parser"
|
|
|
|
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
|
)
|
|
|
|
// CheckedExprToAst converts a checked expression proto message to an Ast.
|
|
func CheckedExprToAst(checkedExpr *exprpb.CheckedExpr) *Ast {
|
|
return CheckedExprToAstWithSource(checkedExpr, nil)
|
|
}
|
|
|
|
// CheckedExprToAstWithSource converts a checked expression proto message to an Ast,
|
|
// using the provided Source as the textual contents.
|
|
//
|
|
// In general the source is not necessary unless the AST has been modified between the
|
|
// `Parse` and `Check` calls as an `Ast` created from the `Parse` step will carry the source
|
|
// through future calls.
|
|
//
|
|
// Prefer CheckedExprToAst if loading expressions from storage.
|
|
func CheckedExprToAstWithSource(checkedExpr *exprpb.CheckedExpr, src common.Source) *Ast {
|
|
refMap := checkedExpr.GetReferenceMap()
|
|
if refMap == nil {
|
|
refMap = map[int64]*exprpb.Reference{}
|
|
}
|
|
typeMap := checkedExpr.GetTypeMap()
|
|
if typeMap == nil {
|
|
typeMap = map[int64]*exprpb.Type{}
|
|
}
|
|
si := checkedExpr.GetSourceInfo()
|
|
if si == nil {
|
|
si = &exprpb.SourceInfo{}
|
|
}
|
|
if src == nil {
|
|
src = common.NewInfoSource(si)
|
|
}
|
|
return &Ast{
|
|
expr: checkedExpr.GetExpr(),
|
|
info: si,
|
|
source: src,
|
|
refMap: refMap,
|
|
typeMap: typeMap,
|
|
}
|
|
}
|
|
|
|
// AstToCheckedExpr converts an Ast to an protobuf CheckedExpr value.
|
|
//
|
|
// If the Ast.IsChecked() returns false, this conversion method will return an error.
|
|
func AstToCheckedExpr(a *Ast) (*exprpb.CheckedExpr, error) {
|
|
if !a.IsChecked() {
|
|
return nil, fmt.Errorf("cannot convert unchecked ast")
|
|
}
|
|
return &exprpb.CheckedExpr{
|
|
Expr: a.Expr(),
|
|
SourceInfo: a.SourceInfo(),
|
|
ReferenceMap: a.refMap,
|
|
TypeMap: a.typeMap,
|
|
}, nil
|
|
}
|
|
|
|
// ParsedExprToAst converts a parsed expression proto message to an Ast.
|
|
func ParsedExprToAst(parsedExpr *exprpb.ParsedExpr) *Ast {
|
|
return ParsedExprToAstWithSource(parsedExpr, nil)
|
|
}
|
|
|
|
// ParsedExprToAstWithSource converts a parsed expression proto message to an Ast,
|
|
// using the provided Source as the textual contents.
|
|
//
|
|
// In general you only need this if you need to recheck a previously checked
|
|
// expression, or if you need to separately check a subset of an expression.
|
|
//
|
|
// Prefer ParsedExprToAst if loading expressions from storage.
|
|
func ParsedExprToAstWithSource(parsedExpr *exprpb.ParsedExpr, src common.Source) *Ast {
|
|
si := parsedExpr.GetSourceInfo()
|
|
if si == nil {
|
|
si = &exprpb.SourceInfo{}
|
|
}
|
|
if src == nil {
|
|
src = common.NewInfoSource(si)
|
|
}
|
|
return &Ast{
|
|
expr: parsedExpr.GetExpr(),
|
|
info: si,
|
|
source: src,
|
|
}
|
|
}
|
|
|
|
// AstToParsedExpr converts an Ast to an protobuf ParsedExpr value.
|
|
func AstToParsedExpr(a *Ast) (*exprpb.ParsedExpr, error) {
|
|
return &exprpb.ParsedExpr{
|
|
Expr: a.Expr(),
|
|
SourceInfo: a.SourceInfo(),
|
|
}, nil
|
|
}
|
|
|
|
// AstToString converts an Ast back to a string if possible.
|
|
//
|
|
// Note, the conversion may not be an exact replica of the original expression, but will produce
|
|
// a string that is semantically equivalent and whose textual representation is stable.
|
|
func AstToString(a *Ast) (string, error) {
|
|
expr := a.Expr()
|
|
info := a.SourceInfo()
|
|
return parser.Unparse(expr, info)
|
|
}
|