{"id":13412709,"url":"https://github.com/google/cel-go","last_synced_at":"2025-05-12T05:27:42.724Z","repository":{"id":37470556,"uuid":"124602093","full_name":"google/cel-go","owner":"google","description":"Fast, portable, non-Turing complete expression evaluation with gradual typing (Go)","archived":false,"fork":false,"pushed_at":"2025-05-07T21:15:31.000Z","size":11203,"stargazers_count":2536,"open_issues_count":47,"forks_count":242,"subscribers_count":35,"default_branch":"master","last_synced_at":"2025-05-11T03:14:04.151Z","etag":null,"topics":["cel","expression","expression-evaluator","expression-language","expression-parser","go","golang"],"latest_commit_sha":null,"homepage":"https://cel.dev","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/google.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-03-09T22:57:58.000Z","updated_at":"2025-05-09T12:33:53.000Z","dependencies_parsed_at":"2023-11-21T19:26:20.715Z","dependency_job_id":"3ba5c087-250a-49a9-abda-857bb626045a","html_url":"https://github.com/google/cel-go","commit_stats":{"total_commits":618,"total_committers":67,"mean_commits":9.223880597014926,"dds":"0.37216828478964403","last_synced_commit":"fbf5c7746c18076c810843c4d25cf3a2579dd6e9"},"previous_names":[],"tags_count":74,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google%2Fcel-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google%2Fcel-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google%2Fcel-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google%2Fcel-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/google","download_url":"https://codeload.github.com/google/cel-go/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253509788,"owners_count":21919590,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cel","expression","expression-evaluator","expression-language","expression-parser","go","golang"],"created_at":"2024-07-30T20:01:28.151Z","updated_at":"2025-05-11T03:14:10.284Z","avatar_url":"https://github.com/google.png","language":"Go","readme":"# Common Expression Language\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/google/cel-go)](https://goreportcard.com/report/github.com/google/cel-go)\n[![GoDoc](https://godoc.org/github.com/google/cel-go?status.svg)][6]\n\nThe Common Expression Language (CEL) is a non-Turing complete language designed\nfor simplicity, speed, safety, and portability. CEL's C-like [syntax][1] looks\nnearly identical to equivalent expressions in C++, Go, Java, and TypeScript.\n\n```java\n// Check whether a resource name starts with a group name.\nresource.name.startsWith(\"/groups/\" + auth.claims.group)\n```\n\n```go\n// Determine whether the request is in the permitted time window.\nrequest.time - resource.age \u003c duration(\"24h\")\n```\n\n```typescript\n// Check whether all resource names in a list match a given filter.\nauth.claims.email_verified \u0026\u0026 resources.all(r, r.startsWith(auth.claims.email))\n```\n\nA CEL \"program\" is a single expression. The examples have been tagged as\n`java`, `go`, and `typescript` within the markdown to showcase the commonality\nof the syntax.\n\nCEL is ideal for lightweight expression evaluation when a fully sandboxed\nscripting language is too resource intensive. To get started, try the\n[Codelab](https://codelabs.developers.google.com/codelabs/cel-go/index.html).\n\n---\n\n* [Overview](#overview)\n  * [Environment Setup](#environment-setup)\n  * [Parse and Check](#parse-and-check)\n  * [Macros](#macros)\n  * [Evaluate](#evaluate)\n  * [Errors](#Errors)\n* [Examples](examples/README.md)\n* [Install](#install)\n* [Common Questions](#common-questions)\n* [License](#license)\n\n---\n\n## Overview\n\nDetermine the variables and functions you want to provide to CEL. Parse and\ncheck an expression to make sure it's valid. Then evaluate the output AST\nagainst some input. Checking is optional, but strongly encouraged.\n\n### Environment Setup\n\nLet's expose `name` and  `group` variables to CEL using the `cel.Variable`\nenvironment option:\n\n```go\nimport \"github.com/google/cel-go/cel\"\n\nenv, err := cel.NewEnv(\n    cel.Variable(\"name\", cel.StringType),\n    cel.Variable(\"group\", cel.StringType),\n)\n```\n\nThat's it. The environment is ready to be used for parsing and type-checking.\nCEL supports all the usual primitive types in addition to lists, maps, as well\nas first-class support for JSON and Protocol Buffers.\n\n### Parse and Check\n\nThe parsing phase indicates whether the expression is syntactically valid and\nexpands any macros present within the environment. Parsing and checking are\nmore computationally expensive than evaluation, and it is recommended that\nexpressions be parsed and checked ahead of time.\n\nThe parse and check phases are combined for convenience into the `Compile`\nstep:\n\n```go\nast, issues := env.Compile(`name.startsWith(\"/groups/\" + group)`)\nif issues != nil \u0026\u0026 issues.Err() != nil {\n    log.Fatalf(\"type-check error: %s\", issues.Err())\n}\nprg, err := env.Program(ast)\nif err != nil {\n    log.Fatalf(\"program construction error: %s\", err)\n}\n```\n\nThe `cel.Program` generated at the end of parse and check is stateless,\nthread-safe, and cachable.\n\nType-checking is an optional, but strongly encouraged step that can reject some\nsemantically invalid expressions using static analysis. Additionally, the check\nproduces metadata which can improve function invocation performance and object\nfield selection at evaluation-time.\n\n#### Macros\n\nMacros are optional but enabled by default. Macros were introduced to\nsupport optional CEL features that might not be desired in all use cases\nwithout the syntactic burden and complexity such features might desire if\nthey were part of the core CEL syntax. Macros are expanded at parse time and\ntheir expansions are type-checked at check time.\n\nFor example, when macros are enabled it is possible to support bounded\niteration / fold operators. The macros `all`, `exists`, `exists_one`, `filter`,\nand `map` are particularly useful for evaluating a single predicate against\nlist and map values.\n\n```javascript\n// Ensure all tweets are less than 140 chars\ntweets.all(t, t.size() \u003c= 140)\n```\n\nThe `has` macro is useful for unifying field presence testing logic across\nprotobuf types and dynamic (JSON-like) types.\n\n```javascript\n// Test whether the field is a non-default value if proto-based, or defined\n// in the JSON case.\nhas(message.field)\n```\n\nBoth cases traditionally require special syntax at the language level, but\nthese features are exposed via macros in CEL.\n\n### Evaluate\n\nNow, evaluate for fun and profit. The evaluation is thread-safe and side-effect\nfree. Many different inputs can be sent to the same `cel.Program` and if fields\nare present in the input, but not referenced in the expression, they are\nignored.\n\n```go\n// The `out` var contains the output of a successful evaluation.\n// The `details' var would contain intermediate evaluation state if enabled as\n// a cel.ProgramOption. This can be useful for visualizing how the `out` value\n// was arrive at.\nout, details, err := prg.Eval(map[string]interface{}{\n    \"name\": \"/groups/acme.co/documents/secret-stuff\",\n    \"group\": \"acme.co\"})\nfmt.Println(out) // 'true'\n```\n\n#### Partial State\n\nWhat if `name` hadn't been supplied? CEL is designed for this case. In\ndistributed apps it is not uncommon to have edge caches and central services.\nIf possible, evaluation should happen at the edge, but it isn't always possible\nto know the full state required for all values and functions present in the\nCEL expression.\n\nTo improve the odds of successful evaluation with partial state, CEL uses\ncommutative logical operators `\u0026\u0026`, `||`. If an error or unknown value (not the\nsame thing) is encountered on the left-hand side, the right hand side is\nevaluated also to determine the outcome. While it is possible to implement\nevaluation with partial state without this feature, this method was chosen\nbecause it aligns with the semantics of SQL evaluation and because it's more\nrobust to evaluation against dynamic data types such as JSON inputs.\n\nIn the following truth-table, the symbols `\u003cx\u003e` and `\u003cy\u003e` represent error or\nunknown values, with the `?` indicating that the branch is not taken due to\nshort-circuiting. When the result is `\u003cx, y\u003e` this means that the both args\nare possibly relevant to the result.\n\n| Expression          | Result   |\n|---------------------|----------|\n| `false \u0026\u0026 ?`        | `false`  |\n| `true \u0026\u0026 false`     | `false`  |\n| `\u003cx\u003e \u0026\u0026 false`      | `false`  |\n| `true \u0026\u0026 true`      | `true`   |\n| `true \u0026\u0026 \u003cx\u003e`       | `\u003cx\u003e`    |\n| `\u003cx\u003e \u0026\u0026 true`       | `\u003cx\u003e`    |\n| `\u003cx\u003e \u0026\u0026 \u003cy\u003e`        | `\u003cx, y\u003e` |\n| `true \\|\\| ?`       | `true`   |\n| `false \\|\\| true`   | `true`   |\n| `\u003cx\u003e \\|\\| true`     | `true`   |\n| `false \\|\\| false`  | `false`  |\n| `false \\|\\| \u003cx\u003e`    | `\u003cx\u003e`    |\n| `\u003cx\u003e \\|\\| false`    | `\u003cx\u003e`    |\n| `\u003cx\u003e \\|\\| \u003cy\u003e`      | `\u003cx, y\u003e` |\n\nIn the cases where unknowns are expected, `cel.EvalOptions(cel.OptTrackState)`\nshould be enabled. The `details` value returned by `Eval()` will contain the\nintermediate evaluation values and can be provided to the `interpreter.Prune`\nfunction to generate a residual expression. e.g.:\n\n```cpp\n// Residual when `name` omitted:\nname.startsWith(\"/groups/acme.co\")\n```\n\nThis technique can be useful when there are variables that are expensive to\ncompute unless they are absolutely needed. This functionality will be the\nfocus of many future improvements, so keep an eye out for more goodness here!\n\n### Errors\n\nParse and check errors have friendly error messages with pointers to where the\nissues occur in source:\n\n```sh\nERROR: \u003cinput\u003e:1:40: undefined field 'undefined'\n    | TestAllTypes{single_int32: 1, undefined: 2}\n    | .......................................^`,\n```\n\nBoth the parsed and checked expressions contain source position information\nabout each node that appears in the output AST. This information can be used\nto determine error locations at evaluation time as well.\n\n## Install\n\nCEL-Go supports `modules` and uses semantic versioning. For more info\nsee the [Go Modules](https://github.com/golang/go/wiki/Modules) docs.\n\nAnd of course, there is always the option to build from source directly.\n\n## Common Questions\n\n### Why not JavaScript, Lua, or WASM?\n\nJavaScript and Lua are rich languages that require sandboxing to execute\nsafely. Sandboxing is costly and factors into the \"what will I let users\nevaluate?\" question heavily when the answer is anything more than O(n)\ncomplexity.\n\nCEL evaluates linearly with respect to the size of the expression and the input\nbeing evaluated when macros are disabled. The only functions beyond the\nbuilt-ins that may be invoked are provided by the host environment. While\nextension functions may be more complex, this is a choice by the application\nembedding CEL.\n\nBut, why not WASM? WASM is an excellent choice for certain applications and\nis far superior to embedded JavaScript and Lua, but it does not have support\nfor garbage collection and non-primitive object types require semi-expensive\ncalls across modules. In most cases CEL will be faster and just as portable\nfor its intended use case, though for node.js and web-based execution CEL\ntoo may offer a WASM evaluator with direct to WASM compilation.\n\n### Do I need to Parse _and_ Check?\n\nChecking is an optional, but strongly suggested step in CEL expression\nvalidation. It is sufficient in some cases to simply parse and rely on the\nruntime bindings and error handling to do the right thing.\n\n### Where can I learn more about the language?\n\n* See the [CEL Spec][1] for the specification and conformance test suite.\n* Ask for support on the [CEL Go Discuss][2] Google group.\n\n### Where can I learn more about the internals?\n\n* See [GoDoc][6] to learn how to integrate CEL into services written in Go.\n* See the [CEL C++][3] toolchain (under development) for information about how\n  to integrate CEL evaluation into other environments.\n\n### How can I contribute?\n\n* See [CONTRIBUTING.md](./CONTRIBUTING.md) to get started.\n* Use [GitHub Issues][4] to request features or report bugs.\n\n### Some tests don't work with `go test`?\n\nA handful of tests rely on [Bazel][5]. In particular dynamic proto support\nat check time and the conformance test driver require Bazel to coordinate\nthe test inputs:\n\n```sh\nbazel test ...\n```\n\n## License\n\nReleased under the [Apache License](LICENSE).\n\n[1]:  https://github.com/google/cel-spec\n[2]:  https://groups.google.com/forum/#!forum/cel-go-discuss\n[3]:  https://github.com/google/cel-cpp\n[4]:  https://github.com/google/cel-go/issues\n[5]:  https://bazel.build\n[6]:  https://godoc.org/github.com/google/cel-go\n","funding_links":[],"categories":["脚本语言与嵌入式编程","开源类库","Embeddable Scripting Languages","Open source library","Go","Relational Databases","可嵌入的脚本语言","脚本语言与嵌入式编程`在你的go代码中嵌入其他脚本语言`","Repositories"],"sub_categories":["SQL 查询语句构建库","解释器","Search and Analytic Databases","Interpreter","Advanced Console UIs","检索及分析资料库"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoogle%2Fcel-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoogle%2Fcel-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoogle%2Fcel-go/lists"}