कॉमन एक्सप्रेशन लैंग्वेज (सीईएल) एपीआई का रेफ़रंस

यह दस्तावेज़, कॉमन एक्सप्रेशन लैंग्वेज (सीईएल) के लिए, एक ही एपीआई दस्तावेज़ के रेफ़रंस के तौर पर काम करता है. इसमें सभी मैक्रो, ऑपरेटर, और स्टैंडर्ड फ़ंक्शन की सूची दी गई है. साथ ही, इसमें उनके सिग्नेचर, व्यवहार, और 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 Mirrors

CEL के आधिकारिक तौर पर लागू किए गए वर्शन, GitHub पर cel-expr संगठन के तहत उपलब्ध हैं:


1. कोर मैक्रो

ये बिल्ट-इन मैक्रो हैं, जिन्हें कंपाइल करने के समय बढ़ाया जाता है.

मैक्रो ब्यौरा ऐप पर जाएं 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. कोर ऑपरेटर

ऑपरेटर ब्यौरा ऐप पर जाएं C++ Java 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, और टर्नरी कंडीशनल. इसके अलावा, शॉर्ट-सर्किट इवैलुएशन का इस्तेमाल करें.

सिग्नेचर:
!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

² C रनटाइम में, सूची को एक साथ जोड़ने (list + list) की सुविधा काम नहीं करती. हालांकि, अन्य अंकगणितीय ऑपरेटर काम करते हैं.


3. मुख्य फ़ंक्शन

सामान्य और स्ट्रिंग फ़ंक्शन

फ़ंक्शन ब्यौरा ऐप पर जाएं 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 से कॉम्पोनेंट निकालते हैं.

फ़ंक्शन ब्यौरा ऐप पर जाएं C++ Java Python C
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 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 (शून्य पर राउंड करता है)
int(string) -> int
int(timestamp) -> int (epoch के बाद के सेकंड)

उदाहरण:
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. एक्सटेंशन (लाइब्रेरी)

Bindings Library

फ़ंक्शन ब्यौरा ऐप पर जाएं C++ Java 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)

चालू करने का तरीका

  • जाओ: ext.Bindings() को cel.NewEnv() पर पास करो.
  • C++: CompilerBuilder में BindingsCompilerLibrary() जोड़ें. (रनटाइम अपने-आप मैनेज होता है).
  • Java: CelCompiler और CelRuntime बिल्डर में CelExtensions.bindings() जोड़ें.
  • Python: cel_expr_python.ext.ext_bindings को इंपोर्ट करें और cel.NewEnv(extensions=[...]) में ExtBindings() का इस्तेमाल करें.

Encoders Library

फ़ंक्शन ब्यौरा ऐप पर जाएं C++ Java 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)

चालू करने का तरीका

  • जाओ: ext.Encoders() को cel.NewEnv() पर पास करो.
  • C++:
  • Java: CelCompiler और CelRuntime बिल्डर में CelExtensions.encoders() जोड़ें.
  • Python: cel_expr_python.ext.ext_encoders को इंपोर्ट करें और cel.NewEnv(extensions=[...]) में ExtEncoders() का इस्तेमाल करें.

गणित लाइब्रेरी

फ़ंक्शन ब्यौरा ऐप पर जाएं C++ Java 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 शून्य की ओर पूर्णांक बनाने की सुविधा.

हस्ताक्षर:
math.trunc(double) -> double

उदाहरण:
math.trunc(-1.8) // -1.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.isInf यह फ़ंक्शन जांच करता है कि डबल पॉज़िटिव या नेगेटिव इनफ़िनिटी है या नहीं.

सिग्नेचर:
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 यह जांच करता है कि डबल फ़ाइनिट है या नहीं.

सिग्नेचर:
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)

