Référence de l'API Common Expression Language (CEL)

Ce document sert de référence unifiée pour la documentation de l'API CEL (Common Expression Language). Il liste toutes les macros, tous les opérateurs et toutes les fonctions standards, en indiquant leurs signatures, leurs comportements et leur état de compatibilité dans les piles CEL officielles.

Pour en savoir plus sur le comportement et les spécifications du langage, consultez la définition du langage CEL.

Versions de la pile

Ce document de référence est basé sur les versions suivantes des piles CEL :

  • CEL Go : v0.29.2 (et versions ultérieures)
  • CEL C++ : v0.15.0
  • CEL Java : v0.13.1
  • CEL Python : v0.1.3
  • CEL C : instantané de développement (non publié)

Miroirs GitHub

Les implémentations officielles de CEL sont mises en miroir sur GitHub sous l'organisation cel-expr :


1. Macros de base

Il s'agit de macros intégrées qui sont développées au moment de la compilation.

Macro Description Go C++ Java Python C
has(container.field) Teste si un champ est présent dans un message ou si une clé est présente dans une carte.

Signatures :
has(container.field) -> bool

Exemples :
has(request.auth.claims.email)
list.all(var, predicate) Teste si tous les éléments d'une liste satisfont un prédicat.

Signatures :
list.all(var, predicate) -> bool

Exemples :
[1, 2, 3].all(x, x > 0) // true
¹
list.exists(var, predicate) Teste si au moins un élément d'une liste satisfait un prédicat.

Signatures :
list.exists(var, predicate) -> bool

Exemples :
[1, 2, 3].exists(x, x > 2) // true
¹
list.exists_one(var, predicate) Teste si exactement un élément d'une liste satisfait un prédicat.

Signatures :
list.exists_one(var, predicate) -> bool

Exemples :
[1, 2, 3].exists_one(x, x == 2) // true
¹
list.filter(var, predicate) Filtre les éléments d'une liste en fonction d'un prédicat.

Signatures :
list.filter(var, predicate) -> list

Exemples :
[1, 2, 3].filter(x, x > 1) // [2, 3]
¹
list.map(var, transform) Transforme chaque élément d'une liste à l'aide d'une expression.

Signatures :
list.map(var, transform) -> list

Exemples :
[1, 2, 3].map(x, x * 2) // [2, 4, 6]
¹
list.map(var, filter, transform) Transforme les éléments d'une liste qui répondent à un prédicat de filtre.

Signatures :
list.map(var, filter, transform) -> list

Exemples :
[1, 2, 3].map(x, x > 1, x * 2) // [4, 6]
¹

¹ Pris en charge dans le runtime C, car les macros sont développées en compréhensions lors de la compilation par le compilateur hôte.


2. Opérateurs principaux

Opérateur Description Go C++ Java Python C
Arithmétiques (+, -, *, /, %) Opérations arithmétiques standards. Négation (-x) et identité (+x). La concaténation de listes (list + list) est acceptée dans Go, C++, Java et Python.

Signatures :
T + T -> T
T - T -> T
T * T -> T
T / T -> T
T % T -> T
-T -> T
+T -> T
list + list -> list

Exemples :
1 + 2 * 3 // 7
[1] + [2] // [1, 2]
²
Comparaison (==, !=, <, <=, >, >=) Comparaison standard. Les comparaisons numériques sont hétérogènes (par exemple, 1 == 1.0).

Signatures :
T == T -> bool
T != T -> bool
T < T -> bool
T <= T -> bool
T > T -> bool
T >= T -> bool

Exemples :
x < 42.0
1 == 1.0 // true
Logiques (!, &&, ||, ? :) Opérateurs logiques NOT, AND, OR et conditionnels ternaires. AND/OR utilise l'évaluation de court-circuit.

Signatures :
!bool -> bool
bool && bool -> bool
bool || bool -> bool
bool ? T : T -> T

Exemples :
x > 0 ? "positive" : "non-positive"
Indexation ([]) Accédez à l'élément d'une liste par index ou à la clé de recherche dans une carte.

Signatures :
list[int] -> T
map[K] -> V

Exemples :
tags[0]
users['john']
Abonnement (in) Vérifie si un élément se trouve dans une liste ou si une clé se trouve dans un mappage.

