Справочник по API языка выражений Common Expression Language (CEL)

Этот документ служит единым справочником API для языка выражений Common Expression Language (CEL). В нем перечислены все макросы, операторы и стандартные функции, указаны их сигнатуры, поведение и статус поддержки во всех официальных стеках CEL.

Для получения более подробной информации о поведении и спецификациях языка обратитесь к определению языка CEL .

Версии стека

Данный справочный документ основан на следующих версиях стеков CEL:

  • CEL Go : v0.29.2 (и более новые версии)
  • CELC C++ : v0.15.0
  • CEL Java : v0.13.1
  • 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 -> T
T - T -> T
T * T -> T
T / T -> T
T % T -> T
-T -> T
+T -> T
list + list -> list

Примеры:
1 + 2 * 3 // 7
[1] + [2] // [1, 2]
²
Сравнение ( == , != , < , <= , > , >= ) Стандартное сравнение. Числовые сравнения неоднородны (например, 1 == 1.0 ).

Подписи:
T == T -> bool
T != T -> bool
T < T -> bool
T <= T -> bool
T > T -> bool
T >= T -> bool

Примеры:
x < 42.0
1 == 1.0 // true
Логическое ( ! , && , || , ? : ) Логические операторы НЕ, И, ИЛИ и троичные условные операторы. Операторы И/ИЛИ используют сокращенную оценку.

Подписи:
!bool -> bool
bool && bool -> bool
bool || bool -> bool
bool ? T : T -> T

Примеры:
x > 0 ? "positive" : "non-positive"
Индексирование ( [] ) Доступ к элементу списка осуществляется по индексу или по ключу поиска в карте.

Подписи:
list[int] -> T
map[K] -> V

Примеры:
tags[0]
users['john']
Членство ( in ) Проверьте, находится ли элемент в списке или ключ в карте.

Подписи:
T in list -> bool
K in map -> bool

Примеры:
'admin' in roles

² Конкатенация списков ( list + list ) не поддерживается в среде выполнения C, хотя другие арифметические операторы поддерживаются.


3. Основные функции

Общие и строковые функции

Функция Описание Идти C++ Java Python С
size Возвращает размер строки (символов), байтов, списка или карты.

Подписи:
size(T) -> int (где Tstring , bytes , list или map ) <br /><br />**Examples:**<br /> 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]) -> int
duration.getHours() -> int

Примеры:
duration("1h30m").getHours() // 1
getMinutes Возвращает количество минут (от 0 до 59).

Подписи:
timestamp.getMinutes([tz]) -> int
duration.getMinutes() -> int

Примеры:
duration("1h30m").getMinutes() // 30
getSeconds Возвращает секунды (от 0 до 59).

Подписи:
timestamp.getSeconds([tz]) -> int
duration.getSeconds() -> int

Примеры:
duration("1h30m45s").getSeconds() // 45
getMilliseconds Возвращает значение в миллисекундах (0-999).

Подписи:
timestamp.getMilliseconds([tz]) -> int
duration.getMilliseconds() -> int

Примеры:
duration("1.5s").getMilliseconds() // 500

Преобразование типов

Тип цели Описание Идти C++ Java Python С
bool Преобразует в логическое значение.

Подписи:
bool(bool) -> bool
bool(string) -> bool

Примеры:
bool("true") // true
bytes Преобразует в байты.

Подписи:
bytes(bytes) -> bytes
bytes(string) -> bytes

Примеры:
bytes("hello") // b"hello"
double Преобразует в число с плавающей запятой двойной точности.

Подписи:
double(double) -> double
double(int) -> double
double(uint) -> double
double(string) -> double

Примеры:
double(1) // 1.0
duration Преобразуется в продолжительность.

Подписи:
duration(duration) -> duration
duration(string) -> duration

Примеры:
duration("1.5s") // 1.5s duration
int Преобразует в 64-битное знаковое целое число.

Подписи:
int(int) -> int
int(uint) -> int
int(double) -> int (округляет до нуля)
int(string) -> int
int(timestamp) -> int (секунд с начала эпохи)

Примеры:
int(1.5) // 1
string Преобразует в строку.

Подписи:
string(T) -> string (поддерживает bool , int , uint , double , bytes , timestamp , duration ) <br /><br />**Examples:**<br /> string(1.5) // "1.5"`
timestamp Преобразует в метку времени.

Подписи:
timestamp(timestamp) -> timestamp
timestamp(string) -> timestamp (RFC3339)

