Этот документ служит единым справочником API для языка выражений Common Expression Language (CEL). В нем перечислены все макросы, операторы и стандартные функции, указаны их сигнатуры, поведение и статус поддержки во всех официальных стеках CEL.
Для получения более подробной информации о поведении и спецификациях языка обратитесь к определению языка CEL .
Версии стека
Данный справочный документ основан на следующих версиях стеков CEL:
- CEL Go :
v0.32.0(и более новые версии) - CELC C++ :
v0.16.1 - CEL Java :
v0.14.0 - CEL Python :
v0.1.3 - CEL C : Снимок процесса разработки (не выпущен)
Зеркала GitHub
Официальные реализации CEL представлены на GitHub в рамках организации cel-expr :
1. Основные макросы
Это встроенные макросы, которые разворачиваются во время компиляции.
| Макро | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
has(container.field) | Проверяет, присутствует ли поле в сообщении или ключ в карте. Подписи: has(container.field) -> boolПримеры: has(request.auth.claims.email) | ✓ | ✓ | ✓ | ✓ | ✓ |
list.all(var, predicate) | Проверяет, удовлетворяют ли все элементы списка заданному предикату. Подписи: list.all(var, predicate) -> boolПримеры: [1, 2, 3].all(x, x > 0) // true | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.exists(var, predicate) | Проверяет, удовлетворяет ли хотя бы один элемент списка предикату. Подписи: list.exists(var, predicate) -> boolПримеры: [1, 2, 3].exists(x, x > 2) // true | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.exists_one(var, predicate) | Проверяет, удовлетворяет ли ровно один элемент списка предикату. Подписи: list.exists_one(var, predicate) -> boolПримеры: [1, 2, 3].exists_one(x, x == 2) // true | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.filter(var, predicate) | Фильтрует элементы списка в соответствии с предикатом. Подписи: list.filter(var, predicate) -> listПримеры: [1, 2, 3].filter(x, x > 1) // [2, 3] | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.map(var, transform) | Преобразует каждый элемент списка с помощью выражения. Подписи: list.map(var, transform) -> listПримеры: [1, 2, 3].map(x, x * 2) // [2, 4, 6] | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.map(var, filter, transform) | Преобразует элементы списка, удовлетворяющие предикату фильтра. Подписи: list.map(var, filter, transform) -> listПримеры: [1, 2, 3].map(x, x > 1, x * 2) // [4, 6] | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
¹ Поддерживается в среде выполнения C, поскольку макросы разворачиваются в списковые выражения во время компиляции хост-компилятором.
2. Основные операторы
| Оператор | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
Арифметические операции ( + , - , * , / , % ) | Стандартные арифметические операции. Отрицание ( -x ) и тождество ( +x ). Конкатенация списков ( list + list ) поддерживается в Go, C++, Java и Python.Подписи: T + T -> TT - T -> TT * T -> TT / T -> TT % T -> T-T -> T+T -> Tlist + list -> listПримеры: 1 + 2 * 3 // 7[1] + [2] // [1, 2] | ✓ | ✓ | ✓ | ✓ | ✓ ² |
Сравнение ( == , != , < , <= , > , >= ) | Стандартное сравнение. Числовые сравнения неоднородны (например, 1 == 1.0 ).Подписи: T == T -> boolT != T -> boolT < T -> boolT <= T -> boolT > T -> boolT >= T -> boolПримеры: x < 42.01 == 1.0 // true | ✓ | ✓ | ✓ | ✓ | ✓ |
Логическое ( ! , && , || , ? : ) | Логические операторы НЕ, И, ИЛИ и троичные условные операторы. Операторы И/ИЛИ используют сокращенную оценку. Подписи: !bool -> boolbool && bool -> boolbool || bool -> boolbool ? T : T -> TПримеры: x > 0 ? "positive" : "non-positive" | ✓ | ✓ | ✓ | ✓ | ✓ |
Индексирование ( [] ) | Доступ к элементу списка осуществляется по индексу или по ключу поиска в карте. Подписи: list[int] -> Tmap[K] -> VПримеры: tags[0]users['john'] | ✓ | ✓ | ✓ | ✓ | ✓ |
Членство ( in ) | Проверьте, находится ли элемент в списке или ключ в карте. Подписи: T in list -> boolK in map -> boolПримеры: 'admin' in roles | ✓ | ✓ | ✓ | ✓ | ✓ |
² Конкатенация списков ( list + list ) не поддерживается в среде выполнения C, хотя другие арифметические операторы поддерживаются.
3. Основные функции
Общие и строковые функции
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
size | Возвращает размер строки (символов), байтов, списка или карты. Подписи: size(T) -> int (где T — string , bytes , list или map )Примеры: size("hello") // 5 | ✓ | ✓ | ✓ | ✓ | ✓ |
contains | Возвращает true, если строка содержит подстроку. Подписи: string.contains(string) -> boolПримеры: "hello".contains("ell") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
startsWith | Возвращает значение, указывающее, начинается ли строка с префикса. Подписи: string.startsWith(string) -> boolПримеры: "hello".startsWith("he") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
endsWith | Возвращает значение, указывающее, заканчивается ли строка суффиксом. Подписи: string.endsWith(string) -> boolПримеры: "hello".endsWith("lo") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
matches | Возвращает значение, указывающее, соответствует ли строка регулярному выражению RE2. Подписи: string.matches(string) -> boolПримеры: "123".matches(r"^\d+$") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
Функции выбора даты и времени
Эти функции извлекают компоненты из google.protobuf.Timestamp или google.protobuf.Duration .
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
getFullYear | Возвращает четырехзначный год. Подписи: timestamp.getFullYear([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getFullYear() // 2026 | ✓ | ✓ | ✓ | ✓ | ✗ |
getMonth | Возвращает месяц (от 0 до 11). Подписи: timestamp.getMonth([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getMonth() // 6 | ✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfMonth | Возвращает день месяца (1-31). Подписи: timestamp.getDayOfMonth([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getDayOfMonth() // 23 | ✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfWeek | Возвращает день недели (0 = воскресенье). Подписи: timestamp.getDayOfWeek([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getDayOfWeek() // 4 | ✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfYear | Возвращает день года (0-365). Подписи: timestamp.getDayOfYear([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getDayOfYear() // 203 | ✓ | ✓ | ✓ | ✓ | ✗ |
getHours | Возвращает количество часов (от 0 до 23). Подписи: timestamp.getHours([tz]) -> intduration.getHours() -> intПримеры: duration("1h30m").getHours() // 1 | ✓ | ✓ | ✓ | ✓ | ✗ |
getMinutes | Возвращает количество минут (от 0 до 59). Подписи: timestamp.getMinutes([tz]) -> intduration.getMinutes() -> intПримеры: duration("1h30m").getMinutes() // 30 | ✓ | ✓ | ✓ | ✓ | ✗ |
getSeconds | Возвращает секунды (от 0 до 59). Подписи: timestamp.getSeconds([tz]) -> intduration.getSeconds() -> intПримеры: duration("1h30m45s").getSeconds() // 45 | ✓ | ✓ | ✓ | ✓ | ✗ |
getMilliseconds | Возвращает значение в миллисекундах (0-999). Подписи: timestamp.getMilliseconds([tz]) -> intduration.getMilliseconds() -> intПримеры: duration("1.5s").getMilliseconds() // 500 | ✓ | ✓ | ✓ | ✓ | ✗ |
Преобразование типов
| Тип цели | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
bool | Преобразует в логическое значение. Подписи: bool(bool) -> boolbool(string) -> boolПримеры: bool("true") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
bytes | Преобразует в байты. Подписи: bytes(bytes) -> bytesbytes(string) -> bytesПримеры: bytes("hello") // b"hello" | ✓ | ✓ | ✓ | ✓ | ✓ |
double | Преобразует в число с плавающей запятой двойной точности. Подписи: double(double) -> doubledouble(int) -> doubledouble(uint) -> doubledouble(string) -> doubleПримеры: double(1) // 1.0 | ✓ | ✓ | ✓ | ✓ | ✓ |
duration | Преобразуется в продолжительность. Подписи: duration(duration) -> durationduration(string) -> durationПримеры: duration("1.5s") // 1.5s duration | ✓ | ✓ | ✓ | ✓ | ✓ |
int | Преобразует в 64-битное знаковое целое число. Подписи: int(int) -> intint(uint) -> intint(double) -> int (округляет до нуля)int(string) -> intint(timestamp) -> int (секунд с начала эпохи)Примеры: int(1.5) // 1 | ✓ | ✓ | ✓ | ✓ | ✓ |
string | Преобразует в строку. Подписи: string(T) -> string (поддерживает bool , int , uint , double , bytes , timestamp , duration )Примеры: string(1.5) // "1.5" | ✓ | ✓ | ✓ | ✓ | ✓ |
timestamp | Преобразует в метку времени. Подписи: timestamp(timestamp) -> timestamptimestamp(string) -> timestamp (RFC3339)Примеры: timestamp("2026-07-23T00:00:00Z") | ✓ | ✓ | ✓ | ✓ | ✓ |
uint | Преобразует в 64-битное беззнаковое целое число. Подписи: uint(uint) -> uintuint(int) -> uintuint(double) -> uintuint(string) -> uintПримеры: uint(1) // 1u | ✓ | ✓ | ✓ | ✓ | ✓ |
dyn | Приводит значение к динамическому типу для проверки типа. Подписи: dyn(T) -> dynПримеры: dyn([1, "two"]) | ✓ | ✓ | ✓ | ✓ | ✗ |
type | Возвращает тип значения. Подписи: type(T) -> typeПримеры: type(1) // int | ✓ | ✓ | ✓ | ✓ | ✗ |
4. Дополнительные ресурсы (библиотеки)
Библиотека переплетов
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
cel.bind | Привязывает локальную переменную для предотвращения повторной оценки. Подписи: cel.bind(varName, initExpr, resultExpr) -> TПримеры: cel.bind(x, a + b, x * x) | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Передайте
ext.Bindings()вcel.NewEnv(). - C++: Добавьте
BindingsCompilerLibrary()вCompilerBuilder. (Обработка во время выполнения происходит автоматически). - Java: Добавить
CelExtensions.bindings()в сборщикиCelCompilerиCelRuntime. - Python: Импортируйте
cel_expr_python.ext.ext_bindingsи используйтеExtBindings()вcel.NewEnv(extensions=[...]).
Библиотека кодировщиков
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
base64.encode | Кодирует байты в строку base64. Подписи: base64.encode(bytes) -> stringПримеры: base64.encode(b"hello") // "aGVsbG8=" | ✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
base64.decode | Декодирует строку base64 в байты. Выдает ошибку при недопустимом вводе. Подписи: base64.decode(string) -> bytesПримеры: base64.decode("aGVsbG8=") // b"hello" | ✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
json.encode | Сериализует значение CEL в строку JSON. Подписи: json.encode(dyn) -> stringПримеры: json.encode([1, 2]) // "[1,2]" | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Передайте
ext.Encoders()вcel.NewEnv(). - C++:
- Компилятор: Добавьте
EncodersCompilerLibrary()вCompilerBuilder. - Во время выполнения: вызовите
RegisterEncodersFunctions()дляFunctionRegistry.
- Компилятор: Добавьте
- Java: Добавить
CelExtensions.encoders()в сборщикиCelCompilerиCelRuntime. - Python: Импортируйте
cel_expr_python.ext.ext_encodersи используйтеExtEncoders()вcel.NewEnv(extensions=[...]).
Математическая библиотека
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
math.greatest | Возвращает наибольшее из числовых аргументов (или список числовых значений). Подписи: math.greatest(arg, ...) -> TПримеры: math.greatest(1, 3, 2) // 3 | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.least | Возвращает наименьшее из числовых аргументов (или список числовых значений). Подписи: math.least(arg, ...) -> TПримеры: math.least([1, 3, 2]) // 1 | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.abs | Абсолютное значение. Подписи: math.abs(T) -> T (поддерживает int , uint , double )Примеры: math.abs(-1) // 1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sqrt | Квадратный корень. Подписи: math.sqrt(T) -> double (поддерживает int , uint , double )Примеры: math.sqrt(9) // 3.0 | ✓ (v0.25.1) | ✓ (v0.12.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
math.bitAnd | Побитовое И. Подписи: math.bitAnd(T, T) -> T (поддерживает int , uint )Примеры: math.bitAnd(5, 3) // 1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitOr | Побитовое ИЛИ. Подписи: math.bitOr(T, T) -> T (поддерживает int , uint )Примеры: math.bitOr(5, 3) // 7 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitXor | Побитовое XOR. Подписи: math.bitXor(T, T) -> T (поддерживает int , uint )Примеры: math.bitXor(5, 3) // 6 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitNot | Побитовое НЕ. Подписи: math.bitNot(T) -> T (поддерживает int , uint )Примеры: math.bitNot(1) // -2 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftLeft | Побитовый сдвиг влево. Подписи: math.bitShiftLeft(T, int) -> T (поддерживает int , uint )Примеры: math.bitShiftLeft(1, 2) // 4 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftRight | Побитовый сдвиг вправо. Подписи: math.bitShiftRight(T, int) -> T (поддерживает int , uint )Примеры: math.bitShiftRight(4, 2) // 1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.ceil | Закругление потолка. Подписи: math.ceil(double) -> doubleПримеры: math.ceil(1.2) // 2.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.floor | Скругление пола. Подписи: math.floor(double) -> doubleПримеры: math.floor(1.8) // 1.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.round | Округление до ближайшего целого числа. Подписи: math.round(double) -> doubleПримеры: math.round(1.5) // 2.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.trunc | Округление с отсечением (в сторону нуля). Подписи: math.trunc(double) -> doubleПримеры: math.trunc(-1.8) // -1.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isInf | Проверяет, является ли double положительным или отрицательным значением бесконечности. Подписи: math.isInf(double) -> boolПримеры: math.isInf(1.0/0.0) // true | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isNaN | Проверяет, является ли значение типа double значением NaN. Подписи: math.isNaN(double) -> boolПримеры: math.isNaN(0.0/0.0) // true | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isFinite | Проверяет, является ли тип double конечным. Подписи: math.isFinite(double) -> boolПримеры: math.isFinite(1.2) // true | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sign | Возвращает знак значения (-1, 0 или 1). Подписи: math.sign(T) -> T (поддерживает int , uint , double )Примеры: math.sign(-42) // -1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Передайте
ext.Math()вcel.NewEnv(). - C++:
- Компилятор: Добавьте
MathCompilerLibrary()вCompilerBuilder. - Во время выполнения: вызовите
RegisterMathExtensionFunctions()дляFunctionRegistry.
- Компилятор: Добавьте
- Java: Добавить
CelExtensions.math()в сборщикиCelCompilerиCelRuntime. - Python: Импортируйте
cel_expr_python.ext.ext_mathи используйтеExtMath()вcel.NewEnv(extensions=[...]).
Библиотека Протос
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
proto.getExt | Получает поле расширения proto2 или значение по умолчанию, если оно не задано. Подписи: proto.getExt(msg, extName) -> TПримеры: proto.getExt(msg, google.api.expr.test.int32_ext) | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
proto.hasExt | Проверяет, задано ли поле расширения proto2. Подписи: proto.hasExt(msg, extName) -> boolПримеры: proto.hasExt(msg, google.api.expr.test.int32_ext) | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Передайте
ext.Protos()вcel.NewEnv(). - C++: Добавьте
ProtoExtCompilerLibrary()вCompilerBuilder. (Обработка во время выполнения происходит автоматически). - Java: Добавить
CelExtensions.protos()в сборщикиCelCompilerиCelRuntime. - Python: Импортируйте
cel_expr_python.ext.ext_protoи используйтеExtProto()вcel.NewEnv(extensions=[...]).
Библиотека списков
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
distinct | Возвращает уникальные элементы. Подписи: list.distinct() -> listПримеры: [1, 2, 2].distinct() // [1, 2] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
flatten | Сглаживает вложенные списки. Подписи: list.flatten([depth]) -> listПримеры: [[1], [2, 3]].flatten() // [1, 2, 3] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.7.1) | ✓ (v0.1.1) | ✗ |
lists.range | Возвращает список целых чисел [0, ..., n-1] .Подписи: lists.range(int) -> list(int)Примеры: lists.range(3) // [0, 1, 2] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
reverse | Переворачивает список. Подписи: list.reverse() -> listПримеры: [1, 2].reverse() // [2, 1] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
slice | Возвращает подсписок (начало включительно, конец исключая). Подписи: list.slice(start, end) -> listПримеры: [1, 2, 3].slice(1, 3) // [2, 3] | ✓ (v0.17.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sort | Сортирует список сопоставимых элементов. Подписи: list.sort() -> listПримеры: [3, 1, 2].sort() // [1, 2, 3] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sortBy | Сортирует список по ключу, вычисленному на основе выражения. Подписи: list.sortBy(var, expr) -> listПримеры: [{"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 | Возвращает первый элемент как необязательный. Требуется расширение Optional. Подписи: list.first() -> optionalПримеры: [1, 2].first() // optional(1) | ✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
last | Возвращает последний элемент как необязательный. Требуется расширение Optional. Подписи: list.last() -> optionalПримеры: [1, 2].last() // optional(2) | ✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
Как включить
- Go: Передайте
ext.Lists()вcel.NewEnv(). - C++:
- Компилятор: Добавьте
ListsCompilerLibrary()вCompilerBuilder. - Во время выполнения: вызовите
RegisterListsFunctions()дляFunctionRegistryиRegisterListsMacros()дляMacroRegistry.
- Компилятор: Добавьте
- Java: Добавить
CelExtensions.lists()в сборщикиCelCompilerиCelRuntime. - Python: Включить через
cel.EnvConfig, добавивlistsв списокextensions.
Библиотека наборов
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
sets.contains | Проверяет, содержит ли список list1 все элементы списка list2. Подписи: sets.contains(list1, list2) -> boolПримеры: sets.contains([1, 2], [1]) // true | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.equivalent | Проверяет, являются ли списки эквивалентными множествам (содержат ли они одинаковые уникальные элементы). Подписи: sets.equivalent(list1, list2) -> boolПримеры: sets.equivalent([1, 2], [2, 1, 1]) // true | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.intersects | Проверяет, есть ли в списках хотя бы один общий элемент. Подписи: sets.intersects(list1, list2) -> boolПримеры: sets.intersects([1, 2], [2, 3]) // true | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Передайте
ext.Sets()вcel.NewEnv(). - C++:
- Компилятор: Добавьте
SetsCompilerLibrary()вCompilerBuilder. - Во время выполнения: вызовите метод
RegisterSetsFunctions()дляFunctionRegistry.
- Компилятор: Добавьте
- Java: Добавить
CelExtensions.sets()в сборщикиCelCompilerиCelRuntime. - Python: Включить через
cel.EnvConfig, добавивsetsв списокextensions.
Библиотека струн
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
charAt | Возвращает символ по указанному индексу. Подписи: string.charAt(int) -> stringПримеры: "hello".charAt(1) // "e" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
indexOf | Возвращает индекс первого вхождения подстроки или -1. Подписи: string.indexOf(substr, [start]) -> intПримеры: "hello".indexOf("l") // 2 | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
lastIndexOf | Возвращает индекс последнего вхождения подстроки или -1. Подписи: string.lastIndexOf(substr, [end]) -> intПримеры: "hello".lastIndexOf("l") // 3 | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
join | Объединяет строки. Подписи: list(string).join([separator]) -> stringПримеры: ["a", "b"].join("-") // "ab" | ✓ (v0.10.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
split | Разделяет строку по разделителю. Подписи: string.split(separator, [limit]) -> list(string)Примеры: "ab".split("-") // ["a", "b"] | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
substring | Возвращает подстроку (начало включительно, конец исключая). Подписи: string.substring(start, [end]) -> stringПримеры: "hello".substring(1, 3) // "el" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
trim | Удаляет пробелы в кодировке Unicode. Подписи: string.trim() -> stringПримеры: " hello ".trim() // "hello" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
replace | Заменяет старые вхождения новыми. Подписи: string.replace(old, new, [limit]) -> stringПримеры: "hello".replace("l", "w") // "hewwo" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
reverse | Переворачивает кодовые точки Unicode. Подписи: string.reverse() -> stringПримеры: "abc".reverse() // "cba" | ✓ (v0.18.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
lowerAscii | Преобразует символы ASCII в нижний регистр. Подписи: string.lowerAscii() -> stringПримеры: "Hello".lowerAscii() // "hello" | ✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
upperAscii | Преобразует символы ASCII в верхний регистр. Подписи: string.upperAscii() -> stringПримеры: "Hello".upperAscii() // "HELLO" | ✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
quote | Экранирует строку для безопасной печати. Подписи: strings.quote(string) -> stringПримеры: strings.quote("a\tb") // "\"a\\tb\"" | ✓ (v0.14.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
format | Форматирует строку, используя заполнители в стиле printf. Подписи: string.format(list) -> stringПримеры: "str: %s, int: %d".format(["a", 1]) // "str: a, int: 1" | ✓ (v0.14.0) | ✓ (v0.11.0) | ✗ | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Передайте
ext.Strings()вcel.NewEnv(). - C++:
- Компилятор: Добавьте
StringsCompilerLibrary()вCompilerBuilder. - Во время выполнения: вызовите метод
RegisterStringsFunctions()дляFunctionRegistry.
- Компилятор: Добавьте
- Java: Добавить
CelExtensions.strings()в сборщикиCelCompilerиCelRuntime. - Python: Импортируйте
cel_expr_python.ext.ext_stringsи используйтеExtStrings()вcel.NewEnv(extensions=[...]).
Библиотека регулярных выражений
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
regex.replace | Заменяет найденные значения строкой-заменителем (поддерживает обратные ссылки). Подписи: regex.replace(target, pat, repl, [limit]) -> stringПримеры: 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 | Возвращает первое совпадение шаблона (должно содержать одну группу захвата). Подписи: regex.extract(target, pat) -> optional(string)Примеры: regex.extract("a123b", r"(\d+)") // optional("123") | ✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
regex.extractAll | Возвращает все совпадения шаблона (должна содержать одну группу захвата). Подписи: regex.extractAll(target, pat) -> list(string)Примеры: regex.extractAll("a1b2", r"(\d+)") // ["1", "2"] | ✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Передайте
ext.Regex()вcel.NewEnv(). - C++:
- Компилятор: Добавьте
RegexExtCompilerLibrary()вCompilerBuilder. - Во время выполнения: вызовите метод
RegisterRegexExtensionFunctions()дляFunctionRegistry.
- Компилятор: Добавьте
- Java: Добавить
CelExtensions.regex()в сборщикиCelCompilerиCelRuntime. - Python: Включить через
cel.EnvConfig, добавивregexиoptionalв списокextensions.
Понимание двух переменных
| Макро | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
all | Замыкание логической операции И по ключу/индексу и значению. Подписи: list.all(i, v, pred) -> boolmap.all(k, v, pred) -> boolПримеры: [1, 2].all(i, v, v > 0) // true | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
exists | Замедление логического ИЛИ по ключу/индексу и значению. Подписи: list.exists(i, v, pred) -> boolmap.exists(k, v, pred) -> boolПримеры: [1, 2].exists(i, v, v == 2) // true | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
existsOne | Проверяет, удовлетворяет ли предикат ровно одна пара условий. Подписи: list.existsOne(i, v, pred) -> boolmap.existsOne(k, v, pred) -> boolПримеры: [1, 2].existsOne(i, v, v == 2) // true | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformList | Преобразует/фильтрует список/карту в список. Подписи: list.transformList(i, v, [filter], transform) -> listmap.transformList(k, v, [filter], transform) -> listПримеры: [1, 2].transformList(i, v, v * 2) // [2, 4] | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMap | Преобразует значения списка/карты в карту (ключи остаются неизменными). Подписи: list.transformMap(i, v, [filter], transform) -> mapmap.transformMap(k, v, [filter], transform) -> mapПримеры: [1, 2].transformMap(i, v, v * 2) // {0: 2, 1: 4} | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMapEntry | Превращается в карту. Подписи: list.transformMapEntry(i, v, [filter], transform_entry) -> mapmap.transformMapEntry(k, v, [filter], transform_entry) -> mapПримеры: [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) | ✗ |
Как включить
- Go: Передайте
ext.TwoVarComprehensions()вcel.NewEnv(). - C++:
- Компилятор: Добавить
ComprehensionsV2CompilerLibrary()вCompilerBuilder. - Во время выполнения: вызовите
RegisterComprehensionsV2Functions()дляFunctionRegistryиRegisterComprehensionsV2Macros()дляMacroRegistry.
- Компилятор: Добавить
- Java: Добавить
CelExtensions.comprehensions()в построителиCelCompilerиCelRuntime. - Python: Включить через
cel.EnvConfig, добавивtwo-var-comprehensionsв списокextensions.
Библиотека исходных типов
| Особенность | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
| Местные сооружения | Регистрация и создание экземпляров собственных типов хоста (структур Go / POJO-объектов Java) в CEL. Примеры: Account{id: 123} (Java POJO, созданный в CEL) | ✓ (v0.13.0) | ✗ | ✓ (v0.13.0) | ✗ | ✗ |
Как включить
- Go: Передайте
cel.NativeTypes(...)илиext.NativeTypes(...)(предоставляющие типы отражения) вcel.NewEnv(). - C++: Не поддерживается.
- Java: Добавить
CelExtensions.nativeTypes()(предоставляющий Java-классы) в сборщикиCelCompilerиCelRuntime. - Python: Не поддерживается.
Сетевая библиотека
Библиотека Network предоставляет функции для анализа, проверки и обработки IP-адресов и блоков CIDR.
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
ip | Преобразует строку в IP-адрес или извлекает IP-адрес из CIDR-диапазона. Подписи: ip(string) -> IPCIDR.ip() -> IPПримеры: ip("192.168.0.1")cidr("192.168.0.0/24").ip() | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isIP | Проверяет, является ли строка допустимым IP-адресом. Подписи: isIP(string) -> boolПримеры: isIP("192.168.0.1") // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
ip.isCanonical | Проверяет, соответствует ли строка IP-адреса своему каноническому формату. Подписи: ip.isCanonical(string) -> boolПримеры: ip.isCanonical("192.168.0.1") // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
cidr | Преобразует строку в блок CIDR. Подписи: cidr(string) -> CIDRПримеры: cidr("192.168.0.0/24") | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isCIDR | Проверяет, является ли строка допустимым блоком CIDR. Подписи: isCIDR(string) -> boolПримеры: isCIDR("192.168.0.0/24") // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsIP | Проверяет, содержит ли блок CIDR IP-адрес. Подписи: CIDR.containsIP(IP) -> boolCIDR.containsIP(string) -> boolПримеры: cidr("192.168.0.0/24").containsIP(ip("192.168.0.1")) // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsCIDR | Проверяет, содержит ли один блок CIDR другой блок CIDR. Подписи: CIDR.containsCIDR(CIDR) -> boolCIDR.containsCIDR(string) -> boolПримеры: cidr("192.168.0.0/16").containsCIDR(cidr("192.168.1.0/24")) // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
family | Возвращает семейство IP-адресов (4 для IPv4, 6 для IPv6). Подписи: IP.family() -> intПримеры: ip("192.168.0.1").family() // 4 | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isGlobalUnicast | Проверяет, является ли IP-адрес глобальным одноадресным адресом. Подписи: IP.isGlobalUnicast() -> boolПримеры: ip("192.168.0.1").isGlobalUnicast() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalMulticast | Проверяет, является ли IP-адрес локальным многоадресным адресом. Подписи: IP.isLinkLocalMulticast() -> boolПримеры: ip("224.0.0.1").isLinkLocalMulticast() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalUnicast | Проверяет, является ли IP-адрес локальным одноадресным адресом. Подписи: IP.isLinkLocalUnicast() -> boolПримеры: ip("169.254.0.1").isLinkLocalUnicast() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLoopback | Проверяет, является ли IP-адрес адресом замыкания (loopback). Подписи: IP.isLoopback() -> boolПримеры: ip("127.0.0.1").isLoopback() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isMask | Проверяет, является ли CIDR допустимой маской подсети. Подписи: CIDR.isMask() -> boolПримеры: cidr("255.255.255.0/24").isMask() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isUnspecified | Проверяет, является ли IP-адрес неуказанным (например, 0.0.0.0 ).Подписи: IP.isUnspecified() -> boolПримеры: ip("0.0.0.0").isUnspecified() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
masked | Возвращает замаскированный блок CIDR. Подписи: CIDR.masked() -> CIDRПримеры: cidr("192.168.0.1/24").masked() // 192.168.0.0/24 | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
prefixLength | Возвращает длину префикса блока CIDR. Подписи: CIDR.prefixLength() -> intПримеры: cidr("192.168.0.0/24").prefixLength() // 24 | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
string | Преобразует IP-адрес или CIDR в строку. Подписи: string(IP) -> stringstring(CIDR) -> stringПримеры: string(ip("192.168.0.1")) // "192.168.0.1" | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Передайте
ext.Network()вcel.NewEnv(). - C++: Не поддерживается.
- Java: не поддерживается.
- Python: Не поддерживается.
Библиотека JWT
Библиотека JWT предоставляет типы данных и вспомогательные функции для анализа JSON Web Tokens (JWT) и проверки стандартных и пользовательских утверждений.
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
jwt.parse | Преобразует необработанную строку токена в структурированный объект jwt.Token , обернутый в необязательный параметр.Подписи: jwt.parse(string) -> optional(jwt.Token)Примеры: jwt.parse(token_string).hasValue() | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
claim | Выполняет запрос к пользовательскому значению утверждения по имени ключа из полезной нагрузки токена. Подписи: jwt.Token.claim(string) -> optional(dyn)optional(jwt.Token).claim(string) -> optional(dyn)Примеры: jwt.parse(token).claim("tenant").orValue("") | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
presentedBy | Проверяет соответствие эмитента и целевой аудитории токена ожидаемым значениям. Подписи: jwt.Token.presentedBy(string, string) -> booloptional(jwt.Token).presentedBy(string, string) -> boolПримеры: jwt.parse(token).presentedBy("https://auth.example.com", "https://api.example.com") | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Импортируйте
cel.dev/cel-go/ext/security/jwtи передайтеjwt.Library()вcel.NewEnv(). - C++: Не поддерживается.
- Java: не поддерживается.
- Python: Не поддерживается.
Библиотека HMAC
Библиотека HMAC предоставляет криптографические функции для вычисления и проверки хеш-кодов аутентификации сообщений (HMAC) для строк и последовательностей байтов.
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
hmac.compute | Вычисляет необработанные байты HMAC-подписи, используя указанный алгоритм и секретный ключ. Подписи: hmac.compute(string, string|bytes, string|bytes) -> bytesПримеры: hmac.compute(hmac.SHA256, "secret", "message") | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
hmac.verify | Проверяет, соответствует ли сигнатура HMAC ожидаемому дайджесту. Подписи: hmac.verify(string, string|bytes, string|bytes, string|bytes) -> boolПримеры: hmac.verify(hmac.SHA256, secret, msg, expected_sig) // true | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Импортируйте
cel.dev/cel-go/ext/security/hmacи передайтеhmac.Library()вcel.NewEnv(). - C++: Не поддерживается.
- Java: не поддерживается.
- Python: Не поддерживается.
5. Расширенные функции
Краткое описание расширенных функций
| Особенность | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
| Частичная оценка | Выполняет оценку при наличии недостающих входных данных; возвращает неизвестные значения или упрощенное выражение. | ✓ ³ | ✓ ⁴ | ✓ ⁴ | ✗ | ✗ |
| Асинхронная оценка | Неблокирующее параллельное выполнение функций расширения. | ✓ ⁵ | ✗ | ✓ ⁶ | ✗ | ✗ |
| Валидаторы AST | Статический анализ проверяется в AST после проверки типов. | ✓ | ✓ | ✓ | ✗ | ✗ |
| Оптимизаторы AST | Переписывание AST (свертывание констант, встраивание, CSE) для повышения производительности. | ✓ | ✓ | ✓ | ✗ | ✗ |
| Компилятор политик CEL | Компилирует структуры политик на основе YAML в стандартные CEL AST. | ✓ | ✓ | ✓ | ✗ | ✗ |
| Формальная верификация | Доказывает инварианты безопасности, выполнимость, валидность и эквивалентность AST. | ✗ | ✗ | ✓ (v0.14.0) | ✗ | ✗ |
³ Go поддерживает генерацию остаточного AST (усеченного AST). ⁴ C++ и Java поддерживают возврат UnknownSet / CelUnknownSet во время выполнения, но не предоставляют публичных API для генерации остаточного AST. ⁵ Go использует AsyncBinding / AsyncOp , возвращающие каналы. ⁶ Java использует CelAsyncRuntime возвращающий ListenableFuture .
Частичная оценка (неизвестные данные)
Частичная оценка позволяет вычислить выражение, когда известно лишь подмножество входных переменных (аргументов). Вместо ошибки, оценка выдает результат, указывающий на недостающие данные, или упрощенное выражение.
- Go: Полная поддержка. Позволяет определять
PartialActivationс шаблонами неизвестных атрибутов. Результат вычисления возвращает значение типаtypes.Unknown. Go поддерживает генерацию остаточного AST (Env.ResidualAst), который представляет собой усеченное, упрощенное AST, содержащее только те части выражения, которые не удалось вычислить. - C++: Поддерживает
Unknownзначения. Шаблоны неизвестных атрибутов настраиваются с помощьюActivation::set_unknown_attribute_patterns. Результат вычисления возвращаетUnknownSet. В настоящее время публичный API не предоставляет возможность генерации остаточного AST. - Java: Поддерживает частичную оценку с помощью
PartialVarsпередаваемых вProgram.eval(). Результат оценки возвращаетCelUnknownSet. В настоящее время публичный API не предоставляет возможность генерации остаточного AST. - Python / C: Отсутствует встроенная поддержка.
Асинхронная оценка
Асинхронная оценка позволяет выражениям CEL вызывать функции, которые выполняются асинхронно (например, при выполнении RPC-вызовов или запросов к базе данных), и блокировать оценку до тех пор, пока не станут доступны результаты, не блокируя при этом основной поток выполнения.
- Go: Поддерживает асинхронные перегрузки функций с помощью
AsyncBindingиAsyncOp. Асинхронные функции возвращают канал Go (<-chan ref.Val), а интерпретатор управляет параллельным выполнением и синхронизацией. - Java: Поддерживает асинхронную оценку с помощью
CelAsyncRuntimeиAsyncProgram. ИспользуетListenableFutureдля представления ожидающих значений и автоматически доводит оценку до завершения по мере разрешения Future. - C++ / Python / C: Встроенная поддержка отсутствует.
Валидаторы AST
После проверки типов валидаторы выполняют статический анализ проверяемого абстрактного синтаксического дерева (AST) для обеспечения соблюдения ограничений, специфичных для предметной области, перед выполнением программы.
- Go: Поддерживает интерфейс
ASTValidator. Канонические валидаторы включаютcel.validator.duration,cel.validator.timestamp,cel.validator.matches(regex),cel.validator.homogeneous_literalsиcel.validator.comprehension_nesting_limit. - C++: Поддерживает
cel::Validator. Канонические проверки включаютAstDepthValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,MatchesValidatorиTimestampLiteralValidator. - Java: Поддерживает
CelValidatorиCelAstValidator. Канонические валидаторы включаютAstDepthLimitValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,RegexLiteralValidatorиTimestampLiteralValidator. - Python / C: Прямая поддержка отсутствует.
Оптимизаторы AST
Оптимизаторы переписывают абстрактное синтаксическое дерево (AST) для повышения производительности выполнения. Оптимизаторы делятся на две категории: статические и оптимизаторы времени выполнения. C++, Java и Go поддерживают оптимизацию времени выполнения. CEL Java и Go также поддерживают статические оптимизаторы.
Типичные методы оптимизации включают в себя постоянное свертывание (предварительная оценка подвыражений с постоянными входными данными) и исключение общих подвыражений (CSE).
- Go: Поддерживает свертывание AST во время компиляции/планирования.
- C++: Поддерживает свертывание констант с помощью расширения
cel::extensions::EnableConstantFoldingна этапе планирования. - Java: Поддерживает интерфейс
CelOptimizer. Канонические оптимизаторы включаютConstantFoldingOptimizer(поддерживает обход в порядке предварительного просмотра, свертывание констант сообщений Protobuf и агрегированное или необязательное отсечение),InliningOptimizerиSubexpressionOptimizer(CSE). - Python / C: Прямая поддержка отсутствует.
Компилятор политик CEL
CEL Policy — это формат на основе YAML для объединения нескольких выражений CEL с переменными, блоками соответствия, условными выходными данными и вложенными правилами. Он разработан для сложных механизмов управления политиками (таких как Kubernetes Admission Control), где отдельные выражения CEL стали бы нечитаемыми.
Для получения информации о формальном определении языка, синтаксисе и наборе стандартов соответствия обратитесь к спецификации политики CEL .
Компилятор политик объединяет эти политики YAML в единый стандартный CEL AST, что означает их полную совместимость со стандартными средами выполнения CEL и сохранение всех гарантий производительности и безопасности.
- Go: Поддерживается посредством политики Go (включая семантику оценки агрегированных правил).
- C++: Поддерживается в соответствии с политикой C++ .
- Java: Поддерживается через политику Java (включая семантику оценки агрегированных правил и сокращенные спецификаторы типов в конфигурациях политики).
- Python / C: Прямая поддержка отсутствует.
Структура формальной верификации
Структура формальной верификации позволяет пользователям математически доказывать инварианты безопасности, логическую эквивалентность, выполнимость и достоверность выражений CEL и структурированных политик CEL.
- Java: Поддерживается через CEL Java Verifier (
dev.cel:verifierиdev.cel:verifier-cli). Возможности включают проверку выполнимости (isSatisfiable) с генерацией входных данных-свидетелей, проверку валидности (isAlwaysTrue) с генерацией контрпримеров, ограниченную проверку моделей (BMC) для списковых представлений, доказательства логической эквивалентности между AST и пользовательскую проверку инвариантов политикиassume/assert. - Go / C++ / Python / C: Поддерживаются косвенно через инструментарий командной строки Java.
Для ознакомления и примеров из реальной жизни см. сообщение в блоге Google Open Source: Обеспечение безопасности в эпоху агентного управления: внедрение формальной верификации для CEL .
,Этот документ служит единым справочником API для языка выражений Common Expression Language (CEL). В нем перечислены все макросы, операторы и стандартные функции, указаны их сигнатуры, поведение и статус поддержки во всех официальных стеках CEL.
Для получения более подробной информации о поведении и спецификациях языка обратитесь к определению языка CEL .
Версии стека
Данный справочный документ основан на следующих версиях стеков CEL:
- CEL Go :
v0.32.0(и более новые версии) - CELC C++ :
v0.16.1 - CEL Java :
v0.14.0 - CEL Python :
v0.1.3 - CEL C : Снимок процесса разработки (не выпущен)
Зеркала GitHub
Официальные реализации CEL представлены на GitHub в рамках организации cel-expr :
1. Основные макросы
Это встроенные макросы, которые разворачиваются во время компиляции.
| Макро | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
has(container.field) | Проверяет, присутствует ли поле в сообщении или ключ в карте. Подписи: has(container.field) -> boolПримеры: has(request.auth.claims.email) | ✓ | ✓ | ✓ | ✓ | ✓ |
list.all(var, predicate) | Проверяет, удовлетворяют ли все элементы списка заданному предикату. Подписи: list.all(var, predicate) -> boolПримеры: [1, 2, 3].all(x, x > 0) // true | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.exists(var, predicate) | Проверяет, удовлетворяет ли хотя бы один элемент списка предикату. Подписи: list.exists(var, predicate) -> boolПримеры: [1, 2, 3].exists(x, x > 2) // true | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.exists_one(var, predicate) | Проверяет, удовлетворяет ли ровно один элемент списка предикату. Подписи: list.exists_one(var, predicate) -> boolПримеры: [1, 2, 3].exists_one(x, x == 2) // true | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.filter(var, predicate) | Фильтрует элементы списка в соответствии с предикатом. Подписи: list.filter(var, predicate) -> listПримеры: [1, 2, 3].filter(x, x > 1) // [2, 3] | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.map(var, transform) | Преобразует каждый элемент списка с помощью выражения. Подписи: list.map(var, transform) -> listПримеры: [1, 2, 3].map(x, x * 2) // [2, 4, 6] | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.map(var, filter, transform) | Преобразует элементы списка, удовлетворяющие предикату фильтра. Подписи: list.map(var, filter, transform) -> listПримеры: [1, 2, 3].map(x, x > 1, x * 2) // [4, 6] | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
¹ Поддерживается в среде выполнения C, поскольку макросы разворачиваются в списковые выражения во время компиляции хост-компилятором.
2. Основные операторы
| Оператор | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
Арифметические операции ( + , - , * , / , % ) | Стандартные арифметические операции. Отрицание ( -x ) и тождество ( +x ). Конкатенация списков ( list + list ) поддерживается в Go, C++, Java и Python.Подписи: T + T -> TT - T -> TT * T -> TT / T -> TT % T -> T-T -> T+T -> Tlist + list -> listПримеры: 1 + 2 * 3 // 7[1] + [2] // [1, 2] | ✓ | ✓ | ✓ | ✓ | ✓ ² |
Сравнение ( == , != , < , <= , > , >= ) | Стандартное сравнение. Числовые сравнения неоднородны (например, 1 == 1.0 ).Подписи: T == T -> boolT != T -> boolT < T -> boolT <= T -> boolT > T -> boolT >= T -> boolПримеры: x < 42.01 == 1.0 // true | ✓ | ✓ | ✓ | ✓ | ✓ |
Логическое ( ! , && , || , ? : ) | Логические операторы НЕ, И, ИЛИ и троичные условные операторы. Операторы И/ИЛИ используют сокращенную оценку. Подписи: !bool -> boolbool && bool -> boolbool || bool -> boolbool ? T : T -> TПримеры: x > 0 ? "positive" : "non-positive" | ✓ | ✓ | ✓ | ✓ | ✓ |
Индексирование ( [] ) | Доступ к элементу списка осуществляется по индексу или по ключу поиска в карте. Подписи: list[int] -> Tmap[K] -> VПримеры: tags[0]users['john'] | ✓ | ✓ | ✓ | ✓ | ✓ |
Членство ( in ) | Проверьте, находится ли элемент в списке или ключ в карте. Подписи: T in list -> boolK in map -> boolПримеры: 'admin' in roles | ✓ | ✓ | ✓ | ✓ | ✓ |
² Конкатенация списков ( list + list ) не поддерживается в среде выполнения C, хотя другие арифметические операторы поддерживаются.
3. Основные функции
Общие и строковые функции
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
size | Возвращает размер строки (символов), байтов, списка или карты. Подписи: size(T) -> int (где T — string , bytes , list или map )Примеры: size("hello") // 5 | ✓ | ✓ | ✓ | ✓ | ✓ |
contains | Возвращает true, если строка содержит подстроку. Подписи: string.contains(string) -> boolПримеры: "hello".contains("ell") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
startsWith | Возвращает значение, указывающее, начинается ли строка с префикса. Подписи: string.startsWith(string) -> boolПримеры: "hello".startsWith("he") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
endsWith | Возвращает значение, указывающее, заканчивается ли строка суффиксом. Подписи: string.endsWith(string) -> boolПримеры: "hello".endsWith("lo") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
matches | Возвращает значение, указывающее, соответствует ли строка регулярному выражению RE2. Подписи: string.matches(string) -> boolПримеры: "123".matches(r"^\d+$") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
Функции выбора даты и времени
Эти функции извлекают компоненты из google.protobuf.Timestamp или google.protobuf.Duration .
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
getFullYear | Возвращает четырехзначный год. Подписи: timestamp.getFullYear([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getFullYear() // 2026 | ✓ | ✓ | ✓ | ✓ | ✗ |
getMonth | Возвращает месяц (от 0 до 11). Подписи: timestamp.getMonth([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getMonth() // 6 | ✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfMonth | Возвращает день месяца (1-31). Подписи: timestamp.getDayOfMonth([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getDayOfMonth() // 23 | ✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfWeek | Возвращает день недели (0 = воскресенье). Подписи: timestamp.getDayOfWeek([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getDayOfWeek() // 4 | ✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfYear | Возвращает день года (0-365). Подписи: timestamp.getDayOfYear([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getDayOfYear() // 203 | ✓ | ✓ | ✓ | ✓ | ✗ |
getHours | Возвращает количество часов (от 0 до 23). Подписи: timestamp.getHours([tz]) -> intduration.getHours() -> intПримеры: duration("1h30m").getHours() // 1 | ✓ | ✓ | ✓ | ✓ | ✗ |
getMinutes | Возвращает количество минут (от 0 до 59). Подписи: timestamp.getMinutes([tz]) -> intduration.getMinutes() -> intПримеры: duration("1h30m").getMinutes() // 30 | ✓ | ✓ | ✓ | ✓ | ✗ |
getSeconds | Возвращает секунды (от 0 до 59). Подписи: timestamp.getSeconds([tz]) -> intduration.getSeconds() -> intПримеры: duration("1h30m45s").getSeconds() // 45 | ✓ | ✓ | ✓ | ✓ | ✗ |
getMilliseconds | Возвращает значение в миллисекундах (0-999). Подписи: timestamp.getMilliseconds([tz]) -> intduration.getMilliseconds() -> intПримеры: duration("1.5s").getMilliseconds() // 500 | ✓ | ✓ | ✓ | ✓ | ✗ |
Преобразование типов
| Тип цели | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
bool | Преобразует в логическое значение. Подписи: bool(bool) -> boolbool(string) -> boolПримеры: bool("true") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
bytes | Преобразует в байты. Подписи: bytes(bytes) -> bytesbytes(string) -> bytesПримеры: bytes("hello") // b"hello" | ✓ | ✓ | ✓ | ✓ | ✓ |
double | Преобразует в число с плавающей запятой двойной точности. Подписи: double(double) -> doubledouble(int) -> doubledouble(uint) -> doubledouble(string) -> doubleПримеры: double(1) // 1.0 | ✓ | ✓ | ✓ | ✓ | ✓ |
duration | Преобразуется в продолжительность. Подписи: duration(duration) -> durationduration(string) -> durationПримеры: duration("1.5s") // 1.5s duration | ✓ | ✓ | ✓ | ✓ | ✓ |
int | Преобразует в 64-битное знаковое целое число. Подписи: int(int) -> intint(uint) -> intint(double) -> int (округляет до нуля)int(string) -> intint(timestamp) -> int (секунд с начала эпохи)Примеры: int(1.5) // 1 | ✓ | ✓ | ✓ | ✓ | ✓ |
string | Преобразует в строку. Подписи: string(T) -> string (поддерживает bool , int , uint , double , bytes , timestamp , duration )Примеры: string(1.5) // "1.5" | ✓ | ✓ | ✓ | ✓ | ✓ |
timestamp | Преобразует в метку времени. Подписи: timestamp(timestamp) -> timestamptimestamp(string) -> timestamp (RFC3339)Примеры: timestamp("2026-07-23T00:00:00Z") | ✓ | ✓ | ✓ | ✓ | ✓ |
uint | Преобразует в 64-битное беззнаковое целое число. Подписи: uint(uint) -> uintuint(int) -> uintuint(double) -> uintuint(string) -> uintПримеры: uint(1) // 1u | ✓ | ✓ | ✓ | ✓ | ✓ |
dyn | Приводит значение к динамическому типу для проверки типа. Подписи: dyn(T) -> dynПримеры: dyn([1, "two"]) | ✓ | ✓ | ✓ | ✓ | ✗ |
type | Возвращает тип значения. Подписи: type(T) -> typeПримеры: type(1) // int | ✓ | ✓ | ✓ | ✓ | ✗ |
4. Дополнительные ресурсы (библиотеки)
Библиотека переплетов
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
cel.bind | Привязывает локальную переменную для предотвращения повторной оценки. Подписи: cel.bind(varName, initExpr, resultExpr) -> TПримеры: cel.bind(x, a + b, x * x) | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Передайте
ext.Bindings()вcel.NewEnv(). - C++: Добавьте
BindingsCompilerLibrary()вCompilerBuilder. (Обработка во время выполнения происходит автоматически). - Java: Добавить
CelExtensions.bindings()в сборщикиCelCompilerиCelRuntime. - Python: Импортируйте
cel_expr_python.ext.ext_bindingsи используйтеExtBindings()вcel.NewEnv(extensions=[...]).
Библиотека кодировщиков
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
base64.encode | Кодирует байты в строку base64. Подписи: base64.encode(bytes) -> stringПримеры: base64.encode(b"hello") // "aGVsbG8=" | ✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
base64.decode | Декодирует строку base64 в байты. Выдает ошибку при недопустимом вводе. Подписи: base64.decode(string) -> bytesПримеры: base64.decode("aGVsbG8=") // b"hello" | ✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
json.encode | Сериализует значение CEL в строку JSON. Подписи: json.encode(dyn) -> stringПримеры: json.encode([1, 2]) // "[1,2]" | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Передайте
ext.Encoders()вcel.NewEnv(). - C++:
- Компилятор: Добавьте
EncodersCompilerLibrary()вCompilerBuilder. - Во время выполнения: вызовите
RegisterEncodersFunctions()дляFunctionRegistry.
- Компилятор: Добавьте
- Java: Добавить
CelExtensions.encoders()в сборщикиCelCompilerиCelRuntime. - Python: Импортируйте
cel_expr_python.ext.ext_encodersи используйтеExtEncoders()вcel.NewEnv(extensions=[...]).
Математическая библиотека
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
math.greatest | Возвращает наибольшее из числовых аргументов (или список числовых значений). Подписи: math.greatest(arg, ...) -> TПримеры: math.greatest(1, 3, 2) // 3 | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.least | Возвращает наименьшее из числовых аргументов (или список числовых значений). Подписи: math.least(arg, ...) -> TПримеры: math.least([1, 3, 2]) // 1 | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.abs | Абсолютное значение. Подписи: math.abs(T) -> T (поддерживает int , uint , double )Примеры: math.abs(-1) // 1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sqrt | Квадратный корень. Подписи: math.sqrt(T) -> double (поддерживает int , uint , double )Примеры: math.sqrt(9) // 3.0 | ✓ (v0.25.1) | ✓ (v0.12.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
math.bitAnd | Побитовое И. Подписи: math.bitAnd(T, T) -> T (поддерживает int , uint )Примеры: math.bitAnd(5, 3) // 1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitOr | Побитовое ИЛИ. Подписи: math.bitOr(T, T) -> T (поддерживает int , uint )Примеры: math.bitOr(5, 3) // 7 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitXor | Побитовое XOR. Подписи: math.bitXor(T, T) -> T (поддерживает int , uint )Примеры: math.bitXor(5, 3) // 6 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitNot | Побитовое НЕ. Подписи: math.bitNot(T) -> T (поддерживает int , uint )Примеры: math.bitNot(1) // -2 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftLeft | Побитовый сдвиг влево. Подписи: math.bitShiftLeft(T, int) -> T (поддерживает int , uint )Примеры: math.bitShiftLeft(1, 2) // 4 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftRight | Побитовый сдвиг вправо. Подписи: math.bitShiftRight(T, int) -> T (поддерживает int , uint )Примеры: math.bitShiftRight(4, 2) // 1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.ceil | Закругление потолка. Подписи: math.ceil(double) -> doubleПримеры: math.ceil(1.2) // 2.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.floor | Скругление пола. Подписи: math.floor(double) -> doubleПримеры: math.floor(1.8) // 1.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.round | Округление до ближайшего целого числа. Подписи: math.round(double) -> doubleПримеры: math.round(1.5) // 2.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.trunc | Округление с отсечением (в сторону нуля). Подписи: math.trunc(double) -> doubleПримеры: math.trunc(-1.8) // -1.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isInf | Проверяет, является ли double положительным или отрицательным значением бесконечности. Подписи: math.isInf(double) -> boolПримеры: math.isInf(1.0/0.0) // true | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isNaN | Проверяет, является ли значение типа double значением NaN. Подписи: math.isNaN(double) -> boolПримеры: math.isNaN(0.0/0.0) // true | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isFinite | Проверяет, является ли тип double конечным. Подписи: math.isFinite(double) -> boolПримеры: math.isFinite(1.2) // true | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sign | Возвращает знак значения (-1, 0 или 1). Подписи: math.sign(T) -> T (поддерживает int , uint , double )Примеры: math.sign(-42) // -1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Передайте
ext.Math()вcel.NewEnv(). - C++:
- Компилятор: Добавьте
MathCompilerLibrary()вCompilerBuilder. - Во время выполнения: вызовите
RegisterMathExtensionFunctions()дляFunctionRegistry.
- Компилятор: Добавьте
- Java: Добавить
CelExtensions.math()в сборщикиCelCompilerиCelRuntime. - Python: Импортируйте
cel_expr_python.ext.ext_mathи используйтеExtMath()вcel.NewEnv(extensions=[...]).
Библиотека Протос
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
proto.getExt | Получает поле расширения proto2 или значение по умолчанию, если оно не задано. Подписи: proto.getExt(msg, extName) -> TПримеры: proto.getExt(msg, google.api.expr.test.int32_ext) | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
proto.hasExt | Проверяет, задано ли поле расширения proto2. Подписи: proto.hasExt(msg, extName) -> boolПримеры: proto.hasExt(msg, google.api.expr.test.int32_ext) | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Передайте
ext.Protos()вcel.NewEnv(). - C++: Добавьте
ProtoExtCompilerLibrary()вCompilerBuilder. (Обработка во время выполнения происходит автоматически). - Java: Добавить
CelExtensions.protos()в сборщикиCelCompilerиCelRuntime. - Python: Импортируйте
cel_expr_python.ext.ext_protoи используйтеExtProto()вcel.NewEnv(extensions=[...]).
Библиотека списков
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
distinct | Возвращает уникальные элементы. Подписи: list.distinct() -> listПримеры: [1, 2, 2].distinct() // [1, 2] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
flatten | Сглаживает вложенные списки. Подписи: list.flatten([depth]) -> listПримеры: [[1], [2, 3]].flatten() // [1, 2, 3] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.7.1) | ✓ (v0.1.1) | ✗ |
lists.range | Возвращает список целых чисел [0, ..., n-1] .Подписи: lists.range(int) -> list(int)Примеры: lists.range(3) // [0, 1, 2] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
reverse | Переворачивает список. Подписи: list.reverse() -> listПримеры: [1, 2].reverse() // [2, 1] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
slice | Возвращает подсписок (начало включительно, конец исключая). Подписи: list.slice(start, end) -> listПримеры: [1, 2, 3].slice(1, 3) // [2, 3] | ✓ (v0.17.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sort | Сортирует список сопоставимых элементов. Подписи: list.sort() -> listПримеры: [3, 1, 2].sort() // [1, 2, 3] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sortBy | Сортирует список по ключу, вычисленному на основе выражения. Подписи: list.sortBy(var, expr) -> listПримеры: [{"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 | Возвращает первый элемент как необязательный. Требуется расширение Optional. Подписи: list.first() -> optionalПримеры: [1, 2].first() // optional(1) | ✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
last | Возвращает последний элемент как необязательный. Требуется расширение Optional. Подписи: list.last() -> optionalПримеры: [1, 2].last() // optional(2) | ✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
Как включить
- Go: Передайте
ext.Lists()вcel.NewEnv(). - C++:
- Компилятор: Добавьте
ListsCompilerLibrary()вCompilerBuilder. - Во время выполнения: вызовите
RegisterListsFunctions()дляFunctionRegistryиRegisterListsMacros()дляMacroRegistry.
- Компилятор: Добавьте
- Java: Добавить
CelExtensions.lists()в сборщикиCelCompilerиCelRuntime. - Python: Включить через
cel.EnvConfig, добавивlistsв списокextensions.
Библиотека наборов
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
sets.contains | Проверяет, содержит ли список list1 все элементы списка list2. Подписи: sets.contains(list1, list2) -> boolПримеры: sets.contains([1, 2], [1]) // true | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.equivalent | Проверяет, являются ли списки эквивалентными множествам (содержат ли они одинаковые уникальные элементы). Подписи: sets.equivalent(list1, list2) -> boolПримеры: sets.equivalent([1, 2], [2, 1, 1]) // true | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.intersects | Проверяет, есть ли в списках хотя бы один общий элемент. Подписи: sets.intersects(list1, list2) -> boolПримеры: sets.intersects([1, 2], [2, 3]) // true | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Передайте
ext.Sets()вcel.NewEnv(). - C++:
- Компилятор: Добавьте
SetsCompilerLibrary()вCompilerBuilder. - Во время выполнения: вызовите метод
RegisterSetsFunctions()дляFunctionRegistry.
- Компилятор: Добавьте
- Java: Добавить
CelExtensions.sets()в сборщикиCelCompilerиCelRuntime. - Python: Включить через
cel.EnvConfig, добавивsetsв списокextensions.
Библиотека струн
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
charAt | Возвращает символ по указанному индексу. Подписи: string.charAt(int) -> stringПримеры: "hello".charAt(1) // "e" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
indexOf | Возвращает индекс первого вхождения подстроки или -1. Подписи: string.indexOf(substr, [start]) -> intПримеры: "hello".indexOf("l") // 2 | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
lastIndexOf | Возвращает индекс последнего вхождения подстроки или -1. Подписи: string.lastIndexOf(substr, [end]) -> intПримеры: "hello".lastIndexOf("l") // 3 | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
join | Объединяет строки. Подписи: list(string).join([separator]) -> stringПримеры: ["a", "b"].join("-") // "ab" | ✓ (v0.10.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
split | Разделяет строку по разделителю. Подписи: string.split(separator, [limit]) -> list(string)Примеры: "ab".split("-") // ["a", "b"] | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
substring | Возвращает подстроку (начало включительно, конец исключая). Подписи: string.substring(start, [end]) -> stringПримеры: "hello".substring(1, 3) // "el" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
trim | Удаляет пробелы в кодировке Unicode. Подписи: string.trim() -> stringПримеры: " hello ".trim() // "hello" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
replace | Заменяет старые вхождения новыми. Подписи: string.replace(old, new, [limit]) -> stringПримеры: "hello".replace("l", "w") // "hewwo" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
reverse | Переворачивает кодовые точки Unicode. Подписи: string.reverse() -> stringПримеры: "abc".reverse() // "cba" | ✓ (v0.18.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
lowerAscii | Преобразует символы ASCII в нижний регистр. Подписи: string.lowerAscii() -> stringПримеры: "Hello".lowerAscii() // "hello" | ✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
upperAscii | Преобразует символы ASCII в верхний регистр. Подписи: string.upperAscii() -> stringПримеры: "Hello".upperAscii() // "HELLO" | ✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
quote | Экранирует строку для безопасной печати. Подписи: strings.quote(string) -> stringПримеры: strings.quote("a\tb") // "\"a\\tb\"" | ✓ (v0.14.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
format | Formats the string using printf-style placeholders. Signatures: string.format(list) -> stringПримеры: "str: %s, int: %d".format(["a", 1]) // "str: a, int: 1" | ✓ (v0.14.0) | ✓ (v0.11.0) | ✗ | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Strings()tocel.NewEnv(). - C++:
- Compiler: Add
StringsCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterStringsFunctions()onFunctionRegistry.
- Compiler: Add
- Java: Add
CelExtensions.strings()toCelCompilerandCelRuntimebuilders. - Python: Import
cel_expr_python.ext.ext_stringsand useExtStrings()incel.NewEnv(extensions=[...]).
Regular Expression Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
regex.replace | Replaces matches with replacement string (supports backreferences). Signatures: regex.replace(target, pat, repl, [limit]) -> stringПримеры: 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 | Returns first match of pattern (must have one capture group). Signatures: regex.extract(target, pat) -> optional(string)Примеры: regex.extract("a123b", r"(\d+)") // optional("123") | ✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
regex.extractAll | Returns all matches of pattern (must have one capture group). Подписи: regex.extractAll(target, pat) -> list(string)Примеры: regex.extractAll("a1b2", r"(\d+)") // ["1", "2"] | ✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Regex()tocel.NewEnv(). - C++:
- Compiler: Add
RegexExtCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterRegexExtensionFunctions()onFunctionRegistry.
- Compiler: Add
- Java: Add
CelExtensions.regex()toCelCompilerandCelRuntimebuilders. - Python: Enable via
cel.EnvConfigby addingregexandoptionalto theextensionslist.
Two-Variable Comprehensions
| Макро | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
all | Short-circuiting logical AND over key/index and value. Signatures: list.all(i, v, pred) -> boolmap.all(k, v, pred) -> boolПримеры: [1, 2].all(i, v, v > 0) // true | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
exists | Short-circuiting logical OR over key/index and value. Signatures: list.exists(i, v, pred) -> boolmap.exists(k, v, pred) -> boolПримеры: [1, 2].exists(i, v, v == 2) // true | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
existsOne | Checks if exactly one pair satisfies predicate. Signatures: list.existsOne(i, v, pred) -> boolmap.existsOne(k, v, pred) -> boolПримеры: [1, 2].existsOne(i, v, v == 2) // true | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformList | Transforms/filters list/map into a list. Signatures: list.transformList(i, v, [filter], transform) -> listmap.transformList(k, v, [filter], transform) -> listПримеры: [1, 2].transformList(i, v, v * 2) // [2, 4] | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMap | Transforms values of list/map into a map (keys remain fixed). Signatures: list.transformMap(i, v, [filter], transform) -> mapmap.transformMap(k, v, [filter], transform) -> mapПримеры: [1, 2].transformMap(i, v, v * 2) // {0: 2, 1: 4} | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMapEntry | Transforms into a map. Signatures: list.transformMapEntry(i, v, [filter], transform_entry) -> mapmap.transformMapEntry(k, v, [filter], transform_entry) -> mapПримеры: [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) | ✗ |
Как включить
- Go: Pass
ext.TwoVarComprehensions()tocel.NewEnv(). - C++:
- Compiler: Add
ComprehensionsV2CompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterComprehensionsV2Functions()onFunctionRegistryandRegisterComprehensionsV2Macros()onMacroRegistry.
- Compiler: Add
- Java: Add
CelExtensions.comprehensions()toCelCompilerandCelRuntimebuilders. - Python: Enable via
cel.EnvConfigby addingtwo-var-comprehensionsto theextensionslist.
Native Types Library
| Особенность | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
| Native Structs | Registering and instantiating host native types (Go structs / Java POJOs) in CEL. Примеры: Account{id: 123} (Java POJO instanced in CEL) | ✓ (v0.13.0) | ✗ | ✓ (v0.13.0) | ✗ | ✗ |
Как включить
- Go: Pass
cel.NativeTypes(...)orext.NativeTypes(...)(providing reflect types) tocel.NewEnv(). - C++: Not supported.
- Java: Add
CelExtensions.nativeTypes()(providing Java classes) toCelCompilerandCelRuntimebuilders. - Python: Not supported.
Network Library
The Network library provides functions for parsing, validating, and manipulating IP addresses and CIDR blocks.
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
ip | Parses a string into an IP address, or extracts the IP from a CIDR. Signatures: ip(string) -> IPCIDR.ip() -> IPПримеры: ip("192.168.0.1")cidr("192.168.0.0/24").ip() | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isIP | Checks if a string is a valid IP address. Signatures: isIP(string) -> boolПримеры: isIP("192.168.0.1") // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
ip.isCanonical | Checks if an IP address string is in its canonical format. Signatures: ip.isCanonical(string) -> boolПримеры: ip.isCanonical("192.168.0.1") // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
cidr | Parses a string into a CIDR block. Signatures: cidr(string) -> CIDRПримеры: cidr("192.168.0.0/24") | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isCIDR | Checks if a string is a valid CIDR block. Signatures: isCIDR(string) -> boolПримеры: isCIDR("192.168.0.0/24") // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsIP | Checks if a CIDR block contains an IP address. Signatures: CIDR.containsIP(IP) -> boolCIDR.containsIP(string) -> boolПримеры: cidr("192.168.0.0/24").containsIP(ip("192.168.0.1")) // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsCIDR | Checks if a CIDR block contains another CIDR block. Signatures: CIDR.containsCIDR(CIDR) -> boolCIDR.containsCIDR(string) -> boolПримеры: cidr("192.168.0.0/16").containsCIDR(cidr("192.168.1.0/24")) // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
family | Returns the IP family (4 for IPv4, 6 for IPv6). Signatures: IP.family() -> intПримеры: ip("192.168.0.1").family() // 4 | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isGlobalUnicast | Checks if the IP is a global unicast address. Signatures: IP.isGlobalUnicast() -> boolПримеры: ip("192.168.0.1").isGlobalUnicast() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalMulticast | Checks if the IP is a link-local multicast address. Signatures: IP.isLinkLocalMulticast() -> boolПримеры: ip("224.0.0.1").isLinkLocalMulticast() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalUnicast | Checks if the IP is a link-local unicast address. Signatures: IP.isLinkLocalUnicast() -> boolПримеры: ip("169.254.0.1").isLinkLocalUnicast() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLoopback | Checks if the IP is a loopback address. Signatures: IP.isLoopback() -> boolПримеры: ip("127.0.0.1").isLoopback() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isMask | Checks if the CIDR is a valid subnet mask. Signatures: CIDR.isMask() -> boolПримеры: cidr("255.255.255.0/24").isMask() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isUnspecified | Checks if the IP is an unspecified address (eg 0.0.0.0 ).Signatures: IP.isUnspecified() -> boolПримеры: ip("0.0.0.0").isUnspecified() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
masked | Returns the masked CIDR block. Подписи: CIDR.masked() -> CIDRПримеры: cidr("192.168.0.1/24").masked() // 192.168.0.0/24 | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
prefixLength | Returns the prefix length of the CIDR block. Signatures: CIDR.prefixLength() -> intПримеры: cidr("192.168.0.0/24").prefixLength() // 24 | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
string | Converts IP or CIDR to string. Signatures: string(IP) -> stringstring(CIDR) -> stringПримеры: string(ip("192.168.0.1")) // "192.168.0.1" | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Pass
ext.Network()tocel.NewEnv(). - C++: Not supported.
- Java: Not supported.
- Python: Not supported.
Библиотека JWT
The JWT library provides data types and helper functions for parsing JSON Web Tokens (JWT) and inspecting standard and custom claims.
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
jwt.parse | Parses a raw token string into a structured jwt.Token wrapped in an optional.Signatures: jwt.parse(string) -> optional(jwt.Token)Примеры: jwt.parse(token_string).hasValue() | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
claim | Queries a custom claim value by key name from the token payload. Signatures: jwt.Token.claim(string) -> optional(dyn)optional(jwt.Token).claim(string) -> optional(dyn)Примеры: jwt.parse(token).claim("tenant").orValue("") | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
presentedBy | Validates that the token's issuer and audience match expected values. Signatures: jwt.Token.presentedBy(string, string) -> booloptional(jwt.Token).presentedBy(string, string) -> boolПримеры: jwt.parse(token).presentedBy("https://auth.example.com", "https://api.example.com") | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Import
cel.dev/cel-go/ext/security/jwtand passjwt.Library()tocel.NewEnv(). - C++: Not supported.
- Java: Not supported.
- Python: Not supported.
HMAC Library
The HMAC library provides cryptographic functions to compute and verify Hash-based Message Authentication Codes (HMAC) over strings and byte sequences.
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
hmac.compute | Computes raw HMAC signature bytes using the specified algorithm and secret key. Signatures: hmac.compute(string, string|bytes, string|bytes) -> bytesПримеры: hmac.compute(hmac.SHA256, "secret", "message") | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
hmac.verify | Verifies whether an HMAC signature matches the expected digest. Signatures: hmac.verify(string, string|bytes, string|bytes, string|bytes) -> boolПримеры: hmac.verify(hmac.SHA256, secret, msg, expected_sig) // true | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Import
cel.dev/cel-go/ext/security/hmacand passhmac.Library()tocel.NewEnv(). - C++: Not supported.
- Java: Not supported.
- Python: Not supported.
5. Расширенные функции
Advanced Features Summary
| Особенность | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
| Частичная оценка | Evaluate with missing inputs; returns unknowns or a simplified expression. | ✓ ³ | ✓ ⁴ | ✓ ⁴ | ✗ | ✗ |
| Async Evaluation | Non-blocking concurrent execution of extension functions. | ✓ ⁵ | ✗ | ✓ ⁶ | ✗ | ✗ |
| AST Validators | Static analysis checks on the Checked AST after type-checking. | ✓ | ✓ | ✓ | ✗ | ✗ |
| AST Optimizers | AST rewrites (constant folding, inlining, CSE) to improve performance. | ✓ | ✓ | ✓ | ✗ | ✗ |
| CEL Policy Compiler | Compiles YAML-based policy structures into standard CEL ASTs. | ✓ | ✓ | ✓ | ✗ | ✗ |
| Формальная верификация | Proves safety invariants, satisfiability, validity, and AST equivalence. | ✗ | ✗ | ✓ (v0.14.0) | ✗ | ✗ |
³ Go supports generating a Residual AST (pruned AST). ⁴ C++ and Java support returning UnknownSet / CelUnknownSet at runtime, but do not expose public APIs for residual AST generation. ⁵ Go uses AsyncBinding / AsyncOp returning channels. ⁶ Java uses CelAsyncRuntime returning ListenableFuture .
Partial Evaluation (Unknowns)
Partial evaluation allows evaluating an expression when only a subset of the input variables (arguments) are known. Instead of failing, the evaluation produces a result that indicates what is missing, or a simplified expression.
- Go: Full support. Allows defining a
PartialActivationwith patterns of unknown attributes. Evaluation returns atypes.Unknownvalue. Go supports generating a Residual AST (Env.ResidualAst) which is a pruned, simplified AST containing only the parts of the expression that could not be evaluated. - C++: Supports
Unknownvalues. Unknown attribute patterns are configured viaActivation::set_unknown_attribute_patterns. Evaluation returns anUnknownSet. Public API does not currently expose residual AST generation. - Java: Supports partial evaluation via
PartialVarspassed toProgram.eval(). Evaluation returns aCelUnknownSet. Public API does not currently expose residual AST generation. - Python / C: No native support.
Async Evaluation
Async evaluation allows CEL expressions to call functions that execute asynchronously (eg, making RPCs or database queries) and block evaluation until the results are available, without blocking the main execution thread.
- Go: Supports asynchronous function overloads via
AsyncBindingandAsyncOp. Async functions return a Go channel (<-chan ref.Val), and the interpreter manages the concurrent execution and synchronization. - Java: Supports async evaluation via
CelAsyncRuntimeandAsyncProgram. It usesListenableFutureto represent pending values and automatically drives evaluation to completion as futures resolve. - C++ / Python / C: No built-in support.
AST Validators
Validators perform static analysis on the Checked AST after type-checking to enforce domain-specific constraints before the program is executed.
- Go: Supports
ASTValidatorinterface. Canonical validators includecel.validator.duration,cel.validator.timestamp,cel.validator.matches(regex),cel.validator.homogeneous_literals, andcel.validator.comprehension_nesting_limit. - C++: Supports
cel::Validator. Canonical validations includeAstDepthValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,MatchesValidator, andTimestampLiteralValidator. - Java: Supports
CelValidatorandCelAstValidator. Canonical validators includeAstDepthLimitValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,RegexLiteralValidator, andTimestampLiteralValidator. - Python / C: No direct support.
AST Optimizers
Optimizers rewrite the AST to improve execution performance. Optimizers fall into one of two categories: static and runtime optimizers. C++, Java, and Go support runtime optimization. CEL Java and Go also support static optimizers.
Typical optimizations include constant folding (pre-evaluating sub-expressions with constant inputs) and common subexpression elimination (CSE).
- Go: Supports AST folding during compilation/planning.
- C++: Supports constant folding via the
cel::extensions::EnableConstantFoldingextension at plan time. - Java: Supports
CelOptimizerinterface. Canonical optimizers includeConstantFoldingOptimizer(which supports pre-order traversal, Protobuf message constant folding, and aggregate or optional pruning),InliningOptimizer, andSubexpressionOptimizer(CSE). - Python / C: No direct support.
CEL Policy Compiler
CEL Policy is a YAML-based format for composing multiple CEL expressions together with variables, match blocks, conditional outputs, and nested rules. It is designed for complex policy engines (like Kubernetes Admission Control) where single CEL expressions would become unreadable.
For the formal language definition, syntax, and conformance suite, refer to the CEL Policy Specification .
The Policy Compiler compiles these YAML policies into a single standard CEL AST, meaning they are fully compatible with standard CEL runtimes and inherit all performance and safety guarantees.
- Go: Supported via Go policy (including aggregate rule evaluation semantics).
- C++: Supported via C++ policy .
- Java: Supported via Java policy (including aggregate rule evaluation semantics and shorthand type specifiers in policy configs).
- Python / C: Not directly supported.
Formal Verification Framework
The Formal Verification framework allows users to mathematically prove safety invariants, logical equivalence, satisfiability, and validity across CEL expressions and structured CEL Policies.
- Java: Supported via the CEL Java Verifier (
dev.cel:verifieranddev.cel:verifier-cli). Capabilities include satisfiability (isSatisfiable) with witness input generation, validity (isAlwaysTrue) with counterexample generation, bounded model checking (BMC) for comprehensions, logical equivalence proofs across ASTs, and customassume/assertpolicy invariant verification. - Go / C++ / Python / C: Are supported indirectly via the Java command line toolchain.
Для ознакомления и примеров из реальной жизни см. сообщение в блоге Google Open Source: Обеспечение безопасности в эпоху агентного управления: внедрение формальной верификации для CEL .
,This document serves as the unified API Doc reference for the Common Expression Language (CEL). It lists all macros, operators, and standard functions, indicating their signatures, behaviors, and support status across the official CEL stacks.
For more details on language behavior and specifications, refer to the CEL Language Definition .
Версии стека
This reference document is based on the following versions of the CEL stacks:
- CEL Go :
v0.32.0(and newer) - CEL C++ :
v0.16.1 - CEL Java :
v0.14.0 - CEL Python :
v0.1.3 - CEL C : Development snapshot (unreleased)
GitHub Mirrors
The official implementations of CEL are mirrored on GitHub under the cel-expr organization:
1. Core Macros
These are built-in macros that are expanded at compile time.
| Макро | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
has(container.field) | Tests whether a field is present in a message, or a key in a map. Signatures: has(container.field) -> boolПримеры: has(request.auth.claims.email) | ✓ | ✓ | ✓ | ✓ | ✓ |
list.all(var, predicate) | Tests whether all elements in a list satisfy a predicate. Signatures: list.all(var, predicate) -> boolПримеры: [1, 2, 3].all(x, x > 0) // true | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.exists(var, predicate) | Tests whether at least one element in a list satisfies a predicate. Signatures: list.exists(var, predicate) -> boolПримеры: [1, 2, 3].exists(x, x > 2) // true | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.exists_one(var, predicate) | Tests whether exactly one element in a list satisfies a predicate. Signatures: list.exists_one(var, predicate) -> boolПримеры: [1, 2, 3].exists_one(x, x == 2) // true | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.filter(var, predicate) | Filters elements of a list according to a predicate. Signatures: list.filter(var, predicate) -> listПримеры: [1, 2, 3].filter(x, x > 1) // [2, 3] | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.map(var, transform) | Transforms each element of a list using an expression. Signatures: list.map(var, transform) -> listПримеры: [1, 2, 3].map(x, x * 2) // [2, 4, 6] | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.map(var, filter, transform) | Transforms elements of a list that satisfy a filter predicate. Signatures: list.map(var, filter, transform) -> listПримеры: [1, 2, 3].map(x, x > 1, x * 2) // [4, 6] | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
¹ Supported in C runtime because macros are expanded into comprehensions during compilation by the host compiler.
2. Core Operators
| Оператор | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
Arithmetic ( + , - , * , / , % ) | Standard arithmetic operations. Negation ( -x ) and Identity ( +x ). List concatenation ( list + list ) is supported in Go, C++, Java, and Python.Signatures: T + T -> TT - T -> TT * T -> TT / T -> TT % T -> T-T -> T+T -> Tlist + list -> listПримеры: 1 + 2 * 3 // 7[1] + [2] // [1, 2] | ✓ | ✓ | ✓ | ✓ | ✓ ² |
Comparison ( == , != , < , <= , > , >= ) | Standard comparison. Numeric comparisons are heterogeneous (eg 1 == 1.0 ).Signatures: T == T -> boolT != T -> boolT < T -> boolT <= T -> boolT > T -> boolT >= T -> boolПримеры: x < 42.01 == 1.0 // true | ✓ | ✓ | ✓ | ✓ | ✓ |
Logical ( ! , && , || , ? : ) | Logical NOT, AND, OR, and Ternary Conditional. AND/OR use short-circuit evaluation. Signatures: !bool -> boolbool && bool -> boolbool || bool -> boolbool ? T : T -> TПримеры: x > 0 ? "positive" : "non-positive" | ✓ | ✓ | ✓ | ✓ | ✓ |
Indexing ( [] ) | Access element of a list by index, or lookup key in a map. Signatures: list[int] -> Tmap[K] -> VПримеры: tags[0]users['john'] | ✓ | ✓ | ✓ | ✓ | ✓ |
Membership ( in ) | Check if element is in a list, or key is in a map. Signatures: T in list -> boolK in map -> boolПримеры: 'admin' in roles | ✓ | ✓ | ✓ | ✓ | ✓ |
² List concatenation ( list + list ) is not supported in the C runtime, though other arithmetic operators are supported.
3. Основные функции
General & String Functions
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
size | Returns the size of a string (characters), bytes, list, or map. Подписи: size(T) -> int (where T is string , bytes , list , or map )Примеры: size("hello") // 5 | ✓ | ✓ | ✓ | ✓ | ✓ |
contains | Returns whether string contains substring. Signatures: string.contains(string) -> boolПримеры: "hello".contains("ell") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
startsWith | Returns whether string starts with prefix. Signatures: string.startsWith(string) -> boolПримеры: "hello".startsWith("he") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
endsWith | Returns whether string ends with suffix. Signatures: string.endsWith(string) -> boolПримеры: "hello".endsWith("lo") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
matches | Returns whether string matches RE2 regular expression. Signatures: string.matches(string) -> boolПримеры: "123".matches(r"^\d+$") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
Date and Time Selector Functions
These functions extract components from google.protobuf.Timestamp or google.protobuf.Duration .
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
getFullYear | Returns the 4-digit year. Signatures: timestamp.getFullYear([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getFullYear() // 2026 | ✓ | ✓ | ✓ | ✓ | ✗ |
getMonth | Returns the month (0-11). Signatures: timestamp.getMonth([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getMonth() // 6 | ✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfMonth | Returns the day of the month (1-31). Signatures: timestamp.getDayOfMonth([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getDayOfMonth() // 23 | ✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfWeek | Returns the day of the week (0 = Sunday). Signatures: timestamp.getDayOfWeek([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getDayOfWeek() // 4 | ✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfYear | Returns the day of the year (0-365). Signatures: timestamp.getDayOfYear([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getDayOfYear() // 203 | ✓ | ✓ | ✓ | ✓ | ✗ |
getHours | Returns the hours (0-23). Signatures: timestamp.getHours([tz]) -> intduration.getHours() -> intПримеры: duration("1h30m").getHours() // 1 | ✓ | ✓ | ✓ | ✓ | ✗ |
getMinutes | Returns the minutes (0-59). Signatures: timestamp.getMinutes([tz]) -> intduration.getMinutes() -> intПримеры: duration("1h30m").getMinutes() // 30 | ✓ | ✓ | ✓ | ✓ | ✗ |
getSeconds | Returns the seconds (0-59). Signatures: timestamp.getSeconds([tz]) -> intduration.getSeconds() -> intПримеры: duration("1h30m45s").getSeconds() // 45 | ✓ | ✓ | ✓ | ✓ | ✗ |
getMilliseconds | Returns the milliseconds (0-999). Signatures: timestamp.getMilliseconds([tz]) -> intduration.getMilliseconds() -> intПримеры: duration("1.5s").getMilliseconds() // 500 | ✓ | ✓ | ✓ | ✓ | ✗ |
Преобразование типов
| Тип цели | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
bool | Converts to boolean. Signatures: bool(bool) -> boolbool(string) -> boolПримеры: bool("true") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
bytes | Converts to bytes. Signatures: bytes(bytes) -> bytesbytes(string) -> bytesПримеры: bytes("hello") // b"hello" | ✓ | ✓ | ✓ | ✓ | ✓ |
double | Converts to double-precision float. Signatures: double(double) -> doubledouble(int) -> doubledouble(uint) -> doubledouble(string) -> doubleПримеры: double(1) // 1.0 | ✓ | ✓ | ✓ | ✓ | ✓ |
duration | Converts to duration. Signatures: duration(duration) -> durationduration(string) -> durationПримеры: duration("1.5s") // 1.5s duration | ✓ | ✓ | ✓ | ✓ | ✓ |
int | Converts to 64-bit signed integer. Signatures: int(int) -> intint(uint) -> intint(double) -> int (rounds to zero)int(string) -> intint(timestamp) -> int (seconds since epoch)Примеры: int(1.5) // 1 | ✓ | ✓ | ✓ | ✓ | ✓ |
string | Converts to string. Signatures: string(T) -> string (supports bool , int , uint , double , bytes , timestamp , duration )Примеры: string(1.5) // "1.5" | ✓ | ✓ | ✓ | ✓ | ✓ |
timestamp | Converts to timestamp. Signatures: timestamp(timestamp) -> timestamptimestamp(string) -> timestamp (RFC3339)Примеры: timestamp("2026-07-23T00:00:00Z") | ✓ | ✓ | ✓ | ✓ | ✓ |
uint | Converts to 64-bit unsigned integer. Signatures: uint(uint) -> uintuint(int) -> uintuint(double) -> uintuint(string) -> uintПримеры: uint(1) // 1u | ✓ | ✓ | ✓ | ✓ | ✓ |
dyn | Casts value to dynamic type for type-checking. Signatures: dyn(T) -> dynПримеры: dyn([1, "two"]) | ✓ | ✓ | ✓ | ✓ | ✗ |
type | Returns the type of the value. Signatures: type(T) -> typeПримеры: type(1) // int | ✓ | ✓ | ✓ | ✓ | ✗ |
4. Extensions (Libraries)
Bindings Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
cel.bind | Binds a local variable to avoid duplicate evaluation. Подписи: cel.bind(varName, initExpr, resultExpr) -> TПримеры: cel.bind(x, a + b, x * x) | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Bindings()tocel.NewEnv(). - C++: Add
BindingsCompilerLibrary()toCompilerBuilder. (Runtime is handled automatically). - Java: Add
CelExtensions.bindings()toCelCompilerandCelRuntimebuilders. - Python: Import
cel_expr_python.ext.ext_bindingsand useExtBindings()incel.NewEnv(extensions=[...]).
Encoders Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
base64.encode | Encodes bytes to base64 string. Signatures: base64.encode(bytes) -> stringПримеры: base64.encode(b"hello") // "aGVsbG8=" | ✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
base64.decode | Decodes base64 string to bytes. Throws error on invalid input. Signatures: base64.decode(string) -> bytesПримеры: base64.decode("aGVsbG8=") // b"hello" | ✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
json.encode | Serializes a CEL value to JSON string. Signatures: json.encode(dyn) -> stringПримеры: json.encode([1, 2]) // "[1,2]" | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Pass
ext.Encoders()tocel.NewEnv(). - C++:
- Compiler: Add
EncodersCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterEncodersFunctions()onFunctionRegistry.
- Compiler: Add
- Java: Add
CelExtensions.encoders()toCelCompilerandCelRuntimebuilders. - Python: Import
cel_expr_python.ext.ext_encodersand useExtEncoders()incel.NewEnv(extensions=[...]).
Математическая библиотека
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
math.greatest | Returns greatest of numeric arguments (or list of numerics). Signatures: math.greatest(arg, ...) -> TПримеры: math.greatest(1, 3, 2) // 3 | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.least | Returns least of numeric arguments (or list of numerics). Signatures: math.least(arg, ...) -> TПримеры: math.least([1, 3, 2]) // 1 | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.abs | Абсолютное значение. Signatures: math.abs(T) -> T (supports int , uint , double )Примеры: math.abs(-1) // 1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sqrt | Квадратный корень. Signatures: math.sqrt(T) -> double (supports int , uint , double )Примеры: math.sqrt(9) // 3.0 | ✓ (v0.25.1) | ✓ (v0.12.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
math.bitAnd | Bitwise AND. Signatures: math.bitAnd(T, T) -> T (supports int , uint )Примеры: math.bitAnd(5, 3) // 1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitOr | Bitwise OR. Signatures: math.bitOr(T, T) -> T (supports int , uint )Примеры: math.bitOr(5, 3) // 7 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitXor | Bitwise XOR. Signatures: math.bitXor(T, T) -> T (supports int , uint )Примеры: math.bitXor(5, 3) // 6 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitNot | Bitwise NOT. Signatures: math.bitNot(T) -> T (supports int , uint )Примеры: math.bitNot(1) // -2 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftLeft | Bitwise shift left. Signatures: math.bitShiftLeft(T, int) -> T (supports int , uint )Примеры: math.bitShiftLeft(1, 2) // 4 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftRight | Bitwise shift right. Signatures: math.bitShiftRight(T, int) -> T (supports int , uint )Примеры: math.bitShiftRight(4, 2) // 1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.ceil | Ceiling rounding. Signatures: math.ceil(double) -> doubleПримеры: math.ceil(1.2) // 2.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.floor | Floor rounding. Signatures: math.floor(double) -> doubleПримеры: math.floor(1.8) // 1.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.round | Nearest integer rounding. Signatures: math.round(double) -> doubleПримеры: math.round(1.5) // 2.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.trunc | Truncation rounding (towards zero). Подписи: math.trunc(double) -> doubleПримеры: math.trunc(-1.8) // -1.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isInf | Checks if double is positive or negative infinity. Signatures: math.isInf(double) -> boolПримеры: math.isInf(1.0/0.0) // true | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isNaN | Checks if double is NaN. Signatures: math.isNaN(double) -> boolПримеры: math.isNaN(0.0/0.0) // true | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isFinite | Checks if double is finite. Signatures: math.isFinite(double) -> boolПримеры: math.isFinite(1.2) // true | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sign | Returns sign of value (-1, 0, or 1). Signatures: math.sign(T) -> T (supports int , uint , double )Примеры: math.sign(-42) // -1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Math()tocel.NewEnv(). - C++:
- Compiler: Add
MathCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterMathExtensionFunctions()onFunctionRegistry.
- Compiler: Add
- Java: Add
CelExtensions.math()toCelCompilerandCelRuntimebuilders. - Python: Import
cel_expr_python.ext.ext_mathand useExtMath()incel.NewEnv(extensions=[...]).
Protos Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
proto.getExt | Gets proto2 extension field, or default if unset. Signatures: proto.getExt(msg, extName) -> TПримеры: proto.getExt(msg, google.api.expr.test.int32_ext) | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
proto.hasExt | Checks if proto2 extension field is set. Signatures: proto.hasExt(msg, extName) -> boolПримеры: proto.hasExt(msg, google.api.expr.test.int32_ext) | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Protos()tocel.NewEnv(). - C++: Add
ProtoExtCompilerLibrary()toCompilerBuilder. (Runtime is handled automatically). - Java: Add
CelExtensions.protos()toCelCompilerandCelRuntimebuilders. - Python: Import
cel_expr_python.ext.ext_protoand useExtProto()incel.NewEnv(extensions=[...]).
Lists Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
distinct | Returns distinct elements. Signatures: list.distinct() -> listПримеры: [1, 2, 2].distinct() // [1, 2] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
flatten | Flattens nested lists. Signatures: list.flatten([depth]) -> listПримеры: [[1], [2, 3]].flatten() // [1, 2, 3] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.7.1) | ✓ (v0.1.1) | ✗ |
lists.range | Returns list of integers [0, ..., n-1] .Signatures: lists.range(int) -> list(int)Примеры: lists.range(3) // [0, 1, 2] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
reverse | Reverses the list. Signatures: list.reverse() -> listПримеры: [1, 2].reverse() // [2, 1] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
slice | Returns sub-list (start inclusive, end exclusive). Signatures: list.slice(start, end) -> listПримеры: [1, 2, 3].slice(1, 3) // [2, 3] | ✓ (v0.17.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sort | Sorts list of comparable elements. Signatures: list.sort() -> listПримеры: [3, 1, 2].sort() // [1, 2, 3] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sortBy | Sorts list by key evaluated from expression. Signatures: list.sortBy(var, expr) -> listПримеры: [{"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 | Returns first element as optional. Requires the Optional extension. Signatures: list.first() -> optionalПримеры: [1, 2].first() // optional(1) | ✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
last | Returns last element as optional. Requires the Optional extension. Signatures: list.last() -> optionalПримеры: [1, 2].last() // optional(2) | ✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
Как включить
- Go: Pass
ext.Lists()tocel.NewEnv(). - C++:
- Compiler: Add
ListsCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterListsFunctions()onFunctionRegistryandRegisterListsMacros()onMacroRegistry.
- Compiler: Add
- Java: Add
CelExtensions.lists()toCelCompilerandCelRuntimebuilders. - Python: Enable via
cel.EnvConfigby addingliststo theextensionslist.
Sets Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
sets.contains | Checks if list1 contains all elements of list2. Signatures: sets.contains(list1, list2) -> boolПримеры: sets.contains([1, 2], [1]) // true | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.equivalent | Checks if lists are set-equivalent (contain same unique elements). Signatures: sets.equivalent(list1, list2) -> boolПримеры: sets.equivalent([1, 2], [2, 1, 1]) // true | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.intersects | Checks if lists share at least one element. Signatures: sets.intersects(list1, list2) -> boolПримеры: sets.intersects([1, 2], [2, 3]) // true | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Sets()tocel.NewEnv(). - C++:
- Compiler: Add
SetsCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterSetsFunctions()onFunctionRegistry.
- Compiler: Add
- Java: Add
CelExtensions.sets()toCelCompilerandCelRuntimebuilders. - Python: Enable via
cel.EnvConfigby addingsetsto theextensionslist.
Strings Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
charAt | Returns character at index. Signatures: string.charAt(int) -> stringПримеры: "hello".charAt(1) // "e" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
indexOf | Returns index of first occurrence of substring, or -1. Signatures: string.indexOf(substr, [start]) -> intПримеры: "hello".indexOf("l") // 2 | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
lastIndexOf | Returns index of last occurrence of substring, or -1. Signatures: string.lastIndexOf(substr, [end]) -> intПримеры: "hello".lastIndexOf("l") // 3 | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
join | Concatenates strings. Signatures: list(string).join([separator]) -> stringПримеры: ["a", "b"].join("-") // "ab" | ✓ (v0.10.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
split | Splits string by separator. Signatures: string.split(separator, [limit]) -> list(string)Примеры: "ab".split("-") // ["a", "b"] | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
substring | Returns substring (start inclusive, end exclusive). Signatures: string.substring(start, [end]) -> stringПримеры: "hello".substring(1, 3) // "el" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
trim | Trims Unicode whitespace. Signatures: string.trim() -> stringПримеры: " hello ".trim() // "hello" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
replace | Replaces occurrences of old with new. Подписи: string.replace(old, new, [limit]) -> stringПримеры: "hello".replace("l", "w") // "hewwo" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
reverse | Reverses Unicode code points. Signatures: string.reverse() -> stringПримеры: "abc".reverse() // "cba" | ✓ (v0.18.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
lowerAscii | Converts ASCII characters to lowercase. Signatures: string.lowerAscii() -> stringПримеры: "Hello".lowerAscii() // "hello" | ✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
upperAscii | Converts ASCII characters to uppercase. Signatures: string.upperAscii() -> stringПримеры: "Hello".upperAscii() // "HELLO" | ✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
quote | Escapes string for safe printing. Signatures: strings.quote(string) -> stringПримеры: strings.quote("a\tb") // "\"a\\tb\"" | ✓ (v0.14.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
format | Formats the string using printf-style placeholders. Signatures: string.format(list) -> stringПримеры: "str: %s, int: %d".format(["a", 1]) // "str: a, int: 1" | ✓ (v0.14.0) | ✓ (v0.11.0) | ✗ | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Strings()tocel.NewEnv(). - C++:
- Compiler: Add
StringsCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterStringsFunctions()onFunctionRegistry.
- Compiler: Add
- Java: Add
CelExtensions.strings()toCelCompilerandCelRuntimebuilders. - Python: Import
cel_expr_python.ext.ext_stringsand useExtStrings()incel.NewEnv(extensions=[...]).
Regular Expression Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
regex.replace | Replaces matches with replacement string (supports backreferences). Signatures: regex.replace(target, pat, repl, [limit]) -> stringПримеры: 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 | Returns first match of pattern (must have one capture group). Signatures: regex.extract(target, pat) -> optional(string)Примеры: regex.extract("a123b", r"(\d+)") // optional("123") | ✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
regex.extractAll | Returns all matches of pattern (must have one capture group). Signatures: regex.extractAll(target, pat) -> list(string)Примеры: regex.extractAll("a1b2", r"(\d+)") // ["1", "2"] | ✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Regex()tocel.NewEnv(). - C++:
- Compiler: Add
RegexExtCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterRegexExtensionFunctions()onFunctionRegistry.
- Compiler: Add
- Java: Add
CelExtensions.regex()toCelCompilerandCelRuntimebuilders. - Python: Enable via
cel.EnvConfigby addingregexandoptionalto theextensionslist.
Two-Variable Comprehensions
| Макро | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
all | Short-circuiting logical AND over key/index and value. Signatures: list.all(i, v, pred) -> boolmap.all(k, v, pred) -> boolПримеры: [1, 2].all(i, v, v > 0) // true | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
exists | Short-circuiting logical OR over key/index and value. Signatures: list.exists(i, v, pred) -> boolmap.exists(k, v, pred) -> boolПримеры: [1, 2].exists(i, v, v == 2) // true | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
existsOne | Checks if exactly one pair satisfies predicate. Signatures: list.existsOne(i, v, pred) -> boolmap.existsOne(k, v, pred) -> boolПримеры: [1, 2].existsOne(i, v, v == 2) // true | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformList | Transforms/filters list/map into a list. Signatures: list.transformList(i, v, [filter], transform) -> listmap.transformList(k, v, [filter], transform) -> listПримеры: [1, 2].transformList(i, v, v * 2) // [2, 4] | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMap | Transforms values of list/map into a map (keys remain fixed). Signatures: list.transformMap(i, v, [filter], transform) -> mapmap.transformMap(k, v, [filter], transform) -> mapПримеры: [1, 2].transformMap(i, v, v * 2) // {0: 2, 1: 4} | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMapEntry | Transforms into a map. Signatures: list.transformMapEntry(i, v, [filter], transform_entry) -> mapmap.transformMapEntry(k, v, [filter], transform_entry) -> mapПримеры: [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) | ✗ |
Как включить
- Go: Pass
ext.TwoVarComprehensions()tocel.NewEnv(). - C++:
- Compiler: Add
ComprehensionsV2CompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterComprehensionsV2Functions()onFunctionRegistryandRegisterComprehensionsV2Macros()onMacroRegistry.
- Compiler: Add
- Java: Add
CelExtensions.comprehensions()toCelCompilerandCelRuntimebuilders. - Python: Enable via
cel.EnvConfigby addingtwo-var-comprehensionsto theextensionslist.
Native Types Library
| Особенность | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
| Native Structs | Registering and instantiating host native types (Go structs / Java POJOs) in CEL. Примеры: Account{id: 123} (Java POJO instanced in CEL) | ✓ (v0.13.0) | ✗ | ✓ (v0.13.0) | ✗ | ✗ |
Как включить
- Go: Pass
cel.NativeTypes(...)orext.NativeTypes(...)(providing reflect types) tocel.NewEnv(). - C++: Not supported.
- Java: Add
CelExtensions.nativeTypes()(providing Java classes) toCelCompilerandCelRuntimebuilders. - Python: Not supported.
Network Library
The Network library provides functions for parsing, validating, and manipulating IP addresses and CIDR blocks.
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
ip | Parses a string into an IP address, or extracts the IP from a CIDR. Signatures: ip(string) -> IPCIDR.ip() -> IPПримеры: ip("192.168.0.1")cidr("192.168.0.0/24").ip() | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isIP | Checks if a string is a valid IP address. Подписи: isIP(string) -> boolПримеры: isIP("192.168.0.1") // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
ip.isCanonical | Checks if an IP address string is in its canonical format. Signatures: ip.isCanonical(string) -> boolПримеры: ip.isCanonical("192.168.0.1") // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
cidr | Parses a string into a CIDR block. Signatures: cidr(string) -> CIDRПримеры: cidr("192.168.0.0/24") | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isCIDR | Checks if a string is a valid CIDR block. Signatures: isCIDR(string) -> boolПримеры: isCIDR("192.168.0.0/24") // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsIP | Checks if a CIDR block contains an IP address. Signatures: CIDR.containsIP(IP) -> boolCIDR.containsIP(string) -> boolПримеры: cidr("192.168.0.0/24").containsIP(ip("192.168.0.1")) // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsCIDR | Checks if a CIDR block contains another CIDR block. Signatures: CIDR.containsCIDR(CIDR) -> boolCIDR.containsCIDR(string) -> boolПримеры: cidr("192.168.0.0/16").containsCIDR(cidr("192.168.1.0/24")) // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
family | Returns the IP family (4 for IPv4, 6 for IPv6). Signatures: IP.family() -> intПримеры: ip("192.168.0.1").family() // 4 | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isGlobalUnicast | Checks if the IP is a global unicast address. Signatures: IP.isGlobalUnicast() -> boolПримеры: ip("192.168.0.1").isGlobalUnicast() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalMulticast | Checks if the IP is a link-local multicast address. Signatures: IP.isLinkLocalMulticast() -> boolПримеры: ip("224.0.0.1").isLinkLocalMulticast() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalUnicast | Checks if the IP is a link-local unicast address. Signatures: IP.isLinkLocalUnicast() -> boolПримеры: ip("169.254.0.1").isLinkLocalUnicast() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLoopback | Checks if the IP is a loopback address. Signatures: IP.isLoopback() -> boolПримеры: ip("127.0.0.1").isLoopback() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isMask | Checks if the CIDR is a valid subnet mask. Signatures: CIDR.isMask() -> boolПримеры: cidr("255.255.255.0/24").isMask() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isUnspecified | Checks if the IP is an unspecified address (eg 0.0.0.0 ).Signatures: IP.isUnspecified() -> boolПримеры: ip("0.0.0.0").isUnspecified() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
masked | Returns the masked CIDR block. Signatures: CIDR.masked() -> CIDRПримеры: cidr("192.168.0.1/24").masked() // 192.168.0.0/24 | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
prefixLength | Returns the prefix length of the CIDR block. Signatures: CIDR.prefixLength() -> intПримеры: cidr("192.168.0.0/24").prefixLength() // 24 | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
string | Converts IP or CIDR to string. Signatures: string(IP) -> stringstring(CIDR) -> stringПримеры: string(ip("192.168.0.1")) // "192.168.0.1" | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Pass
ext.Network()tocel.NewEnv(). - C++: Not supported.
- Java: Not supported.
- Python: Not supported.
Библиотека JWT
The JWT library provides data types and helper functions for parsing JSON Web Tokens (JWT) and inspecting standard and custom claims.
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
jwt.parse | Parses a raw token string into a structured jwt.Token wrapped in an optional.Подписи: jwt.parse(string) -> optional(jwt.Token)Примеры: jwt.parse(token_string).hasValue() | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
claim | Queries a custom claim value by key name from the token payload. Signatures: jwt.Token.claim(string) -> optional(dyn)optional(jwt.Token).claim(string) -> optional(dyn)Примеры: jwt.parse(token).claim("tenant").orValue("") | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
presentedBy | Validates that the token's issuer and audience match expected values. Signatures: jwt.Token.presentedBy(string, string) -> booloptional(jwt.Token).presentedBy(string, string) -> boolПримеры: jwt.parse(token).presentedBy("https://auth.example.com", "https://api.example.com") | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Import
cel.dev/cel-go/ext/security/jwtand passjwt.Library()tocel.NewEnv(). - C++: Not supported.
- Java: Not supported.
- Python: Not supported.
HMAC Library
The HMAC library provides cryptographic functions to compute and verify Hash-based Message Authentication Codes (HMAC) over strings and byte sequences.
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
hmac.compute | Computes raw HMAC signature bytes using the specified algorithm and secret key. Signatures: hmac.compute(string, string|bytes, string|bytes) -> bytesПримеры: hmac.compute(hmac.SHA256, "secret", "message") | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
hmac.verify | Verifies whether an HMAC signature matches the expected digest. Signatures: hmac.verify(string, string|bytes, string|bytes, string|bytes) -> boolПримеры: hmac.verify(hmac.SHA256, secret, msg, expected_sig) // true | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Import
cel.dev/cel-go/ext/security/hmacand passhmac.Library()tocel.NewEnv(). - C++: Not supported.
- Java: Not supported.
- Python: Not supported.
5. Расширенные функции
Advanced Features Summary
| Особенность | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
| Частичная оценка | Evaluate with missing inputs; returns unknowns or a simplified expression. | ✓ ³ | ✓ ⁴ | ✓ ⁴ | ✗ | ✗ |
| Async Evaluation | Non-blocking concurrent execution of extension functions. | ✓ ⁵ | ✗ | ✓ ⁶ | ✗ | ✗ |
| AST Validators | Static analysis checks on the Checked AST after type-checking. | ✓ | ✓ | ✓ | ✗ | ✗ |
| AST Optimizers | AST rewrites (constant folding, inlining, CSE) to improve performance. | ✓ | ✓ | ✓ | ✗ | ✗ |
| CEL Policy Compiler | Compiles YAML-based policy structures into standard CEL ASTs. | ✓ | ✓ | ✓ | ✗ | ✗ |
| Формальная верификация | Proves safety invariants, satisfiability, validity, and AST equivalence. | ✗ | ✗ | ✓ (v0.14.0) | ✗ | ✗ |
³ Go supports generating a Residual AST (pruned AST). ⁴ C++ and Java support returning UnknownSet / CelUnknownSet at runtime, but do not expose public APIs for residual AST generation. ⁵ Go uses AsyncBinding / AsyncOp returning channels. ⁶ Java uses CelAsyncRuntime returning ListenableFuture .
Partial Evaluation (Unknowns)
Partial evaluation allows evaluating an expression when only a subset of the input variables (arguments) are known. Instead of failing, the evaluation produces a result that indicates what is missing, or a simplified expression.
- Go: Full support. Allows defining a
PartialActivationwith patterns of unknown attributes. Evaluation returns atypes.Unknownvalue. Go supports generating a Residual AST (Env.ResidualAst) which is a pruned, simplified AST containing only the parts of the expression that could not be evaluated. - C++: Supports
Unknownvalues. Unknown attribute patterns are configured viaActivation::set_unknown_attribute_patterns. Evaluation returns anUnknownSet. Public API does not currently expose residual AST generation. - Java: Supports partial evaluation via
PartialVarspassed toProgram.eval(). Evaluation returns aCelUnknownSet. Public API does not currently expose residual AST generation. - Python / C: No native support.
Async Evaluation
Async evaluation allows CEL expressions to call functions that execute asynchronously (eg, making RPCs or database queries) and block evaluation until the results are available, without blocking the main execution thread.
- Go: Supports asynchronous function overloads via
AsyncBindingandAsyncOp. Async functions return a Go channel (<-chan ref.Val), and the interpreter manages the concurrent execution and synchronization. - Java: Supports async evaluation via
CelAsyncRuntimeandAsyncProgram. It usesListenableFutureto represent pending values and automatically drives evaluation to completion as futures resolve. - C++ / Python / C: No built-in support.
AST Validators
Validators perform static analysis on the Checked AST after type-checking to enforce domain-specific constraints before the program is executed.
- Go: Supports
ASTValidatorinterface. Canonical validators includecel.validator.duration,cel.validator.timestamp,cel.validator.matches(regex),cel.validator.homogeneous_literals, andcel.validator.comprehension_nesting_limit. - C++: Supports
cel::Validator. Canonical validations includeAstDepthValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,MatchesValidator, andTimestampLiteralValidator. - Java: Supports
CelValidatorandCelAstValidator. Canonical validators includeAstDepthLimitValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,RegexLiteralValidator, andTimestampLiteralValidator. - Python / C: No direct support.
AST Optimizers
Optimizers rewrite the AST to improve execution performance. Optimizers fall into one of two categories: static and runtime optimizers. C++, Java, and Go support runtime optimization. CEL Java and Go also support static optimizers.
Typical optimizations include constant folding (pre-evaluating sub-expressions with constant inputs) and common subexpression elimination (CSE).
- Go: Supports AST folding during compilation/planning.
- C++: Supports constant folding via the
cel::extensions::EnableConstantFoldingextension at plan time. - Java: Supports
CelOptimizerinterface. Canonical optimizers includeConstantFoldingOptimizer(which supports pre-order traversal, Protobuf message constant folding, and aggregate or optional pruning),InliningOptimizer, andSubexpressionOptimizer(CSE). - Python / C: No direct support.
CEL Policy Compiler
CEL Policy is a YAML-based format for composing multiple CEL expressions together with variables, match blocks, conditional outputs, and nested rules. It is designed for complex policy engines (like Kubernetes Admission Control) where single CEL expressions would become unreadable.
For the formal language definition, syntax, and conformance suite, refer to the CEL Policy Specification .
The Policy Compiler compiles these YAML policies into a single standard CEL AST, meaning they are fully compatible with standard CEL runtimes and inherit all performance and safety guarantees.
- Go: Supported via Go policy (including aggregate rule evaluation semantics).
- C++: Supported via C++ policy .
- Java: Supported via Java policy (including aggregate rule evaluation semantics and shorthand type specifiers in policy configs).
- Python / C: Not directly supported.
Formal Verification Framework
The Formal Verification framework allows users to mathematically prove safety invariants, logical equivalence, satisfiability, and validity across CEL expressions and structured CEL Policies.
- Java: Supported via the CEL Java Verifier (
dev.cel:verifieranddev.cel:verifier-cli). Capabilities include satisfiability (isSatisfiable) with witness input generation, validity (isAlwaysTrue) with counterexample generation, bounded model checking (BMC) for comprehensions, logical equivalence proofs across ASTs, and customassume/assertpolicy invariant verification. - Go / C++ / Python / C: Are supported indirectly via the Java command line toolchain.
Для ознакомления и примеров из реальной жизни см. сообщение в блоге Google Open Source: Обеспечение безопасности в эпоху агентного управления: внедрение формальной верификации для CEL .
,This document serves as the unified API Doc reference for the Common Expression Language (CEL). It lists all macros, operators, and standard functions, indicating their signatures, behaviors, and support status across the official CEL stacks.
For more details on language behavior and specifications, refer to the CEL Language Definition .
Версии стека
This reference document is based on the following versions of the CEL stacks:
- CEL Go :
v0.32.0(and newer) - CEL C++ :
v0.16.1 - CEL Java :
v0.14.0 - CEL Python :
v0.1.3 - CEL C : Development snapshot (unreleased)
GitHub Mirrors
The official implementations of CEL are mirrored on GitHub under the cel-expr organization:
1. Core Macros
These are built-in macros that are expanded at compile time.
| Макро | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
has(container.field) | Tests whether a field is present in a message, or a key in a map. Signatures: has(container.field) -> boolПримеры: has(request.auth.claims.email) | ✓ | ✓ | ✓ | ✓ | ✓ |
list.all(var, predicate) | Tests whether all elements in a list satisfy a predicate. Signatures: list.all(var, predicate) -> boolПримеры: [1, 2, 3].all(x, x > 0) // true | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.exists(var, predicate) | Tests whether at least one element in a list satisfies a predicate. Signatures: list.exists(var, predicate) -> boolПримеры: [1, 2, 3].exists(x, x > 2) // true | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.exists_one(var, predicate) | Tests whether exactly one element in a list satisfies a predicate. Signatures: list.exists_one(var, predicate) -> boolПримеры: [1, 2, 3].exists_one(x, x == 2) // true | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.filter(var, predicate) | Filters elements of a list according to a predicate. Signatures: list.filter(var, predicate) -> listПримеры: [1, 2, 3].filter(x, x > 1) // [2, 3] | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.map(var, transform) | Transforms each element of a list using an expression. Подписи: list.map(var, transform) -> listПримеры: [1, 2, 3].map(x, x * 2) // [2, 4, 6] | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
list.map(var, filter, transform) | Transforms elements of a list that satisfy a filter predicate. Signatures: list.map(var, filter, transform) -> listПримеры: [1, 2, 3].map(x, x > 1, x * 2) // [4, 6] | ✓ | ✓ | ✓ | ✓ | ✓ ¹ |
¹ Supported in C runtime because macros are expanded into comprehensions during compilation by the host compiler.
2. Core Operators
| Оператор | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
Arithmetic ( + , - , * , / , % ) | Standard arithmetic operations. Negation ( -x ) and Identity ( +x ). List concatenation ( list + list ) is supported in Go, C++, Java, and Python.Signatures: T + T -> TT - T -> TT * T -> TT / T -> TT % T -> T-T -> T+T -> Tlist + list -> listПримеры: 1 + 2 * 3 // 7[1] + [2] // [1, 2] | ✓ | ✓ | ✓ | ✓ | ✓ ² |
Comparison ( == , != , < , <= , > , >= ) | Standard comparison. Numeric comparisons are heterogeneous (eg 1 == 1.0 ).Signatures: T == T -> boolT != T -> boolT < T -> boolT <= T -> boolT > T -> boolT >= T -> boolПримеры: x < 42.01 == 1.0 // true | ✓ | ✓ | ✓ | ✓ | ✓ |
Logical ( ! , && , || , ? : ) | Logical NOT, AND, OR, and Ternary Conditional. AND/OR use short-circuit evaluation. Signatures: !bool -> boolbool && bool -> boolbool || bool -> boolbool ? T : T -> TПримеры: x > 0 ? "positive" : "non-positive" | ✓ | ✓ | ✓ | ✓ | ✓ |
Indexing ( [] ) | Access element of a list by index, or lookup key in a map. Signatures: list[int] -> Tmap[K] -> VПримеры: tags[0]users['john'] | ✓ | ✓ | ✓ | ✓ | ✓ |
Membership ( in ) | Check if element is in a list, or key is in a map. Signatures: T in list -> boolK in map -> boolПримеры: 'admin' in roles | ✓ | ✓ | ✓ | ✓ | ✓ |
² List concatenation ( list + list ) is not supported in the C runtime, though other arithmetic operators are supported.
3. Основные функции
General & String Functions
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
size | Returns the size of a string (characters), bytes, list, or map. Signatures: size(T) -> int (where T is string , bytes , list , or map )Примеры: size("hello") // 5 | ✓ | ✓ | ✓ | ✓ | ✓ |
contains | Returns whether string contains substring. Signatures: string.contains(string) -> boolПримеры: "hello".contains("ell") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
startsWith | Returns whether string starts with prefix. Signatures: string.startsWith(string) -> boolПримеры: "hello".startsWith("he") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
endsWith | Returns whether string ends with suffix. Signatures: string.endsWith(string) -> boolПримеры: "hello".endsWith("lo") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
matches | Returns whether string matches RE2 regular expression. Signatures: string.matches(string) -> boolПримеры: "123".matches(r"^\d+$") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
Date and Time Selector Functions
These functions extract components from google.protobuf.Timestamp or google.protobuf.Duration .
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
getFullYear | Returns the 4-digit year. Signatures: timestamp.getFullYear([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getFullYear() // 2026 | ✓ | ✓ | ✓ | ✓ | ✗ |
getMonth | Returns the month (0-11). Signatures: timestamp.getMonth([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getMonth() // 6 | ✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfMonth | Returns the day of the month (1-31). Signatures: timestamp.getDayOfMonth([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getDayOfMonth() // 23 | ✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfWeek | Returns the day of the week (0 = Sunday). Signatures: timestamp.getDayOfWeek([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getDayOfWeek() // 4 | ✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfYear | Returns the day of the year (0-365). Signatures: timestamp.getDayOfYear([tz]) -> intПримеры: timestamp("2026-07-23T00:00:00Z").getDayOfYear() // 203 | ✓ | ✓ | ✓ | ✓ | ✗ |
getHours | Returns the hours (0-23). Signatures: timestamp.getHours([tz]) -> intduration.getHours() -> intПримеры: duration("1h30m").getHours() // 1 | ✓ | ✓ | ✓ | ✓ | ✗ |
getMinutes | Returns the minutes (0-59). Подписи: timestamp.getMinutes([tz]) -> intduration.getMinutes() -> intПримеры: duration("1h30m").getMinutes() // 30 | ✓ | ✓ | ✓ | ✓ | ✗ |
getSeconds | Returns the seconds (0-59). Signatures: timestamp.getSeconds([tz]) -> intduration.getSeconds() -> intПримеры: duration("1h30m45s").getSeconds() // 45 | ✓ | ✓ | ✓ | ✓ | ✗ |
getMilliseconds | Returns the milliseconds (0-999). Signatures: timestamp.getMilliseconds([tz]) -> intduration.getMilliseconds() -> intПримеры: duration("1.5s").getMilliseconds() // 500 | ✓ | ✓ | ✓ | ✓ | ✗ |
Преобразование типов
| Тип цели | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
bool | Converts to boolean. Signatures: bool(bool) -> boolbool(string) -> boolПримеры: bool("true") // true | ✓ | ✓ | ✓ | ✓ | ✓ |
bytes | Converts to bytes. Signatures: bytes(bytes) -> bytesbytes(string) -> bytesПримеры: bytes("hello") // b"hello" | ✓ | ✓ | ✓ | ✓ | ✓ |
double | Converts to double-precision float. Signatures: double(double) -> doubledouble(int) -> doubledouble(uint) -> doubledouble(string) -> doubleПримеры: double(1) // 1.0 | ✓ | ✓ | ✓ | ✓ | ✓ |
duration | Converts to duration. Signatures: duration(duration) -> durationduration(string) -> durationПримеры: duration("1.5s") // 1.5s duration | ✓ | ✓ | ✓ | ✓ | ✓ |
int | Converts to 64-bit signed integer. Signatures: int(int) -> intint(uint) -> intint(double) -> int (rounds to zero)int(string) -> intint(timestamp) -> int (seconds since epoch)Примеры: int(1.5) // 1 | ✓ | ✓ | ✓ | ✓ | ✓ |
string | Converts to string. Signatures: string(T) -> string (supports bool , int , uint , double , bytes , timestamp , duration )Примеры: string(1.5) // "1.5" | ✓ | ✓ | ✓ | ✓ | ✓ |
timestamp | Converts to timestamp. Signatures: timestamp(timestamp) -> timestamptimestamp(string) -> timestamp (RFC3339)Примеры: timestamp("2026-07-23T00:00:00Z") | ✓ | ✓ | ✓ | ✓ | ✓ |
uint | Converts to 64-bit unsigned integer. Signatures: uint(uint) -> uintuint(int) -> uintuint(double) -> uintuint(string) -> uintПримеры: uint(1) // 1u | ✓ | ✓ | ✓ | ✓ | ✓ |
dyn | Casts value to dynamic type for type-checking. Signatures: dyn(T) -> dynПримеры: dyn([1, "two"]) | ✓ | ✓ | ✓ | ✓ | ✗ |
type | Returns the type of the value. Signatures: type(T) -> typeПримеры: type(1) // int | ✓ | ✓ | ✓ | ✓ | ✗ |
4. Extensions (Libraries)
Bindings Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
cel.bind | Binds a local variable to avoid duplicate evaluation. Signatures: cel.bind(varName, initExpr, resultExpr) -> TПримеры: cel.bind(x, a + b, x * x) | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Bindings()tocel.NewEnv(). - C++: Add
BindingsCompilerLibrary()toCompilerBuilder. (Runtime is handled automatically). - Java: Add
CelExtensions.bindings()toCelCompilerandCelRuntimebuilders. - Python: Import
cel_expr_python.ext.ext_bindingsand useExtBindings()incel.NewEnv(extensions=[...]).
Encoders Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
base64.encode | Encodes bytes to base64 string. Signatures: base64.encode(bytes) -> stringПримеры: base64.encode(b"hello") // "aGVsbG8=" | ✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
base64.decode | Decodes base64 string to bytes. Throws error on invalid input. Подписи: base64.decode(string) -> bytesПримеры: base64.decode("aGVsbG8=") // b"hello" | ✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
json.encode | Serializes a CEL value to JSON string. Signatures: json.encode(dyn) -> stringПримеры: json.encode([1, 2]) // "[1,2]" | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Pass
ext.Encoders()tocel.NewEnv(). - C++:
- Compiler: Add
EncodersCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterEncodersFunctions()onFunctionRegistry.
- Compiler: Add
- Java: Add
CelExtensions.encoders()toCelCompilerandCelRuntimebuilders. - Python: Import
cel_expr_python.ext.ext_encodersand useExtEncoders()incel.NewEnv(extensions=[...]).
Математическая библиотека
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
math.greatest | Returns greatest of numeric arguments (or list of numerics). Signatures: math.greatest(arg, ...) -> TПримеры: math.greatest(1, 3, 2) // 3 | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.least | Returns least of numeric arguments (or list of numerics). Signatures: math.least(arg, ...) -> TПримеры: math.least([1, 3, 2]) // 1 | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.abs | Абсолютное значение. Signatures: math.abs(T) -> T (supports int , uint , double )Примеры: math.abs(-1) // 1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sqrt | Квадратный корень. Signatures: math.sqrt(T) -> double (supports int , uint , double )Примеры: math.sqrt(9) // 3.0 | ✓ (v0.25.1) | ✓ (v0.12.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
math.bitAnd | Bitwise AND. Подписи: math.bitAnd(T, T) -> T (supports int , uint )Примеры: math.bitAnd(5, 3) // 1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitOr | Bitwise OR. Signatures: math.bitOr(T, T) -> T (supports int , uint )Примеры: math.bitOr(5, 3) // 7 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitXor | Bitwise XOR. Signatures: math.bitXor(T, T) -> T (supports int , uint )Примеры: math.bitXor(5, 3) // 6 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitNot | Bitwise NOT. Signatures: math.bitNot(T) -> T (supports int , uint )Примеры: math.bitNot(1) // -2 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftLeft | Bitwise shift left. Signatures: math.bitShiftLeft(T, int) -> T (supports int , uint )Примеры: math.bitShiftLeft(1, 2) // 4 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftRight | Bitwise shift right. Signatures: math.bitShiftRight(T, int) -> T (supports int , uint )Примеры: math.bitShiftRight(4, 2) // 1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.ceil | Ceiling rounding. Подписи: math.ceil(double) -> doubleПримеры: math.ceil(1.2) // 2.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.floor | Floor rounding. Signatures: math.floor(double) -> doubleПримеры: math.floor(1.8) // 1.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.round | Nearest integer rounding. Signatures: math.round(double) -> doubleПримеры: math.round(1.5) // 2.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.trunc | Truncation rounding (towards zero). Signatures: math.trunc(double) -> doubleПримеры: math.trunc(-1.8) // -1.0 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isInf | Checks if double is positive or negative infinity. Signatures: math.isInf(double) -> boolПримеры: math.isInf(1.0/0.0) // true | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isNaN | Checks if double is NaN. Signatures: math.isNaN(double) -> boolПримеры: math.isNaN(0.0/0.0) // true | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isFinite | Checks if double is finite. Signatures: math.isFinite(double) -> boolПримеры: math.isFinite(1.2) // true | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sign | Returns sign of value (-1, 0, or 1). Signatures: math.sign(T) -> T (supports int , uint , double )Примеры: math.sign(-42) // -1 | ✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Math()tocel.NewEnv(). - C++:
- Compiler: Add
MathCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterMathExtensionFunctions()onFunctionRegistry.
- Compiler: Add
- Java: Add
CelExtensions.math()toCelCompilerandCelRuntimebuilders. - Python: Import
cel_expr_python.ext.ext_mathand useExtMath()incel.NewEnv(extensions=[...]).
Protos Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
proto.getExt | Gets proto2 extension field, or default if unset. Signatures: proto.getExt(msg, extName) -> TПримеры: proto.getExt(msg, google.api.expr.test.int32_ext) | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
proto.hasExt | Checks if proto2 extension field is set. Signatures: proto.hasExt(msg, extName) -> boolПримеры: proto.hasExt(msg, google.api.expr.test.int32_ext) | ✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Protos()tocel.NewEnv(). - C++: Add
ProtoExtCompilerLibrary()toCompilerBuilder. (Runtime is handled automatically). - Java: Add
CelExtensions.protos()toCelCompilerandCelRuntimebuilders. - Python: Import
cel_expr_python.ext.ext_protoand useExtProto()incel.NewEnv(extensions=[...]).
Lists Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
distinct | Returns distinct elements. Signatures: list.distinct() -> listПримеры: [1, 2, 2].distinct() // [1, 2] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
flatten | Flattens nested lists. Signatures: list.flatten([depth]) -> listПримеры: [[1], [2, 3]].flatten() // [1, 2, 3] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.7.1) | ✓ (v0.1.1) | ✗ |
lists.range | Returns list of integers [0, ..., n-1] .Signatures: lists.range(int) -> list(int)Примеры: lists.range(3) // [0, 1, 2] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
reverse | Reverses the list. Signatures: list.reverse() -> listПримеры: [1, 2].reverse() // [2, 1] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
slice | Returns sub-list (start inclusive, end exclusive). Signatures: list.slice(start, end) -> listПримеры: [1, 2, 3].slice(1, 3) // [2, 3] | ✓ (v0.17.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sort | Sorts list of comparable elements. Signatures: list.sort() -> listПримеры: [3, 1, 2].sort() // [1, 2, 3] | ✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sortBy | Sorts list by key evaluated from expression. Signatures: list.sortBy(var, expr) -> listПримеры: [{"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 | Returns first element as optional. Requires the Optional extension. Signatures: list.first() -> optionalПримеры: [1, 2].first() // optional(1) | ✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
last | Returns last element as optional. Requires the Optional extension. Signatures: list.last() -> optionalПримеры: [1, 2].last() // optional(2) | ✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
Как включить
- Go: Pass
ext.Lists()tocel.NewEnv(). - C++:
- Compiler: Add
ListsCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterListsFunctions()onFunctionRegistryandRegisterListsMacros()onMacroRegistry.
- Compiler: Add
- Java: Add
CelExtensions.lists()toCelCompilerandCelRuntimebuilders. - Python: Enable via
cel.EnvConfigby addingliststo theextensionslist.
Sets Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
sets.contains | Checks if list1 contains all elements of list2. Signatures: sets.contains(list1, list2) -> boolПримеры: sets.contains([1, 2], [1]) // true | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.equivalent | Checks if lists are set-equivalent (contain same unique elements). Signatures: sets.equivalent(list1, list2) -> boolПримеры: sets.equivalent([1, 2], [2, 1, 1]) // true | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.intersects | Checks if lists share at least one element. Signatures: sets.intersects(list1, list2) -> boolПримеры: sets.intersects([1, 2], [2, 3]) // true | ✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Sets()tocel.NewEnv(). - C++:
- Compiler: Add
SetsCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterSetsFunctions()onFunctionRegistry.
- Compiler: Add
- Java: Add
CelExtensions.sets()toCelCompilerandCelRuntimebuilders. - Python: Enable via
cel.EnvConfigby addingsetsto theextensionslist.
Strings Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
charAt | Returns character at index. Signatures: string.charAt(int) -> stringПримеры: "hello".charAt(1) // "e" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
indexOf | Returns index of first occurrence of substring, or -1. Signatures: string.indexOf(substr, [start]) -> intПримеры: "hello".indexOf("l") // 2 | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
lastIndexOf | Returns index of last occurrence of substring, or -1. Signatures: string.lastIndexOf(substr, [end]) -> intПримеры: "hello".lastIndexOf("l") // 3 | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
join | Concatenates strings. Signatures: list(string).join([separator]) -> stringПримеры: ["a", "b"].join("-") // "ab" | ✓ (v0.10.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
split | Splits string by separator. Signatures: string.split(separator, [limit]) -> list(string)Примеры: "ab".split("-") // ["a", "b"] | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
substring | Returns substring (start inclusive, end exclusive). Signatures: string.substring(start, [end]) -> stringПримеры: "hello".substring(1, 3) // "el" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
trim | Trims Unicode whitespace. Signatures: string.trim() -> stringПримеры: " hello ".trim() // "hello" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
replace | Replaces occurrences of old with new. Signatures: string.replace(old, new, [limit]) -> stringПримеры: "hello".replace("l", "w") // "hewwo" | ✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
reverse | Reverses Unicode code points. Signatures: string.reverse() -> stringПримеры: "abc".reverse() // "cba" | ✓ (v0.18.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
lowerAscii | Converts ASCII characters to lowercase. Signatures: string.lowerAscii() -> stringПримеры: "Hello".lowerAscii() // "hello" | ✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
upperAscii | Converts ASCII characters to uppercase. Signatures: string.upperAscii() -> stringПримеры: "Hello".upperAscii() // "HELLO" | ✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
quote | Escapes string for safe printing. Signatures: strings.quote(string) -> stringПримеры: strings.quote("a\tb") // "\"a\\tb\"" | ✓ (v0.14.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
format | Formats the string using printf-style placeholders. Signatures: string.format(list) -> stringПримеры: "str: %s, int: %d".format(["a", 1]) // "str: a, int: 1" | ✓ (v0.14.0) | ✓ (v0.11.0) | ✗ | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Strings()tocel.NewEnv(). - C++:
- Compiler: Add
StringsCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterStringsFunctions()onFunctionRegistry.
- Compiler: Add
- Java: Add
CelExtensions.strings()toCelCompilerandCelRuntimebuilders. - Python: Import
cel_expr_python.ext.ext_stringsand useExtStrings()incel.NewEnv(extensions=[...]).
Regular Expression Library
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
regex.replace | Replaces matches with replacement string (supports backreferences). Signatures: regex.replace(target, pat, repl, [limit]) -> stringПримеры: 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 | Returns first match of pattern (must have one capture group). Signatures: regex.extract(target, pat) -> optional(string)Примеры: regex.extract("a123b", r"(\d+)") // optional("123") | ✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
regex.extractAll | Returns all matches of pattern (must have one capture group). Signatures: regex.extractAll(target, pat) -> list(string)Примеры: regex.extractAll("a1b2", r"(\d+)") // ["1", "2"] | ✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
Как включить
- Go: Pass
ext.Regex()tocel.NewEnv(). - C++:
- Compiler: Add
RegexExtCompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterRegexExtensionFunctions()onFunctionRegistry.
- Compiler: Add
- Java: Add
CelExtensions.regex()toCelCompilerandCelRuntimebuilders. - Python: Enable via
cel.EnvConfigby addingregexandoptionalto theextensionslist.
Two-Variable Comprehensions
| Макро | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
all | Short-circuiting logical AND over key/index and value. Signatures: list.all(i, v, pred) -> boolmap.all(k, v, pred) -> boolПримеры: [1, 2].all(i, v, v > 0) // true | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
exists | Short-circuiting logical OR over key/index and value. Signatures: list.exists(i, v, pred) -> boolmap.exists(k, v, pred) -> boolПримеры: [1, 2].exists(i, v, v == 2) // true | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
existsOne | Checks if exactly one pair satisfies predicate. Signatures: list.existsOne(i, v, pred) -> boolmap.existsOne(k, v, pred) -> boolПримеры: [1, 2].existsOne(i, v, v == 2) // true | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformList | Transforms/filters list/map into a list. Signatures: list.transformList(i, v, [filter], transform) -> listmap.transformList(k, v, [filter], transform) -> listПримеры: [1, 2].transformList(i, v, v * 2) // [2, 4] | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMap | Transforms values of list/map into a map (keys remain fixed). Signatures: list.transformMap(i, v, [filter], transform) -> mapmap.transformMap(k, v, [filter], transform) -> mapПримеры: [1, 2].transformMap(i, v, v * 2) // {0: 2, 1: 4} | ✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMapEntry | Transforms into a map. Signatures: list.transformMapEntry(i, v, [filter], transform_entry) -> mapmap.transformMapEntry(k, v, [filter], transform_entry) -> mapПримеры: [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) | ✗ |
Как включить
- Go: Pass
ext.TwoVarComprehensions()tocel.NewEnv(). - C++:
- Compiler: Add
ComprehensionsV2CompilerLibrary()toCompilerBuilder. - Runtime: Call
RegisterComprehensionsV2Functions()onFunctionRegistryandRegisterComprehensionsV2Macros()onMacroRegistry.
- Compiler: Add
- Java: Add
CelExtensions.comprehensions()toCelCompilerandCelRuntimebuilders. - Python: Enable via
cel.EnvConfigby addingtwo-var-comprehensionsto theextensionslist.
Native Types Library
| Особенность | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
| Native Structs | Registering and instantiating host native types (Go structs / Java POJOs) in CEL. Примеры: Account{id: 123} (Java POJO instanced in CEL) | ✓ (v0.13.0) | ✗ | ✓ (v0.13.0) | ✗ | ✗ |
Как включить
- Go: Pass
cel.NativeTypes(...)orext.NativeTypes(...)(providing reflect types) tocel.NewEnv(). - C++: Not supported.
- Java: Add
CelExtensions.nativeTypes()(providing Java classes) toCelCompilerandCelRuntimebuilders. - Python: Not supported.
Network Library
The Network library provides functions for parsing, validating, and manipulating IP addresses and CIDR blocks.
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
ip | Parses a string into an IP address, or extracts the IP from a CIDR. Signatures: ip(string) -> IPCIDR.ip() -> IPПримеры: ip("192.168.0.1")cidr("192.168.0.0/24").ip() | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isIP | Checks if a string is a valid IP address. Signatures: isIP(string) -> boolПримеры: isIP("192.168.0.1") // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
ip.isCanonical | Checks if an IP address string is in its canonical format. Signatures: ip.isCanonical(string) -> boolПримеры: ip.isCanonical("192.168.0.1") // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
cidr | Parses a string into a CIDR block. Signatures: cidr(string) -> CIDRПримеры: cidr("192.168.0.0/24") | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isCIDR | Checks if a string is a valid CIDR block. Signatures: isCIDR(string) -> boolПримеры: isCIDR("192.168.0.0/24") // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsIP | Checks if a CIDR block contains an IP address. Signatures: CIDR.containsIP(IP) -> boolCIDR.containsIP(string) -> boolПримеры: cidr("192.168.0.0/24").containsIP(ip("192.168.0.1")) // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsCIDR | Checks if a CIDR block contains another CIDR block. Signatures: CIDR.containsCIDR(CIDR) -> boolCIDR.containsCIDR(string) -> boolПримеры: cidr("192.168.0.0/16").containsCIDR(cidr("192.168.1.0/24")) // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
family | Returns the IP family (4 for IPv4, 6 for IPv6). Signatures: IP.family() -> intПримеры: ip("192.168.0.1").family() // 4 | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isGlobalUnicast | Checks if the IP is a global unicast address. Signatures: IP.isGlobalUnicast() -> boolПримеры: ip("192.168.0.1").isGlobalUnicast() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalMulticast | Checks if the IP is a link-local multicast address. Signatures: IP.isLinkLocalMulticast() -> boolПримеры: ip("224.0.0.1").isLinkLocalMulticast() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalUnicast | Checks if the IP is a link-local unicast address. Signatures: IP.isLinkLocalUnicast() -> boolПримеры: ip("169.254.0.1").isLinkLocalUnicast() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLoopback | Checks if the IP is a loopback address. Signatures: IP.isLoopback() -> boolПримеры: ip("127.0.0.1").isLoopback() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isMask | Checks if the CIDR is a valid subnet mask. Signatures: CIDR.isMask() -> boolПримеры: cidr("255.255.255.0/24").isMask() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isUnspecified | Checks if the IP is an unspecified address (eg 0.0.0.0 ).Signatures: IP.isUnspecified() -> boolПримеры: ip("0.0.0.0").isUnspecified() // true | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
masked | Returns the masked CIDR block. Signatures: CIDR.masked() -> CIDRПримеры: cidr("192.168.0.1/24").masked() // 192.168.0.0/24 | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
prefixLength | Returns the prefix length of the CIDR block. Signatures: CIDR.prefixLength() -> intПримеры: cidr("192.168.0.0/24").prefixLength() // 24 | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
string | Converts IP or CIDR to string. Signatures: string(IP) -> stringstring(CIDR) -> stringПримеры: string(ip("192.168.0.1")) // "192.168.0.1" | ✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Pass
ext.Network()tocel.NewEnv(). - C++: Not supported.
- Java: Not supported.
- Python: Not supported.
Библиотека JWT
The JWT library provides data types and helper functions for parsing JSON Web Tokens (JWT) and inspecting standard and custom claims.
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
jwt.parse | Parses a raw token string into a structured jwt.Token wrapped in an optional.Signatures: jwt.parse(string) -> optional(jwt.Token)Примеры: jwt.parse(token_string).hasValue() | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
claim | Queries a custom claim value by key name from the token payload. Signatures: jwt.Token.claim(string) -> optional(dyn)optional(jwt.Token).claim(string) -> optional(dyn)Примеры: jwt.parse(token).claim("tenant").orValue("") | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
presentedBy | Validates that the token's issuer and audience match expected values. Signatures: jwt.Token.presentedBy(string, string) -> booloptional(jwt.Token).presentedBy(string, string) -> boolПримеры: jwt.parse(token).presentedBy("https://auth.example.com", "https://api.example.com") | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Import
cel.dev/cel-go/ext/security/jwtand passjwt.Library()tocel.NewEnv(). - C++: Not supported.
- Java: Not supported.
- Python: Not supported.
HMAC Library
The HMAC library provides cryptographic functions to compute and verify Hash-based Message Authentication Codes (HMAC) over strings and byte sequences.
| Функция | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
hmac.compute | Computes raw HMAC signature bytes using the specified algorithm and secret key. Signatures: hmac.compute(string, string|bytes, string|bytes) -> bytesПримеры: hmac.compute(hmac.SHA256, "secret", "message") | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
hmac.verify | Verifies whether an HMAC signature matches the expected digest. Signatures: hmac.verify(string, string|bytes, string|bytes, string|bytes) -> boolПримеры: hmac.verify(hmac.SHA256, secret, msg, expected_sig) // true | ✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
Как включить
- Go: Import
cel.dev/cel-go/ext/security/hmacand passhmac.Library()tocel.NewEnv(). - C++: Not supported.
- Java: Not supported.
- Python: Not supported.
5. Расширенные функции
Advanced Features Summary
| Особенность | Описание | Идти | C++ | Java | Python | С |
|---|---|---|---|---|---|---|
| Частичная оценка | Evaluate with missing inputs; returns unknowns or a simplified expression. | ✓ ³ | ✓ ⁴ | ✓ ⁴ | ✗ | ✗ |
| Async Evaluation | Non-blocking concurrent execution of extension functions. | ✓ ⁵ | ✗ | ✓ ⁶ | ✗ | ✗ |
| AST Validators | Static analysis checks on the Checked AST after type-checking. | ✓ | ✓ | ✓ | ✗ | ✗ |
| AST Optimizers | AST rewrites (constant folding, inlining, CSE) to improve performance. | ✓ | ✓ | ✓ | ✗ | ✗ |
| CEL Policy Compiler | Compiles YAML-based policy structures into standard CEL ASTs. | ✓ | ✓ | ✓ | ✗ | ✗ |
| Формальная верификация | Proves safety invariants, satisfiability, validity, and AST equivalence. | ✗ | ✗ | ✓ (v0.14.0) | ✗ | ✗ |
³ Go supports generating a Residual AST (pruned AST). ⁴ C++ and Java support returning UnknownSet / CelUnknownSet at runtime, but do not expose public APIs for residual AST generation. ⁵ Go uses AsyncBinding / AsyncOp returning channels. ⁶ Java uses CelAsyncRuntime returning ListenableFuture .
Partial Evaluation (Unknowns)
Partial evaluation allows evaluating an expression when only a subset of the input variables (arguments) are known. Instead of failing, the evaluation produces a result that indicates what is missing, or a simplified expression.
- Go: Full support. Allows defining a
PartialActivationwith patterns of unknown attributes. Evaluation returns atypes.Unknownvalue. Go supports generating a Residual AST (Env.ResidualAst) which is a pruned, simplified AST containing only the parts of the expression that could not be evaluated. - C++: Supports
Unknownvalues. Unknown attribute patterns are configured viaActivation::set_unknown_attribute_patterns. Evaluation returns anUnknownSet. Public API does not currently expose residual AST generation. - Java: Supports partial evaluation via
PartialVarspassed toProgram.eval(). Evaluation returns aCelUnknownSet. Public API does not currently expose residual AST generation. - Python / C: No native support.
Async Evaluation
Async evaluation allows CEL expressions to call functions that execute asynchronously (eg, making RPCs or database queries) and block evaluation until the results are available, without blocking the main execution thread.
- Go: Supports asynchronous function overloads via
AsyncBindingandAsyncOp. Async functions return a Go channel (<-chan ref.Val), and the interpreter manages the concurrent execution and synchronization. - Java: Supports async evaluation via
CelAsyncRuntimeandAsyncProgram. It usesListenableFutureto represent pending values and automatically drives evaluation to completion as futures resolve. - C++ / Python / C: No built-in support.
AST Validators
Validators perform static analysis on the Checked AST after type-checking to enforce domain-specific constraints before the program is executed.
- Go: Supports
ASTValidatorinterface. Canonical validators includecel.validator.duration,cel.validator.timestamp,cel.validator.matches(regex),cel.validator.homogeneous_literals, andcel.validator.comprehension_nesting_limit. - C++: Supports
cel::Validator. Canonical validations includeAstDepthValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,MatchesValidator, andTimestampLiteralValidator. - Java: Supports
CelValidatorandCelAstValidator. Canonical validators includeAstDepthLimitValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,RegexLiteralValidator, andTimestampLiteralValidator. - Python / C: No direct support.
AST Optimizers
Optimizers rewrite the AST to improve execution performance. Optimizers fall into one of two categories: static and runtime optimizers. C++, Java, and Go support runtime optimization. CEL Java and Go also support static optimizers.
Typical optimizations include constant folding (pre-evaluating sub-expressions with constant inputs) and common subexpression elimination (CSE).
- Go: Supports AST folding during compilation/planning.
- C++: Supports constant folding via the
cel::extensions::EnableConstantFoldingextension at plan time. - Java: Supports
CelOptimizerinterface. Canonical optimizers includeConstantFoldingOptimizer(which supports pre-order traversal, Protobuf message constant folding, and aggregate or optional pruning),InliningOptimizer, andSubexpressionOptimizer(CSE). - Python / C: No direct support.
CEL Policy Compiler
CEL Policy is a YAML-based format for composing multiple CEL expressions together with variables, match blocks, conditional outputs, and nested rules. It is designed for complex policy engines (like Kubernetes Admission Control) where single CEL expressions would become unreadable.
For the formal language definition, syntax, and conformance suite, refer to the CEL Policy Specification .
The Policy Compiler compiles these YAML policies into a single standard CEL AST, meaning they are fully compatible with standard CEL runtimes and inherit all performance and safety guarantees.
- Go: Supported via Go policy (including aggregate rule evaluation semantics).
- C++: Supported via C++ policy .
- Java: Supported via Java policy (including aggregate rule evaluation semantics and shorthand type specifiers in policy configs).
- Python / C: Not directly supported.
Formal Verification Framework
The Formal Verification framework allows users to mathematically prove safety invariants, logical equivalence, satisfiability, and validity across CEL expressions and structured CEL Policies.
- Java: Supported via the CEL Java Verifier (
dev.cel:verifieranddev.cel:verifier-cli). Capabilities include satisfiability (isSatisfiable) with witness input generation, validity (isAlwaysTrue) with counterexample generation, bounded model checking (BMC) for comprehensions, logical equivalence proofs across ASTs, and customassume/assertpolicy invariant verification. - Go / C++ / Python / C: Are supported indirectly via the Java command line toolchain.
Для ознакомления и примеров из реальной жизни см. сообщение в блоге Google Open Source: Обеспечение безопасности в эпоху агентного управления: внедрение формальной верификации для CEL .