Signatures :
T in list -> bool
K in map -> bool

Exemples :
'admin' in roles

² La concaténation de listes (list + list) n'est pas acceptée dans le runtime C, contrairement aux autres opérateurs arithmétiques.


3. Fonctions principales

Fonctions générales et de chaîne

Fonction Description Go C++ Java Python C
size Renvoie la taille d'une chaîne (caractères), d'octets, d'une liste ou d'une carte.

Signatures :
size(T) -> int (où T correspond à string, bytes, list ou map)<br /><br />**Examples:**<br />size("hello") // 5`
contains Indique si la chaîne contient une sous-chaîne.

Signatures :
string.contains(string) -> bool

Exemples :
"hello".contains("ell") // true
startsWith Indique si la chaîne commence par le préfixe.

Signatures :
string.startsWith(string) -> bool

Exemples :
"hello".startsWith("he") // true
endsWith Indique si la chaîne se termine par le suffixe.

Signatures :
string.endsWith(string) -> bool

Exemples :
"hello".endsWith("lo") // true
matches Indique si la chaîne correspond à l'expression régulière RE2.

Signatures :
string.matches(string) -> bool

Exemples :
"123".matches(r"^\d+$") // true

Fonctions de sélection de la date et de l'heure

Ces fonctions extraient des composants de google.protobuf.Timestamp ou google.protobuf.Duration.

Fonction Description Go C++ Java Python C
getFullYear Renvoie l'année à quatre chiffres.

Signatures :
timestamp.getFullYear([tz]) -> int

Exemples :
timestamp("2026-07-23T00:00:00Z").getFullYear() // 2026
getMonth Renvoie le mois (0 à 11).

Signatures :
timestamp.getMonth([tz]) -> int

Exemples :
timestamp("2026-07-23T00:00:00Z").getMonth() // 6
getDayOfMonth Renvoie le jour du mois (1 à 31).

Signatures :
timestamp.getDayOfMonth([tz]) -> int

Exemples :
timestamp("2026-07-23T00:00:00Z").getDayOfMonth() // 23
getDayOfWeek Renvoie le jour de la semaine (0 = dimanche).

Signatures :
timestamp.getDayOfWeek([tz]) -> int

Exemples :
timestamp("2026-07-23T00:00:00Z").getDayOfWeek() // 4
getDayOfYear Renvoie le jour de l'année (0 à 365).

Signatures :
timestamp.getDayOfYear([tz]) -> int

Exemples :
timestamp("2026-07-23T00:00:00Z").getDayOfYear() // 203
getHours Renvoie les heures (0-23).

Signatures :
timestamp.getHours([tz]) -> int
duration.getHours() -> int

Exemples :
duration("1h30m").getHours() // 1
getMinutes Renvoie les minutes (0-59).

Signatures :
timestamp.getMinutes([tz]) -> int
duration.getMinutes() -> int

Exemples :
duration("1h30m").getMinutes() // 30
getSeconds Renvoie les secondes (0 à 59).

Signatures :
timestamp.getSeconds([tz]) -> int
duration.getSeconds() -> int

Exemples :
duration("1h30m45s").getSeconds() // 45
getMilliseconds Renvoie les millisecondes (0 à 999).

Signatures :
timestamp.getMilliseconds([tz]) -> int
duration.getMilliseconds() -> int

Exemples :
duration("1.5s").getMilliseconds() // 500

Conversions de types

Type de cible Description Go C++ Java Python C
bool Convertit une valeur en valeur booléenne.

Signatures :
bool(bool) -> bool
bool(string) -> bool

Exemples :
bool("true") // true
bytes Convertit en octets.

Signatures :
bytes(bytes) -> bytes
bytes(string) -> bytes

Exemples :
bytes("hello") // b"hello"
double Convertit en float à double précision.

Signatures :
double(double) -> double
double(int) -> double
double(uint) -> double
double(string) -> double

Exemples :
double(1) // 1.0
duration Convertit en durée.

Signatures :
duration(duration) -> duration
duration(string) -> duration

Exemples :
duration("1.5s") // 1.5s duration
int Convertit en entier signé de 64 bits.

