Este documento serve como referência unificada da documentação da API para a Common Expression Language (CEL). Ele lista todas as macros, operadores e funções padrão, indicando as assinaturas, os comportamentos e o status de suporte em todas as pilhas CEL oficiais.
Para mais detalhes sobre o comportamento e as especificações da linguagem, consulte a definição da linguagem CEL.
Versões da pilha
Este documento de referência é baseado nas seguintes versões das stacks da CEL:
- CEL Go:
v0.29.2(e mais recentes) - CEL C++:
v0.15.0 - CEL Java:
v0.13.1 - CEL Python:
v0.1.3 - CEL C: snapshot de desenvolvimento (não lançado)
Espelhos do GitHub
As implementações oficiais da CEL são espelhadas no GitHub na organização cel-expr:
1. Macros principais
São macros integradas que são expandidas no tempo de compilação.
| Macro | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
has(container.field) |
Testa se um campo está presente em uma mensagem ou uma chave em um mapa. Assinaturas: has(container.field) -> boolExemplos: has(request.auth.claims.email) |
✓ | ✓ | ✓ | ✓ | ✓ |
list.all(var, predicate) |
Testa se todos os elementos em uma lista atendem a um predicado. Assinaturas: list.all(var, predicate) -> boolExemplos: [1, 2, 3].all(x, x > 0) // true |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.exists(var, predicate) |
Testa se pelo menos um elemento em uma lista atende a um predicado. Assinaturas: list.exists(var, predicate) -> boolExemplos: [1, 2, 3].exists(x, x > 2) // true |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.exists_one(var, predicate) |
Testa se exatamente um elemento em uma lista atende a um predicado. Assinaturas: list.exists_one(var, predicate) -> boolExemplos: [1, 2, 3].exists_one(x, x == 2) // true |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.filter(var, predicate) |
Filtra elementos de uma lista de acordo com um predicado. Assinaturas: list.filter(var, predicate) -> listExemplos: [1, 2, 3].filter(x, x > 1) // [2, 3] |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.map(var, transform) |
Transforma cada elemento de uma lista usando uma expressão. Assinaturas: list.map(var, transform) -> listExemplos: [1, 2, 3].map(x, x * 2) // [2, 4, 6] |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.map(var, filter, transform) |
Transforma elementos de uma lista que satisfazem um predicado de filtro. Assinaturas: list.map(var, filter, transform) -> listExemplos: [1, 2, 3].map(x, x > 1, x * 2) // [4, 6] |
✓ | ✓ | ✓ | ✓ | ✓¹ |
¹ Compatível com o ambiente de execução C porque as macros são expandidas em comprehensions durante a compilação pelo compilador host.
2. Operadores principais
| Operador | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
Aritmética (+, -, *, /, %) |
Operações aritméticas padrão. Negação (-x) e identidade (+x). A concatenação de listas (list + list) é compatível com Go, C++, Java e Python.Assinaturas: T + T -> TT - T -> TT * T -> TT / T -> TT % T -> T-T -> T+T -> Tlist + list -> listExemplos: 1 + 2 * 3 // 7[1] + [2] // [1, 2] |
✓ | ✓ | ✓ | ✓ | ✓² |
Comparação (==, !=, <, <=, >, >=) |
Comparação padrão. As comparações numéricas são heterogêneas (por exemplo, 1 == 1.0).Assinaturas: T == T -> boolT != T -> boolT < T -> boolT <= T -> boolT > T -> boolT >= T -> boolExemplos: x < 42.01 == 1.0 // true |
✓ | ✓ | ✓ | ✓ | ✓ |
Lógica (!, &&, ||, ? :) |
NOT, AND, OR lógicos e condicional ternária. E/OU use a avaliação de curto-circuito. Assinaturas: !bool -> boolbool && bool -> boolbool || bool -> boolbool ? T : T -> TExemplos: x > 0 ? "positive" : "non-positive" |
✓ | ✓ | ✓ | ✓ | ✓ |
Indexação ([]) |
Acessa o elemento de uma lista por índice ou a chave de pesquisa em um mapa. Assinaturas: list[int] -> Tmap[K] -> VExemplos: tags[0]users['john'] |
✓ | ✓ | ✓ | ✓ | ✓ |
Assinatura (in) |
Verifica se o elemento está em uma lista ou se a chave está em um mapa. Assinaturas: T in list -> boolK in map -> boolExemplos: 'admin' in roles |
✓ | ✓ | ✓ | ✓ | ✓ |
² A concatenação de listas (list + list) não é compatível no tempo de execução de C,
embora outros operadores aritméticos sejam compatíveis.
3. Funções principais
Funções gerais e de string
| Função | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
size |
Retorna o tamanho de uma string (caracteres), bytes, lista ou mapa. Assinaturas: size(T) -> int (em que T é string, bytes, list ou map)<br /><br />**Examples:**<br />size("hello") // 5` |
✓ | ✓ | ✓ | ✓ | ✓ |
contains |
Retorna se a string contém uma substring. Assinaturas: string.contains(string) -> boolExemplos: "hello".contains("ell") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
startsWith |
Retorna se a string começa com o prefixo. Assinaturas: string.startsWith(string) -> boolExemplos: "hello".startsWith("he") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
endsWith |
Retorna se a string termina com o sufixo. Assinaturas: string.endsWith(string) -> boolExemplos: "hello".endsWith("lo") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
matches |
Retorna se a string corresponde à expressão regular RE2. Assinaturas: string.matches(string) -> boolExemplos: "123".matches(r"^\d+$") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
Funções do seletor de data e hora
Essas funções extraem componentes de google.protobuf.Timestamp ou google.protobuf.Duration.
| Função | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
getFullYear |
Retorna o ano com quatro dígitos. Assinaturas: timestamp.getFullYear([tz]) -> intExemplos: timestamp("2026-07-23T00:00:00Z").getFullYear() // 2026 |
✓ | ✓ | ✓ | ✓ | ✗ |
getMonth |
Retorna o mês (0 a 11). Assinaturas: timestamp.getMonth([tz]) -> intExemplos: timestamp("2026-07-23T00:00:00Z").getMonth() // 6 |
✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfMonth |
Retorna o dia do mês (1 a 31). Assinaturas: timestamp.getDayOfMonth([tz]) -> intExemplos: timestamp("2026-07-23T00:00:00Z").getDayOfMonth() // 23 |
✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfWeek |
Retorna o dia da semana (0 = domingo). Assinaturas: timestamp.getDayOfWeek([tz]) -> intExemplos: timestamp("2026-07-23T00:00:00Z").getDayOfWeek() // 4 |
✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfYear |
Retorna o dia do ano (0 a 365). Assinaturas: timestamp.getDayOfYear([tz]) -> intExemplos: timestamp("2026-07-23T00:00:00Z").getDayOfYear() // 203 |
✓ | ✓ | ✓ | ✓ | ✗ |
getHours |
Retorna as horas (0 a 23). Assinaturas: timestamp.getHours([tz]) -> intduration.getHours() -> intExemplos: duration("1h30m").getHours() // 1 |
✓ | ✓ | ✓ | ✓ | ✗ |
getMinutes |
Retorna os minutos (0 a 59). Assinaturas: timestamp.getMinutes([tz]) -> intduration.getMinutes() -> intExemplos: duration("1h30m").getMinutes() // 30 |
✓ | ✓ | ✓ | ✓ | ✗ |
getSeconds |
Retorna os segundos (0 a 59). Assinaturas: timestamp.getSeconds([tz]) -> intduration.getSeconds() -> intExemplos: duration("1h30m45s").getSeconds() // 45 |
✓ | ✓ | ✓ | ✓ | ✗ |
getMilliseconds |
Retorna os milissegundos (0 a 999). Assinaturas: timestamp.getMilliseconds([tz]) -> intduration.getMilliseconds() -> intExemplos: duration("1.5s").getMilliseconds() // 500 |
✓ | ✓ | ✓ | ✓ | ✗ |
Conversões de tipos
| Tipo de segmentação | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
bool |
Converte em booleano. Assinaturas: bool(bool) -> boolbool(string) -> boolExemplos: bool("true") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
bytes |
Converte em bytes. Assinaturas: bytes(bytes) -> bytesbytes(string) -> bytesExemplos: bytes("hello") // b"hello" |
✓ | ✓ | ✓ | ✓ | ✓ |
double |
Converte para ponto flutuante de precisão dupla. Assinaturas: double(double) -> doubledouble(int) -> doubledouble(uint) -> doubledouble(string) -> doubleExemplos: double(1) // 1.0 |
✓ | ✓ | ✓ | ✓ | ✓ |
duration |
Converte em duração. Assinaturas: duration(duration) -> durationduration(string) -> durationExemplos: duration("1.5s") // 1.5s duration |
✓ | ✓ | ✓ | ✓ | ✓ |
int |
Converte para um número inteiro assinado de 64 bits. Assinaturas: int(int) -> intint(uint) -> intint(double) -> int (arredonda para zero)int(string) -> intint(timestamp) -> int (segundos desde a época)Exemplos: int(1.5) // 1 |
✓ | ✓ | ✓ | ✓ | ✓ |
string |
Converte para string. Assinaturas: string(T) -> string (compatível com bool, int, uint, double, bytes, timestamp, duration)<br /><br />**Examples:**<br />string(1.5) // "1.5"` |
✓ | ✓ | ✓ | ✓ | ✓ |
timestamp |
Converte para carimbo de data/hora. Assinaturas: timestamp(timestamp) -> timestamptimestamp(string) -> timestamp (RFC3339)Exemplos: timestamp("2026-07-23T00:00:00Z") |
✓ | ✓ | ✓ | ✓ | ✓ |
uint |
Converte para um número inteiro sem sinal de 64 bits. Assinaturas: uint(uint) -> uintuint(int) -> uintuint(double) -> uintuint(string) -> uintExemplos: uint(1) // 1u |
✓ | ✓ | ✓ | ✓ | ✓ |
dyn |
Converte o valor para o tipo dinâmico para verificação de tipo. Assinaturas: dyn(T) -> dynExemplos: dyn([1, "two"]) |
✓ | ✓ | ✓ | ✓ | ✗ |
type |
Retorna o tipo do valor. Assinaturas: type(T) -> typeExemplos: type(1) // int |
✓ | ✓ | ✓ | ✓ | ✗ |
4. Extensões (bibliotecas)
Biblioteca Bindings
| Função | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
cel.bind |
Vincula uma variável local para evitar a avaliação duplicada. Assinaturas: cel.bind(varName, initExpr, resultExpr) -> TExemplos: cel.bind(x, a + b, x * x) |
✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
Como ativar
- Go:transmita
ext.Bindings()paracel.NewEnv(). - C++:adicione
BindingsCompilerLibrary()aCompilerBuilder. O ambiente de execução é tratado automaticamente. - Java:adicione
CelExtensions.bindings()aos buildersCelCompilereCelRuntime. - Python:importe
cel_expr_python.ext.ext_bindingse useExtBindings()emcel.NewEnv(extensions=[...]).
Biblioteca de codificadores
| Função | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
base64.encode |
Codifica bytes em uma string base64. Assinaturas: base64.encode(bytes) -> stringExemplos: base64.encode(b"hello") // "aGVsbG8=" |
✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
base64.decode |
Decodifica uma string base64 em bytes. Gera um erro em entradas inválidas. Assinaturas: base64.decode(string) -> bytesExemplos: base64.decode("aGVsbG8=") // b"hello" |
✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
json.encode |
Serializa um valor CEL em uma string JSON. Assinaturas: json.encode(dyn) -> stringExemplos: json.encode([1, 2]) // "[1,2]" |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
Como ativar
- Go:transmita
ext.Encoders()paracel.NewEnv(). - C++:
- Compilador: adicione
EncodersCompilerLibrary()aCompilerBuilder. - Tempo de execução: chame
RegisterEncodersFunctions()emFunctionRegistry.
- Compilador: adicione
- Java:adicione
CelExtensions.encoders()aos buildersCelCompilereCelRuntime. - Python:importe
cel_expr_python.ext.ext_encoderse useExtEncoders()emcel.NewEnv(extensions=[...]).
Biblioteca de matemática
| Função | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
math.greatest |
Retorna o maior dos argumentos numéricos (ou lista de números). Assinaturas: math.greatest(arg, ...) -> TExemplos: math.greatest(1, 3, 2) // 3 |
✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.least |
Retorna o menor dos argumentos numéricos (ou lista de números). Assinaturas: math.least(arg, ...) -> TExemplos: math.least([1, 3, 2]) // 1 |
✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.abs |
Valor absoluto. Assinaturas: math.abs(T) -> T (compatível com int, uint, double)<br /><br />**Examples:**<br />math.abs(-1) // 1` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sqrt |
Raiz quadrada. Assinaturas: math.sqrt(T) -> double (compatível com int, uint, double)<br /><br />**Examples:**<br />math.sqrt(9) // 3.0` |
✓ (v0.25.1) | ✓ (v0.12.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
math.bitAnd |
AND bit a bit. Assinaturas: math.bitAnd(T, T) -> T (compatível com int, uint)<br /><br />**Examples:**<br />math.bitAnd(5, 3) // 1` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitOr |
OR bit a bit. Assinaturas: math.bitOr(T, T) -> T (compatível com int, uint)<br /><br />**Examples:**<br />math.bitOr(5, 3) // 7` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitXor |
XOR bit a bit. Assinaturas: math.bitXor(T, T) -> T (compatível com int, uint)<br /><br />**Examples:**<br />math.bitXor(5, 3) // 6` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitNot |
NOT bit a bit. Assinaturas: math.bitNot(T) -> T (aceita int, uint)<br /><br />**Examples:**<br />math.bitNot(1) // -2` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftLeft |
Deslocamento bit a bit para a esquerda. Assinaturas: math.bitShiftLeft(T, int) -> T (compatível com int, uint)<br /><br />**Examples:**<br />math.bitShiftLeft(1, 2) // 4` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftRight |
Desloca para a direita bit a bit. Assinaturas: math.bitShiftRight(T, int) -> T (compatível com int, uint)<br /><br />**Examples:**<br />math.bitShiftRight(4, 2) // 1` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.ceil |
Arredondamento para cima. Assinaturas: math.ceil(double) -> doubleExemplos: math.ceil(1.2) // 2.0 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.floor |
Arredondamento para baixo. Assinaturas: math.floor(double) -> doubleExemplos: math.floor(1.8) // 1.0 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.round |
Arredondamento para o número inteiro mais próximo. Assinaturas: math.round(double) -> doubleExemplos: math.round(1.5) // 2.0 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.trunc |
Arredondamento por truncamento (mais ou menos zero). Assinaturas: math.trunc(double) -> doubleExemplos: math.trunc(-1.8) // -1.0 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isInf |
Verifica se o valor de ponto flutuante de precisão dupla é um infinito positivo ou negativo. Assinaturas: math.isInf(double) -> boolExemplos: math.isInf(1.0/0.0) // true |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isNaN |
Verifica se o valor double é NaN. Assinaturas: math.isNaN(double) -> boolExemplos: math.isNaN(0.0/0.0) // true |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isFinite |
Verifica se o valor double é finito. Assinaturas: math.isFinite(double) -> boolExemplos: math.isFinite(1.2) // true |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sign |
Retorna o sinal do valor (-1, 0 ou 1). Assinaturas: math.sign(T) -> T (compatível com int, uint, double)<br /><br />**Examples:**<br />math.sign(-42) // -1` |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
Como ativar
- Go:transmita
ext.Math()paracel.NewEnv(). - C++:
- Compilador: adicione
MathCompilerLibrary()aCompilerBuilder. - Tempo de execução: chame
RegisterMathExtensionFunctions()emFunctionRegistry.
- Compilador: adicione
- Java:adicione
CelExtensions.math()aos buildersCelCompilereCelRuntime. - Python:importe
cel_expr_python.ext.ext_mathe useExtMath()emcel.NewEnv(extensions=[...]).
Biblioteca Protos
| Função | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
proto.getExt |
Recebe o campo de extensão proto2 ou o padrão, se não definido. Assinaturas: proto.getExt(msg, extName) -> TExemplos: proto.getExt(msg, google.api.expr.test.int32_ext) |
✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
proto.hasExt |
Verifica se o campo de extensão proto2 está definido. Assinaturas: proto.hasExt(msg, extName) -> boolExemplos: proto.hasExt(msg, google.api.expr.test.int32_ext) |
✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
Como ativar
- Go:transmita
ext.Protos()paracel.NewEnv(). - C++:adicione
ProtoExtCompilerLibrary()aCompilerBuilder. O ambiente de execução é tratado automaticamente. - Java:adicione
CelExtensions.protos()aos buildersCelCompilereCelRuntime. - Python:importe
cel_expr_python.ext.ext_protoe useExtProto()emcel.NewEnv(extensions=[...]).
Biblioteca Lists
| Função | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
distinct |
Retorna elementos distintos. Assinaturas: list.distinct() -> listExemplos: [1, 2, 2].distinct() // [1, 2] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
flatten |
Transforma listas aninhadas em listas simples. Assinaturas: list.flatten([depth]) -> listExemplos: [[1], [2, 3]].flatten() // [1, 2, 3] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.7.1) | ✓ (v0.1.1) | ✗ |
lists.range |
Retorna a lista de números inteiros [0, ..., n-1].Assinaturas: lists.range(int) -> list(int)Exemplos: lists.range(3) // [0, 1, 2] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
reverse |
Inverte a lista. Assinaturas: list.reverse() -> listExemplos: [1, 2].reverse() // [2, 1] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
slice |
Retorna a sublista (início inclusivo, fim exclusivo). Assinaturas: list.slice(start, end) -> listExemplos: [1, 2, 3].slice(1, 3) // [2, 3] |
✓ (v0.17.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sort |
Classifica a lista de elementos comparáveis. Assinaturas: list.sort() -> listExemplos: [3, 1, 2].sort() // [1, 2, 3] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sortBy |
Classifica a lista pela chave avaliada da expressão. Assinaturas: list.sortBy(var, expr) -> listExemplos: [{"val": 2}, {"val": 1}].sortBy(x, x.val) // [{"val": 1}, {"val": 2}] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
first |
Retorna o primeiro elemento como opcional. Requer a extensão opcional. Assinaturas: list.first() -> optionalExemplos: [1, 2].first() // optional(1) |
✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
last |
Retorna o último elemento como opcional. Requer a extensão opcional. Assinaturas: list.last() -> optionalExemplos: [1, 2].last() // optional(2) |
✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
Como ativar
- Go:transmita
ext.Lists()paracel.NewEnv(). - C++:
- Compilador: adicione
ListsCompilerLibrary()aCompilerBuilder. - Tempo de execução: chame
RegisterListsFunctions()emFunctionRegistryeRegisterListsMacros()emMacroRegistry.
- Compilador: adicione
- Java:adicione
CelExtensions.lists()aos buildersCelCompilereCelRuntime. - Python:ative via
cel.EnvConfigadicionandolistsà listaextensions.
Biblioteca de conjuntos
| Função | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
sets.contains |
Verifica se list1 contém todos os elementos de list2. Assinaturas: sets.contains(list1, list2) -> boolExemplos: sets.contains([1, 2], [1]) // true |
✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.equivalent |
Verifica se as listas são equivalentes a conjuntos (contêm os mesmos elementos únicos). Assinaturas: sets.equivalent(list1, list2) -> boolExemplos: sets.equivalent([1, 2], [2, 1, 1]) // true |
✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.intersects |
Verifica se as listas compartilham pelo menos um elemento. Assinaturas: sets.intersects(list1, list2) -> boolExemplos: sets.intersects([1, 2], [2, 3]) // true |
✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
Como ativar
- Go:transmita
ext.Sets()paracel.NewEnv(). - C++:
- Compilador: adicione
SetsCompilerLibrary()aCompilerBuilder. - Tempo de execução: chame
RegisterSetsFunctions()emFunctionRegistry.
- Compilador: adicione
- Java:adicione
CelExtensions.sets()aos buildersCelCompilereCelRuntime. - Python:ative via
cel.EnvConfigadicionandosetsà listaextensions.
Biblioteca de strings
| Função | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
charAt |
Retorna o caractere no índice. Assinaturas: string.charAt(int) -> stringExemplos: "hello".charAt(1) // "e" |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
indexOf |
Retorna o índice da primeira ocorrência da substring ou -1. Assinaturas: string.indexOf(substr, [start]) -> intExemplos: "hello".indexOf("l") // 2 |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
lastIndexOf |
Retorna o índice da última ocorrência da substring ou -1. Assinaturas: string.lastIndexOf(substr, [end]) -> intExemplos: "hello".lastIndexOf("l") // 3 |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
join |
Concatena strings. Assinaturas: list(string).join([separator]) -> stringExemplos: ["a", "b"].join("-") // "a-b" |
✓ (v0.10.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
split |
Divide a string pelo separador. Assinaturas: string.split(separator, [limit]) -> list(string)Exemplos: "a-b".split("-") // ["a", "b"] |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
substring |
Retorna a substring (início inclusivo, fim exclusivo). Assinaturas: string.substring(start, [end]) -> stringExemplos: "hello".substring(1, 3) // "el" |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
trim |
Corta espaços em branco Unicode. Assinaturas: string.trim() -> stringExemplos: " hello ".trim() // "hello" |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
replace |
Substitui ocorrências de "antigo" por "novo". Assinaturas: string.replace(old, new, [limit]) -> stringExemplos: "hello".replace("l", "w") // "hewwo" |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
reverse |
Inverte pontos de código Unicode. Assinaturas: string.reverse() -> stringExemplos: "abc".reverse() // "cba" |
✓ (v0.18.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
lowerAscii |
Converte caracteres ASCII para minúsculas. Assinaturas: string.lowerAscii() -> stringExemplos: "Hello".lowerAscii() // "hello" |
✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
upperAscii |
Converte caracteres ASCII para maiúsculas. Assinaturas: string.upperAscii() -> stringExemplos: "Hello".upperAscii() // "HELLO" |
✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
quote |
Faz o escape da string para impressão segura. Assinaturas: strings.quote(string) -> stringExemplos: strings.quote("a\tb") // "\"a\\tb\"" |
✓ (v0.14.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
Como ativar
- Go:transmita
ext.Strings()paracel.NewEnv(). - C++:
- Compilador: adicione
StringsCompilerLibrary()aCompilerBuilder. - Tempo de execução: chame
RegisterStringsFunctions()emFunctionRegistry.
- Compilador: adicione
- Java:adicione
CelExtensions.strings()aos buildersCelCompilereCelRuntime. - Python:importe
cel_expr_python.ext.ext_stringse useExtStrings()emcel.NewEnv(extensions=[...]).
Biblioteca de expressões regulares
| Função | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
regex.replace |
Substitui as correspondências pela string de substituição (aceita referências anteriores). Assinaturas: regex.replace(target, pat, repl, [limit]) -> stringExemplos: regex.replace("123-456", r"(\d+)-(\d+)", r"\2-\1") // "456-123" |
✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
regex.extract |
Retorna a primeira correspondência do padrão (precisa ter um grupo de captura). Assinaturas: regex.extract(target, pat) -> optional(string)Exemplos: regex.extract("a123b", r"(\d+)") // optional("123") |
✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
regex.extractAll |
Retorna todas as correspondências do padrão (precisa ter um grupo de captura). Assinaturas: regex.extractAll(target, pat) -> list(string)Exemplos: regex.extractAll("a1b2", r"(\d+)") // ["1", "2"] |
✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
Como ativar
- Go:transmita
ext.Regex()paracel.NewEnv(). - C++:
- Compilador: adicione
RegexExtCompilerLibrary()aCompilerBuilder. - Tempo de execução: chame
RegisterRegexExtensionFunctions()emFunctionRegistry.
- Compilador: adicione
- Java:adicione
CelExtensions.regex()aos buildersCelCompilereCelRuntime. - Python:ative via
cel.EnvConfigadicionandoregexeoptionalà listaextensions.
Compreensões de duas variáveis
| Macro | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
all |
Curto-circuito lógico AND em chave/índice e valor. Assinaturas: list.all(i, v, pred) -> boolmap.all(k, v, pred) -> boolExemplos: [1, 2].all(i, v, v > 0) // true |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
exists |
Curto-circuito OR lógico em chave/índice e valor. Assinaturas: list.exists(i, v, pred) -> boolmap.exists(k, v, pred) -> boolExemplos: [1, 2].exists(i, v, v == 2) // true |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
existsOne |
Verifica se exatamente um par satisfaz o predicado. Assinaturas: list.existsOne(i, v, pred) -> boolmap.existsOne(k, v, pred) -> boolExemplos: [1, 2].existsOne(i, v, v == 2) // true |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformList |
Transforma/filtra lista/mapa em uma lista. Assinaturas: list.transformList(i, v, [filter], transform) -> listmap.transformList(k, v, [filter], transform) -> listExemplos: [1, 2].transformList(i, v, v * 2) // [2, 4] |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMap |
Transforma valores de lista/mapa em um mapa (as chaves permanecem fixas). Assinaturas: list.transformMap(i, v, [filter], transform) -> mapmap.transformMap(k, v, [filter], transform) -> mapExemplos: [1, 2].transformMap(i, v, v * 2) // {0: 2, 1: 4} |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMapEntry |
Transforma em um mapa. Assinaturas: list.transformMapEntry(i, v, [filter], transform_entry) -> mapmap.transformMapEntry(k, v, [filter], transform_entry) -> mapExemplos: [1, 2].transformMapEntry(i, v, {string(v): v * 2}) // {"1": 2, "2": 4} |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
Como ativar
- Go:transmita
ext.TwoVarComprehensions()paracel.NewEnv(). - C++:
- Compilador: adicione
ComprehensionsV2CompilerLibrary()aCompilerBuilder. - Tempo de execução: chame
RegisterComprehensionsV2Functions()emFunctionRegistryeRegisterComprehensionsV2Macros()emMacroRegistry.
- Compilador: adicione
- Java:adicione
CelExtensions.comprehensions()aos buildersCelCompilereCelRuntime. - Python:ative via
cel.EnvConfigadicionandotwo-var-comprehensionsà listaextensions.
Biblioteca de tipos nativos
| Recurso | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
| Estruturas nativas | Registrar e instanciar tipos nativos do host (structs Go / POJOs Java) em CEL. Exemplos: Account{id: 123} (POJO Java instanciado em CEL) |
✓ (v0.13.0) | ✗ | ✓ (v0.13.0) | ✗ | ✗ |
Como ativar
- Go:passe
ext.NativeTypes(...)(fornecendo tipos de reflexão) paracel.NewEnv(). - C++:indisponível.
- Java:adicione
CelExtensions.nativeTypes()(fornecendo classes Java) aos buildersCelCompilereCelRuntime. - Python:indisponível.
Biblioteca de rede
A biblioteca de rede fornece funções para analisar, validar e manipular endereços IP e blocos CIDR.
| Função | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
ip |
Analisa uma string em um endereço IP ou extrai o IP de um CIDR. Assinaturas: ip(string) -> IPCIDR.ip() -> IPExemplos: ip("192.168.0.1")cidr("192.168.0.0/24").ip() |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isIP |
Verifica se uma string é um endereço IP válido. Assinaturas: isIP(string) -> boolExemplos: isIP("192.168.0.1") // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
ip.isCanonical |
Verifica se uma string de endereço IP está no formato canônico. Assinaturas: ip.isCanonical(string) -> boolExemplos: ip.isCanonical("192.168.0.1") // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
cidr |
Analisa uma string em um bloco CIDR. Assinaturas: cidr(string) -> CIDRExemplos: cidr("192.168.0.0/24") |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isCIDR |
Verifica se uma string é um bloco CIDR válido. Assinaturas: isCIDR(string) -> boolExemplos: isCIDR("192.168.0.0/24") // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsIP |
Verifica se um bloco CIDR contém um endereço IP. Assinaturas: CIDR.containsIP(IP) -> boolCIDR.containsIP(string) -> boolExemplos: cidr("192.168.0.0/24").containsIP(ip("192.168.0.1")) // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsCIDR |
Verifica se um bloco CIDR contém outro bloco CIDR. Assinaturas: CIDR.containsCIDR(CIDR) -> boolCIDR.containsCIDR(string) -> boolExemplos: cidr("192.168.0.0/16").containsCIDR(cidr("192.168.1.0/24")) // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
family |
Retorna a família de IP (4 para IPv4, 6 para IPv6). Assinaturas: IP.family() -> intExemplos: ip("192.168.0.1").family() // 4 |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isGlobalUnicast |
Verifica se o IP é um endereço unicast global. Assinaturas: IP.isGlobalUnicast() -> boolExemplos: ip("192.168.0.1").isGlobalUnicast() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalMulticast |
Verifica se o IP é um endereço multicast de link local. Assinaturas: IP.isLinkLocalMulticast() -> boolExemplos: ip("224.0.0.1").isLinkLocalMulticast() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalUnicast |
Verifica se o IP é um endereço unicast de link local. Assinaturas: IP.isLinkLocalUnicast() -> boolExemplos: ip("169.254.0.1").isLinkLocalUnicast() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLoopback |
Verifica se o IP é um endereço de loopback. Assinaturas: IP.isLoopback() -> boolExemplos: ip("127.0.0.1").isLoopback() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isMask |
Verifica se o CIDR é uma máscara de sub-rede válida. Assinaturas: CIDR.isMask() -> boolExemplos: cidr("255.255.255.0/24").isMask() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isUnspecified |
Verifica se o IP é um endereço não especificado (por exemplo, 0.0.0.0).Assinaturas: IP.isUnspecified() -> boolExemplos: ip("0.0.0.0").isUnspecified() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
masked |
Retorna o bloco CIDR mascarado. Assinaturas: CIDR.masked() -> CIDRExemplos: cidr("192.168.0.1/24").masked() // 192.168.0.0/24 |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
prefixLength |
Retorna o tamanho do prefixo do bloco CIDR. Assinaturas: CIDR.prefixLength() -> intExemplos: cidr("192.168.0.0/24").prefixLength() // 24 |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
string |
Converte IP ou CIDR em string. Assinaturas: string(IP) -> stringstring(CIDR) -> stringExemplos: string(ip("192.168.0.1")) // "192.168.0.1" |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
Como ativar
- Go:transmita
ext.Network()paracel.NewEnv(). - C++:indisponível.
- Java:indisponível.
- Python:indisponível.
5. Recursos avançados
Resumo dos recursos avançados
| Recurso | Descrição | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
| Avaliação parcial | Avalia com entradas ausentes e retorna valores desconhecidos ou uma expressão simplificada. | ✓³ | ✓⁴ | ✓⁴ | ✗ | ✗ |
| Avaliação assíncrona | Execução simultânea sem bloqueio de funções de extensão. | ✓⁵ | ✗ | ✓⁶ | ✗ | ✗ |
| Validadores de AST | A análise estática verifica a AST verificada após a verificação de tipos. | ✓ | ✓ | ✓ | ✗ | ✗ |
| Otimizadores de AST | Reescritas de AST (redução de constantes, inlining, CSE) para melhorar o desempenho. | ✓ | ✓ | ✓ | ✗ | ✗ |
| Compilador de políticas CEL | Compila estruturas de políticas baseadas em YAML em ASTs CEL padrão. | ✓ | ✓ | ✓ | ✗ | ✗ |
³ O Go é compatível com a geração de uma AST residual (AST podada). ⁴ O C++ e o Java oferecem suporte
para retornar UnknownSet / CelUnknownSet no tempo de execução, mas não expõem APIs
públicas para geração de AST residual. ⁵ O Go usa AsyncBinding / AsyncOp retornando canais. ⁶ O Java usa CelAsyncRuntime, retornando ListenableFuture.
Avaliação parcial (desconhecidos)
A avaliação parcial permite avaliar uma expressão quando apenas um subconjunto das variáveis de entrada (argumentos) é conhecido. Em vez de falhar, a avaliação produz um resultado que indica o que está faltando ou uma expressão simplificada.
- Go:suporte total. Permite definir um
PartialActivationcom padrões de atributos desconhecidos. A avaliação retorna um valortypes.Unknown. O Go oferece suporte à geração de uma AST residual (Env.ResidualAst), que é uma AST simplificada e reduzida que contém apenas as partes da expressão que não puderam ser avaliadas. - C++:aceita valores
Unknown. Padrões de atributos desconhecidos são configurados viaActivation::set_unknown_attribute_patterns. A avaliação retorna umUnknownSet. No momento, a API pública não expõe a geração de AST residual. - Java:oferece suporte à avaliação parcial via
PartialVarstransmitido paraProgram.eval(). A avaliação retorna umCelUnknownSet. A API pública não expõe a geração de AST residual no momento. - Python / C:sem suporte nativo.
Avaliação assíncrona
A avaliação assíncrona permite que as expressões CEL chamem funções que são executadas de forma assíncrona (por exemplo, fazendo RPCs ou consultas de banco de dados) e bloqueiem a avaliação até que os resultados estejam disponíveis, sem bloquear a linha de execução principal.
- Go:oferece suporte a sobrecargas de função assíncronas via
AsyncBindingeAsyncOp. As funções assíncronas retornam um canal Go (<-chan ref.Val), e o interpretador gerencia a execução e a sincronização simultâneas. - Java:oferece suporte à avaliação assíncrona via
CelAsyncRuntimeeAsyncProgram. Ele usaListenableFuturepara representar valores pendentes e conclui automaticamente a avaliação à medida que as promessas são resolvidas. - C++ / Python / C:não há suporte integrado.
Validadores de AST
Os validadores realizam uma análise estática na AST verificada após a verificação de tipo para aplicar restrições específicas do domínio antes da execução do programa.
- Go:compatível com a interface
ASTValidator. Os validadores canônicos incluemcel.validator.duration,cel.validator.timestamp,cel.validator.matches(regex),cel.validator.homogeneous_literalsecel.validator.comprehension_nesting_limit. - C++:compatível com
cel::Validator. As validações canônicas incluemAstDepthValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,MatchesValidatoreTimestampLiteralValidator. - Java:compatível com
CelValidatoreCelAstValidator. Os validadores canônicos incluemAstDepthLimitValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,RegexLiteralValidatoreTimestampLiteralValidator. - Python / C:não há suporte direto.
Otimizadores de AST
Os otimizadores reescrevem a AST para melhorar o desempenho da execução. Os otimizadores se enquadram em uma de duas categorias: estáticos e de tempo de execução. C++, Java e Go oferecem suporte à otimização de tempo de execução. O CEL Java e o Go também são compatíveis com otimizadores estáticos. As otimizações típicas incluem a substituição de constantes (pré-avaliação de subexpressões com entradas constantes) e a eliminação de subexpressões comuns (CSE, na sigla em inglês).
- Go:oferece suporte à junção de AST durante a compilação/planejamento.
- C++:oferece suporte à substituição de constantes usando a extensão
cel::extensions::EnableConstantFoldingdurante o planejamento. - Java:compatível com a interface
CelOptimizer. Os otimizadores canônicos incluemConstantFoldingOptimizer(que pode dobrar ramificações de curto-circuito simulando avaliação parcial),InliningOptimizereSubexpressionOptimizer(CSE). - Python / C:não há suporte direto.
Compilador de políticas CEL
A política CEL é um formato baseado em YAML para compor várias expressões CEL com variáveis, blocos de correspondência, saídas condicionais e regras aninhadas. Ele foi projetado para mecanismos de política complexos (como o controle de admissão do Kubernetes), em que expressões CEL únicas ficariam ilegíveis.
O compilador de políticas compila essas políticas YAML em uma única AST CEL padrão, o que significa que elas são totalmente compatíveis com os tempos de execução CEL padrão e herdam todas as garantias de desempenho e segurança.
- Go:compatível com
third_party/cel/go/policy. - C++:compatível com
third_party/cel/cpp/policy. - Java:compatível com
third_party/java/cel/policy. - Python / C:não há suporte direto.