Примеры:
timestamp("2026-07-23T00:00:00Z")
uint Преобразует в 64-битное беззнаковое целое число.

Подписи:
uint(uint) -> uint
uint(int) -> uint
uint(double) -> uint
uint(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)

Как включить

Математическая библиотека

Функция Описание Идти 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 ) <br /><br />**Examples:**<br /> 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 ) <br /><br />**Examples:**<br /> 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 ) <br /><br />**Examples:**<br /> 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 ) <br /><br />**Examples:**<br /> 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 ) <br /><br />**Examples:**<br /> 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 ) <br /><br />**Examples:**<br /> 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 ) <br /><br />**Examples:**<br /> 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 ) <br /><br />**Examples:**<br /> 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 ) <br /><br />**Examples:**<br /> math.sign(-42) // -1`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)

Как включить

  • Go: Передайте ext.Math() в cel.NewEnv() .
  • C++:
  • 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)

Как включить

Библиотека наборов

Функция Описание Идти 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++:
  • 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)

Как включить

  • Go: Передайте ext.Strings() в cel.NewEnv() .
  • C++:
  • 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++:
  • Java: Добавить CelExtensions.regex() в сборщики CelCompiler и CelRuntime .
  • Python: Включить через cel.EnvConfig , добавив regex и optional в список extensions .

Понимание двух переменных

Макро Описание Идти C++ Java Python С
all Замыкание логической операции И по ключу/индексу и значению.

Подписи:
list.all(i, v, pred) -> bool
map.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) -> bool
map.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) -> bool
map.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) -> list
map.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) -> map
map.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) -> map
map.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)

Как включить

Библиотека исходных типов

Особенность Описание Идти C++ Java Python С
Местные сооружения Регистрация и создание экземпляров собственных типов хоста (структур Go / POJO-объектов Java) в CEL.

Примеры:
Account{id: 123} (Java POJO, созданный в CEL)
(v0.13.0) (v0.13.0)

Как включить

  • Go: Передайте ext.NativeTypes(...) (предоставляющий типы отражения) в cel.NewEnv() .
  • C++: Не поддерживается.
  • Java: Добавить CelExtensions.nativeTypes() (предоставляющий Java-классы) в сборщики CelCompiler и CelRuntime .
  • Python: Не поддерживается.

Сетевая библиотека

Библиотека Network предоставляет функции для анализа, проверки и обработки IP-адресов и блоков CIDR.

Функция Описание Идти C++ Java Python С
ip Преобразует строку в IP-адрес или извлекает IP-адрес из CIDR-диапазона.

Подписи:
ip(string) -> IP
CIDR.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) -> bool
CIDR.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) -> bool
CIDR.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) -> string
string(CIDR) -> string

Примеры:
string(ip("192.168.0.1")) // "192.168.0.1"
(v0.29.0)

Как включить

  • Go: Передайте ext.Network() в cel.NewEnv() .
  • C++: Не поддерживается.
  • Java: не поддерживается.
  • Python: Не поддерживается.

5. Расширенные функции

Краткое описание расширенных функций

Особенность Описание Идти C++ Java Python С
Частичная оценка Выполняет оценку при наличии недостающих входных данных; возвращает неизвестные значения или упрощенное выражение. ³
Асинхронная оценка Неблокирующее параллельное выполнение функций расширения.
Валидаторы AST Статический анализ проверяется в AST после проверки типов.
Оптимизаторы AST Переписывание AST (свертывание констант, встраивание, CSE) для повышения производительности.
Компилятор политик CEL Компилирует структуры политик на основе YAML в стандартные CEL AST.

³ 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 (который может сворачивать короткие ветви, имитируя частичную оценку), InliningOptimizer и SubexpressionOptimizer (CSE).
  • Python / C: Прямая поддержка отсутствует.

Компилятор политик CEL

CEL Policy — это формат на основе YAML для объединения нескольких выражений CEL с переменными, блоками соответствия, условными выходными данными и вложенными правилами. Он разработан для сложных механизмов управления политиками (таких как Kubernetes Admission Control), где отдельные выражения CEL стали бы нечитаемыми.

Компилятор политик объединяет эти политики YAML в единый стандартный CEL AST, что означает их полную совместимость со стандартными средами выполнения CEL и сохранение всех гарантий производительности и безопасности.

  • Go: Поддерживается через third_party/cel/go/policy .
  • C++: Поддерживается через third_party/cel/cpp/policy .
  • Java: Поддерживается через third_party/java/cel/policy .
  • Python / C: Прямая поддержка отсутствует.