เอกสารอ้างอิง API ของ Common Expression Language (CEL)

เอกสารนี้ทำหน้าที่เป็นข้อมูลอ้างอิงเอกสาร API แบบรวมสำหรับ Common Expression Language (CEL) โดยจะแสดงรายการมาโคร โอเปอเรเตอร์ และฟังก์ชันมาตรฐานทั้งหมด พร้อมระบุลายเซ็น ลักษณะการทำงาน และสถานะการรองรับในสแต็ก CEL อย่างเป็นทางการ

ดูรายละเอียดเพิ่มเติมเกี่ยวกับลักษณะการทำงานและข้อกำหนดของภาษาได้ที่คำจำกัดความของภาษา CEL

เวอร์ชัน Stack

เอกสารอ้างอิงนี้อิงตามสแต็ก CEL เวอร์ชันต่อไปนี้

  • CEL Go: v0.32.0 (และใหม่กว่า)
  • CEL C++: v0.16.1
  • CEL Java: v0.14.0
  • CEL Python: v0.1.3
  • CEL C: ภาพรวมการพัฒนา (ยังไม่เผยแพร่)

มิเรอร์ GitHub

การใช้งาน CEL อย่างเป็นทางการจะมิเรอร์ใน GitHub ภายใต้cel-expr องค์กร


1. มาโครหลัก

มาโครเหล่านี้เป็นมาโครในตัวที่จะขยายในเวลาคอมไพล์

มาโคร คำอธิบาย 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) ทดสอบว่าองค์ประกอบอย่างน้อย 1 รายการในลิสต์เป็นไปตามเพรดิเคตหรือไม่

ลายเซ็น:
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++ 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
เชิงตรรกะ (!, &&, ||, ? :) Logical NOT, AND, OR และ Ternary Conditional และ/หรือใช้การประเมินแบบลัด

ลายเซ็น:
!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. ฟังก์ชันหลัก

ฟังก์ชันทั่วไปและฟังก์ชันสตริง

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
size แสดงขนาดของสตริง (อักขระ), ไบต์, รายการ หรือแมป

ลายเซ็น:
size(T) -> int (โดยที่ T คือ string, bytes, list หรือ map)

ตัวอย่าง:
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]) -> 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++ 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 (ปัดเป็น 0)
int(string) -> int
int(timestamp) -> int (วินาทีตั้งแต่ Epoch)

ตัวอย่าง:
int(1.5) // 1
string แปลงเป็นสตริง

ลายเซ็น:
string(T) -> string (รองรับ bool, int, uint, double, bytes, timestamp, duration)

ตัวอย่าง:
string(1.5) // "1.5"
timestamp แปลงเป็น 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++ 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++: เพิ่ม BindingsCompilerLibrary() ไปยัง CompilerBuilder (ระบบจะจัดการรันไทม์โดยอัตโนมัติ)
  • Java: เพิ่ม CelExtensions.bindings() ไปยัง CelCompiler และบิลเดอร์ CelRuntime
  • 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="