चालू करने का तरीका

  • जाओ: ext.Math() को cel.NewEnv() पर पास करो.
  • C++:
  • Java: CelCompiler और CelRuntime बिल्डर में CelExtensions.math() जोड़ें.
  • Python: cel_expr_python.ext.ext_math को इंपोर्ट करें और cel.NewEnv(extensions=[...]) में ExtMath() का इस्तेमाल करें.

Protos Library

फ़ंक्शन ब्यौरा ऐप पर जाएं C++ Java 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++: CompilerBuilder में ProtoExtCompilerLibrary() जोड़ें. (रनटाइम अपने-आप मैनेज होता है).
  • Java: CelCompiler और CelRuntime बिल्डर में CelExtensions.protos() जोड़ें.
  • Python: cel_expr_python.ext.ext_proto को इंपोर्ट करें और cel.NewEnv(extensions=[...]) में ExtProto() का इस्तेमाल करें.

सूचियों की लाइब्रेरी

फ़ंक्शन ब्यौरा ऐप पर जाएं C++ Java 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 पहले एलिमेंट को 'ज़रूरी नहीं है' के तौर पर दिखाता है. इसके लिए, 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)

चालू करने का तरीका

  • जाओ: ext.Lists() को cel.NewEnv() पर पास करो.
  • C++:
  • Java: CelCompiler और CelRuntime बिल्डर में CelExtensions.lists() जोड़ें.
  • Python: extensions सूची में lists जोड़कर, cel.EnvConfig के ज़रिए इसे चालू करें.

सेट की लाइब्रेरी

फ़ंक्शन ब्यौरा ऐप पर जाएं C++ Java 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: CelCompiler और CelRuntime बिल्डर में CelExtensions.sets() जोड़ें.
  • Python: extensions सूची में sets जोड़कर, cel.EnvConfig के ज़रिए इसे चालू करें.

स्ट्रिंग लाइब्रेरी

फ़ंक्शन ब्यौरा ऐप पर जाएं C++ Java 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)

चालू करने का तरीका

  • जाओ: ext.Strings() को cel.NewEnv() पर पास करो.
  • C++:
  • Java: CelCompiler और CelRuntime बिल्डर में CelExtensions.strings() जोड़ें.
  • Python: cel_expr_python.ext.ext_strings को इंपोर्ट करें और cel.NewEnv(extensions=[...]) में ExtStrings() का इस्तेमाल करें.

रेगुलर एक्सप्रेशन लाइब्रेरी

फ़ंक्शन ब्यौरा ऐप पर जाएं 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"
(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)

चालू करने का तरीका

  • जाओ: ext.Regex() को cel.NewEnv() पर पास करो.
  • C++:
  • Java: CelCompiler और CelRuntime बिल्डर में CelExtensions.regex() जोड़ें.
  • Python: cel.EnvConfig के ज़रिए इसे चालू करें. इसके लिए, extensions सूची में regex और optional जोड़ें.

दो वैरिएबल वाले कंप्रीहेंशन

मैक्रो ब्यौरा ऐप पर जाएं C++ Java 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)

चालू करने का तरीका

नेटिव टाइप लाइब्रेरी

सुविधा ब्यौरा ऐप पर जाएं C++ Java Python C
नेटिव स्ट्रक्चर CEL में होस्ट नेटिव टाइप (Go स्ट्रक्चर / Java POJO) रजिस्टर करना और इंस्टैंटिएट करना.

उदाहरण:
Account{id: 123} (CEL में इंस्टेंस किया गया Java POJO)
(v0.13.0) (v0.13.0)

चालू करने का तरीका

  • जाएं: पास ext.NativeTypes(...) (reflect टाइप उपलब्ध कराना) से cel.NewEnv() पर जाएं.
  • C++: इसका इस्तेमाल नहीं किया जा सकता.
  • Java: CelCompiler और CelRuntime बिल्डर में CelExtensions.nativeTypes() (Java क्लास उपलब्ध कराता है) जोड़ें.
  • Python: इसका इस्तेमाल नहीं किया जा सकता.

नेटवर्क लाइब्रेरी

