Common Expression Language (CEL) API 참조

이 문서는 Common Expression Language (CEL)의 통합 API 문서 참조 역할을 합니다. 공식 CEL 스택 전반에서 시그니처, 동작, 지원 상태를 나타내는 모든 매크로, 연산자, 표준 함수를 나열합니다.

언어 동작 및 사양에 대한 자세한 내용은 CEL 언어 정의를 참고하세요.

스택 버전

이 참조 문서는 다음 버전의 CEL 스택을 기반으로 합니다.

  • CEL Go: v0.29.2 이상
  • CEL C++: v0.15.0
  • CEL Java: v0.13.1
  • CEL Python: v0.1.3
  • CEL C: 개발 스냅샷 (미출시)

GitHub 미러

CEL의 공식 구현은 GitHub의 cel-expr 조직 아래에 미러링됩니다.


1. 핵심 매크로

이러한 매크로는 컴파일 시간에 확장되는 기본 제공 매크로입니다.

Macro 설명 Go C++ 자바 Python C
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) 목록의 요소 중 정확히 1개가 조건자를 충족하는지 테스트합니다.

서명:
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. 핵심 연산자

연산자 설명 Go C++ 자바 Python C
산술 (+, -, *, /, %) 표준 산술 연산입니다. 부정 (-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
논리 (!, &&, ||, ? :) 논리 NOT, AND, OR, 삼항 조건 연산자입니다. AND/OR 단락 회로 평가를 사용합니다.

서명:
!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. 핵심 기능

일반 및 문자열 함수

함수 설명 Go C++ 자바 Python C
size 문자열 (문자), 바이트, 목록 또는 지도의 크기를 반환합니다.

서명:
size(T) -> int (여기서 Tstring, bytes, list 또는 map임)<br /><br />**Examples:**<br />size("hello") // 5`
contains 문자열에 하위 문자열이 포함되어 있는지 여부를 반환합니다.

서명:
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에서 구성요소를 추출합니다.

함수 설명 Go C++ 자바 Python C
getFullYear 4자리 연도를 반환합니다.

서명:
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

유형 변환

타겟 유형 설명 Go C++ 자바 Python C
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 (0으로 반올림)
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. 확장 프로그램 (라이브러리)

바인딩 라이브러리

함수 설명 Go C++ 자바 Python C
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 C++ 자바 Python C
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 C++ 자바 Python C
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 비트 AND입니다.

서명:
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 비트 OR입니다.

서명:
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 비트 NOT입니다.

서명:
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 절삭 반올림 (0 방향)

서명:
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)

사용 설정 방법

Protos 라이브러리

함수 설명 Go C++ 자바 Python C
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)

사용 설정 방법

  • 이동: ext.Protos()cel.NewEnv()에 전달합니다.
  • C++: CompilerBuilderProtoExtCompilerLibrary() 추가 (런타임은 자동으로 처리됩니다.)
  • Java: CelCompilerCelRuntime 빌더에 CelExtensions.protos()를 추가합니다.
  • Python: cel_expr_python.ext.ext_proto를 가져오고 cel.NewEnv(extensions=[...])에서 ExtProto()를 사용합니다.

목록 라이브러리

함수 설명 Go C++ 자바 Python C
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 첫 번째 요소를 선택사항으로 반환합니다. 선택적 확장 프로그램이 필요합니다.

서명:
list.first() -> optional

예:
[1, 2].first() // optional(1)
(v0.23.0) (v0.15.0) (v0.11.0) (v0.1.2)
last 마지막 요소를 선택사항으로 반환합니다. 선택적 확장 프로그램이 필요합니다.

서명:
list.last() -> optional

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

사용 설정 방법

세트 보관함

함수 설명 Go C++ 자바 Python C
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)

사용 설정 방법

  • 이동: ext.Sets()cel.NewEnv()에 전달합니다.
  • C++:
  • Java: CelCompilerCelRuntime 빌더에 CelExtensions.sets()를 추가합니다.
  • Python: extensions 목록에 sets를 추가하여 cel.EnvConfig를 통해 사용 설정합니다.

문자열 라이브러리

함수 설명 Go C++ 자바 Python C
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("-") // "a-b"
(v0.10.0) (v0.10.0) (v0.2.0) (v0.1.1)
split 구분자로 문자열을 분할합니다.

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

예:
"a-b".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 유니코드 공백을 자릅니다.

서명:
string.trim() -> string

예:
" hello ".trim() // "hello"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
replace old를 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 유니코드 코드 포인트를 반전합니다.

서명:
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 C++ 자바 Python C
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)

사용 설정 방법

2변수 컴프리헨션

Macro 설명 Go C++ 자바 Python C
all 키/색인 및 값에 대한 논리적 AND를 단락 회로로 연결합니다.

서명:
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 키/색인 및 값에 대한 논리적 OR을 단락합니다.

서명:
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)

사용 설정 방법

네이티브 유형 라이브러리

기능 설명 Go C++ 자바 Python C
네이티브 구조체 CEL에서 호스트 네이티브 유형 (Go 구조체 / Java POJO)을 등록하고 인스턴스화합니다.

예:
Account{id: 123} (CEL에서 인스턴스화된 Java POJO)
(v0.13.0) (v0.13.0)

사용 설정 방법

  • Go: cel.NewEnv()ext.NativeTypes(...) (리플렉션 유형 제공)을 전달합니다.
  • C++: 지원되지 않습니다.
  • Java: Java 클래스를 제공하는 CelExtensions.nativeTypes()CelCompilerCelRuntime 빌더에 추가합니다.
  • Python: 지원되지 않습니다.