(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: เพิ่ม CelExtensions.encoders() ไปยัง CelCompiler และบิลเดอร์ CelRuntime
  • 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
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
math.least แสดงผลอาร์กิวเมนต์ที่เป็นตัวเลขที่น้อยที่สุด (หรือรายการตัวเลข)

ลายเซ็น:
math.least(arg, ...) -> T

ตัวอย่าง:
math.least([1, 3, 2]) // 1
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
math.abs ค่าสัมบูรณ์

ลายเซ็น:
math.abs(T) -> T (รองรับ int, uint, double)

ตัวอย่าง:
math.abs(-1) // 1
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.sqrt รากที่สอง

ลายเซ็น:
math.sqrt(T) -> double (รองรับ int, uint, double)

ตัวอย่าง:
math.sqrt(9) // 3.0
(v0.25.1) (v0.12.0) (v0.11.0) (v0.1.1)
math.bitAnd บิตไวส์ AND

ลายเซ็น:
math.bitAnd(T, T) -> T (รองรับ int, uint)

ตัวอย่าง:
math.bitAnd(5, 3) // 1
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitOr Bitwise OR

ลายเซ็น:
math.bitOr(T, T) -> T (รองรับ int, uint)

ตัวอย่าง:
math.bitOr(5, 3) // 7
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitXor XOR แบบบิต

ลายเซ็น:
math.bitXor(T, T) -> T (รองรับ int, uint)

ตัวอย่าง:
math.bitXor(5, 3) // 6
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitNot NOT แบบบิต

ลายเซ็น:
math.bitNot(T) -> T (รองรับ int, uint)

ตัวอย่าง:
math.bitNot(1) // -2
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitShiftLeft เลื่อนบิตไปทางซ้าย

ลายเซ็น:
math.bitShiftLeft(T, int) -> T (รองรับ int, uint)

ตัวอย่าง:
math.bitShiftLeft(1, 2) // 4
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitShiftRight เลื่อนบิตไปทางขวา

ลายเซ็น:
math.bitShiftRight(T, int) -> T (รองรับ int, uint)

ตัวอย่าง:
math.bitShiftRight(4, 2) // 1
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.ceil การปัดเศษขึ้น

รูปแบบ:
math.ceil(double) -> double

ตัวอย่าง:
math.ceil(1.2) // 2.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.floor การปัดเศษลง

ลายเซ็น:
math.floor(double) -> double

ตัวอย่าง:
math.floor(1.8) // 1.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.round การปัดเศษเป็นจำนวนเต็มที่ใกล้ที่สุด

ลายเซ็น:
math.round(double) -> double

ตัวอย่าง:
math.round(1.5) // 2.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.trunc การปัดเศษแบบตัดทิ้ง (เข้าหา 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)

ตัวอย่าง:
math.sign(-42) // -1
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)

วิธีเปิดใช้

  • ไป: ส่ง ext.Math() ไปยัง cel.NewEnv()
  • C++:
  • Java: เพิ่ม CelExtensions.math() ไปยัง CelCompiler และ CelRuntime บิลเดอร์
  • Python: นำเข้า cel_expr_python.ext.ext_math และใช้ ExtMath() ใน cel.NewEnv(extensions=[...])

คลัง Protos

ฟังก์ชัน คำอธิบาย Go 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++: เพิ่ม 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]
(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)

วิธีเปิดใช้

  • ไป: ส่ง ext.Lists() ไปยัง cel.NewEnv()
  • C++:
  • 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
(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 ตรวจสอบว่ารายการแชร์องค์ประกอบอย่างน้อย 1 รายการหรือไม่

รูปแบบ:
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: เพิ่ม CelExtensions.sets() ไปยัง CelCompiler และ CelRuntime บิลเดอร์
  • Python: เปิดใช้ผ่าน cel.EnvConfig โดยเพิ่ม sets ลงในextensions รายการ

คลังสตริง

ฟังก์ชัน คำอธิบาย Go 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 ตัดช่องว่าง Unicode

ลายเซ็น:
string.trim() -> string

ตัวอย่าง:
" hello ".trim() // "hello"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
replace แทนที่ค่าเก่าด้วยค่าใหม่

รูปแบบ:
string.replace(old, new, [limit]) -> string

ตัวอย่าง:
"hello".replace("l", "w") // "hewwo"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
reverse กลับจุดโค้ด Unicode

ลายเซ็น:
string.reverse() -> string

ตัวอย่าง:
"abc".reverse() // "cba"
(v0.18.0) (v0.14.0) (v0.13.0) (v0.1.1)
lowerAscii แปลงอักขระ ASCII เป็นตัวพิมพ์เล็ก

ลายเซ็น:
string.lowerAscii() -> string

ตัวอย่าง:
"Hello".lowerAscii() // "hello"
(v0.6.0) (v0.11.0) (v0.2.0) (v0.1.1)
upperAscii แปลงอักขระ ASCII เป็นตัวพิมพ์ใหญ่

ลายเซ็น:
string.upperAscii() -> string

ตัวอย่าง:
"Hello".upperAscii() // "HELLO"
(v0.6.0) (v0.11.0) (v0.2.0) (v0.1.1)
quote หลีกเลี่ยงสตริงเพื่อการพิมพ์ที่ปลอดภัย

ลายเซ็น:
strings.quote(string) -> string

ตัวอย่าง:
strings.quote("a\tb") // "\"a\\tb\""
(v0.14.0) (v0.14.0) (v0.13.0) (v0.1.1)
format จัดรูปแบบสตริงโดยใช้ตัวยึดตำแหน่งสไตล์ printf

ลายเซ็น:
string.format(list) -> string

ตัวอย่าง:
"str: %s, int: %d".format(["a", 1]) // "str: a, int: 1"
(v0.14.0) (v0.11.0) (v0.1.1)

วิธีเปิดใช้

  • ไป: ส่ง ext.Strings() ไปยัง cel.NewEnv()
  • C++:
  • 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"
(v0.25.1) (v0.13.0) (v0.10.1) (v0.1.1)
regex.extract แสดงการจับคู่รูปแบบแรก (ต้องมีกลุ่มจับภาพ 1 กลุ่ม)

ลายเซ็น:
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 แสดงผลการจับคู่ทั้งหมดของรูปแบบ (ต้องมีแคปเจอร์กรุ๊ปอย่างน้อย 1 กลุ่ม)

ลายเซ็น:
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: เพิ่ม CelExtensions.regex() ไปยัง CelCompiler และ CelRuntime บิลเดอร์
  • Python: เปิดใช้ผ่าน cel.EnvConfig โดยเพิ่ม regex และ optional ลงใน รายการ extensions

การทำความเข้าใจตัวแปร 2 ตัว

มาโคร คำอธิบาย Go 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)