नेटवर्क लाइब्रेरी, आईपी पतों और सीआईडीआर ब्लॉक को पार्स करने, पुष्टि करने, और उनमें बदलाव करने के लिए फ़ंक्शन उपलब्ध कराती है.

फ़ंक्शन ब्यौरा ऐप पर जाएं C++ Java Python C
ip यह फ़ंक्शन, किसी स्ट्रिंग को आईपी पते में पार्स करता है या सीआईडीआर से आईपी पता निकालता है.

हस्ताक्षर:
ip(string) -> IP
CIDR.ip() -> IP

उदाहरण:
ip("192.168.0.1")
cidr("192.168.0.0/24").ip()
(v0.29.0)
isIP यह फ़ंक्शन, यह जांच करता है कि कोई स्ट्रिंग मान्य आईपी पता है या नहीं.

सिग्नेचर:
isIP(string) -> bool

उदाहरण:
isIP("192.168.0.1") // true
(v0.29.0)
ip.isCanonical यह फ़ंक्शन, यह जांच करता है कि आईपी पते की स्ट्रिंग, कैननिकल फ़ॉर्मैट में है या नहीं.

हस्ताक्षर:
ip.isCanonical(string) -> bool

उदाहरण:
ip.isCanonical("192.168.0.1") // true
(v0.29.0)
cidr यह फ़ंक्शन, किसी स्ट्रिंग को सीआईडीआर ब्लॉक में पार्स करता है.

सिग्नेचर:
cidr(string) -> CIDR

उदाहरण:
cidr("192.168.0.0/24")
(v0.29.0)
isCIDR यह फ़ंक्शन जांच करता है कि कोई स्ट्रिंग मान्य सीआईडीआर ब्लॉक है या नहीं.

हस्ताक्षर:
isCIDR(string) -> bool

उदाहरण:
isCIDR("192.168.0.0/24") // true
(v0.29.0)
containsIP इस फ़ंक्शन से यह पता चलता है कि सीआईडीआर ब्लॉक में कोई आईपी पता शामिल है या नहीं.

सिग्नेचर:
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.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 यह फ़ंक्शन, आईपी फ़ैमिली (IPv4 के लिए 4 और IPv6 के लिए 6) दिखाता है.

सिग्नेचर:
IP.family() -> int

उदाहरण:
ip("192.168.0.1").family() // 4
(v0.29.0)
isGlobalUnicast यह फ़ंक्शन, यह जांच करता है कि आईपी पता ग्लोबल यूनिकास्ट पता है या नहीं.

हस्ताक्षर:
IP.isGlobalUnicast() -> bool

उदाहरण:
ip("192.168.0.1").isGlobalUnicast() // true
(v0.29.0)
isLinkLocalMulticast यह फ़ंक्शन जांच करता है कि आईपी पता, लिंक-लोकल मल्टीकास्ट पता है या नहीं.

सिग्नेचर:
IP.isLinkLocalMulticast() -> bool

उदाहरण:
ip("224.0.0.1").isLinkLocalMulticast() // true
(v0.29.0)
isLinkLocalUnicast यह फ़ंक्शन जांचता है कि आईपी पता, लिंक-लोकल यूनिकास्ट पता है या नहीं.

सिग्नेचर:
IP.isLinkLocalUnicast() -> bool

उदाहरण:
ip("169.254.0.1").isLinkLocalUnicast() // true
(v0.29.0)
isLoopback यह जांच करता है कि आईपी पता लूपबैक पता है या नहीं.

हस्ताक्षर:
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 यह फ़ंक्शन, यह जांच करता है कि आईपी पता, तय नहीं किया गया पता है या नहीं. उदाहरण के लिए, 0.0.0.0.

सिग्नेचर:
IP.isUnspecified() -> bool

उदाहरण:
ip("0.0.0.0").isUnspecified() // true
(v0.29.0)
masked यह फ़ंक्शन, मास्क किए गए सीआईडीआर ब्लॉक को दिखाता है.