Signatures :
int(int) -> int
int(uint) -> int
int(double) -> int (arrondi à zéro)
int(string) -> int
int(timestamp) -> int (secondes depuis l'époque)

Exemples :
int(1.5) // 1
string Convertit en chaîne.

Signatures :
string(T) -> string (accepte bool, int, uint, double, bytes, timestamp, duration)<br /><br />**Examples:**<br />string(1.5) // "1.5"`
timestamp Convertit en code temporel.

Signatures :
timestamp(timestamp) -> timestamp
timestamp(string) -> timestamp (RFC3339)

Exemples :
timestamp("2026-07-23T00:00:00Z")
uint Convertit en entier non signé de 64 bits.

Signatures :
uint(uint) -> uint
uint(int) -> uint
uint(double) -> uint
uint(string) -> uint

Exemples :
uint(1) // 1u
dyn Caste la valeur en type dynamique pour la vérification du type.

Signatures :
dyn(T) -> dyn

Exemples :
dyn([1, "two"])
type Renvoie le type de la valeur.

Signatures :
type(T) -> type

Exemples :
type(1) // int

4. Extensions (bibliothèques)

Bibliothèque de liaisons

Fonction Description Go C++ Java Python C
cel.bind Lie une variable locale pour éviter une évaluation en double.

Signatures :
cel.bind(varName, initExpr, resultExpr) -> T

Exemples :
cel.bind(x, a + b, x * x)
(v0.15.0) (v0.10.0) (v0.2.0) (v0.1.1)

Activer

Bibliothèque d'encodeurs

Fonction Description Go C++ Java Python C
base64.encode Encode les octets en chaîne base64.

Signatures :
base64.encode(bytes) -> string

Exemples :
base64.encode(b"hello") // "aGVsbG8="
(v0.6.0) (v0.10.0) (v0.2.0) (v0.1.1)
base64.decode Décode une chaîne base64 en octets. Génère une erreur en cas d'entrée non valide.

Signatures :
base64.decode(string) -> bytes

Exemples :
base64.decode("aGVsbG8=") // b"hello"
(v0.6.0) (v0.10.0) (v0.2.0) (v0.1.1)
json.encode Sérialise une valeur CEL en chaîne JSON.

Signatures :
json.encode(dyn) -> string

Exemples :
json.encode([1, 2]) // "[1,2]"
(v0.29.0)

Activer

Bibliothèque de mathématiques

Fonction Description Go C++ Java Python C
math.greatest Renvoie le plus grand des arguments numériques (ou d'une liste de nombres).

Signatures :
math.greatest(arg, ...) -> T

Exemples :
math.greatest(1, 3, 2) // 3
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
math.least Renvoie le plus petit des arguments numériques (ou la liste des arguments numériques).

Signatures :
math.least(arg, ...) -> T

Exemples :
math.least([1, 3, 2]) // 1
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
math.abs Valeur absolue.

Signatures :
math.abs(T) -> T (compatible avec 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 Racine carrée.

Signatures :
math.sqrt(T) -> double (accepte 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 Opérateur AND (ET) bit à bit.

Signatures :
math.bitAnd(T, T) -> T (compatible avec 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 Opérateur OR (OU) bit à bit.

Signatures :
math.bitOr(T, T) -> T (compatible avec 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 Opérateur XOR (OU exclusif) bit à bit.

Signatures :
math.bitXor(T, T) -> T (compatible avec 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 à bit.

Signatures :
math.bitNot(T) -> T (compatible avec int, uint)<br /><br />**Examples:**<br />math.bitNot(1) // -2`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitShiftLeft Décalage à gauche bit à bit.

Signatures :
math.bitShiftLeft(T, int) -> T (compatible avec 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 Décalage à droite bit à bit.

Signatures :
math.bitShiftRight(T, int) -> T (compatible avec 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 Arrondi au plafond.

Signatures :
math.ceil(double) -> double

Exemples :
math.ceil(1.2) // 2.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.floor Arrondi à l'inférieur.

Signatures :
math.floor(double) -> double

Exemples :
math.floor(1.8) // 1.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.round Arrondi à l'entier le plus proche.

Signatures :
math.round(double) -> double

Exemples :
math.round(1.5) // 2.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.trunc Arrondi par troncature (vers zéro).

Signatures :
math.trunc(double) -> double

Exemples :
math.trunc(-1.8) // -1.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.isInf Vérifie si la valeur double correspond à l'infini positif ou négatif.

Signatures :
math.isInf(double) -> bool

Exemples :
math.isInf(1.0/0.0) // true
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.isNaN Vérifie si la valeur double est NaN.

Signatures :
math.isNaN(double) -> bool

Exemples :
math.isNaN(0.0/0.0) // true
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.isFinite Vérifie si la valeur double est finie.

Signatures :
math.isFinite(double) -> bool

Exemples :
math.isFinite(1.2) // true
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.sign Renvoie le signe de la valeur (-1, 0 ou 1).

Signatures
math.sign(T) -> T (compatible avec int, uint, double)<br /><br />**Examples:**<br />math.sign(-42) // -1`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)

Activer

Bibliothèque de protos

Fonction Description Go C++ Java Python C
proto.getExt Récupère le champ d'extension proto2 ou la valeur par défaut s'il n'est pas défini.

Signatures :
proto.getExt(msg, extName) -> T

Exemples :
proto.getExt(msg, google.api.expr.test.int32_ext)
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
proto.hasExt Vérifie si le champ d'extension proto2 est défini.

Signatures :
proto.hasExt(msg, extName) -> bool

Exemples :
proto.hasExt(msg, google.api.expr.test.int32_ext)
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)

Activer

  • Aller : transmettez ext.Protos() à cel.NewEnv().
  • C++ : ajoutez ProtoExtCompilerLibrary() à CompilerBuilder. (L'environnement d'exécution est géré automatiquement.)
  • Java : ajoutez CelExtensions.protos() aux générateurs CelCompiler et CelRuntime.
  • Python : importez cel_expr_python.ext.ext_proto et utilisez ExtProto() dans cel.NewEnv(extensions=[...]).

Bibliothèque de listes

Fonction Description Go C++ Java Python C
distinct Renvoie des éléments distincts.

Signatures :
list.distinct() -> list

Exemples :
[1, 2, 2].distinct() // [1, 2]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
flatten Aplatit les listes imbriquées.

Signatures :
list.flatten([depth]) -> list

Exemples :
[[1], [2, 3]].flatten() // [1, 2, 3]
(v0.22.0) (v0.11.0) (v0.7.1) (v0.1.1)
lists.range Renvoie une liste d'entiers [0, ..., n-1].

Signatures :
lists.range(int) -> list(int)

Exemples :
lists.range(3) // [0, 1, 2]
(v0.22.0) (v0.11.0) (v0.10.1) (v0.1.1)
reverse Inverse l'ordre des éléments de la liste.

Signatures :
list.reverse() -> list

Exemples :
[1, 2].reverse() // [2, 1]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
slice Renvoie une sous-liste (début inclus, fin exclus).

Signatures :
list.slice(start, end) -> list

Exemples :
[1, 2, 3].slice(1, 3) // [2, 3]
(v0.17.0) (v0.11.0) (v0.11.0) (v0.1.1)
sort Trie la liste des éléments comparables.

Signatures :
list.sort() -> list

Exemples :
[3, 1, 2].sort() // [1, 2, 3]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
sortBy Trie la liste par clé évaluée à partir de l'expression.

Signatures :
list.sortBy(var, expr) -> list

Exemples :
[{"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 Renvoie le premier élément comme facultatif. Nécessite l'extension facultative.

Signatures :
list.first() -> optional

Exemples :
[1, 2].first() // optional(1)
(v0.23.0) (v0.15.0) (v0.11.0) (v0.1.2)
last Renvoie le dernier élément comme facultatif. Nécessite l'extension facultative.

Signatures :
list.last() -> optional

Exemples :
[1, 2].last() // optional(2)
(v0.23.0) (v0.15.0) (v0.11.0) (v0.1.2)

Activer

Bibliothèque de sets

Fonction Description Go C++ Java Python C
sets.contains Vérifie si list1 contient tous les éléments de list2.

Signatures :
sets.contains(list1, list2) -> bool

Exemples :
sets.contains([1, 2], [1]) // true
(v0.15.0) (v0.10.0) (v0.6.0) (v0.1.1)
sets.equivalent Vérifie si les listes sont équivalentes (contiennent les mêmes éléments uniques).

Signatures :
sets.equivalent(list1, list2) -> bool

Exemples :
sets.equivalent([1, 2], [2, 1, 1]) // true
(v0.15.0) (v0.10.0) (v0.6.0) (v0.1.1)
sets.intersects Vérifie si les listes partagent au moins un élément.

Signatures :
sets.intersects(list1, list2) -> bool

Exemples :
sets.intersects([1, 2], [2, 3]) // true
(v0.15.0) (v0.10.0) (v0.6.0) (v0.1.1)

Activer

Bibliothèque de chaînes

Fonction Description Go C++ Java Python C
charAt Renvoie le caractère à l'index.

Signatures :
string.charAt(int) -> string

Exemples :
"hello".charAt(1) // "e"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
indexOf Renvoie l'index de la première occurrence de la sous-chaîne ou -1.

Signatures :
string.indexOf(substr, [start]) -> int

Exemples :
"hello".indexOf("l") // 2
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
lastIndexOf Renvoie l'index de la dernière occurrence de la sous-chaîne, ou -1.

Signatures :
string.lastIndexOf(substr, [end]) -> int

Exemples :
"hello".lastIndexOf("l") // 3
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
join Concatène des chaînes.

Signatures :
list(string).join([separator]) -> string

Exemples :
["a", "b"].join("-") // "a-b"
(v0.10.0) (v0.10.0) (v0.2.0) (v0.1.1)
split Divise la chaîne par le séparateur.

Signatures :
string.split(separator, [limit]) -> list(string)

Exemples :
"a-b".split("-") // ["a", "b"]
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
substring Renvoie la sous-chaîne (début inclus, fin exclus).

Signatures :
string.substring(start, [end]) -> string

Exemples :
"hello".substring(1, 3) // "el"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
trim Supprime les espaces blancs Unicode.

Signatures :
string.trim() -> string

Exemples :
" hello ".trim() // "hello"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
replace Remplace les occurrences de l'ancienne valeur par la nouvelle.

Signatures :
string.replace(old, new, [limit]) -> string

Exemples :
"hello".replace("l", "w") // "hewwo"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
reverse Inverse les points de code Unicode.

Signatures :
string.reverse() -> string

Exemples :
"abc".reverse() // "cba"
(v0.18.0) (v0.14.0) (v0.13.0) (v0.1.1)
lowerAscii Convertit les caractères ASCII en minuscules.

Signatures
string.lowerAscii() -> string

Exemples
"Hello".lowerAscii() // "hello"
(v0.6.0) (v0.11.0) (v0.2.0) (v0.1.1)
upperAscii Convertit les caractères ASCII en majuscules.

Signatures
string.upperAscii() -> string

Exemples
"Hello".upperAscii() // "HELLO"
(v0.6.0) (v0.11.0) (v0.2.0) (v0.1.1)
quote Échappe la chaîne pour une impression sécurisée.

Signatures :
strings.quote(string) -> string

Exemples :
strings.quote("a\tb") // "\"a\\tb\""
(v0.14.0) (v0.14.0) (v0.13.0) (v0.1.1)

Activer

Bibliothèque d'expressions régulières

Fonction Description Go C++ Java Python C
regex.replace Remplace les correspondances par une chaîne de remplacement (accepte les références arrière).

Signatures :
regex.replace(target, pat, repl, [limit]) -> string

Exemples :
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 Renvoie la première correspondance du modèle (doit comporter un groupe de capture).

Signatures :
regex.extract(target, pat) -> optional(string)

Exemples :
regex.extract("a123b", r"(\d+)") // optional("123")
(v0.25.1) (v0.13.0) (v0.10.1) (v0.1.1)
regex.extractAll Renvoie toutes les correspondances du modèle (doit comporter un groupe de capture).

Signatures :
regex.extractAll(target, pat) -> list(string)

Exemples :
regex.extractAll("a1b2", r"(\d+)") // ["1", "2"]
(v0.25.1) (v0.13.0) (v0.10.1) (v0.1.1)

Activer

Compréhensions à deux variables

Macro Description Go C++ Java Python C
all Court-circuit logique AND sur la clé/l'index et la valeur.

Signatures :
list.all(i, v, pred) -> bool
map.all(k, v, pred) -> bool

Exemples :
[1, 2].all(i, v, v > 0) // true
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
exists Court-circuit logique OR sur la clé/l'index et la valeur.

Signatures :
list.exists(i, v, pred) -> bool
map.exists(k, v, pred) -> bool

Exemples :
[1, 2].exists(i, v, v == 2) // true
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
existsOne Vérifie si une seule paire satisfait le prédicat.

Signatures :
list.existsOne(i, v, pred) -> bool
map.existsOne(k, v, pred) -> bool

Exemples :
[1, 2].existsOne(i, v, v == 2) // true
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
transformList Transforme/filtre une liste/carte en liste.

Signatures :
list.transformList(i, v, [filter], transform) -> list
map.transformList(k, v, [filter], transform) -> list

Exemples :
[1, 2].transformList(i, v, v * 2) // [2, 4]
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
transformMap Transforme les valeurs de la liste/du mappage en mappage (les clés restent fixes).

Signatures :
list.transformMap(i, v, [filter], transform) -> map
map.transformMap(k, v, [filter], transform) -> map

Exemples :
[1, 2].transformMap(i, v, v * 2) // {0: 2, 1: 4}
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
transformMapEntry Se transforme en carte.

Signatures :
list.transformMapEntry(i, v, [filter], transform_entry) -> map
map.transformMapEntry(k, v, [filter], transform_entry) -> map

Exemples :
[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)

Activer

Bibliothèque de types natifs

Fonctionnalité Description Go C++ Java Python C
Structs natifs Enregistrement et instanciation des types natifs de l'hôte (structs Go / POJO Java) dans CEL.

Exemples :
Account{id: 123} (POJO Java instancié dans CEL)
(v0.13.0) (v0.13.0)

Activer

  • Go: Pass ext.NativeTypes(...) (providing reflect types) to cel.NewEnv().
  • C++ : non compatible.
  • Java : ajoutez CelExtensions.nativeTypes() (qui fournit des classes Java) aux compilateurs CelCompiler et CelRuntime.
  • Python : non compatible.

Bibliothèque réseau

La bibliothèque Network fournit des fonctions permettant d'analyser, de valider et de manipuler les adresses IP et les blocs CIDR.

Fonction Description Go C++ Java Python C
ip Analyse une chaîne pour la convertir en adresse IP ou extrait l'adresse IP d'un CIDR.

Signatures :
ip(string) -> IP
CIDR.ip() -> IP

Exemples :
ip("192.168.0.1")
cidr("192.168.0.0/24").ip()
(v0.29.0)
isIP Vérifie si une chaîne est une adresse IP valide.

Signatures :
isIP(string) -> bool

Exemples :
isIP("192.168.0.1") // true
(v0.29.0)
ip.isCanonical Vérifie si une chaîne d'adresse IP est au format canonique.

Signatures :
ip.isCanonical(string) -> bool

Exemples :
ip.isCanonical("192.168.0.1") // true
(v0.29.0)
cidr Analyse une chaîne pour la convertir en bloc CIDR.

Signatures :
cidr(string) -> CIDR

Exemples :
cidr("192.168.0.0/24")
(v0.29.0)
isCIDR Vérifie si une chaîne est un bloc CIDR valide.

Signatures
isCIDR(string) -> bool

Exemples
isCIDR("192.168.0.0/24") // true
(v0.29.0)
containsIP Vérifie si un bloc CIDR contient une adresse IP.

Signatures :
CIDR.containsIP(IP) -> bool
CIDR.containsIP(string) -> bool

Exemples :
cidr("192.168.0.0/24").containsIP(ip("192.168.0.1")) // true
(v0.29.0)
containsCIDR Vérifie si un bloc CIDR contient un autre bloc CIDR.

Signatures :
CIDR.containsCIDR(CIDR) -> bool
CIDR.containsCIDR(string) -> bool

Exemples :
cidr("192.168.0.0/16").containsCIDR(cidr("192.168.1.0/24")) // true
(v0.29.0)
family Renvoie la famille d'adresses IP (4 pour IPv4, 6 pour IPv6).

Signatures :
IP.family() -> int

Exemples :
ip("192.168.0.1").family() // 4
(v0.29.0)
isGlobalUnicast Vérifie si l'adresse IP est une adresse unicast globale.

Signatures :
IP.isGlobalUnicast() -> bool

Exemples :
ip("192.168.0.1").isGlobalUnicast() // true
(v0.29.0)
isLinkLocalMulticast Vérifie si l'adresse IP est une adresse de multidiffusion de liaison locale.

Signatures :
IP.isLinkLocalMulticast() -> bool

Exemples :
ip("224.0.0.1").isLinkLocalMulticast() // true
(v0.29.0)
isLinkLocalUnicast Vérifie si l'adresse IP est une adresse unicast link-local.

Signatures :
IP.isLinkLocalUnicast() -> bool

Exemples :
ip("169.254.0.1").isLinkLocalUnicast() // true
(v0.29.0)
isLoopback Vérifie si l'adresse IP est une adresse de bouclage.

Signatures :
IP.isLoopback() -> bool

Exemples :
ip("127.0.0.1").isLoopback() // true
(v0.29.0)
isMask Vérifie si le CIDR est un masque de sous-réseau valide.

Signatures :
CIDR.isMask() -> bool

Exemples :
cidr("255.255.255.0/24").isMask() // true
(v0.29.0)
isUnspecified Vérifie si l'adresse IP est une adresse non spécifiée (par exemple, 0.0.0.0).

Signatures :
IP.isUnspecified() -> bool

Exemples :
ip("0.0.0.0").isUnspecified() // true
(v0.29.0)
masked Renvoie le bloc CIDR masqué.

Signatures :
CIDR.masked() -> CIDR

Exemples :
cidr("192.168.0.1/24").masked() // 192.168.0.0/24
(v0.29.0)
prefixLength Renvoie la longueur du préfixe du bloc CIDR.

Signatures
CIDR.prefixLength() -> int

Exemples
cidr("192.168.0.0/24").prefixLength() // 24
(v0.29.0)
string Convertit une adresse IP ou un bloc CIDR en chaîne.

Signatures :
string(IP) -> string
string(CIDR) -> string

Exemples :
string(ip("192.168.0.1")) // "192.168.0.1"
(v0.29.0)

Activer

  • Aller : transmettez ext.Network() à cel.NewEnv().
  • C++ : non compatible.
  • Java : non compatible.
  • Python : non compatible.

5. Fonctionnalités avancées

Récapitulatif des fonctionnalités avancées

Fonctionnalité Description Go C++ Java Python C
Évaluation partielle Évalue avec des entrées manquantes ; renvoie des inconnues ou une expression simplifiée. ³
Évaluation asynchrone Exécution simultanée non bloquante des fonctions d'extension.
Validateurs AST L'analyse statique effectue des vérifications sur l'AST Checked après la vérification du type.
Optimiseurs AST Réécritures AST (pliage constant, inlining, CSE) pour améliorer les performances.
Compilateur de règles CEL Compile les structures de règles basées sur YAML en AST CEL standards.

³ Go permet de générer un AST résiduel (AST élagué). ⁴ C++ et Java permettent de renvoyer UnknownSet / CelUnknownSet au moment de l'exécution, mais n'exposent pas d'API publiques pour la génération d'AST résiduel. ⁵ Go utilise des canaux de retour AsyncBinding / AsyncOp. ⁶ Java utilise CelAsyncRuntime et renvoie ListenableFuture.

Évaluation partielle (inconnues)

L'évaluation partielle permet d'évaluer une expression lorsque seul un sous-ensemble des variables d'entrée (arguments) est connu. Au lieu d'échouer, l'évaluation produit un résultat qui indique ce qui manque ou une expression simplifiée.

  • Go : assistance complète. Permet de définir un PartialActivation avec des modèles d'attributs inconnus. L'évaluation renvoie une valeur types.Unknown. Go permet de générer un AST résiduel (Env.ResidualAst), qui est un AST élagué et simplifié ne contenant que les parties de l'expression qui n'ont pas pu être évaluées.
  • C++ : compatible avec les valeurs Unknown. Les modèles d'attributs inconnus sont configurés via Activation::set_unknown_attribute_patterns. L'évaluation renvoie un UnknownSet. L'API publique n'expose pas actuellement la génération d'AST résiduel.
  • Java : compatible avec l'évaluation partielle via PartialVars transmis à Program.eval(). L'évaluation renvoie un CelUnknownSet. L'API publique n'expose pas actuellement la génération d'AST résiduel.
  • Python / C : aucune compatibilité native.

Évaluation asynchrone

L'évaluation asynchrone permet aux expressions CEL d'appeler des fonctions qui s'exécutent de manière asynchrone (par exemple, en effectuant des RPC ou des requêtes de base de données) et de bloquer l'évaluation jusqu'à ce que les résultats soient disponibles, sans bloquer le thread d'exécution principal.

  • Go : compatible avec les surcharges de fonctions asynchrones via AsyncBinding et AsyncOp. Les fonctions asynchrones renvoient un canal Go (<-chan ref.Val), et l'interpréteur gère l'exécution et la synchronisation simultanées.
  • Java : compatible avec l'évaluation asynchrone via CelAsyncRuntime et AsyncProgram. Il utilise ListenableFuture pour représenter les valeurs en attente et effectue automatiquement l'évaluation à mesure que les futurs sont résolus.
  • C++, Python et C : aucune compatibilité intégrée.

Outils de validation AST

Les validateurs effectuent une analyse statique sur l'AST vérifié après la vérification du type pour appliquer des contraintes spécifiques au domaine avant l'exécution du programme.

  • Go : compatible avec l'interface ASTValidator. Les validateurs canoniques incluent cel.validator.duration, cel.validator.timestamp, cel.validator.matches (expression régulière), cel.validator.homogeneous_literals et cel.validator.comprehension_nesting_limit.
  • C++ : compatible avec cel::Validator. Les validations canoniques incluent AstDepthValidator, ComprehensionNestingLimitValidator, DurationLiteralValidator, HomogeneousLiteralValidator, MatchesValidator et TimestampLiteralValidator.
  • Java : compatible avec CelValidator et CelAstValidator. Les validateurs canoniques incluent AstDepthLimitValidator, ComprehensionNestingLimitValidator, DurationLiteralValidator, HomogeneousLiteralValidator, RegexLiteralValidator et TimestampLiteralValidator.
  • Python / C : aucune compatibilité directe.

Optimiseurs AST

Les optimiseurs réécrivent l'AST pour améliorer les performances d'exécution. Les optimiseurs se divisent en deux catégories : les optimiseurs statiques et les optimiseurs d'exécution. C++, Java et Go sont compatibles avec l'optimisation de l'exécution. CEL Java et Go sont également compatibles avec les optimiseurs statiques. Les optimisations types incluent le pliage constant (pré-évaluation des sous-expressions avec des entrées constantes) et l'élimination des sous-expressions communes (CSE).

  • Go : compatible avec le pliage AST lors de la compilation/planification.
  • C++ : compatible avec le pliage constant via l'extension cel::extensions::EnableConstantFolding au moment de la planification.
  • Java : compatible avec l'interface CelOptimizer. Les optimiseurs canoniques incluent ConstantFoldingOptimizer (qui peut plier les branches de court-circuit en simulant une évaluation partielle), InliningOptimizer et SubexpressionOptimizer (CSE).
  • Python / C : aucune compatibilité directe.

Compilateur de règles CEL

Une stratégie CEL est un format basé sur YAML permettant de composer plusieurs expressions CEL avec des variables, des blocs de correspondance, des sorties conditionnelles et des règles imbriquées. Il est conçu pour les moteurs de règles complexes (comme le contrôle des admissions Kubernetes) où les expressions CEL uniques deviendraient illisibles.

Le compilateur de règles compile ces règles YAML en un seul AST CEL standard, ce qui signifie qu'elles sont entièrement compatibles avec les runtimes CEL standards et qu'elles héritent de toutes les garanties de performances et de sécurité.

  • Go : compatible avec third_party/cel/go/policy.
  • C++ : compatible avec third_party/cel/cpp/policy.
  • Java : compatible avec third_party/java/cel/policy.
  • Python / C : non compatible directement.