วิธีเปิดใช้

คลังประเภทเนทีฟ

ฟีเจอร์ คำอธิบาย Go C++ Java Python C
โครงสร้างข้อมูลดั้งเดิม การลงทะเบียนและสร้างอินสแตนซ์ของประเภทดั้งเดิมของโฮสต์ (โครงสร้าง Go / POJO ของ Java) ใน CEL

ตัวอย่าง:
Account{id: 123} (สร้างอินสแตนซ์ POJO ของ Java ใน CEL)
(v0.13.0) (v0.13.0)

วิธีเปิดใช้

  • ไปที่: ส่ง cel.NativeTypes(...) หรือ ext.NativeTypes(...) (ระบุประเภทการสะท้อน) ไปยัง cel.NewEnv()
  • C++: ไม่รองรับ
  • Java: เพิ่ม CelExtensions.nativeTypes() (ระบุคลาส Java) ลงในเครื่องมือสร้าง CelCompiler และ CelRuntime
  • Python: ไม่รองรับ

คลังเครือข่าย

ไลบรารีเครือข่ายมีฟังก์ชันสำหรับการแยกวิเคราะห์ ตรวจสอบ และจัดการ ที่อยู่ IP และบล็อก CIDR

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
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 อยู่ในรูปแบบ Canonical หรือไม่

ลายเซ็น:
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 เป็นที่อยู่แบบ 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 เป็นที่อยู่ 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)

วิธีเปิดใช้

  • ไป: ส่ง ext.Network() ไปยัง cel.NewEnv()
  • C++: ไม่รองรับ
  • Java: ไม่รองรับ
  • Python: ไม่รองรับ

ไลบรารี JWT

ไลบรารี JWT มีประเภทข้อมูลและฟังก์ชันช่วยสำหรับการแยกวิเคราะห์โทเค็นเว็บ JSON (JWT) และตรวจสอบการอ้างสิทธิ์มาตรฐานและการอ้างสิทธิ์ที่กำหนดเอง

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
jwt.parse แยกวิเคราะห์สตริงโทเค็นดิบเป็น jwt.Token ที่มีโครงสร้างซึ่งอยู่ใน Optional

ลายเซ็น:
jwt.parse(string) -> optional(jwt.Token)

ตัวอย่าง:
jwt.parse(token_string).hasValue()
(v0.32.0)
claim ค้นหาค่าการอ้างสิทธิ์ที่กำหนดเองตามชื่อคีย์จากเพย์โหลดของโทเค็น

ลายเซ็น:
jwt.Token.claim(string) -> optional(dyn)
optional(jwt.Token).claim(string) -> optional(dyn)

ตัวอย่าง:
jwt.parse(token).claim("tenant").orValue("")
(v0.32.0)
presentedBy ตรวจสอบว่าผู้ออกโทเค็นและกลุ่มเป้าหมายตรงกับค่าที่คาดไว้

ลายเซ็น:
jwt.Token.presentedBy(string, string) -> bool
optional(jwt.Token).presentedBy(string, string) -> bool