सिग्नेचर:
CIDR.masked() -> CIDR

उदाहरण:
cidr("192.168.0.1/24").masked() // 192.168.0.0/24
(v0.29.0)
prefixLength यह फ़ंक्शन, सीआईडीआर ब्लॉक के प्रीफ़िक्स की लंबाई दिखाता है.

सिग्नेचर:
CIDR.prefixLength() -> int

उदाहरण:
cidr("192.168.0.0/24").prefixLength() // 24
(v0.29.0)
string यह फ़ंक्शन, आईपी या सीआईडीआर को स्ट्रिंग में बदलता है.

सिग्नेचर:
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. बेहतर सुविधाएं

ऐडवांस सुविधाओं के बारे में खास जानकारी

सुविधा ब्यौरा ऐप पर जाएं C++ Java Python C
आंशिक तौर पर आकलन करना इनपुट मौजूद न होने पर, यह फ़ंक्शन वैल्यू का अनुमान लगाता है. यह 'अज्ञात' वैल्यू या आसान एक्सप्रेशन दिखाता है. ³
एसिंक मूल्यांकन एक्सटेंशन फ़ंक्शन को एक साथ बिना किसी रुकावट के लागू किया जा सकता है.
एएसटी की पुष्टि करने वाले प्रोग्राम स्टैटिक विश्लेषण, टाइप-चेकिंग के बाद Checked AST की जांच करता है.
AST ऑप्टिमाइज़र परफ़ॉर्मेंस को बेहतर बनाने के लिए, एएसटी को फिर से लिखा जाता है. जैसे, कॉन्स्टेंट फ़ोल्डिंग, इनलाइनिंग, और सीएसई.
CEL Policy Compiler यह YAML पर आधारित नीति के स्ट्रक्चर को स्टैंडर्ड CEL AST में कंपाइल करता है.

³ Go, रेज़िडुअल एएसटी (प्रून किया गया एएसटी) जनरेट करने की सुविधा के साथ काम करता है. ⁴ C++ और Java के साथ काम करता है. रनटाइम के दौरान UnknownSet / CelUnknownSet दिखाता है, लेकिन बचे हुए एएसटी जनरेशन के लिए सार्वजनिक एपीआई उपलब्ध नहीं कराता. ⁵ Go, AsyncBinding / AsyncOp रिटर्निंग चैनल का इस्तेमाल करता है. ⁶ Java, CelAsyncRuntime का इस्तेमाल करता है, जो ListenableFuture दिखाता है.

आंशिक तौर पर आकलन किया गया (अज्ञात)

आंशिक आकलन की मदद से, किसी एक्सप्रेशन का आकलन तब किया जा सकता है, जब सिर्फ़ इनपुट वैरिएबल (आर्ग्युमेंट) का सबसेट पता हो. जांच में फ़ेल होने के बजाय, यह पता चलता है कि क्या मौजूद नहीं है या कोई आसान एक्सप्रेशन.

  • Go: पूरी तरह से काम करता है. इसकी मदद से, ऐसे पैटर्न के साथ PartialActivation को तय किया जा सकता है जिसमें अज्ञात एट्रिब्यूट शामिल हों. आकलन करने पर types.Unknown वैल्यू मिलती है. Go, रेज़िडुअल एएसटी (Env.ResidualAst) जनरेट करने की सुविधा देता है. यह एक छोटा और आसान एएसटी होता है. इसमें एक्सप्रेशन के सिर्फ़ वे हिस्से शामिल होते हैं जिनका आकलन नहीं किया जा सका.
  • C++: इसमें Unknown वैल्यू इस्तेमाल की जा सकती हैं. Activation::set_unknown_attribute_patterns के ज़रिए, एट्रिब्यूट के ऐसे पैटर्न कॉन्फ़िगर किए जाते हैं जिनकी जानकारी मौजूद नहीं है. Evaluation UnknownSet दिखाता है. फ़िलहाल, सार्वजनिक एपीआई, रीज़िडुअल एएसटी जनरेशन को एक्सपोज़ नहीं करता है.
  • Java: Program.eval() को पास किए गए PartialVars के ज़रिए, कुछ हद तक आकलन करने की सुविधा उपलब्ध है. इवैलुएशन से CelUnknownSet मिलता है. फ़िलहाल, सार्वजनिक एपीआई में एएसटी जनरेट करने की सुविधा उपलब्ध नहीं है.
  • Python / C: नेटिव तौर पर काम नहीं करता.

