You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

cel_expression.go 2.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package expr
  18. import (
  19. "github.com/google/cel-go/cel"
  20. )
  21. type CELExpression struct {
  22. env *cel.Env
  23. program cel.Program
  24. expression string
  25. }
  26. // This is used to make sure that the CELExpression implements the Expression interface.
  27. var _ Expression = (*CELExpression)(nil)
  28. // NewCELExpression creates a new CELExpression instance
  29. // by compiling the provided expression.
  30. // how to use cel: https://codelabs.developers.google.com/codelabs/cel-go
  31. func NewCELExpression(expression string) (*CELExpression, error) {
  32. // Create the standard environment.
  33. env, err := cel.NewEnv(
  34. cel.Variable(
  35. "elContext", cel.DynType,
  36. ),
  37. )
  38. if err != nil {
  39. return nil, err
  40. }
  41. // Check that the expression compiles and returns a String.
  42. ast, issues := env.Compile(expression)
  43. // Report syntax errors, if present.
  44. if issues != nil && issues.Err() != nil {
  45. return nil, issues.Err()
  46. }
  47. // Type-check the expression ofr correctness.
  48. checkedAst, issues := env.Check(ast)
  49. if issues.Err() != nil {
  50. return nil, issues.Err()
  51. }
  52. program, err := env.Program(checkedAst)
  53. if err != nil {
  54. return nil, err
  55. }
  56. CELExpression := &CELExpression{
  57. env: env,
  58. program: program,
  59. expression: expression,
  60. }
  61. return CELExpression, nil
  62. }
  63. // Value evaluates the expression with the provided context and returns the result.
  64. func (c *CELExpression) Value(elContext any) any {
  65. result, _, err := c.program.Eval(map[string]any{
  66. "elContext": elContext,
  67. })
  68. if err != nil {
  69. return err
  70. }
  71. return result.Value()
  72. }
  73. // TODO: I think this is not needed.
  74. // I see seata-java doesn't use this method.
  75. // Do we need to implement this?
  76. func (c *CELExpression) SetValue(val any, elContext any) {
  77. panic("implement me")
  78. }
  79. // ExpressionString returns the expression string.
  80. func (c *CELExpression) ExpressionString() string {
  81. return c.expression
  82. }