ตัวอย่าง:
jwt.parse(token).presentedBy("https://auth.example.com", "https://api.example.com")
(v0.32.0)

วิธีเปิดใช้

  • ไปที่: นำเข้า cel.dev/cel-go/ext/security/jwt และส่ง jwt.Library() ไปยัง cel.NewEnv()
  • C++: ไม่รองรับ
  • Java: ไม่รองรับ
  • Python: ไม่รองรับ

ไลบรารี HMAC

ไลบรารี HMAC มีฟังก์ชันการเข้ารหัสเพื่อคำนวณและยืนยัน รหัสการตรวจสอบสิทธิ์ข้อความที่ใช้แฮช (HMAC) ในสตริงและลำดับไบต์

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
hmac.compute คำนวณไบต์ลายเซ็น HMAC ดิบโดยใช้อัลกอริทึมและคีย์ลับที่ระบุ

ลายเซ็น:
hmac.compute(string, string|bytes, string|bytes) -> bytes

ตัวอย่าง:
hmac.compute(hmac.SHA256, "secret", "message")
(v0.32.0)
hmac.verify ตรวจสอบว่าลายเซ็น HMAC ตรงกับค่าแฮชที่คาดไว้หรือไม่

ลายเซ็น:
hmac.verify(string, string|bytes, string|bytes, string|bytes) -> bool

ตัวอย่าง:
hmac.verify(hmac.SHA256, secret, msg, expected_sig) // true
(v0.32.0)

วิธีเปิดใช้

  • ไปที่: นำเข้า cel.dev/cel-go/ext/security/hmac และส่ง hmac.Library() ไปยัง cel.NewEnv()
  • C++: ไม่รองรับ
  • Java: ไม่รองรับ
  • Python: ไม่รองรับ

5. ฟีเจอร์ขั้นสูง

สรุปเกี่ยวกับฟีเจอร์ขั้นสูง

ฟีเจอร์ คำอธิบาย Go C++ Java Python C
การประเมินบางส่วน ประเมินด้วยอินพุตที่ขาดหายไป โดยจะแสดงผลเป็นค่าที่ไม่รู้จักหรือนิพจน์ที่ลดความซับซ้อนแล้ว ³
การประเมินแบบไม่พร้อมกัน การดำเนินการฟังก์ชันส่วนขยายพร้อมกันแบบไม่บล็อก
โปรแกรมตรวจสอบ AST การวิเคราะห์แบบคงที่จะตรวจสอบ AST ที่ตรวจสอบแล้วหลังจากตรวจสอบประเภท
เครื่องมือเพิ่มประสิทธิภาพ AST การเขียน AST ใหม่ (การพับค่าคงที่ การแทรกอินไลน์ CSE) เพื่อปรับปรุงประสิทธิภาพ
CEL Policy Compiler คอมไพล์โครงสร้างนโยบายที่ใช้ YAML เป็น AST ของ CEL มาตรฐาน
การยืนยันอย่างเป็นทางการ พิสูจน์ตัวแปรความปลอดภัย ความพึงพอใจ ความถูกต้อง และความเท่าเทียมกันของ AST (v0.14.0)

³ Go รองรับการสร้าง Residual AST (AST ที่ตัดแต่งแล้ว) ⁴ C++ และ Java รองรับ การแสดงผล UnknownSet / CelUnknownSet ที่รันไทม์ แต่ไม่ได้เปิดเผย API สาธารณะ สำหรับการสร้าง AST ที่เหลือ ⁵ Go ใช้ AsyncBinding / AsyncOp ที่ส่งคืน แชแนล ⁶ Java ใช้ CelAsyncRuntime โดยแสดงผล ListenableFuture

การประเมินบางส่วน (ไม่ทราบ)

