cel_cxx_ffi/
compiler.rs

1use crate::absl::Status;
2use crate::checker::{
3    CheckerLibrary, CheckerOptions, TypeChecker, TypeCheckerSubset,
4    TypeCheckerBuilderConfigurer, FunctionPredicate,
5    TypeCheckerBuilder, ValidationResult,
6};
7use crate::parser::{
8    ParserOptions, Parser, ParserBuilder, ParserLibrary, ParserLibrarySubset,
9    ParserBuilderConfigurer, MacroPredicate,
10};
11use crate::protobuf::DescriptorPool;
12use std::pin::Pin;
13
14#[cxx::bridge]
15mod ffi {
16    #[namespace = "absl"]
17    unsafe extern "C++" {
18        include!(<absl/status/status.h>);
19        type Status = super::Status;
20    }
21
22    #[namespace = "google::protobuf"]
23    unsafe extern "C++" {
24        include!(<google/protobuf/descriptor.h>);
25        type DescriptorPool = super::DescriptorPool;
26    }
27
28    #[namespace = "cel"]
29    unsafe extern "C++" {
30        include!(<compiler/compiler.h>);
31        type ParserOptions = super::ParserOptions;
32        type CheckerOptions = super::CheckerOptions;
33        type ParserBuilderConfigurer = super::ParserBuilderConfigurer;
34        type TypeCheckerBuilderConfigurer = super::TypeCheckerBuilderConfigurer;
35        type ParserBuilder = super::ParserBuilder;
36        type ParserLibrary = super::ParserLibrary;
37        type CheckerLibrary = super::CheckerLibrary;
38        type TypeCheckerSubset = super::TypeCheckerSubset;
39        type ParserLibrarySubset = super::ParserLibrarySubset;
40        type TypeChecker = super::TypeChecker;
41        type Parser = super::Parser;
42        type TypeCheckerBuilder<'a> = super::TypeCheckerBuilder<'a>;
43        type ValidationResult = super::ValidationResult;
44
45        type Compiler<'a>;
46        #[rust_name = "type_checker"]
47        fn GetTypeChecker<'a>(self: &Compiler<'a>) -> &TypeChecker;
48        #[rust_name = "parser"]
49        fn GetParser<'a>(self: &Compiler<'a>) -> &Parser;
50
51        type CompilerBuilder<'a>;
52        #[rust_name = "checker_builder"]
53        fn GetCheckerBuilder<'a>(
54            self: Pin<&mut CompilerBuilder<'a>>,
55        ) -> Pin<&mut TypeCheckerBuilder<'a>>;
56        #[rust_name = "parser_builder"]
57        fn GetParserBuilder<'a>(self: Pin<&mut CompilerBuilder<'a>>) -> Pin<&mut ParserBuilder>;
58
59        type CompilerLibrary;
60        type CompilerLibrarySubset;
61        type CompilerOptions;
62    }
63
64    #[namespace = "rust::cel_cxx"]
65    unsafe extern "C++" {
66        include!(<cel-cxx-ffi/include/absl.h>);
67        include!(<cel-cxx-ffi/include/compiler.h>);
68
69        type MacroPredicate = super::MacroPredicate;
70        type FunctionPredicate = super::FunctionPredicate;
71
72        // Compiler
73        fn Compiler_compile(
74            compiler: &Compiler,
75            source: &[u8],
76            description: &str,
77            result: &mut UniquePtr<ValidationResult>,
78        ) -> Status;
79
80        // CompilerBuilder
81        fn CompilerBuilder_new<'a>(
82            descriptor_pool: SharedPtr<DescriptorPool>,
83            options: &CompilerOptions,
84            result: &mut UniquePtr<CompilerBuilder<'a>>,
85        ) -> Status;
86
87        fn CompilerBuilder_add_library<'a>(
88            compiler_builder: Pin<&mut CompilerBuilder<'a>>,
89            library: UniquePtr<CompilerLibrary>,
90        ) -> Status;
91
92        fn CompilerBuilder_build<'a>(
93            compiler_builder: Pin<&mut CompilerBuilder<'a>>,
94            result: &mut UniquePtr<Compiler<'a>>,
95        ) -> Status;
96
97        // CompilerLibrary
98        fn CompilerLibrary_new_standard() -> UniquePtr<CompilerLibrary>;
99        fn CompilerLibrary_new_optional() -> UniquePtr<CompilerLibrary>;
100        fn CompilerLibrary_from_checker_library(
101            checker_library: UniquePtr<CheckerLibrary>,
102        ) -> UniquePtr<CompilerLibrary>;
103        fn CompilerLibrary_from_parser_library(
104            parser_library: UniquePtr<ParserLibrary>,
105        ) -> UniquePtr<CompilerLibrary>;
106
107        fn CompilerLibrary_new(id: &CxxString) -> UniquePtr<CompilerLibrary>;
108        fn CompilerLibrary_set_parser_configurer(
109            compiler_library: Pin<&mut CompilerLibrary>,
110            parser_configurer: UniquePtr<ParserBuilderConfigurer>,
111        );
112        fn CompilerLibrary_set_checker_configurer(
113            compiler_library: Pin<&mut CompilerLibrary>,
114            checker_configurer: UniquePtr<TypeCheckerBuilderConfigurer>,
115        );
116        fn CompilerLibrary_id<'a>(compiler_library: &'a CompilerLibrary) -> &'a CxxString;
117
118        // CompilerLibrarySubset
119        fn CompilerLibrarySubset_from_parser_library_subset(
120            parser_library_subset: UniquePtr<ParserLibrarySubset>,
121        ) -> UniquePtr<CompilerLibrarySubset>;
122        fn CompilerLibrarySubset_from_checker_library_subset(
123            checker_library_subset: UniquePtr<TypeCheckerSubset>,
124        ) -> UniquePtr<CompilerLibrarySubset>;
125
126        fn CompilerLibrarySubset_new(library_id: &CxxString) -> UniquePtr<CompilerLibrarySubset>;
127        fn CompilerLibrarySubset_set_macro_predicate(
128            compiler_library_subset: Pin<&mut CompilerLibrarySubset>,
129            should_include_macro: UniquePtr<MacroPredicate>,
130        );
131        fn CompilerLibrarySubset_set_function_predicate(
132            compiler_library_subset: Pin<&mut CompilerLibrarySubset>,
133            should_include_overload: UniquePtr<FunctionPredicate>,
134        );
135        fn CompilerLibrarySubset_library_id<'a>(compiler_library_subset: &'a CompilerLibrarySubset) -> &'a CxxString;
136
137        // CompilerOptions
138        fn CompilerOptions_new() -> UniquePtr<CompilerOptions>;
139
140        // CompilerOptions getters and setters
141        fn CompilerOptions_parser_options(compiler_options: &CompilerOptions) -> &ParserOptions;
142        fn CompilerOptions_parser_options_mut(
143            compiler_options: Pin<&mut CompilerOptions>,
144        ) -> Pin<&mut ParserOptions>;
145        fn CompilerOptions_checker_options(compiler_options: &CompilerOptions) -> &CheckerOptions;
146        fn CompilerOptions_checker_options_mut(
147            compiler_options: Pin<&mut CompilerOptions>,
148        ) -> Pin<&mut CheckerOptions>;
149    }
150}
151
152pub use ffi::Compiler;
153unsafe impl<'a> Send for Compiler<'a> {}
154unsafe impl<'a> Sync for Compiler<'a> {}
155
156impl<'a> Compiler<'a> {
157    pub fn compile(
158        &self,
159        source: &[u8],
160        description: Option<&str>,
161    ) -> Result<cxx::UniquePtr<ValidationResult>, Status> {
162        let description = description.unwrap_or("<input>");
163        let mut result = cxx::UniquePtr::null();
164        let status = ffi::Compiler_compile(self, source, description, &mut result);
165        if status.is_ok() {
166            Ok(result)
167        } else {
168            Err(status)
169        }
170    }
171}
172
173impl<'a> std::fmt::Debug for Compiler<'a> {
174    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
175        write!(
176            f,
177            "Compiler {{ type_checker: {:?}, parser: {:?} }}",
178            self.type_checker(),
179            self.parser(),
180        )
181    }
182}
183
184pub use ffi::CompilerBuilder;
185unsafe impl<'a> Send for CompilerBuilder<'a> {}
186unsafe impl<'a> Sync for CompilerBuilder<'a> {}
187
188impl<'a> CompilerBuilder<'a> {
189    pub fn new(
190        descriptor_pool: cxx::SharedPtr<DescriptorPool>,
191        options: &CompilerOptions,
192    ) -> Result<cxx::UniquePtr<Self>, Status> {
193        let mut result = cxx::UniquePtr::null();
194        let status = ffi::CompilerBuilder_new(descriptor_pool, options, &mut result);
195        if status.is_ok() {
196            Ok(result)
197        } else {
198            Err(status)
199        }
200    }
201
202    pub fn add_library(
203        self: Pin<&mut Self>,
204        library: cxx::UniquePtr<CompilerLibrary>,
205    ) -> Result<(), Status> {
206        let status = ffi::CompilerBuilder_add_library(self, library);
207        if status.is_ok() {
208            Ok(())
209        } else {
210            Err(status)
211        }
212    }
213
214    pub fn build(self: Pin<&mut Self>) -> Result<cxx::UniquePtr<Compiler<'a>>, Status> {
215        let mut result = cxx::UniquePtr::null();
216        let status = ffi::CompilerBuilder_build(self, &mut result);
217        if status.is_ok() {
218            Ok(result)
219        } else {
220            Err(status)
221        }
222    }
223}
224
225impl<'a> std::fmt::Debug for CompilerBuilder<'a> {
226    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
227        write!(f, "CompilerBuilder {{ ptr: {:p} }}", self as *const Self)
228    }
229}
230
231// CompilerLibrary
232pub use ffi::CompilerLibrary;
233unsafe impl Send for CompilerLibrary {}
234unsafe impl Sync for CompilerLibrary {}
235
236impl CompilerLibrary {
237    pub fn new(id: &cxx::CxxString) -> cxx::UniquePtr<Self> {
238        ffi::CompilerLibrary_new(id)
239    }
240
241    pub fn set_parser_configurer(
242        self: Pin<&mut Self>,
243        parser_configurer: cxx::UniquePtr<ParserBuilderConfigurer>,
244    ) {
245        ffi::CompilerLibrary_set_parser_configurer(self, parser_configurer);
246    }
247
248    pub fn set_checker_configurer(
249        self: Pin<&mut Self>,
250        checker_configurer: cxx::UniquePtr<TypeCheckerBuilderConfigurer>,
251    ) {
252        ffi::CompilerLibrary_set_checker_configurer(self, checker_configurer);
253    }
254
255    pub fn new_standard() -> cxx::UniquePtr<Self> {
256        ffi::CompilerLibrary_new_standard()
257    }
258
259    pub fn new_optional() -> cxx::UniquePtr<Self> {
260        ffi::CompilerLibrary_new_optional()
261    }
262
263    pub fn from_checker_library(
264        checker_library: cxx::UniquePtr<CheckerLibrary>,
265    ) -> cxx::UniquePtr<Self> {
266        ffi::CompilerLibrary_from_checker_library(checker_library)
267    }
268
269    pub fn from_parser_library(
270        parser_library: cxx::UniquePtr<ParserLibrary>,
271    ) -> cxx::UniquePtr<Self> {
272        ffi::CompilerLibrary_from_parser_library(parser_library)
273    }
274
275    pub fn id(&self) -> &cxx::CxxString {
276        ffi::CompilerLibrary_id(self)
277    }
278}
279
280// CompilerLibrarySubset
281pub use ffi::CompilerLibrarySubset;
282unsafe impl Send for CompilerLibrarySubset {}
283unsafe impl Sync for CompilerLibrarySubset {}
284
285impl CompilerLibrarySubset {
286    pub fn new(library_id: &cxx::CxxString) -> cxx::UniquePtr<Self> {
287        ffi::CompilerLibrarySubset_new(library_id)
288    }
289
290    pub fn set_macro_predicate(
291        self: Pin<&mut Self>,
292        macro_predicate: cxx::UniquePtr<MacroPredicate>,
293    ) {
294        ffi::CompilerLibrarySubset_set_macro_predicate(self, macro_predicate);
295    }
296
297    pub fn set_function_predicate(
298        self: Pin<&mut Self>,
299        function_predicate: cxx::UniquePtr<FunctionPredicate>,
300    ) {
301        ffi::CompilerLibrarySubset_set_function_predicate(self, function_predicate);
302    }
303
304    pub fn library_id(&self) -> &cxx::CxxString {
305        ffi::CompilerLibrarySubset_library_id(self)
306    }
307
308    pub fn from_parser_library_subset(
309        parser_library_subset: cxx::UniquePtr<ParserLibrarySubset>,
310    ) -> cxx::UniquePtr<Self> {
311        ffi::CompilerLibrarySubset_from_parser_library_subset(parser_library_subset)
312    }
313
314    pub fn from_checker_library_subset(
315        checker_library_subset: cxx::UniquePtr<TypeCheckerSubset>,
316    ) -> cxx::UniquePtr<Self> {
317        ffi::CompilerLibrarySubset_from_checker_library_subset(checker_library_subset)
318    }
319}
320
321// CompilerOptions
322pub use ffi::CompilerOptions;
323unsafe impl Send for CompilerOptions {}
324unsafe impl Sync for CompilerOptions {}
325
326impl CompilerOptions {
327    pub fn new() -> cxx::UniquePtr<Self> {
328        let mut options = ffi::CompilerOptions_new();
329        *options
330            .pin_mut()
331            .parser_options_mut()
332            .enable_optional_syntax_mut() = true;
333        options
334    }
335
336    pub fn parser_options(&self) -> &ParserOptions {
337        ffi::CompilerOptions_parser_options(self)
338    }
339
340    pub fn parser_options_mut(self: Pin<&mut Self>) -> Pin<&mut ParserOptions> {
341        ffi::CompilerOptions_parser_options_mut(self)
342    }
343
344    pub fn checker_options(&self) -> &CheckerOptions {
345        ffi::CompilerOptions_checker_options(self)
346    }
347
348    pub fn checker_options_mut(self: Pin<&mut Self>) -> Pin<&mut CheckerOptions> {
349        ffi::CompilerOptions_checker_options_mut(self)
350    }
351}