एसिंक्रोनस तरीके से आकलन करना

एसिंक तरीके से आकलन करने की सुविधा की मदद से, CEL एक्सप्रेशन ऐसे फ़ंक्शन को कॉल कर सकते हैं जो एसिंक तरीके से काम करते हैं. जैसे, आरपीसी या डेटाबेस क्वेरी करना. साथ ही, जब तक नतीजे उपलब्ध नहीं हो जाते, तब तक आकलन को ब्लॉक कर सकते हैं. हालांकि, इससे मुख्य एक्ज़ीक्यूशन थ्रेड ब्लॉक नहीं होती.

  • Go: यह AsyncBinding और AsyncOp के ज़रिए, एसिंक्रोनस फ़ंक्शन ओवरलोड का इस्तेमाल करने की सुविधा देता है. एसिंक फ़ंक्शन, Go चैनल (<-chan ref.Val) दिखाते हैं. साथ ही, इंटरप्रेटर एक साथ कई फ़ंक्शन चलाने और उन्हें सिंक करने की प्रोसेस को मैनेज करता है.
  • Java: CelAsyncRuntime और AsyncProgram के ज़रिए, एसिंक जांच की सुविधा उपलब्ध है. यह ListenableFuture का इस्तेमाल करके, प्रोसेस की जा रही वैल्यू दिखाता है. साथ ही, फ़्यूचर के पूरे होने पर, अपने-आप इवैल्यूएशन पूरा कर देता है.
  • C++ / Python / C: इसमें कोई बिल्ट-इन सपोर्ट नहीं होता.

एएसटी वैलिडेटर

टाइप-चेकिंग के बाद, वैलिडेटर, Checked 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, स्टैटिक ऑप्टिमाइज़र के साथ भी काम करते हैं. सामान्य ऑप्टिमाइज़ेशन में, कॉन्स्टेंट फ़ोल्डिंग (कॉन्स्टेंट इनपुट के साथ सब-एक्सप्रेशन का पहले से आकलन करना) और कॉमन सबएक्सप्रेशन एलिमिनेशन (सीएसई) शामिल है.

  • Go: यह कंपाइलेशन/प्लानिंग के दौरान एएसटी फ़ोल्डिंग की सुविधा देता है.
  • C++: यह प्लान के समय cel::extensions::EnableConstantFolding एक्सटेंशन के ज़रिए कॉन्स्टेंट फ़ोल्डिंग की सुविधा देता है.
  • Java: CelOptimizer इंटरफ़ेस के साथ काम करता है. कैननिकल ऑप्टिमाइज़र में ये शामिल हैं ConstantFoldingOptimizer (जो कुछ हद तक आकलन करके, शॉर्ट-सर्किट करने वाली ब्रांच को छोटा कर सकता है), InliningOptimizer, और SubexpressionOptimizer (सीएसई).
  • Python / C: सीधे तौर पर काम नहीं करता.

CEL Policy Compiler

सीईएल नीति, YAML पर आधारित फ़ॉर्मैट है. इसका इस्तेमाल, कई सीईएल एक्सप्रेशन को एक साथ कंपोज़ करने के लिए किया जाता है. इसमें वैरिएबल, मैच ब्लॉक, शर्तों के हिसाब से आउटपुट, और नेस्ट किए गए नियम शामिल होते हैं. इसे जटिल नीति इंजन (जैसे कि 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: सीधे तौर पर काम नहीं करता.