การประเมินบางส่วนช่วยให้ประเมินนิพจน์ได้เมื่อทราบเฉพาะชุดย่อยของตัวแปรอินพุต (อาร์กิวเมนต์) การประเมินจะสร้างผลลัพธ์ที่ระบุสิ่งที่ขาดหายไปหรือนิพจน์ที่ง่ายขึ้นแทนที่จะล้มเหลว

  • ไป: รองรับอย่างเต็มรูปแบบ อนุญาตให้กำหนด PartialActivation ด้วยรูปแบบของแอตทริบิวต์ที่ไม่รู้จัก การประเมินจะแสดงผลค่า types.Unknown Go รองรับ การสร้าง AST ที่เหลือ (Env.ResidualAst) ซึ่งเป็น AST ที่ตัดทอน และลดความซับซ้อนแล้ว โดยมีเฉพาะส่วนของนิพจน์ที่ประเมินค่าไม่ได้
  • C++: รองรับค่า Unknown รูปแบบแอตทริบิวต์ที่ไม่รู้จักจะ กำหนดค่าผ่าน Activation::set_unknown_attribute_patterns การประเมิน จะแสดง UnknownSet ขณะนี้ API สาธารณะยังไม่แสดงการสร้าง AST ที่เหลือ
  • Java: รองรับการประเมินบางส่วนผ่าน PartialVars passed to Program.eval() การประเมินจะแสดงผลเป็น CelUnknownSet ขณะนี้ Public API ยังไม่แสดงการสร้าง AST ที่เหลือ
  • Python / C: ไม่รองรับโดยตรง

การประเมินแบบไม่พร้อมกัน

การประเมินแบบไม่พร้อมกันช่วยให้นิพจน์ CEL เรียกฟังก์ชันที่ดำเนินการแบบไม่พร้อมกัน (เช่น การเรียก RPC หรือการค้นหาฐานข้อมูล) และบล็อกการประเมินจนกว่าผลลัพธ์จะพร้อมใช้งาน โดยไม่บล็อกเธรดการดำเนินการหลัก

  • Go: รองรับการโอเวอร์โหลดฟังก์ชันแบบอะซิงโครนัสผ่าน AsyncBinding และ AsyncOp ฟังก์ชันแบบไม่พร้อมกันจะแสดงผลแชแนล Go (<-chan ref.Val) และ อินเทอร์พรีเตอร์จะจัดการการดำเนินการพร้อมกันและการซิงโครไนซ์
  • Java: รองรับการประเมินแบบอะซิงโครนัสผ่าน CelAsyncRuntime และ AsyncProgram โดยใช้ ListenableFuture เพื่อแสดงค่าที่รอดำเนินการและ ขับเคลื่อนการประเมินให้เสร็จสมบูรณ์โดยอัตโนมัติเมื่อฟิวเจอร์สได้รับการแก้ไข
  • C++ / Python / C: ไม่รองรับในตัว

โปรแกรมตรวจสอบ AST

เครื่องมือตรวจสอบจะทำการวิเคราะห์แบบคงที่ใน AST ที่ตรวจสอบแล้วหลังจากตรวจสอบประเภทเพื่อบังคับใช้ข้อจำกัดเฉพาะโดเมนก่อนที่จะมีการเรียกใช้โปรแกรม

  • Go: รองรับอินเทอร์เฟซ ASTValidator เครื่องมือตรวจสอบ Canonical ได้แก่ cel.validator.duration, cel.validator.timestamp, cel.validator.matches (นิพจน์ทั่วไป), cel.validator.homogeneous_literals และ cel.validator.comprehension_nesting_limit
  • C++: รองรับ cel::Validator การตรวจสอบ Canonical ประกอบด้วย AstDepthValidator, ComprehensionNestingLimitValidator, DurationLiteralValidator, HomogeneousLiteralValidator, MatchesValidator และ TimestampLiteralValidator
  • Java: รองรับ CelValidator และ CelAstValidator เครื่องมือตรวจสอบ Canonical ได้แก่ AstDepthLimitValidator, ComprehensionNestingLimitValidator, DurationLiteralValidator, HomogeneousLiteralValidator, RegexLiteralValidator และ TimestampLiteralValidator
  • Python / C: ไม่มีการสนับสนุนโดยตรง

เครื่องมือเพิ่มประสิทธิภาพ AST

ตัวเพิ่มประสิทธิภาพจะเขียน AST ใหม่เพื่อปรับปรุงประสิทธิภาพการดำเนินการ ตัวเพิ่มประสิทธิภาพแบ่งออกเป็น 2 หมวดหมู่ ได้แก่ ตัวเพิ่มประสิทธิภาพแบบคงที่และตัวเพิ่มประสิทธิภาพรันไทม์ C++, Java และ Go รองรับการเพิ่มประสิทธิภาพรันไทม์ นอกจากนี้ CEL Java และ Go ยังรองรับเครื่องมือเพิ่มประสิทธิภาพแบบคงที่ด้วย

