המסמך הזה משמש כהפניה מאוחדת לתיעוד של Common Expression Language (CEL). היא כוללת רשימה של כל פקודות המאקרו, האופרטורים והפונקציות הרגילות, עם פירוט של החתימות, ההתנהגויות וסטטוס התמיכה שלהם בכל מחסניות CEL הרשמיות.
פרטים נוספים על התנהגות השפה והמפרטים זמינים בהגדרת השפה של CEL.
גרסאות של Stack
מסמך העיון הזה מבוסס על הגרסאות הבאות של חבילות 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. Core Macros
אלה פקודות מאקרו מובנות שמתרחבות בזמן ההידור.
| Macro | תיאור | Go | C++ | Java | 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) |
הפונקציה בודקת אם רכיב אחד בדיוק ברשימה עומד בתנאי. חתימות: 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++ | Java | Python | C |
|---|---|---|---|---|---|---|
חשבוני (+, -, *, /, %) |
פעולות חשבוניות רגילות. שלילה (-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 |
✓ | ✓ | ✓ | ✓ | ✓ |
לוגי (!, &&, ||, ? :) |
NOT, AND, OR לוגיים ותנאי טרנרי. אפשר גם להשתמש בהערכה של מעגל קצר. חתימות: !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. פונקציות ליבה
פונקציות כלליות ופונקציות של מחרוזות
| פונקציה | תיאור | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
size |
הפונקציה מחזירה את הגודל של מחרוזת (תווים), בייטים, רשימה או מפה. חתימות: size(T) -> int (כאשר T הוא string, 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++ | Java | 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]) -> 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 |
✓ | ✓ | ✓ | ✓ | ✗ |
המרות של סוגים
| סוג המיקוד | תיאור | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
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)<br /><br />**Examples:**<br />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. תוספים (ספריות)
ספריית כריכות
| פונקציה | תיאור | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
cel.bind |
הפונקציה מקשרת משתנה מקומי כדי למנוע הערכה כפולה. חתימות: cel.bind(varName, initExpr, resultExpr) -> Tדוגמאות: cel.bind(x, a + b, x * x) |
✓ (גרסה 0.15.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
איך מפעילים את התכונה
- הולכים: מעבירים את
ext.Bindings()אלcel.NewEnv(). - C++: מוסיפים את
BindingsCompilerLibrary()אלCompilerBuilder. (זמן הריצה מטופל באופן אוטומטי). - Java: מוסיפים את
CelExtensions.bindings()ל-CelCompilerול-CelRuntimebuilders. - Python: מייבאים את
cel_expr_python.ext.ext_bindingsומשתמשים ב-ExtBindings()ב-cel.NewEnv(extensions=[...]).
ספריית מקודדים
| פונקציה | תיאור | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
base64.encode |
מקודד בייטים למחרוזת base64. חתימות: base64.encode(bytes) -> stringדוגמאות: base64.encode(b"hello") // "aGVsbG8=" |
✓ (גרסה 0.6.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
base64.decode |
מפענח מחרוזת base64 לבייטים. הפונקציה מחזירה שגיאה אם הקלט לא תקין. חתימות: base64.decode(string) -> bytesדוגמאות: base64.decode("aGVsbG8=") // b"hello" |
✓ (גרסה 0.6.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
json.encode |
הפונקציה יוצרת סריאליזציה של ערך CEL למחרוזת JSON. חתימות: json.encode(dyn) -> stringדוגמאות: json.encode([1, 2]) // "[1,2]" |
✓ (גרסה v0.29.0) | ✗ | ✗ | ✗ | ✗ |
איך מפעילים את התכונה
- הולכים: מעבירים את
ext.Encoders()אלcel.NewEnv(). - C++:
- קומפיילר: הוספה של
EncodersCompilerLibrary()אלCompilerBuilder. - זמן ריצה: התקשרות אל
RegisterEncodersFunctions()בכתובתFunctionRegistry.
- קומפיילר: הוספה של
- Java: מוסיפים את
CelExtensions.encoders()ל-CelCompilerול-CelRuntimebuilders. - Python: מייבאים את
cel_expr_python.ext.ext_encodersומשתמשים ב-ExtEncoders()ב-cel.NewEnv(extensions=[...]).
ספריית מתמטיקה
| פונקציה | תיאור | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
math.greatest |
הפונקציה מחזירה את המספר הגדול ביותר מבין הארגומנטים המספריים (או רשימה של מספרים). חתימות: math.greatest(arg, ...) -> Tדוגמאות: math.greatest(1, 3, 2) // 3 |
✓ (גרסה 0.13.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
math.least |
הפונקציה מחזירה את המספר הקטן ביותר מבין הארגומנטים המספריים (או רשימה של מספרים). חתימות: math.least(arg, ...) -> Tדוגמאות: math.least([1, 3, 2]) // 1 |
✓ (גרסה 0.13.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
math.abs |
ערך מוחלט. חתימות: math.abs(T) -> T (תומך ב-int, uint, double)<br /><br />**Examples:**<br />math.abs(-1) // 1` |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
math.sqrt |
שורש ריבועי. חתימות: math.sqrt(T) -> double (תמיכה ב-int, uint, double)<br /><br />**Examples:**<br />math.sqrt(9) // 3.0` |
✓ (גרסה 0.25.1) | ✓ (גרסה 0.12.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.1.1) | ✗ |
math.bitAnd |
ערך AND ברמת הביטים. חתימות: math.bitAnd(T, T) -> T (יש תמיכה ב-int, ב-uint)<br /><br />**Examples:**<br />math.bitAnd(5, 3) // 1` |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
math.bitOr |
ערך OR ברמת הסיביות. חתימות: math.bitOr(T, T) -> T (תומך ב-int, uint)<br /><br />**Examples:**<br />math.bitOr(5, 3) // 7` |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
math.bitXor |
ערך XOR ברמת הביטים. חתימות: math.bitXor(T, T) -> T (תומך ב-int, uint)<br /><br />**Examples:**<br />math.bitXor(5, 3) // 6` |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
math.bitNot |
היפוך ביטים. חתימות: math.bitNot(T) -> T (תמיכה ב-int, uint)<br /><br />**Examples:**<br />math.bitNot(1) // -2` |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
math.bitShiftLeft |
הזזה שמאלה ברמת הביטים. חתימות: math.bitShiftLeft(T, int) -> T (תומך ב-int, uint)<br /><br />**Examples:**<br />math.bitShiftLeft(1, 2) // 4` |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
math.bitShiftRight |
הזזה ימינה ברמת הביטים. חתימות: math.bitShiftRight(T, int) -> T (תומך ב-int, uint)<br /><br />**Examples:**<br />math.bitShiftRight(4, 2) // 1` |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
math.ceil |
עיגול כלפי מעלה. חתימות: math.ceil(double) -> doubleדוגמאות: math.ceil(1.2) // 2.0 |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
math.floor |
עיגול כלפי מטה. חתימות: math.floor(double) -> doubleדוגמאות: math.floor(1.8) // 1.0 |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
math.round |
עיגול למספר השלם הקרוב ביותר. חתימות: math.round(double) -> doubleדוגמאות: math.round(1.5) // 2.0 |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
math.trunc |
עיגול בחיתוך (לכיוון אפס). חתימות: math.trunc(double) -> doubleדוגמאות: math.trunc(-1.8) // -1.0 |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
math.isInf |
הפונקציה בודקת אם הערך מסוג double הוא אינסוף חיובי או שלילי. חתימות: math.isInf(double) -> boolדוגמאות: math.isInf(1.0/0.0) // true |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
math.isNaN |
בודקת אם הערך מסוג double הוא NaN. חתימות: math.isNaN(double) -> boolדוגמאות: math.isNaN(0.0/0.0) // true |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
math.isFinite |
בודקת אם המספר מסוג double הוא סופי. חתימות: math.isFinite(double) -> boolדוגמאות: math.isFinite(1.2) // true |
✓ (גרסה v0.21.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.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) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
איך מפעילים את התכונה
- הולכים: מעבירים את
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=[...]).
ספריית פרוטוקולים
| פונקציה | תיאור | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
proto.getExt |
מחזירה שדה הרחבה של proto2, או ערך ברירת מחדל אם לא הוגדר ערך. חתימות: proto.getExt(msg, extName) -> Tדוגמאות: proto.getExt(msg, google.api.expr.test.int32_ext) |
✓ (גרסה 0.13.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
proto.hasExt |
בודקת אם שדה ההרחבה proto2 מוגדר. חתימות: proto.hasExt(msg, extName) -> boolדוגמאות: proto.hasExt(msg, google.api.expr.test.int32_ext) |
✓ (גרסה 0.13.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
איך מפעילים את התכונה
- הולכים: מעבירים את
ext.Protos()אלcel.NewEnv(). - C++: מוסיפים את
ProtoExtCompilerLibrary()אלCompilerBuilder. (זמן הריצה מטופל באופן אוטומטי). - Java: מוסיפים את
CelExtensions.protos()אלCelCompilerואל בוניCelRuntime. - Python: מייבאים את
cel_expr_python.ext.ext_protoומשתמשים ב-ExtProto()ב-cel.NewEnv(extensions=[...]).
ספריית הרשימות
| פונקציה | תיאור | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
distinct |
מחזירה רכיבים ייחודיים. חתימות: list.distinct() -> listדוגמאות: [1, 2, 2].distinct() // [1, 2] |
✓ (גרסה 0.22.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.1.1) | ✗ |
flatten |
הפונקציה משטחת רשימות מקוננות. חתימות: list.flatten([depth]) -> listדוגמאות: [[1], [2, 3]].flatten() // [1, 2, 3] |
✓ (גרסה 0.22.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.7.1) | ✓ (גרסה 0.1.1) | ✗ |
lists.range |
הפונקציה מחזירה רשימה של מספרים שלמים [0, ..., n-1].חתימות: lists.range(int) -> list(int)דוגמאות: lists.range(3) // [0, 1, 2] |
✓ (גרסה 0.22.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
reverse |
הופך את סדר הרשימה. חתימות: list.reverse() -> listדוגמאות: [1, 2].reverse() // [2, 1] |
✓ (גרסה 0.22.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.1.1) | ✗ |
slice |
מחזירה רשימת משנה (ההתחלה כוללת, הסוף לא כולל). חתימות: list.slice(start, end) -> listדוגמאות: [1, 2, 3].slice(1, 3) // [2, 3] |
✓ (v0.17.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.1.1) | ✗ |
sort |
ממיינת רשימה של רכיבים להשוואה. חתימות: list.sort() -> listדוגמאות: [3, 1, 2].sort() // [1, 2, 3] |
✓ (גרסה 0.22.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.1.1) | ✗ |
sortBy |
ממיין את הרשימה לפי מפתח שמוערך מתוך הביטוי. חתימות: list.sortBy(var, expr) -> listדוגמאות: [{"val": 2}, {"val": 1}].sortBy(x, x.val) // [{"val": 1}, {"val": 2}] |
✓ (גרסה 0.22.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.1.1) | ✗ |
first |
הפונקציה מחזירה את הרכיב הראשון כאופציונלי. נדרש התוסף Optional. חתימות: list.first() -> optionalדוגמאות: [1, 2].first() // optional(1) |
✓ (גרסה 0.23.0) | ✓ (גרסה 0.15.0) | ✓ (גרסה 0.11.0) | ✓ (v0.1.2) | ✗ |
last |
מחזירה את הרכיב האחרון כאופציונלי. נדרש התוסף Optional. חתימות: list.last() -> optionalדוגמאות: [1, 2].last() // optional(2) |
✓ (גרסה 0.23.0) | ✓ (גרסה 0.15.0) | ✓ (גרסה 0.11.0) | ✓ (v0.1.2) | ✗ |
איך מפעילים את התכונה
- הולכים: מעבירים את
ext.Lists()אלcel.NewEnv(). - C++:
- קומפיילר: הוספה של
ListsCompilerLibrary()אלCompilerBuilder. - זמן ריצה: שיחה אל
RegisterListsFunctions()בFunctionRegistryואלRegisterListsMacros()בMacroRegistry.
- קומפיילר: הוספה של
- Java: מוסיפים את
CelExtensions.lists()אלCelCompilerואל בוניCelRuntime. - Python: מפעילים דרך
cel.EnvConfigעל ידי הוספתlistsלרשימהextensions.
ספריית סטים
| פונקציה | תיאור | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
sets.contains |
הפונקציה בודקת אם list1 מכילה את כל הרכיבים של list2. חתימות: sets.contains(list1, list2) -> boolדוגמאות: sets.contains([1, 2], [1]) // true |
✓ (גרסה 0.15.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.6.0) | ✓ (גרסה 0.1.1) | ✗ |
sets.equivalent |
הפונקציה בודקת אם הרשימות שוות (מכילות את אותם רכיבים ייחודיים). חתימות: sets.equivalent(list1, list2) -> boolדוגמאות: sets.equivalent([1, 2], [2, 1, 1]) // true |
✓ (גרסה 0.15.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.6.0) | ✓ (גרסה 0.1.1) | ✗ |
sets.intersects |
הפונקציה בודקת אם יש לפחות רכיב אחד משותף ברשימות. חתימות: sets.intersects(list1, list2) -> boolדוגמאות: sets.intersects([1, 2], [2, 3]) // true |
✓ (גרסה 0.15.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.6.0) | ✓ (גרסה 0.1.1) | ✗ |
איך מפעילים את התכונה
- הולכים: מעבירים את
ext.Sets()אלcel.NewEnv(). - C++:
- קומפיילר: הוספה של
SetsCompilerLibrary()אלCompilerBuilder. - זמן ריצה: התקשרות אל
RegisterSetsFunctions()בכתובתFunctionRegistry.
- קומפיילר: הוספה של
- Java: מוסיפים את
CelExtensions.sets()אלCelCompilerואל בוניCelRuntime. - Python: מפעילים דרך
cel.EnvConfigעל ידי הוספתsetsלרשימהextensions.
ספריית מחרוזות
| פונקציה | תיאור | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
charAt |
הפונקציה מחזירה את התו באינדקס. חתימות: string.charAt(int) -> stringדוגמאות: "hello".charAt(1) // "e" |
✓ (גרסה 0.4.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
indexOf |
הפונקציה מחזירה את האינדקס של המופע הראשון של מחרוזת משנה, או את הערך -1. חתימות: string.indexOf(substr, [start]) -> intדוגמאות: "hello".indexOf("l") // 2 |
✓ (גרסה 0.4.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
lastIndexOf |
הפונקציה מחזירה את האינדקס של המופע האחרון של מחרוזת משנה, או את הערך -1. חתימות: string.lastIndexOf(substr, [end]) -> intדוגמאות: "hello".lastIndexOf("l") // 3 |
✓ (גרסה 0.4.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
join |
משרשרת מחרוזות. חתימות: list(string).join([separator]) -> stringדוגמאות: ["a", "b"].join("-") // "a-b" |
✓ (גרסה 0.10.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
split |
מפצלת מחרוזת לפי מפריד. חתימות: string.split(separator, [limit]) -> list(string)דוגמאות: "a-b".split("-") // ["a", "b"] |
✓ (גרסה 0.4.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
substring |
מחזירה מחרוזת משנה (ההתחלה כוללת, הסוף לא כולל). חתימות: string.substring(start, [end]) -> stringדוגמאות: "hello".substring(1, 3) // "el" |
✓ (גרסה 0.4.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
trim |
חיתוך רווחים לבנים ב-Unicode. חתימות: string.trim() -> stringדוגמאות: " hello ".trim() // "hello" |
✓ (גרסה 0.4.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
replace |
מחליפה את המופעים של old ב-new. חתימות: string.replace(old, new, [limit]) -> stringדוגמאות: "hello".replace("l", "w") // "hewwo" |
✓ (גרסה 0.4.0) | ✓ (גרסה 0.10.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
reverse |
הפונקציה הופכת את מיקומי התווים (code points) של Unicode. חתימות: string.reverse() -> stringדוגמאות: "abc".reverse() // "cba" |
✓ (גרסה 0.18.0) | ✓ (גרסה 0.14.0) | ✓ (גרסה 0.13.0) | ✓ (גרסה 0.1.1) | ✗ |
lowerAscii |
הפונקציה ממירה תווים מסוג ASCII לאותיות קטנות. חתימות: string.lowerAscii() -> stringדוגמאות: "Hello".lowerAscii() // "hello" |
✓ (גרסה 0.6.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
upperAscii |
הפונקציה ממירה תווים מסוג ASCII לאותיות רישיות. חתימות: string.upperAscii() -> stringדוגמאות: "Hello".upperAscii() // "HELLO" |
✓ (גרסה 0.6.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.2.0) | ✓ (גרסה 0.1.1) | ✗ |
quote |
הפונקציה מסירה תווים מיוחדים ממחרוזת כדי לאפשר הדפסה בטוחה. חתימות: strings.quote(string) -> stringדוגמאות: strings.quote("a\tb") // "\"a\\tb\"" |
✓ (v0.14.0) | ✓ (v0.14.0) | ✓ (גרסה 0.13.0) | ✓ (גרסה 0.1.1) | ✗ |
איך מפעילים את התכונה
- הולכים: מעבירים את
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=[...]).
ספריית ביטויים רגולריים
| פונקציה | תיאור | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
regex.replace |
הפונקציה מחליפה התאמות במחרוזת החלפה (תומכת בהפניות חוזרות). חתימות: regex.replace(target, pat, repl, [limit]) -> stringדוגמאות: regex.replace("123-456", r"(\d+)-(\d+)", r"\2-\1") // "456-123" |
✓ (גרסה 0.25.1) | ✓ (גרסה 0.13.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
regex.extract |
הפונקציה מחזירה את ההתאמה הראשונה של התבנית (חייבת להיות קבוצה אחת לחילוץ). חתימות: regex.extract(target, pat) -> optional(string)דוגמאות: regex.extract("a123b", r"(\d+)") // optional("123") |
✓ (גרסה 0.25.1) | ✓ (גרסה 0.13.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
regex.extractAll |
הפונקציה מחזירה את כל ההתאמות של התבנית (חייבת להיות קבוצה אחת לחילוץ). חתימות: regex.extractAll(target, pat) -> list(string)דוגמאות: regex.extractAll("a1b2", r"(\d+)") // ["1", "2"] |
✓ (גרסה 0.25.1) | ✓ (גרסה 0.13.0) | ✓ (גרסה 0.10.1) | ✓ (גרסה 0.1.1) | ✗ |
איך מפעילים את התכונה
- הולכים: מעבירים את
ext.Regex()אלcel.NewEnv(). - C++:
- קומפיילר: הוספה של
RegexExtCompilerLibrary()אלCompilerBuilder. - זמן ריצה: התקשר אל
RegisterRegexExtensionFunctions()בFunctionRegistry.
- קומפיילר: הוספה של
- Java: מוסיפים את
CelExtensions.regex()אלCelCompilerואל בוניCelRuntime. - Python: כדי להפעיל את התוסף דרך
cel.EnvConfig, מוסיפים אתregexואתoptionalלרשימהextensions.
הבנות של שני משתנים
| Macro | תיאור | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
all |
קיצור דרך לוגי של AND על מפתח/אינדקס וערך. חתימות: list.all(i, v, pred) -> boolmap.all(k, v, pred) -> boolדוגמאות: [1, 2].all(i, v, v > 0) // true |
✓ (גרסה 0.22.0) | ✓ (v0.14.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.1.1) | ✗ |
exists |
קיצור דרך לוגי של OR על מפתח/אינדקס וערך. חתימות: list.exists(i, v, pred) -> boolmap.exists(k, v, pred) -> boolדוגמאות: [1, 2].exists(i, v, v == 2) // true |
✓ (גרסה 0.22.0) | ✓ (v0.14.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.1.1) | ✗ |
existsOne |
הפונקציה בודקת אם יש בדיוק זוג אחד שמקיים את התנאי. חתימות: list.existsOne(i, v, pred) -> boolmap.existsOne(k, v, pred) -> boolדוגמאות: [1, 2].existsOne(i, v, v == 2) // true |
✓ (גרסה 0.22.0) | ✓ (v0.14.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.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] |
✓ (גרסה 0.22.0) | ✓ (v0.14.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.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} |
✓ (גרסה 0.22.0) | ✓ (v0.14.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.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} |
✓ (גרסה 0.22.0) | ✓ (v0.14.0) | ✓ (גרסה 0.11.0) | ✓ (גרסה 0.1.1) | ✗ |
איך מפעילים את התכונה
- הולכים: מעבירים את
ext.TwoVarComprehensions()אלcel.NewEnv(). - C++:
- קומפיילר: הוספה של
ComprehensionsV2CompilerLibrary()אלCompilerBuilder. - זמן ריצה: שיחה אל
RegisterComprehensionsV2Functions()בFunctionRegistryואלRegisterComprehensionsV2Macros()בMacroRegistry.
- קומפיילר: הוספה של
- Java: מוסיפים את
CelExtensions.comprehensions()ל-CelCompilerול-CelRuntimebuilders. - Python: כדי להפעיל את התכונה דרך
cel.EnvConfig, מוסיפים אתtwo-var-comprehensionsלרשימהextensions.
ספריית סוגים מקוריים
| תכונה | תיאור | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
| מבני נתונים מקוריים | רישום והפעלת סוגי נייטיב של מארח (מבני Go / אובייקטים פשוטים של Java) ב-CEL. דוגמאות: Account{id: 123} (אובייקט פשוט של Java שהופעל ב-CEL) |
✓ (גרסה 0.13.0) | ✗ | ✓ (גרסה 0.13.0) | ✗ | ✗ |
איך מפעילים את התכונה
- הוראה: מעבירים את
ext.NativeTypes(...)(עם סוגי ההשתקפות) אלcel.NewEnv(). - C++: אין תמיכה.
- Java: מוסיפים
CelExtensions.nativeTypes()(שמספק מחלקות Java) ל-buildersCelCompilerו-CelRuntime. - Python: לא אפשרי.
ספריית רשת
ספריית הרשת מספקת פונקציות לניתוח, לאימות ולשינוי של כתובות IP ובלוקים של CIDR.
| פונקציה | תיאור | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
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 היא כתובת unicast גלובלית. חתימות: 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 היא כתובת unicast מקומית לקישור. חתימות: 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) -> stringstring(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++ | Java | Python | C |
|---|---|---|---|---|---|---|
| Partial Evaluation | הערכה עם קלט חסר; מחזירה ערכים לא ידועים או ביטוי פשוט. | ✓³ | ✓⁴ | ✓⁴ | ✗ | ✗ |
| Async Evaluation | ביצוע מקביל של פונקציות של תוספים שלא חוסם את הפעולה. | ✓⁵ | ✗ | ✓⁶ | ✗ | ✗ |
| כלי אימות של AST | בדיקות ניתוח סטטי מתבצעות ב-Checked AST אחרי בדיקת הסוג. | ✓ | ✓ | ✓ | ✗ | ✗ |
| AST Optimizers | שכתוב של AST (קיפול קבוע, הטמעה, CSE) כדי לשפר את הביצועים. | ✓ | ✓ | ✓ | ✗ | ✗ |
| מהדר המדיניות של CEL | הכלי הזה מרכיב מבני מדיניות מבוססי YAML ל-ASTs סטנדרטיים של CEL. | ✓ | ✓ | ✓ | ✗ | ✗ |
³ Go תומכת ביצירת Residual 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. הפונקציה Evaluation מחזירה את הערך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כדי לייצג ערכים בהמתנה, ומבצע הערכה עד לסיום באופן אוטומטי כשהערכים העתידיים נפתרים. - 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: תומך ב-
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 היא פורמט מבוסס-YAML ליצירת מספר ביטויי CEL יחד עם משתנים, בלוקים של התאמות, פלט מותנה וכללים מקוננים. היא מיועדת למנועי מדיניות מורכבים (כמו Kubernetes Admission Control) שבהם ביטויים יחידים של CEL יהפכו לבלתי קריאים.
הקומפיילר של המדיניות מקמפל את מדיניות ה-YAML הזו ל-AST CEL רגיל יחיד, כלומר היא תואמת באופן מלא לזמני ריצה רגילים של CEL ומקבלת בירושה את כל הביצועים והבטיחות.
- כניסה: נתמך דרך
third_party/cel/go/policy. - C++: נתמך באמצעות
third_party/cel/cpp/policy. - Java: נתמך באמצעות
third_party/java/cel/policy. - Python / C: אין תמיכה ישירה.