This is an automated email from the ASF dual-hosted git repository.

zfeng pushed a commit to branch feature/saga
in repository https://gitbox.apache.org/repos/asf/incubator-seata-go.git


The following commit(s) were added to refs/heads/feature/saga by this push:
     new 8e84b0ef Feat cel expression (#788)
8e84b0ef is described below

commit 8e84b0ef2cdc66bb552bd4f9e46f6b57f6c1db00
Author: marsevilspirit <marsevilspi...@gmail.com>
AuthorDate: Sat May 10 18:55:42 2025 +0800

    Feat cel expression (#788)
    
    * implement cel expression
    
    * move sequence expression into a new file
    
    * mv expression factory into a new file
    
    * move expression factory manager into a new file
    
    * implement cel expression factory and add test
    
    * move expression resolver into a new file
    
    * add parse expression struct test
    
    * update
    
    * update go.mod
    
    ---------
    
    Co-authored-by: FengZhang <zfc...@qq.com>
---
 go.mod                                             |  25 +++--
 go.sum                                             |  43 ++++++---
 .../statemachine/engine/expr/cel_expression.go     |  96 +++++++++++++++++++
 .../engine/expr/cel_expression_factory.go          |  36 +++++++
 .../engine/expr/cel_expression_factory_test.go     |  31 ++++++
 .../engine/expr/cel_expression_test.go             |  42 +++++++++
 pkg/saga/statemachine/engine/expr/expression.go    |  92 ++----------------
 .../statemachine/engine/expr/expression_factory.go |  22 +++++
 ...expression.go => expression_factory_manager.go} |  66 +------------
 .../engine/expr/expression_resolver.go             | 105 +++++++++++++++++++++
 .../engine/expr/expression_resolver_test.go        |  53 +++++++++++
 .../expr/{expression.go => sequence_expression.go} |  48 +---------
 12 files changed, 438 insertions(+), 221 deletions(-)

diff --git a/go.mod b/go.mod
index c927882f..feb9bfb8 100644
--- a/go.mod
+++ b/go.mod
@@ -25,7 +25,7 @@ require (
        github.com/stretchr/testify v1.8.3
        go.uber.org/atomic v1.9.0
        go.uber.org/zap v1.21.0
-       google.golang.org/grpc v1.51.0
+       google.golang.org/grpc v1.57.0
        gopkg.in/yaml.v2 v2.4.0
        vimagination.zapto.org/byteio v0.0.0-20200222190125-d27cba0f0b10
 )
@@ -33,20 +33,23 @@ require (
 require (
        github.com/agiledragon/gomonkey v2.0.2+incompatible
        github.com/agiledragon/gomonkey/v2 v2.9.0
+       github.com/google/cel-go v0.18.0
        github.com/mattn/go-sqlite3 v1.14.19
        golang.org/x/sync v0.6.0
-       google.golang.org/protobuf v1.30.0
+       google.golang.org/protobuf v1.33.0
+       gopkg.in/yaml.v3 v3.0.1
 )
 
 require (
        github.com/RoaringBitmap/roaring v1.2.0 // indirect
        github.com/Workiva/go-datastructures v1.0.52 // indirect
+       github.com/antlr/antlr4/runtime/Go/antlr/v4 
v4.0.0-20230305170008-8188dc5388df // indirect
        github.com/apache/dubbo-go-hessian2 v1.11.4 // indirect
        github.com/benbjohnson/clock v1.1.0 // indirect
        github.com/beorn7/perks v1.0.1 // indirect
        github.com/bits-and-blooms/bitset v1.2.0 // indirect
        github.com/bytedance/sonic v1.9.1 // indirect
-       github.com/cespare/xxhash/v2 v2.1.2 // indirect
+       github.com/cespare/xxhash/v2 v2.3.0 // indirect
        github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // 
indirect
        github.com/creasty/defaults v1.5.2 // indirect
        github.com/davecgh/go-spew v1.1.1 // indirect
@@ -55,7 +58,7 @@ require (
        github.com/go-ole/go-ole v1.2.6 // indirect
        github.com/go-playground/locales v0.14.1 // indirect
        github.com/go-playground/universal-translator v0.18.1 // indirect
-       github.com/golang/protobuf v1.5.2 // indirect
+       github.com/golang/protobuf v1.5.4 // indirect
        github.com/golang/snappy v0.0.4 // indirect
        github.com/gorilla/websocket v1.4.2 // indirect
        github.com/jinzhu/copier v0.3.5 // indirect
@@ -76,10 +79,11 @@ require (
        github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 // 
indirect
        github.com/pmezard/go-difflib v1.0.0 // indirect
        github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // 
indirect
-       github.com/prometheus/client_model v0.2.0 // indirect
+       github.com/prometheus/client_model v0.3.0 // indirect
        github.com/prometheus/procfs v0.7.3 // indirect
        github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b // 
indirect
        github.com/shirou/gopsutil/v3 v3.22.2 // indirect
+       github.com/stoewer/go-strcase v1.2.0 // indirect
        github.com/tklauser/go-sysconf v0.3.10 // indirect
        github.com/tklauser/numcpus v0.4.0 // indirect
        github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
@@ -87,9 +91,11 @@ require (
        github.com/yusufpapurcu/wmi v1.2.2 // indirect
        go.uber.org/multierr v1.8.0 // indirect
        golang.org/x/arch v0.3.0 // indirect
+       golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 // indirect
        golang.org/x/text v0.14.0 // indirect
+       google.golang.org/genproto/googleapis/api 
v0.0.0-20230803162519-f966b187b2e5 // indirect
+       google.golang.org/genproto/googleapis/rpc 
v0.0.0-20230803162519-f966b187b2e5 // indirect
        gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
-       gopkg.in/yaml.v3 v3.0.1 // indirect
 )
 
 require (
@@ -100,10 +106,9 @@ require (
        github.com/mattn/go-isatty v0.0.19 // indirect
        github.com/pelletier/go-toml v1.9.3 // indirect
        github.com/pingcap/log v0.0.0-20210906054005-afc726e70354 // indirect
-       golang.org/x/crypto v0.17.0 // indirect
-       golang.org/x/net v0.10.0 // indirect
-       golang.org/x/sys v0.15.0 // indirect
-       google.golang.org/genproto v0.0.0-20220630174209-ad1d48641aa7 // 
indirect
+       golang.org/x/crypto v0.19.0 // indirect
+       golang.org/x/net v0.21.0 // indirect
+       golang.org/x/sys v0.17.0 // indirect
        vimagination.zapto.org/memio v0.0.0-20200222190306-588ebc67b97d // 
indirect
 )
 
diff --git a/go.sum b/go.sum
index e269c87d..fae6c71b 100644
--- a/go.sum
+++ b/go.sum
@@ -67,6 +67,8 @@ github.com/alecthomas/units 
v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5
 github.com/alibaba/sentinel-golang v1.0.4/go.mod 
h1:Lag5rIYyJiPOylK8Kku2P+a23gdKMMqzQS7wTnjWEpk=
 github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod 
h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk=
 github.com/antihax/optional v1.0.0/go.mod 
h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
+github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df 
h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18=
+github.com/antlr/antlr4/runtime/Go/antlr/v4 
v4.0.0-20230305170008-8188dc5388df/go.mod 
h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
 github.com/apache/dubbo-getty v1.4.9-0.20221022181821-4dc6252ce98c/go.mod 
h1:6qmrqBSPGs3B35zwEuGhEYNVsx1nfGT/xzV2yOt2amM=
 github.com/apache/dubbo-getty v1.4.10-0.20230731065302-7c0f0039e59c 
h1:e1pJKY0lFvO6rik7m3qmpMRA98cc9Zkg6AJeB1/7QFQ=
 github.com/apache/dubbo-getty v1.4.10-0.20230731065302-7c0f0039e59c/go.mod 
h1:TqHfi87Ufv7wpwI7nER5Kx8FCb/jjwlyazxiYwEmTs8=
@@ -119,8 +121,9 @@ github.com/census-instrumentation/opencensus-proto 
v0.2.1/go.mod h1:f6KPmirojxKA
 github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod 
h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
 github.com/cespare/xxhash v1.1.0/go.mod 
h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod 
h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cespare/xxhash/v2 v2.1.2 
h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
 github.com/cespare/xxhash/v2 v2.1.2/go.mod 
h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.3.0 
h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod 
h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod 
h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
 github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 
h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
 github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod 
h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
@@ -304,14 +307,17 @@ github.com/golang/protobuf v1.4.1/go.mod 
h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
 github.com/golang/protobuf v1.4.2/go.mod 
h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.4.3/go.mod 
h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.5.0/go.mod 
h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2 
h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
 github.com/golang/protobuf v1.5.2/go.mod 
h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.4 
h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod 
h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod 
h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.1/go.mod 
h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 github.com/golang/snappy v0.0.4/go.mod 
h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod 
h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod 
h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/cel-go v0.18.0 
h1:u74MPiEC8mejBrkXqrTWT102g5IFEUjxOngzQIijMzU=
+github.com/google/cel-go v0.18.0/go.mod 
h1:PVAybmSnWkNMUZR/tEWFUiJ1Np4Hz0MHsZJcgC4zln4=
 github.com/google/go-cmp v0.2.0/go.mod 
h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0/go.mod 
h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod 
h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -637,8 +643,9 @@ github.com/prometheus/client_model 
v0.0.0-20190115171406-56726106282f/go.mod h1:
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod 
h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod 
h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.1.0/go.mod 
h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.2.0 
h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
 github.com/prometheus/client_model v0.2.0/go.mod 
h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.3.0 
h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
+github.com/prometheus/client_model v0.3.0/go.mod 
h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
 github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod 
h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
 github.com/prometheus/common v0.2.0/go.mod 
h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/common v0.4.0/go.mod 
h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
@@ -708,6 +715,8 @@ github.com/spf13/pflag v1.0.3/go.mod 
h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod 
h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/spf13/viper v1.7.0/go.mod 
h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
+github.com/stoewer/go-strcase v1.2.0 
h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
+github.com/stoewer/go-strcase v1.2.0/go.mod 
h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
 github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod 
h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
 github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod 
h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod 
h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
@@ -831,8 +840,8 @@ golang.org/x/crypto 
v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod 
h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod 
h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod 
h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
-golang.org/x/crypto v0.17.0/go.mod 
h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
+golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
+golang.org/x/crypto v0.19.0/go.mod 
h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
 golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod 
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod 
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod 
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -848,6 +857,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod 
h1:2RIsYlXP63K8oxa1u0
 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod 
h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
 golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod 
h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
 golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod 
h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
+golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 
h1:tnebWN09GYg9OLPss1KXj8txwZc6X6uMr6VFdcGNbHw=
+golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod 
h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
 golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod 
h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod 
h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod 
h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@@ -921,8 +932,8 @@ golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod 
h1:9nx3DQGgdP8bBQD5qx
 golang.org/x/net v0.0.0-20211105192438-b53810dc28af/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod 
h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod 
h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod 
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod 
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1021,8 +1032,8 @@ golang.org/x/sys 
v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
-golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
+golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod 
h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod 
h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod 
h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1171,8 +1182,10 @@ google.golang.org/genproto 
v0.0.0-20210106152847-07624b53cd92/go.mod h1:FWY/as6D
 google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod 
h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
 google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247/go.mod 
h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
 google.golang.org/genproto v0.0.0-20220504150022-98cd25cafc72/go.mod 
h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
-google.golang.org/genproto v0.0.0-20220630174209-ad1d48641aa7 
h1:q4zUJDd0+knPFB9x20S3vnxzlYNBbt8Yd7zBMVMteeM=
-google.golang.org/genproto v0.0.0-20220630174209-ad1d48641aa7/go.mod 
h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
+google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 
h1:nIgk/EEq3/YlnmVVXVnm14rC2oxgs1o0ong4sD/rd44=
+google.golang.org/genproto/googleapis/api 
v0.0.0-20230803162519-f966b187b2e5/go.mod 
h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 
h1:eSaPbMR4T7WfH9FvABk36NBMacoTUKdWCvV0dx+KfOg=
+google.golang.org/genproto/googleapis/rpc 
v0.0.0-20230803162519-f966b187b2e5/go.mod 
h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I=
 google.golang.org/grpc v1.8.0/go.mod 
h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.14.0/go.mod 
h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.17.0/go.mod 
h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
@@ -1201,10 +1214,10 @@ google.golang.org/grpc v1.38.0/go.mod 
h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ
 google.golang.org/grpc v1.40.0/go.mod 
h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
 google.golang.org/grpc v1.41.0/go.mod 
h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
 google.golang.org/grpc v1.46.0/go.mod 
h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.47.0/go.mod 
h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
 google.golang.org/grpc v1.48.0/go.mod 
h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U=
 google.golang.org/grpc v1.51.0/go.mod 
h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
+google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
+google.golang.org/grpc v1.57.0/go.mod 
h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod 
h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod 
h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod 
h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -1220,8 +1233,8 @@ google.golang.org/protobuf v1.26.0/go.mod 
h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
 google.golang.org/protobuf v1.27.1/go.mod 
h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.28.0/go.mod 
h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.28.1/go.mod 
h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-google.golang.org/protobuf v1.30.0 
h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
-google.golang.org/protobuf v1.30.0/go.mod 
h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.33.0 
h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod 
h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod 
h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod 
h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod 
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/pkg/saga/statemachine/engine/expr/cel_expression.go 
b/pkg/saga/statemachine/engine/expr/cel_expression.go
new file mode 100644
index 00000000..675e0c72
--- /dev/null
+++ b/pkg/saga/statemachine/engine/expr/cel_expression.go
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 expr
+
+import (
+       "github.com/google/cel-go/cel"
+)
+
+type CELExpression struct {
+       env        *cel.Env
+       program    cel.Program
+       expression string
+}
+
+// This is used to make sure that the CELExpression implements the Expression 
interface.
+var _ Expression = (*CELExpression)(nil)
+
+// NewCELExpression creates a new CELExpression instance
+// by compiling the provided expression.
+// how to use cel: https://codelabs.developers.google.com/codelabs/cel-go
+func NewCELExpression(expression string) (*CELExpression, error) {
+       // Create the standard environment.
+       env, err := cel.NewEnv(
+               cel.Variable(
+                       "elContext", cel.DynType,
+               ),
+       )
+
+       if err != nil {
+               return nil, err
+       }
+
+       // Check that the expression compiles and returns a String.
+       ast, issues := env.Compile(expression)
+       // Report syntax errors, if present.
+       if issues != nil && issues.Err() != nil {
+               return nil, issues.Err()
+       }
+
+       // Type-check the expression ofr correctness.
+       checkedAst, issues := env.Check(ast)
+       if issues.Err() != nil {
+               return nil, issues.Err()
+       }
+
+       program, err := env.Program(checkedAst)
+       if err != nil {
+               return nil, err
+       }
+
+       CELExpression := &CELExpression{
+               env:        env,
+               program:    program,
+               expression: expression,
+       }
+
+       return CELExpression, nil
+}
+
+// Value evaluates the expression with the provided context and returns the 
result.
+func (c *CELExpression) Value(elContext any) any {
+       result, _, err := c.program.Eval(map[string]any{
+               "elContext": elContext,
+       })
+       if err != nil {
+               return err
+       }
+       return result.Value()
+}
+
+// TODO: I think this is not needed.
+// I see seata-java doesn't use this method.
+// Do we need to implement this?
+func (c *CELExpression) SetValue(val any, elContext any) {
+       panic("implement me")
+}
+
+// ExpressionString returns the expression string.
+func (c *CELExpression) ExpressionString() string {
+       return c.expression
+}
diff --git a/pkg/saga/statemachine/engine/expr/cel_expression_factory.go 
b/pkg/saga/statemachine/engine/expr/cel_expression_factory.go
new file mode 100644
index 00000000..dcdc7d67
--- /dev/null
+++ b/pkg/saga/statemachine/engine/expr/cel_expression_factory.go
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 expr
+
+type CELExpressionFactory struct {
+       expr *CELExpression
+}
+
+// This is used to make sure that CELExpressionFactory implements 
ExpressionFactory
+var _ ExpressionFactory = (*CELExpressionFactory)(nil)
+
+// NewCELExpressionFactory creates a new instance of CELExpressionFactory
+func NewCELExpressionFactory() *CELExpressionFactory {
+       return &CELExpressionFactory{}
+}
+
+// CreateExpression creates a new instance of CELExpression
+func (f *CELExpressionFactory) CreateExpression(expression string) Expression {
+       f.expr, _ = NewCELExpression(expression)
+       return f.expr
+}
diff --git a/pkg/saga/statemachine/engine/expr/cel_expression_factory_test.go 
b/pkg/saga/statemachine/engine/expr/cel_expression_factory_test.go
new file mode 100644
index 00000000..a84fe48c
--- /dev/null
+++ b/pkg/saga/statemachine/engine/expr/cel_expression_factory_test.go
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 expr
+
+import (
+       "testing"
+
+       "github.com/stretchr/testify/assert"
+)
+
+func TestCelExpressionFactory(t *testing.T) {
+       factory := NewCELExpressionFactory()
+       expression := factory.CreateExpression("'Hello' + ' World!'")
+       value := expression.Value(nil)
+       assert.Equal(t, "Hello World!", value, "Expected 'Hello World!'")
+}
diff --git a/pkg/saga/statemachine/engine/expr/cel_expression_test.go 
b/pkg/saga/statemachine/engine/expr/cel_expression_test.go
new file mode 100644
index 00000000..1c3f05da
--- /dev/null
+++ b/pkg/saga/statemachine/engine/expr/cel_expression_test.go
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 expr
+
+import (
+       "testing"
+
+       "github.com/stretchr/testify/assert"
+)
+
+func TestValueWithNil(t *testing.T) {
+       expr, err := NewCELExpression("'Hello' + ' World!'")
+       assert.NoError(t, err, "Error creating expression")
+       value := expr.Value(nil)
+       assert.Equal(t, "Hello World!", value, "Expected 'Hello World!'")
+}
+
+func TestValue(t *testing.T) {
+       expr, err := NewCELExpression("elContext['name'] + ' World!'")
+       assert.NoError(t, err, "Error creating expression")
+       elContext := map[string]any{
+               "name": "Hello",
+       }
+
+       value := expr.Value(elContext)
+       assert.Equal(t, "Hello World!", value, "Expected 'Hello World!'")
+}
diff --git a/pkg/saga/statemachine/engine/expr/expression.go 
b/pkg/saga/statemachine/engine/expr/expression.go
index 00441d1f..343ea1be 100644
--- a/pkg/saga/statemachine/engine/expr/expression.go
+++ b/pkg/saga/statemachine/engine/expr/expression.go
@@ -17,94 +17,14 @@
 
 package expr
 
-import (
-       "github.com/seata/seata-go/pkg/saga/statemachine/engine/sequence"
-       "strings"
-)
-
-const DefaultExpressionType string = "Default"
-
-type ExpressionResolver interface {
-       Expression(expressionStr string) Expression
-       ExpressionFactoryManager() ExpressionFactoryManager
-       SetExpressionFactoryManager(expressionFactoryManager 
ExpressionFactoryManager)
-}
-
+// expression interface
 type Expression interface {
+       // get the value of the expression
+       // elContext is the el context
        Value(elContext any) any
-       SetValue(value any, elContext any)
-       ExpressionString() string
-}
-
-type ExpressionFactory interface {
-       CreateExpression(expression string) Expression
-}
-
-type ExpressionFactoryManager struct {
-       expressionFactoryMap map[string]ExpressionFactory
-}
-
-func NewExpressionFactoryManager() *ExpressionFactoryManager {
-       return &ExpressionFactoryManager{
-               expressionFactoryMap: make(map[string]ExpressionFactory),
-       }
-}
-
-func (e *ExpressionFactoryManager) GetExpressionFactory(expressionType string) 
ExpressionFactory {
-       if strings.TrimSpace(expressionType) == "" {
-               expressionType = DefaultExpressionType
-       }
-       return e.expressionFactoryMap[expressionType]
-}
 
-func (e *ExpressionFactoryManager) 
SetExpressionFactoryMap(expressionFactoryMap map[string]ExpressionFactory) {
-       for k, v := range expressionFactoryMap {
-               e.expressionFactoryMap[k] = v
-       }
-}
-
-func (e *ExpressionFactoryManager) PutExpressionFactory(expressionType string, 
factory ExpressionFactory) {
-       e.expressionFactoryMap[expressionType] = factory
-}
-
-type SequenceExpression struct {
-       seqGenerator sequence.SeqGenerator
-       entity       string
-       rule         string
-}
-
-func (s *SequenceExpression) SeqGenerator() sequence.SeqGenerator {
-       return s.seqGenerator
-}
-
-func (s *SequenceExpression) SetSeqGenerator(seqGenerator 
sequence.SeqGenerator) {
-       s.seqGenerator = seqGenerator
-}
-
-func (s *SequenceExpression) Entity() string {
-       return s.entity
-}
-
-func (s *SequenceExpression) SetEntity(entity string) {
-       s.entity = entity
-}
-
-func (s *SequenceExpression) Rule() string {
-       return s.rule
-}
-
-func (s *SequenceExpression) SetRule(rule string) {
-       s.rule = rule
-}
-
-func (s SequenceExpression) Value(elContext any) any {
-       return s.seqGenerator.GenerateId(s.entity, s.rule)
-}
-
-func (s SequenceExpression) SetValue(value any, elContext any) {
-
-}
+       SetValue(value any, elContext any)
 
-func (s SequenceExpression) ExpressionString() string {
-       return s.entity + "|" + s.rule
+       // return the expression string
+       ExpressionString() string
 }
diff --git a/pkg/saga/statemachine/engine/expr/expression_factory.go 
b/pkg/saga/statemachine/engine/expr/expression_factory.go
new file mode 100644
index 00000000..b785775a
--- /dev/null
+++ b/pkg/saga/statemachine/engine/expr/expression_factory.go
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 expr
+
+type ExpressionFactory interface {
+       CreateExpression(expression string) Expression
+}
diff --git a/pkg/saga/statemachine/engine/expr/expression.go 
b/pkg/saga/statemachine/engine/expr/expression_factory_manager.go
similarity index 52%
copy from pkg/saga/statemachine/engine/expr/expression.go
copy to pkg/saga/statemachine/engine/expr/expression_factory_manager.go
index 00441d1f..82e3f04d 100644
--- a/pkg/saga/statemachine/engine/expr/expression.go
+++ b/pkg/saga/statemachine/engine/expr/expression_factory_manager.go
@@ -18,27 +18,11 @@
 package expr
 
 import (
-       "github.com/seata/seata-go/pkg/saga/statemachine/engine/sequence"
+       "maps"
        "strings"
 )
 
-const DefaultExpressionType string = "Default"
-
-type ExpressionResolver interface {
-       Expression(expressionStr string) Expression
-       ExpressionFactoryManager() ExpressionFactoryManager
-       SetExpressionFactoryManager(expressionFactoryManager 
ExpressionFactoryManager)
-}
-
-type Expression interface {
-       Value(elContext any) any
-       SetValue(value any, elContext any)
-       ExpressionString() string
-}
-
-type ExpressionFactory interface {
-       CreateExpression(expression string) Expression
-}
+const DefaultExpressionType = "Default"
 
 type ExpressionFactoryManager struct {
        expressionFactoryMap map[string]ExpressionFactory
@@ -58,53 +42,9 @@ func (e *ExpressionFactoryManager) 
GetExpressionFactory(expressionType string) E
 }
 
 func (e *ExpressionFactoryManager) 
SetExpressionFactoryMap(expressionFactoryMap map[string]ExpressionFactory) {
-       for k, v := range expressionFactoryMap {
-               e.expressionFactoryMap[k] = v
-       }
+       maps.Copy(e.expressionFactoryMap, expressionFactoryMap)
 }
 
 func (e *ExpressionFactoryManager) PutExpressionFactory(expressionType string, 
factory ExpressionFactory) {
        e.expressionFactoryMap[expressionType] = factory
 }
-
-type SequenceExpression struct {
-       seqGenerator sequence.SeqGenerator
-       entity       string
-       rule         string
-}
-
-func (s *SequenceExpression) SeqGenerator() sequence.SeqGenerator {
-       return s.seqGenerator
-}
-
-func (s *SequenceExpression) SetSeqGenerator(seqGenerator 
sequence.SeqGenerator) {
-       s.seqGenerator = seqGenerator
-}
-
-func (s *SequenceExpression) Entity() string {
-       return s.entity
-}
-
-func (s *SequenceExpression) SetEntity(entity string) {
-       s.entity = entity
-}
-
-func (s *SequenceExpression) Rule() string {
-       return s.rule
-}
-
-func (s *SequenceExpression) SetRule(rule string) {
-       s.rule = rule
-}
-
-func (s SequenceExpression) Value(elContext any) any {
-       return s.seqGenerator.GenerateId(s.entity, s.rule)
-}
-
-func (s SequenceExpression) SetValue(value any, elContext any) {
-
-}
-
-func (s SequenceExpression) ExpressionString() string {
-       return s.entity + "|" + s.rule
-}
diff --git a/pkg/saga/statemachine/engine/expr/expression_resolver.go 
b/pkg/saga/statemachine/engine/expr/expression_resolver.go
new file mode 100644
index 00000000..d7841021
--- /dev/null
+++ b/pkg/saga/statemachine/engine/expr/expression_resolver.go
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 expr
+
+import (
+       "errors"
+       "strings"
+)
+
+type ExpressionResolver interface {
+       Expression(expressionStr string) Expression
+       ExpressionFactoryManager() ExpressionFactoryManager
+       SetExpressionFactoryManager(expressionFactoryManager 
ExpressionFactoryManager)
+}
+
+type DefaultExpressionResolver struct {
+       expressionFactoryManager ExpressionFactoryManager
+}
+
+func (resolver *DefaultExpressionResolver) Expression(expressionStr string) 
Expression {
+       expressionStruct, err := parseExpressionStruct(expressionStr)
+       if err != nil {
+               return nil
+       }
+       expressionFactory := 
resolver.expressionFactoryManager.GetExpressionFactory(expressionStruct.typ)
+       if expressionFactory == nil {
+               return nil
+       }
+       return expressionFactory.CreateExpression(expressionStruct.content)
+}
+
+func (resolver *DefaultExpressionResolver) ExpressionFactoryManager() 
ExpressionFactoryManager {
+       return resolver.expressionFactoryManager
+}
+
+func (resolver *DefaultExpressionResolver) 
SetExpressionFactoryManager(expressionFactoryManager ExpressionFactoryManager) {
+       resolver.expressionFactoryManager = expressionFactoryManager
+}
+
+type ExpressionStruct struct {
+       typeStart int
+       typeEnd   int
+       end       int
+       typ       string
+       content   string
+}
+
+// old style: $type{content}
+// new style: $type.content
+func parseExpressionStruct(expressionStr string) (*ExpressionStruct, error) {
+       eStruct := &ExpressionStruct{}
+       eStruct.typeStart = strings.Index(expressionStr, "$")
+       if eStruct.typeStart == -1 {
+               return nil, errors.New("invalid expression")
+       }
+
+       dot := strings.Index(expressionStr, ".")
+       leftBracket := strings.Index(expressionStr, "{")
+
+       isOldEvaluatorStyle := false
+       if eStruct.typeStart == 0 {
+               if leftBracket < 0 && dot < 0 {
+                       return nil, errors.New("invalid expression")
+               }
+               // Backward compatible for structure: 
$expressionType{expressionContent}
+               if leftBracket > 0 && (leftBracket < dot || dot < 0) {
+                       eStruct.typeEnd = leftBracket
+                       isOldEvaluatorStyle = true
+               }
+               if dot > 0 && (dot < leftBracket || leftBracket < 0) {
+                       eStruct.typeEnd = dot
+               }
+       }
+
+       if eStruct.typeStart == 0 && leftBracket != -1 && leftBracket < dot {
+               // Backward compatible for structure: 
$expressionType{expressionContent}
+               eStruct.typeEnd = strings.Index(expressionStr, "{")
+               isOldEvaluatorStyle = true
+       }
+
+       eStruct.typ = expressionStr[eStruct.typeStart+1 : eStruct.typeEnd]
+
+       if isOldEvaluatorStyle {
+               eStruct.end = strings.Index(expressionStr, "}")
+       } else {
+               eStruct.end = len(expressionStr)
+       }
+       eStruct.content = expressionStr[eStruct.typeEnd+1 : eStruct.end]
+       return eStruct, nil
+}
diff --git a/pkg/saga/statemachine/engine/expr/expression_resolver_test.go 
b/pkg/saga/statemachine/engine/expr/expression_resolver_test.go
new file mode 100644
index 00000000..f518a425
--- /dev/null
+++ b/pkg/saga/statemachine/engine/expr/expression_resolver_test.go
@@ -0,0 +1,53 @@
+package expr
+
+import (
+       "testing"
+
+       "github.com/stretchr/testify/assert"
+)
+
+func TestParseExpressionStruct(t *testing.T) {
+       tests := []struct {
+               expressionStr string
+               expected      *ExpressionStruct
+               expectError   bool
+       }{
+               {
+                       expressionStr: "$type{content}",
+                       expected: &ExpressionStruct{
+                               typeStart: 0,
+                               typeEnd:   5,
+                               typ:       "type",
+                               end:       13,
+                               content:   "content",
+                       },
+                       expectError: false,
+               },
+               {
+                       expressionStr: "$type.content",
+                       expected: &ExpressionStruct{
+                               typeStart: 0,
+                               typeEnd:   5,
+                               typ:       "type",
+                               end:       13,
+                               content:   "content",
+                       },
+                       expectError: false,
+               },
+               {
+                       expressionStr: "invalid expression",
+                       expected:      nil,
+                       expectError:   true,
+               },
+       }
+       for _, test := range tests {
+               result, err := parseExpressionStruct(test.expressionStr)
+               if test.expectError {
+                       assert.Error(t, err, "Expected an error for input 
'%s'", test.expressionStr)
+               } else {
+                       assert.NoError(t, err, "Did not expect an error for 
input '%s'", test.expressionStr)
+                       assert.NotNil(t, result, "Expected a non-nil result for 
input '%s'", test.expressionStr)
+                       assert.Equal(t, *test.expected, *result, "Expected 
result %+v, got %+v for input '%s'", test.expected, result, test.expressionStr)
+               }
+       }
+}
diff --git a/pkg/saga/statemachine/engine/expr/expression.go 
b/pkg/saga/statemachine/engine/expr/sequence_expression.go
similarity index 55%
copy from pkg/saga/statemachine/engine/expr/expression.go
copy to pkg/saga/statemachine/engine/expr/sequence_expression.go
index 00441d1f..d6509252 100644
--- a/pkg/saga/statemachine/engine/expr/expression.go
+++ b/pkg/saga/statemachine/engine/expr/sequence_expression.go
@@ -19,54 +19,8 @@ package expr
 
 import (
        "github.com/seata/seata-go/pkg/saga/statemachine/engine/sequence"
-       "strings"
 )
 
-const DefaultExpressionType string = "Default"
-
-type ExpressionResolver interface {
-       Expression(expressionStr string) Expression
-       ExpressionFactoryManager() ExpressionFactoryManager
-       SetExpressionFactoryManager(expressionFactoryManager 
ExpressionFactoryManager)
-}
-
-type Expression interface {
-       Value(elContext any) any
-       SetValue(value any, elContext any)
-       ExpressionString() string
-}
-
-type ExpressionFactory interface {
-       CreateExpression(expression string) Expression
-}
-
-type ExpressionFactoryManager struct {
-       expressionFactoryMap map[string]ExpressionFactory
-}
-
-func NewExpressionFactoryManager() *ExpressionFactoryManager {
-       return &ExpressionFactoryManager{
-               expressionFactoryMap: make(map[string]ExpressionFactory),
-       }
-}
-
-func (e *ExpressionFactoryManager) GetExpressionFactory(expressionType string) 
ExpressionFactory {
-       if strings.TrimSpace(expressionType) == "" {
-               expressionType = DefaultExpressionType
-       }
-       return e.expressionFactoryMap[expressionType]
-}
-
-func (e *ExpressionFactoryManager) 
SetExpressionFactoryMap(expressionFactoryMap map[string]ExpressionFactory) {
-       for k, v := range expressionFactoryMap {
-               e.expressionFactoryMap[k] = v
-       }
-}
-
-func (e *ExpressionFactoryManager) PutExpressionFactory(expressionType string, 
factory ExpressionFactory) {
-       e.expressionFactoryMap[expressionType] = factory
-}
-
 type SequenceExpression struct {
        seqGenerator sequence.SeqGenerator
        entity       string
@@ -97,7 +51,7 @@ func (s *SequenceExpression) SetRule(rule string) {
        s.rule = rule
 }
 
-func (s SequenceExpression) Value(elContext any) any {
+func (s SequenceExpression) Value(vars map[string]any) any {
        return s.seqGenerator.GenerateId(s.entity, s.rule)
 }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@seata.apache.org
For additional commands, e-mail: notifications-h...@seata.apache.org


Reply via email to