การเพิ่มประสิทธิภาพทั่วไป ได้แก่ การพับค่าคงที่ (การประเมินนิพจน์ย่อยล่วงหน้า ด้วยอินพุตค่าคงที่) และการกำจัดนิพจน์ย่อยที่ใช้ร่วมกัน (CSE)

  • Go: รองรับการพับ AST ระหว่างการคอมไพล์/วางแผน
  • C++: รองรับการพับค่าคงที่ผ่านส่วนขยาย cel::extensions::EnableConstantFolding ในเวลาวางแผน
  • Java: รองรับอินเทอร์เฟซ CelOptimizer ตัวเพิ่มประสิทธิภาพ Canonical ได้แก่ ConstantFoldingOptimizer (ซึ่งรองรับการข้ามแบบ Pre-Order, การพับค่าคงที่ของข้อความ Protobuf และการตัดแต่งแบบรวมหรือแบบไม่บังคับ) InliningOptimizer และ SubexpressionOptimizer (CSE)
  • Python / C: ไม่มีการสนับสนุนโดยตรง

เครื่องมือคอมไพล์นโยบาย CEL

นโยบาย CEL เป็นรูปแบบที่อิงตาม YAML สำหรับการเขียนนิพจน์ CEL หลายรายการ ร่วมกับตัวแปร บล็อกการจับคู่ เอาต์พุตแบบมีเงื่อนไข และกฎที่ซ้อนกัน โดยออกแบบมาสำหรับเครื่องมือนโยบายที่ซับซ้อน (เช่น Admission Control ของ Kubernetes) ซึ่งนิพจน์ CEL เดียวจะอ่านไม่ได้

ดูคำจำกัดความของภาษา รูปแบบ และชุดการทดสอบความสอดคล้องอย่างเป็นทางการได้ที่ข้อกำหนดนโยบาย CEL

คอมไพเลอร์นโยบายจะคอมไพล์นโยบาย YAML เหล่านี้เป็น AST ของ CEL มาตรฐานรายการเดียว ซึ่งหมายความว่านโยบายเหล่านี้จะเข้ากันได้กับรันไทม์ CEL มาตรฐานอย่างสมบูรณ์และจะรับประกัน ประสิทธิภาพและความปลอดภัยทั้งหมด

  • Go: รองรับผ่านนโยบาย Go (รวมถึงความหมายของการประเมินกฎแบบรวม)
  • C++: รองรับผ่านนโยบาย C++
  • Java: รองรับผ่านนโยบาย Java (รวมถึงความหมายของการประเมินกฎแบบรวม และตัวระบุประเภทแบบย่อในการกำหนดค่านโยบาย)
  • Python / C: ไม่รองรับโดยตรง

กรอบการตรวจสอบอย่างเป็นทางการ

เฟรมเวิร์กการตรวจสอบอย่างเป็นทางการช่วยให้ผู้ใช้พิสูจน์ความปลอดภัย ตัวแปรที่ไม่เปลี่ยนแปลง ความเท่าเทียมกันเชิงตรรกะ ความพึงพอใจ และความถูกต้องในนิพจน์ CEL และนโยบาย CEL ที่มีโครงสร้างได้ในเชิงคณิตศาสตร์

  • Java: รองรับผ่าน CEL Java Verifier (dev.cel:verifier และ dev.cel:verifier-cli) ความสามารถรวมถึง ความพึงพอใจ (isSatisfiable) พร้อมการสร้างอินพุตพยาน ความถูกต้อง (isAlwaysTrue) พร้อมการสร้างตัวอย่างที่ขัดแย้ง การตรวจสอบโมเดลแบบจำกัด (BMC) สำหรับความเข้าใจ การพิสูจน์ความสมมูลเชิงตรรกะใน AST และการตรวจสอบตัวแปรนโยบาย assume/assert ที่กำหนดเอง
  • Go / C++ / Python / C: รองรับโดยอ้อมผ่าน Toolchain บรรทัดคำสั่ง Java

ดูข้อมูลเบื้องต้นและตัวอย่างการใช้งานจริงได้ในบล็อกโพสต์ของ Google Open Source ที่ชื่อSecuring the agentic era: Introducing formal verification for CEL