네트워크 라이브러리

네트워크 라이브러리는 IP 주소와 CIDR 블록을 파싱, 검증, 조작하는 기능을 제공합니다.

함수 설명 Go C++ 자바 Python C
ip 문자열을 IP 주소로 파싱하거나 CIDR에서 IP를 추출합니다.

서명:
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 패밀리 (IPv4의 경우 4, IPv6의 경우 6)를 반환합니다.

서명:
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가 루프백 주소인지 확인합니다.

서명:
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)

사용 설정 방법

  • 이동: ext.Network()cel.NewEnv()에 전달합니다.
  • C++: 지원되지 않습니다.
  • Java: 지원되지 않습니다.
  • Python: 지원되지 않습니다.

5. 고급 기능

고급 기능 요약

기능 설명 Go C++ 자바 Python C
부분 평가 입력이 누락된 상태로 평가합니다. 알 수 없는 값이나 단순화된 표현식을 반환합니다. ³
비동기 평가 확장 프로그램 함수의 비차단 동시 실행
AST 검사기 정적 분석은 유형 검사 후 검사된 AST에서 실행됩니다.
AST 옵티마이저 성능을 개선하기 위해 AST 재작성 (상수 폴딩, 인라이닝, CSE)
CEL 정책 컴파일러 YAML 기반 정책 구조를 표준 CEL AST로 컴파일합니다.

³ Go는 잔여 AST (잘린 AST) 생성을 지원합니다. ⁴ C++ 및 Java는 런타임에 UnknownSet / CelUnknownSet 반환을 지원하지만 잔여 AST 생성을 위한 공개 API를 노출하지는 않습니다. ⁵ Go는 AsyncBinding / AsyncOp를 사용하여 채널을 반환합니다. ⁶ Java는 CelAsyncRuntime를 사용하여 ListenableFuture를 반환합니다.

부분 평가 (알 수 없음)

부분 평가는 입력 변수 (인수)의 하위 집합만 알려진 경우 표현식을 평가할 수 있습니다. 실패하는 대신 평가에서 누락된 항목이나 단순화된 표현식을 나타내는 결과가 생성됩니다.

  • Go: 완전 지원 알 수 없는 속성의 패턴으로 PartialActivation를 정의할 수 있습니다. 평가에서 types.Unknown 값을 반환합니다. Go는 평가할 수 없는 표현식 부분만 포함하는 가지치기되고 간소화된 AST인 잔여 AST (Env.ResidualAst) 생성을 지원합니다.
  • C++: Unknown 값을 지원합니다. 알 수 없는 속성 패턴은 Activation::set_unknown_attribute_patterns을 통해 구성됩니다. 평가에서는 UnknownSet을 반환합니다. 공개 API는 현재 잔여 AST 생성을 노출하지 않습니다.
  • Java: Program.eval()에 전달된 PartialVars를 통해 부분 평가를 지원합니다. 평가에서 CelUnknownSet를 반환합니다. 공개 API는 현재 잔여 AST 생성을 노출하지 않습니다.
  • Python / C: 기본 지원 없음

비동기 평가

비동기 평가를 사용하면 CEL 표현식이 비동기적으로 실행되는 함수 (예: RPC 또는 데이터베이스 쿼리 실행)를 호출하고 결과가 제공될 때까지 평가를 차단하여 기본 실행 스레드를 차단하지 않을 수 있습니다.

  • Go: AsyncBindingAsyncOp를 통해 비동기 함수 오버로드를 지원합니다. 비동기 함수는 Go 채널 (<-chan ref.Val)을 반환하며 인터프리터는 동시 실행과 동기화를 관리합니다.
  • Java: CelAsyncRuntimeAsyncProgram을 통한 비동기 평가를 지원합니다. ListenableFuture를 사용하여 대기 중인 값을 나타내고, 미래가 해결되면 평가가 완료되도록 자동으로 유도합니다.
  • C++ / Python / C: 기본 지원이 없습니다.

AST 검사기

유효성 검사기는 프로그램이 실행되기 전에 도메인별 제약 조건을 적용하기 위해 유형 검사 후 확인된 AST에 정적 분석을 실행합니다.

  • Go: ASTValidator 인터페이스를 지원합니다. 표준 유효성 검사기에는 cel.validator.duration, cel.validator.timestamp, cel.validator.matches(정규식), cel.validator.homogeneous_literals, cel.validator.comprehension_nesting_limit이 포함됩니다.
  • C++: cel::Validator를 지원합니다. 표준 검증에는 AstDepthValidator, ComprehensionNestingLimitValidator, DurationLiteralValidator, HomogeneousLiteralValidator, MatchesValidator, TimestampLiteralValidator이 포함됩니다.
  • Java: CelValidatorCelAstValidator을 지원합니다. 표준 검사기에는 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 정책은 변수, 일치 블록, 조건부 출력, 중첩된 규칙과 함께 여러 CEL 표현식을 구성하기 위한 YAML 기반 형식입니다. 단일 CEL 표현식이 읽을 수 없게 되는 복잡한 정책 엔진 (예: Kubernetes 승인 제어)을 위해 설계되었습니다.

정책 컴파일러는 이러한 YAML 정책을 단일 표준 CEL AST로 컴파일합니다. 즉, 표준 CEL 런타임과 완전히 호환되며 모든 성능 및 안전 보장을 상속합니다.

  • Go: third_party/cel/go/policy를 통해 지원됩니다.
  • C++: third_party/cel/cpp/policy를 통해 지원됩니다.
  • Java: third_party/java/cel/policy를 통해 지원됩니다.
  • Python / C: 직접 지원되지 않습니다.