From 0b296826a64bebb76d8a8301e8b402fab8248d12 Mon Sep 17 00:00:00 2001 From: Brian Thorne Date: Tue, 14 Oct 2025 19:50:51 +1300 Subject: [PATCH] Support lazy Python mappings via dynamic MapValue --- Cargo.lock | 2 - Cargo.toml | 3 + src/lib.rs | 188 +- tests/test_context.py | 17 + vendor/cel/.cargo-ok | 1 + vendor/cel/.cargo_vcs_info.json | 6 + vendor/cel/CHANGELOG.md | 139 + vendor/cel/Cargo.lock | 984 +++ vendor/cel/Cargo.toml | 111 + vendor/cel/Cargo.toml.orig | 40 + vendor/cel/README.md | 55 + vendor/cel/benches/runtime.rs | 108 + vendor/cel/src/common/ast/mod.rs | 158 + vendor/cel/src/common/ast/operators.rs | 53 + vendor/cel/src/common/mod.rs | 4 + vendor/cel/src/common/traits.rs | 47 + vendor/cel/src/common/types/bool.rs | 58 + vendor/cel/src/common/types/bytes.rs | 27 + vendor/cel/src/common/types/double.rs | 27 + vendor/cel/src/common/types/duration.rs | 28 + vendor/cel/src/common/types/int.rs | 27 + vendor/cel/src/common/types/mod.rs | 255 + vendor/cel/src/common/types/null.rs | 15 + vendor/cel/src/common/types/optional.rs | 32 + vendor/cel/src/common/types/string.rs | 28 + vendor/cel/src/common/types/timestamp.rs | 28 + vendor/cel/src/common/types/uint.rs | 27 + vendor/cel/src/common/value.rs | 78 + vendor/cel/src/context.rs | 187 + vendor/cel/src/duration.rs | 281 + vendor/cel/src/functions.rs | 871 +++ vendor/cel/src/json.rs | 122 + vendor/cel/src/lib.rs | 303 + vendor/cel/src/macros.rs | 102 + vendor/cel/src/magic.rs | 328 + vendor/cel/src/objects.rs | 1374 +++++ vendor/cel/src/parser/gen/CEL.g4 | 207 + vendor/cel/src/parser/gen/CEL.interp | 102 + vendor/cel/src/parser/gen/CEL.tokens | 65 + vendor/cel/src/parser/gen/CELLexer.interp | 139 + vendor/cel/src/parser/gen/CELLexer.tokens | 65 + vendor/cel/src/parser/gen/cellexer.rs | 590 ++ vendor/cel/src/parser/gen/cellistener.rs | 417 ++ vendor/cel/src/parser/gen/celparser.rs | 6733 +++++++++++++++++++++ vendor/cel/src/parser/gen/celvisitor.rs | 829 +++ vendor/cel/src/parser/gen/mod.rs | 7 + vendor/cel/src/parser/macros.rs | 342 ++ vendor/cel/src/parser/mod.rs | 15 + vendor/cel/src/parser/parse.rs | 531 ++ vendor/cel/src/parser/parser.rs | 1986 ++++++ vendor/cel/src/parser/references.rs | 155 + vendor/cel/src/resolvers.rs | 64 + vendor/cel/src/ser.rs | 1375 +++++ vendor/cel/src/types/map.rs | 19 + vendor/cel/src/types/mod.rs | 1 + 55 files changed, 19726 insertions(+), 30 deletions(-) create mode 100644 vendor/cel/.cargo-ok create mode 100644 vendor/cel/.cargo_vcs_info.json create mode 100644 vendor/cel/CHANGELOG.md create mode 100644 vendor/cel/Cargo.lock create mode 100644 vendor/cel/Cargo.toml create mode 100644 vendor/cel/Cargo.toml.orig create mode 100644 vendor/cel/README.md create mode 100644 vendor/cel/benches/runtime.rs create mode 100644 vendor/cel/src/common/ast/mod.rs create mode 100644 vendor/cel/src/common/ast/operators.rs create mode 100644 vendor/cel/src/common/mod.rs create mode 100644 vendor/cel/src/common/traits.rs create mode 100644 vendor/cel/src/common/types/bool.rs create mode 100644 vendor/cel/src/common/types/bytes.rs create mode 100644 vendor/cel/src/common/types/double.rs create mode 100644 vendor/cel/src/common/types/duration.rs create mode 100644 vendor/cel/src/common/types/int.rs create mode 100644 vendor/cel/src/common/types/mod.rs create mode 100644 vendor/cel/src/common/types/null.rs create mode 100644 vendor/cel/src/common/types/optional.rs create mode 100644 vendor/cel/src/common/types/string.rs create mode 100644 vendor/cel/src/common/types/timestamp.rs create mode 100644 vendor/cel/src/common/types/uint.rs create mode 100644 vendor/cel/src/common/value.rs create mode 100644 vendor/cel/src/context.rs create mode 100644 vendor/cel/src/duration.rs create mode 100644 vendor/cel/src/functions.rs create mode 100644 vendor/cel/src/json.rs create mode 100644 vendor/cel/src/lib.rs create mode 100644 vendor/cel/src/macros.rs create mode 100644 vendor/cel/src/magic.rs create mode 100644 vendor/cel/src/objects.rs create mode 100644 vendor/cel/src/parser/gen/CEL.g4 create mode 100644 vendor/cel/src/parser/gen/CEL.interp create mode 100644 vendor/cel/src/parser/gen/CEL.tokens create mode 100644 vendor/cel/src/parser/gen/CELLexer.interp create mode 100644 vendor/cel/src/parser/gen/CELLexer.tokens create mode 100644 vendor/cel/src/parser/gen/cellexer.rs create mode 100644 vendor/cel/src/parser/gen/cellistener.rs create mode 100644 vendor/cel/src/parser/gen/celparser.rs create mode 100644 vendor/cel/src/parser/gen/celvisitor.rs create mode 100644 vendor/cel/src/parser/gen/mod.rs create mode 100644 vendor/cel/src/parser/macros.rs create mode 100644 vendor/cel/src/parser/mod.rs create mode 100644 vendor/cel/src/parser/parse.rs create mode 100644 vendor/cel/src/parser/parser.rs create mode 100644 vendor/cel/src/parser/references.rs create mode 100644 vendor/cel/src/resolvers.rs create mode 100644 vendor/cel/src/ser.rs create mode 100644 vendor/cel/src/types/map.rs create mode 100644 vendor/cel/src/types/mod.rs diff --git a/Cargo.lock b/Cargo.lock index c3dac81..4ae1bb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,8 +118,6 @@ dependencies = [ [[package]] name = "cel" version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd757373c0c269eaaca1c355cbd8dc78e1191982c0e9e6dfe1f61ff38b235ad" dependencies = [ "antlr4rust", "base64", diff --git a/Cargo.toml b/Cargo.toml index e02b4e2..16147a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,6 @@ cel = { version = "0.11.4", features = ["chrono", "json", "regex"] } log = "0.4.27" pyo3-log = "0.12.4" chrono = { version = "0.4.41", features = ["serde"] } + +[patch.crates-io] +cel = { path = "vendor/cel" } diff --git a/src/lib.rs b/src/lib.rs index f951a49..de145fb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,15 +1,17 @@ mod context; use ::cel::objects::{Key, TryIntoValue}; +use ::cel::types::map::MapValue; use ::cel::{Context as CelContext, ExecutionError, Program, Value}; use log::debug; use pyo3::exceptions::{PyRuntimeError, PyTypeError, PyValueError}; use pyo3::prelude::*; use pyo3::BoundObject; +use pyo3::IntoPyObject; use std::panic::{self, AssertUnwindSafe}; use chrono::{DateTime, Duration as ChronoDuration, Offset, TimeZone}; -use pyo3::types::{PyBool, PyBytes, PyDict, PyList, PyTuple}; +use pyo3::types::{PyBool, PyBytes, PyDict, PyList, PyMapping, PyTuple}; use std::collections::HashMap; use std::error::Error; @@ -66,6 +68,17 @@ impl<'py> IntoPyObject<'py> for RustyCelType { python_dict.into_any() } + RustyCelType(Value::DynamicMap(map)) => { + let python_dict = PyDict::new(py); + + for (key, value) in map.iter() { + let key_obj = PyMappingValue::key_to_python(py, &key); + let value_obj = RustyCelType(value).into_pyobject(py)?; + python_dict.set_item(key_obj.bind(py), &value_obj)?; + } + + python_dict.into_any() + } // Turn everything else into a String: nonprimitive => format!("{nonprimitive:?}").into_pyobject(py)?.into_any(), @@ -77,6 +90,115 @@ impl<'py> IntoPyObject<'py> for RustyCelType { #[derive(Debug)] struct RustyPyType<'a>(&'a Bound<'a, PyAny>); +#[derive(Clone)] +struct PyMappingValue { + mapping: Py, +} + +impl PyMappingValue { + fn new(mapping: Py) -> Self { + Self { mapping } + } + + fn key_to_python(py: Python<'_>, key: &Key) -> Py { + match key { + Key::Int(value) => value.into_pyobject(py).unwrap().unbind().into(), + Key::Uint(value) => value.into_pyobject(py).unwrap().unbind().into(), + Key::Bool(value) => value.into_pyobject(py).unwrap().unbind().into(), + Key::String(value) => value.as_str().into_pyobject(py).unwrap().unbind().into(), + } + } + + fn py_to_key(obj: &Bound<'_, PyAny>) -> Option { + if obj.is_none() { + return None; + } + + if let Ok(value) = obj.extract::() { + Some(Key::Int(value)) + } else if let Ok(value) = obj.extract::() { + Some(Key::Uint(value)) + } else if let Ok(value) = obj.extract::() { + Some(Key::Bool(value)) + } else if let Ok(value) = obj.extract::() { + Some(Key::String(value.into())) + } else { + None + } + } +} + +impl fmt::Debug for PyMappingValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("PyMappingValue").finish() + } +} + +impl MapValue for PyMappingValue { + fn get(&self, key: &Key) -> Option { + Python::with_gil(|py| { + let bound = self.mapping.bind(py); + let mapping = bound.downcast::().ok()?; + let py_key = Self::key_to_python(py, key); + let value = mapping.get_item(py_key).ok()?; + RustyPyType(&value).try_into_value().ok() + }) + } + + fn contains_key(&self, key: &Key) -> bool { + Python::with_gil(|py| { + let bound = self.mapping.bind(py); + let mapping = match bound.downcast::() { + Ok(mapping) => mapping, + Err(_) => return false, + }; + let py_key = Self::key_to_python(py, key); + mapping.contains(py_key).unwrap_or(false) + }) + } + + fn len(&self) -> usize { + Python::with_gil(|py| { + let bound = self.mapping.bind(py); + bound + .downcast::() + .ok() + .and_then(|mapping| mapping.len().ok()) + .unwrap_or(0) + }) + } + + fn iter(&self) -> Box + '_> { + let items = Python::with_gil(|py| { + let bound = self.mapping.bind(py); + let mapping = match bound.downcast::() { + Ok(mapping) => mapping, + Err(_) => return Vec::new(), + }; + let list = match mapping.items() { + Ok(items) => items, + Err(_) => return Vec::new(), + }; + + list.iter() + .filter_map(|item| { + let tuple = item.downcast::().ok()?; + if tuple.len() != 2 { + return None; + } + let key_obj = tuple.get_item(0).ok()?; + let value_obj = tuple.get_item(1).ok()?; + let key = Self::py_to_key(&key_obj)?; + let value = RustyPyType(&value_obj).try_into_value().ok()?; + Some((key, value)) + }) + .collect::>() + }); + + Box::new(items.into_iter()) + } +} + #[derive(Debug, PartialEq, Clone)] pub enum CelError { ConversionError(String), @@ -212,35 +334,45 @@ impl TryIntoValue for RustyPyType<'_> { .map(|item| RustyPyType(&item).try_into_value()) .collect::, Self::Error>>(); list.map(|v| Value::List(Arc::new(v))) - } else if let Ok(value) = pyobject.downcast::() { - let mut map: HashMap = HashMap::new(); - for (key, value) in value.into_iter() { - let key = if key.is_none() { - return Err(CelError::ConversionError( - "None cannot be used as a key in dictionaries".to_string(), - )); - } else if let Ok(k) = key.extract::() { - Key::Int(k) - } else if let Ok(k) = key.extract::() { - Key::Uint(k) - } else if let Ok(k) = key.extract::() { - Key::Bool(k) - } else if let Ok(k) = key.extract::() { - Key::String(k.into()) - } else { - return Err(CelError::ConversionError( - "Failed to convert PyDict key to Key".to_string(), - )); - }; - if let Ok(dict_value) = RustyPyType(&value).try_into_value() { - map.insert(key, dict_value); - } else { - return Err(CelError::ConversionError( - "Failed to convert PyDict value to Value".to_string(), - )); + } else if let Ok(dict) = pyobject.downcast::() { + if pyobject.is_exact_instance_of::() { + let mut map: HashMap = HashMap::new(); + for (key, value) in dict.iter() { + let key = if key.is_none() { + return Err(CelError::ConversionError( + "None cannot be used as a key in dictionaries".to_string(), + )); + } else if let Ok(k) = key.extract::() { + Key::Int(k) + } else if let Ok(k) = key.extract::() { + Key::Uint(k) + } else if let Ok(k) = key.extract::() { + Key::Bool(k) + } else if let Ok(k) = key.extract::() { + Key::String(k.into()) + } else { + return Err(CelError::ConversionError( + "Failed to convert PyDict key to Key".to_string(), + )); + }; + if let Ok(dict_value) = RustyPyType(&value).try_into_value() { + map.insert(key, dict_value); + } else { + return Err(CelError::ConversionError( + "Failed to convert PyDict value to Value".to_string(), + )); + } } + Ok(Value::Map(map.into())) + } else { + Ok(Value::DynamicMap(Arc::new(PyMappingValue::new( + dict.clone().into_any().unbind(), + )))) } - Ok(Value::Map(map.into())) + } else if let Ok(mapping) = pyobject.downcast::() { + Ok(Value::DynamicMap(Arc::new(PyMappingValue::new( + mapping.clone().into_any().unbind(), + )))) } else if let Ok(value) = pyobject.extract::>() { Ok(Value::Bytes(value.into())) } else { diff --git a/tests/test_context.py b/tests/test_context.py index d1da03c..3c230ca 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -107,3 +107,20 @@ def test_nested_context_none(): assert cel.evaluate("spec.host", cel_context) == "github.com" assert cel.evaluate("data['response-code']", cel_context) == "NOERROR" assert cel.evaluate("size(data.A)", cel_context) == 1 + + +def test_lazy_mapping_lookup(): + class LazyDict(dict): + def __init__(self): + super().__init__() + self._storage = {} + + def __getitem__(self, key): + if key not in self._storage: + self._storage[key] = f"computed-{key}" + return self._storage[key] + + data = LazyDict() + context = cel.Context({"data": data}) + + assert cel.evaluate("data.key", context) == "computed-key" diff --git a/vendor/cel/.cargo-ok b/vendor/cel/.cargo-ok new file mode 100644 index 0000000..5f8b795 --- /dev/null +++ b/vendor/cel/.cargo-ok @@ -0,0 +1 @@ +{"v":1} \ No newline at end of file diff --git a/vendor/cel/.cargo_vcs_info.json b/vendor/cel/.cargo_vcs_info.json new file mode 100644 index 0000000..948abec --- /dev/null +++ b/vendor/cel/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "4e4d40d33529add8a4e3dd70ddacc7c7b5a91663" + }, + "path_in_vcs": "cel" +} \ No newline at end of file diff --git a/vendor/cel/CHANGELOG.md b/vendor/cel/CHANGELOG.md new file mode 100644 index 0000000..a473425 --- /dev/null +++ b/vendor/cel/CHANGELOG.md @@ -0,0 +1,139 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.11.4](https://github.com/cel-rust/cel-rust/compare/cel-v0.11.3...cel-v0.11.4) - 2025-10-09 + +### Fixed + +- antlr4rust update, and fix to allow for linefeed ParseErr +- *(parser)* Gets rid of ever invoking Visitable with no impl +- *(string)* String index accesses err out +- *(clippy)* manual_is_multiple_of +- *(parser)* Stop traversing AST on PrimaryContextAll::Error + +### Other + +- add coverage +- Merge pull request #199 from cel-rust/issue-198 + +## [0.11.3](https://github.com/cel-rust/cel-rust/compare/cel-v0.11.2...cel-v0.11.3) - 2025-10-02 + +### Fixed + +- *(parsing)* stop navigating AST on err + +## [0.11.2](https://github.com/cel-rust/cel-rust/compare/cel-v0.11.1...cel-v0.11.2) - 2025-09-19 + +### Other + +- updated antlr4rust to v0.3.0-rc1 explicitly ([#189](https://github.com/cel-rust/cel-rust/pull/189)) + +## [0.11.1](https://github.com/cel-rust/cel-rust/compare/cel-v0.11.0...cel-v0.11.1) - 2025-08-20 + +### Fixed + +- *(clippy)* hiding a lifetime that's elided elsewhere is confusing +- Added proper `ExecutionError::NoSuchOverload` +- no bool coercion + +### Other + +- Merge pull request #185 from alexsnaps/cleanup-coerce-into-bool + +## [0.11.0](https://github.com/cel-rust/cel-rust/compare/cel-v0.10.0...cel-v0.11.0) - 2025-08-06 + +### Other + +- Fix CEL readme ([#180](https://github.com/cel-rust/cel-rust/pull/180)) +- Merge pull request #154 from alexsnaps/types +- Fix usage of identifier in custom functions ([#174](https://github.com/cel-rust/cel-rust/pull/174)) +- Merge pull request #169 from cgettys-microsoft/shrink-expr-01 +- Make Program expose the Expr ([#171](https://github.com/cel-rust/cel-rust/pull/171)) +- unused struct, using ([#170](https://github.com/cel-rust/cel-rust/pull/170)) + +## [0.10.0](https://github.com/cel-rust/cel-rust/compare/cel-interpreter-v0.9.1...cel-interpreter-v0.10.0) - 2025-07-23 + +### Added + +- *(antlr)* 🔥 previous parser +- *(antlr)* Good ridance .unwrap()s - part 2 of 2 +- *(antlr)* offending whitespaces are fine +- *(antlr)* deal with lexer errors +- *(antlr)* support multiple errors from parsing +- *(antlr)* impl _[_] +- *(antlr)* test only SelectExpr +- *(macros)* Comprehensions +- *(antlr)* Expr are now ID'ed + +### Fixed + +- Mistakenly Public API changes reverted +- Do not expose internal comprehension var idents +- Do not resolve left operand twice +- has defaults to false on non container types +- don't drop the IdedExpr +- has(_[_]) is that a thing? +- double eval, and lazy eval of right hand expr +- dunno why this changed + +### Other + +- Updated GH urls to new org ([#158](https://github.com/cel-rust/cel-rust/pull/158)) +- Optimizations around member lookups ([#156](https://github.com/cel-rust/cel-rust/pull/156)) +- Fixing fuzz test ([#157](https://github.com/cel-rust/cel-rust/pull/157)) +- :uninlined_format_args fixes ([#153](https://github.com/cel-rust/cel-rust/pull/153)) +- Add basic infrastructure for fuzzing and one target for Value binops ([#152](https://github.com/cel-rust/cel-rust/pull/152)) +- Append to lists and strings in place instead of cloning when possible ([#149](https://github.com/cel-rust/cel-rust/pull/149)) +- Remove non-standard binary operators ([#147](https://github.com/cel-rust/cel-rust/pull/147)) +- Make ExecutionError non-exhaustive ([#148](https://github.com/cel-rust/cel-rust/pull/148)) +- Avoid panics due to division by zero and integer overflow ([#145](https://github.com/cel-rust/cel-rust/pull/145)) +- Remove redundant clone +- Remove redundant string/error allocations/clones during name resolution +- cargo fmt +- deleted dead code +- add test for 3 args map macro +- deleting fn replaced with macros +- fmt & clippy +- Interpreter adapted to compile using new parser +- simplify function binding magic as an IntoFunction trait ([#133](https://github.com/cel-rust/cel-rust/pull/133)) + +## [0.9.1](https://github.com/cel-rust/cel-rust/compare/cel-interpreter-v0.9.0...cel-interpreter-v0.9.1) - 2025-04-29 + +### Added + +- Implement Short-Circuit Evaluation for AND Expressions to Fix Issue #117 ([#118](https://github.com/cel-rust/cel-rust/pull/118)) + +### Fixed + +- improve `Context::add_variable` `Err` type ([#127](https://github.com/cel-rust/cel-rust/pull/127)) + +### Other + +- Add `min` function ([#130](https://github.com/cel-rust/cel-rust/pull/130)) +- Fix typos. ([#125](https://github.com/cel-rust/cel-rust/pull/125)) +- Add custom Duration and Timestamp types for conversion with serde ([#89](https://github.com/cel-rust/cel-rust/pull/89)) +- Export timestamp and duration fn as they were ([#112](https://github.com/cel-rust/cel-rust/pull/112)) +- ValueType copy & debug ([#113](https://github.com/cel-rust/cel-rust/pull/113)) +- Expose Serialization and ToJson errors ([#114](https://github.com/cel-rust/cel-rust/pull/114)) +- Fix compilation without chrono ([#111](https://github.com/cel-rust/cel-rust/pull/111)) +- Fix default features, cleanup dependencies & other minor code improvements ([#109](https://github.com/cel-rust/cel-rust/pull/109)) +- Added missing timestamp macros ([#106](https://github.com/cel-rust/cel-rust/pull/106)) + +## [0.9.0](https://github.com/cel-rust/cel-rust/compare/cel-interpreter-v0.8.1...cel-interpreter-v0.9.0) - 2024-10-30 + +### Other + +- Support `.map` over map ([#105](https://github.com/cel-rust/cel-rust/pull/105)) +- Detailed parse error ([#102](https://github.com/cel-rust/cel-rust/pull/102)) +- Fix `clippy::too_long_first_doc_paragraph` lints. ([#101](https://github.com/cel-rust/cel-rust/pull/101)) +- Support empty/default contexts, put chrono/regex behind features ([#97](https://github.com/cel-rust/cel-rust/pull/97)) +- Fix `clippy::empty_line_after_doc_comments` lints ([#98](https://github.com/cel-rust/cel-rust/pull/98)) +- Allow `.size()` method on types ([#88](https://github.com/cel-rust/cel-rust/pull/88)) +- Conformance test fixes ([#79](https://github.com/cel-rust/cel-rust/pull/79)) +- Convert CEL values to JSON ([#77](https://github.com/cel-rust/cel-rust/pull/77)) diff --git a/vendor/cel/Cargo.lock b/vendor/cel/Cargo.lock new file mode 100644 index 0000000..24bae47 --- /dev/null +++ b/vendor/cel/Cargo.lock @@ -0,0 +1,984 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "antlr4rust" +version = "0.3.0-rc2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d240d49ee89063f90fa0cb18aead41a5893cd544a1785983dc3bf5c3d5faa58b" +dependencies = [ + "better_any", + "bit-set", + "byteorder", + "lazy_static", + "murmur3", + "once_cell", + "parking_lot", + "typed-arena", + "uuid", +] + +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "better_any" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1795ebc740ea791ffbe6685e0688ab1effec16c2864e0476db40bfdf0c02cb3d" + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitflags" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cel" +version = "0.11.4" +dependencies = [ + "antlr4rust", + "arbitrary", + "base64", + "chrono", + "criterion", + "dhat", + "lazy_static", + "nom", + "paste", + "regex", + "serde", + "serde_bytes", + "serde_json", + "thiserror", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "chrono" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +dependencies = [ + "arbitrary", + "num-traits", + "serde", +] + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clap" +version = "4.5.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" +dependencies = [ + "anstyle", + "clap_lex", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "derive_arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dhat" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cd11d84628e233de0ce467de10b8633f4ddaecafadefc86e13b84b8739b827" +dependencies = [ + "backtrace", + "lazy_static", + "mintex", + "parking_lot", + "rustc-hash", + "serde", + "serde_json", + "thousands", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "half" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e54c115d4f30f52c67202f079c5f9d8b49db4691f460fdb0b4c2e838261b2ba5" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "is-terminal" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.177" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mintex" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c505b3e17ed6b70a7ed2e67fbb2c560ee327353556120d6e72f5232b6880d536" + +[[package]] +name = "murmur3" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a198f9589efc03f544388dfc4a19fe8af4323662b62f598b8dcfdac62c14771c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thousands" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "uuid" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/vendor/cel/Cargo.toml b/vendor/cel/Cargo.toml new file mode 100644 index 0000000..11cd291 --- /dev/null +++ b/vendor/cel/Cargo.toml @@ -0,0 +1,111 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +name = "cel" +version = "0.11.4" +authors = [ + "Clark McCauley ", + "Alex Snaps ", +] +build = false +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "A parser and interpreter for the Common Expression Language (CEL)" +readme = "README.md" +categories = ["compilers"] +license = "MIT" +repository = "https://github.com/cel-rust/cel-rust" + +[features] +arbitrary = [ + "dep:arbitrary", + "chrono?/arbitrary", + "chrono?/std", +] +chrono = ["dep:chrono"] +default = [ + "regex", + "chrono", +] +dhat-heap = [] +json = [ + "dep:serde_json", + "dep:base64", +] +regex = ["dep:regex"] + +[lib] +name = "cel" +path = "src/lib.rs" + +[[bench]] +name = "runtime" +path = "benches/runtime.rs" +harness = false + +[dependencies.antlr4rust] +version = "0.3.0-rc2" + +[dependencies.arbitrary] +version = "1.4.1" +features = ["derive"] +optional = true + +[dependencies.base64] +version = "0.22.1" +optional = true + +[dependencies.chrono] +version = "0.4" +features = [ + "alloc", + "serde", +] +optional = true +default-features = false + +[dependencies.lazy_static] +version = "1.5.0" + +[dependencies.nom] +version = "7.1.3" + +[dependencies.paste] +version = "1.0" + +[dependencies.regex] +version = "1.10.5" +optional = true + +[dependencies.serde] +version = "1.0" + +[dependencies.serde_json] +version = "1.0" +optional = true + +[dependencies.thiserror] +version = "1.0" + +[dev-dependencies.criterion] +version = "0.5.1" +features = ["html_reports"] + +[dev-dependencies.dhat] +version = "0.3.3" + +[dev-dependencies.serde_bytes] +version = "0.11.14" diff --git a/vendor/cel/Cargo.toml.orig b/vendor/cel/Cargo.toml.orig new file mode 100644 index 0000000..b0c902b --- /dev/null +++ b/vendor/cel/Cargo.toml.orig @@ -0,0 +1,40 @@ +[package] +name = "cel" +description = "A parser and interpreter for the Common Expression Language (CEL)" +repository = "https://github.com/cel-rust/cel-rust" +version = "0.11.4" +authors = ["Clark McCauley ", "Alex Snaps "] +edition = "2021" +license = "MIT" +categories = ["compilers"] + +[dependencies] +antlr4rust = "0.3.0-rc2" +lazy_static = "1.5.0" +nom = "7.1.3" +chrono = { version = "0.4", default-features = false, features = ["alloc", "serde"], optional = true } +regex = { version = "1.10.5", optional = true } +serde = "1.0" +serde_json = { version = "1.0", optional = true } +base64 = { version = "0.22.1", optional = true } + +thiserror = "1.0" +paste = "1.0" +arbitrary = { version = "1.4.1", optional = true, features = ["derive"] } + +[dev-dependencies] +criterion = { version = "0.5.1", features = ["html_reports"] } +serde_bytes = "0.11.14" +dhat = { version = "0.3.3" } + +[[bench]] +name = "runtime" +harness = false + +[features] +default = ["regex", "chrono"] +json = ["dep:serde_json", "dep:base64"] +regex = ["dep:regex"] +chrono = ["dep:chrono"] +arbitrary = ["dep:arbitrary", "chrono?/arbitrary", "chrono?/std"] +dhat-heap = [ ] # if you are doing heap profiling diff --git a/vendor/cel/README.md b/vendor/cel/README.md new file mode 100644 index 0000000..5f06a74 --- /dev/null +++ b/vendor/cel/README.md @@ -0,0 +1,55 @@ +# Common Expression Language (Rust) + +[![Rust](https://github.com/cel-rust/cel-rust/actions/workflows/rust.yml/badge.svg)](https://github.com/cel-rust/cel-rust/actions/workflows/rust.yml) + +The [Common Expression Language (CEL)](https://github.com/google/cel-spec) is a non-Turing complete language designed +for simplicity, speed, safety, and +portability. CEL's C-like syntax looks nearly identical to equivalent expressions in C++, Go, Java, and TypeScript. CEL +is ideal for lightweight expression evaluation when a fully sandboxed scripting language is too resource intensive. + +```java +// Check whether a resource name starts with a group name. +resource.name.startsWith("/groups/" + auth.claims.group) +``` + +```go +// Determine whether the request is in the permitted time window. +request.time - resource.age < duration("24h") +``` + +```typescript +// Check whether all resource names in a list match a given filter. +auth.claims.email_verified && resources.all(r, r.startsWith(auth.claims.email)) +``` + +## Getting Started + +Add `cel` to your `Cargo.toml`: + +```toml +[dependencies] +cel = "0.11.0" +``` + +Create and execute a simple CEL expression: + +```rust +use cel::{Context, Program}; + +fn main() { + let program = Program::compile("add(2, 3) == 5").unwrap(); + let mut context = Context::default(); + context.add_function("add", |a: i64, b: i64| a + b); + let value = program.execute(&context).unwrap(); + assert_eq!(value, true.into()); +} +``` + +### Examples + +Check out these other examples to learn how to use this library: + +- [Simple](./example/src/simple.rs) - A simple example of how to use the library. +- [Variables](./example/src/variables.rs) - Passing variables and using them in your program. +- [Functions](./example/src/functions.rs) - Defining and using custom functions in your program. +- [Concurrent Execution](./example/src/threads.rs) - Executing the same program concurrently. diff --git a/vendor/cel/benches/runtime.rs b/vendor/cel/benches/runtime.rs new file mode 100644 index 0000000..b530c0a --- /dev/null +++ b/vendor/cel/benches/runtime.rs @@ -0,0 +1,108 @@ +use cel::context::Context; +use cel::Program; +use criterion::{black_box, criterion_group, BenchmarkId, Criterion}; +use std::collections::HashMap; + +const EXPRESSIONS: [(&str, &str); 34] = [ + ("ternary_1", "(1 || 2) ? 1 : 2"), + ("ternary_2", "(1 ? 2 : 3) ? 1 : 2"), + ("or_1", "1 || 2"), + ("and_1", "1 && 2"), + ("and_2", "1 && (false ? 2 : 3)"), + ("number", "1"), + ("construct_list", "[1,2,3]"), + ("construct_list_1", "[1]"), + ("construct_list_2", "[1, 2]"), + ("add_list", "[1,2,3] + [4, 5, 6]"), + ("list_element", "[1,2,3][1]"), + ("construct_dict", "{1: 2, '3': '4'}"), + ("add_string", "'abc' + 'def'"), + ("list", "[1,2,3, Now, ]"), + ("mapexpr", "{1 + a: 3}"), + ("map_merge", "{'a': 1} + {'a': 2, 'b': 3}"), + ("size_list", "[1].size()"), + ("size_list_1", "size([1])"), + ("size_str", "'a'.size()"), + ("size_str_2", "size('a')"), + ("size_map", "{1:2}.size()"), + ("size_map_2", "size({1:2})"), + ("member", "foo.bar"), + ("map has", "has(foo.bar.baz)"), + ("map macro", "[1, 2, 3].map(x, x * 2)"), + ("filter macro", "[1, 2, 3].filter(x, x > 2)"), + ("all macro", "[1, 2, 3].all(x, x > 0)"), + ("all map macro", "{0: 0, 1:1, 2:2}.all(x, x >= 0)"), + ("max", "max(1, 2, 3)"), + ("max negative", "max(-1, 0, 1)"), + ("max float", "max(-1.0, 0.0, 1.0)"), + ("duration", "duration('1s')"), + ("timestamp", "timestamp('2023-05-28T00:00:00Z')"), // ("complex", "Account{user_id: 123}.user_id == 123"), + ("stress", "true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true && true") +]; + +pub fn criterion_benchmark(c: &mut Criterion) { + // https://gist.github.com/rhnvrm/db4567fcd87b2cb8e997999e1366d406 + let mut execution_group = c.benchmark_group("execute"); + for (name, expr) in black_box(&EXPRESSIONS) { + execution_group.bench_function(BenchmarkId::from_parameter(name), |b| { + let program = Program::compile(expr).expect("Parsing failed"); + let mut ctx = Context::default(); + ctx.add_variable_from_value("foo", HashMap::from([("bar", 1)])); + b.iter(|| program.execute(&ctx)) + }); + } +} + +pub fn criterion_benchmark_parsing(c: &mut Criterion) { + let mut parsing_group = c.benchmark_group("parse"); + for (name, expr) in black_box(&EXPRESSIONS) { + parsing_group.bench_function(BenchmarkId::from_parameter(name), |b| { + b.iter(|| Program::compile(expr).expect("Parsing failed")) + }); + } +} + +pub fn map_macro_benchmark(c: &mut Criterion) { + let mut group = c.benchmark_group("map list"); + let sizes = vec![1, 10, 100, 1000, 10000, 100000]; + + for size in sizes { + group.bench_function(format!("map_{size}").as_str(), |b| { + let list = (0..size).collect::>(); + let program = Program::compile("list.map(x, x * 2)").unwrap(); + let mut ctx = Context::default(); + ctx.add_variable_from_value("list", list); + b.iter(|| program.execute(&ctx).unwrap()) + }); + } + group.finish(); +} + +criterion_group! { + name = benches; + config = Criterion::default(); + targets = criterion_benchmark, criterion_benchmark_parsing, map_macro_benchmark +} + +#[cfg(feature = "dhat-heap")] +#[global_allocator] +static ALLOC: dhat::Alloc = dhat::Alloc; + +/// This is the following macro expanded: +/// criterion_main!(benches); +/// But expanded manually so that we can keep the dhat profiler in scope until after benchmarks run +fn main() { + #[cfg(feature = "dhat-heap")] + let profiler = dhat::Profiler::new_heap(); + + benches(); + // If adding new criterion groups, do so here. + + // Dropping the dhat profiler prints information to stderr: https://docs.rs/dhat/latest/dhat/ + // Doing so before the below ensures profiler doesn't measure Criterion's summary code. + // It still may measure other bits of Criterion during the benchmark, of course.. + #[cfg(feature = "dhat-heap")] + drop(profiler); + + Criterion::default().configure_from_args().final_summary(); +} diff --git a/vendor/cel/src/common/ast/mod.rs b/vendor/cel/src/common/ast/mod.rs new file mode 100644 index 0000000..6318751 --- /dev/null +++ b/vendor/cel/src/common/ast/mod.rs @@ -0,0 +1,158 @@ +use crate::common::value::CelVal; +use std::collections::BTreeMap; + +pub mod operators; + +pub struct Ast { + pub expr: IdedExpr, +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub enum Expr { + #[default] + /// UnspecifiedExprKind represents an unset expression with no specified properties. + Unspecified, + + /// CallKind represents a function call. + Call(CallExpr), + + /// ComprehensionKind represents a comprehension expression generated by a macro. + Comprehension(Box), + + /// IdentKind represents a simple variable, constant, or type identifier. + Ident(String), + + /// ListKind represents a list literal expression. + List(ListExpr), + + /// LiteralKind represents a primitive scalar literal. + Literal(CelVal), + + /// MapKind represents a map literal expression. + Map(MapExpr), + + /// SelectKind represents a field selection expression. + Select(SelectExpr), + + /// StructKind represents a struct literal expression. + Struct(StructExpr), +} + +#[derive(Clone, Debug, PartialEq)] +pub enum EntryExpr { + StructField(StructFieldExpr), + MapEntry(MapEntryExpr), +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct IdedExpr { + pub id: u64, + pub expr: Expr, +} + +#[derive(Clone, Debug, PartialEq)] +pub struct IdedEntryExpr { + pub id: u64, + pub expr: EntryExpr, +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct CallExpr { + pub func_name: String, + pub target: Option>, + pub args: Vec, +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct SelectExpr { + pub operand: Box, + pub field: String, + pub test: bool, +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct StructExpr { + pub type_name: String, + pub entries: Vec, +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct MapExpr { + pub entries: Vec, +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct ListExpr { + pub elements: Vec, +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct StructFieldExpr { + pub field: String, + pub value: IdedExpr, + pub optional: bool, +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct MapEntryExpr { + pub key: IdedExpr, + pub value: IdedExpr, + pub optional: bool, +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct ComprehensionExpr { + pub iter_range: IdedExpr, + pub iter_var: String, + pub iter_var2: Option, + pub accu_var: String, + pub accu_init: IdedExpr, + pub loop_cond: IdedExpr, + pub loop_step: IdedExpr, + pub result: IdedExpr, +} + +#[derive(Debug, Default)] +pub struct SourceInfo { + offsets: BTreeMap, + pub source: String, +} + +impl SourceInfo { + pub fn add_offset(&mut self, id: u64, start: u32, stop: u32) { + self.offsets.insert(id, OffsetRange { start, stop }); + } + + pub fn offset_for(&self, id: u64) -> Option<(u32, u32)> { + self.offsets.get(&id).map(|range| (range.start, range.stop)) + } + + pub(crate) fn pos_for(&self, id: u64) -> Option<(isize, isize)> { + match self.offset_for(id) { + Some((start, _)) => { + let start = start as isize; + let mut offset = 0; + let mut line = 0; + for l in self.source.split_inclusive('\n') { + line += 1; + offset += l.len() as isize; + if start < offset { + return Some((line, start + (l.len() as isize) - offset + 1)); + } + } + None + } + None => None, + } + } + + pub fn snippet(&self, line: isize) -> Option<&str> { + self.source.lines().nth(line as usize) + } +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct OffsetRange { + pub start: u32, + pub stop: u32, +} diff --git a/vendor/cel/src/common/ast/operators.rs b/vendor/cel/src/common/ast/operators.rs new file mode 100644 index 0000000..8ce3cad --- /dev/null +++ b/vendor/cel/src/common/ast/operators.rs @@ -0,0 +1,53 @@ +pub fn find_operator(input: &str) -> Option<&str> { + for (op, operator) in OPERATORS { + if op == input { + return Some(operator); + } + } + None +} + +pub const CONDITIONAL: &str = "_?_:_"; +pub const LOGICAL_AND: &str = "_&&_"; +pub const LOGICAL_OR: &str = "_||_"; +pub const LOGICAL_NOT: &str = "!_"; +pub const SUBSTRACT: &str = "_-_"; +pub const ADD: &str = "_+_"; +pub const MULTIPLY: &str = "_*_"; +pub const DIVIDE: &str = "_/_"; +pub const MODULO: &str = "_%_"; +pub const EQUALS: &str = "_==_"; +pub const NOT_EQUALS: &str = "_!=_"; +pub const GREATER_EQUALS: &str = "_>=_"; +pub const LESS_EQUALS: &str = "_<=_"; +pub const GREATER: &str = "_>_"; +pub const LESS: &str = "_<_"; +pub const NEGATE: &str = "-_"; +pub const INDEX: &str = "_[_]"; +pub const OPT_INDEX: &str = "_[?_]"; +pub const OPT_SELECT: &str = "_?._"; + +pub const EXISTS_ONE: &str = "exists_one"; +pub const HAS: &str = "has"; +pub const ALL: &str = "all"; +pub const EXISTS: &str = "exists"; +pub const MAP: &str = "map"; +pub const FILTER: &str = "filter"; + +pub const NOT_STRICTLY_FALSE: &str = "@not_strictly_false"; +pub const IN: &str = "@in"; + +const OPERATORS: [(&str, &str); 12] = [ + ("-", SUBSTRACT), + ("+", ADD), + ("*", MULTIPLY), + ("/", DIVIDE), + ("%", MODULO), + ("==", EQUALS), + ("!=", NOT_EQUALS), + (">=", GREATER_EQUALS), + ("<=", LESS_EQUALS), + (">", GREATER), + ("<", LESS), + ("in", IN), +]; diff --git a/vendor/cel/src/common/mod.rs b/vendor/cel/src/common/mod.rs new file mode 100644 index 0000000..5a2b0d2 --- /dev/null +++ b/vendor/cel/src/common/mod.rs @@ -0,0 +1,4 @@ +pub mod ast; +pub mod traits; +pub mod types; +pub mod value; diff --git a/vendor/cel/src/common/traits.rs b/vendor/cel/src/common/traits.rs new file mode 100644 index 0000000..8901a7b --- /dev/null +++ b/vendor/cel/src/common/traits.rs @@ -0,0 +1,47 @@ +/// ADDER_TYPE types provide a '+' operator overload. +pub const ADDER_TYPE: u16 = 1; + +/// COMPARER_TYPE types support ordering comparisons '<', '<=', '>', '>='. +pub const COMPARER_TYPE: u16 = ADDER_TYPE << 1; + +/// CONTAINER_TYPE types support 'in' operations. +pub const CONTAINER_TYPE: u16 = COMPARER_TYPE << 1; + +/// DIVIDER_TYPE types support '/' operations. +pub const DIVIDER_TYPE: u16 = CONTAINER_TYPE << 1; + +/// FIELD_TESTER_TYPE types support the detection of field value presence. +pub const FIELD_TESTER_TYPE: u16 = DIVIDER_TYPE << 1; + +/// INDEXER_TYPE types support index access with dynamic values. +pub const INDEXER_TYPE: u16 = FIELD_TESTER_TYPE << 1; + +/// ITERABLE_TYPE types can be iterated over in comprehensions. +pub const ITERABLE_TYPE: u16 = INDEXER_TYPE << 1; + +/// ITERATOR_TYPE types support iterator semantics. +pub const ITERATOR_TYPE: u16 = ITERABLE_TYPE << 1; + +/// MATCHER_TYPE types support pattern matching via 'matches' method. +pub const MATCHER_TYPE: u16 = ITERATOR_TYPE << 1; + +/// MODDER_TYPE types support modulus operations '%' +pub const MODDER_TYPE: u16 = MATCHER_TYPE << 1; + +/// MULTIPLIER_TYPE types support '*' operations. +pub const MULTIPLIER_TYPE: u16 = MODDER_TYPE << 1; + +/// NEGATOR_TYPE types support either negation via '!' or '-' +pub const NEGATOR_TYPE: u16 = MULTIPLIER_TYPE << 1; + +/// RECEIVER_TYPE types support dynamic dispatch to instance methods. +pub const RECEIVER_TYPE: u16 = NEGATOR_TYPE << 1; + +/// SIZER_TYPE types support the size() method. +pub const SIZER_TYPE: u16 = RECEIVER_TYPE << 1; + +/// SUBTRACTOR_TYPE types support '-' operations. +pub const SUBTRACTOR_TYPE: u16 = SIZER_TYPE << 1; + +/// FOLDABLE_TYPE types support comprehensions v2 macros which iterate over (key, value) pairs. +pub const FOLDABLE_TYPE: u16 = SUBTRACTOR_TYPE << 1; diff --git a/vendor/cel/src/common/types/bool.rs b/vendor/cel/src/common/types/bool.rs new file mode 100644 index 0000000..904bef2 --- /dev/null +++ b/vendor/cel/src/common/types/bool.rs @@ -0,0 +1,58 @@ +use crate::common::types::Type; +use crate::common::value::Val; +use std::any::Any; + +#[derive(Clone, Debug, PartialEq)] +pub struct Bool(bool); + +impl Val for Bool { + fn get_type(&self) -> Type<'_> { + super::BOOL_TYPE + } + + fn into_inner(self) -> Box { + Box::new(self.0) + } +} + +impl From for bool { + fn from(value: Bool) -> Self { + value.0 + } +} + +impl From for Bool { + fn from(value: bool) -> Self { + Bool(value) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::common::types; + use crate::common::types::Kind; + + #[test] + fn test_from() { + let value: Bool = true.into(); + let v: bool = value.into(); + assert!(v) + } + + #[test] + fn test_type() { + let value = Bool(true); + assert_eq!(value.get_type(), types::BOOL_TYPE); + assert_eq!(value.get_type().kind, Kind::Boolean); + } + + #[test] + fn test_into_inner() { + let value = Bool(true); + let inner = value.into_inner(); + let option = inner.downcast::(); + let b = option.unwrap(); + assert!(*b); + } +} diff --git a/vendor/cel/src/common/types/bytes.rs b/vendor/cel/src/common/types/bytes.rs new file mode 100644 index 0000000..261ebc7 --- /dev/null +++ b/vendor/cel/src/common/types/bytes.rs @@ -0,0 +1,27 @@ +use crate::common::types::Type; +use crate::common::value::Val; +use std::any::Any; + +pub struct Bytes(Vec); + +impl Val for Bytes { + fn get_type(&self) -> Type<'_> { + super::BYTES_TYPE + } + + fn into_inner(self) -> Box { + Box::new(self.0) + } +} + +impl From> for Bytes { + fn from(value: Vec) -> Self { + Bytes(value) + } +} + +impl From for Vec { + fn from(value: Bytes) -> Self { + value.0 + } +} diff --git a/vendor/cel/src/common/types/double.rs b/vendor/cel/src/common/types/double.rs new file mode 100644 index 0000000..9755faa --- /dev/null +++ b/vendor/cel/src/common/types/double.rs @@ -0,0 +1,27 @@ +use crate::common::types::Type; +use crate::common::value::Val; +use std::any::Any; + +pub struct Double(f64); + +impl Val for Double { + fn get_type(&self) -> Type<'_> { + super::DOUBLE_TYPE + } + + fn into_inner(self) -> Box { + Box::new(self.0) + } +} + +impl From for f64 { + fn from(value: Double) -> Self { + value.0 + } +} + +impl From for Double { + fn from(value: f64) -> Self { + Self(value) + } +} diff --git a/vendor/cel/src/common/types/duration.rs b/vendor/cel/src/common/types/duration.rs new file mode 100644 index 0000000..16f6310 --- /dev/null +++ b/vendor/cel/src/common/types/duration.rs @@ -0,0 +1,28 @@ +use crate::common::types::Type; +use crate::common::value::Val; +use std::any::Any; +use std::time::Duration as StdDuration; + +pub struct Duration(StdDuration); + +impl Val for Duration { + fn get_type(&self) -> Type<'_> { + super::DURATION_TYPE + } + + fn into_inner(self) -> Box { + Box::new(self.0) + } +} + +impl From for Duration { + fn from(duration: StdDuration) -> Self { + Self(duration) + } +} + +impl From for StdDuration { + fn from(duration: Duration) -> Self { + duration.0 + } +} diff --git a/vendor/cel/src/common/types/int.rs b/vendor/cel/src/common/types/int.rs new file mode 100644 index 0000000..fc13e03 --- /dev/null +++ b/vendor/cel/src/common/types/int.rs @@ -0,0 +1,27 @@ +use crate::common::types::Type; +use crate::common::value::Val; +use std::any::Any; + +pub struct Int(i64); + +impl Val for Int { + fn get_type(&self) -> Type<'_> { + super::INT_TYPE + } + + fn into_inner(self) -> Box { + Box::new(self.0) + } +} + +impl From for i64 { + fn from(value: Int) -> Self { + value.0 + } +} + +impl From for Int { + fn from(value: i64) -> Self { + Self(value) + } +} diff --git a/vendor/cel/src/common/types/mod.rs b/vendor/cel/src/common/types/mod.rs new file mode 100644 index 0000000..4eb5ec7 --- /dev/null +++ b/vendor/cel/src/common/types/mod.rs @@ -0,0 +1,255 @@ +use crate::common::traits; + +mod bool; +mod bytes; +mod double; +mod duration; +mod int; +mod null; +mod optional; +mod string; +mod timestamp; +mod uint; + +pub use bool::Bool; +pub use bytes::Bytes; +pub use double::Double; +pub use duration::Duration; +pub use int::Int; +pub use null::Null; +pub use string::String; +pub use timestamp::Timestamp; +pub use uint::UInt; + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum Kind { + Unspecified, + Error, + Dyn, + Any, + Boolean, + Bytes, + Double, + Duration, + Int, + List, + Map, + NullType, + Opaque, + String, + Struct, + Timestamp, + Type, + TypeParam, + UInt, + Unknown, +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Type<'a> { + kind: Kind, + parameters: &'a [&'a Type<'a>], + runtime_type_name: &'a str, + trait_mask: u16, +} + +pub const ANY_TYPE: Type = Type { + kind: Kind::Any, + parameters: &[], + runtime_type_name: "google.protobuf.Any", + trait_mask: traits::FIELD_TESTER_TYPE | traits::INDEXER_TYPE, +}; + +pub const BOOL_TYPE: Type = Type { + kind: Kind::Boolean, + parameters: &[], + runtime_type_name: "bool", + trait_mask: traits::COMPARER_TYPE | traits::NEGATOR_TYPE, +}; + +pub const BYTES_TYPE: Type = Type { + kind: Kind::Bytes, + parameters: &[], + runtime_type_name: "bytes", + trait_mask: traits::ADDER_TYPE | traits::COMPARER_TYPE | traits::SIZER_TYPE, +}; + +pub const DOUBLE_TYPE: Type = Type { + kind: Kind::Double, + parameters: &[], + runtime_type_name: "double", + trait_mask: traits::ADDER_TYPE + | traits::COMPARER_TYPE + | traits::DIVIDER_TYPE + | traits::MULTIPLIER_TYPE + | traits::NEGATOR_TYPE + | traits::SUBTRACTOR_TYPE, +}; + +pub const DURATION_TYPE: Type = Type { + kind: Kind::Duration, + parameters: &[], + runtime_type_name: "google.protobuf.Duration", + trait_mask: traits::ADDER_TYPE + | traits::COMPARER_TYPE + | traits::NEGATOR_TYPE + | traits::RECEIVER_TYPE + | traits::SUBTRACTOR_TYPE, +}; + +pub const DYN_TYPE: Type = Type::simple_type(Kind::Dyn, "dyn"); + +pub const ERROR_TYPE: Type = Type::simple_type(Kind::Error, "error"); + +pub const INT_TYPE: Type = Type { + kind: Kind::Int, + parameters: &[], + runtime_type_name: "int", + trait_mask: traits::ADDER_TYPE + | traits::COMPARER_TYPE + | traits::DIVIDER_TYPE + | traits::MODDER_TYPE + | traits::MULTIPLIER_TYPE + | traits::NEGATOR_TYPE + | traits::SUBTRACTOR_TYPE, +}; + +pub const LIST_TYPE: Type = Type::new_list_type(&[&DYN_TYPE]); + +pub const MAP_TYPE: Type = Type::new_map_type(&[&DYN_TYPE, &DYN_TYPE]); + +pub const NULL_TYPE: Type = Type::simple_type(Kind::NullType, "null_type"); + +pub const STRING_TYPE: Type = Type { + kind: Kind::String, + parameters: &[], + runtime_type_name: "string", + trait_mask: traits::ADDER_TYPE + | traits::COMPARER_TYPE + | traits::MATCHER_TYPE + | traits::RECEIVER_TYPE + | traits::SIZER_TYPE, +}; + +pub const TIMESTAMP_TYPE: Type = Type { + kind: Kind::Timestamp, + parameters: &[], + runtime_type_name: "google.protobuf.Timestamp", + trait_mask: traits::ADDER_TYPE + | traits::COMPARER_TYPE + | traits::RECEIVER_TYPE + | traits::SUBTRACTOR_TYPE, +}; + +pub const TYPE_TYPE: Type = Type::simple_type(Kind::Type, "type"); + +pub const UINT_TYPE: Type = Type { + kind: Kind::UInt, + parameters: &[], + runtime_type_name: "uint", + trait_mask: traits::ADDER_TYPE + | traits::COMPARER_TYPE + | traits::DIVIDER_TYPE + | traits::MODDER_TYPE + | traits::MULTIPLIER_TYPE + | traits::SUBTRACTOR_TYPE, +}; + +pub const UNKNOWN_TYPE: Type = Type::simple_type(Kind::Unknown, "unknown"); + +impl<'a> Type<'a> { + pub const fn simple_type(kind: Kind, name: &str) -> Type<'_> { + Type { + kind, + parameters: &[], + runtime_type_name: name, + trait_mask: 0, + } + } + + pub const fn new_list_type<'b>(param: &'b [&'b Type<'b>; 1]) -> Type<'b> { + Type { + kind: Kind::List, + parameters: param, + runtime_type_name: "list", + trait_mask: traits::ADDER_TYPE + | traits::CONTAINER_TYPE + | traits::INDEXER_TYPE + | traits::ITERABLE_TYPE + | traits::SIZER_TYPE, + } + } + + pub const fn new_map_type<'b>(param: &'b [&'b Type<'b>; 2]) -> Type<'b> { + Type { + kind: Kind::Map, + parameters: param, + runtime_type_name: "map", + trait_mask: traits::CONTAINER_TYPE + | traits::INDEXER_TYPE + | traits::ITERABLE_TYPE + | traits::SIZER_TYPE, + } + } + + pub const fn new_unspecified_type(name: &str) -> Type<'_> { + Type { + kind: Kind::Unspecified, + parameters: &[], + runtime_type_name: name, + trait_mask: 0, + } + } + + pub const fn new_opaque_type(name: &str) -> Type<'_> { + Type { + kind: Kind::Opaque, + parameters: &[], + runtime_type_name: name, + trait_mask: 0, + } + } + + pub fn name(&self) -> &'a str { + self.runtime_type_name + } + + pub fn has_trait(&self, t: u16) -> bool { + self.trait_mask & t == t + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parameterized_type() { + let param = Type { + kind: Kind::Unspecified, + parameters: &[], + runtime_type_name: "", + trait_mask: 0, + }; + + let t = std::string::String::from("List"); + let parameterized_list = Type { + kind: Kind::List, + parameters: &[¶m], + runtime_type_name: &t, + trait_mask: 0, + }; + assert_eq!(¶m, parameterized_list.parameters[0]); + + let params = [¶m]; + let list2 = Type::new_list_type(¶ms); + assert_eq!(¶m, list2.parameters[0]); + assert_eq!(1, list2.parameters.len()); + + let params = [¶m, ¶m]; + let map = Type::new_map_type(¶ms); + assert_eq!(¶m, map.parameters[0]); + assert_eq!(¶m, map.parameters[1]); + assert_eq!(2, map.parameters.len()); + } +} diff --git a/vendor/cel/src/common/types/null.rs b/vendor/cel/src/common/types/null.rs new file mode 100644 index 0000000..fe482c1 --- /dev/null +++ b/vendor/cel/src/common/types/null.rs @@ -0,0 +1,15 @@ +use crate::common::types::Type; +use crate::common::value::Val; +use std::any::Any; + +pub struct Null; + +impl Val for Null { + fn get_type(&self) -> Type<'_> { + super::NULL_TYPE + } + + fn into_inner(self) -> Box { + Box::new(None::<()>) + } +} diff --git a/vendor/cel/src/common/types/optional.rs b/vendor/cel/src/common/types/optional.rs new file mode 100644 index 0000000..aed432f --- /dev/null +++ b/vendor/cel/src/common/types/optional.rs @@ -0,0 +1,32 @@ +use crate::common::types::Type; +use crate::common::value::Val; +use std::any::Any; + +pub struct Optional(Option>); + +const OPTIONAL_TYPE: Type = Type::new_opaque_type("optional_type"); + +impl Val for Optional { + fn get_type(&self) -> Type<'_> { + OPTIONAL_TYPE + } + + fn into_inner(self) -> Box { + match self.0 { + None => Box::new(None::<()>), + Some(v) => Box::new(Some(v)), + } + } +} + +impl From>> for Optional { + fn from(val: Option>) -> Self { + Optional(val) + } +} + +impl From for Option> { + fn from(val: Optional) -> Option> { + val.0 + } +} diff --git a/vendor/cel/src/common/types/string.rs b/vendor/cel/src/common/types/string.rs new file mode 100644 index 0000000..14a0afd --- /dev/null +++ b/vendor/cel/src/common/types/string.rs @@ -0,0 +1,28 @@ +use crate::common::types::Type; +use crate::common::value::Val; +use std::any::Any; +use std::string::String as StdString; + +pub struct String(StdString); + +impl Val for String { + fn get_type(&self) -> Type<'_> { + super::STRING_TYPE + } + + fn into_inner(self) -> Box { + Box::new(self.0) + } +} + +impl From for String { + fn from(v: StdString) -> Self { + Self(v) + } +} + +impl From for StdString { + fn from(v: String) -> Self { + v.0 + } +} diff --git a/vendor/cel/src/common/types/timestamp.rs b/vendor/cel/src/common/types/timestamp.rs new file mode 100644 index 0000000..8243e6c --- /dev/null +++ b/vendor/cel/src/common/types/timestamp.rs @@ -0,0 +1,28 @@ +use crate::common::types::Type; +use crate::common::value::Val; +use std::any::Any; +use std::time::SystemTime; + +pub struct Timestamp(SystemTime); + +impl Val for Timestamp { + fn get_type(&self) -> Type<'_> { + super::TIMESTAMP_TYPE + } + + fn into_inner(self) -> Box { + Box::new(self.0) + } +} + +impl From for Timestamp { + fn from(system_time: SystemTime) -> Self { + Self(system_time) + } +} + +impl From for SystemTime { + fn from(timestamp: Timestamp) -> Self { + timestamp.0 + } +} diff --git a/vendor/cel/src/common/types/uint.rs b/vendor/cel/src/common/types/uint.rs new file mode 100644 index 0000000..07cec4e --- /dev/null +++ b/vendor/cel/src/common/types/uint.rs @@ -0,0 +1,27 @@ +use crate::common::types::Type; +use crate::common::value::Val; +use std::any::Any; + +pub struct UInt(u64); + +impl Val for UInt { + fn get_type(&self) -> Type<'_> { + super::UINT_TYPE + } + + fn into_inner(self) -> Box { + Box::new(self.0) + } +} + +impl From for u64 { + fn from(value: UInt) -> Self { + value.0 + } +} + +impl From for UInt { + fn from(value: u64) -> Self { + Self(value) + } +} diff --git a/vendor/cel/src/common/value.rs b/vendor/cel/src/common/value.rs new file mode 100644 index 0000000..730b8c6 --- /dev/null +++ b/vendor/cel/src/common/value.rs @@ -0,0 +1,78 @@ +use crate::common::types; +use crate::common::types::Type; +use std::any::Any; +use std::fmt::Debug; +use std::time::{Duration, SystemTime}; + +#[derive(Clone, Debug, PartialEq)] +pub enum CelVal { + Unspecified, + Error, + Dyn, + Any, + Boolean(bool), + Bytes(Vec), + Double(f64), + Duration(Duration), + Int(i64), + List, + Map, + Null, + String(String), + Timestamp(SystemTime), + Type, + UInt(u64), + Unknown, +} + +pub trait Val { + fn get_type(&self) -> Type<'_>; + + fn into_inner(self) -> Box; +} + +impl Val for CelVal { + fn get_type(&self) -> Type<'_> { + match self { + CelVal::Unspecified => Type::new_unspecified_type("unspecified"), + CelVal::Error => types::ERROR_TYPE, + CelVal::Dyn => types::DYN_TYPE, + CelVal::Any => types::ANY_TYPE, + CelVal::Boolean(_) => types::BOOL_TYPE, + CelVal::Bytes(_) => types::BYTES_TYPE, + CelVal::Double(_) => types::DOUBLE_TYPE, + CelVal::Duration(_) => types::DURATION_TYPE, + CelVal::Int(_) => types::INT_TYPE, + CelVal::List => types::LIST_TYPE, + CelVal::Map => types::MAP_TYPE, + CelVal::Null => types::NULL_TYPE, + CelVal::String(_) => types::STRING_TYPE, + CelVal::Timestamp(_) => types::TIMESTAMP_TYPE, + CelVal::Type => types::TYPE_TYPE, + CelVal::UInt(_) => types::UINT_TYPE, + CelVal::Unknown => types::UNKNOWN_TYPE, + } + } + + fn into_inner(self) -> Box { + match self { + CelVal::Unspecified => todo!(), + CelVal::Error => todo!(), + CelVal::Dyn => todo!(), + CelVal::Any => todo!(), + CelVal::Boolean(b) => Box::new(b), + CelVal::Bytes(b) => Box::new(b), + CelVal::Double(d) => Box::new(d), + CelVal::Duration(d) => Box::new(d), + CelVal::Int(i) => Box::new(i), + CelVal::List => todo!(), + CelVal::Map => todo!(), + CelVal::Null => todo!(), + CelVal::String(s) => Box::new(s), + CelVal::Timestamp(t) => Box::new(t), + CelVal::Type => todo!(), + CelVal::UInt(u) => Box::new(u), + CelVal::Unknown => todo!(), + } + } +} diff --git a/vendor/cel/src/context.rs b/vendor/cel/src/context.rs new file mode 100644 index 0000000..7fbbd77 --- /dev/null +++ b/vendor/cel/src/context.rs @@ -0,0 +1,187 @@ +use crate::magic::{Function, FunctionRegistry, IntoFunction}; +use crate::objects::{TryIntoValue, Value}; +use crate::parser::Expression; +use crate::{functions, ExecutionError}; +use std::collections::HashMap; + +/// Context is a collection of variables and functions that can be used +/// by the interpreter to resolve expressions. +/// +/// The context can be either a parent context, or a child context. A +/// parent context is created by default and contains all of the built-in +/// functions. A child context can be created by calling `.clone()`. The +/// child context has it's own variables (which can be added to), but it +/// will also reference the parent context. This allows for variables to +/// be overridden within the child context while still being able to +/// resolve variables in the child's parents. You can have theoretically +/// have an infinite number of child contexts that reference each-other. +/// +/// So why is this important? Well some CEL-macros such as the `.map` macro +/// declare intermediate user-specified identifiers that should only be +/// available within the macro, and should not override variables in the +/// parent context. The `.map` macro can clone the parent context, add the +/// intermediate identifier to the child context, and then evaluate the +/// map expression. +/// +/// Intermediate variable stored in child context +/// ↓ +/// [1, 2, 3].map(x, x * 2) == [2, 4, 6] +/// ↑ +/// Only in scope for the duration of the map expression +/// +pub enum Context<'a> { + Root { + functions: FunctionRegistry, + variables: HashMap, + }, + Child { + parent: &'a Context<'a>, + variables: HashMap, + }, +} + +impl Context<'_> { + pub fn add_variable( + &mut self, + name: S, + value: V, + ) -> Result<(), ::Error> + where + S: Into, + V: TryIntoValue, + { + match self { + Context::Root { variables, .. } => { + variables.insert(name.into(), value.try_into_value()?); + } + Context::Child { variables, .. } => { + variables.insert(name.into(), value.try_into_value()?); + } + } + Ok(()) + } + + pub fn add_variable_from_value(&mut self, name: S, value: V) + where + S: Into, + V: Into, + { + match self { + Context::Root { variables, .. } => { + variables.insert(name.into(), value.into()); + } + Context::Child { variables, .. } => { + variables.insert(name.into(), value.into()); + } + } + } + + pub fn get_variable(&self, name: S) -> Result + where + S: AsRef, + { + let name = name.as_ref(); + match self { + Context::Child { variables, parent } => variables + .get(name) + .cloned() + .or_else(|| parent.get_variable(name).ok()) + .ok_or_else(|| ExecutionError::UndeclaredReference(name.to_string().into())), + Context::Root { variables, .. } => variables + .get(name) + .cloned() + .ok_or_else(|| ExecutionError::UndeclaredReference(name.to_string().into())), + } + } + + pub(crate) fn get_function(&self, name: &str) -> Option<&Function> { + match self { + Context::Root { functions, .. } => functions.get(name), + Context::Child { parent, .. } => parent.get_function(name), + } + } + + pub fn add_function(&mut self, name: &str, value: F) + where + F: IntoFunction + 'static + Send + Sync, + { + if let Context::Root { functions, .. } = self { + functions.add(name, value); + }; + } + + pub fn resolve(&self, expr: &Expression) -> Result { + Value::resolve(expr, self) + } + + pub fn resolve_all(&self, exprs: &[Expression]) -> Result { + Value::resolve_all(exprs, self) + } + + pub fn new_inner_scope(&self) -> Context<'_> { + Context::Child { + parent: self, + variables: Default::default(), + } + } + + /// Constructs a new empty context with no variables or functions. + /// + /// If you're looking for a context that has all the standard methods, functions + /// and macros already added to the context, use [`Context::default`] instead. + /// + /// # Example + /// ``` + /// use cel::Context; + /// let mut context = Context::empty(); + /// context.add_function("add", |a: i64, b: i64| a + b); + /// ``` + pub fn empty() -> Self { + Context::Root { + variables: Default::default(), + functions: Default::default(), + } + } +} + +impl Default for Context<'_> { + fn default() -> Self { + let mut ctx = Context::Root { + variables: Default::default(), + functions: Default::default(), + }; + + ctx.add_function("contains", functions::contains); + ctx.add_function("size", functions::size); + ctx.add_function("max", functions::max); + ctx.add_function("min", functions::min); + ctx.add_function("startsWith", functions::starts_with); + ctx.add_function("endsWith", functions::ends_with); + ctx.add_function("string", functions::string); + ctx.add_function("bytes", functions::bytes); + ctx.add_function("double", functions::double); + ctx.add_function("int", functions::int); + ctx.add_function("uint", functions::uint); + + #[cfg(feature = "regex")] + ctx.add_function("matches", functions::matches); + + #[cfg(feature = "chrono")] + { + ctx.add_function("duration", functions::duration); + ctx.add_function("timestamp", functions::timestamp); + ctx.add_function("getFullYear", functions::time::timestamp_year); + ctx.add_function("getMonth", functions::time::timestamp_month); + ctx.add_function("getDayOfYear", functions::time::timestamp_year_day); + ctx.add_function("getDayOfMonth", functions::time::timestamp_month_day); + ctx.add_function("getDate", functions::time::timestamp_date); + ctx.add_function("getDayOfWeek", functions::time::timestamp_weekday); + ctx.add_function("getHours", functions::time::timestamp_hours); + ctx.add_function("getMinutes", functions::time::timestamp_minutes); + ctx.add_function("getSeconds", functions::time::timestamp_seconds); + ctx.add_function("getMilliseconds", functions::time::timestamp_millis); + } + + ctx + } +} diff --git a/vendor/cel/src/duration.rs b/vendor/cel/src/duration.rs new file mode 100644 index 0000000..b987181 --- /dev/null +++ b/vendor/cel/src/duration.rs @@ -0,0 +1,281 @@ +use chrono::Duration; +use nom::branch::alt; +use nom::bytes::complete::tag; +use nom::character::complete::char; +use nom::combinator::{map, opt}; +use nom::multi::many1; +use nom::number::complete::double; +use nom::IResult; + +// Constants representing time units in nanoseconds +const SECOND: u64 = 1_000_000_000; +const MILLISECOND: u64 = 1_000_000; +const MICROSECOND: u64 = 1_000; + +/// Parses a duration string into a [`Duration`]. Duration strings support the +/// following grammar: +/// +/// DurationString -> Sign? Number Unit String? +/// Sign -> '-' +/// Number -> Digit+ ('.' Digit+)? +/// Digit -> '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' +/// Unit -> 'h' | 'm' | 's' | 'ms' | 'us' | 'ns' +/// String -> DurationString +/// +/// # Examples +/// - `1h` parses as 1 hour +/// - `1.5h` parses as 1 hour and 30 minutes +/// - `1h30m` parses as 1 hour and 30 minutes +/// - `1h30m1s` parses as 1 hour, 30 minutes, and 1 second +/// - `1ms` parses as 1 millisecond +/// - `1.5ms` parses as 1 millisecond and 500 microseconds +/// - `1ns` parses as 1 nanosecond +/// - `1.5ns` parses as 1 nanosecond (sub-nanosecond durations not supported) +pub fn parse_duration(i: &str) -> IResult<&str, Duration> { + let (i, neg) = opt(parse_negative)(i)?; + if i == "0" { + return Ok((i, Duration::zero())); + } + let (i, duration) = many1(parse_number_unit)(i) + .map(|(i, d)| (i, d.iter().fold(Duration::zero(), |acc, next| acc + *next)))?; + Ok((i, duration * if neg.is_some() { -1 } else { 1 })) +} + +enum Unit { + Nanosecond, + Microsecond, + Millisecond, + Second, + Minute, + Hour, +} + +impl Unit { + fn nanos(&self) -> i64 { + match self { + Unit::Nanosecond => 1, + Unit::Microsecond => 1_000, + Unit::Millisecond => 1_000_000, + Unit::Second => 1_000_000_000, + Unit::Minute => 60 * 1_000_000_000, + Unit::Hour => 60 * 60 * 1_000_000_000, + } + } +} + +fn parse_number_unit(i: &str) -> IResult<&str, Duration> { + let (i, num) = double(i)?; + let (i, unit) = parse_unit(i)?; + let duration = to_duration(num, unit); + Ok((i, duration)) +} + +fn parse_negative(i: &str) -> IResult<&str, ()> { + let (i, _): (&str, char) = char('-')(i)?; + Ok((i, ())) +} + +fn parse_unit(i: &str) -> IResult<&str, Unit> { + alt(( + map(tag("ms"), |_| Unit::Millisecond), + map(tag("us"), |_| Unit::Microsecond), + map(tag("ns"), |_| Unit::Nanosecond), + map(char('h'), |_| Unit::Hour), + map(char('m'), |_| Unit::Minute), + map(char('s'), |_| Unit::Second), + ))(i) +} + +fn to_duration(num: f64, unit: Unit) -> Duration { + Duration::nanoseconds((num * unit.nanos() as f64).trunc() as i64) +} + +/// Formats a [`Duration`] into a string. String returns a string representing the +/// duration in the form "72h3m0.5s". Leading zero units are omitted. As a special +/// case, durations less than one second format use a smaller unit (milli-, micro-, +/// or nanoseconds) to ensure that the leading digit is non-zero. The zero duration +/// formats as 0s. +/// +/// This is a direct port of the Go version of the time.Duration(0).String() function. +pub fn format_duration(d: &Duration) -> String { + let buf = &mut [0u8; 32]; + let mut w = buf.len(); + + let mut neg = false; + let mut u = d + .num_nanoseconds() + .map(|n| { + if n < 0 { + neg = true; + } + n as u64 + }) + .unwrap_or_else(|| { + let s = d.num_seconds(); + if s < 0 { + neg = true; + } + s as u64 * SECOND + }); + + if u < SECOND { + // Special case: if duration is smaller than a second, + // use smaller units, like 1.2ms + let mut _prec = 0; + w -= 1; + buf[w] = b's'; + w -= 1; + + if u == 0 { + return "0s".to_string(); + } else if u < MICROSECOND { + _prec = 0; + buf[w] = b'n'; + } else if u < MILLISECOND { + _prec = 3; + // U+00B5 'µ' micro sign == 0xC2 0xB5 + buf[w] = 0xB5; + w -= 1; + buf[w] = 0xC2; + } else { + _prec = 6; + buf[w] = b'm'; + } + (w, u) = format_float(&mut buf[..w], u, _prec); + w = format_int(&mut buf[..w], u); + } else { + w -= 1; + buf[w] = b's'; + (w, u) = format_float(&mut buf[..w], u, 9); + + // u is now integer number of seconds + w = format_int(&mut buf[..w], u % 60); + u /= 60; + + // u is now integer number of minutes + if u > 0 { + w -= 1; + buf[w] = b'm'; + w = format_int(&mut buf[..w], u % 60); + u /= 60; + + // u is now integer number of hours + if u > 0 { + w -= 1; + buf[w] = b'h'; + w = format_int(&mut buf[..w], u); + } + } + } + + if neg { + w -= 1; + buf[w] = b'-'; + } + String::from_utf8_lossy(&buf[w..]).into_owned() +} + +fn format_float(buf: &mut [u8], mut v: u64, prec: usize) -> (usize, u64) { + let mut w = buf.len(); + let mut print = false; + for _ in 0..prec { + let digit = v % 10; + print = print || digit != 0; + if print { + w -= 1; + buf[w] = digit as u8 + b'0'; + } + v /= 10; + } + if print { + w -= 1; + buf[w] = b'.'; + } + (w, v) +} + +fn format_int(buf: &mut [u8], mut v: u64) -> usize { + let mut w = buf.len(); + if v == 0 { + w -= 1; + buf[w] = b'0'; + } else { + while v > 0 { + w -= 1; + buf[w] = (v % 10) as u8 + b'0'; + v /= 10; + } + } + w +} + +#[cfg(test)] +mod tests { + use crate::duration::{format_duration, parse_duration}; + use chrono::Duration; + + fn assert_duration(input: &str, expected: Duration) { + let (_, duration) = parse_duration(input).unwrap(); + assert_eq!(duration, expected, "{input}"); + } + + fn assert_print_duration(input: Duration, expected: &str) { + let actual = format_duration(&input); + assert_eq!(actual, expected, "{input}"); + } + + macro_rules! assert_durations { + ($($str:expr => $duration:expr),*$(,)?) => { + #[test] + fn test_durations() { + $( + assert_duration($str, $duration); + )* + } + }; + } + + macro_rules! assert_duration_format { + ($($duration:expr => $str:expr),*$(,)?) => { + #[test] + fn test_format_durations() { + $( + assert_print_duration($duration, $str); + )* + } + }; + } + + assert_durations! { + "1s" => Duration::seconds(1), + "-1s" => Duration::seconds(-1), + "1.1s" => Duration::seconds(1) + Duration::milliseconds(100), + "1.5m" => Duration::minutes(1) + Duration::seconds(30), + "1m1s" => Duration::minutes(1) + Duration::seconds(1), + "1h1m1s" => Duration::hours(1) + Duration::minutes(1) + Duration::seconds(1), + "1ms" => Duration::milliseconds(1), + "1us" => Duration::microseconds(1), + "1ns" => Duration::nanoseconds(1), + "1.1ns" => Duration::nanoseconds(1), + "1.123us" => Duration::microseconds(1) + Duration::nanoseconds(123), + "0s" => Duration::zero(), + "0h0m0s" => Duration::zero(), + "0h0m1s" => Duration::seconds(1), + "0" => Duration::zero(), + "-0" => Duration::zero(), + } + + assert_duration_format! { + Duration::zero() => "0s", + Duration::nanoseconds(1) => "1ns", + Duration::nanoseconds(1100) => "1.1µs", + Duration::microseconds(2200) => "2.2ms", + Duration::milliseconds(3300) => "3.3s", + Duration::minutes(4) + Duration::seconds(5) => "4m5s", + Duration::minutes(4) + Duration::milliseconds(5001) => "4m5.001s", + Duration::hours(5) + Duration::minutes(6) + Duration::milliseconds(7001) => "5h6m7.001s", + Duration::minutes(8) + Duration::nanoseconds(1) => "8m0.000000001s", + Duration::nanoseconds(i64::MAX) => "2562047h47m16.854775807s", + Duration::nanoseconds(i64::MIN) => "-2562047h47m16.854775808s", + } +} diff --git a/vendor/cel/src/functions.rs b/vendor/cel/src/functions.rs new file mode 100644 index 0000000..5bac185 --- /dev/null +++ b/vendor/cel/src/functions.rs @@ -0,0 +1,871 @@ +use crate::context::Context; +use crate::magic::{Arguments, This}; +use crate::objects::Value; +use crate::parser::Expression; +use crate::resolvers::Resolver; +use crate::ExecutionError; +use std::cmp::Ordering; +use std::convert::TryInto; +use std::sync::Arc; + +type Result = std::result::Result; + +/// `FunctionContext` is a context object passed to functions when they are called. +/// +/// It contains references to the target object (if the function is called as +/// a method), the program context ([`Context`]) which gives functions access +/// to variables, and the arguments to the function call. +#[derive(Clone)] +pub struct FunctionContext<'context> { + pub name: Arc, + pub this: Option, + pub ptx: &'context Context<'context>, + pub args: Vec, + pub arg_idx: usize, +} + +impl<'context> FunctionContext<'context> { + pub fn new( + name: Arc, + this: Option, + ptx: &'context Context<'context>, + args: Vec, + ) -> Self { + Self { + name, + this, + ptx, + args, + arg_idx: 0, + } + } + + /// Resolves the given expression using the program's [`Context`]. + pub fn resolve(&self, resolver: R) -> Result + where + R: Resolver, + { + resolver.resolve(self) + } + + /// Returns an execution error for the currently execution function. + pub fn error(&self, message: M) -> ExecutionError { + ExecutionError::function_error(self.name.as_str(), message) + } +} + +/// Calculates the size of either the target, or the provided args depending on how +/// the function is called. +/// +/// If called as a method, the target will be used. If called as a function, the +/// first argument will be used. +/// +/// The following [`Value`] variants are supported: +/// * [`Value::List`] +/// * [`Value::Map`] +/// * [`Value::String`] +/// * [`Value::Bytes`] +/// +/// # Examples +/// ```skip +/// size([1, 2, 3]) == 3 +/// ``` +/// ```skip +/// 'foobar'.size() == 6 +/// ``` +pub fn size(ftx: &FunctionContext, This(this): This) -> Result { + let size = match this { + Value::List(l) => l.len(), + Value::Map(m) => m.map.len(), + Value::DynamicMap(m) => m.len(), + Value::String(s) => s.len(), + Value::Bytes(b) => b.len(), + value => return Err(ftx.error(format!("cannot determine the size of {value:?}"))), + }; + Ok(size as i64) +} + +/// Returns true if the target contains the provided argument. The actual behavior +/// depends mainly on the type of the target. +/// +/// The following [`Value`] variants are supported: +/// * [`Value::List`] - Returns true if the list contains the provided value. +/// * [`Value::Map`] - Returns true if the map contains the provided key. +/// * [`Value::String`] - Returns true if the string contains the provided substring. +/// * [`Value::Bytes`] - Returns true if the bytes contain the provided byte. +/// +/// # Example +/// +/// ## List +/// ```cel +/// [1, 2, 3].contains(1) == true +/// ``` +/// +/// ## Map +/// ```cel +/// {"a": 1, "b": 2, "c": 3}.contains("a") == true +/// ``` +/// +/// ## String +/// ```cel +/// "abc".contains("b") == true +/// ``` +/// +/// ## Bytes +/// ```cel +/// b"abc".contains(b"c") == true +/// ``` +pub fn contains(This(this): This, arg: Value) -> Result { + Ok(match this { + Value::List(v) => v.contains(&arg), + Value::Map(v) => v + .map + .contains_key(&arg.try_into().map_err(ExecutionError::UnsupportedKeyType)?), + Value::DynamicMap(v) => v + .contains_key(&arg.try_into().map_err(ExecutionError::UnsupportedKeyType)?), + Value::String(s) => { + if let Value::String(arg) = arg { + s.contains(arg.as_str()) + } else { + false + } + } + Value::Bytes(b) => { + if let Value::Bytes(arg) = arg { + let s = arg.as_slice(); + b.windows(arg.len()).any(|w| w == s) + } else { + false + } + } + _ => false, + } + .into()) +} + +// Performs a type conversion on the target. The following conversions are currently +// supported: +// * `string` - Returns a copy of the target string. +// * `timestamp` - Returns the timestamp in RFC3339 format. +// * `duration` - Returns the duration in a string formatted like "72h3m0.5s". +// * `int` - Returns the integer value of the target. +// * `uint` - Returns the unsigned integer value of the target. +// * `float` - Returns the float value of the target. +// * `bytes` - Converts bytes to string using from_utf8_lossy. +pub fn string(ftx: &FunctionContext, This(this): This) -> Result { + Ok(match this { + Value::String(v) => Value::String(v.clone()), + #[cfg(feature = "chrono")] + Value::Timestamp(t) => Value::String(t.to_rfc3339().into()), + #[cfg(feature = "chrono")] + Value::Duration(v) => Value::String(crate::duration::format_duration(&v).into()), + Value::Int(v) => Value::String(v.to_string().into()), + Value::UInt(v) => Value::String(v.to_string().into()), + Value::Float(v) => Value::String(v.to_string().into()), + Value::Bytes(v) => Value::String(Arc::new(String::from_utf8_lossy(v.as_slice()).into())), + v => return Err(ftx.error(format!("cannot convert {v:?} to string"))), + }) +} + +pub fn bytes(value: Arc) -> Result { + Ok(Value::Bytes(value.as_bytes().to_vec().into())) +} + +// Performs a type conversion on the target. +pub fn double(ftx: &FunctionContext, This(this): This) -> Result { + Ok(match this { + Value::String(v) => v + .parse::() + .map(Value::Float) + .map_err(|e| ftx.error(format!("string parse error: {e}")))?, + Value::Float(v) => Value::Float(v), + Value::Int(v) => Value::Float(v as f64), + Value::UInt(v) => Value::Float(v as f64), + v => return Err(ftx.error(format!("cannot convert {v:?} to double"))), + }) +} + +// Performs a type conversion on the target. +pub fn uint(ftx: &FunctionContext, This(this): This) -> Result { + Ok(match this { + Value::String(v) => v + .parse::() + .map(Value::UInt) + .map_err(|e| ftx.error(format!("string parse error: {e}")))?, + Value::Float(v) => { + if v > u64::MAX as f64 || v < u64::MIN as f64 { + return Err(ftx.error("unsigned integer overflow")); + } + Value::UInt(v as u64) + } + Value::Int(v) => Value::UInt( + v.try_into() + .map_err(|_| ftx.error("unsigned integer overflow"))?, + ), + Value::UInt(v) => Value::UInt(v), + v => return Err(ftx.error(format!("cannot convert {v:?} to uint"))), + }) +} + +// Performs a type conversion on the target. +pub fn int(ftx: &FunctionContext, This(this): This) -> Result { + Ok(match this { + Value::String(v) => v + .parse::() + .map(Value::Int) + .map_err(|e| ftx.error(format!("string parse error: {e}")))?, + Value::Float(v) => { + if v > i64::MAX as f64 || v < i64::MIN as f64 { + return Err(ftx.error("integer overflow")); + } + Value::Int(v as i64) + } + Value::Int(v) => Value::Int(v), + Value::UInt(v) => Value::Int(v.try_into().map_err(|_| ftx.error("integer overflow"))?), + v => return Err(ftx.error(format!("cannot convert {v:?} to int"))), + }) +} + +/// Returns true if a string starts with another string. +/// +/// # Example +/// ```cel +/// "abc".startsWith("a") == true +/// ``` +pub fn starts_with(This(this): This>, prefix: Arc) -> bool { + this.starts_with(prefix.as_str()) +} + +/// Returns true if a string ends with another string. +/// +/// # Example +/// ```cel +/// "abc".endsWith("c") == true +/// ``` +pub fn ends_with(This(this): This>, suffix: Arc) -> bool { + this.ends_with(suffix.as_str()) +} + +/// Returns true if a string matches the regular expression. +/// +/// # Example +/// ```cel +/// "abc".matches("^[a-z]*$") == true +/// ``` +#[cfg(feature = "regex")] +pub fn matches( + ftx: &FunctionContext, + This(this): This>, + regex: Arc, +) -> Result { + match regex::Regex::new(®ex) { + Ok(re) => Ok(re.is_match(&this)), + Err(err) => Err(ftx.error(format!("'{regex}' not a valid regex:\n{err}"))), + } +} + +#[cfg(feature = "chrono")] +pub use time::duration; +#[cfg(feature = "chrono")] +pub use time::timestamp; + +#[cfg(feature = "chrono")] +pub mod time { + use super::Result; + use crate::magic::This; + use crate::{ExecutionError, Value}; + use chrono::{Datelike, Days, Months, Timelike}; + use std::sync::Arc; + + /// Duration parses the provided argument into a [`Value::Duration`] value. + /// + /// The argument must be string, and must be in the format of a duration. See + /// the [`parse_duration`] documentation for more information on the supported + /// formats. + /// + /// # Examples + /// - `1h` parses as 1 hour + /// - `1.5h` parses as 1 hour and 30 minutes + /// - `1h30m` parses as 1 hour and 30 minutes + /// - `1h30m1s` parses as 1 hour, 30 minutes, and 1 second + /// - `1ms` parses as 1 millisecond + /// - `1.5ms` parses as 1 millisecond and 500 microseconds + /// - `1ns` parses as 1 nanosecond + /// - `1.5ns` parses as 1 nanosecond (sub-nanosecond durations not supported) + pub fn duration(value: Arc) -> crate::functions::Result { + Ok(Value::Duration(_duration(value.as_str())?)) + } + + /// Timestamp parses the provided argument into a [`Value::Timestamp`] value. + /// The + pub fn timestamp(value: Arc) -> Result { + Ok(Value::Timestamp( + chrono::DateTime::parse_from_rfc3339(value.as_str()) + .map_err(|e| ExecutionError::function_error("timestamp", e.to_string().as_str()))?, + )) + } + + /// A wrapper around [`parse_duration`] that converts errors into [`ExecutionError`]. + /// and only returns the duration, rather than returning the remaining input. + fn _duration(i: &str) -> Result { + let (_, duration) = crate::duration::parse_duration(i) + .map_err(|e| ExecutionError::function_error("duration", e.to_string()))?; + Ok(duration) + } + + fn _timestamp(i: &str) -> Result> { + chrono::DateTime::parse_from_rfc3339(i) + .map_err(|e| ExecutionError::function_error("timestamp", e.to_string())) + } + + pub fn timestamp_year( + This(this): This>, + ) -> Result { + Ok(this.year().into()) + } + + pub fn timestamp_month( + This(this): This>, + ) -> Result { + Ok((this.month0() as i32).into()) + } + + pub fn timestamp_year_day( + This(this): This>, + ) -> Result { + let year = this + .checked_sub_days(Days::new(this.day0() as u64)) + .unwrap() + .checked_sub_months(Months::new(this.month0())) + .unwrap(); + Ok(this.signed_duration_since(year).num_days().into()) + } + + pub fn timestamp_month_day( + This(this): This>, + ) -> Result { + Ok((this.day0() as i32).into()) + } + + pub fn timestamp_date( + This(this): This>, + ) -> Result { + Ok((this.day() as i32).into()) + } + + pub fn timestamp_weekday( + This(this): This>, + ) -> Result { + Ok((this.weekday().num_days_from_sunday() as i32).into()) + } + + pub fn timestamp_hours( + This(this): This>, + ) -> Result { + Ok((this.hour() as i32).into()) + } + + pub fn timestamp_minutes( + This(this): This>, + ) -> Result { + Ok((this.minute() as i32).into()) + } + + pub fn timestamp_seconds( + This(this): This>, + ) -> Result { + Ok((this.second() as i32).into()) + } + + pub fn timestamp_millis( + This(this): This>, + ) -> Result { + Ok((this.timestamp_subsec_millis() as i32).into()) + } +} + +pub fn max(Arguments(args): Arguments) -> Result { + // If items is a list of values, then operate on the list + let items = if args.len() == 1 { + match &args[0] { + Value::List(values) => values, + _ => return Ok(args[0].clone()), + } + } else { + &args + }; + + items + .iter() + .skip(1) + .try_fold(items.first().unwrap_or(&Value::Null), |acc, x| { + match acc.partial_cmp(x) { + Some(Ordering::Greater) => Ok(acc), + Some(_) => Ok(x), + None => Err(ExecutionError::ValuesNotComparable(acc.clone(), x.clone())), + } + }) + .cloned() +} + +pub fn min(Arguments(args): Arguments) -> Result { + // If items is a list of values, then operate on the list + let items = if args.len() == 1 { + match &args[0] { + Value::List(values) => values, + _ => return Ok(args[0].clone()), + } + } else { + &args + }; + + items + .iter() + .skip(1) + .try_fold(items.first().unwrap_or(&Value::Null), |acc, x| { + match acc.partial_cmp(x) { + Some(Ordering::Less) => Ok(acc), + Some(_) => Ok(x), + None => Err(ExecutionError::ValuesNotComparable(acc.clone(), x.clone())), + } + }) + .cloned() +} + +#[cfg(test)] +mod tests { + use crate::context::Context; + use crate::tests::test_script; + + fn assert_script(input: &(&str, &str)) { + assert_eq!(test_script(input.1, None), Ok(true.into()), "{}", input.0); + } + + fn assert_error(input: &(&str, &str, &str)) { + assert_eq!( + test_script(input.1, None) + .expect_err("expected error") + .to_string(), + input.2, + "{}", + input.0 + ); + } + + #[test] + fn test_size() { + [ + ("size of list", "size([1, 2, 3]) == 3"), + ("size of map", "size({'a': 1, 'b': 2, 'c': 3}) == 3"), + ("size of string", "size('foo') == 3"), + ("size of bytes", "size(b'foo') == 3"), + ("size as a list method", "[1, 2, 3].size() == 3"), + ("size as a string method", "'foobar'.size() == 6"), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_has() { + let tests = vec![ + ("map has", "has(foo.bar) == true"), + ("map not has", "has(foo.baz) == false"), + ]; + + for (name, script) in tests { + let mut ctx = Context::default(); + ctx.add_variable_from_value("foo", std::collections::HashMap::from([("bar", 1)])); + assert_eq!(test_script(script, Some(ctx)), Ok(true.into()), "{name}"); + } + } + + #[test] + fn test_map() { + [ + ("map list", "[1, 2, 3].map(x, x * 2) == [2, 4, 6]"), + ("map list 2", "[1, 2, 3].map(y, y + 1) == [2, 3, 4]"), + ( + "map list filter", + "[1, 2, 3].map(y, y % 2 == 0, y + 1) == [3]", + ), + ( + "nested map", + "[[1, 2], [2, 3]].map(x, x.map(x, x * 2)) == [[2, 4], [4, 6]]", + ), + ( + "map to list", + r#"{'John': 'smart'}.map(key, key) == ['John']"#, + ), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_filter() { + [("filter list", "[1, 2, 3].filter(x, x > 2) == [3]")] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_all() { + [ + ("all list #1", "[0, 1, 2].all(x, x >= 0)"), + ("all list #2", "[0, 1, 2].all(x, x > 0) == false"), + ("all map", "{0: 0, 1:1, 2:2}.all(x, x >= 0) == true"), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_exists() { + [ + ("exist list #1", "[0, 1, 2].exists(x, x > 0)"), + ("exist list #2", "[0, 1, 2].exists(x, x == 3) == false"), + ("exist list #3", "[0, 1, 2, 2].exists(x, x == 2)"), + ("exist map", "{0: 0, 1:1, 2:2}.exists(x, x > 0)"), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_exists_one() { + [ + ("exist list #1", "[0, 1, 2].exists_one(x, x > 0) == false"), + ("exist list #2", "[0, 1, 2].exists_one(x, x == 0)"), + ("exist map", "{0: 0, 1:1, 2:2}.exists_one(x, x == 2)"), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_max() { + [ + ("max single", "max(1) == 1"), + ("max multiple", "max(1, 2, 3) == 3"), + ("max negative", "max(-1, 0) == 0"), + ("max float", "max(-1.0, 0.0) == 0.0"), + ("max list", "max([1, 2, 3]) == 3"), + ("max empty list", "max([]) == null"), + ("max no args", "max() == null"), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_min() { + [ + ("min single", "min(1) == 1"), + ("min multiple", "min(1, 2, 3) == 1"), + ("min negative", "min(-1, 0) == -1"), + ("min float", "min(-1.0, 0.0) == -1.0"), + ( + "min float multiple", + "min(1.61803, 3.1415, 2.71828, 1.41421) == 1.41421", + ), + ("min list", "min([1, 2, 3]) == 1"), + ("min empty list", "min([]) == null"), + ("min no args", "min() == null"), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_starts_with() { + [ + ("starts with true", "'foobar'.startsWith('foo') == true"), + ("starts with false", "'foobar'.startsWith('bar') == false"), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_ends_with() { + [ + ("ends with true", "'foobar'.endsWith('bar') == true"), + ("ends with false", "'foobar'.endsWith('foo') == false"), + ] + .iter() + .for_each(assert_script); + } + + #[cfg(feature = "chrono")] + #[test] + fn test_timestamp() { + [( + "comparison", + "timestamp('2023-05-29T00:00:00Z') > timestamp('2023-05-28T00:00:00Z')", + ), + ( + "comparison", + "timestamp('2023-05-29T00:00:00Z') < timestamp('2023-05-30T00:00:00Z')", + ), + ( + "subtracting duration", + "timestamp('2023-05-29T00:00:00Z') - duration('24h') == timestamp('2023-05-28T00:00:00Z')", + ), + ( + "subtracting date", + "timestamp('2023-05-29T00:00:00Z') - timestamp('2023-05-28T00:00:00Z') == duration('24h')", + ), + ( + "adding duration", + "timestamp('2023-05-28T00:00:00Z') + duration('24h') == timestamp('2023-05-29T00:00:00Z')", + ), + ( + "timestamp string", + "timestamp('2023-05-28T00:00:00Z').string() == '2023-05-28T00:00:00+00:00'", + ), + ( + "timestamp getFullYear", + "timestamp('2023-05-28T00:00:00Z').getFullYear() == 2023", + ), + ( + "timestamp getMonth", + "timestamp('2023-05-28T00:00:00Z').getMonth() == 4", + ), + ( + "timestamp getDayOfMonth", + "timestamp('2023-05-28T00:00:00Z').getDayOfMonth() == 27", + ), + ( + "timestamp getDayOfYear", + "timestamp('2023-05-28T00:00:00Z').getDayOfYear() == 147", + ), + ( + "timestamp getDate", + "timestamp('2023-05-28T00:00:00Z').getDate() == 28", + ), + ( + "timestamp getDayOfWeek", + "timestamp('2023-05-28T00:00:00Z').getDayOfWeek() == 0", + ), + ( + "timestamp getHours", + "timestamp('2023-05-28T02:00:00Z').getHours() == 2", + ), + ( + "timestamp getMinutes", + " timestamp('2023-05-28T00:05:00Z').getMinutes() == 5", + ), + ( + "timestamp getSeconds", + "timestamp('2023-05-28T00:00:06Z').getSeconds() == 6", + ), + ( + "timestamp getMilliseconds", + "timestamp('2023-05-28T00:00:42.123Z').getMilliseconds() == 123", + ), + ] + .iter() + .for_each(assert_script); + + [ + ( + "timestamp out of range", + "timestamp('0000-01-00T00:00:00Z')", + "Error executing function 'timestamp': input is out of range", + ), + ( + "timestamp out of range", + "timestamp('9999-12-32T23:59:59.999999999Z')", + "Error executing function 'timestamp': input is out of range", + ), + ( + "timestamp overflow", + "timestamp('9999-12-31T23:59:59Z') + duration('1s')", + "Overflow from binary operator 'add': Timestamp(9999-12-31T23:59:59+00:00), Duration(TimeDelta { secs: 1, nanos: 0 })", + ), + ( + "timestamp underflow", + "timestamp('0001-01-01T00:00:00Z') - duration('1s')", + "Overflow from binary operator 'sub': Timestamp(0001-01-01T00:00:00+00:00), Duration(TimeDelta { secs: 1, nanos: 0 })", + ), + ( + "timestamp underflow", + "timestamp('0001-01-01T00:00:00Z') + duration('-1s')", + "Overflow from binary operator 'add': Timestamp(0001-01-01T00:00:00+00:00), Duration(TimeDelta { secs: -1, nanos: 0 })", + ), + ] + .iter() + .for_each(assert_error) + } + + #[cfg(feature = "chrono")] + #[test] + fn test_duration() { + [ + ("duration equal 1", "duration('1s') == duration('1000ms')"), + ("duration equal 2", "duration('1m') == duration('60s')"), + ("duration equal 3", "duration('1h') == duration('60m')"), + ("duration comparison 1", "duration('1m') > duration('1s')"), + ("duration comparison 2", "duration('1m') < duration('1h')"), + ( + "duration subtraction", + "duration('1h') - duration('1m') == duration('59m')", + ), + ( + "duration addition", + "duration('1h') + duration('1m') == duration('1h1m')", + ), + ] + .iter() + .for_each(assert_script); + } + + #[cfg(feature = "chrono")] + #[test] + fn test_timestamp_variable() { + let mut context = Context::default(); + let ts: chrono::DateTime = + chrono::DateTime::parse_from_rfc3339("2023-05-29T00:00:00Z").unwrap(); + context + .add_variable("ts", crate::Value::Timestamp(ts)) + .unwrap(); + + let program = crate::Program::compile("ts == timestamp('2023-05-29T00:00:00Z')").unwrap(); + let result = program.execute(&context).unwrap(); + assert_eq!(result, true.into()); + } + + #[cfg(feature = "chrono")] + #[test] + fn test_chrono_string() { + [ + ("duration", "duration('1h30m').string() == '1h30m0s'"), + ( + "timestamp", + "timestamp('2023-05-29T00:00:00Z').string() == '2023-05-29T00:00:00+00:00'", + ), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_contains() { + let tests = vec![ + ("list", "[1, 2, 3].contains(3) == true"), + ("map", "{1: true, 2: true, 3: true}.contains(3) == true"), + ("string", "'foobar'.contains('bar') == true"), + ("bytes", "b'foobar'.contains(b'o') == true"), + ]; + + for (name, script) in tests { + assert_eq!(test_script(script, None), Ok(true.into()), "{name}"); + } + } + + #[cfg(feature = "regex")] + #[test] + fn test_matches() { + let tests = vec![ + ("string", "'foobar'.matches('^[a-zA-Z]*$') == true"), + ( + "map", + "{'1': 'abc', '2': 'def', '3': 'ghi'}.all(key, key.matches('^[a-zA-Z]*$')) == false", + ), + ]; + + for (name, script) in tests { + assert_eq!( + test_script(script, None), + Ok(true.into()), + ".matches failed for '{name}'" + ); + } + } + + #[cfg(feature = "regex")] + #[test] + fn test_matches_err() { + assert_eq!( + test_script( + "'foobar'.matches('(foo') == true", None), + Err( + crate::ExecutionError::FunctionError { + function: "matches".to_string(), + message: "'(foo' not a valid regex:\nregex parse error:\n (foo\n ^\nerror: unclosed group".to_string() + } + ) + ); + } + + #[test] + fn test_string() { + [ + ("string", "'foo'.string() == 'foo'"), + ("int", "10.string() == '10'"), + ("float", "10.5.string() == '10.5'"), + ("bytes", "b'foo'.string() == 'foo'"), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_bytes() { + [ + ("string", "bytes('abc') == b'abc'"), + ("bytes", "bytes('abc') == b'\\x61b\\x63'"), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_double() { + [ + ("string", "'10'.double() == 10.0"), + ("int", "10.double() == 10.0"), + ("double", "10.0.double() == 10.0"), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_uint() { + [ + ("string", "'10'.uint() == 10.uint()"), + ("double", "10.5.uint() == 10.uint()"), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn test_int() { + [ + ("string", "'10'.int() == 10"), + ("int", "10.int() == 10"), + ("uint", "10.uint().int() == 10"), + ("double", "10.5.int() == 10"), + ] + .iter() + .for_each(assert_script); + } + + #[test] + fn no_bool_coercion() { + [ + ("string || bool", "'' || false", "No such overload"), + ("int || bool", "1 || false", "No such overload"), + ("int || bool", "1u || false", "No such overload"), + ("float || bool", "0.1|| false", "No such overload"), + ("list || bool", "[] || false", "No such overload"), + ("map || bool", "{} || false", "No such overload"), + ("null || bool", "null || false", "No such overload"), + ] + .iter() + .for_each(assert_error) + } +} diff --git a/vendor/cel/src/json.rs b/vendor/cel/src/json.rs new file mode 100644 index 0000000..ffcd7fa --- /dev/null +++ b/vendor/cel/src/json.rs @@ -0,0 +1,122 @@ +use crate::Value; +use base64::prelude::*; +#[cfg(feature = "chrono")] +use chrono::Duration; +use thiserror::Error; + +#[derive(Debug, Clone, Error)] +#[error("unable to convert value to json: {0:?}")] +pub enum ConvertToJsonError<'a> { + /// We cannot convert the CEL value to JSON. Some CEL types (like functions) are + /// not representable in JSON. + #[error("unable to convert value to json: {0:?}")] + Value(&'a Value), + + #[cfg(feature = "chrono")] + /// The duration is too large to convert to nanoseconds. Any duration of 2^63 + /// nanoseconds or more will overflow. We'll return the duration type in the + /// error message. + #[error("duration too large to convert to nanoseconds: {0:?}")] + DurationOverflow(&'a Duration), +} + +impl Value { + /// Converts a CEL value to a JSON value. + /// + /// # Example + /// ``` + /// use cel::{Context, Program}; + /// + /// let program = Program::compile("null").unwrap(); + /// let value = program.execute(&Context::default()).unwrap(); + /// let result = value.json().unwrap(); + /// + /// assert_eq!(result, serde_json::Value::Null); + /// ``` + pub fn json(&self) -> Result> { + Ok(match *self { + Value::List(ref vec) => serde_json::Value::Array( + vec.iter() + .map(|v| v.json()) + .collect::, _>>()?, + ), + Value::Map(ref map) => { + let mut obj = serde_json::Map::new(); + for (k, v) in map.map.iter() { + obj.insert(k.to_string(), v.json()?); + } + serde_json::Value::Object(obj) + } + Value::DynamicMap(ref map) => { + let mut obj = serde_json::Map::new(); + for (k, v) in map.iter() { + let json_value = match v.json() { + Ok(value) => value, + Err(_) => return Err(ConvertToJsonError::Value(self)), + }; + obj.insert(k.to_string(), json_value); + } + serde_json::Value::Object(obj) + } + Value::Int(i) => i.into(), + Value::UInt(u) => u.into(), + Value::Float(f) => f.into(), + Value::String(ref s) => s.to_string().into(), + Value::Bool(b) => b.into(), + Value::Bytes(ref b) => BASE64_STANDARD.encode(b.as_slice()).to_string().into(), + Value::Null => serde_json::Value::Null, + #[cfg(feature = "chrono")] + Value::Timestamp(ref dt) => dt.to_rfc3339().into(), + #[cfg(feature = "chrono")] + Value::Duration(ref v) => serde_json::Value::Number(serde_json::Number::from( + v.num_nanoseconds() + .ok_or(ConvertToJsonError::DurationOverflow(v))?, + )), + _ => return Err(ConvertToJsonError::Value(self)), + }) + } +} + +#[cfg(test)] +mod tests { + use crate::objects::Map; + use crate::Value as CelValue; + #[cfg(feature = "chrono")] + use chrono::Duration; + use serde_json::json; + use std::collections::HashMap; + + #[test] + fn test_cel_value_to_json() { + let mut tests = vec![ + (json!("hello"), CelValue::String("hello".to_string().into())), + (json!(42), CelValue::Int(42)), + (json!(42.0), CelValue::Float(42.0)), + (json!(true), CelValue::Bool(true)), + (json!(null), CelValue::Null), + ( + json!([true, null]), + CelValue::List(vec![CelValue::Bool(true), CelValue::Null].into()), + ), + ( + json!({"hello": "world"}), + CelValue::Map(Map::from(HashMap::from([( + "hello".to_string(), + CelValue::String("world".to_string().into()), + )]))), + ), + ]; + + #[cfg(feature = "chrono")] + if true { + tests.push(( + json!(1_000_000_000), + CelValue::Duration(Duration::seconds(1)), + )); + } + + for (expected, value) in tests.iter() { + assert_eq!(value.json().unwrap(), *expected, "{value:?}={expected:?}"); + } + } +} diff --git a/vendor/cel/src/lib.rs b/vendor/cel/src/lib.rs new file mode 100644 index 0000000..b8fe697 --- /dev/null +++ b/vendor/cel/src/lib.rs @@ -0,0 +1,303 @@ +extern crate core; + +use std::convert::TryFrom; +use std::sync::Arc; +use thiserror::Error; + +mod macros; + +pub mod common; +pub mod context; +pub mod parser; + +pub use common::ast::IdedExpr; +use common::ast::SelectExpr; +pub use context::Context; +pub use functions::FunctionContext; +pub use objects::{ResolveResult, Value}; +use parser::{Expression, ExpressionReferences, Parser}; +pub use parser::{ParseError, ParseErrors}; +pub mod functions; +mod magic; +pub mod objects; +mod resolvers; +pub mod types; + +#[cfg(feature = "chrono")] +mod duration; +#[cfg(feature = "chrono")] +pub use ser::{Duration, Timestamp}; + +mod ser; +pub use ser::to_value; +pub use ser::SerializationError; + +#[cfg(feature = "json")] +mod json; +#[cfg(feature = "json")] +pub use json::ConvertToJsonError; + +use magic::FromContext; + +pub mod extractors { + pub use crate::magic::{Arguments, Identifier, This}; +} + +#[derive(Error, Clone, Debug, PartialEq)] +#[non_exhaustive] +pub enum ExecutionError { + #[error("Invalid argument count: expected {expected}, got {actual}")] + InvalidArgumentCount { expected: usize, actual: usize }, + #[error("Invalid argument type: {:?}", .target)] + UnsupportedTargetType { target: Value }, + #[error("Method '{method}' not supported on type '{target:?}'")] + NotSupportedAsMethod { method: String, target: Value }, + /// Indicates that the script attempted to use a value as a key in a map, + /// but the type of the value was not supported as a key. + #[error("Unable to use value '{0:?}' as a key")] + UnsupportedKeyType(Value), + #[error("Unexpected type: got '{got}', want '{want}'")] + UnexpectedType { got: String, want: String }, + /// Indicates that the script attempted to reference a key on a type that + /// was missing the requested key. + #[error("No such key: {0}")] + NoSuchKey(Arc), + /// Indicates that the script used an existing operator or function with + /// values of one or more types for which no overload was declared. + #[error("No such overload")] + NoSuchOverload, + /// Indicates that the script attempted to reference an undeclared variable + /// method, or function. + #[error("Undeclared reference to '{0}'")] + UndeclaredReference(Arc), + /// Indicates that a function expected to be called as a method, or to be + /// called with at least one parameter. + #[error("Missing argument or target")] + MissingArgumentOrTarget, + /// Indicates that a comparison could not be performed. + #[error("{0:?} can not be compared to {1:?}")] + ValuesNotComparable(Value, Value), + /// Indicates that an operator was used on a type that does not support it. + #[error("Unsupported unary operator '{0}': {1:?}")] + UnsupportedUnaryOperator(&'static str, Value), + /// Indicates that an unsupported binary operator was applied on two values + /// where it's unsupported, for example list + map. + #[error("Unsupported binary operator '{0}': {1:?}, {2:?}")] + UnsupportedBinaryOperator(&'static str, Value, Value), + /// Indicates that an unsupported type was used to index a map + #[error("Cannot use value as map index: {0:?}")] + UnsupportedMapIndex(Value), + /// Indicates that an unsupported type was used to index a list + #[error("Cannot use value as list index: {0:?}")] + UnsupportedListIndex(Value), + /// Indicates that an unsupported type was used to index a list + #[error("Cannot use value {0:?} to index {1:?}")] + UnsupportedIndex(Value, Value), + /// Indicates that a function call occurred without an [`Expression::Ident`] + /// as the function identifier. + #[error("Unsupported function call identifier type: {0:?}")] + UnsupportedFunctionCallIdentifierType(Expression), + /// Indicates that a [`Member::Fields`] construction was attempted + /// which is not yet supported. + #[error("Unsupported fields construction: {0:?}")] + UnsupportedFieldsConstruction(SelectExpr), + /// Indicates that a function had an error during execution. + #[error("Error executing function '{function}': {message}")] + FunctionError { function: String, message: String }, + #[error("Division by zero of {0:?}")] + DivisionByZero(Value), + #[error("Remainder by zero of {0:?}")] + RemainderByZero(Value), + #[error("Overflow from binary operator '{0}': {1:?}, {2:?}")] + Overflow(&'static str, Value, Value), + #[error("Index out of bounds: {0:?}")] + IndexOutOfBounds(Value), +} + +impl ExecutionError { + pub fn no_such_key(name: &str) -> Self { + ExecutionError::NoSuchKey(Arc::new(name.to_string())) + } + + pub fn undeclared_reference(name: &str) -> Self { + ExecutionError::UndeclaredReference(Arc::new(name.to_string())) + } + + pub fn invalid_argument_count(expected: usize, actual: usize) -> Self { + ExecutionError::InvalidArgumentCount { expected, actual } + } + + pub fn function_error(function: &str, error: E) -> Self { + ExecutionError::FunctionError { + function: function.to_string(), + message: error.to_string(), + } + } + + pub fn unsupported_target_type(target: Value) -> Self { + ExecutionError::UnsupportedTargetType { target } + } + + pub fn not_supported_as_method(method: &str, target: Value) -> Self { + ExecutionError::NotSupportedAsMethod { + method: method.to_string(), + target, + } + } + + pub fn unsupported_key_type(value: Value) -> Self { + ExecutionError::UnsupportedKeyType(value) + } + + pub fn missing_argument_or_target() -> Self { + ExecutionError::MissingArgumentOrTarget + } +} + +#[derive(Debug)] +pub struct Program { + expression: Expression, +} + +impl Program { + pub fn compile(source: &str) -> Result { + let parser = Parser::default(); + parser + .parse(source) + .map(|expression| Program { expression }) + } + + pub fn execute(&self, context: &Context) -> ResolveResult { + Value::resolve(&self.expression, context) + } + + /// Returns the variables and functions referenced by the CEL program + /// + /// # Example + /// ```rust + /// # use cel::Program; + /// let program = Program::compile("size(foo) > 0").unwrap(); + /// let references = program.references(); + /// + /// assert!(references.has_function("size")); + /// assert!(references.has_variable("foo")); + /// ``` + pub fn references(&self) -> ExpressionReferences<'_> { + self.expression.references() + } + + /// Returns the contained expression + pub fn expression(&self) -> &Expression { + &self.expression + } +} + +impl TryFrom<&str> for Program { + type Error = ParseErrors; + + fn try_from(value: &str) -> Result { + Program::compile(value) + } +} + +#[cfg(test)] +mod tests { + use crate::context::Context; + use crate::objects::{ResolveResult, Value}; + use crate::{ExecutionError, Program}; + use std::collections::HashMap; + use std::convert::TryInto; + + /// Tests the provided script and returns the result. An optional context can be provided. + pub(crate) fn test_script(script: &str, ctx: Option) -> ResolveResult { + let program = match Program::compile(script) { + Ok(p) => p, + Err(e) => panic!("{}", e), + }; + program.execute(&ctx.unwrap_or_default()) + } + + #[test] + fn parse() { + Program::compile("1 + 1").unwrap(); + } + + #[test] + fn from_str() { + let input = "1.1"; + let _p: Program = input.try_into().unwrap(); + } + + #[test] + fn variables() { + fn assert_output(script: &str, expected: ResolveResult) { + let mut ctx = Context::default(); + ctx.add_variable_from_value("foo", HashMap::from([("bar", 1i64)])); + ctx.add_variable_from_value("arr", vec![1i64, 2, 3]); + ctx.add_variable_from_value("str", "foobar".to_string()); + assert_eq!(test_script(script, Some(ctx)), expected); + } + + // Test methods + assert_output("size([1, 2, 3]) == 3", Ok(true.into())); + assert_output("size([size([42]), 2, 3]) == 3", Ok(true.into())); + assert_output("size([]) == 3", Ok(false.into())); + + // Test variable attribute traversals + assert_output("foo.bar == 1", Ok(true.into())); + + // Test that we can index into an array + assert_output("arr[0] == 1", Ok(true.into())); + + // Test that we can index into a string + assert_output( + "str[0]", + Err(ExecutionError::NoSuchKey("0".to_string().into())), + ); + } + + #[test] + fn references() { + let p = Program::compile("[1, 1].map(x, x * 2)").unwrap(); + assert!(p.references().has_variable("x")); + assert_eq!(p.references().variables().len(), 1); + } + + #[test] + fn test_execution_errors() { + let tests = vec![ + ( + "no such key", + "foo.baz.bar == 1", + ExecutionError::no_such_key("baz"), + ), + ( + "undeclared reference", + "missing == 1", + ExecutionError::undeclared_reference("missing"), + ), + ( + "undeclared method", + "1.missing()", + ExecutionError::undeclared_reference("missing"), + ), + ( + "undeclared function", + "missing(1)", + ExecutionError::undeclared_reference("missing"), + ), + ( + "unsupported key type", + "{null: true}", + ExecutionError::unsupported_key_type(Value::Null), + ), + ]; + + for (name, script, error) in tests { + let mut ctx = Context::default(); + ctx.add_variable_from_value("foo", HashMap::from([("bar", 1)])); + let res = test_script(script, Some(ctx)); + assert_eq!(res, error.into(), "{name}"); + } + } +} diff --git a/vendor/cel/src/macros.rs b/vendor/cel/src/macros.rs new file mode 100644 index 0000000..65a901d --- /dev/null +++ b/vendor/cel/src/macros.rs @@ -0,0 +1,102 @@ +#[macro_export] +macro_rules! impl_conversions { + // Capture pairs separated by commas, where each pair is separated by => + ($($target_type:ty => $value_variant:path),* $(,)?) => { + $( + impl FromValue for $target_type { + fn from_value(expr: &Value) -> Result { + if let $value_variant(v) = expr { + Ok(v.clone()) + } else { + Err(ExecutionError::UnexpectedType { + got: format!("{:?}", expr), + want: stringify!($target_type).to_string(), + }) + } + } + } + + impl FromValue for Option<$target_type> { + fn from_value(expr: &Value) -> Result { + match expr { + Value::Null => Ok(None), + $value_variant(v) => Ok(Some(v.clone())), + _ => Err(ExecutionError::UnexpectedType { + got: format!("{:?}", expr), + want: stringify!($target_type).to_string(), + }), + } + } + } + + impl From<$target_type> for Value { + fn from(value: $target_type) -> Self { + $value_variant(value) + } + } + + impl $crate::magic::IntoResolveResult for $target_type { + fn into_resolve_result(self) -> ResolveResult { + Ok($value_variant(self)) + } + } + + impl $crate::magic::IntoResolveResult for Result<$target_type, ExecutionError> { + fn into_resolve_result(self) -> ResolveResult { + self.map($value_variant) + } + } + + impl<'a, 'context> FromContext<'a, 'context> for $target_type { + fn from_context(ctx: &'a mut FunctionContext<'context>) -> Result + where + Self: Sized, + { + arg_value_from_context(ctx).and_then(|v| FromValue::from_value(&v)) + } + } + )* + } +} + +#[macro_export] +macro_rules! impl_handler { + ($($t:ty),*) => { + paste::paste! { + impl IntoFunction<($($t,)*)> for F + where + F: Fn($($t,)*) -> R + Send + Sync + 'static, + $($t: for<'a, 'context> $crate::FromContext<'a, 'context>,)* + R: IntoResolveResult, + { + fn into_function(self) -> Function { + Box::new(move |_ftx| { + $( + let [] = $t::from_context(_ftx)?; + )* + self($([],)*).into_resolve_result() + }) + } + } + + impl IntoFunction<(WithFunctionContext, $($t,)*)> for F + where + F: Fn(&FunctionContext, $($t,)*) -> R + Send + Sync + 'static, + $($t: for<'a, 'context> $crate::FromContext<'a, 'context>,)* + R: IntoResolveResult, + { + fn into_function(self) -> Function { + Box::new(move |_ftx| { + $( + let [] = $t::from_context(_ftx)?; + )* + self(_ftx, $([],)*).into_resolve_result() + }) + } + } + } + }; +} + +pub(crate) use impl_conversions; +pub(crate) use impl_handler; diff --git a/vendor/cel/src/magic.rs b/vendor/cel/src/magic.rs new file mode 100644 index 0000000..658ec2a --- /dev/null +++ b/vendor/cel/src/magic.rs @@ -0,0 +1,328 @@ +use crate::common::ast::Expr; +use crate::macros::{impl_conversions, impl_handler}; +use crate::resolvers::{AllArguments, Argument}; +use crate::{ExecutionError, Expression, FunctionContext, ResolveResult, Value}; +use std::collections::HashMap; +use std::sync::Arc; + +impl_conversions!( + i64 => Value::Int, + u64 => Value::UInt, + f64 => Value::Float, + Arc => Value::String, + Arc> => Value::Bytes, + bool => Value::Bool, + Arc> => Value::List +); + +#[cfg(feature = "chrono")] +impl_conversions!( + chrono::Duration => Value::Duration, + chrono::DateTime => Value::Timestamp, +); + +impl From for Value { + fn from(value: i32) -> Self { + Value::Int(value as i64) + } +} + +/// Describes any type that can be converted from a [`Value`] into itself. +/// This is commonly used to convert from [`Value`] into primitive types, +/// e.g. from `Value::Bool(true) -> true`. This trait is auto-implemented +/// for many CEL-primitive types. +trait FromValue { + fn from_value(value: &Value) -> Result + where + Self: Sized; +} + +impl FromValue for Value { + fn from_value(value: &Value) -> Result + where + Self: Sized, + { + Ok(value.clone()) + } +} + +/// A trait for types that can be converted into a [`ResolveResult`]. Every function that can +/// be registered to the CEL context must return a value that implements this trait. +pub trait IntoResolveResult { + fn into_resolve_result(self) -> ResolveResult; +} + +impl IntoResolveResult for String { + fn into_resolve_result(self) -> ResolveResult { + Ok(Value::String(Arc::new(self))) + } +} + +impl IntoResolveResult for Result { + fn into_resolve_result(self) -> ResolveResult { + self + } +} + +/// Describes any type that can be converted from a [`FunctionContext`] into +/// itself, for example CEL primitives implement this trait to allow them to +/// be used as arguments to functions. This trait is core to the 'magic function +/// parameter' system. Every argument to a function that can be registered to +/// the CEL context must implement this type. +pub(crate) trait FromContext<'a, 'context> { + fn from_context(ctx: &'a mut FunctionContext<'context>) -> Result + where + Self: Sized; +} + +/// A function argument abstraction enabling dynamic method invocation on a +/// target instance or on the first argument if the function is not called +/// as a method. +/// +/// This is similar to how methods can be called as functions using the +/// [fully-qualified syntax](https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name). +/// +/// # Using `This` +/// ``` +/// # use std::sync::Arc; +/// # use cel::{Program, Context}; +/// use cel::extractors::This; +/// # let mut context = Context::default(); +/// # context.add_function("startsWith", starts_with); +/// +/// /// Notice how `This` refers to the target value when called as a method, +/// /// but the first argument when called as a function. +/// let program1 = "'foobar'.startsWith('foo') == true"; +/// let program2 = "startsWith('foobar', 'foo') == true"; +/// # let program1 = Program::compile(program1).unwrap(); +/// # let program2 = Program::compile(program2).unwrap(); +/// # let value = program1.execute(&context).unwrap(); +/// # assert_eq!(value, true.into()); +/// # let value = program2.execute(&context).unwrap(); +/// # assert_eq!(value, true.into()); +/// +/// fn starts_with(This(this): This>, prefix: Arc) -> bool { +/// this.starts_with(prefix.as_str()) +/// } +/// ``` +/// +/// # Type of `This` +/// This also accepts a type `T` which determines the specific type +/// that's extracted. Any type that supports [`FromValue`] can be used. +/// In the previous example, the method `startsWith` is only ever called +/// on a string, so we can use `This>` to extract the string +/// automatically prior to our method actually being called. +/// +/// In some cases, you may want access to the raw [`Value`] instead, for +/// example, the `contains` method works for several different types. In these +/// cases, you can use `This` to extract the raw value. +/// +/// ```skip +/// pub fn contains(This(this): This, arg: Value) -> Result { +/// Ok(match this { +/// Value::List(v) => v.contains(&arg), +/// ... +/// } +/// } +/// ``` +pub struct This(pub T); + +impl<'a, 'context, T> FromContext<'a, 'context> for This +where + T: FromValue, +{ + fn from_context(ctx: &'a mut FunctionContext<'context>) -> Result + where + Self: Sized, + { + if let Some(ref this) = ctx.this { + Ok(This(T::from_value(this)?)) + } else { + let arg = arg_value_from_context(ctx) + .map_err(|_| ExecutionError::missing_argument_or_target())?; + Ok(This(T::from_value(&arg)?)) + } + } +} + +/// Identifier is an argument extractor that attempts to extract an identifier +/// from an argument's expression. +/// +/// It fails if the argument is not available, or if the argument cannot be +/// converted into an expression. +/// +/// # Examples +/// Identifiers are useful for functions like `.map` or `.filter` where one +/// of the arguments is the declaration of a variable. In this case, as noted +/// below, the x is an identifier, and we want to be able to parse it +/// automatically. +/// +/// ```javascript +/// // Identifier +/// // ↓ +/// [1, 2, 3].map(x, x * 2) == [2, 4, 6] +/// ``` +/// +/// The function signature for the Rust implementation of `map` looks like this +/// +/// ```skip +/// pub fn map( +/// ftx: &FunctionContext, +/// This(this): This, // <- [1, 2, 3] +/// ident: Identifier, // <- x +/// expr: Expression, // <- x * 2 +/// ) -> Result; +/// ``` +#[derive(Clone)] +pub struct Identifier(pub Arc); + +impl<'a, 'context> FromContext<'a, 'context> for Identifier { + fn from_context(ctx: &'a mut FunctionContext<'context>) -> Result + where + Self: Sized, + { + match &arg_expr_from_context(ctx).expr { + Expr::Ident(ident) => Ok(Identifier(ident.clone().into())), + expr => Err(ExecutionError::UnexpectedType { + got: format!("{expr:?}"), + want: "identifier".to_string(), + }), + } + } +} + +impl From<&Identifier> for String { + fn from(value: &Identifier) -> Self { + value.0.to_string() + } +} + +impl From for String { + fn from(value: Identifier) -> Self { + value.0.as_ref().clone() + } +} + +/// An argument extractor that extracts all the arguments passed to a function, resolves their +/// expressions and returns a vector of [`Value`]. +/// +/// This is useful for functions that accept a variable number of arguments rather than known +/// arguments and types (for example a `sum` function). +/// +/// # Example +/// ```javascript +/// sum(1, 2.0, uint(3)) == 5.0 +/// ``` +/// +/// ```rust +/// # use cel::{Value}; +/// use cel::extractors::Arguments; +/// pub fn sum(Arguments(args): Arguments) -> Value { +/// args.iter().fold(0.0, |acc, val| match val { +/// Value::Int(x) => *x as f64 + acc, +/// Value::UInt(x) => *x as f64 + acc, +/// Value::Float(x) => *x + acc, +/// _ => acc, +/// }).into() +/// } +/// ``` +#[derive(Clone)] +pub struct Arguments(pub Arc>); + +impl<'a> FromContext<'a, '_> for Arguments { + fn from_context(ctx: &'a mut FunctionContext) -> Result + where + Self: Sized, + { + match ctx.resolve(AllArguments)? { + Value::List(list) => Ok(Arguments(list.clone())), + _ => todo!(), + } + } +} + +impl<'a, 'context> FromContext<'a, 'context> for Value { + fn from_context(ctx: &'a mut FunctionContext<'context>) -> Result + where + Self: Sized, + { + arg_value_from_context(ctx) + } +} + +impl<'a, 'context> FromContext<'a, 'context> for Expression { + fn from_context(ctx: &'a mut FunctionContext<'context>) -> Result + where + Self: Sized, + { + Ok(arg_expr_from_context(ctx).clone()) + } +} + +/// Returns the next argument specified by the context's `arg_idx` field as an expression +/// (i.e. not resolved). Calling this multiple times will increment the `arg_idx` which will +/// return subsequent arguments every time. +/// +/// Calling this function when there are no more arguments will result in a panic. Since this +/// function is only ever called within the context of a controlled macro that calls it once +/// for each argument, this should never happen. +fn arg_expr_from_context<'a>(ctx: &'a mut FunctionContext) -> &'a Expression { + let idx = ctx.arg_idx; + ctx.arg_idx += 1; + &ctx.args[idx] +} + +/// Returns the next argument specified by the context's `arg_idx` field as after resolving +/// it. Calling this multiple times will increment the `arg_idx` which will return subsequent +/// arguments every time. +/// +/// Calling this function when there are no more arguments will result in a panic. Since this +/// function is only ever called within the context of a controlled macro that calls it once +/// for each argument, this should never happen. +fn arg_value_from_context(ctx: &mut FunctionContext) -> Result { + let idx = ctx.arg_idx; + ctx.arg_idx += 1; + ctx.resolve(Argument(idx)) +} + +pub struct WithFunctionContext; + +impl_handler!(); +impl_handler!(C1); +impl_handler!(C1, C2); +impl_handler!(C1, C2, C3); +impl_handler!(C1, C2, C3, C4); +impl_handler!(C1, C2, C3, C4, C5); +impl_handler!(C1, C2, C3, C4, C5, C6); +impl_handler!(C1, C2, C3, C4, C5, C6, C7); +impl_handler!(C1, C2, C3, C4, C5, C6, C7, C8); +impl_handler!(C1, C2, C3, C4, C5, C6, C7, C8, C9); + +// Heavily inspired by https://users.rust-lang.org/t/common-data-type-for-functions-with-different-parameters-e-g-axum-route-handlers/90207/6 +// and https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c6744c27c2358ec1d1196033a0ec11e4 + +#[derive(Default)] +pub struct FunctionRegistry { + functions: HashMap, +} + +impl FunctionRegistry { + pub(crate) fn add(&mut self, name: &str, function: F) + where + F: IntoFunction + 'static + Send + Sync, + T: 'static, + { + self.functions + .insert(name.to_string(), function.into_function()); + } + + pub(crate) fn get(&self, name: &str) -> Option<&Function> { + self.functions.get(name) + } +} + +pub type Function = Box ResolveResult + Send + Sync>; + +pub trait IntoFunction { + fn into_function(self) -> Function; +} diff --git a/vendor/cel/src/objects.rs b/vendor/cel/src/objects.rs new file mode 100644 index 0000000..17fb187 --- /dev/null +++ b/vendor/cel/src/objects.rs @@ -0,0 +1,1374 @@ +use crate::common::ast::{operators, EntryExpr, Expr}; +use crate::context::Context; +use crate::functions::FunctionContext; +use crate::types::map::MapValue; +use crate::{ExecutionError, Expression}; +use std::cmp::Ordering; +use std::collections::HashMap; +use std::convert::{Infallible, TryFrom, TryInto}; +use std::fmt::{Display, Formatter}; +use std::ops; +use std::ops::Deref; +use std::sync::Arc; +#[cfg(feature = "chrono")] +use std::sync::LazyLock; + +use crate::common::value::CelVal; +#[cfg(feature = "chrono")] +use chrono::TimeZone; + +/// Timestamp values are limited to the range of values which can be serialized as a string: +/// `["0001-01-01T00:00:00Z", "9999-12-31T23:59:59.999999999Z"]`. Since the max is a smaller +/// and the min is a larger timestamp than what is possible to represent with [`DateTime`], +/// we need to perform our own spec-compliant overflow checks. +/// +/// https://github.com/google/cel-spec/blob/master/doc/langdef.md#overflow +#[cfg(feature = "chrono")] +static MAX_TIMESTAMP: LazyLock> = LazyLock::new(|| { + let naive = chrono::NaiveDate::from_ymd_opt(9999, 12, 31) + .unwrap() + .and_hms_nano_opt(23, 59, 59, 999_999_999) + .unwrap(); + chrono::FixedOffset::east_opt(0) + .unwrap() + .from_utc_datetime(&naive) +}); + +#[cfg(feature = "chrono")] +static MIN_TIMESTAMP: LazyLock> = LazyLock::new(|| { + let naive = chrono::NaiveDate::from_ymd_opt(1, 1, 1) + .unwrap() + .and_hms_opt(0, 0, 0) + .unwrap(); + chrono::FixedOffset::east_opt(0) + .unwrap() + .from_utc_datetime(&naive) +}); + +#[derive(Debug, PartialEq, Clone)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +pub struct Map { + pub map: Arc>, +} + +impl PartialOrd for Map { + fn partial_cmp(&self, _: &Self) -> Option { + None + } +} + +impl Map { + /// Returns a reference to the value corresponding to the key. Implicitly converts between int + /// and uint keys. + pub fn get(&self, key: &Key) -> Option<&Value> { + self.map.get(key).or_else(|| { + // Also check keys that are cross type comparable. + let converted = match key { + Key::Int(k) => Key::Uint(u64::try_from(*k).ok()?), + Key::Uint(k) => Key::Int(i64::try_from(*k).ok()?), + _ => return None, + }; + self.map.get(&converted) + }) + } +} + +impl MapValue for Map { + fn get(&self, key: &Key) -> Option { + self.get(key).cloned() + } + + fn contains_key(&self, key: &Key) -> bool { + self.get(key).is_some() + } + + fn len(&self) -> usize { + self.map.len() + } + + fn iter(&self) -> Box + '_> { + Box::new(self.map.iter().map(|(k, v)| (k.clone(), v.clone()))) + } +} + +fn map_values_equal(left: &dyn MapValue, right: &dyn MapValue) -> bool { + if left.len() != right.len() { + return false; + } + + for (key, value) in left.iter() { + match right.get(&key) { + Some(other) if other == value => continue, + _ => return false, + } + } + + true +} + +#[derive(Debug, Eq, PartialEq, Hash, Ord, Clone, PartialOrd)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +pub enum Key { + Int(i64), + Uint(u64), + Bool(bool), + String(Arc), +} + +/// Implement conversions from primitive types to [`Key`] +impl From for Key { + fn from(v: String) -> Self { + Key::String(v.into()) + } +} + +impl From> for Key { + fn from(v: Arc) -> Self { + Key::String(v) + } +} + +impl<'a> From<&'a str> for Key { + fn from(v: &'a str) -> Self { + Key::String(Arc::new(v.into())) + } +} + +impl From for Key { + fn from(v: bool) -> Self { + Key::Bool(v) + } +} + +impl From for Key { + fn from(v: i64) -> Self { + Key::Int(v) + } +} + +impl From for Key { + fn from(v: u64) -> Self { + Key::Uint(v) + } +} + +impl serde::Serialize for Key { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + match self { + Key::Int(v) => v.serialize(serializer), + Key::Uint(v) => v.serialize(serializer), + Key::Bool(v) => v.serialize(serializer), + Key::String(v) => v.serialize(serializer), + } + } +} + +impl Display for Key { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Key::Int(v) => write!(f, "{v}"), + Key::Uint(v) => write!(f, "{v}"), + Key::Bool(v) => write!(f, "{v}"), + Key::String(v) => write!(f, "{v}"), + } + } +} + +/// Implement conversions from [`Key`] into [`Value`] +impl TryInto for Value { + type Error = Value; + + #[inline(always)] + fn try_into(self) -> Result { + match self { + Value::Int(v) => Ok(Key::Int(v)), + Value::UInt(v) => Ok(Key::Uint(v)), + Value::String(v) => Ok(Key::String(v)), + Value::Bool(v) => Ok(Key::Bool(v)), + _ => Err(self), + } + } +} + +// Implement conversion from HashMap into CelMap +impl, V: Into> From> for Map { + fn from(map: HashMap) -> Self { + let mut new_map = HashMap::with_capacity(map.len()); + for (k, v) in map { + new_map.insert(k.into(), v.into()); + } + Map { + map: Arc::new(new_map), + } + } +} + +pub trait TryIntoValue { + type Error: std::error::Error + 'static + Send + Sync; + fn try_into_value(self) -> Result; +} + +impl TryIntoValue for T { + type Error = crate::ser::SerializationError; + fn try_into_value(self) -> Result { + crate::ser::to_value(self) + } +} +impl TryIntoValue for Value { + type Error = Infallible; + fn try_into_value(self) -> Result { + Ok(self) + } +} + +#[derive(Debug, Clone)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +pub enum Value { + List(Arc>), + Map(Map), + DynamicMap(Arc), + + Function(Arc, Option>), + + // Atoms + Int(i64), + UInt(u64), + Float(f64), + String(Arc), + Bytes(Arc>), + Bool(bool), + #[cfg(feature = "chrono")] + Duration(chrono::Duration), + #[cfg(feature = "chrono")] + Timestamp(chrono::DateTime), + Null, +} + +impl From for Value { + fn from(val: CelVal) -> Self { + match val { + CelVal::String(s) => Value::String(Arc::new(s)), + CelVal::Boolean(b) => Value::Bool(b), + CelVal::Int(i) => Value::Int(i), + CelVal::UInt(u) => Value::UInt(u), + CelVal::Double(d) => Value::Float(d), + CelVal::Bytes(bytes) => Value::Bytes(Arc::new(bytes)), + CelVal::Null => Value::Null, + v => unimplemented!("{v:?}"), + } + } +} + +#[derive(Clone, Copy, Debug)] +pub enum ValueType { + List, + Map, + Function, + Int, + UInt, + Float, + String, + Bytes, + Bool, + Duration, + Timestamp, + Null, +} + +impl Display for ValueType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + ValueType::List => write!(f, "list"), + ValueType::Map => write!(f, "map"), + ValueType::Function => write!(f, "function"), + ValueType::Int => write!(f, "int"), + ValueType::UInt => write!(f, "uint"), + ValueType::Float => write!(f, "float"), + ValueType::String => write!(f, "string"), + ValueType::Bytes => write!(f, "bytes"), + ValueType::Bool => write!(f, "bool"), + ValueType::Duration => write!(f, "duration"), + ValueType::Timestamp => write!(f, "timestamp"), + ValueType::Null => write!(f, "null"), + } + } +} + +impl Value { + fn as_map_value(&self) -> Option<&dyn MapValue> { + match self { + Value::Map(map) => Some(map), + Value::DynamicMap(map) => Some(map.as_ref()), + _ => None, + } + } + + pub fn type_of(&self) -> ValueType { + match self { + Value::List(_) => ValueType::List, + Value::Map(_) | Value::DynamicMap(_) => ValueType::Map, + Value::Function(_, _) => ValueType::Function, + Value::Int(_) => ValueType::Int, + Value::UInt(_) => ValueType::UInt, + Value::Float(_) => ValueType::Float, + Value::String(_) => ValueType::String, + Value::Bytes(_) => ValueType::Bytes, + Value::Bool(_) => ValueType::Bool, + #[cfg(feature = "chrono")] + Value::Duration(_) => ValueType::Duration, + #[cfg(feature = "chrono")] + Value::Timestamp(_) => ValueType::Timestamp, + Value::Null => ValueType::Null, + } + } + + pub fn error_expected_type(&self, expected: ValueType) -> ExecutionError { + ExecutionError::UnexpectedType { + got: self.type_of().to_string(), + want: expected.to_string(), + } + } +} + +impl From<&Value> for Value { + fn from(value: &Value) -> Self { + value.clone() + } +} + +impl PartialEq for Value { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Value::Map(a), Value::Map(b)) => a == b, + (Value::Map(a), Value::DynamicMap(b)) => map_values_equal(a, b.as_ref()), + (Value::DynamicMap(a), Value::Map(b)) => map_values_equal(a.as_ref(), b), + (Value::DynamicMap(a), Value::DynamicMap(b)) => map_values_equal(a.as_ref(), b.as_ref()), + (Value::List(a), Value::List(b)) => a == b, + (Value::Function(a1, a2), Value::Function(b1, b2)) => a1 == b1 && a2 == b2, + (Value::Int(a), Value::Int(b)) => a == b, + (Value::UInt(a), Value::UInt(b)) => a == b, + (Value::Float(a), Value::Float(b)) => a == b, + (Value::String(a), Value::String(b)) => a == b, + (Value::Bytes(a), Value::Bytes(b)) => a == b, + (Value::Bool(a), Value::Bool(b)) => a == b, + (Value::Null, Value::Null) => true, + #[cfg(feature = "chrono")] + (Value::Duration(a), Value::Duration(b)) => a == b, + #[cfg(feature = "chrono")] + (Value::Timestamp(a), Value::Timestamp(b)) => a == b, + // Allow different numeric types to be compared without explicit casting. + (Value::Int(a), Value::UInt(b)) => a + .to_owned() + .try_into() + .map(|a: u64| a == *b) + .unwrap_or(false), + (Value::Int(a), Value::Float(b)) => (*a as f64) == *b, + (Value::UInt(a), Value::Int(b)) => a + .to_owned() + .try_into() + .map(|a: i64| a == *b) + .unwrap_or(false), + (Value::UInt(a), Value::Float(b)) => (*a as f64) == *b, + (Value::Float(a), Value::Int(b)) => *a == (*b as f64), + (Value::Float(a), Value::UInt(b)) => *a == (*b as f64), + (_, _) => false, + } + } +} + +impl Eq for Value {} + +impl PartialOrd for Value { + fn partial_cmp(&self, other: &Self) -> Option { + match (self, other) { + (Value::Int(a), Value::Int(b)) => Some(a.cmp(b)), + (Value::UInt(a), Value::UInt(b)) => Some(a.cmp(b)), + (Value::Float(a), Value::Float(b)) => a.partial_cmp(b), + (Value::String(a), Value::String(b)) => Some(a.cmp(b)), + (Value::Bool(a), Value::Bool(b)) => Some(a.cmp(b)), + (Value::Null, Value::Null) => Some(Ordering::Equal), + #[cfg(feature = "chrono")] + (Value::Duration(a), Value::Duration(b)) => Some(a.cmp(b)), + #[cfg(feature = "chrono")] + (Value::Timestamp(a), Value::Timestamp(b)) => Some(a.cmp(b)), + // Allow different numeric types to be compared without explicit casting. + (Value::Int(a), Value::UInt(b)) => Some( + a.to_owned() + .try_into() + .map(|a: u64| a.cmp(b)) + // If the i64 doesn't fit into a u64 it must be less than 0. + .unwrap_or(Ordering::Less), + ), + (Value::Int(a), Value::Float(b)) => (*a as f64).partial_cmp(b), + (Value::UInt(a), Value::Int(b)) => Some( + a.to_owned() + .try_into() + .map(|a: i64| a.cmp(b)) + // If the u64 doesn't fit into a i64 it must be greater than i64::MAX. + .unwrap_or(Ordering::Greater), + ), + (Value::UInt(a), Value::Float(b)) => (*a as f64).partial_cmp(b), + (Value::Float(a), Value::Int(b)) => a.partial_cmp(&(*b as f64)), + (Value::Float(a), Value::UInt(b)) => a.partial_cmp(&(*b as f64)), + _ => None, + } + } +} + +impl From<&Key> for Value { + fn from(value: &Key) -> Self { + match value { + Key::Int(v) => Value::Int(*v), + Key::Uint(v) => Value::UInt(*v), + Key::Bool(v) => Value::Bool(*v), + Key::String(v) => Value::String(v.clone()), + } + } +} + +impl From for Value { + fn from(value: Key) -> Self { + match value { + Key::Int(v) => Value::Int(v), + Key::Uint(v) => Value::UInt(v), + Key::Bool(v) => Value::Bool(v), + Key::String(v) => Value::String(v), + } + } +} + +impl From<&Key> for Key { + fn from(key: &Key) -> Self { + key.clone() + } +} + +// Convert Vec to Value +impl> From> for Value { + fn from(v: Vec) -> Self { + Value::List(v.into_iter().map(|v| v.into()).collect::>().into()) + } +} + +// Convert Vec to Value +impl From> for Value { + fn from(v: Vec) -> Self { + Value::Bytes(v.into()) + } +} + +// Convert String to Value +impl From for Value { + fn from(v: String) -> Self { + Value::String(v.into()) + } +} + +impl From<&str> for Value { + fn from(v: &str) -> Self { + Value::String(v.to_string().into()) + } +} + +// Convert Option to Value +impl> From> for Value { + fn from(v: Option) -> Self { + match v { + Some(v) => v.into(), + None => Value::Null, + } + } +} + +// Convert HashMap to Value +impl, V: Into> From> for Value { + fn from(v: HashMap) -> Self { + Value::Map(v.into()) + } +} + +impl From for ResolveResult { + fn from(value: ExecutionError) -> Self { + Err(value) + } +} + +pub type ResolveResult = Result; + +impl From for ResolveResult { + fn from(value: Value) -> Self { + Ok(value) + } +} + +impl Value { + pub fn resolve_all(expr: &[Expression], ctx: &Context) -> ResolveResult { + let mut res = Vec::with_capacity(expr.len()); + for expr in expr { + res.push(Value::resolve(expr, ctx)?); + } + Ok(Value::List(res.into())) + } + + #[inline(always)] + pub fn resolve(expr: &Expression, ctx: &Context) -> ResolveResult { + match &expr.expr { + Expr::Literal(val) => Ok(val.clone().into()), + Expr::Call(call) => { + if call.args.len() == 3 && call.func_name == operators::CONDITIONAL { + let cond = Value::resolve(&call.args[0], ctx)?; + return if cond.to_bool()? { + Value::resolve(&call.args[1], ctx) + } else { + Value::resolve(&call.args[2], ctx) + }; + } + if call.args.len() == 2 { + match call.func_name.as_str() { + operators::ADD => { + return Value::resolve(&call.args[0], ctx)? + + Value::resolve(&call.args[1], ctx)? + } + operators::SUBSTRACT => { + return Value::resolve(&call.args[0], ctx)? + - Value::resolve(&call.args[1], ctx)? + } + operators::DIVIDE => { + return Value::resolve(&call.args[0], ctx)? + / Value::resolve(&call.args[1], ctx)? + } + operators::MULTIPLY => { + return Value::resolve(&call.args[0], ctx)? + * Value::resolve(&call.args[1], ctx)? + } + operators::MODULO => { + return Value::resolve(&call.args[0], ctx)? + % Value::resolve(&call.args[1], ctx)? + } + operators::EQUALS => { + return Value::Bool( + Value::resolve(&call.args[0], ctx)? + .eq(&Value::resolve(&call.args[1], ctx)?), + ) + .into() + } + operators::NOT_EQUALS => { + return Value::Bool( + Value::resolve(&call.args[0], ctx)? + .ne(&Value::resolve(&call.args[1], ctx)?), + ) + .into() + } + operators::LESS => { + let left = Value::resolve(&call.args[0], ctx)?; + let right = Value::resolve(&call.args[1], ctx)?; + return Value::Bool( + left.partial_cmp(&right) + .ok_or(ExecutionError::ValuesNotComparable(left, right))? + == Ordering::Less, + ) + .into(); + } + operators::LESS_EQUALS => { + let left = Value::resolve(&call.args[0], ctx)?; + let right = Value::resolve(&call.args[1], ctx)?; + return Value::Bool( + left.partial_cmp(&right) + .ok_or(ExecutionError::ValuesNotComparable(left, right))? + != Ordering::Greater, + ) + .into(); + } + operators::GREATER => { + let left = Value::resolve(&call.args[0], ctx)?; + let right = Value::resolve(&call.args[1], ctx)?; + return Value::Bool( + left.partial_cmp(&right) + .ok_or(ExecutionError::ValuesNotComparable(left, right))? + == Ordering::Greater, + ) + .into(); + } + operators::GREATER_EQUALS => { + let left = Value::resolve(&call.args[0], ctx)?; + let right = Value::resolve(&call.args[1], ctx)?; + return Value::Bool( + left.partial_cmp(&right) + .ok_or(ExecutionError::ValuesNotComparable(left, right))? + != Ordering::Less, + ) + .into(); + } + operators::IN => { + let left = Value::resolve(&call.args[0], ctx)?; + let right = Value::resolve(&call.args[1], ctx)?; + match (left, right) { + (Value::String(l), Value::String(r)) => { + return Value::Bool(r.contains(&*l)).into() + } + (any, Value::List(v)) => { + return Value::Bool(v.contains(&any)).into() + } + (any, map_value) + if matches!(map_value, Value::Map(_) | Value::DynamicMap(_)) => + { + if let Ok(key) = any.try_into() { + let contains = map_value + .as_map_value() + .expect("checked map variant") + .contains_key(&key); + return Value::Bool(contains).into(); + } else { + return Value::Bool(false).into(); + } + }, + (left, right) => { + Err(ExecutionError::ValuesNotComparable(left, right))? + } + } + } + operators::LOGICAL_OR => { + let left = Value::resolve(&call.args[0], ctx)?; + return if left.to_bool()? { + left.into() + } else { + Value::resolve(&call.args[1], ctx) + }; + } + operators::LOGICAL_AND => { + let left = Value::resolve(&call.args[0], ctx)?; + return if !left.to_bool()? { + Value::Bool(false) + } else { + let right = Value::resolve(&call.args[1], ctx)?; + Value::Bool(right.to_bool()?) + } + .into(); + } + operators::INDEX => { + let value = Value::resolve(&call.args[0], ctx)?; + let idx = Value::resolve(&call.args[1], ctx)?; + return match (value, idx) { + (Value::List(items), Value::Int(idx)) => { + if idx >= 0 && (idx as usize) < items.len() { + items[idx as usize].clone().into() + } else { + Err(ExecutionError::IndexOutOfBounds(idx.into())) + } + } + (Value::List(items), Value::UInt(idx)) => { + if (idx as usize) < items.len() { + items[idx as usize].clone().into() + } else { + Err(ExecutionError::IndexOutOfBounds(idx.into())) + } + } + (Value::String(_), Value::Int(idx)) => { + Err(ExecutionError::NoSuchKey(idx.to_string().into())) + } + (map_value, index) + if matches!(map_value, Value::Map(_) | Value::DynamicMap(_)) => + { + let map = map_value + .as_map_value() + .expect("checked map variant"); + match index.try_into() { + Ok(key) => map.get(&key).unwrap_or(Value::Null).into(), + Err(index) => { + Err(ExecutionError::UnsupportedMapIndex(index)) + } + } + } + (Value::List(_), index) => { + Err(ExecutionError::UnsupportedListIndex(index)) + } + (value, index) => { + Err(ExecutionError::UnsupportedIndex(value, index)) + } + }; + } + _ => (), + } + } + if call.args.len() == 1 { + let expr = Value::resolve(&call.args[0], ctx)?; + match call.func_name.as_str() { + operators::LOGICAL_NOT => return Ok(Value::Bool(!expr.to_bool()?)), + operators::NEGATE => { + return match expr { + Value::Int(i) => Ok(Value::Int(-i)), + Value::Float(f) => Ok(Value::Float(-f)), + value => { + Err(ExecutionError::UnsupportedUnaryOperator("minus", value)) + } + } + } + operators::NOT_STRICTLY_FALSE => { + return match expr { + Value::Bool(b) => Ok(Value::Bool(b)), + _ => Ok(Value::Bool(true)), + } + } + _ => (), + } + } + let func = ctx.get_function(call.func_name.as_str()).ok_or_else(|| { + ExecutionError::UndeclaredReference(call.func_name.clone().into()) + })?; + match &call.target { + None => { + let mut ctx = FunctionContext::new( + call.func_name.clone().into(), + None, + ctx, + call.args.clone(), + ); + (func)(&mut ctx) + } + Some(target) => { + let mut ctx = FunctionContext::new( + call.func_name.clone().into(), + Some(Value::resolve(target, ctx)?), + ctx, + call.args.clone(), + ); + (func)(&mut ctx) + } + } + } + Expr::Ident(name) => ctx.get_variable(name), + Expr::Select(select) => { + let left = Value::resolve(select.operand.deref(), ctx)?; + if select.test { + match left.as_map_value() { + Some(map) => Ok(Value::Bool( + map.iter().any(|(key, _)| key.to_string() == select.field), + )), + None => Ok(Value::Bool(false)), + } + } else { + left.member(&select.field) + } + } + Expr::List(list_expr) => { + let list = list_expr + .elements + .iter() + .map(|i| Value::resolve(i, ctx)) + .collect::, _>>()?; + Value::List(list.into()).into() + } + Expr::Map(map_expr) => { + let mut map = HashMap::with_capacity(map_expr.entries.len()); + for entry in map_expr.entries.iter() { + let (k, v) = match &entry.expr { + EntryExpr::StructField(_) => panic!("WAT?"), + EntryExpr::MapEntry(e) => (&e.key, &e.value), + }; + let key = Value::resolve(k, ctx)? + .try_into() + .map_err(ExecutionError::UnsupportedKeyType)?; + let value = Value::resolve(v, ctx)?; + map.insert(key, value); + } + Ok(Value::Map(Map { + map: Arc::from(map), + })) + } + Expr::Comprehension(comprehension) => { + let accu_init = Value::resolve(&comprehension.accu_init, ctx)?; + let iter = Value::resolve(&comprehension.iter_range, ctx)?; + let mut ctx = ctx.new_inner_scope(); + ctx.add_variable(&comprehension.accu_var, accu_init) + .expect("Failed to add accu variable"); + + match iter { + Value::List(items) => { + for item in items.deref() { + if !Value::resolve(&comprehension.loop_cond, &ctx)?.to_bool()? { + break; + } + ctx.add_variable_from_value(&comprehension.iter_var, item.clone()); + let accu = Value::resolve(&comprehension.loop_step, &ctx)?; + ctx.add_variable_from_value(&comprehension.accu_var, accu); + } + } + map_value if matches!(map_value, Value::Map(_) | Value::DynamicMap(_)) => { + let map = map_value + .as_map_value() + .expect("checked map variant"); + for (key, _) in map.iter() { + if !Value::resolve(&comprehension.loop_cond, &ctx)?.to_bool()? { + break; + } + ctx.add_variable_from_value( + &comprehension.iter_var, + Value::from(key.clone()), + ); + let accu = Value::resolve(&comprehension.loop_step, &ctx)?; + ctx.add_variable_from_value(&comprehension.accu_var, accu); + } + } + t => todo!("Support {t:?}"), + } + Value::resolve(&comprehension.result, &ctx) + } + Expr::Struct(_) => todo!("Support structs!"), + Expr::Unspecified => panic!("Can't evaluate Unspecified Expr"), + } + } + + // >> a(b) + // Member(Ident("a"), + // FunctionCall([Ident("b")])) + // >> a.b(c) + // Member(Member(Ident("a"), + // Attribute("b")), + // FunctionCall([Ident("c")])) + + fn member(self, name: &str) -> ResolveResult { + // todo! Ideally we would avoid creating a String just to create a Key for lookup in the + // map, but this would require something like the `hashbrown` crate's `Equivalent` trait. + let name: Arc = name.to_owned().into(); + + // This will always either be because we're trying to access + // a property on self, or a method on self. + let child = self + .as_map_value() + .and_then(|map| map.get(&name.clone().into())); + + // If the property is both an attribute and a method, then we + // give priority to the property. Maybe we can implement lookahead + // to see if the next token is a function call? + if let Some(child) = child { + child.into() + } else { + ExecutionError::NoSuchKey(name.clone()).into() + } + } + + #[inline(always)] + fn to_bool(&self) -> Result { + match self { + Value::Bool(v) => Ok(*v), + _ => Err(ExecutionError::NoSuchOverload), + } + } +} + +impl ops::Add for Value { + type Output = ResolveResult; + + #[inline(always)] + fn add(self, rhs: Value) -> Self::Output { + match (self, rhs) { + (Value::Int(l), Value::Int(r)) => l + .checked_add(r) + .ok_or(ExecutionError::Overflow("add", l.into(), r.into())) + .map(Value::Int), + + (Value::UInt(l), Value::UInt(r)) => l + .checked_add(r) + .ok_or(ExecutionError::Overflow("add", l.into(), r.into())) + .map(Value::UInt), + + (Value::Float(l), Value::Float(r)) => Value::Float(l + r).into(), + + (Value::List(mut l), Value::List(mut r)) => { + { + // If this is the only reference to `l`, we can append to it in place. + // `l` is replaced with a clone otherwise. + let l = Arc::make_mut(&mut l); + + // Likewise, if this is the only reference to `r`, we can move its values + // instead of cloning them. + match Arc::get_mut(&mut r) { + Some(r) => l.append(r), + None => l.extend(r.iter().cloned()), + } + } + + Ok(Value::List(l)) + } + (Value::String(mut l), Value::String(r)) => { + // If this is the only reference to `l`, we can append to it in place. + // `l` is replaced with a clone otherwise. + Arc::make_mut(&mut l).push_str(&r); + Ok(Value::String(l)) + } + #[cfg(feature = "chrono")] + (Value::Duration(l), Value::Duration(r)) => l + .checked_add(&r) + .ok_or(ExecutionError::Overflow("add", l.into(), r.into())) + .map(Value::Duration), + #[cfg(feature = "chrono")] + (Value::Timestamp(l), Value::Duration(r)) => checked_op(TsOp::Add, &l, &r), + #[cfg(feature = "chrono")] + (Value::Duration(l), Value::Timestamp(r)) => r + .checked_add_signed(l) + .ok_or(ExecutionError::Overflow("add", l.into(), r.into())) + .map(Value::Timestamp), + (left, right) => Err(ExecutionError::UnsupportedBinaryOperator( + "add", left, right, + )), + } + } +} + +impl ops::Sub for Value { + type Output = ResolveResult; + + #[inline(always)] + fn sub(self, rhs: Value) -> Self::Output { + match (self, rhs) { + (Value::Int(l), Value::Int(r)) => l + .checked_sub(r) + .ok_or(ExecutionError::Overflow("sub", l.into(), r.into())) + .map(Value::Int), + + (Value::UInt(l), Value::UInt(r)) => l + .checked_sub(r) + .ok_or(ExecutionError::Overflow("sub", l.into(), r.into())) + .map(Value::UInt), + + (Value::Float(l), Value::Float(r)) => Value::Float(l - r).into(), + + #[cfg(feature = "chrono")] + (Value::Duration(l), Value::Duration(r)) => l + .checked_sub(&r) + .ok_or(ExecutionError::Overflow("sub", l.into(), r.into())) + .map(Value::Duration), + #[cfg(feature = "chrono")] + (Value::Timestamp(l), Value::Duration(r)) => checked_op(TsOp::Sub, &l, &r), + #[cfg(feature = "chrono")] + (Value::Timestamp(l), Value::Timestamp(r)) => { + Value::Duration(l.signed_duration_since(r)).into() + } + (left, right) => Err(ExecutionError::UnsupportedBinaryOperator( + "sub", left, right, + )), + } + } +} + +impl ops::Div for Value { + type Output = ResolveResult; + + #[inline(always)] + fn div(self, rhs: Value) -> Self::Output { + match (self, rhs) { + (Value::Int(l), Value::Int(r)) => { + if r == 0 { + Err(ExecutionError::DivisionByZero(l.into())) + } else { + l.checked_div(r) + .ok_or(ExecutionError::Overflow("div", l.into(), r.into())) + .map(Value::Int) + } + } + + (Value::UInt(l), Value::UInt(r)) => l + .checked_div(r) + .ok_or(ExecutionError::DivisionByZero(l.into())) + .map(Value::UInt), + + (Value::Float(l), Value::Float(r)) => Value::Float(l / r).into(), + + (left, right) => Err(ExecutionError::UnsupportedBinaryOperator( + "div", left, right, + )), + } + } +} + +impl ops::Mul for Value { + type Output = ResolveResult; + + #[inline(always)] + fn mul(self, rhs: Value) -> Self::Output { + match (self, rhs) { + (Value::Int(l), Value::Int(r)) => l + .checked_mul(r) + .ok_or(ExecutionError::Overflow("mul", l.into(), r.into())) + .map(Value::Int), + + (Value::UInt(l), Value::UInt(r)) => l + .checked_mul(r) + .ok_or(ExecutionError::Overflow("mul", l.into(), r.into())) + .map(Value::UInt), + + (Value::Float(l), Value::Float(r)) => Value::Float(l * r).into(), + + (left, right) => Err(ExecutionError::UnsupportedBinaryOperator( + "mul", left, right, + )), + } + } +} + +impl ops::Rem for Value { + type Output = ResolveResult; + + #[inline(always)] + fn rem(self, rhs: Value) -> Self::Output { + match (self, rhs) { + (Value::Int(l), Value::Int(r)) => { + if r == 0 { + Err(ExecutionError::RemainderByZero(l.into())) + } else { + l.checked_rem(r) + .ok_or(ExecutionError::Overflow("rem", l.into(), r.into())) + .map(Value::Int) + } + } + + (Value::UInt(l), Value::UInt(r)) => l + .checked_rem(r) + .ok_or(ExecutionError::RemainderByZero(l.into())) + .map(Value::UInt), + + (left, right) => Err(ExecutionError::UnsupportedBinaryOperator( + "rem", left, right, + )), + } + } +} + +/// Op represents a binary arithmetic operation supported on a timestamp +/// +#[cfg(feature = "chrono")] +enum TsOp { + Add, + Sub, +} + +#[cfg(feature = "chrono")] +impl TsOp { + fn str(&self) -> &'static str { + match self { + TsOp::Add => "add", + TsOp::Sub => "sub", + } + } +} + +/// Performs a checked arithmetic operation [`TsOp`] on a timestamp and a duration and ensures that +/// the resulting timestamp does not overflow the data type internal limits, as well as the timestamp +/// limits defined in the cel-spec. See [`MAX_TIMESTAMP`] and [`MIN_TIMESTAMP`] for more details. +#[cfg(feature = "chrono")] +fn checked_op( + op: TsOp, + lhs: &chrono::DateTime, + rhs: &chrono::Duration, +) -> ResolveResult { + // Add lhs and rhs together, checking for data type overflow + let result = match op { + TsOp::Add => lhs.checked_add_signed(*rhs), + TsOp::Sub => lhs.checked_sub_signed(*rhs), + } + .ok_or(ExecutionError::Overflow( + op.str(), + (*lhs).into(), + (*rhs).into(), + ))?; + + // Check for cel-spec limits + if result > *MAX_TIMESTAMP || result < *MIN_TIMESTAMP { + Err(ExecutionError::Overflow( + op.str(), + (*lhs).into(), + (*rhs).into(), + )) + } else { + Value::Timestamp(result).into() + } +} + +#[cfg(test)] +mod tests { + use crate::{objects::Key, Context, ExecutionError, Program, Value}; + use std::collections::HashMap; + use std::sync::Arc; + + #[test] + fn test_indexed_map_access() { + let mut context = Context::default(); + let mut headers = HashMap::new(); + headers.insert("Content-Type", "application/json".to_string()); + context.add_variable_from_value("headers", headers); + + let program = Program::compile("headers[\"Content-Type\"]").unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, "application/json".into()); + } + + #[test] + fn test_numeric_map_access() { + let mut context = Context::default(); + let mut numbers = HashMap::new(); + numbers.insert(Key::Uint(1), "one".to_string()); + context.add_variable_from_value("numbers", numbers); + + let program = Program::compile("numbers[1]").unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, "one".into()); + } + + #[test] + fn test_heterogeneous_compare() { + let context = Context::default(); + + let program = Program::compile("1 < uint(2)").unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, true.into()); + + let program = Program::compile("1 < 1.1").unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, true.into()); + + let program = Program::compile("uint(0) > -10").unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!( + value, + true.into(), + "negative signed ints should be less than uints" + ); + } + + #[test] + fn test_float_compare() { + let context = Context::default(); + + let program = Program::compile("1.0 > 0.0").unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, true.into()); + + let program = Program::compile("double('NaN') == double('NaN')").unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, false.into(), "NaN should not equal itself"); + + let program = Program::compile("1.0 > double('NaN')").unwrap(); + let result = program.execute(&context); + assert!( + result.is_err(), + "NaN should not be comparable with inequality operators" + ); + } + + #[test] + fn test_invalid_compare() { + let context = Context::default(); + + let program = Program::compile("{} == []").unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, false.into()); + } + + #[test] + fn test_size_fn_var() { + let program = Program::compile("size(requests) + size == 5").unwrap(); + let mut context = Context::default(); + let requests = vec![Value::Int(42), Value::Int(42)]; + context + .add_variable("requests", Value::List(Arc::new(requests))) + .unwrap(); + context.add_variable("size", Value::Int(3)).unwrap(); + assert_eq!(program.execute(&context).unwrap(), Value::Bool(true)); + } + + fn test_execution_error(program: &str, expected: ExecutionError) { + let program = Program::compile(program).unwrap(); + let result = program.execute(&Context::default()); + assert_eq!(result.unwrap_err(), expected); + } + + #[test] + fn test_invalid_sub() { + test_execution_error( + "'foo' - 10", + ExecutionError::UnsupportedBinaryOperator("sub", "foo".into(), Value::Int(10)), + ); + } + + #[test] + fn test_invalid_add() { + test_execution_error( + "'foo' + 10", + ExecutionError::UnsupportedBinaryOperator("add", "foo".into(), Value::Int(10)), + ); + } + + #[test] + fn test_invalid_div() { + test_execution_error( + "'foo' / 10", + ExecutionError::UnsupportedBinaryOperator("div", "foo".into(), Value::Int(10)), + ); + } + + #[test] + fn test_invalid_rem() { + test_execution_error( + "'foo' % 10", + ExecutionError::UnsupportedBinaryOperator("rem", "foo".into(), Value::Int(10)), + ); + } + + #[test] + fn out_of_bound_list_access() { + let program = Program::compile("list[10]").unwrap(); + let mut context = Context::default(); + context + .add_variable("list", Value::List(Arc::new(vec![]))) + .unwrap(); + let result = program.execute(&context); + assert_eq!( + result, + Err(ExecutionError::IndexOutOfBounds(Value::Int(10))) + ); + } + + #[test] + fn out_of_bound_list_access_negative() { + let program = Program::compile("list[-1]").unwrap(); + let mut context = Context::default(); + context + .add_variable("list", Value::List(Arc::new(vec![]))) + .unwrap(); + let result = program.execute(&context); + assert_eq!( + result, + Err(ExecutionError::IndexOutOfBounds(Value::Int(-1))) + ); + } + + #[test] + fn list_access_uint() { + let program = Program::compile("list[1u]").unwrap(); + let mut context = Context::default(); + context + .add_variable("list", Value::List(Arc::new(vec![1.into(), 2.into()]))) + .unwrap(); + let result = program.execute(&context); + assert_eq!(result, Ok(Value::Int(2.into()))); + } + + #[test] + fn reference_to_value() { + let test = "example".to_string(); + let direct: Value = test.as_str().into(); + assert_eq!(direct, Value::String(Arc::new(String::from("example")))); + + let vec = vec![test.as_str()]; + let indirect: Value = vec.into(); + assert_eq!( + indirect, + Value::List(Arc::new(vec![Value::String(Arc::new(String::from( + "example" + )))])) + ); + } + + #[test] + fn test_short_circuit_and() { + let mut context = Context::default(); + let data: HashMap = HashMap::new(); + context.add_variable_from_value("data", data); + + let program = Program::compile("has(data.x) && data.x.startsWith(\"foo\")").unwrap(); + let value = program.execute(&context); + println!("{value:?}"); + assert!( + value.is_ok(), + "The AND expression should support short-circuit evaluation." + ); + } + + #[test] + fn invalid_int_math() { + use ExecutionError::*; + + let cases = [ + ("1 / 0", DivisionByZero(1.into())), + ("1 % 0", RemainderByZero(1.into())), + ( + &format!("{} + 1", i64::MAX), + Overflow("add", i64::MAX.into(), 1.into()), + ), + ( + &format!("{} - 1", i64::MIN), + Overflow("sub", i64::MIN.into(), 1.into()), + ), + ( + &format!("{} * 2", i64::MAX), + Overflow("mul", i64::MAX.into(), 2.into()), + ), + ( + &format!("{} / -1", i64::MIN), + Overflow("div", i64::MIN.into(), (-1).into()), + ), + ( + &format!("{} % -1", i64::MIN), + Overflow("rem", i64::MIN.into(), (-1).into()), + ), + ]; + + for (expr, err) in cases { + test_execution_error(expr, err); + } + } + + #[test] + fn invalid_uint_math() { + use ExecutionError::*; + + let cases = [ + ("1u / 0u", DivisionByZero(1u64.into())), + ("1u % 0u", RemainderByZero(1u64.into())), + ( + &format!("{}u + 1u", u64::MAX), + Overflow("add", u64::MAX.into(), 1u64.into()), + ), + ("0u - 1u", Overflow("sub", 0u64.into(), 1u64.into())), + ( + &format!("{}u * 2u", u64::MAX), + Overflow("mul", u64::MAX.into(), 2u64.into()), + ), + ]; + + for (expr, err) in cases { + test_execution_error(expr, err); + } + } + + #[test] + fn test_function_identifier() { + fn with( + ftx: &crate::FunctionContext, + crate::extractors::This(this): crate::extractors::This, + ident: crate::extractors::Identifier, + expr: crate::parser::Expression, + ) -> crate::ResolveResult { + let mut ptx = ftx.ptx.new_inner_scope(); + ptx.add_variable_from_value(&ident, this); + ptx.resolve(&expr) + } + let mut context = Context::default(); + context.add_function("with", with); + + let program = Program::compile("[1,2].with(a, a + a)").unwrap(); + let value = program.execute(&context); + assert_eq!( + value, + Ok(Value::List(Arc::new(vec![ + Value::Int(1), + Value::Int(2), + Value::Int(1), + Value::Int(2) + ]))) + ); + } +} diff --git a/vendor/cel/src/parser/gen/CEL.g4 b/vendor/cel/src/parser/gen/CEL.g4 new file mode 100644 index 0000000..ea3e2b3 --- /dev/null +++ b/vendor/cel/src/parser/gen/CEL.g4 @@ -0,0 +1,207 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +grammar CEL; + +// Grammar Rules +// ============= + +start + : e=expr EOF + ; + +expr + : e=conditionalOr (op='?' e1=conditionalOr ':' e2=expr)? + ; + +conditionalOr + : e=conditionalAnd (ops+='||' e1+=conditionalAnd)* + ; + +conditionalAnd + : e=relation (ops+='&&' e1+=relation)* + ; + +relation + : calc + | relation op=('<'|'<='|'>='|'>'|'=='|'!='|'in') relation + ; + +calc + : unary + | calc op=('*'|'/'|'%') calc + | calc op=('+'|'-') calc + ; + +unary + : member # MemberExpr + | (ops+='!')+ member # LogicalNot + | (ops+='-')+ member # Negate + ; + +member + : primary # PrimaryExpr + | member op='.' (opt='?')? id=escapeIdent # Select + | member op='.' id=IDENTIFIER open='(' args=exprList? ')' # MemberCall + | member op='[' (opt='?')? index=expr ']' # Index + ; + +primary + : leadingDot='.'? id=IDENTIFIER # Ident + | leadingDot='.'? id=IDENTIFIER (op='(' args=exprList? ')') # GlobalCall + | '(' e=expr ')' # Nested + | op='[' elems=listInit? ','? ']' # CreateList + | op='{' entries=mapInitializerList? ','? '}' # CreateStruct + | leadingDot='.'? ids+=IDENTIFIER (ops+='.' ids+=IDENTIFIER)* + op='{' entries=field_initializer_list? ','? '}' # CreateMessage + | literal # ConstantLiteral + ; + +exprList + : e+=expr (',' e+=expr)* + ; + +listInit + : elems+=optExpr (',' elems+=optExpr)* + ; + +field_initializer_list + : fields+=optField cols+=':' values+=expr (',' fields+=optField cols+=':' values+=expr)* + ; + +optField + : (opt='?')? escapeIdent + ; + +mapInitializerList + : keys+=optExpr cols+=':' values+=expr (',' keys+=optExpr cols+=':' values+=expr)* + ; + +escapeIdent + : id=IDENTIFIER # SimpleIdentifier + | id=ESC_IDENTIFIER # EscapedIdentifier +; + +optExpr + : (opt='?')? e=expr + ; + +literal + : sign=MINUS? tok=NUM_INT # Int + | tok=NUM_UINT # Uint + | sign=MINUS? tok=NUM_FLOAT # Double + | tok=STRING # String + | tok=BYTES # Bytes + | tok=CEL_TRUE # BoolTrue + | tok=CEL_FALSE # BoolFalse + | tok=NUL # Null + ; + +// Lexer Rules +// =========== + +EQUALS : '=='; +NOT_EQUALS : '!='; +IN: 'in'; +LESS : '<'; +LESS_EQUALS : '<='; +GREATER_EQUALS : '>='; +GREATER : '>'; +LOGICAL_AND : '&&'; +LOGICAL_OR : '||'; + +LBRACKET : '['; +RPRACKET : ']'; +LBRACE : '{'; +RBRACE : '}'; +LPAREN : '('; +RPAREN : ')'; +DOT : '.'; +COMMA : ','; +MINUS : '-'; +EXCLAM : '!'; +QUESTIONMARK : '?'; +COLON : ':'; +PLUS : '+'; +STAR : '*'; +SLASH : '/'; +PERCENT : '%'; +CEL_TRUE : 'true'; +CEL_FALSE : 'false'; +NUL : 'null'; + +fragment BACKSLASH : '\\'; +fragment LETTER : 'A'..'Z' | 'a'..'z' ; +fragment DIGIT : '0'..'9' ; +fragment EXPONENT : ('e' | 'E') ( '+' | '-' )? DIGIT+ ; +fragment HEXDIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ; +fragment RAW : 'r' | 'R'; + +fragment ESC_SEQ + : ESC_CHAR_SEQ + | ESC_BYTE_SEQ + | ESC_UNI_SEQ + | ESC_OCT_SEQ + ; + +fragment ESC_CHAR_SEQ + : BACKSLASH ('a'|'b'|'f'|'n'|'r'|'t'|'v'|'"'|'\''|'\\'|'?'|'`') + ; + +fragment ESC_OCT_SEQ + : BACKSLASH ('0'..'3') ('0'..'7') ('0'..'7') + ; + +fragment ESC_BYTE_SEQ + : BACKSLASH ( 'x' | 'X' ) HEXDIGIT HEXDIGIT + ; + +fragment ESC_UNI_SEQ + : BACKSLASH 'u' HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT + | BACKSLASH 'U' HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT + ; + +WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ -> channel(HIDDEN) ; +COMMENT : '//' (~'\n')* -> channel(HIDDEN) ; + +NUM_FLOAT + : ( DIGIT+ ('.' DIGIT+) EXPONENT? + | DIGIT+ EXPONENT + | '.' DIGIT+ EXPONENT? + ) + ; + +NUM_INT + : ( DIGIT+ | '0x' HEXDIGIT+ ); + +NUM_UINT + : DIGIT+ ( 'u' | 'U' ) + | '0x' HEXDIGIT+ ( 'u' | 'U' ) + ; + +STRING + : '"' (ESC_SEQ | ~('\\'|'"'|'\n'|'\r'))* '"' + | '\'' (ESC_SEQ | ~('\\'|'\''|'\n'|'\r'))* '\'' + | '"""' (ESC_SEQ | ~('\\'))*? '"""' + | '\'\'\'' (ESC_SEQ | ~('\\'))*? '\'\'\'' + | RAW '"' ~('"'|'\n'|'\r')* '"' + | RAW '\'' ~('\''|'\n'|'\r')* '\'' + | RAW '"""' .*? '"""' + | RAW '\'\'\'' .*? '\'\'\'' + ; + +BYTES : ('b' | 'B') STRING; + +IDENTIFIER : (LETTER | '_') ( LETTER | DIGIT | '_')*; +ESC_IDENTIFIER : '`' (LETTER | DIGIT | '_' | '.' | '-' | '/' | ' ')+ '`'; \ No newline at end of file diff --git a/vendor/cel/src/parser/gen/CEL.interp b/vendor/cel/src/parser/gen/CEL.interp new file mode 100644 index 0000000..53fc8d8 --- /dev/null +++ b/vendor/cel/src/parser/gen/CEL.interp @@ -0,0 +1,102 @@ +token literal names: +null +'==' +'!=' +'in' +'<' +'<=' +'>=' +'>' +'&&' +'||' +'[' +']' +'{' +'}' +'(' +')' +'.' +',' +'-' +'!' +'?' +':' +'+' +'*' +'/' +'%' +'true' +'false' +'null' +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +EQUALS +NOT_EQUALS +IN +LESS +LESS_EQUALS +GREATER_EQUALS +GREATER +LOGICAL_AND +LOGICAL_OR +LBRACKET +RPRACKET +LBRACE +RBRACE +LPAREN +RPAREN +DOT +COMMA +MINUS +EXCLAM +QUESTIONMARK +COLON +PLUS +STAR +SLASH +PERCENT +CEL_TRUE +CEL_FALSE +NUL +WHITESPACE +COMMENT +NUM_FLOAT +NUM_INT +NUM_UINT +STRING +BYTES +IDENTIFIER +ESC_IDENTIFIER + +rule names: +start +expr +conditionalOr +conditionalAnd +relation +calc +unary +member +primary +exprList +listInit +field_initializer_list +optField +mapInitializerList +escapeIdent +optExpr +literal + + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 39, 261, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 46, 10, 3, 3, 4, 3, 4, 3, 4, 7, 4, 51, 10, 4, 12, 4, 14, 4, 54, 11, 4, 3, 5, 3, 5, 3, 5, 7, 5, 59, 10, 5, 12, 5, 14, 5, 62, 11, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 7, 6, 70, 10, 6, 12, 6, 14, 6, 73, 11, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 7, 7, 84, 10, 7, 12, 7, 14, 7, 87, 11, 7, 3, 8, 3, 8, 6, 8, 91, 10, 8, 13, 8, 14, 8, 92, 3, 8, 3, 8, 6, 8, 97, 10, 8, 13, 8, 14, 8, 98, 3, 8, 5, 8, 102, 10, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 110, 10, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 118, 10, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 124, 10, 9, 3, 9, 3, 9, 3, 9, 7, 9, 129, 10, 9, 12, 9, 14, 9, 132, 11, 9, 3, 10, 5, 10, 135, 10, 10, 3, 10, 3, 10, 5, 10, 139, 10, 10, 3, 10, 3, 10, 3, 10, 5, 10, 144, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 153, 10, 10, 3, 10, 5, 10, 156, 10, 10, 3, 10, 3, 10, 3, 10, 5, 10, 161, 10, 10, 3, 10, 5, 10, 164, 10, 10, 3, 10, 3, 10, 5, 10, 168, 10, 10, 3, 10, 3, 10, 3, 10, 7, 10, 173, 10, 10, 12, 10, 14, 10, 176, 11, 10, 3, 10, 3, 10, 5, 10, 180, 10, 10, 3, 10, 5, 10, 183, 10, 10, 3, 10, 3, 10, 5, 10, 187, 10, 10, 3, 11, 3, 11, 3, 11, 7, 11, 192, 10, 11, 12, 11, 14, 11, 195, 11, 11, 3, 12, 3, 12, 3, 12, 7, 12, 200, 10, 12, 12, 12, 14, 12, 203, 11, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 7, 13, 213, 10, 13, 12, 13, 14, 13, 216, 11, 13, 3, 14, 5, 14, 219, 10, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 7, 15, 231, 10, 15, 12, 15, 14, 15, 234, 11, 15, 3, 16, 3, 16, 5, 16, 238, 10, 16, 3, 17, 5, 17, 241, 10, 17, 3, 17, 3, 17, 3, 18, 5, 18, 246, 10, 18, 3, 18, 3, 18, 3, 18, 5, 18, 251, 10, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 5, 18, 259, 10, 18, 3, 18, 2, 5, 10, 12, 16, 19, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 2, 5, 3, 2, 3, 9, 3, 2, 25, 27, 4, 2, 20, 20, 24, 24, 2, 292, 2, 36, 3, 2, 2, 2, 4, 39, 3, 2, 2, 2, 6, 47, 3, 2, 2, 2, 8, 55, 3, 2, 2, 2, 10, 63, 3, 2, 2, 2, 12, 74, 3, 2, 2, 2, 14, 101, 3, 2, 2, 2, 16, 103, 3, 2, 2, 2, 18, 186, 3, 2, 2, 2, 20, 188, 3, 2, 2, 2, 22, 196, 3, 2, 2, 2, 24, 204, 3, 2, 2, 2, 26, 218, 3, 2, 2, 2, 28, 222, 3, 2, 2, 2, 30, 237, 3, 2, 2, 2, 32, 240, 3, 2, 2, 2, 34, 258, 3, 2, 2, 2, 36, 37, 5, 4, 3, 2, 37, 38, 7, 2, 2, 3, 38, 3, 3, 2, 2, 2, 39, 45, 5, 6, 4, 2, 40, 41, 7, 22, 2, 2, 41, 42, 5, 6, 4, 2, 42, 43, 7, 23, 2, 2, 43, 44, 5, 4, 3, 2, 44, 46, 3, 2, 2, 2, 45, 40, 3, 2, 2, 2, 45, 46, 3, 2, 2, 2, 46, 5, 3, 2, 2, 2, 47, 52, 5, 8, 5, 2, 48, 49, 7, 11, 2, 2, 49, 51, 5, 8, 5, 2, 50, 48, 3, 2, 2, 2, 51, 54, 3, 2, 2, 2, 52, 50, 3, 2, 2, 2, 52, 53, 3, 2, 2, 2, 53, 7, 3, 2, 2, 2, 54, 52, 3, 2, 2, 2, 55, 60, 5, 10, 6, 2, 56, 57, 7, 10, 2, 2, 57, 59, 5, 10, 6, 2, 58, 56, 3, 2, 2, 2, 59, 62, 3, 2, 2, 2, 60, 58, 3, 2, 2, 2, 60, 61, 3, 2, 2, 2, 61, 9, 3, 2, 2, 2, 62, 60, 3, 2, 2, 2, 63, 64, 8, 6, 1, 2, 64, 65, 5, 12, 7, 2, 65, 71, 3, 2, 2, 2, 66, 67, 12, 3, 2, 2, 67, 68, 9, 2, 2, 2, 68, 70, 5, 10, 6, 4, 69, 66, 3, 2, 2, 2, 70, 73, 3, 2, 2, 2, 71, 69, 3, 2, 2, 2, 71, 72, 3, 2, 2, 2, 72, 11, 3, 2, 2, 2, 73, 71, 3, 2, 2, 2, 74, 75, 8, 7, 1, 2, 75, 76, 5, 14, 8, 2, 76, 85, 3, 2, 2, 2, 77, 78, 12, 4, 2, 2, 78, 79, 9, 3, 2, 2, 79, 84, 5, 12, 7, 5, 80, 81, 12, 3, 2, 2, 81, 82, 9, 4, 2, 2, 82, 84, 5, 12, 7, 4, 83, 77, 3, 2, 2, 2, 83, 80, 3, 2, 2, 2, 84, 87, 3, 2, 2, 2, 85, 83, 3, 2, 2, 2, 85, 86, 3, 2, 2, 2, 86, 13, 3, 2, 2, 2, 87, 85, 3, 2, 2, 2, 88, 102, 5, 16, 9, 2, 89, 91, 7, 21, 2, 2, 90, 89, 3, 2, 2, 2, 91, 92, 3, 2, 2, 2, 92, 90, 3, 2, 2, 2, 92, 93, 3, 2, 2, 2, 93, 94, 3, 2, 2, 2, 94, 102, 5, 16, 9, 2, 95, 97, 7, 20, 2, 2, 96, 95, 3, 2, 2, 2, 97, 98, 3, 2, 2, 2, 98, 96, 3, 2, 2, 2, 98, 99, 3, 2, 2, 2, 99, 100, 3, 2, 2, 2, 100, 102, 5, 16, 9, 2, 101, 88, 3, 2, 2, 2, 101, 90, 3, 2, 2, 2, 101, 96, 3, 2, 2, 2, 102, 15, 3, 2, 2, 2, 103, 104, 8, 9, 1, 2, 104, 105, 5, 18, 10, 2, 105, 130, 3, 2, 2, 2, 106, 107, 12, 5, 2, 2, 107, 109, 7, 18, 2, 2, 108, 110, 7, 22, 2, 2, 109, 108, 3, 2, 2, 2, 109, 110, 3, 2, 2, 2, 110, 111, 3, 2, 2, 2, 111, 129, 5, 30, 16, 2, 112, 113, 12, 4, 2, 2, 113, 114, 7, 18, 2, 2, 114, 115, 7, 38, 2, 2, 115, 117, 7, 16, 2, 2, 116, 118, 5, 20, 11, 2, 117, 116, 3, 2, 2, 2, 117, 118, 3, 2, 2, 2, 118, 119, 3, 2, 2, 2, 119, 129, 7, 17, 2, 2, 120, 121, 12, 3, 2, 2, 121, 123, 7, 12, 2, 2, 122, 124, 7, 22, 2, 2, 123, 122, 3, 2, 2, 2, 123, 124, 3, 2, 2, 2, 124, 125, 3, 2, 2, 2, 125, 126, 5, 4, 3, 2, 126, 127, 7, 13, 2, 2, 127, 129, 3, 2, 2, 2, 128, 106, 3, 2, 2, 2, 128, 112, 3, 2, 2, 2, 128, 120, 3, 2, 2, 2, 129, 132, 3, 2, 2, 2, 130, 128, 3, 2, 2, 2, 130, 131, 3, 2, 2, 2, 131, 17, 3, 2, 2, 2, 132, 130, 3, 2, 2, 2, 133, 135, 7, 18, 2, 2, 134, 133, 3, 2, 2, 2, 134, 135, 3, 2, 2, 2, 135, 136, 3, 2, 2, 2, 136, 187, 7, 38, 2, 2, 137, 139, 7, 18, 2, 2, 138, 137, 3, 2, 2, 2, 138, 139, 3, 2, 2, 2, 139, 140, 3, 2, 2, 2, 140, 141, 7, 38, 2, 2, 141, 143, 7, 16, 2, 2, 142, 144, 5, 20, 11, 2, 143, 142, 3, 2, 2, 2, 143, 144, 3, 2, 2, 2, 144, 145, 3, 2, 2, 2, 145, 187, 7, 17, 2, 2, 146, 147, 7, 16, 2, 2, 147, 148, 5, 4, 3, 2, 148, 149, 7, 17, 2, 2, 149, 187, 3, 2, 2, 2, 150, 152, 7, 12, 2, 2, 151, 153, 5, 22, 12, 2, 152, 151, 3, 2, 2, 2, 152, 153, 3, 2, 2, 2, 153, 155, 3, 2, 2, 2, 154, 156, 7, 19, 2, 2, 155, 154, 3, 2, 2, 2, 155, 156, 3, 2, 2, 2, 156, 157, 3, 2, 2, 2, 157, 187, 7, 13, 2, 2, 158, 160, 7, 14, 2, 2, 159, 161, 5, 28, 15, 2, 160, 159, 3, 2, 2, 2, 160, 161, 3, 2, 2, 2, 161, 163, 3, 2, 2, 2, 162, 164, 7, 19, 2, 2, 163, 162, 3, 2, 2, 2, 163, 164, 3, 2, 2, 2, 164, 165, 3, 2, 2, 2, 165, 187, 7, 15, 2, 2, 166, 168, 7, 18, 2, 2, 167, 166, 3, 2, 2, 2, 167, 168, 3, 2, 2, 2, 168, 169, 3, 2, 2, 2, 169, 174, 7, 38, 2, 2, 170, 171, 7, 18, 2, 2, 171, 173, 7, 38, 2, 2, 172, 170, 3, 2, 2, 2, 173, 176, 3, 2, 2, 2, 174, 172, 3, 2, 2, 2, 174, 175, 3, 2, 2, 2, 175, 177, 3, 2, 2, 2, 176, 174, 3, 2, 2, 2, 177, 179, 7, 14, 2, 2, 178, 180, 5, 24, 13, 2, 179, 178, 3, 2, 2, 2, 179, 180, 3, 2, 2, 2, 180, 182, 3, 2, 2, 2, 181, 183, 7, 19, 2, 2, 182, 181, 3, 2, 2, 2, 182, 183, 3, 2, 2, 2, 183, 184, 3, 2, 2, 2, 184, 187, 7, 15, 2, 2, 185, 187, 5, 34, 18, 2, 186, 134, 3, 2, 2, 2, 186, 138, 3, 2, 2, 2, 186, 146, 3, 2, 2, 2, 186, 150, 3, 2, 2, 2, 186, 158, 3, 2, 2, 2, 186, 167, 3, 2, 2, 2, 186, 185, 3, 2, 2, 2, 187, 19, 3, 2, 2, 2, 188, 193, 5, 4, 3, 2, 189, 190, 7, 19, 2, 2, 190, 192, 5, 4, 3, 2, 191, 189, 3, 2, 2, 2, 192, 195, 3, 2, 2, 2, 193, 191, 3, 2, 2, 2, 193, 194, 3, 2, 2, 2, 194, 21, 3, 2, 2, 2, 195, 193, 3, 2, 2, 2, 196, 201, 5, 32, 17, 2, 197, 198, 7, 19, 2, 2, 198, 200, 5, 32, 17, 2, 199, 197, 3, 2, 2, 2, 200, 203, 3, 2, 2, 2, 201, 199, 3, 2, 2, 2, 201, 202, 3, 2, 2, 2, 202, 23, 3, 2, 2, 2, 203, 201, 3, 2, 2, 2, 204, 205, 5, 26, 14, 2, 205, 206, 7, 23, 2, 2, 206, 214, 5, 4, 3, 2, 207, 208, 7, 19, 2, 2, 208, 209, 5, 26, 14, 2, 209, 210, 7, 23, 2, 2, 210, 211, 5, 4, 3, 2, 211, 213, 3, 2, 2, 2, 212, 207, 3, 2, 2, 2, 213, 216, 3, 2, 2, 2, 214, 212, 3, 2, 2, 2, 214, 215, 3, 2, 2, 2, 215, 25, 3, 2, 2, 2, 216, 214, 3, 2, 2, 2, 217, 219, 7, 22, 2, 2, 218, 217, 3, 2, 2, 2, 218, 219, 3, 2, 2, 2, 219, 220, 3, 2, 2, 2, 220, 221, 5, 30, 16, 2, 221, 27, 3, 2, 2, 2, 222, 223, 5, 32, 17, 2, 223, 224, 7, 23, 2, 2, 224, 232, 5, 4, 3, 2, 225, 226, 7, 19, 2, 2, 226, 227, 5, 32, 17, 2, 227, 228, 7, 23, 2, 2, 228, 229, 5, 4, 3, 2, 229, 231, 3, 2, 2, 2, 230, 225, 3, 2, 2, 2, 231, 234, 3, 2, 2, 2, 232, 230, 3, 2, 2, 2, 232, 233, 3, 2, 2, 2, 233, 29, 3, 2, 2, 2, 234, 232, 3, 2, 2, 2, 235, 238, 7, 38, 2, 2, 236, 238, 7, 39, 2, 2, 237, 235, 3, 2, 2, 2, 237, 236, 3, 2, 2, 2, 238, 31, 3, 2, 2, 2, 239, 241, 7, 22, 2, 2, 240, 239, 3, 2, 2, 2, 240, 241, 3, 2, 2, 2, 241, 242, 3, 2, 2, 2, 242, 243, 5, 4, 3, 2, 243, 33, 3, 2, 2, 2, 244, 246, 7, 20, 2, 2, 245, 244, 3, 2, 2, 2, 245, 246, 3, 2, 2, 2, 246, 247, 3, 2, 2, 2, 247, 259, 7, 34, 2, 2, 248, 259, 7, 35, 2, 2, 249, 251, 7, 20, 2, 2, 250, 249, 3, 2, 2, 2, 250, 251, 3, 2, 2, 2, 251, 252, 3, 2, 2, 2, 252, 259, 7, 33, 2, 2, 253, 259, 7, 36, 2, 2, 254, 259, 7, 37, 2, 2, 255, 259, 7, 28, 2, 2, 256, 259, 7, 29, 2, 2, 257, 259, 7, 30, 2, 2, 258, 245, 3, 2, 2, 2, 258, 248, 3, 2, 2, 2, 258, 250, 3, 2, 2, 2, 258, 253, 3, 2, 2, 2, 258, 254, 3, 2, 2, 2, 258, 255, 3, 2, 2, 2, 258, 256, 3, 2, 2, 2, 258, 257, 3, 2, 2, 2, 259, 35, 3, 2, 2, 2, 38, 45, 52, 60, 71, 83, 85, 92, 98, 101, 109, 117, 123, 128, 130, 134, 138, 143, 152, 155, 160, 163, 167, 174, 179, 182, 186, 193, 201, 214, 218, 232, 237, 240, 245, 250, 258] \ No newline at end of file diff --git a/vendor/cel/src/parser/gen/CEL.tokens b/vendor/cel/src/parser/gen/CEL.tokens new file mode 100644 index 0000000..aa1f5ee --- /dev/null +++ b/vendor/cel/src/parser/gen/CEL.tokens @@ -0,0 +1,65 @@ +EQUALS=1 +NOT_EQUALS=2 +IN=3 +LESS=4 +LESS_EQUALS=5 +GREATER_EQUALS=6 +GREATER=7 +LOGICAL_AND=8 +LOGICAL_OR=9 +LBRACKET=10 +RPRACKET=11 +LBRACE=12 +RBRACE=13 +LPAREN=14 +RPAREN=15 +DOT=16 +COMMA=17 +MINUS=18 +EXCLAM=19 +QUESTIONMARK=20 +COLON=21 +PLUS=22 +STAR=23 +SLASH=24 +PERCENT=25 +CEL_TRUE=26 +CEL_FALSE=27 +NUL=28 +WHITESPACE=29 +COMMENT=30 +NUM_FLOAT=31 +NUM_INT=32 +NUM_UINT=33 +STRING=34 +BYTES=35 +IDENTIFIER=36 +ESC_IDENTIFIER=37 +'=='=1 +'!='=2 +'in'=3 +'<'=4 +'<='=5 +'>='=6 +'>'=7 +'&&'=8 +'||'=9 +'['=10 +']'=11 +'{'=12 +'}'=13 +'('=14 +')'=15 +'.'=16 +','=17 +'-'=18 +'!'=19 +'?'=20 +':'=21 +'+'=22 +'*'=23 +'/'=24 +'%'=25 +'true'=26 +'false'=27 +'null'=28 diff --git a/vendor/cel/src/parser/gen/CELLexer.interp b/vendor/cel/src/parser/gen/CELLexer.interp new file mode 100644 index 0000000..4b38c9b --- /dev/null +++ b/vendor/cel/src/parser/gen/CELLexer.interp @@ -0,0 +1,139 @@ +token literal names: +null +'==' +'!=' +'in' +'<' +'<=' +'>=' +'>' +'&&' +'||' +'[' +']' +'{' +'}' +'(' +')' +'.' +',' +'-' +'!' +'?' +':' +'+' +'*' +'/' +'%' +'true' +'false' +'null' +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +EQUALS +NOT_EQUALS +IN +LESS +LESS_EQUALS +GREATER_EQUALS +GREATER +LOGICAL_AND +LOGICAL_OR +LBRACKET +RPRACKET +LBRACE +RBRACE +LPAREN +RPAREN +DOT +COMMA +MINUS +EXCLAM +QUESTIONMARK +COLON +PLUS +STAR +SLASH +PERCENT +CEL_TRUE +CEL_FALSE +NUL +WHITESPACE +COMMENT +NUM_FLOAT +NUM_INT +NUM_UINT +STRING +BYTES +IDENTIFIER +ESC_IDENTIFIER + +rule names: +EQUALS +NOT_EQUALS +IN +LESS +LESS_EQUALS +GREATER_EQUALS +GREATER +LOGICAL_AND +LOGICAL_OR +LBRACKET +RPRACKET +LBRACE +RBRACE +LPAREN +RPAREN +DOT +COMMA +MINUS +EXCLAM +QUESTIONMARK +COLON +PLUS +STAR +SLASH +PERCENT +CEL_TRUE +CEL_FALSE +NUL +BACKSLASH +LETTER +DIGIT +EXPONENT +HEXDIGIT +RAW +ESC_SEQ +ESC_CHAR_SEQ +ESC_OCT_SEQ +ESC_BYTE_SEQ +ESC_UNI_SEQ +WHITESPACE +COMMENT +NUM_FLOAT +NUM_INT +NUM_UINT +STRING +BYTES +IDENTIFIER +ESC_IDENTIFIER + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 39, 437, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 33, 3, 33, 5, 33, 181, 10, 33, 3, 33, 6, 33, 184, 10, 33, 13, 33, 14, 33, 185, 3, 34, 3, 34, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 5, 36, 196, 10, 36, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 5, 40, 229, 10, 40, 3, 41, 6, 41, 232, 10, 41, 13, 41, 14, 41, 233, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 7, 42, 242, 10, 42, 12, 42, 14, 42, 245, 11, 42, 3, 42, 3, 42, 3, 43, 6, 43, 250, 10, 43, 13, 43, 14, 43, 251, 3, 43, 3, 43, 6, 43, 256, 10, 43, 13, 43, 14, 43, 257, 3, 43, 5, 43, 261, 10, 43, 3, 43, 6, 43, 264, 10, 43, 13, 43, 14, 43, 265, 3, 43, 3, 43, 3, 43, 3, 43, 6, 43, 272, 10, 43, 13, 43, 14, 43, 273, 3, 43, 5, 43, 277, 10, 43, 5, 43, 279, 10, 43, 3, 44, 6, 44, 282, 10, 44, 13, 44, 14, 44, 283, 3, 44, 3, 44, 3, 44, 3, 44, 6, 44, 290, 10, 44, 13, 44, 14, 44, 291, 5, 44, 294, 10, 44, 3, 45, 6, 45, 297, 10, 45, 13, 45, 14, 45, 298, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 6, 45, 307, 10, 45, 13, 45, 14, 45, 308, 3, 45, 3, 45, 5, 45, 313, 10, 45, 3, 46, 3, 46, 3, 46, 7, 46, 318, 10, 46, 12, 46, 14, 46, 321, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 327, 10, 46, 12, 46, 14, 46, 330, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 339, 10, 46, 12, 46, 14, 46, 342, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 353, 10, 46, 12, 46, 14, 46, 356, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 364, 10, 46, 12, 46, 14, 46, 367, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 374, 10, 46, 12, 46, 14, 46, 377, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 387, 10, 46, 12, 46, 14, 46, 390, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 7, 46, 402, 10, 46, 12, 46, 14, 46, 405, 11, 46, 3, 46, 3, 46, 3, 46, 3, 46, 5, 46, 411, 10, 46, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 5, 48, 418, 10, 48, 3, 48, 3, 48, 3, 48, 7, 48, 423, 10, 48, 12, 48, 14, 48, 426, 11, 48, 3, 49, 3, 49, 3, 49, 3, 49, 6, 49, 432, 10, 49, 13, 49, 14, 49, 433, 3, 49, 3, 49, 6, 340, 354, 388, 403, 2, 50, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 2, 61, 2, 63, 2, 65, 2, 67, 2, 69, 2, 71, 2, 73, 2, 75, 2, 77, 2, 79, 2, 81, 31, 83, 32, 85, 33, 87, 34, 89, 35, 91, 36, 93, 37, 95, 38, 97, 39, 3, 2, 19, 4, 2, 67, 92, 99, 124, 4, 2, 71, 71, 103, 103, 4, 2, 45, 45, 47, 47, 5, 2, 50, 59, 67, 72, 99, 104, 4, 2, 84, 84, 116, 116, 12, 2, 36, 36, 41, 41, 65, 65, 94, 94, 98, 100, 104, 104, 112, 112, 116, 116, 118, 118, 120, 120, 4, 2, 90, 90, 122, 122, 5, 2, 11, 12, 14, 15, 34, 34, 3, 2, 12, 12, 4, 2, 87, 87, 119, 119, 6, 2, 12, 12, 15, 15, 36, 36, 94, 94, 6, 2, 12, 12, 15, 15, 41, 41, 94, 94, 3, 2, 94, 94, 5, 2, 12, 12, 15, 15, 36, 36, 5, 2, 12, 12, 15, 15, 41, 41, 4, 2, 68, 68, 100, 100, 5, 2, 34, 34, 47, 49, 97, 97, 2, 473, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 3, 99, 3, 2, 2, 2, 5, 102, 3, 2, 2, 2, 7, 105, 3, 2, 2, 2, 9, 108, 3, 2, 2, 2, 11, 110, 3, 2, 2, 2, 13, 113, 3, 2, 2, 2, 15, 116, 3, 2, 2, 2, 17, 118, 3, 2, 2, 2, 19, 121, 3, 2, 2, 2, 21, 124, 3, 2, 2, 2, 23, 126, 3, 2, 2, 2, 25, 128, 3, 2, 2, 2, 27, 130, 3, 2, 2, 2, 29, 132, 3, 2, 2, 2, 31, 134, 3, 2, 2, 2, 33, 136, 3, 2, 2, 2, 35, 138, 3, 2, 2, 2, 37, 140, 3, 2, 2, 2, 39, 142, 3, 2, 2, 2, 41, 144, 3, 2, 2, 2, 43, 146, 3, 2, 2, 2, 45, 148, 3, 2, 2, 2, 47, 150, 3, 2, 2, 2, 49, 152, 3, 2, 2, 2, 51, 154, 3, 2, 2, 2, 53, 156, 3, 2, 2, 2, 55, 161, 3, 2, 2, 2, 57, 167, 3, 2, 2, 2, 59, 172, 3, 2, 2, 2, 61, 174, 3, 2, 2, 2, 63, 176, 3, 2, 2, 2, 65, 178, 3, 2, 2, 2, 67, 187, 3, 2, 2, 2, 69, 189, 3, 2, 2, 2, 71, 195, 3, 2, 2, 2, 73, 197, 3, 2, 2, 2, 75, 200, 3, 2, 2, 2, 77, 205, 3, 2, 2, 2, 79, 228, 3, 2, 2, 2, 81, 231, 3, 2, 2, 2, 83, 237, 3, 2, 2, 2, 85, 278, 3, 2, 2, 2, 87, 293, 3, 2, 2, 2, 89, 312, 3, 2, 2, 2, 91, 410, 3, 2, 2, 2, 93, 412, 3, 2, 2, 2, 95, 417, 3, 2, 2, 2, 97, 427, 3, 2, 2, 2, 99, 100, 7, 63, 2, 2, 100, 101, 7, 63, 2, 2, 101, 4, 3, 2, 2, 2, 102, 103, 7, 35, 2, 2, 103, 104, 7, 63, 2, 2, 104, 6, 3, 2, 2, 2, 105, 106, 7, 107, 2, 2, 106, 107, 7, 112, 2, 2, 107, 8, 3, 2, 2, 2, 108, 109, 7, 62, 2, 2, 109, 10, 3, 2, 2, 2, 110, 111, 7, 62, 2, 2, 111, 112, 7, 63, 2, 2, 112, 12, 3, 2, 2, 2, 113, 114, 7, 64, 2, 2, 114, 115, 7, 63, 2, 2, 115, 14, 3, 2, 2, 2, 116, 117, 7, 64, 2, 2, 117, 16, 3, 2, 2, 2, 118, 119, 7, 40, 2, 2, 119, 120, 7, 40, 2, 2, 120, 18, 3, 2, 2, 2, 121, 122, 7, 126, 2, 2, 122, 123, 7, 126, 2, 2, 123, 20, 3, 2, 2, 2, 124, 125, 7, 93, 2, 2, 125, 22, 3, 2, 2, 2, 126, 127, 7, 95, 2, 2, 127, 24, 3, 2, 2, 2, 128, 129, 7, 125, 2, 2, 129, 26, 3, 2, 2, 2, 130, 131, 7, 127, 2, 2, 131, 28, 3, 2, 2, 2, 132, 133, 7, 42, 2, 2, 133, 30, 3, 2, 2, 2, 134, 135, 7, 43, 2, 2, 135, 32, 3, 2, 2, 2, 136, 137, 7, 48, 2, 2, 137, 34, 3, 2, 2, 2, 138, 139, 7, 46, 2, 2, 139, 36, 3, 2, 2, 2, 140, 141, 7, 47, 2, 2, 141, 38, 3, 2, 2, 2, 142, 143, 7, 35, 2, 2, 143, 40, 3, 2, 2, 2, 144, 145, 7, 65, 2, 2, 145, 42, 3, 2, 2, 2, 146, 147, 7, 60, 2, 2, 147, 44, 3, 2, 2, 2, 148, 149, 7, 45, 2, 2, 149, 46, 3, 2, 2, 2, 150, 151, 7, 44, 2, 2, 151, 48, 3, 2, 2, 2, 152, 153, 7, 49, 2, 2, 153, 50, 3, 2, 2, 2, 154, 155, 7, 39, 2, 2, 155, 52, 3, 2, 2, 2, 156, 157, 7, 118, 2, 2, 157, 158, 7, 116, 2, 2, 158, 159, 7, 119, 2, 2, 159, 160, 7, 103, 2, 2, 160, 54, 3, 2, 2, 2, 161, 162, 7, 104, 2, 2, 162, 163, 7, 99, 2, 2, 163, 164, 7, 110, 2, 2, 164, 165, 7, 117, 2, 2, 165, 166, 7, 103, 2, 2, 166, 56, 3, 2, 2, 2, 167, 168, 7, 112, 2, 2, 168, 169, 7, 119, 2, 2, 169, 170, 7, 110, 2, 2, 170, 171, 7, 110, 2, 2, 171, 58, 3, 2, 2, 2, 172, 173, 7, 94, 2, 2, 173, 60, 3, 2, 2, 2, 174, 175, 9, 2, 2, 2, 175, 62, 3, 2, 2, 2, 176, 177, 4, 50, 59, 2, 177, 64, 3, 2, 2, 2, 178, 180, 9, 3, 2, 2, 179, 181, 9, 4, 2, 2, 180, 179, 3, 2, 2, 2, 180, 181, 3, 2, 2, 2, 181, 183, 3, 2, 2, 2, 182, 184, 5, 63, 32, 2, 183, 182, 3, 2, 2, 2, 184, 185, 3, 2, 2, 2, 185, 183, 3, 2, 2, 2, 185, 186, 3, 2, 2, 2, 186, 66, 3, 2, 2, 2, 187, 188, 9, 5, 2, 2, 188, 68, 3, 2, 2, 2, 189, 190, 9, 6, 2, 2, 190, 70, 3, 2, 2, 2, 191, 196, 5, 73, 37, 2, 192, 196, 5, 77, 39, 2, 193, 196, 5, 79, 40, 2, 194, 196, 5, 75, 38, 2, 195, 191, 3, 2, 2, 2, 195, 192, 3, 2, 2, 2, 195, 193, 3, 2, 2, 2, 195, 194, 3, 2, 2, 2, 196, 72, 3, 2, 2, 2, 197, 198, 5, 59, 30, 2, 198, 199, 9, 7, 2, 2, 199, 74, 3, 2, 2, 2, 200, 201, 5, 59, 30, 2, 201, 202, 4, 50, 53, 2, 202, 203, 4, 50, 57, 2, 203, 204, 4, 50, 57, 2, 204, 76, 3, 2, 2, 2, 205, 206, 5, 59, 30, 2, 206, 207, 9, 8, 2, 2, 207, 208, 5, 67, 34, 2, 208, 209, 5, 67, 34, 2, 209, 78, 3, 2, 2, 2, 210, 211, 5, 59, 30, 2, 211, 212, 7, 119, 2, 2, 212, 213, 5, 67, 34, 2, 213, 214, 5, 67, 34, 2, 214, 215, 5, 67, 34, 2, 215, 216, 5, 67, 34, 2, 216, 229, 3, 2, 2, 2, 217, 218, 5, 59, 30, 2, 218, 219, 7, 87, 2, 2, 219, 220, 5, 67, 34, 2, 220, 221, 5, 67, 34, 2, 221, 222, 5, 67, 34, 2, 222, 223, 5, 67, 34, 2, 223, 224, 5, 67, 34, 2, 224, 225, 5, 67, 34, 2, 225, 226, 5, 67, 34, 2, 226, 227, 5, 67, 34, 2, 227, 229, 3, 2, 2, 2, 228, 210, 3, 2, 2, 2, 228, 217, 3, 2, 2, 2, 229, 80, 3, 2, 2, 2, 230, 232, 9, 9, 2, 2, 231, 230, 3, 2, 2, 2, 232, 233, 3, 2, 2, 2, 233, 231, 3, 2, 2, 2, 233, 234, 3, 2, 2, 2, 234, 235, 3, 2, 2, 2, 235, 236, 8, 41, 2, 2, 236, 82, 3, 2, 2, 2, 237, 238, 7, 49, 2, 2, 238, 239, 7, 49, 2, 2, 239, 243, 3, 2, 2, 2, 240, 242, 10, 10, 2, 2, 241, 240, 3, 2, 2, 2, 242, 245, 3, 2, 2, 2, 243, 241, 3, 2, 2, 2, 243, 244, 3, 2, 2, 2, 244, 246, 3, 2, 2, 2, 245, 243, 3, 2, 2, 2, 246, 247, 8, 42, 2, 2, 247, 84, 3, 2, 2, 2, 248, 250, 5, 63, 32, 2, 249, 248, 3, 2, 2, 2, 250, 251, 3, 2, 2, 2, 251, 249, 3, 2, 2, 2, 251, 252, 3, 2, 2, 2, 252, 253, 3, 2, 2, 2, 253, 255, 7, 48, 2, 2, 254, 256, 5, 63, 32, 2, 255, 254, 3, 2, 2, 2, 256, 257, 3, 2, 2, 2, 257, 255, 3, 2, 2, 2, 257, 258, 3, 2, 2, 2, 258, 260, 3, 2, 2, 2, 259, 261, 5, 65, 33, 2, 260, 259, 3, 2, 2, 2, 260, 261, 3, 2, 2, 2, 261, 279, 3, 2, 2, 2, 262, 264, 5, 63, 32, 2, 263, 262, 3, 2, 2, 2, 264, 265, 3, 2, 2, 2, 265, 263, 3, 2, 2, 2, 265, 266, 3, 2, 2, 2, 266, 267, 3, 2, 2, 2, 267, 268, 5, 65, 33, 2, 268, 279, 3, 2, 2, 2, 269, 271, 7, 48, 2, 2, 270, 272, 5, 63, 32, 2, 271, 270, 3, 2, 2, 2, 272, 273, 3, 2, 2, 2, 273, 271, 3, 2, 2, 2, 273, 274, 3, 2, 2, 2, 274, 276, 3, 2, 2, 2, 275, 277, 5, 65, 33, 2, 276, 275, 3, 2, 2, 2, 276, 277, 3, 2, 2, 2, 277, 279, 3, 2, 2, 2, 278, 249, 3, 2, 2, 2, 278, 263, 3, 2, 2, 2, 278, 269, 3, 2, 2, 2, 279, 86, 3, 2, 2, 2, 280, 282, 5, 63, 32, 2, 281, 280, 3, 2, 2, 2, 282, 283, 3, 2, 2, 2, 283, 281, 3, 2, 2, 2, 283, 284, 3, 2, 2, 2, 284, 294, 3, 2, 2, 2, 285, 286, 7, 50, 2, 2, 286, 287, 7, 122, 2, 2, 287, 289, 3, 2, 2, 2, 288, 290, 5, 67, 34, 2, 289, 288, 3, 2, 2, 2, 290, 291, 3, 2, 2, 2, 291, 289, 3, 2, 2, 2, 291, 292, 3, 2, 2, 2, 292, 294, 3, 2, 2, 2, 293, 281, 3, 2, 2, 2, 293, 285, 3, 2, 2, 2, 294, 88, 3, 2, 2, 2, 295, 297, 5, 63, 32, 2, 296, 295, 3, 2, 2, 2, 297, 298, 3, 2, 2, 2, 298, 296, 3, 2, 2, 2, 298, 299, 3, 2, 2, 2, 299, 300, 3, 2, 2, 2, 300, 301, 9, 11, 2, 2, 301, 313, 3, 2, 2, 2, 302, 303, 7, 50, 2, 2, 303, 304, 7, 122, 2, 2, 304, 306, 3, 2, 2, 2, 305, 307, 5, 67, 34, 2, 306, 305, 3, 2, 2, 2, 307, 308, 3, 2, 2, 2, 308, 306, 3, 2, 2, 2, 308, 309, 3, 2, 2, 2, 309, 310, 3, 2, 2, 2, 310, 311, 9, 11, 2, 2, 311, 313, 3, 2, 2, 2, 312, 296, 3, 2, 2, 2, 312, 302, 3, 2, 2, 2, 313, 90, 3, 2, 2, 2, 314, 319, 7, 36, 2, 2, 315, 318, 5, 71, 36, 2, 316, 318, 10, 12, 2, 2, 317, 315, 3, 2, 2, 2, 317, 316, 3, 2, 2, 2, 318, 321, 3, 2, 2, 2, 319, 317, 3, 2, 2, 2, 319, 320, 3, 2, 2, 2, 320, 322, 3, 2, 2, 2, 321, 319, 3, 2, 2, 2, 322, 411, 7, 36, 2, 2, 323, 328, 7, 41, 2, 2, 324, 327, 5, 71, 36, 2, 325, 327, 10, 13, 2, 2, 326, 324, 3, 2, 2, 2, 326, 325, 3, 2, 2, 2, 327, 330, 3, 2, 2, 2, 328, 326, 3, 2, 2, 2, 328, 329, 3, 2, 2, 2, 329, 331, 3, 2, 2, 2, 330, 328, 3, 2, 2, 2, 331, 411, 7, 41, 2, 2, 332, 333, 7, 36, 2, 2, 333, 334, 7, 36, 2, 2, 334, 335, 7, 36, 2, 2, 335, 340, 3, 2, 2, 2, 336, 339, 5, 71, 36, 2, 337, 339, 10, 14, 2, 2, 338, 336, 3, 2, 2, 2, 338, 337, 3, 2, 2, 2, 339, 342, 3, 2, 2, 2, 340, 341, 3, 2, 2, 2, 340, 338, 3, 2, 2, 2, 341, 343, 3, 2, 2, 2, 342, 340, 3, 2, 2, 2, 343, 344, 7, 36, 2, 2, 344, 345, 7, 36, 2, 2, 345, 411, 7, 36, 2, 2, 346, 347, 7, 41, 2, 2, 347, 348, 7, 41, 2, 2, 348, 349, 7, 41, 2, 2, 349, 354, 3, 2, 2, 2, 350, 353, 5, 71, 36, 2, 351, 353, 10, 14, 2, 2, 352, 350, 3, 2, 2, 2, 352, 351, 3, 2, 2, 2, 353, 356, 3, 2, 2, 2, 354, 355, 3, 2, 2, 2, 354, 352, 3, 2, 2, 2, 355, 357, 3, 2, 2, 2, 356, 354, 3, 2, 2, 2, 357, 358, 7, 41, 2, 2, 358, 359, 7, 41, 2, 2, 359, 411, 7, 41, 2, 2, 360, 361, 5, 69, 35, 2, 361, 365, 7, 36, 2, 2, 362, 364, 10, 15, 2, 2, 363, 362, 3, 2, 2, 2, 364, 367, 3, 2, 2, 2, 365, 363, 3, 2, 2, 2, 365, 366, 3, 2, 2, 2, 366, 368, 3, 2, 2, 2, 367, 365, 3, 2, 2, 2, 368, 369, 7, 36, 2, 2, 369, 411, 3, 2, 2, 2, 370, 371, 5, 69, 35, 2, 371, 375, 7, 41, 2, 2, 372, 374, 10, 16, 2, 2, 373, 372, 3, 2, 2, 2, 374, 377, 3, 2, 2, 2, 375, 373, 3, 2, 2, 2, 375, 376, 3, 2, 2, 2, 376, 378, 3, 2, 2, 2, 377, 375, 3, 2, 2, 2, 378, 379, 7, 41, 2, 2, 379, 411, 3, 2, 2, 2, 380, 381, 5, 69, 35, 2, 381, 382, 7, 36, 2, 2, 382, 383, 7, 36, 2, 2, 383, 384, 7, 36, 2, 2, 384, 388, 3, 2, 2, 2, 385, 387, 11, 2, 2, 2, 386, 385, 3, 2, 2, 2, 387, 390, 3, 2, 2, 2, 388, 389, 3, 2, 2, 2, 388, 386, 3, 2, 2, 2, 389, 391, 3, 2, 2, 2, 390, 388, 3, 2, 2, 2, 391, 392, 7, 36, 2, 2, 392, 393, 7, 36, 2, 2, 393, 394, 7, 36, 2, 2, 394, 411, 3, 2, 2, 2, 395, 396, 5, 69, 35, 2, 396, 397, 7, 41, 2, 2, 397, 398, 7, 41, 2, 2, 398, 399, 7, 41, 2, 2, 399, 403, 3, 2, 2, 2, 400, 402, 11, 2, 2, 2, 401, 400, 3, 2, 2, 2, 402, 405, 3, 2, 2, 2, 403, 404, 3, 2, 2, 2, 403, 401, 3, 2, 2, 2, 404, 406, 3, 2, 2, 2, 405, 403, 3, 2, 2, 2, 406, 407, 7, 41, 2, 2, 407, 408, 7, 41, 2, 2, 408, 409, 7, 41, 2, 2, 409, 411, 3, 2, 2, 2, 410, 314, 3, 2, 2, 2, 410, 323, 3, 2, 2, 2, 410, 332, 3, 2, 2, 2, 410, 346, 3, 2, 2, 2, 410, 360, 3, 2, 2, 2, 410, 370, 3, 2, 2, 2, 410, 380, 3, 2, 2, 2, 410, 395, 3, 2, 2, 2, 411, 92, 3, 2, 2, 2, 412, 413, 9, 17, 2, 2, 413, 414, 5, 91, 46, 2, 414, 94, 3, 2, 2, 2, 415, 418, 5, 61, 31, 2, 416, 418, 7, 97, 2, 2, 417, 415, 3, 2, 2, 2, 417, 416, 3, 2, 2, 2, 418, 424, 3, 2, 2, 2, 419, 423, 5, 61, 31, 2, 420, 423, 5, 63, 32, 2, 421, 423, 7, 97, 2, 2, 422, 419, 3, 2, 2, 2, 422, 420, 3, 2, 2, 2, 422, 421, 3, 2, 2, 2, 423, 426, 3, 2, 2, 2, 424, 422, 3, 2, 2, 2, 424, 425, 3, 2, 2, 2, 425, 96, 3, 2, 2, 2, 426, 424, 3, 2, 2, 2, 427, 431, 7, 98, 2, 2, 428, 432, 5, 61, 31, 2, 429, 432, 5, 63, 32, 2, 430, 432, 9, 18, 2, 2, 431, 428, 3, 2, 2, 2, 431, 429, 3, 2, 2, 2, 431, 430, 3, 2, 2, 2, 432, 433, 3, 2, 2, 2, 433, 431, 3, 2, 2, 2, 433, 434, 3, 2, 2, 2, 434, 435, 3, 2, 2, 2, 435, 436, 7, 98, 2, 2, 436, 98, 3, 2, 2, 2, 40, 2, 180, 185, 195, 228, 233, 243, 251, 257, 260, 265, 273, 276, 278, 283, 291, 293, 298, 308, 312, 317, 319, 326, 328, 338, 340, 352, 354, 365, 375, 388, 403, 410, 417, 422, 424, 431, 433, 3, 2, 3, 2] \ No newline at end of file diff --git a/vendor/cel/src/parser/gen/CELLexer.tokens b/vendor/cel/src/parser/gen/CELLexer.tokens new file mode 100644 index 0000000..aa1f5ee --- /dev/null +++ b/vendor/cel/src/parser/gen/CELLexer.tokens @@ -0,0 +1,65 @@ +EQUALS=1 +NOT_EQUALS=2 +IN=3 +LESS=4 +LESS_EQUALS=5 +GREATER_EQUALS=6 +GREATER=7 +LOGICAL_AND=8 +LOGICAL_OR=9 +LBRACKET=10 +RPRACKET=11 +LBRACE=12 +RBRACE=13 +LPAREN=14 +RPAREN=15 +DOT=16 +COMMA=17 +MINUS=18 +EXCLAM=19 +QUESTIONMARK=20 +COLON=21 +PLUS=22 +STAR=23 +SLASH=24 +PERCENT=25 +CEL_TRUE=26 +CEL_FALSE=27 +NUL=28 +WHITESPACE=29 +COMMENT=30 +NUM_FLOAT=31 +NUM_INT=32 +NUM_UINT=33 +STRING=34 +BYTES=35 +IDENTIFIER=36 +ESC_IDENTIFIER=37 +'=='=1 +'!='=2 +'in'=3 +'<'=4 +'<='=5 +'>='=6 +'>'=7 +'&&'=8 +'||'=9 +'['=10 +']'=11 +'{'=12 +'}'=13 +'('=14 +')'=15 +'.'=16 +','=17 +'-'=18 +'!'=19 +'?'=20 +':'=21 +'+'=22 +'*'=23 +'/'=24 +'%'=25 +'true'=26 +'false'=27 +'null'=28 diff --git a/vendor/cel/src/parser/gen/cellexer.rs b/vendor/cel/src/parser/gen/cellexer.rs new file mode 100644 index 0000000..b7b6fa8 --- /dev/null +++ b/vendor/cel/src/parser/gen/cellexer.rs @@ -0,0 +1,590 @@ +// Generated from /Users/asnaps/src/github.com/clarkmcc/cel-rust/antlr/src/gen/CEL.g4 by ANTLR 4.8 +#![allow(dead_code)] +#![allow(nonstandard_style)] +#![allow(unused_imports)] +#![allow(unused_variables)] +use antlr4rust::atn::ATN; +use antlr4rust::atn_deserializer::ATNDeserializer; +use antlr4rust::char_stream::CharStream; +use antlr4rust::dfa::DFA; +use antlr4rust::error_listener::ErrorListener; +use antlr4rust::int_stream::IntStream; +use antlr4rust::lexer::{BaseLexer, Lexer, LexerRecog}; +use antlr4rust::lexer_atn_simulator::{ILexerATNSimulator, LexerATNSimulator}; +use antlr4rust::parser_rule_context::{cast, BaseParserRuleContext, ParserRuleContext}; +use antlr4rust::recognizer::{Actions, Recognizer}; +use antlr4rust::rule_context::{BaseRuleContext, EmptyContext, EmptyCustomRuleContext}; +use antlr4rust::token::*; +use antlr4rust::token_factory::{CommonTokenFactory, TokenAware, TokenFactory}; +use antlr4rust::vocabulary::{Vocabulary, VocabularyImpl}; +use antlr4rust::PredictionContextCache; +use antlr4rust::TokenSource; + +use antlr4rust::{lazy_static, Tid, TidAble, TidExt}; + +use std::cell::RefCell; +use std::marker::PhantomData; +use std::ops::{Deref, DerefMut}; +use std::rc::Rc; +use std::sync::Arc; + +pub const EQUALS: isize = 1; +pub const NOT_EQUALS: isize = 2; +pub const IN: isize = 3; +pub const LESS: isize = 4; +pub const LESS_EQUALS: isize = 5; +pub const GREATER_EQUALS: isize = 6; +pub const GREATER: isize = 7; +pub const LOGICAL_AND: isize = 8; +pub const LOGICAL_OR: isize = 9; +pub const LBRACKET: isize = 10; +pub const RPRACKET: isize = 11; +pub const LBRACE: isize = 12; +pub const RBRACE: isize = 13; +pub const LPAREN: isize = 14; +pub const RPAREN: isize = 15; +pub const DOT: isize = 16; +pub const COMMA: isize = 17; +pub const MINUS: isize = 18; +pub const EXCLAM: isize = 19; +pub const QUESTIONMARK: isize = 20; +pub const COLON: isize = 21; +pub const PLUS: isize = 22; +pub const STAR: isize = 23; +pub const SLASH: isize = 24; +pub const PERCENT: isize = 25; +pub const CEL_TRUE: isize = 26; +pub const CEL_FALSE: isize = 27; +pub const NUL: isize = 28; +pub const WHITESPACE: isize = 29; +pub const COMMENT: isize = 30; +pub const NUM_FLOAT: isize = 31; +pub const NUM_INT: isize = 32; +pub const NUM_UINT: isize = 33; +pub const STRING: isize = 34; +pub const BYTES: isize = 35; +pub const IDENTIFIER: isize = 36; +pub const ESC_IDENTIFIER: isize = 37; +pub const channelNames: [&str; 2] = ["DEFAULT_TOKEN_CHANNEL", "HIDDEN"]; + +pub const modeNames: [&str; 1] = ["DEFAULT_MODE"]; + +pub const ruleNames: [&str; 48] = [ + "EQUALS", + "NOT_EQUALS", + "IN", + "LESS", + "LESS_EQUALS", + "GREATER_EQUALS", + "GREATER", + "LOGICAL_AND", + "LOGICAL_OR", + "LBRACKET", + "RPRACKET", + "LBRACE", + "RBRACE", + "LPAREN", + "RPAREN", + "DOT", + "COMMA", + "MINUS", + "EXCLAM", + "QUESTIONMARK", + "COLON", + "PLUS", + "STAR", + "SLASH", + "PERCENT", + "CEL_TRUE", + "CEL_FALSE", + "NUL", + "BACKSLASH", + "LETTER", + "DIGIT", + "EXPONENT", + "HEXDIGIT", + "RAW", + "ESC_SEQ", + "ESC_CHAR_SEQ", + "ESC_OCT_SEQ", + "ESC_BYTE_SEQ", + "ESC_UNI_SEQ", + "WHITESPACE", + "COMMENT", + "NUM_FLOAT", + "NUM_INT", + "NUM_UINT", + "STRING", + "BYTES", + "IDENTIFIER", + "ESC_IDENTIFIER", +]; + +pub const _LITERAL_NAMES: [Option<&'static str>; 29] = [ + None, + Some("'=='"), + Some("'!='"), + Some("'in'"), + Some("'<'"), + Some("'<='"), + Some("'>='"), + Some("'>'"), + Some("'&&'"), + Some("'||'"), + Some("'['"), + Some("']'"), + Some("'{'"), + Some("'}'"), + Some("'('"), + Some("')'"), + Some("'.'"), + Some("','"), + Some("'-'"), + Some("'!'"), + Some("'?'"), + Some("':'"), + Some("'+'"), + Some("'*'"), + Some("'/'"), + Some("'%'"), + Some("'true'"), + Some("'false'"), + Some("'null'"), +]; +pub const _SYMBOLIC_NAMES: [Option<&'static str>; 38] = [ + None, + Some("EQUALS"), + Some("NOT_EQUALS"), + Some("IN"), + Some("LESS"), + Some("LESS_EQUALS"), + Some("GREATER_EQUALS"), + Some("GREATER"), + Some("LOGICAL_AND"), + Some("LOGICAL_OR"), + Some("LBRACKET"), + Some("RPRACKET"), + Some("LBRACE"), + Some("RBRACE"), + Some("LPAREN"), + Some("RPAREN"), + Some("DOT"), + Some("COMMA"), + Some("MINUS"), + Some("EXCLAM"), + Some("QUESTIONMARK"), + Some("COLON"), + Some("PLUS"), + Some("STAR"), + Some("SLASH"), + Some("PERCENT"), + Some("CEL_TRUE"), + Some("CEL_FALSE"), + Some("NUL"), + Some("WHITESPACE"), + Some("COMMENT"), + Some("NUM_FLOAT"), + Some("NUM_INT"), + Some("NUM_UINT"), + Some("STRING"), + Some("BYTES"), + Some("IDENTIFIER"), + Some("ESC_IDENTIFIER"), +]; +lazy_static! { + static ref _shared_context_cache: Arc = + Arc::new(PredictionContextCache::new()); + static ref VOCABULARY: Box = Box::new(VocabularyImpl::new( + _LITERAL_NAMES.iter(), + _SYMBOLIC_NAMES.iter(), + None + )); +} + +pub type LexerContext<'input> = + BaseRuleContext<'input, EmptyCustomRuleContext<'input, LocalTokenFactory<'input>>>; +pub type LocalTokenFactory<'input> = CommonTokenFactory; + +type From<'a> = as TokenFactory<'a>>::From; + +pub struct CELLexer<'input, Input: CharStream>> { + base: BaseLexer<'input, CELLexerActions, Input, LocalTokenFactory<'input>>, +} + +antlr4rust::tid! { impl<'input,Input> TidAble<'input> for CELLexer<'input,Input> where Input:CharStream > } + +impl<'input, Input: CharStream>> Deref for CELLexer<'input, Input> { + type Target = BaseLexer<'input, CELLexerActions, Input, LocalTokenFactory<'input>>; + + fn deref(&self) -> &Self::Target { + &self.base + } +} + +impl<'input, Input: CharStream>> DerefMut for CELLexer<'input, Input> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.base + } +} + +impl<'input, Input: CharStream>> CELLexer<'input, Input> { + fn get_rule_names(&self) -> &'static [&'static str] { + &ruleNames + } + fn get_literal_names(&self) -> &[Option<&str>] { + &_LITERAL_NAMES + } + + fn get_symbolic_names(&self) -> &[Option<&str>] { + &_SYMBOLIC_NAMES + } + + fn get_grammar_file_name(&self) -> &'static str { + "CELLexer.g4" + } + + pub fn new_with_token_factory(input: Input, tf: &'input LocalTokenFactory<'input>) -> Self { + antlr4rust::recognizer::check_version("0", "3"); + Self { + base: BaseLexer::new_base_lexer( + input, + LexerATNSimulator::new_lexer_atnsimulator( + _ATN.clone(), + _decision_to_DFA.clone(), + _shared_context_cache.clone(), + ), + CELLexerActions {}, + tf, + ), + } + } +} + +impl<'input, Input: CharStream>> CELLexer<'input, Input> +where + &'input LocalTokenFactory<'input>: Default, +{ + pub fn new(input: Input) -> Self { + CELLexer::new_with_token_factory(input, <&LocalTokenFactory<'input> as Default>::default()) + } +} + +pub struct CELLexerActions {} + +impl CELLexerActions {} + +impl<'input, Input: CharStream>> + Actions<'input, BaseLexer<'input, CELLexerActions, Input, LocalTokenFactory<'input>>> + for CELLexerActions +{ +} + +impl<'input, Input: CharStream>> CELLexer<'input, Input> {} + +impl<'input, Input: CharStream>> + LexerRecog<'input, BaseLexer<'input, CELLexerActions, Input, LocalTokenFactory<'input>>> + for CELLexerActions +{ +} +impl<'input> TokenAware<'input> for CELLexerActions { + type TF = LocalTokenFactory<'input>; +} + +impl<'input, Input: CharStream>> TokenSource<'input> for CELLexer<'input, Input> { + type TF = LocalTokenFactory<'input>; + + fn next_token(&mut self) -> >::Tok { + self.base.next_token() + } + + fn get_line(&self) -> isize { + self.base.get_line() + } + + fn get_char_position_in_line(&self) -> isize { + self.base.get_char_position_in_line() + } + + fn get_input_stream(&mut self) -> Option<&mut dyn IntStream> { + self.base.get_input_stream() + } + + fn get_source_name(&self) -> String { + self.base.get_source_name() + } + + fn get_token_factory(&self) -> &'input Self::TF { + self.base.get_token_factory() + } +} + +lazy_static! { + static ref _ATN: Arc = + Arc::new(ATNDeserializer::new(None).deserialize(_serializedATN.chars())); + static ref _decision_to_DFA: Arc>> = { + let mut dfa = Vec::new(); + let size = _ATN.decision_to_state.len(); + for i in 0..size { + dfa.push(DFA::new(_ATN.clone(), _ATN.get_decision_state(i), i as isize).into()) + } + Arc::new(dfa) + }; +} + +const _serializedATN: &str = + "\x03\u{608b}\u{a72a}\u{8133}\u{b9ed}\u{417c}\u{3be7}\u{7786}\u{5964}\x02\ + \x27\u{1b5}\x08\x01\x04\x02\x09\x02\x04\x03\x09\x03\x04\x04\x09\x04\x04\ + \x05\x09\x05\x04\x06\x09\x06\x04\x07\x09\x07\x04\x08\x09\x08\x04\x09\x09\ + \x09\x04\x0a\x09\x0a\x04\x0b\x09\x0b\x04\x0c\x09\x0c\x04\x0d\x09\x0d\x04\ + \x0e\x09\x0e\x04\x0f\x09\x0f\x04\x10\x09\x10\x04\x11\x09\x11\x04\x12\x09\ + \x12\x04\x13\x09\x13\x04\x14\x09\x14\x04\x15\x09\x15\x04\x16\x09\x16\x04\ + \x17\x09\x17\x04\x18\x09\x18\x04\x19\x09\x19\x04\x1a\x09\x1a\x04\x1b\x09\ + \x1b\x04\x1c\x09\x1c\x04\x1d\x09\x1d\x04\x1e\x09\x1e\x04\x1f\x09\x1f\x04\ + \x20\x09\x20\x04\x21\x09\x21\x04\x22\x09\x22\x04\x23\x09\x23\x04\x24\x09\ + \x24\x04\x25\x09\x25\x04\x26\x09\x26\x04\x27\x09\x27\x04\x28\x09\x28\x04\ + \x29\x09\x29\x04\x2a\x09\x2a\x04\x2b\x09\x2b\x04\x2c\x09\x2c\x04\x2d\x09\ + \x2d\x04\x2e\x09\x2e\x04\x2f\x09\x2f\x04\x30\x09\x30\x04\x31\x09\x31\x03\ + \x02\x03\x02\x03\x02\x03\x03\x03\x03\x03\x03\x03\x04\x03\x04\x03\x04\x03\ + \x05\x03\x05\x03\x06\x03\x06\x03\x06\x03\x07\x03\x07\x03\x07\x03\x08\x03\ + \x08\x03\x09\x03\x09\x03\x09\x03\x0a\x03\x0a\x03\x0a\x03\x0b\x03\x0b\x03\ + \x0c\x03\x0c\x03\x0d\x03\x0d\x03\x0e\x03\x0e\x03\x0f\x03\x0f\x03\x10\x03\ + \x10\x03\x11\x03\x11\x03\x12\x03\x12\x03\x13\x03\x13\x03\x14\x03\x14\x03\ + \x15\x03\x15\x03\x16\x03\x16\x03\x17\x03\x17\x03\x18\x03\x18\x03\x19\x03\ + \x19\x03\x1a\x03\x1a\x03\x1b\x03\x1b\x03\x1b\x03\x1b\x03\x1b\x03\x1c\x03\ + \x1c\x03\x1c\x03\x1c\x03\x1c\x03\x1c\x03\x1d\x03\x1d\x03\x1d\x03\x1d\x03\ + \x1d\x03\x1e\x03\x1e\x03\x1f\x03\x1f\x03\x20\x03\x20\x03\x21\x03\x21\x05\ + \x21\u{b5}\x0a\x21\x03\x21\x06\x21\u{b8}\x0a\x21\x0d\x21\x0e\x21\u{b9}\ + \x03\x22\x03\x22\x03\x23\x03\x23\x03\x24\x03\x24\x03\x24\x03\x24\x05\x24\ + \u{c4}\x0a\x24\x03\x25\x03\x25\x03\x25\x03\x26\x03\x26\x03\x26\x03\x26\ + \x03\x26\x03\x27\x03\x27\x03\x27\x03\x27\x03\x27\x03\x28\x03\x28\x03\x28\ + \x03\x28\x03\x28\x03\x28\x03\x28\x03\x28\x03\x28\x03\x28\x03\x28\x03\x28\ + \x03\x28\x03\x28\x03\x28\x03\x28\x03\x28\x03\x28\x05\x28\u{e5}\x0a\x28\ + \x03\x29\x06\x29\u{e8}\x0a\x29\x0d\x29\x0e\x29\u{e9}\x03\x29\x03\x29\x03\ + \x2a\x03\x2a\x03\x2a\x03\x2a\x07\x2a\u{f2}\x0a\x2a\x0c\x2a\x0e\x2a\u{f5}\ + \x0b\x2a\x03\x2a\x03\x2a\x03\x2b\x06\x2b\u{fa}\x0a\x2b\x0d\x2b\x0e\x2b\ + \u{fb}\x03\x2b\x03\x2b\x06\x2b\u{100}\x0a\x2b\x0d\x2b\x0e\x2b\u{101}\x03\ + \x2b\x05\x2b\u{105}\x0a\x2b\x03\x2b\x06\x2b\u{108}\x0a\x2b\x0d\x2b\x0e\ + \x2b\u{109}\x03\x2b\x03\x2b\x03\x2b\x03\x2b\x06\x2b\u{110}\x0a\x2b\x0d\ + \x2b\x0e\x2b\u{111}\x03\x2b\x05\x2b\u{115}\x0a\x2b\x05\x2b\u{117}\x0a\x2b\ + \x03\x2c\x06\x2c\u{11a}\x0a\x2c\x0d\x2c\x0e\x2c\u{11b}\x03\x2c\x03\x2c\ + \x03\x2c\x03\x2c\x06\x2c\u{122}\x0a\x2c\x0d\x2c\x0e\x2c\u{123}\x05\x2c\ + \u{126}\x0a\x2c\x03\x2d\x06\x2d\u{129}\x0a\x2d\x0d\x2d\x0e\x2d\u{12a}\x03\ + \x2d\x03\x2d\x03\x2d\x03\x2d\x03\x2d\x03\x2d\x06\x2d\u{133}\x0a\x2d\x0d\ + \x2d\x0e\x2d\u{134}\x03\x2d\x03\x2d\x05\x2d\u{139}\x0a\x2d\x03\x2e\x03\ + \x2e\x03\x2e\x07\x2e\u{13e}\x0a\x2e\x0c\x2e\x0e\x2e\u{141}\x0b\x2e\x03\ + \x2e\x03\x2e\x03\x2e\x03\x2e\x07\x2e\u{147}\x0a\x2e\x0c\x2e\x0e\x2e\u{14a}\ + \x0b\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x07\x2e\ + \u{153}\x0a\x2e\x0c\x2e\x0e\x2e\u{156}\x0b\x2e\x03\x2e\x03\x2e\x03\x2e\ + \x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x07\x2e\u{161}\x0a\x2e\ + \x0c\x2e\x0e\x2e\u{164}\x0b\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\ + \x03\x2e\x07\x2e\u{16c}\x0a\x2e\x0c\x2e\x0e\x2e\u{16f}\x0b\x2e\x03\x2e\ + \x03\x2e\x03\x2e\x03\x2e\x03\x2e\x07\x2e\u{176}\x0a\x2e\x0c\x2e\x0e\x2e\ + \u{179}\x0b\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\ + \x03\x2e\x07\x2e\u{183}\x0a\x2e\x0c\x2e\x0e\x2e\u{186}\x0b\x2e\x03\x2e\ + \x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\x03\x2e\ + \x07\x2e\u{192}\x0a\x2e\x0c\x2e\x0e\x2e\u{195}\x0b\x2e\x03\x2e\x03\x2e\ + \x03\x2e\x03\x2e\x05\x2e\u{19b}\x0a\x2e\x03\x2f\x03\x2f\x03\x2f\x03\x30\ + \x03\x30\x05\x30\u{1a2}\x0a\x30\x03\x30\x03\x30\x03\x30\x07\x30\u{1a7}\ + \x0a\x30\x0c\x30\x0e\x30\u{1aa}\x0b\x30\x03\x31\x03\x31\x03\x31\x03\x31\ + \x06\x31\u{1b0}\x0a\x31\x0d\x31\x0e\x31\u{1b1}\x03\x31\x03\x31\x06\u{154}\ + \u{162}\u{184}\u{193}\x02\x32\x03\x03\x05\x04\x07\x05\x09\x06\x0b\x07\x0d\ + \x08\x0f\x09\x11\x0a\x13\x0b\x15\x0c\x17\x0d\x19\x0e\x1b\x0f\x1d\x10\x1f\ + \x11\x21\x12\x23\x13\x25\x14\x27\x15\x29\x16\x2b\x17\x2d\x18\x2f\x19\x31\ + \x1a\x33\x1b\x35\x1c\x37\x1d\x39\x1e\x3b\x02\x3d\x02\x3f\x02\x41\x02\x43\ + \x02\x45\x02\x47\x02\x49\x02\x4b\x02\x4d\x02\x4f\x02\x51\x1f\x53\x20\x55\ + \x21\x57\x22\x59\x23\x5b\x24\x5d\x25\x5f\x26\x61\x27\x03\x02\x13\x04\x02\ + \x43\x5c\x63\x7c\x04\x02\x47\x47\x67\x67\x04\x02\x2d\x2d\x2f\x2f\x05\x02\ + \x32\x3b\x43\x48\x63\x68\x04\x02\x54\x54\x74\x74\x0c\x02\x24\x24\x29\x29\ + \x41\x41\x5e\x5e\x62\x64\x68\x68\x70\x70\x74\x74\x76\x76\x78\x78\x04\x02\ + \x5a\x5a\x7a\x7a\x05\x02\x0b\x0c\x0e\x0f\x22\x22\x03\x02\x0c\x0c\x04\x02\ + \x57\x57\x77\x77\x06\x02\x0c\x0c\x0f\x0f\x24\x24\x5e\x5e\x06\x02\x0c\x0c\ + \x0f\x0f\x29\x29\x5e\x5e\x03\x02\x5e\x5e\x05\x02\x0c\x0c\x0f\x0f\x24\x24\ + \x05\x02\x0c\x0c\x0f\x0f\x29\x29\x04\x02\x44\x44\x64\x64\x05\x02\x22\x22\ + \x2f\x31\x61\x61\x02\u{1d9}\x02\x03\x03\x02\x02\x02\x02\x05\x03\x02\x02\ + \x02\x02\x07\x03\x02\x02\x02\x02\x09\x03\x02\x02\x02\x02\x0b\x03\x02\x02\ + \x02\x02\x0d\x03\x02\x02\x02\x02\x0f\x03\x02\x02\x02\x02\x11\x03\x02\x02\ + \x02\x02\x13\x03\x02\x02\x02\x02\x15\x03\x02\x02\x02\x02\x17\x03\x02\x02\ + \x02\x02\x19\x03\x02\x02\x02\x02\x1b\x03\x02\x02\x02\x02\x1d\x03\x02\x02\ + \x02\x02\x1f\x03\x02\x02\x02\x02\x21\x03\x02\x02\x02\x02\x23\x03\x02\x02\ + \x02\x02\x25\x03\x02\x02\x02\x02\x27\x03\x02\x02\x02\x02\x29\x03\x02\x02\ + \x02\x02\x2b\x03\x02\x02\x02\x02\x2d\x03\x02\x02\x02\x02\x2f\x03\x02\x02\ + \x02\x02\x31\x03\x02\x02\x02\x02\x33\x03\x02\x02\x02\x02\x35\x03\x02\x02\ + \x02\x02\x37\x03\x02\x02\x02\x02\x39\x03\x02\x02\x02\x02\x51\x03\x02\x02\ + \x02\x02\x53\x03\x02\x02\x02\x02\x55\x03\x02\x02\x02\x02\x57\x03\x02\x02\ + \x02\x02\x59\x03\x02\x02\x02\x02\x5b\x03\x02\x02\x02\x02\x5d\x03\x02\x02\ + \x02\x02\x5f\x03\x02\x02\x02\x02\x61\x03\x02\x02\x02\x03\x63\x03\x02\x02\ + \x02\x05\x66\x03\x02\x02\x02\x07\x69\x03\x02\x02\x02\x09\x6c\x03\x02\x02\ + \x02\x0b\x6e\x03\x02\x02\x02\x0d\x71\x03\x02\x02\x02\x0f\x74\x03\x02\x02\ + \x02\x11\x76\x03\x02\x02\x02\x13\x79\x03\x02\x02\x02\x15\x7c\x03\x02\x02\ + \x02\x17\x7e\x03\x02\x02\x02\x19\u{80}\x03\x02\x02\x02\x1b\u{82}\x03\x02\ + \x02\x02\x1d\u{84}\x03\x02\x02\x02\x1f\u{86}\x03\x02\x02\x02\x21\u{88}\ + \x03\x02\x02\x02\x23\u{8a}\x03\x02\x02\x02\x25\u{8c}\x03\x02\x02\x02\x27\ + \u{8e}\x03\x02\x02\x02\x29\u{90}\x03\x02\x02\x02\x2b\u{92}\x03\x02\x02\ + \x02\x2d\u{94}\x03\x02\x02\x02\x2f\u{96}\x03\x02\x02\x02\x31\u{98}\x03\ + \x02\x02\x02\x33\u{9a}\x03\x02\x02\x02\x35\u{9c}\x03\x02\x02\x02\x37\u{a1}\ + \x03\x02\x02\x02\x39\u{a7}\x03\x02\x02\x02\x3b\u{ac}\x03\x02\x02\x02\x3d\ + \u{ae}\x03\x02\x02\x02\x3f\u{b0}\x03\x02\x02\x02\x41\u{b2}\x03\x02\x02\ + \x02\x43\u{bb}\x03\x02\x02\x02\x45\u{bd}\x03\x02\x02\x02\x47\u{c3}\x03\ + \x02\x02\x02\x49\u{c5}\x03\x02\x02\x02\x4b\u{c8}\x03\x02\x02\x02\x4d\u{cd}\ + \x03\x02\x02\x02\x4f\u{e4}\x03\x02\x02\x02\x51\u{e7}\x03\x02\x02\x02\x53\ + \u{ed}\x03\x02\x02\x02\x55\u{116}\x03\x02\x02\x02\x57\u{125}\x03\x02\x02\ + \x02\x59\u{138}\x03\x02\x02\x02\x5b\u{19a}\x03\x02\x02\x02\x5d\u{19c}\x03\ + \x02\x02\x02\x5f\u{1a1}\x03\x02\x02\x02\x61\u{1ab}\x03\x02\x02\x02\x63\ + \x64\x07\x3f\x02\x02\x64\x65\x07\x3f\x02\x02\x65\x04\x03\x02\x02\x02\x66\ + \x67\x07\x23\x02\x02\x67\x68\x07\x3f\x02\x02\x68\x06\x03\x02\x02\x02\x69\ + \x6a\x07\x6b\x02\x02\x6a\x6b\x07\x70\x02\x02\x6b\x08\x03\x02\x02\x02\x6c\ + \x6d\x07\x3e\x02\x02\x6d\x0a\x03\x02\x02\x02\x6e\x6f\x07\x3e\x02\x02\x6f\ + \x70\x07\x3f\x02\x02\x70\x0c\x03\x02\x02\x02\x71\x72\x07\x40\x02\x02\x72\ + \x73\x07\x3f\x02\x02\x73\x0e\x03\x02\x02\x02\x74\x75\x07\x40\x02\x02\x75\ + \x10\x03\x02\x02\x02\x76\x77\x07\x28\x02\x02\x77\x78\x07\x28\x02\x02\x78\ + \x12\x03\x02\x02\x02\x79\x7a\x07\x7e\x02\x02\x7a\x7b\x07\x7e\x02\x02\x7b\ + \x14\x03\x02\x02\x02\x7c\x7d\x07\x5d\x02\x02\x7d\x16\x03\x02\x02\x02\x7e\ + \x7f\x07\x5f\x02\x02\x7f\x18\x03\x02\x02\x02\u{80}\u{81}\x07\x7d\x02\x02\ + \u{81}\x1a\x03\x02\x02\x02\u{82}\u{83}\x07\x7f\x02\x02\u{83}\x1c\x03\x02\ + \x02\x02\u{84}\u{85}\x07\x2a\x02\x02\u{85}\x1e\x03\x02\x02\x02\u{86}\u{87}\ + \x07\x2b\x02\x02\u{87}\x20\x03\x02\x02\x02\u{88}\u{89}\x07\x30\x02\x02\ + \u{89}\x22\x03\x02\x02\x02\u{8a}\u{8b}\x07\x2e\x02\x02\u{8b}\x24\x03\x02\ + \x02\x02\u{8c}\u{8d}\x07\x2f\x02\x02\u{8d}\x26\x03\x02\x02\x02\u{8e}\u{8f}\ + \x07\x23\x02\x02\u{8f}\x28\x03\x02\x02\x02\u{90}\u{91}\x07\x41\x02\x02\ + \u{91}\x2a\x03\x02\x02\x02\u{92}\u{93}\x07\x3c\x02\x02\u{93}\x2c\x03\x02\ + \x02\x02\u{94}\u{95}\x07\x2d\x02\x02\u{95}\x2e\x03\x02\x02\x02\u{96}\u{97}\ + \x07\x2c\x02\x02\u{97}\x30\x03\x02\x02\x02\u{98}\u{99}\x07\x31\x02\x02\ + \u{99}\x32\x03\x02\x02\x02\u{9a}\u{9b}\x07\x27\x02\x02\u{9b}\x34\x03\x02\ + \x02\x02\u{9c}\u{9d}\x07\x76\x02\x02\u{9d}\u{9e}\x07\x74\x02\x02\u{9e}\ + \u{9f}\x07\x77\x02\x02\u{9f}\u{a0}\x07\x67\x02\x02\u{a0}\x36\x03\x02\x02\ + \x02\u{a1}\u{a2}\x07\x68\x02\x02\u{a2}\u{a3}\x07\x63\x02\x02\u{a3}\u{a4}\ + \x07\x6e\x02\x02\u{a4}\u{a5}\x07\x75\x02\x02\u{a5}\u{a6}\x07\x67\x02\x02\ + \u{a6}\x38\x03\x02\x02\x02\u{a7}\u{a8}\x07\x70\x02\x02\u{a8}\u{a9}\x07\ + \x77\x02\x02\u{a9}\u{aa}\x07\x6e\x02\x02\u{aa}\u{ab}\x07\x6e\x02\x02\u{ab}\ + \x3a\x03\x02\x02\x02\u{ac}\u{ad}\x07\x5e\x02\x02\u{ad}\x3c\x03\x02\x02\ + \x02\u{ae}\u{af}\x09\x02\x02\x02\u{af}\x3e\x03\x02\x02\x02\u{b0}\u{b1}\ + \x04\x32\x3b\x02\u{b1}\x40\x03\x02\x02\x02\u{b2}\u{b4}\x09\x03\x02\x02\ + \u{b3}\u{b5}\x09\x04\x02\x02\u{b4}\u{b3}\x03\x02\x02\x02\u{b4}\u{b5}\x03\ + \x02\x02\x02\u{b5}\u{b7}\x03\x02\x02\x02\u{b6}\u{b8}\x05\x3f\x20\x02\u{b7}\ + \u{b6}\x03\x02\x02\x02\u{b8}\u{b9}\x03\x02\x02\x02\u{b9}\u{b7}\x03\x02\ + \x02\x02\u{b9}\u{ba}\x03\x02\x02\x02\u{ba}\x42\x03\x02\x02\x02\u{bb}\u{bc}\ + \x09\x05\x02\x02\u{bc}\x44\x03\x02\x02\x02\u{bd}\u{be}\x09\x06\x02\x02\ + \u{be}\x46\x03\x02\x02\x02\u{bf}\u{c4}\x05\x49\x25\x02\u{c0}\u{c4}\x05\ + \x4d\x27\x02\u{c1}\u{c4}\x05\x4f\x28\x02\u{c2}\u{c4}\x05\x4b\x26\x02\u{c3}\ + \u{bf}\x03\x02\x02\x02\u{c3}\u{c0}\x03\x02\x02\x02\u{c3}\u{c1}\x03\x02\ + \x02\x02\u{c3}\u{c2}\x03\x02\x02\x02\u{c4}\x48\x03\x02\x02\x02\u{c5}\u{c6}\ + \x05\x3b\x1e\x02\u{c6}\u{c7}\x09\x07\x02\x02\u{c7}\x4a\x03\x02\x02\x02\ + \u{c8}\u{c9}\x05\x3b\x1e\x02\u{c9}\u{ca}\x04\x32\x35\x02\u{ca}\u{cb}\x04\ + \x32\x39\x02\u{cb}\u{cc}\x04\x32\x39\x02\u{cc}\x4c\x03\x02\x02\x02\u{cd}\ + \u{ce}\x05\x3b\x1e\x02\u{ce}\u{cf}\x09\x08\x02\x02\u{cf}\u{d0}\x05\x43\ + \x22\x02\u{d0}\u{d1}\x05\x43\x22\x02\u{d1}\x4e\x03\x02\x02\x02\u{d2}\u{d3}\ + \x05\x3b\x1e\x02\u{d3}\u{d4}\x07\x77\x02\x02\u{d4}\u{d5}\x05\x43\x22\x02\ + \u{d5}\u{d6}\x05\x43\x22\x02\u{d6}\u{d7}\x05\x43\x22\x02\u{d7}\u{d8}\x05\ + \x43\x22\x02\u{d8}\u{e5}\x03\x02\x02\x02\u{d9}\u{da}\x05\x3b\x1e\x02\u{da}\ + \u{db}\x07\x57\x02\x02\u{db}\u{dc}\x05\x43\x22\x02\u{dc}\u{dd}\x05\x43\ + \x22\x02\u{dd}\u{de}\x05\x43\x22\x02\u{de}\u{df}\x05\x43\x22\x02\u{df}\ + \u{e0}\x05\x43\x22\x02\u{e0}\u{e1}\x05\x43\x22\x02\u{e1}\u{e2}\x05\x43\ + \x22\x02\u{e2}\u{e3}\x05\x43\x22\x02\u{e3}\u{e5}\x03\x02\x02\x02\u{e4}\ + \u{d2}\x03\x02\x02\x02\u{e4}\u{d9}\x03\x02\x02\x02\u{e5}\x50\x03\x02\x02\ + \x02\u{e6}\u{e8}\x09\x09\x02\x02\u{e7}\u{e6}\x03\x02\x02\x02\u{e8}\u{e9}\ + \x03\x02\x02\x02\u{e9}\u{e7}\x03\x02\x02\x02\u{e9}\u{ea}\x03\x02\x02\x02\ + \u{ea}\u{eb}\x03\x02\x02\x02\u{eb}\u{ec}\x08\x29\x02\x02\u{ec}\x52\x03\ + \x02\x02\x02\u{ed}\u{ee}\x07\x31\x02\x02\u{ee}\u{ef}\x07\x31\x02\x02\u{ef}\ + \u{f3}\x03\x02\x02\x02\u{f0}\u{f2}\x0a\x0a\x02\x02\u{f1}\u{f0}\x03\x02\ + \x02\x02\u{f2}\u{f5}\x03\x02\x02\x02\u{f3}\u{f1}\x03\x02\x02\x02\u{f3}\ + \u{f4}\x03\x02\x02\x02\u{f4}\u{f6}\x03\x02\x02\x02\u{f5}\u{f3}\x03\x02\ + \x02\x02\u{f6}\u{f7}\x08\x2a\x02\x02\u{f7}\x54\x03\x02\x02\x02\u{f8}\u{fa}\ + \x05\x3f\x20\x02\u{f9}\u{f8}\x03\x02\x02\x02\u{fa}\u{fb}\x03\x02\x02\x02\ + \u{fb}\u{f9}\x03\x02\x02\x02\u{fb}\u{fc}\x03\x02\x02\x02\u{fc}\u{fd}\x03\ + \x02\x02\x02\u{fd}\u{ff}\x07\x30\x02\x02\u{fe}\u{100}\x05\x3f\x20\x02\u{ff}\ + \u{fe}\x03\x02\x02\x02\u{100}\u{101}\x03\x02\x02\x02\u{101}\u{ff}\x03\x02\ + \x02\x02\u{101}\u{102}\x03\x02\x02\x02\u{102}\u{104}\x03\x02\x02\x02\u{103}\ + \u{105}\x05\x41\x21\x02\u{104}\u{103}\x03\x02\x02\x02\u{104}\u{105}\x03\ + \x02\x02\x02\u{105}\u{117}\x03\x02\x02\x02\u{106}\u{108}\x05\x3f\x20\x02\ + \u{107}\u{106}\x03\x02\x02\x02\u{108}\u{109}\x03\x02\x02\x02\u{109}\u{107}\ + \x03\x02\x02\x02\u{109}\u{10a}\x03\x02\x02\x02\u{10a}\u{10b}\x03\x02\x02\ + \x02\u{10b}\u{10c}\x05\x41\x21\x02\u{10c}\u{117}\x03\x02\x02\x02\u{10d}\ + \u{10f}\x07\x30\x02\x02\u{10e}\u{110}\x05\x3f\x20\x02\u{10f}\u{10e}\x03\ + \x02\x02\x02\u{110}\u{111}\x03\x02\x02\x02\u{111}\u{10f}\x03\x02\x02\x02\ + \u{111}\u{112}\x03\x02\x02\x02\u{112}\u{114}\x03\x02\x02\x02\u{113}\u{115}\ + \x05\x41\x21\x02\u{114}\u{113}\x03\x02\x02\x02\u{114}\u{115}\x03\x02\x02\ + \x02\u{115}\u{117}\x03\x02\x02\x02\u{116}\u{f9}\x03\x02\x02\x02\u{116}\ + \u{107}\x03\x02\x02\x02\u{116}\u{10d}\x03\x02\x02\x02\u{117}\x56\x03\x02\ + \x02\x02\u{118}\u{11a}\x05\x3f\x20\x02\u{119}\u{118}\x03\x02\x02\x02\u{11a}\ + \u{11b}\x03\x02\x02\x02\u{11b}\u{119}\x03\x02\x02\x02\u{11b}\u{11c}\x03\ + \x02\x02\x02\u{11c}\u{126}\x03\x02\x02\x02\u{11d}\u{11e}\x07\x32\x02\x02\ + \u{11e}\u{11f}\x07\x7a\x02\x02\u{11f}\u{121}\x03\x02\x02\x02\u{120}\u{122}\ + \x05\x43\x22\x02\u{121}\u{120}\x03\x02\x02\x02\u{122}\u{123}\x03\x02\x02\ + \x02\u{123}\u{121}\x03\x02\x02\x02\u{123}\u{124}\x03\x02\x02\x02\u{124}\ + \u{126}\x03\x02\x02\x02\u{125}\u{119}\x03\x02\x02\x02\u{125}\u{11d}\x03\ + \x02\x02\x02\u{126}\x58\x03\x02\x02\x02\u{127}\u{129}\x05\x3f\x20\x02\u{128}\ + \u{127}\x03\x02\x02\x02\u{129}\u{12a}\x03\x02\x02\x02\u{12a}\u{128}\x03\ + \x02\x02\x02\u{12a}\u{12b}\x03\x02\x02\x02\u{12b}\u{12c}\x03\x02\x02\x02\ + \u{12c}\u{12d}\x09\x0b\x02\x02\u{12d}\u{139}\x03\x02\x02\x02\u{12e}\u{12f}\ + \x07\x32\x02\x02\u{12f}\u{130}\x07\x7a\x02\x02\u{130}\u{132}\x03\x02\x02\ + \x02\u{131}\u{133}\x05\x43\x22\x02\u{132}\u{131}\x03\x02\x02\x02\u{133}\ + \u{134}\x03\x02\x02\x02\u{134}\u{132}\x03\x02\x02\x02\u{134}\u{135}\x03\ + \x02\x02\x02\u{135}\u{136}\x03\x02\x02\x02\u{136}\u{137}\x09\x0b\x02\x02\ + \u{137}\u{139}\x03\x02\x02\x02\u{138}\u{128}\x03\x02\x02\x02\u{138}\u{12e}\ + \x03\x02\x02\x02\u{139}\x5a\x03\x02\x02\x02\u{13a}\u{13f}\x07\x24\x02\x02\ + \u{13b}\u{13e}\x05\x47\x24\x02\u{13c}\u{13e}\x0a\x0c\x02\x02\u{13d}\u{13b}\ + \x03\x02\x02\x02\u{13d}\u{13c}\x03\x02\x02\x02\u{13e}\u{141}\x03\x02\x02\ + \x02\u{13f}\u{13d}\x03\x02\x02\x02\u{13f}\u{140}\x03\x02\x02\x02\u{140}\ + \u{142}\x03\x02\x02\x02\u{141}\u{13f}\x03\x02\x02\x02\u{142}\u{19b}\x07\ + \x24\x02\x02\u{143}\u{148}\x07\x29\x02\x02\u{144}\u{147}\x05\x47\x24\x02\ + \u{145}\u{147}\x0a\x0d\x02\x02\u{146}\u{144}\x03\x02\x02\x02\u{146}\u{145}\ + \x03\x02\x02\x02\u{147}\u{14a}\x03\x02\x02\x02\u{148}\u{146}\x03\x02\x02\ + \x02\u{148}\u{149}\x03\x02\x02\x02\u{149}\u{14b}\x03\x02\x02\x02\u{14a}\ + \u{148}\x03\x02\x02\x02\u{14b}\u{19b}\x07\x29\x02\x02\u{14c}\u{14d}\x07\ + \x24\x02\x02\u{14d}\u{14e}\x07\x24\x02\x02\u{14e}\u{14f}\x07\x24\x02\x02\ + \u{14f}\u{154}\x03\x02\x02\x02\u{150}\u{153}\x05\x47\x24\x02\u{151}\u{153}\ + \x0a\x0e\x02\x02\u{152}\u{150}\x03\x02\x02\x02\u{152}\u{151}\x03\x02\x02\ + \x02\u{153}\u{156}\x03\x02\x02\x02\u{154}\u{155}\x03\x02\x02\x02\u{154}\ + \u{152}\x03\x02\x02\x02\u{155}\u{157}\x03\x02\x02\x02\u{156}\u{154}\x03\ + \x02\x02\x02\u{157}\u{158}\x07\x24\x02\x02\u{158}\u{159}\x07\x24\x02\x02\ + \u{159}\u{19b}\x07\x24\x02\x02\u{15a}\u{15b}\x07\x29\x02\x02\u{15b}\u{15c}\ + \x07\x29\x02\x02\u{15c}\u{15d}\x07\x29\x02\x02\u{15d}\u{162}\x03\x02\x02\ + \x02\u{15e}\u{161}\x05\x47\x24\x02\u{15f}\u{161}\x0a\x0e\x02\x02\u{160}\ + \u{15e}\x03\x02\x02\x02\u{160}\u{15f}\x03\x02\x02\x02\u{161}\u{164}\x03\ + \x02\x02\x02\u{162}\u{163}\x03\x02\x02\x02\u{162}\u{160}\x03\x02\x02\x02\ + \u{163}\u{165}\x03\x02\x02\x02\u{164}\u{162}\x03\x02\x02\x02\u{165}\u{166}\ + \x07\x29\x02\x02\u{166}\u{167}\x07\x29\x02\x02\u{167}\u{19b}\x07\x29\x02\ + \x02\u{168}\u{169}\x05\x45\x23\x02\u{169}\u{16d}\x07\x24\x02\x02\u{16a}\ + \u{16c}\x0a\x0f\x02\x02\u{16b}\u{16a}\x03\x02\x02\x02\u{16c}\u{16f}\x03\ + \x02\x02\x02\u{16d}\u{16b}\x03\x02\x02\x02\u{16d}\u{16e}\x03\x02\x02\x02\ + \u{16e}\u{170}\x03\x02\x02\x02\u{16f}\u{16d}\x03\x02\x02\x02\u{170}\u{171}\ + \x07\x24\x02\x02\u{171}\u{19b}\x03\x02\x02\x02\u{172}\u{173}\x05\x45\x23\ + \x02\u{173}\u{177}\x07\x29\x02\x02\u{174}\u{176}\x0a\x10\x02\x02\u{175}\ + \u{174}\x03\x02\x02\x02\u{176}\u{179}\x03\x02\x02\x02\u{177}\u{175}\x03\ + \x02\x02\x02\u{177}\u{178}\x03\x02\x02\x02\u{178}\u{17a}\x03\x02\x02\x02\ + \u{179}\u{177}\x03\x02\x02\x02\u{17a}\u{17b}\x07\x29\x02\x02\u{17b}\u{19b}\ + \x03\x02\x02\x02\u{17c}\u{17d}\x05\x45\x23\x02\u{17d}\u{17e}\x07\x24\x02\ + \x02\u{17e}\u{17f}\x07\x24\x02\x02\u{17f}\u{180}\x07\x24\x02\x02\u{180}\ + \u{184}\x03\x02\x02\x02\u{181}\u{183}\x0b\x02\x02\x02\u{182}\u{181}\x03\ + \x02\x02\x02\u{183}\u{186}\x03\x02\x02\x02\u{184}\u{185}\x03\x02\x02\x02\ + \u{184}\u{182}\x03\x02\x02\x02\u{185}\u{187}\x03\x02\x02\x02\u{186}\u{184}\ + \x03\x02\x02\x02\u{187}\u{188}\x07\x24\x02\x02\u{188}\u{189}\x07\x24\x02\ + \x02\u{189}\u{18a}\x07\x24\x02\x02\u{18a}\u{19b}\x03\x02\x02\x02\u{18b}\ + \u{18c}\x05\x45\x23\x02\u{18c}\u{18d}\x07\x29\x02\x02\u{18d}\u{18e}\x07\ + \x29\x02\x02\u{18e}\u{18f}\x07\x29\x02\x02\u{18f}\u{193}\x03\x02\x02\x02\ + \u{190}\u{192}\x0b\x02\x02\x02\u{191}\u{190}\x03\x02\x02\x02\u{192}\u{195}\ + \x03\x02\x02\x02\u{193}\u{194}\x03\x02\x02\x02\u{193}\u{191}\x03\x02\x02\ + \x02\u{194}\u{196}\x03\x02\x02\x02\u{195}\u{193}\x03\x02\x02\x02\u{196}\ + \u{197}\x07\x29\x02\x02\u{197}\u{198}\x07\x29\x02\x02\u{198}\u{199}\x07\ + \x29\x02\x02\u{199}\u{19b}\x03\x02\x02\x02\u{19a}\u{13a}\x03\x02\x02\x02\ + \u{19a}\u{143}\x03\x02\x02\x02\u{19a}\u{14c}\x03\x02\x02\x02\u{19a}\u{15a}\ + \x03\x02\x02\x02\u{19a}\u{168}\x03\x02\x02\x02\u{19a}\u{172}\x03\x02\x02\ + \x02\u{19a}\u{17c}\x03\x02\x02\x02\u{19a}\u{18b}\x03\x02\x02\x02\u{19b}\ + \x5c\x03\x02\x02\x02\u{19c}\u{19d}\x09\x11\x02\x02\u{19d}\u{19e}\x05\x5b\ + \x2e\x02\u{19e}\x5e\x03\x02\x02\x02\u{19f}\u{1a2}\x05\x3d\x1f\x02\u{1a0}\ + \u{1a2}\x07\x61\x02\x02\u{1a1}\u{19f}\x03\x02\x02\x02\u{1a1}\u{1a0}\x03\ + \x02\x02\x02\u{1a2}\u{1a8}\x03\x02\x02\x02\u{1a3}\u{1a7}\x05\x3d\x1f\x02\ + \u{1a4}\u{1a7}\x05\x3f\x20\x02\u{1a5}\u{1a7}\x07\x61\x02\x02\u{1a6}\u{1a3}\ + \x03\x02\x02\x02\u{1a6}\u{1a4}\x03\x02\x02\x02\u{1a6}\u{1a5}\x03\x02\x02\ + \x02\u{1a7}\u{1aa}\x03\x02\x02\x02\u{1a8}\u{1a6}\x03\x02\x02\x02\u{1a8}\ + \u{1a9}\x03\x02\x02\x02\u{1a9}\x60\x03\x02\x02\x02\u{1aa}\u{1a8}\x03\x02\ + \x02\x02\u{1ab}\u{1af}\x07\x62\x02\x02\u{1ac}\u{1b0}\x05\x3d\x1f\x02\u{1ad}\ + \u{1b0}\x05\x3f\x20\x02\u{1ae}\u{1b0}\x09\x12\x02\x02\u{1af}\u{1ac}\x03\ + \x02\x02\x02\u{1af}\u{1ad}\x03\x02\x02\x02\u{1af}\u{1ae}\x03\x02\x02\x02\ + \u{1b0}\u{1b1}\x03\x02\x02\x02\u{1b1}\u{1af}\x03\x02\x02\x02\u{1b1}\u{1b2}\ + \x03\x02\x02\x02\u{1b2}\u{1b3}\x03\x02\x02\x02\u{1b3}\u{1b4}\x07\x62\x02\ + \x02\u{1b4}\x62\x03\x02\x02\x02\x28\x02\u{b4}\u{b9}\u{c3}\u{e4}\u{e9}\u{f3}\ + \u{fb}\u{101}\u{104}\u{109}\u{111}\u{114}\u{116}\u{11b}\u{123}\u{125}\u{12a}\ + \u{134}\u{138}\u{13d}\u{13f}\u{146}\u{148}\u{152}\u{154}\u{160}\u{162}\ + \u{16d}\u{177}\u{184}\u{193}\u{19a}\u{1a1}\u{1a6}\u{1a8}\u{1af}\u{1b1}\ + \x03\x02\x03\x02"; diff --git a/vendor/cel/src/parser/gen/cellistener.rs b/vendor/cel/src/parser/gen/cellistener.rs new file mode 100644 index 0000000..9bf3ab2 --- /dev/null +++ b/vendor/cel/src/parser/gen/cellistener.rs @@ -0,0 +1,417 @@ +#![allow(nonstandard_style)] +// Generated from /Users/asnaps/src/github.com/clarkmcc/cel-rust/antlr/src/gen/CEL.g4 by ANTLR 4.8 +use super::celparser::*; +use antlr4rust::tree::ParseTreeListener; + +pub trait CELListener<'input>: ParseTreeListener<'input, CELParserContextType> { + /** + * Enter a parse tree produced by {@link CELParser#start}. + * @param ctx the parse tree + */ + fn enter_start(&mut self, _ctx: &StartContext<'input>) {} + /** + * Exit a parse tree produced by {@link CELParser#start}. + * @param ctx the parse tree + */ + fn exit_start(&mut self, _ctx: &StartContext<'input>) {} + /** + * Enter a parse tree produced by {@link CELParser#expr}. + * @param ctx the parse tree + */ + fn enter_expr(&mut self, _ctx: &ExprContext<'input>) {} + /** + * Exit a parse tree produced by {@link CELParser#expr}. + * @param ctx the parse tree + */ + fn exit_expr(&mut self, _ctx: &ExprContext<'input>) {} + /** + * Enter a parse tree produced by {@link CELParser#conditionalOr}. + * @param ctx the parse tree + */ + fn enter_conditionalOr(&mut self, _ctx: &ConditionalOrContext<'input>) {} + /** + * Exit a parse tree produced by {@link CELParser#conditionalOr}. + * @param ctx the parse tree + */ + fn exit_conditionalOr(&mut self, _ctx: &ConditionalOrContext<'input>) {} + /** + * Enter a parse tree produced by {@link CELParser#conditionalAnd}. + * @param ctx the parse tree + */ + fn enter_conditionalAnd(&mut self, _ctx: &ConditionalAndContext<'input>) {} + /** + * Exit a parse tree produced by {@link CELParser#conditionalAnd}. + * @param ctx the parse tree + */ + fn exit_conditionalAnd(&mut self, _ctx: &ConditionalAndContext<'input>) {} + /** + * Enter a parse tree produced by {@link CELParser#relation}. + * @param ctx the parse tree + */ + fn enter_relation(&mut self, _ctx: &RelationContext<'input>) {} + /** + * Exit a parse tree produced by {@link CELParser#relation}. + * @param ctx the parse tree + */ + fn exit_relation(&mut self, _ctx: &RelationContext<'input>) {} + /** + * Enter a parse tree produced by {@link CELParser#calc}. + * @param ctx the parse tree + */ + fn enter_calc(&mut self, _ctx: &CalcContext<'input>) {} + /** + * Exit a parse tree produced by {@link CELParser#calc}. + * @param ctx the parse tree + */ + fn exit_calc(&mut self, _ctx: &CalcContext<'input>) {} + /** + * Enter a parse tree produced by the {@code MemberExpr} + * labeled alternative in {@link CELParser#unary}. + * @param ctx the parse tree + */ + fn enter_MemberExpr(&mut self, _ctx: &MemberExprContext<'input>) {} + /** + * Exit a parse tree produced by the {@code MemberExpr} + * labeled alternative in {@link CELParser#unary}. + * @param ctx the parse tree + */ + fn exit_MemberExpr(&mut self, _ctx: &MemberExprContext<'input>) {} + /** + * Enter a parse tree produced by the {@code LogicalNot} + * labeled alternative in {@link CELParser#unary}. + * @param ctx the parse tree + */ + fn enter_LogicalNot(&mut self, _ctx: &LogicalNotContext<'input>) {} + /** + * Exit a parse tree produced by the {@code LogicalNot} + * labeled alternative in {@link CELParser#unary}. + * @param ctx the parse tree + */ + fn exit_LogicalNot(&mut self, _ctx: &LogicalNotContext<'input>) {} + /** + * Enter a parse tree produced by the {@code Negate} + * labeled alternative in {@link CELParser#unary}. + * @param ctx the parse tree + */ + fn enter_Negate(&mut self, _ctx: &NegateContext<'input>) {} + /** + * Exit a parse tree produced by the {@code Negate} + * labeled alternative in {@link CELParser#unary}. + * @param ctx the parse tree + */ + fn exit_Negate(&mut self, _ctx: &NegateContext<'input>) {} + /** + * Enter a parse tree produced by the {@code MemberCall} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn enter_MemberCall(&mut self, _ctx: &MemberCallContext<'input>) {} + /** + * Exit a parse tree produced by the {@code MemberCall} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn exit_MemberCall(&mut self, _ctx: &MemberCallContext<'input>) {} + /** + * Enter a parse tree produced by the {@code Select} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn enter_Select(&mut self, _ctx: &SelectContext<'input>) {} + /** + * Exit a parse tree produced by the {@code Select} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn exit_Select(&mut self, _ctx: &SelectContext<'input>) {} + /** + * Enter a parse tree produced by the {@code PrimaryExpr} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn enter_PrimaryExpr(&mut self, _ctx: &PrimaryExprContext<'input>) {} + /** + * Exit a parse tree produced by the {@code PrimaryExpr} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn exit_PrimaryExpr(&mut self, _ctx: &PrimaryExprContext<'input>) {} + /** + * Enter a parse tree produced by the {@code Index} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn enter_Index(&mut self, _ctx: &IndexContext<'input>) {} + /** + * Exit a parse tree produced by the {@code Index} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn exit_Index(&mut self, _ctx: &IndexContext<'input>) {} + /** + * Enter a parse tree produced by the {@code Ident} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn enter_Ident(&mut self, _ctx: &IdentContext<'input>) {} + /** + * Exit a parse tree produced by the {@code Ident} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn exit_Ident(&mut self, _ctx: &IdentContext<'input>) {} + /** + * Enter a parse tree produced by the {@code GlobalCall} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn enter_GlobalCall(&mut self, _ctx: &GlobalCallContext<'input>) {} + /** + * Exit a parse tree produced by the {@code GlobalCall} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn exit_GlobalCall(&mut self, _ctx: &GlobalCallContext<'input>) {} + /** + * Enter a parse tree produced by the {@code Nested} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn enter_Nested(&mut self, _ctx: &NestedContext<'input>) {} + /** + * Exit a parse tree produced by the {@code Nested} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn exit_Nested(&mut self, _ctx: &NestedContext<'input>) {} + /** + * Enter a parse tree produced by the {@code CreateList} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn enter_CreateList(&mut self, _ctx: &CreateListContext<'input>) {} + /** + * Exit a parse tree produced by the {@code CreateList} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn exit_CreateList(&mut self, _ctx: &CreateListContext<'input>) {} + /** + * Enter a parse tree produced by the {@code CreateStruct} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn enter_CreateStruct(&mut self, _ctx: &CreateStructContext<'input>) {} + /** + * Exit a parse tree produced by the {@code CreateStruct} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn exit_CreateStruct(&mut self, _ctx: &CreateStructContext<'input>) {} + /** + * Enter a parse tree produced by the {@code CreateMessage} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn enter_CreateMessage(&mut self, _ctx: &CreateMessageContext<'input>) {} + /** + * Exit a parse tree produced by the {@code CreateMessage} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn exit_CreateMessage(&mut self, _ctx: &CreateMessageContext<'input>) {} + /** + * Enter a parse tree produced by the {@code ConstantLiteral} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn enter_ConstantLiteral(&mut self, _ctx: &ConstantLiteralContext<'input>) {} + /** + * Exit a parse tree produced by the {@code ConstantLiteral} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn exit_ConstantLiteral(&mut self, _ctx: &ConstantLiteralContext<'input>) {} + /** + * Enter a parse tree produced by {@link CELParser#exprList}. + * @param ctx the parse tree + */ + fn enter_exprList(&mut self, _ctx: &ExprListContext<'input>) {} + /** + * Exit a parse tree produced by {@link CELParser#exprList}. + * @param ctx the parse tree + */ + fn exit_exprList(&mut self, _ctx: &ExprListContext<'input>) {} + /** + * Enter a parse tree produced by {@link CELParser#listInit}. + * @param ctx the parse tree + */ + fn enter_listInit(&mut self, _ctx: &ListInitContext<'input>) {} + /** + * Exit a parse tree produced by {@link CELParser#listInit}. + * @param ctx the parse tree + */ + fn exit_listInit(&mut self, _ctx: &ListInitContext<'input>) {} + /** + * Enter a parse tree produced by {@link CELParser#fieldInitializerList}. + * @param ctx the parse tree + */ + fn enter_fieldInitializerList(&mut self, _ctx: &FieldInitializerListContext<'input>) {} + /** + * Exit a parse tree produced by {@link CELParser#fieldInitializerList}. + * @param ctx the parse tree + */ + fn exit_fieldInitializerList(&mut self, _ctx: &FieldInitializerListContext<'input>) {} + /** + * Enter a parse tree produced by {@link CELParser#optField}. + * @param ctx the parse tree + */ + fn enter_optField(&mut self, _ctx: &OptFieldContext<'input>) {} + /** + * Exit a parse tree produced by {@link CELParser#optField}. + * @param ctx the parse tree + */ + fn exit_optField(&mut self, _ctx: &OptFieldContext<'input>) {} + /** + * Enter a parse tree produced by {@link CELParser#mapInitializerList}. + * @param ctx the parse tree + */ + fn enter_mapInitializerList(&mut self, _ctx: &MapInitializerListContext<'input>) {} + /** + * Exit a parse tree produced by {@link CELParser#mapInitializerList}. + * @param ctx the parse tree + */ + fn exit_mapInitializerList(&mut self, _ctx: &MapInitializerListContext<'input>) {} + /** + * Enter a parse tree produced by the {@code SimpleIdentifier} + * labeled alternative in {@link CELParser#escapeIdent}. + * @param ctx the parse tree + */ + fn enter_SimpleIdentifier(&mut self, _ctx: &SimpleIdentifierContext<'input>) {} + /** + * Exit a parse tree produced by the {@code SimpleIdentifier} + * labeled alternative in {@link CELParser#escapeIdent}. + * @param ctx the parse tree + */ + fn exit_SimpleIdentifier(&mut self, _ctx: &SimpleIdentifierContext<'input>) {} + /** + * Enter a parse tree produced by the {@code EscapedIdentifier} + * labeled alternative in {@link CELParser#escapeIdent}. + * @param ctx the parse tree + */ + fn enter_EscapedIdentifier(&mut self, _ctx: &EscapedIdentifierContext<'input>) {} + /** + * Exit a parse tree produced by the {@code EscapedIdentifier} + * labeled alternative in {@link CELParser#escapeIdent}. + * @param ctx the parse tree + */ + fn exit_EscapedIdentifier(&mut self, _ctx: &EscapedIdentifierContext<'input>) {} + /** + * Enter a parse tree produced by {@link CELParser#optExpr}. + * @param ctx the parse tree + */ + fn enter_optExpr(&mut self, _ctx: &OptExprContext<'input>) {} + /** + * Exit a parse tree produced by {@link CELParser#optExpr}. + * @param ctx the parse tree + */ + fn exit_optExpr(&mut self, _ctx: &OptExprContext<'input>) {} + /** + * Enter a parse tree produced by the {@code Int} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn enter_Int(&mut self, _ctx: &IntContext<'input>) {} + /** + * Exit a parse tree produced by the {@code Int} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn exit_Int(&mut self, _ctx: &IntContext<'input>) {} + /** + * Enter a parse tree produced by the {@code Uint} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn enter_Uint(&mut self, _ctx: &UintContext<'input>) {} + /** + * Exit a parse tree produced by the {@code Uint} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn exit_Uint(&mut self, _ctx: &UintContext<'input>) {} + /** + * Enter a parse tree produced by the {@code Double} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn enter_Double(&mut self, _ctx: &DoubleContext<'input>) {} + /** + * Exit a parse tree produced by the {@code Double} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn exit_Double(&mut self, _ctx: &DoubleContext<'input>) {} + /** + * Enter a parse tree produced by the {@code String} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn enter_String(&mut self, _ctx: &StringContext<'input>) {} + /** + * Exit a parse tree produced by the {@code String} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn exit_String(&mut self, _ctx: &StringContext<'input>) {} + /** + * Enter a parse tree produced by the {@code Bytes} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn enter_Bytes(&mut self, _ctx: &BytesContext<'input>) {} + /** + * Exit a parse tree produced by the {@code Bytes} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn exit_Bytes(&mut self, _ctx: &BytesContext<'input>) {} + /** + * Enter a parse tree produced by the {@code BoolTrue} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn enter_BoolTrue(&mut self, _ctx: &BoolTrueContext<'input>) {} + /** + * Exit a parse tree produced by the {@code BoolTrue} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn exit_BoolTrue(&mut self, _ctx: &BoolTrueContext<'input>) {} + /** + * Enter a parse tree produced by the {@code BoolFalse} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn enter_BoolFalse(&mut self, _ctx: &BoolFalseContext<'input>) {} + /** + * Exit a parse tree produced by the {@code BoolFalse} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn exit_BoolFalse(&mut self, _ctx: &BoolFalseContext<'input>) {} + /** + * Enter a parse tree produced by the {@code Null} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn enter_Null(&mut self, _ctx: &NullContext<'input>) {} + /** + * Exit a parse tree produced by the {@code Null} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn exit_Null(&mut self, _ctx: &NullContext<'input>) {} +} + +antlr4rust::coerce_from! { 'input : CELListener<'input> } diff --git a/vendor/cel/src/parser/gen/celparser.rs b/vendor/cel/src/parser/gen/celparser.rs new file mode 100644 index 0000000..51c2af1 --- /dev/null +++ b/vendor/cel/src/parser/gen/celparser.rs @@ -0,0 +1,6733 @@ +// Generated from /Users/asnaps/src/github.com/clarkmcc/cel-rust/antlr/src/gen/CEL.g4 by ANTLR 4.8 +#![allow(dead_code)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(nonstandard_style)] +#![allow(unused_imports)] +#![allow(unused_mut)] +#![allow(unused_braces)] +use super::cellistener::*; +use super::celvisitor::*; +use antlr4rust::atn::{ATN, INVALID_ALT}; +use antlr4rust::atn_deserializer::ATNDeserializer; +use antlr4rust::dfa::DFA; +use antlr4rust::error_strategy::{DefaultErrorStrategy, ErrorStrategy}; +use antlr4rust::errors::*; +use antlr4rust::int_stream::EOF; +use antlr4rust::parser::{BaseParser, Parser, ParserNodeType, ParserRecog}; +use antlr4rust::parser_atn_simulator::ParserATNSimulator; +use antlr4rust::parser_rule_context::{cast, cast_mut, BaseParserRuleContext, ParserRuleContext}; +use antlr4rust::recognizer::{Actions, Recognizer}; +use antlr4rust::rule_context::{BaseRuleContext, CustomRuleContext, RuleContext}; +use antlr4rust::token::{OwningToken, Token, TOKEN_EOF}; +use antlr4rust::token_factory::{CommonTokenFactory, TokenAware, TokenFactory}; +use antlr4rust::token_stream::TokenStream; +use antlr4rust::tree::*; +use antlr4rust::vocabulary::{Vocabulary, VocabularyImpl}; +use antlr4rust::PredictionContextCache; +use antlr4rust::TokenSource; + +use antlr4rust::lazy_static; +use antlr4rust::{TidAble, TidExt}; + +use std::any::{Any, TypeId}; +use std::borrow::{Borrow, BorrowMut}; +use std::cell::RefCell; +use std::convert::TryFrom; +use std::marker::PhantomData; +use std::ops::{Deref, DerefMut}; +use std::rc::Rc; +use std::sync::Arc; + +pub const EQUALS: isize = 1; +pub const NOT_EQUALS: isize = 2; +pub const IN: isize = 3; +pub const LESS: isize = 4; +pub const LESS_EQUALS: isize = 5; +pub const GREATER_EQUALS: isize = 6; +pub const GREATER: isize = 7; +pub const LOGICAL_AND: isize = 8; +pub const LOGICAL_OR: isize = 9; +pub const LBRACKET: isize = 10; +pub const RPRACKET: isize = 11; +pub const LBRACE: isize = 12; +pub const RBRACE: isize = 13; +pub const LPAREN: isize = 14; +pub const RPAREN: isize = 15; +pub const DOT: isize = 16; +pub const COMMA: isize = 17; +pub const MINUS: isize = 18; +pub const EXCLAM: isize = 19; +pub const QUESTIONMARK: isize = 20; +pub const COLON: isize = 21; +pub const PLUS: isize = 22; +pub const STAR: isize = 23; +pub const SLASH: isize = 24; +pub const PERCENT: isize = 25; +pub const CEL_TRUE: isize = 26; +pub const CEL_FALSE: isize = 27; +pub const NUL: isize = 28; +pub const WHITESPACE: isize = 29; +pub const COMMENT: isize = 30; +pub const NUM_FLOAT: isize = 31; +pub const NUM_INT: isize = 32; +pub const NUM_UINT: isize = 33; +pub const STRING: isize = 34; +pub const BYTES: isize = 35; +pub const IDENTIFIER: isize = 36; +pub const ESC_IDENTIFIER: isize = 37; +pub const RULE_start: usize = 0; +pub const RULE_expr: usize = 1; +pub const RULE_conditionalOr: usize = 2; +pub const RULE_conditionalAnd: usize = 3; +pub const RULE_relation: usize = 4; +pub const RULE_calc: usize = 5; +pub const RULE_unary: usize = 6; +pub const RULE_member: usize = 7; +pub const RULE_primary: usize = 8; +pub const RULE_exprList: usize = 9; +pub const RULE_listInit: usize = 10; +pub const RULE_fieldInitializerList: usize = 11; +pub const RULE_optField: usize = 12; +pub const RULE_mapInitializerList: usize = 13; +pub const RULE_escapeIdent: usize = 14; +pub const RULE_optExpr: usize = 15; +pub const RULE_literal: usize = 16; +pub const ruleNames: [&str; 17] = [ + "start", + "expr", + "conditionalOr", + "conditionalAnd", + "relation", + "calc", + "unary", + "member", + "primary", + "exprList", + "listInit", + "fieldInitializerList", + "optField", + "mapInitializerList", + "escapeIdent", + "optExpr", + "literal", +]; + +pub const _LITERAL_NAMES: [Option<&'static str>; 29] = [ + None, + Some("'=='"), + Some("'!='"), + Some("'in'"), + Some("'<'"), + Some("'<='"), + Some("'>='"), + Some("'>'"), + Some("'&&'"), + Some("'||'"), + Some("'['"), + Some("']'"), + Some("'{'"), + Some("'}'"), + Some("'('"), + Some("')'"), + Some("'.'"), + Some("','"), + Some("'-'"), + Some("'!'"), + Some("'?'"), + Some("':'"), + Some("'+'"), + Some("'*'"), + Some("'/'"), + Some("'%'"), + Some("'true'"), + Some("'false'"), + Some("'null'"), +]; +pub const _SYMBOLIC_NAMES: [Option<&'static str>; 38] = [ + None, + Some("EQUALS"), + Some("NOT_EQUALS"), + Some("IN"), + Some("LESS"), + Some("LESS_EQUALS"), + Some("GREATER_EQUALS"), + Some("GREATER"), + Some("LOGICAL_AND"), + Some("LOGICAL_OR"), + Some("LBRACKET"), + Some("RPRACKET"), + Some("LBRACE"), + Some("RBRACE"), + Some("LPAREN"), + Some("RPAREN"), + Some("DOT"), + Some("COMMA"), + Some("MINUS"), + Some("EXCLAM"), + Some("QUESTIONMARK"), + Some("COLON"), + Some("PLUS"), + Some("STAR"), + Some("SLASH"), + Some("PERCENT"), + Some("CEL_TRUE"), + Some("CEL_FALSE"), + Some("NUL"), + Some("WHITESPACE"), + Some("COMMENT"), + Some("NUM_FLOAT"), + Some("NUM_INT"), + Some("NUM_UINT"), + Some("STRING"), + Some("BYTES"), + Some("IDENTIFIER"), + Some("ESC_IDENTIFIER"), +]; +lazy_static! { + static ref _shared_context_cache: Arc = + Arc::new(PredictionContextCache::new()); + static ref VOCABULARY: Box = Box::new(VocabularyImpl::new( + _LITERAL_NAMES.iter(), + _SYMBOLIC_NAMES.iter(), + None + )); +} + +type BaseParserType<'input, I> = BaseParser< + 'input, + CELParserExt<'input>, + I, + CELParserContextType, + dyn CELListener<'input> + 'input, +>; + +type TokenType<'input> = as TokenFactory<'input>>::Tok; +pub type LocalTokenFactory<'input> = CommonTokenFactory; + +pub type CELTreeWalker<'input, 'a> = + ParseTreeWalker<'input, 'a, CELParserContextType, dyn CELListener<'input> + 'a>; + +/// Parser for CEL grammar +pub struct CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + base: BaseParserType<'input, I>, + interpreter: Arc, + _shared_context_cache: Box, + pub err_handler: H, +} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn get_serialized_atn() -> &'static str { + _serializedATN + } + + pub fn set_error_strategy(&mut self, strategy: H) { + self.err_handler = strategy + } + + pub fn with_strategy(input: I, strategy: H) -> Self { + antlr4rust::recognizer::check_version("0", "3"); + let interpreter = Arc::new(ParserATNSimulator::new( + _ATN.clone(), + _decision_to_DFA.clone(), + _shared_context_cache.clone(), + )); + Self { + base: BaseParser::new_base_parser( + input, + Arc::clone(&interpreter), + CELParserExt { + _pd: Default::default(), + }, + ), + interpreter, + _shared_context_cache: Box::new(PredictionContextCache::new()), + err_handler: strategy, + } + } +} + +type DynStrategy<'input, I> = Box> + 'input>; + +impl<'input, I> CELParser<'input, I, DynStrategy<'input, I>> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, +{ + pub fn with_dyn_strategy(input: I) -> Self { + Self::with_strategy(input, Box::new(DefaultErrorStrategy::new())) + } +} + +impl<'input, I> CELParser<'input, I, DefaultErrorStrategy<'input, CELParserContextType>> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, +{ + pub fn new(input: I) -> Self { + Self::with_strategy(input, DefaultErrorStrategy::new()) + } +} + +/// Trait for monomorphized trait object that corresponds to the nodes of parse tree generated for CELParser +pub trait CELParserContext<'input>: + for<'x> Listenable + 'x> + + for<'x> Visitable + 'x> + + ParserRuleContext<'input, TF = LocalTokenFactory<'input>, Ctx = CELParserContextType> +{ +} + +antlr4rust::coerce_from! { 'input : CELParserContext<'input> } + +impl<'input, 'x, T> VisitableDyn for dyn CELParserContext<'input> + 'input +where + T: CELVisitor<'input> + 'x, +{ + fn accept_dyn(&self, visitor: &mut T) { + self.accept(visitor as &mut (dyn CELVisitor<'input> + 'x)) + } +} + +impl<'input> CELParserContext<'input> for TerminalNode<'input, CELParserContextType> {} +impl<'input> CELParserContext<'input> for ErrorNode<'input, CELParserContextType> {} + +antlr4rust::tid! { impl<'input> TidAble<'input> for dyn CELParserContext<'input> + 'input } + +antlr4rust::tid! { impl<'input> TidAble<'input> for dyn CELListener<'input> + 'input } + +pub struct CELParserContextType; +antlr4rust::tid! {CELParserContextType} + +impl<'input> ParserNodeType<'input> for CELParserContextType { + type TF = LocalTokenFactory<'input>; + type Type = dyn CELParserContext<'input> + 'input; +} + +impl<'input, I, H> Deref for CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + type Target = BaseParserType<'input, I>; + + fn deref(&self) -> &Self::Target { + &self.base + } +} + +impl<'input, I, H> DerefMut for CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.base + } +} + +pub struct CELParserExt<'input> { + _pd: PhantomData<&'input str>, +} + +impl<'input> CELParserExt<'input> {} +antlr4rust::tid! { CELParserExt<'a> } + +impl<'input> TokenAware<'input> for CELParserExt<'input> { + type TF = LocalTokenFactory<'input>; +} + +impl<'input, I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>> + ParserRecog<'input, BaseParserType<'input, I>> for CELParserExt<'input> +{ +} + +impl<'input, I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>> + Actions<'input, BaseParserType<'input, I>> for CELParserExt<'input> +{ + fn get_grammar_file_name(&self) -> &str { + "CEL.g4" + } + + fn get_rule_names(&self) -> &[&str] { + &ruleNames + } + + fn get_vocabulary(&self) -> &dyn Vocabulary { + &**VOCABULARY + } + fn sempred( + _localctx: Option<&(dyn CELParserContext<'input> + 'input)>, + rule_index: isize, + pred_index: isize, + recog: &mut BaseParserType<'input, I>, + ) -> bool { + match rule_index { + 4 => CELParser::<'input, I, _>::relation_sempred( + _localctx.and_then(|x| x.downcast_ref()), + pred_index, + recog, + ), + 5 => CELParser::<'input, I, _>::calc_sempred( + _localctx.and_then(|x| x.downcast_ref()), + pred_index, + recog, + ), + 7 => CELParser::<'input, I, _>::member_sempred( + _localctx.and_then(|x| x.downcast_ref()), + pred_index, + recog, + ), + _ => true, + } + } +} + +impl<'input, I> CELParser<'input, I, DefaultErrorStrategy<'input, CELParserContextType>> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, +{ + fn relation_sempred( + _localctx: Option<&RelationContext<'input>>, + pred_index: isize, + recog: &mut ::Target, + ) -> bool { + match pred_index { + 0 => recog.precpred(None, 1), + _ => true, + } + } + fn calc_sempred( + _localctx: Option<&CalcContext<'input>>, + pred_index: isize, + recog: &mut ::Target, + ) -> bool { + match pred_index { + 1 => recog.precpred(None, 2), + 2 => recog.precpred(None, 1), + _ => true, + } + } + fn member_sempred( + _localctx: Option<&MemberContext<'input>>, + pred_index: isize, + recog: &mut ::Target, + ) -> bool { + match pred_index { + 3 => recog.precpred(None, 3), + 4 => recog.precpred(None, 2), + 5 => recog.precpred(None, 1), + _ => true, + } + } +} +//------------------- start ---------------- +pub type StartContextAll<'input> = StartContext<'input>; + +pub type StartContext<'input> = BaseParserRuleContext<'input, StartContextExt<'input>>; + +#[derive(Clone)] +pub struct StartContextExt<'input> { + pub e: Option>>, + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for StartContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for StartContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_start(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_start(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for StartContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_start(self); + } +} + +impl<'input> CustomRuleContext<'input> for StartContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_start + } + //fn type_rule_index() -> usize where Self: Sized { RULE_start } +} +antlr4rust::tid! {StartContextExt<'a>} + +impl<'input> StartContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + StartContextExt { + e: None, + ph: PhantomData, + }, + )) + } +} + +pub trait StartContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ + /// Retrieves first TerminalNode corresponding to token EOF + /// Returns `None` if there is no child corresponding to token EOF + fn EOF(&self) -> Option>> + where + Self: Sized, + { + self.get_token(EOF, 0) + } + fn expr(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } +} + +impl<'input> StartContextAttrs<'input> for StartContext<'input> {} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn start(&mut self) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = StartContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog.base.enter_rule(_localctx.clone(), 0, RULE_start); + let mut _localctx: Rc = _localctx; + let result: Result<(), ANTLRError> = (|| { + //recog.base.enter_outer_alt(_localctx.clone(), 1); + recog.base.enter_outer_alt(None, 1); + { + /*InvokeRule expr*/ + recog.base.set_state(34); + let tmp = recog.expr()?; + cast_mut::<_, StartContext>(&mut _localctx).e = Some(tmp.clone()); + + recog.base.set_state(35); + recog.base.match_token(EOF, &mut recog.err_handler)?; + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} +//------------------- expr ---------------- +pub type ExprContextAll<'input> = ExprContext<'input>; + +pub type ExprContext<'input> = BaseParserRuleContext<'input, ExprContextExt<'input>>; + +#[derive(Clone)] +pub struct ExprContextExt<'input> { + pub e: Option>>, + pub op: Option>, + pub e1: Option>>, + pub e2: Option>>, + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for ExprContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for ExprContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_expr(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_expr(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for ExprContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_expr(self); + } +} + +impl<'input> CustomRuleContext<'input> for ExprContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_expr + } + //fn type_rule_index() -> usize where Self: Sized { RULE_expr } +} +antlr4rust::tid! {ExprContextExt<'a>} + +impl<'input> ExprContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + ExprContextExt { + op: None, + e: None, + e1: None, + e2: None, + ph: PhantomData, + }, + )) + } +} + +pub trait ExprContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ + fn conditionalOr_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + fn conditionalOr(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.child_of_type(i) + } + /// Retrieves first TerminalNode corresponding to token COLON + /// Returns `None` if there is no child corresponding to token COLON + fn COLON(&self) -> Option>> + where + Self: Sized, + { + self.get_token(COLON, 0) + } + /// Retrieves first TerminalNode corresponding to token QUESTIONMARK + /// Returns `None` if there is no child corresponding to token QUESTIONMARK + fn QUESTIONMARK(&self) -> Option>> + where + Self: Sized, + { + self.get_token(QUESTIONMARK, 0) + } + fn expr(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } +} + +impl<'input> ExprContextAttrs<'input> for ExprContext<'input> {} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn expr(&mut self) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = ExprContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog.base.enter_rule(_localctx.clone(), 2, RULE_expr); + let mut _localctx: Rc = _localctx; + let mut _la: isize = -1; + let result: Result<(), ANTLRError> = (|| { + //recog.base.enter_outer_alt(_localctx.clone(), 1); + recog.base.enter_outer_alt(None, 1); + { + /*InvokeRule conditionalOr*/ + recog.base.set_state(37); + let tmp = recog.conditionalOr()?; + cast_mut::<_, ExprContext>(&mut _localctx).e = Some(tmp.clone()); + + recog.base.set_state(43); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la == QUESTIONMARK { + { + recog.base.set_state(38); + let tmp = recog + .base + .match_token(QUESTIONMARK, &mut recog.err_handler)?; + cast_mut::<_, ExprContext>(&mut _localctx).op = Some(tmp.clone()); + + /*InvokeRule conditionalOr*/ + recog.base.set_state(39); + let tmp = recog.conditionalOr()?; + cast_mut::<_, ExprContext>(&mut _localctx).e1 = Some(tmp.clone()); + + recog.base.set_state(40); + recog.base.match_token(COLON, &mut recog.err_handler)?; + + /*InvokeRule expr*/ + recog.base.set_state(41); + let tmp = recog.expr()?; + cast_mut::<_, ExprContext>(&mut _localctx).e2 = Some(tmp.clone()); + } + } + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} +//------------------- conditionalOr ---------------- +pub type ConditionalOrContextAll<'input> = ConditionalOrContext<'input>; + +pub type ConditionalOrContext<'input> = + BaseParserRuleContext<'input, ConditionalOrContextExt<'input>>; + +#[derive(Clone)] +pub struct ConditionalOrContextExt<'input> { + pub e: Option>>, + pub s9: Option>, + pub ops: Vec>, + pub conditionalAnd: Option>>, + pub e1: Vec>>, + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for ConditionalOrContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for ConditionalOrContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_conditionalOr(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_conditionalOr(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for ConditionalOrContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_conditionalOr(self); + } +} + +impl<'input> CustomRuleContext<'input> for ConditionalOrContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_conditionalOr + } + //fn type_rule_index() -> usize where Self: Sized { RULE_conditionalOr } +} +antlr4rust::tid! {ConditionalOrContextExt<'a>} + +impl<'input> ConditionalOrContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + ConditionalOrContextExt { + s9: None, + ops: Vec::new(), + e: None, + conditionalAnd: None, + e1: Vec::new(), + ph: PhantomData, + }, + )) + } +} + +pub trait ConditionalOrContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ + fn conditionalAnd_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + fn conditionalAnd(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.child_of_type(i) + } + /// Retrieves all `TerminalNode`s corresponding to token LOGICAL_OR in current rule + fn LOGICAL_OR_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + /// Retrieves 'i's TerminalNode corresponding to token LOGICAL_OR, starting from 0. + /// Returns `None` if number of children corresponding to token LOGICAL_OR is less or equal than `i`. + fn LOGICAL_OR(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.get_token(LOGICAL_OR, i) + } +} + +impl<'input> ConditionalOrContextAttrs<'input> for ConditionalOrContext<'input> {} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn conditionalOr(&mut self) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = + ConditionalOrContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog + .base + .enter_rule(_localctx.clone(), 4, RULE_conditionalOr); + let mut _localctx: Rc = _localctx; + let mut _la: isize = -1; + let result: Result<(), ANTLRError> = (|| { + //recog.base.enter_outer_alt(_localctx.clone(), 1); + recog.base.enter_outer_alt(None, 1); + { + /*InvokeRule conditionalAnd*/ + recog.base.set_state(45); + let tmp = recog.conditionalAnd()?; + cast_mut::<_, ConditionalOrContext>(&mut _localctx).e = Some(tmp.clone()); + + recog.base.set_state(50); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + while _la == LOGICAL_OR { + { + { + recog.base.set_state(46); + let tmp = recog.base.match_token(LOGICAL_OR, &mut recog.err_handler)?; + cast_mut::<_, ConditionalOrContext>(&mut _localctx).s9 = + Some(tmp.clone()); + + let temp = cast_mut::<_, ConditionalOrContext>(&mut _localctx) + .s9 + .clone() + .unwrap(); + cast_mut::<_, ConditionalOrContext>(&mut _localctx) + .ops + .push(temp); + + /*InvokeRule conditionalAnd*/ + recog.base.set_state(47); + let tmp = recog.conditionalAnd()?; + cast_mut::<_, ConditionalOrContext>(&mut _localctx).conditionalAnd = + Some(tmp.clone()); + + let temp = cast_mut::<_, ConditionalOrContext>(&mut _localctx) + .conditionalAnd + .clone() + .unwrap(); + cast_mut::<_, ConditionalOrContext>(&mut _localctx) + .e1 + .push(temp); + } + } + recog.base.set_state(52); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + } + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} +//------------------- conditionalAnd ---------------- +pub type ConditionalAndContextAll<'input> = ConditionalAndContext<'input>; + +pub type ConditionalAndContext<'input> = + BaseParserRuleContext<'input, ConditionalAndContextExt<'input>>; + +#[derive(Clone)] +pub struct ConditionalAndContextExt<'input> { + pub e: Option>>, + pub s8: Option>, + pub ops: Vec>, + pub relation: Option>>, + pub e1: Vec>>, + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for ConditionalAndContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for ConditionalAndContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_conditionalAnd(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_conditionalAnd(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for ConditionalAndContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_conditionalAnd(self); + } +} + +impl<'input> CustomRuleContext<'input> for ConditionalAndContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_conditionalAnd + } + //fn type_rule_index() -> usize where Self: Sized { RULE_conditionalAnd } +} +antlr4rust::tid! {ConditionalAndContextExt<'a>} + +impl<'input> ConditionalAndContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + ConditionalAndContextExt { + s8: None, + ops: Vec::new(), + e: None, + relation: None, + e1: Vec::new(), + ph: PhantomData, + }, + )) + } +} + +pub trait ConditionalAndContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ + fn relation_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + fn relation(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.child_of_type(i) + } + /// Retrieves all `TerminalNode`s corresponding to token LOGICAL_AND in current rule + fn LOGICAL_AND_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + /// Retrieves 'i's TerminalNode corresponding to token LOGICAL_AND, starting from 0. + /// Returns `None` if number of children corresponding to token LOGICAL_AND is less or equal than `i`. + fn LOGICAL_AND(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.get_token(LOGICAL_AND, i) + } +} + +impl<'input> ConditionalAndContextAttrs<'input> for ConditionalAndContext<'input> {} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn conditionalAnd(&mut self) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = + ConditionalAndContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog + .base + .enter_rule(_localctx.clone(), 6, RULE_conditionalAnd); + let mut _localctx: Rc = _localctx; + let mut _la: isize = -1; + let result: Result<(), ANTLRError> = (|| { + //recog.base.enter_outer_alt(_localctx.clone(), 1); + recog.base.enter_outer_alt(None, 1); + { + /*InvokeRule relation*/ + recog.base.set_state(53); + let tmp = recog.relation_rec(0)?; + cast_mut::<_, ConditionalAndContext>(&mut _localctx).e = Some(tmp.clone()); + + recog.base.set_state(58); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + while _la == LOGICAL_AND { + { + { + recog.base.set_state(54); + let tmp = recog + .base + .match_token(LOGICAL_AND, &mut recog.err_handler)?; + cast_mut::<_, ConditionalAndContext>(&mut _localctx).s8 = + Some(tmp.clone()); + + let temp = cast_mut::<_, ConditionalAndContext>(&mut _localctx) + .s8 + .clone() + .unwrap(); + cast_mut::<_, ConditionalAndContext>(&mut _localctx) + .ops + .push(temp); + + /*InvokeRule relation*/ + recog.base.set_state(55); + let tmp = recog.relation_rec(0)?; + cast_mut::<_, ConditionalAndContext>(&mut _localctx).relation = + Some(tmp.clone()); + + let temp = cast_mut::<_, ConditionalAndContext>(&mut _localctx) + .relation + .clone() + .unwrap(); + cast_mut::<_, ConditionalAndContext>(&mut _localctx) + .e1 + .push(temp); + } + } + recog.base.set_state(60); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + } + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} +//------------------- relation ---------------- +pub type RelationContextAll<'input> = RelationContext<'input>; + +pub type RelationContext<'input> = BaseParserRuleContext<'input, RelationContextExt<'input>>; + +#[derive(Clone)] +pub struct RelationContextExt<'input> { + pub op: Option>, + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for RelationContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for RelationContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_relation(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_relation(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for RelationContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_relation(self); + } +} + +impl<'input> CustomRuleContext<'input> for RelationContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_relation + } + //fn type_rule_index() -> usize where Self: Sized { RULE_relation } +} +antlr4rust::tid! {RelationContextExt<'a>} + +impl<'input> RelationContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + RelationContextExt { + op: None, + ph: PhantomData, + }, + )) + } +} + +pub trait RelationContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ + fn calc(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } + fn relation_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + fn relation(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.child_of_type(i) + } + /// Retrieves first TerminalNode corresponding to token LESS + /// Returns `None` if there is no child corresponding to token LESS + fn LESS(&self) -> Option>> + where + Self: Sized, + { + self.get_token(LESS, 0) + } + /// Retrieves first TerminalNode corresponding to token LESS_EQUALS + /// Returns `None` if there is no child corresponding to token LESS_EQUALS + fn LESS_EQUALS(&self) -> Option>> + where + Self: Sized, + { + self.get_token(LESS_EQUALS, 0) + } + /// Retrieves first TerminalNode corresponding to token GREATER_EQUALS + /// Returns `None` if there is no child corresponding to token GREATER_EQUALS + fn GREATER_EQUALS(&self) -> Option>> + where + Self: Sized, + { + self.get_token(GREATER_EQUALS, 0) + } + /// Retrieves first TerminalNode corresponding to token GREATER + /// Returns `None` if there is no child corresponding to token GREATER + fn GREATER(&self) -> Option>> + where + Self: Sized, + { + self.get_token(GREATER, 0) + } + /// Retrieves first TerminalNode corresponding to token EQUALS + /// Returns `None` if there is no child corresponding to token EQUALS + fn EQUALS(&self) -> Option>> + where + Self: Sized, + { + self.get_token(EQUALS, 0) + } + /// Retrieves first TerminalNode corresponding to token NOT_EQUALS + /// Returns `None` if there is no child corresponding to token NOT_EQUALS + fn NOT_EQUALS(&self) -> Option>> + where + Self: Sized, + { + self.get_token(NOT_EQUALS, 0) + } + /// Retrieves first TerminalNode corresponding to token IN + /// Returns `None` if there is no child corresponding to token IN + fn IN(&self) -> Option>> + where + Self: Sized, + { + self.get_token(IN, 0) + } +} + +impl<'input> RelationContextAttrs<'input> for RelationContext<'input> {} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn relation(&mut self) -> Result>, ANTLRError> { + self.relation_rec(0) + } + + fn relation_rec(&mut self, _p: isize) -> Result>, ANTLRError> { + let recog = self; + let _parentctx = recog.ctx.take(); + let _parentState = recog.base.get_state(); + let mut _localctx = RelationContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog + .base + .enter_recursion_rule(_localctx.clone(), 8, RULE_relation, _p); + let mut _localctx: Rc = _localctx; + let mut _prevctx = _localctx.clone(); + let _startState = 8; + let mut _la: isize = -1; + let result: Result<(), ANTLRError> = (|| { + let mut _alt: isize; + //recog.base.enter_outer_alt(_localctx.clone(), 1); + recog.base.enter_outer_alt(None, 1); + { + { + /*InvokeRule calc*/ + recog.base.set_state(62); + recog.calc_rec(0)?; + } + + let tmp = recog.input.lt(-1).cloned(); + recog.ctx.as_ref().unwrap().set_stop(tmp); + recog.base.set_state(69); + recog.err_handler.sync(&mut recog.base)?; + _alt = recog.interpreter.adaptive_predict(3, &mut recog.base)?; + while { _alt != 2 && _alt != INVALID_ALT } { + if _alt == 1 { + recog.trigger_exit_rule_event(); + _prevctx = _localctx.clone(); + { + { + /*recRuleAltStartAction*/ + let mut tmp = + RelationContextExt::new(_parentctx.clone(), _parentState); + recog.push_new_recursion_context( + tmp.clone(), + _startState, + RULE_relation, + ); + _localctx = tmp; + recog.base.set_state(64); + if !({ recog.precpred(None, 1) }) { + Err(FailedPredicateError::new( + &mut recog.base, + Some("recog.precpred(None, 1)".to_owned()), + None, + ))?; + } + recog.base.set_state(65); + cast_mut::<_, RelationContext>(&mut _localctx).op = + recog.base.input.lt(1).cloned(); + + _la = recog.base.input.la(1); + if !(((_la) & !0x3f) == 0 + && ((1usize << _la) + & ((1usize << EQUALS) + | (1usize << NOT_EQUALS) + | (1usize << IN) + | (1usize << LESS) + | (1usize << LESS_EQUALS) + | (1usize << GREATER_EQUALS) + | (1usize << GREATER))) + != 0) + { + let tmp = recog.err_handler.recover_inline(&mut recog.base)?; + cast_mut::<_, RelationContext>(&mut _localctx).op = + Some(tmp.clone()); + } else { + if recog.base.input.la(1) == TOKEN_EOF { + recog.base.matched_eof = true + }; + recog.err_handler.report_match(&mut recog.base); + recog.base.consume(&mut recog.err_handler); + } + /*InvokeRule relation*/ + recog.base.set_state(66); + recog.relation_rec(2)?; + } + } + } + recog.base.set_state(71); + recog.err_handler.sync(&mut recog.base)?; + _alt = recog.interpreter.adaptive_predict(3, &mut recog.base)?; + } + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.unroll_recursion_context(_parentctx); + + Ok(_localctx) + } +} +//------------------- calc ---------------- +pub type CalcContextAll<'input> = CalcContext<'input>; + +pub type CalcContext<'input> = BaseParserRuleContext<'input, CalcContextExt<'input>>; + +#[derive(Clone)] +pub struct CalcContextExt<'input> { + pub op: Option>, + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for CalcContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for CalcContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_calc(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_calc(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for CalcContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_calc(self); + } +} + +impl<'input> CustomRuleContext<'input> for CalcContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_calc + } + //fn type_rule_index() -> usize where Self: Sized { RULE_calc } +} +antlr4rust::tid! {CalcContextExt<'a>} + +impl<'input> CalcContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + CalcContextExt { + op: None, + ph: PhantomData, + }, + )) + } +} + +pub trait CalcContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ + fn unary(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } + fn calc_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + fn calc(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.child_of_type(i) + } + /// Retrieves first TerminalNode corresponding to token STAR + /// Returns `None` if there is no child corresponding to token STAR + fn STAR(&self) -> Option>> + where + Self: Sized, + { + self.get_token(STAR, 0) + } + /// Retrieves first TerminalNode corresponding to token SLASH + /// Returns `None` if there is no child corresponding to token SLASH + fn SLASH(&self) -> Option>> + where + Self: Sized, + { + self.get_token(SLASH, 0) + } + /// Retrieves first TerminalNode corresponding to token PERCENT + /// Returns `None` if there is no child corresponding to token PERCENT + fn PERCENT(&self) -> Option>> + where + Self: Sized, + { + self.get_token(PERCENT, 0) + } + /// Retrieves first TerminalNode corresponding to token PLUS + /// Returns `None` if there is no child corresponding to token PLUS + fn PLUS(&self) -> Option>> + where + Self: Sized, + { + self.get_token(PLUS, 0) + } + /// Retrieves first TerminalNode corresponding to token MINUS + /// Returns `None` if there is no child corresponding to token MINUS + fn MINUS(&self) -> Option>> + where + Self: Sized, + { + self.get_token(MINUS, 0) + } +} + +impl<'input> CalcContextAttrs<'input> for CalcContext<'input> {} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn calc(&mut self) -> Result>, ANTLRError> { + self.calc_rec(0) + } + + fn calc_rec(&mut self, _p: isize) -> Result>, ANTLRError> { + let recog = self; + let _parentctx = recog.ctx.take(); + let _parentState = recog.base.get_state(); + let mut _localctx = CalcContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog + .base + .enter_recursion_rule(_localctx.clone(), 10, RULE_calc, _p); + let mut _localctx: Rc = _localctx; + let mut _prevctx = _localctx.clone(); + let _startState = 10; + let mut _la: isize = -1; + let result: Result<(), ANTLRError> = (|| { + let mut _alt: isize; + //recog.base.enter_outer_alt(_localctx.clone(), 1); + recog.base.enter_outer_alt(None, 1); + { + { + /*InvokeRule unary*/ + recog.base.set_state(73); + recog.unary()?; + } + + let tmp = recog.input.lt(-1).cloned(); + recog.ctx.as_ref().unwrap().set_stop(tmp); + recog.base.set_state(83); + recog.err_handler.sync(&mut recog.base)?; + _alt = recog.interpreter.adaptive_predict(5, &mut recog.base)?; + while { _alt != 2 && _alt != INVALID_ALT } { + if _alt == 1 { + recog.trigger_exit_rule_event(); + _prevctx = _localctx.clone(); + { + recog.base.set_state(81); + recog.err_handler.sync(&mut recog.base)?; + match recog.interpreter.adaptive_predict(4, &mut recog.base)? { + 1 => { + { + /*recRuleAltStartAction*/ + let mut tmp = + CalcContextExt::new(_parentctx.clone(), _parentState); + recog.push_new_recursion_context( + tmp.clone(), + _startState, + RULE_calc, + ); + _localctx = tmp; + recog.base.set_state(75); + if !({ recog.precpred(None, 2) }) { + Err(FailedPredicateError::new( + &mut recog.base, + Some("recog.precpred(None, 2)".to_owned()), + None, + ))?; + } + recog.base.set_state(76); + cast_mut::<_, CalcContext>(&mut _localctx).op = + recog.base.input.lt(1).cloned(); + + _la = recog.base.input.la(1); + if !(((_la) & !0x3f) == 0 + && ((1usize << _la) + & ((1usize << STAR) + | (1usize << SLASH) + | (1usize << PERCENT))) + != 0) + { + let tmp = recog + .err_handler + .recover_inline(&mut recog.base)?; + cast_mut::<_, CalcContext>(&mut _localctx).op = + Some(tmp.clone()); + } else { + if recog.base.input.la(1) == TOKEN_EOF { + recog.base.matched_eof = true + }; + recog.err_handler.report_match(&mut recog.base); + recog.base.consume(&mut recog.err_handler); + } + /*InvokeRule calc*/ + recog.base.set_state(77); + recog.calc_rec(3)?; + } + } + 2 => { + { + /*recRuleAltStartAction*/ + let mut tmp = + CalcContextExt::new(_parentctx.clone(), _parentState); + recog.push_new_recursion_context( + tmp.clone(), + _startState, + RULE_calc, + ); + _localctx = tmp; + recog.base.set_state(78); + if !({ recog.precpred(None, 1) }) { + Err(FailedPredicateError::new( + &mut recog.base, + Some("recog.precpred(None, 1)".to_owned()), + None, + ))?; + } + recog.base.set_state(79); + cast_mut::<_, CalcContext>(&mut _localctx).op = + recog.base.input.lt(1).cloned(); + + _la = recog.base.input.la(1); + if !(_la == MINUS || _la == PLUS) { + let tmp = recog + .err_handler + .recover_inline(&mut recog.base)?; + cast_mut::<_, CalcContext>(&mut _localctx).op = + Some(tmp.clone()); + } else { + if recog.base.input.la(1) == TOKEN_EOF { + recog.base.matched_eof = true + }; + recog.err_handler.report_match(&mut recog.base); + recog.base.consume(&mut recog.err_handler); + } + /*InvokeRule calc*/ + recog.base.set_state(80); + recog.calc_rec(2)?; + } + } + + _ => {} + } + } + } + recog.base.set_state(85); + recog.err_handler.sync(&mut recog.base)?; + _alt = recog.interpreter.adaptive_predict(5, &mut recog.base)?; + } + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.unroll_recursion_context(_parentctx); + + Ok(_localctx) + } +} +//------------------- unary ---------------- +#[derive(Debug)] +pub enum UnaryContextAll<'input> { + LogicalNotContext(LogicalNotContext<'input>), + MemberExprContext(MemberExprContext<'input>), + NegateContext(NegateContext<'input>), + Error(UnaryContext<'input>), +} +antlr4rust::tid! {UnaryContextAll<'a>} + +impl<'input> antlr4rust::parser_rule_context::DerefSeal for UnaryContextAll<'input> {} + +impl<'input> CELParserContext<'input> for UnaryContextAll<'input> {} + +impl<'input> Deref for UnaryContextAll<'input> { + type Target = dyn UnaryContextAttrs<'input> + 'input; + fn deref(&self) -> &Self::Target { + use UnaryContextAll::*; + match self { + LogicalNotContext(inner) => inner, + MemberExprContext(inner) => inner, + NegateContext(inner) => inner, + Error(inner) => inner, + } + } +} +impl<'input, 'a> Visitable + 'a> for UnaryContextAll<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + if !matches!(self, UnaryContextAll::Error(_)) { + self.deref().accept(visitor) + } + } +} +impl<'input, 'a> Listenable + 'a> for UnaryContextAll<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + self.deref().enter(listener) + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + self.deref().exit(listener) + } +} + +pub type UnaryContext<'input> = BaseParserRuleContext<'input, UnaryContextExt<'input>>; + +#[derive(Clone)] +pub struct UnaryContextExt<'input> { + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for UnaryContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for UnaryContext<'input> {} + +impl<'input, 'a> Visitable + 'a> for UnaryContext<'input> {} + +impl<'input> CustomRuleContext<'input> for UnaryContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_unary + } + //fn type_rule_index() -> usize where Self: Sized { RULE_unary } +} +antlr4rust::tid! {UnaryContextExt<'a>} + +impl<'input> UnaryContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(UnaryContextAll::Error( + BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + UnaryContextExt { ph: PhantomData }, + ), + )) + } +} + +pub trait UnaryContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ +} + +impl<'input> UnaryContextAttrs<'input> for UnaryContext<'input> {} + +pub type LogicalNotContext<'input> = BaseParserRuleContext<'input, LogicalNotContextExt<'input>>; + +pub trait LogicalNotContextAttrs<'input>: CELParserContext<'input> { + fn member(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } + /// Retrieves all `TerminalNode`s corresponding to token EXCLAM in current rule + fn EXCLAM_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + /// Retrieves 'i's TerminalNode corresponding to token EXCLAM, starting from 0. + /// Returns `None` if number of children corresponding to token EXCLAM is less or equal than `i`. + fn EXCLAM(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.get_token(EXCLAM, i) + } +} + +impl<'input> LogicalNotContextAttrs<'input> for LogicalNotContext<'input> {} + +pub struct LogicalNotContextExt<'input> { + base: UnaryContextExt<'input>, + pub s19: Option>, + pub ops: Vec>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {LogicalNotContextExt<'a>} + +impl<'input> CELParserContext<'input> for LogicalNotContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for LogicalNotContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_LogicalNot(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_LogicalNot(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for LogicalNotContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_LogicalNot(self); + } +} + +impl<'input> CustomRuleContext<'input> for LogicalNotContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_unary + } + //fn type_rule_index() -> usize where Self: Sized { RULE_unary } +} + +impl<'input> Borrow> for LogicalNotContext<'input> { + fn borrow(&self) -> &UnaryContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for LogicalNotContext<'input> { + fn borrow_mut(&mut self) -> &mut UnaryContextExt<'input> { + &mut self.base + } +} + +impl<'input> UnaryContextAttrs<'input> for LogicalNotContext<'input> {} + +impl<'input> LogicalNotContextExt<'input> { + fn new(ctx: &dyn UnaryContextAttrs<'input>) -> Rc> { + Rc::new(UnaryContextAll::LogicalNotContext( + BaseParserRuleContext::copy_from( + ctx, + LogicalNotContextExt { + s19: None, + ops: Vec::new(), + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type MemberExprContext<'input> = BaseParserRuleContext<'input, MemberExprContextExt<'input>>; + +pub trait MemberExprContextAttrs<'input>: CELParserContext<'input> { + fn member(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } +} + +impl<'input> MemberExprContextAttrs<'input> for MemberExprContext<'input> {} + +pub struct MemberExprContextExt<'input> { + base: UnaryContextExt<'input>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {MemberExprContextExt<'a>} + +impl<'input> CELParserContext<'input> for MemberExprContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for MemberExprContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_MemberExpr(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_MemberExpr(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for MemberExprContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_MemberExpr(self); + } +} + +impl<'input> CustomRuleContext<'input> for MemberExprContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_unary + } + //fn type_rule_index() -> usize where Self: Sized { RULE_unary } +} + +impl<'input> Borrow> for MemberExprContext<'input> { + fn borrow(&self) -> &UnaryContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for MemberExprContext<'input> { + fn borrow_mut(&mut self) -> &mut UnaryContextExt<'input> { + &mut self.base + } +} + +impl<'input> UnaryContextAttrs<'input> for MemberExprContext<'input> {} + +impl<'input> MemberExprContextExt<'input> { + fn new(ctx: &dyn UnaryContextAttrs<'input>) -> Rc> { + Rc::new(UnaryContextAll::MemberExprContext( + BaseParserRuleContext::copy_from( + ctx, + MemberExprContextExt { + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type NegateContext<'input> = BaseParserRuleContext<'input, NegateContextExt<'input>>; + +pub trait NegateContextAttrs<'input>: CELParserContext<'input> { + fn member(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } + /// Retrieves all `TerminalNode`s corresponding to token MINUS in current rule + fn MINUS_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + /// Retrieves 'i's TerminalNode corresponding to token MINUS, starting from 0. + /// Returns `None` if number of children corresponding to token MINUS is less or equal than `i`. + fn MINUS(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.get_token(MINUS, i) + } +} + +impl<'input> NegateContextAttrs<'input> for NegateContext<'input> {} + +pub struct NegateContextExt<'input> { + base: UnaryContextExt<'input>, + pub s18: Option>, + pub ops: Vec>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {NegateContextExt<'a>} + +impl<'input> CELParserContext<'input> for NegateContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for NegateContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_Negate(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_Negate(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for NegateContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_Negate(self); + } +} + +impl<'input> CustomRuleContext<'input> for NegateContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_unary + } + //fn type_rule_index() -> usize where Self: Sized { RULE_unary } +} + +impl<'input> Borrow> for NegateContext<'input> { + fn borrow(&self) -> &UnaryContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for NegateContext<'input> { + fn borrow_mut(&mut self) -> &mut UnaryContextExt<'input> { + &mut self.base + } +} + +impl<'input> UnaryContextAttrs<'input> for NegateContext<'input> {} + +impl<'input> NegateContextExt<'input> { + fn new(ctx: &dyn UnaryContextAttrs<'input>) -> Rc> { + Rc::new(UnaryContextAll::NegateContext( + BaseParserRuleContext::copy_from( + ctx, + NegateContextExt { + s18: None, + ops: Vec::new(), + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn unary(&mut self) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = UnaryContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog.base.enter_rule(_localctx.clone(), 12, RULE_unary); + let mut _localctx: Rc = _localctx; + let mut _la: isize = -1; + let result: Result<(), ANTLRError> = (|| { + let mut _alt: isize; + recog.base.set_state(99); + recog.err_handler.sync(&mut recog.base)?; + match recog.interpreter.adaptive_predict(8, &mut recog.base)? { + 1 => { + let tmp = MemberExprContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 1); + _localctx = tmp; + { + /*InvokeRule member*/ + recog.base.set_state(86); + recog.member_rec(0)?; + } + } + 2 => { + let tmp = LogicalNotContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 2); + _localctx = tmp; + { + recog.base.set_state(88); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + loop { + { + { + recog.base.set_state(87); + let tmp = + recog.base.match_token(EXCLAM, &mut recog.err_handler)?; + if let UnaryContextAll::LogicalNotContext(ctx) = + cast_mut::<_, UnaryContextAll>(&mut _localctx) + { + ctx.s19 = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + let temp = if let UnaryContextAll::LogicalNotContext(ctx) = + cast_mut::<_, UnaryContextAll>(&mut _localctx) + { + ctx.s19.clone().unwrap() + } else { + unreachable!("cant cast"); + }; + if let UnaryContextAll::LogicalNotContext(ctx) = + cast_mut::<_, UnaryContextAll>(&mut _localctx) + { + ctx.ops.push(temp); + } else { + unreachable!("cant cast"); + } + } + } + recog.base.set_state(90); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la != EXCLAM { + break; + } + } + /*InvokeRule member*/ + recog.base.set_state(92); + recog.member_rec(0)?; + } + } + 3 => { + let tmp = NegateContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 3); + _localctx = tmp; + { + recog.base.set_state(94); + recog.err_handler.sync(&mut recog.base)?; + _alt = 1; + loop { + match _alt { + x if x == 1 => { + recog.base.set_state(93); + let tmp = + recog.base.match_token(MINUS, &mut recog.err_handler)?; + if let UnaryContextAll::NegateContext(ctx) = + cast_mut::<_, UnaryContextAll>(&mut _localctx) + { + ctx.s18 = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + let temp = if let UnaryContextAll::NegateContext(ctx) = + cast_mut::<_, UnaryContextAll>(&mut _localctx) + { + ctx.s18.clone().unwrap() + } else { + unreachable!("cant cast"); + }; + if let UnaryContextAll::NegateContext(ctx) = + cast_mut::<_, UnaryContextAll>(&mut _localctx) + { + ctx.ops.push(temp); + } else { + unreachable!("cant cast"); + } + } + + _ => Err(ANTLRError::NoAltError(NoViableAltError::new( + &mut recog.base, + )))?, + } + recog.base.set_state(96); + recog.err_handler.sync(&mut recog.base)?; + _alt = recog.interpreter.adaptive_predict(7, &mut recog.base)?; + if _alt == 2 || _alt == INVALID_ALT { + break; + } + } + /*InvokeRule member*/ + recog.base.set_state(98); + recog.member_rec(0)?; + } + } + + _ => {} + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} +//------------------- member ---------------- +#[derive(Debug)] +pub enum MemberContextAll<'input> { + MemberCallContext(MemberCallContext<'input>), + SelectContext(SelectContext<'input>), + PrimaryExprContext(PrimaryExprContext<'input>), + IndexContext(IndexContext<'input>), + Error(MemberContext<'input>), +} +antlr4rust::tid! {MemberContextAll<'a>} + +impl<'input> antlr4rust::parser_rule_context::DerefSeal for MemberContextAll<'input> {} + +impl<'input> CELParserContext<'input> for MemberContextAll<'input> {} + +impl<'input> Deref for MemberContextAll<'input> { + type Target = dyn MemberContextAttrs<'input> + 'input; + fn deref(&self) -> &Self::Target { + use MemberContextAll::*; + match self { + MemberCallContext(inner) => inner, + SelectContext(inner) => inner, + PrimaryExprContext(inner) => inner, + IndexContext(inner) => inner, + Error(inner) => inner, + } + } +} +impl<'input, 'a> Visitable + 'a> for MemberContextAll<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + if !matches!(self, MemberContextAll::Error(_)) { + self.deref().accept(visitor) + } + } +} +impl<'input, 'a> Listenable + 'a> for MemberContextAll<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + self.deref().enter(listener) + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + self.deref().exit(listener) + } +} + +pub type MemberContext<'input> = BaseParserRuleContext<'input, MemberContextExt<'input>>; + +#[derive(Clone)] +pub struct MemberContextExt<'input> { + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for MemberContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for MemberContext<'input> {} + +impl<'input, 'a> Visitable + 'a> for MemberContext<'input> {} + +impl<'input> CustomRuleContext<'input> for MemberContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_member + } + //fn type_rule_index() -> usize where Self: Sized { RULE_member } +} +antlr4rust::tid! {MemberContextExt<'a>} + +impl<'input> MemberContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(MemberContextAll::Error( + BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + MemberContextExt { ph: PhantomData }, + ), + )) + } +} + +pub trait MemberContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ +} + +impl<'input> MemberContextAttrs<'input> for MemberContext<'input> {} + +pub type MemberCallContext<'input> = BaseParserRuleContext<'input, MemberCallContextExt<'input>>; + +pub trait MemberCallContextAttrs<'input>: CELParserContext<'input> { + fn member(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } + /// Retrieves first TerminalNode corresponding to token RPAREN + /// Returns `None` if there is no child corresponding to token RPAREN + fn RPAREN(&self) -> Option>> + where + Self: Sized, + { + self.get_token(RPAREN, 0) + } + /// Retrieves first TerminalNode corresponding to token DOT + /// Returns `None` if there is no child corresponding to token DOT + fn DOT(&self) -> Option>> + where + Self: Sized, + { + self.get_token(DOT, 0) + } + /// Retrieves first TerminalNode corresponding to token IDENTIFIER + /// Returns `None` if there is no child corresponding to token IDENTIFIER + fn IDENTIFIER(&self) -> Option>> + where + Self: Sized, + { + self.get_token(IDENTIFIER, 0) + } + /// Retrieves first TerminalNode corresponding to token LPAREN + /// Returns `None` if there is no child corresponding to token LPAREN + fn LPAREN(&self) -> Option>> + where + Self: Sized, + { + self.get_token(LPAREN, 0) + } + fn exprList(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } +} + +impl<'input> MemberCallContextAttrs<'input> for MemberCallContext<'input> {} + +pub struct MemberCallContextExt<'input> { + base: MemberContextExt<'input>, + pub op: Option>, + pub id: Option>, + pub open: Option>, + pub args: Option>>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {MemberCallContextExt<'a>} + +impl<'input> CELParserContext<'input> for MemberCallContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for MemberCallContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_MemberCall(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_MemberCall(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for MemberCallContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_MemberCall(self); + } +} + +impl<'input> CustomRuleContext<'input> for MemberCallContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_member + } + //fn type_rule_index() -> usize where Self: Sized { RULE_member } +} + +impl<'input> Borrow> for MemberCallContext<'input> { + fn borrow(&self) -> &MemberContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for MemberCallContext<'input> { + fn borrow_mut(&mut self) -> &mut MemberContextExt<'input> { + &mut self.base + } +} + +impl<'input> MemberContextAttrs<'input> for MemberCallContext<'input> {} + +impl<'input> MemberCallContextExt<'input> { + fn new(ctx: &dyn MemberContextAttrs<'input>) -> Rc> { + Rc::new(MemberContextAll::MemberCallContext( + BaseParserRuleContext::copy_from( + ctx, + MemberCallContextExt { + op: None, + id: None, + open: None, + args: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type SelectContext<'input> = BaseParserRuleContext<'input, SelectContextExt<'input>>; + +pub trait SelectContextAttrs<'input>: CELParserContext<'input> { + fn member(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } + /// Retrieves first TerminalNode corresponding to token DOT + /// Returns `None` if there is no child corresponding to token DOT + fn DOT(&self) -> Option>> + where + Self: Sized, + { + self.get_token(DOT, 0) + } + fn escapeIdent(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } + /// Retrieves first TerminalNode corresponding to token QUESTIONMARK + /// Returns `None` if there is no child corresponding to token QUESTIONMARK + fn QUESTIONMARK(&self) -> Option>> + where + Self: Sized, + { + self.get_token(QUESTIONMARK, 0) + } +} + +impl<'input> SelectContextAttrs<'input> for SelectContext<'input> {} + +pub struct SelectContextExt<'input> { + base: MemberContextExt<'input>, + pub op: Option>, + pub opt: Option>, + pub id: Option>>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {SelectContextExt<'a>} + +impl<'input> CELParserContext<'input> for SelectContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for SelectContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_Select(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_Select(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for SelectContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_Select(self); + } +} + +impl<'input> CustomRuleContext<'input> for SelectContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_member + } + //fn type_rule_index() -> usize where Self: Sized { RULE_member } +} + +impl<'input> Borrow> for SelectContext<'input> { + fn borrow(&self) -> &MemberContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for SelectContext<'input> { + fn borrow_mut(&mut self) -> &mut MemberContextExt<'input> { + &mut self.base + } +} + +impl<'input> MemberContextAttrs<'input> for SelectContext<'input> {} + +impl<'input> SelectContextExt<'input> { + fn new(ctx: &dyn MemberContextAttrs<'input>) -> Rc> { + Rc::new(MemberContextAll::SelectContext( + BaseParserRuleContext::copy_from( + ctx, + SelectContextExt { + op: None, + opt: None, + id: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type PrimaryExprContext<'input> = BaseParserRuleContext<'input, PrimaryExprContextExt<'input>>; + +pub trait PrimaryExprContextAttrs<'input>: CELParserContext<'input> { + fn primary(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } +} + +impl<'input> PrimaryExprContextAttrs<'input> for PrimaryExprContext<'input> {} + +pub struct PrimaryExprContextExt<'input> { + base: MemberContextExt<'input>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {PrimaryExprContextExt<'a>} + +impl<'input> CELParserContext<'input> for PrimaryExprContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for PrimaryExprContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_PrimaryExpr(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_PrimaryExpr(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for PrimaryExprContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_PrimaryExpr(self); + } +} + +impl<'input> CustomRuleContext<'input> for PrimaryExprContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_member + } + //fn type_rule_index() -> usize where Self: Sized { RULE_member } +} + +impl<'input> Borrow> for PrimaryExprContext<'input> { + fn borrow(&self) -> &MemberContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for PrimaryExprContext<'input> { + fn borrow_mut(&mut self) -> &mut MemberContextExt<'input> { + &mut self.base + } +} + +impl<'input> MemberContextAttrs<'input> for PrimaryExprContext<'input> {} + +impl<'input> PrimaryExprContextExt<'input> { + fn new(ctx: &dyn MemberContextAttrs<'input>) -> Rc> { + Rc::new(MemberContextAll::PrimaryExprContext( + BaseParserRuleContext::copy_from( + ctx, + PrimaryExprContextExt { + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type IndexContext<'input> = BaseParserRuleContext<'input, IndexContextExt<'input>>; + +pub trait IndexContextAttrs<'input>: CELParserContext<'input> { + fn member(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } + /// Retrieves first TerminalNode corresponding to token RPRACKET + /// Returns `None` if there is no child corresponding to token RPRACKET + fn RPRACKET(&self) -> Option>> + where + Self: Sized, + { + self.get_token(RPRACKET, 0) + } + /// Retrieves first TerminalNode corresponding to token LBRACKET + /// Returns `None` if there is no child corresponding to token LBRACKET + fn LBRACKET(&self) -> Option>> + where + Self: Sized, + { + self.get_token(LBRACKET, 0) + } + fn expr(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } + /// Retrieves first TerminalNode corresponding to token QUESTIONMARK + /// Returns `None` if there is no child corresponding to token QUESTIONMARK + fn QUESTIONMARK(&self) -> Option>> + where + Self: Sized, + { + self.get_token(QUESTIONMARK, 0) + } +} + +impl<'input> IndexContextAttrs<'input> for IndexContext<'input> {} + +pub struct IndexContextExt<'input> { + base: MemberContextExt<'input>, + pub op: Option>, + pub opt: Option>, + pub index: Option>>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {IndexContextExt<'a>} + +impl<'input> CELParserContext<'input> for IndexContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for IndexContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_Index(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_Index(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for IndexContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_Index(self); + } +} + +impl<'input> CustomRuleContext<'input> for IndexContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_member + } + //fn type_rule_index() -> usize where Self: Sized { RULE_member } +} + +impl<'input> Borrow> for IndexContext<'input> { + fn borrow(&self) -> &MemberContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for IndexContext<'input> { + fn borrow_mut(&mut self) -> &mut MemberContextExt<'input> { + &mut self.base + } +} + +impl<'input> MemberContextAttrs<'input> for IndexContext<'input> {} + +impl<'input> IndexContextExt<'input> { + fn new(ctx: &dyn MemberContextAttrs<'input>) -> Rc> { + Rc::new(MemberContextAll::IndexContext( + BaseParserRuleContext::copy_from( + ctx, + IndexContextExt { + op: None, + opt: None, + index: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn member(&mut self) -> Result>, ANTLRError> { + self.member_rec(0) + } + + fn member_rec(&mut self, _p: isize) -> Result>, ANTLRError> { + let recog = self; + let _parentctx = recog.ctx.take(); + let _parentState = recog.base.get_state(); + let mut _localctx = MemberContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog + .base + .enter_recursion_rule(_localctx.clone(), 14, RULE_member, _p); + let mut _localctx: Rc = _localctx; + let mut _prevctx = _localctx.clone(); + let _startState = 14; + let mut _la: isize = -1; + let result: Result<(), ANTLRError> = (|| { + let mut _alt: isize; + //recog.base.enter_outer_alt(_localctx.clone(), 1); + recog.base.enter_outer_alt(None, 1); + { + { + let mut tmp = PrimaryExprContextExt::new(&**_localctx); + recog.ctx = Some(tmp.clone()); + _localctx = tmp; + _prevctx = _localctx.clone(); + + /*InvokeRule primary*/ + recog.base.set_state(102); + recog.primary()?; + } + + let tmp = recog.input.lt(-1).cloned(); + recog.ctx.as_ref().unwrap().set_stop(tmp); + recog.base.set_state(128); + recog.err_handler.sync(&mut recog.base)?; + _alt = recog.interpreter.adaptive_predict(13, &mut recog.base)?; + while { _alt != 2 && _alt != INVALID_ALT } { + if _alt == 1 { + recog.trigger_exit_rule_event(); + _prevctx = _localctx.clone(); + { + recog.base.set_state(126); + recog.err_handler.sync(&mut recog.base)?; + match recog.interpreter.adaptive_predict(12, &mut recog.base)? { + 1 => { + { + /*recRuleLabeledAltStartAction*/ + let mut tmp = + SelectContextExt::new(&**MemberContextExt::new( + _parentctx.clone(), + _parentState, + )); + recog.push_new_recursion_context( + tmp.clone(), + _startState, + RULE_member, + ); + _localctx = tmp; + recog.base.set_state(104); + if !({ recog.precpred(None, 3) }) { + Err(FailedPredicateError::new( + &mut recog.base, + Some("recog.precpred(None, 3)".to_owned()), + None, + ))?; + } + recog.base.set_state(105); + let tmp = + recog.base.match_token(DOT, &mut recog.err_handler)?; + if let MemberContextAll::SelectContext(ctx) = + cast_mut::<_, MemberContextAll>(&mut _localctx) + { + ctx.op = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + recog.base.set_state(107); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la == QUESTIONMARK { + { + recog.base.set_state(106); + let tmp = recog.base.match_token( + QUESTIONMARK, + &mut recog.err_handler, + )?; + if let MemberContextAll::SelectContext(ctx) = + cast_mut::<_, MemberContextAll>(&mut _localctx) + { + ctx.opt = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + /*InvokeRule escapeIdent*/ + recog.base.set_state(109); + let tmp = recog.escapeIdent()?; + if let MemberContextAll::SelectContext(ctx) = + cast_mut::<_, MemberContextAll>(&mut _localctx) + { + ctx.id = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + 2 => { + { + /*recRuleLabeledAltStartAction*/ + let mut tmp = + MemberCallContextExt::new(&**MemberContextExt::new( + _parentctx.clone(), + _parentState, + )); + recog.push_new_recursion_context( + tmp.clone(), + _startState, + RULE_member, + ); + _localctx = tmp; + recog.base.set_state(110); + if !({ recog.precpred(None, 2) }) { + Err(FailedPredicateError::new( + &mut recog.base, + Some("recog.precpred(None, 2)".to_owned()), + None, + ))?; + } + recog.base.set_state(111); + let tmp = + recog.base.match_token(DOT, &mut recog.err_handler)?; + if let MemberContextAll::MemberCallContext(ctx) = + cast_mut::<_, MemberContextAll>(&mut _localctx) + { + ctx.op = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + recog.base.set_state(112); + let tmp = recog + .base + .match_token(IDENTIFIER, &mut recog.err_handler)?; + if let MemberContextAll::MemberCallContext(ctx) = + cast_mut::<_, MemberContextAll>(&mut _localctx) + { + ctx.id = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + recog.base.set_state(113); + let tmp = recog + .base + .match_token(LPAREN, &mut recog.err_handler)?; + if let MemberContextAll::MemberCallContext(ctx) = + cast_mut::<_, MemberContextAll>(&mut _localctx) + { + ctx.open = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + recog.base.set_state(115); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if ((_la - 10) & !0x3f) == 0 + && ((1usize << (_la - 10)) + & ((1usize << (LBRACKET - 10)) + | (1usize << (LBRACE - 10)) + | (1usize << (LPAREN - 10)) + | (1usize << (DOT - 10)) + | (1usize << (MINUS - 10)) + | (1usize << (EXCLAM - 10)) + | (1usize << (CEL_TRUE - 10)) + | (1usize << (CEL_FALSE - 10)) + | (1usize << (NUL - 10)) + | (1usize << (NUM_FLOAT - 10)) + | (1usize << (NUM_INT - 10)) + | (1usize << (NUM_UINT - 10)) + | (1usize << (STRING - 10)) + | (1usize << (BYTES - 10)) + | (1usize << (IDENTIFIER - 10)))) + != 0 + { + { + /*InvokeRule exprList*/ + recog.base.set_state(114); + let tmp = recog.exprList()?; + if let MemberContextAll::MemberCallContext(ctx) = + cast_mut::<_, MemberContextAll>(&mut _localctx) + { + ctx.args = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + recog.base.set_state(117); + recog.base.match_token(RPAREN, &mut recog.err_handler)?; + } + } + 3 => { + { + /*recRuleLabeledAltStartAction*/ + let mut tmp = + IndexContextExt::new(&**MemberContextExt::new( + _parentctx.clone(), + _parentState, + )); + recog.push_new_recursion_context( + tmp.clone(), + _startState, + RULE_member, + ); + _localctx = tmp; + recog.base.set_state(118); + if !({ recog.precpred(None, 1) }) { + Err(FailedPredicateError::new( + &mut recog.base, + Some("recog.precpred(None, 1)".to_owned()), + None, + ))?; + } + recog.base.set_state(119); + let tmp = recog + .base + .match_token(LBRACKET, &mut recog.err_handler)?; + if let MemberContextAll::IndexContext(ctx) = + cast_mut::<_, MemberContextAll>(&mut _localctx) + { + ctx.op = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + recog.base.set_state(121); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la == QUESTIONMARK { + { + recog.base.set_state(120); + let tmp = recog.base.match_token( + QUESTIONMARK, + &mut recog.err_handler, + )?; + if let MemberContextAll::IndexContext(ctx) = + cast_mut::<_, MemberContextAll>(&mut _localctx) + { + ctx.opt = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + /*InvokeRule expr*/ + recog.base.set_state(123); + let tmp = recog.expr()?; + if let MemberContextAll::IndexContext(ctx) = + cast_mut::<_, MemberContextAll>(&mut _localctx) + { + ctx.index = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + recog.base.set_state(124); + recog.base.match_token(RPRACKET, &mut recog.err_handler)?; + } + } + + _ => {} + } + } + } + recog.base.set_state(130); + recog.err_handler.sync(&mut recog.base)?; + _alt = recog.interpreter.adaptive_predict(13, &mut recog.base)?; + } + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.unroll_recursion_context(_parentctx); + + Ok(_localctx) + } +} +//------------------- primary ---------------- +#[derive(Debug)] +pub enum PrimaryContextAll<'input> { + CreateListContext(CreateListContext<'input>), + IdentContext(IdentContext<'input>), + CreateStructContext(CreateStructContext<'input>), + ConstantLiteralContext(ConstantLiteralContext<'input>), + NestedContext(NestedContext<'input>), + CreateMessageContext(CreateMessageContext<'input>), + GlobalCallContext(GlobalCallContext<'input>), + Error(PrimaryContext<'input>), +} +antlr4rust::tid! {PrimaryContextAll<'a>} + +impl<'input> antlr4rust::parser_rule_context::DerefSeal for PrimaryContextAll<'input> {} + +impl<'input> CELParserContext<'input> for PrimaryContextAll<'input> {} + +impl<'input> Deref for PrimaryContextAll<'input> { + type Target = dyn PrimaryContextAttrs<'input> + 'input; + fn deref(&self) -> &Self::Target { + use PrimaryContextAll::*; + match self { + CreateListContext(inner) => inner, + IdentContext(inner) => inner, + CreateStructContext(inner) => inner, + ConstantLiteralContext(inner) => inner, + NestedContext(inner) => inner, + CreateMessageContext(inner) => inner, + GlobalCallContext(inner) => inner, + Error(inner) => inner, + } + } +} +impl<'input, 'a> Visitable + 'a> for PrimaryContextAll<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + if !matches!(self, PrimaryContextAll::Error(_)) { + self.deref().accept(visitor) + } + } +} +impl<'input, 'a> Listenable + 'a> for PrimaryContextAll<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + self.deref().enter(listener) + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + self.deref().exit(listener) + } +} + +pub type PrimaryContext<'input> = BaseParserRuleContext<'input, PrimaryContextExt<'input>>; + +#[derive(Clone)] +pub struct PrimaryContextExt<'input> { + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for PrimaryContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for PrimaryContext<'input> {} + +impl<'input, 'a> Visitable + 'a> for PrimaryContext<'input> {} + +impl<'input> CustomRuleContext<'input> for PrimaryContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_primary + } + //fn type_rule_index() -> usize where Self: Sized { RULE_primary } +} +antlr4rust::tid! {PrimaryContextExt<'a>} + +impl<'input> PrimaryContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(PrimaryContextAll::Error( + BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + PrimaryContextExt { ph: PhantomData }, + ), + )) + } +} + +pub trait PrimaryContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ +} + +impl<'input> PrimaryContextAttrs<'input> for PrimaryContext<'input> {} + +pub type CreateListContext<'input> = BaseParserRuleContext<'input, CreateListContextExt<'input>>; + +pub trait CreateListContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token RPRACKET + /// Returns `None` if there is no child corresponding to token RPRACKET + fn RPRACKET(&self) -> Option>> + where + Self: Sized, + { + self.get_token(RPRACKET, 0) + } + /// Retrieves first TerminalNode corresponding to token LBRACKET + /// Returns `None` if there is no child corresponding to token LBRACKET + fn LBRACKET(&self) -> Option>> + where + Self: Sized, + { + self.get_token(LBRACKET, 0) + } + /// Retrieves first TerminalNode corresponding to token COMMA + /// Returns `None` if there is no child corresponding to token COMMA + fn COMMA(&self) -> Option>> + where + Self: Sized, + { + self.get_token(COMMA, 0) + } + fn listInit(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } +} + +impl<'input> CreateListContextAttrs<'input> for CreateListContext<'input> {} + +pub struct CreateListContextExt<'input> { + base: PrimaryContextExt<'input>, + pub op: Option>, + pub elems: Option>>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {CreateListContextExt<'a>} + +impl<'input> CELParserContext<'input> for CreateListContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for CreateListContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_CreateList(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_CreateList(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for CreateListContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_CreateList(self); + } +} + +impl<'input> CustomRuleContext<'input> for CreateListContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_primary + } + //fn type_rule_index() -> usize where Self: Sized { RULE_primary } +} + +impl<'input> Borrow> for CreateListContext<'input> { + fn borrow(&self) -> &PrimaryContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for CreateListContext<'input> { + fn borrow_mut(&mut self) -> &mut PrimaryContextExt<'input> { + &mut self.base + } +} + +impl<'input> PrimaryContextAttrs<'input> for CreateListContext<'input> {} + +impl<'input> CreateListContextExt<'input> { + fn new(ctx: &dyn PrimaryContextAttrs<'input>) -> Rc> { + Rc::new(PrimaryContextAll::CreateListContext( + BaseParserRuleContext::copy_from( + ctx, + CreateListContextExt { + op: None, + elems: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type IdentContext<'input> = BaseParserRuleContext<'input, IdentContextExt<'input>>; + +pub trait IdentContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token IDENTIFIER + /// Returns `None` if there is no child corresponding to token IDENTIFIER + fn IDENTIFIER(&self) -> Option>> + where + Self: Sized, + { + self.get_token(IDENTIFIER, 0) + } + /// Retrieves first TerminalNode corresponding to token DOT + /// Returns `None` if there is no child corresponding to token DOT + fn DOT(&self) -> Option>> + where + Self: Sized, + { + self.get_token(DOT, 0) + } +} + +impl<'input> IdentContextAttrs<'input> for IdentContext<'input> {} + +pub struct IdentContextExt<'input> { + base: PrimaryContextExt<'input>, + pub leadingDot: Option>, + pub id: Option>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {IdentContextExt<'a>} + +impl<'input> CELParserContext<'input> for IdentContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for IdentContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_Ident(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_Ident(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for IdentContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_Ident(self); + } +} + +impl<'input> CustomRuleContext<'input> for IdentContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_primary + } + //fn type_rule_index() -> usize where Self: Sized { RULE_primary } +} + +impl<'input> Borrow> for IdentContext<'input> { + fn borrow(&self) -> &PrimaryContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for IdentContext<'input> { + fn borrow_mut(&mut self) -> &mut PrimaryContextExt<'input> { + &mut self.base + } +} + +impl<'input> PrimaryContextAttrs<'input> for IdentContext<'input> {} + +impl<'input> IdentContextExt<'input> { + fn new(ctx: &dyn PrimaryContextAttrs<'input>) -> Rc> { + Rc::new(PrimaryContextAll::IdentContext( + BaseParserRuleContext::copy_from( + ctx, + IdentContextExt { + leadingDot: None, + id: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type CreateStructContext<'input> = + BaseParserRuleContext<'input, CreateStructContextExt<'input>>; + +pub trait CreateStructContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token RBRACE + /// Returns `None` if there is no child corresponding to token RBRACE + fn RBRACE(&self) -> Option>> + where + Self: Sized, + { + self.get_token(RBRACE, 0) + } + /// Retrieves first TerminalNode corresponding to token LBRACE + /// Returns `None` if there is no child corresponding to token LBRACE + fn LBRACE(&self) -> Option>> + where + Self: Sized, + { + self.get_token(LBRACE, 0) + } + /// Retrieves first TerminalNode corresponding to token COMMA + /// Returns `None` if there is no child corresponding to token COMMA + fn COMMA(&self) -> Option>> + where + Self: Sized, + { + self.get_token(COMMA, 0) + } + fn mapInitializerList(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } +} + +impl<'input> CreateStructContextAttrs<'input> for CreateStructContext<'input> {} + +pub struct CreateStructContextExt<'input> { + base: PrimaryContextExt<'input>, + pub op: Option>, + pub entries: Option>>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {CreateStructContextExt<'a>} + +impl<'input> CELParserContext<'input> for CreateStructContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for CreateStructContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_CreateStruct(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_CreateStruct(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for CreateStructContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_CreateStruct(self); + } +} + +impl<'input> CustomRuleContext<'input> for CreateStructContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_primary + } + //fn type_rule_index() -> usize where Self: Sized { RULE_primary } +} + +impl<'input> Borrow> for CreateStructContext<'input> { + fn borrow(&self) -> &PrimaryContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for CreateStructContext<'input> { + fn borrow_mut(&mut self) -> &mut PrimaryContextExt<'input> { + &mut self.base + } +} + +impl<'input> PrimaryContextAttrs<'input> for CreateStructContext<'input> {} + +impl<'input> CreateStructContextExt<'input> { + fn new(ctx: &dyn PrimaryContextAttrs<'input>) -> Rc> { + Rc::new(PrimaryContextAll::CreateStructContext( + BaseParserRuleContext::copy_from( + ctx, + CreateStructContextExt { + op: None, + entries: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type ConstantLiteralContext<'input> = + BaseParserRuleContext<'input, ConstantLiteralContextExt<'input>>; + +pub trait ConstantLiteralContextAttrs<'input>: CELParserContext<'input> { + fn literal(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } +} + +impl<'input> ConstantLiteralContextAttrs<'input> for ConstantLiteralContext<'input> {} + +pub struct ConstantLiteralContextExt<'input> { + base: PrimaryContextExt<'input>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {ConstantLiteralContextExt<'a>} + +impl<'input> CELParserContext<'input> for ConstantLiteralContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for ConstantLiteralContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_ConstantLiteral(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_ConstantLiteral(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for ConstantLiteralContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_ConstantLiteral(self); + } +} + +impl<'input> CustomRuleContext<'input> for ConstantLiteralContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_primary + } + //fn type_rule_index() -> usize where Self: Sized { RULE_primary } +} + +impl<'input> Borrow> for ConstantLiteralContext<'input> { + fn borrow(&self) -> &PrimaryContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for ConstantLiteralContext<'input> { + fn borrow_mut(&mut self) -> &mut PrimaryContextExt<'input> { + &mut self.base + } +} + +impl<'input> PrimaryContextAttrs<'input> for ConstantLiteralContext<'input> {} + +impl<'input> ConstantLiteralContextExt<'input> { + fn new(ctx: &dyn PrimaryContextAttrs<'input>) -> Rc> { + Rc::new(PrimaryContextAll::ConstantLiteralContext( + BaseParserRuleContext::copy_from( + ctx, + ConstantLiteralContextExt { + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type NestedContext<'input> = BaseParserRuleContext<'input, NestedContextExt<'input>>; + +pub trait NestedContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token LPAREN + /// Returns `None` if there is no child corresponding to token LPAREN + fn LPAREN(&self) -> Option>> + where + Self: Sized, + { + self.get_token(LPAREN, 0) + } + /// Retrieves first TerminalNode corresponding to token RPAREN + /// Returns `None` if there is no child corresponding to token RPAREN + fn RPAREN(&self) -> Option>> + where + Self: Sized, + { + self.get_token(RPAREN, 0) + } + fn expr(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } +} + +impl<'input> NestedContextAttrs<'input> for NestedContext<'input> {} + +pub struct NestedContextExt<'input> { + base: PrimaryContextExt<'input>, + pub e: Option>>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {NestedContextExt<'a>} + +impl<'input> CELParserContext<'input> for NestedContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for NestedContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_Nested(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_Nested(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for NestedContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_Nested(self); + } +} + +impl<'input> CustomRuleContext<'input> for NestedContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_primary + } + //fn type_rule_index() -> usize where Self: Sized { RULE_primary } +} + +impl<'input> Borrow> for NestedContext<'input> { + fn borrow(&self) -> &PrimaryContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for NestedContext<'input> { + fn borrow_mut(&mut self) -> &mut PrimaryContextExt<'input> { + &mut self.base + } +} + +impl<'input> PrimaryContextAttrs<'input> for NestedContext<'input> {} + +impl<'input> NestedContextExt<'input> { + fn new(ctx: &dyn PrimaryContextAttrs<'input>) -> Rc> { + Rc::new(PrimaryContextAll::NestedContext( + BaseParserRuleContext::copy_from( + ctx, + NestedContextExt { + e: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type CreateMessageContext<'input> = + BaseParserRuleContext<'input, CreateMessageContextExt<'input>>; + +pub trait CreateMessageContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token RBRACE + /// Returns `None` if there is no child corresponding to token RBRACE + fn RBRACE(&self) -> Option>> + where + Self: Sized, + { + self.get_token(RBRACE, 0) + } + /// Retrieves all `TerminalNode`s corresponding to token IDENTIFIER in current rule + fn IDENTIFIER_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + /// Retrieves 'i's TerminalNode corresponding to token IDENTIFIER, starting from 0. + /// Returns `None` if number of children corresponding to token IDENTIFIER is less or equal than `i`. + fn IDENTIFIER(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.get_token(IDENTIFIER, i) + } + /// Retrieves first TerminalNode corresponding to token LBRACE + /// Returns `None` if there is no child corresponding to token LBRACE + fn LBRACE(&self) -> Option>> + where + Self: Sized, + { + self.get_token(LBRACE, 0) + } + /// Retrieves first TerminalNode corresponding to token COMMA + /// Returns `None` if there is no child corresponding to token COMMA + fn COMMA(&self) -> Option>> + where + Self: Sized, + { + self.get_token(COMMA, 0) + } + /// Retrieves all `TerminalNode`s corresponding to token DOT in current rule + fn DOT_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + /// Retrieves 'i's TerminalNode corresponding to token DOT, starting from 0. + /// Returns `None` if number of children corresponding to token DOT is less or equal than `i`. + fn DOT(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.get_token(DOT, i) + } + fn fieldInitializerList(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } +} + +impl<'input> CreateMessageContextAttrs<'input> for CreateMessageContext<'input> {} + +pub struct CreateMessageContextExt<'input> { + base: PrimaryContextExt<'input>, + pub leadingDot: Option>, + pub IDENTIFIER: Option>, + pub ids: Vec>, + pub s16: Option>, + pub ops: Vec>, + pub op: Option>, + pub entries: Option>>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {CreateMessageContextExt<'a>} + +impl<'input> CELParserContext<'input> for CreateMessageContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for CreateMessageContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_CreateMessage(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_CreateMessage(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for CreateMessageContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_CreateMessage(self); + } +} + +impl<'input> CustomRuleContext<'input> for CreateMessageContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_primary + } + //fn type_rule_index() -> usize where Self: Sized { RULE_primary } +} + +impl<'input> Borrow> for CreateMessageContext<'input> { + fn borrow(&self) -> &PrimaryContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for CreateMessageContext<'input> { + fn borrow_mut(&mut self) -> &mut PrimaryContextExt<'input> { + &mut self.base + } +} + +impl<'input> PrimaryContextAttrs<'input> for CreateMessageContext<'input> {} + +impl<'input> CreateMessageContextExt<'input> { + fn new(ctx: &dyn PrimaryContextAttrs<'input>) -> Rc> { + Rc::new(PrimaryContextAll::CreateMessageContext( + BaseParserRuleContext::copy_from( + ctx, + CreateMessageContextExt { + leadingDot: None, + IDENTIFIER: None, + s16: None, + op: None, + ids: Vec::new(), + ops: Vec::new(), + entries: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type GlobalCallContext<'input> = BaseParserRuleContext<'input, GlobalCallContextExt<'input>>; + +pub trait GlobalCallContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token IDENTIFIER + /// Returns `None` if there is no child corresponding to token IDENTIFIER + fn IDENTIFIER(&self) -> Option>> + where + Self: Sized, + { + self.get_token(IDENTIFIER, 0) + } + /// Retrieves first TerminalNode corresponding to token RPAREN + /// Returns `None` if there is no child corresponding to token RPAREN + fn RPAREN(&self) -> Option>> + where + Self: Sized, + { + self.get_token(RPAREN, 0) + } + /// Retrieves first TerminalNode corresponding to token LPAREN + /// Returns `None` if there is no child corresponding to token LPAREN + fn LPAREN(&self) -> Option>> + where + Self: Sized, + { + self.get_token(LPAREN, 0) + } + /// Retrieves first TerminalNode corresponding to token DOT + /// Returns `None` if there is no child corresponding to token DOT + fn DOT(&self) -> Option>> + where + Self: Sized, + { + self.get_token(DOT, 0) + } + fn exprList(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } +} + +impl<'input> GlobalCallContextAttrs<'input> for GlobalCallContext<'input> {} + +pub struct GlobalCallContextExt<'input> { + base: PrimaryContextExt<'input>, + pub leadingDot: Option>, + pub id: Option>, + pub op: Option>, + pub args: Option>>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {GlobalCallContextExt<'a>} + +impl<'input> CELParserContext<'input> for GlobalCallContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for GlobalCallContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_GlobalCall(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_GlobalCall(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for GlobalCallContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_GlobalCall(self); + } +} + +impl<'input> CustomRuleContext<'input> for GlobalCallContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_primary + } + //fn type_rule_index() -> usize where Self: Sized { RULE_primary } +} + +impl<'input> Borrow> for GlobalCallContext<'input> { + fn borrow(&self) -> &PrimaryContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for GlobalCallContext<'input> { + fn borrow_mut(&mut self) -> &mut PrimaryContextExt<'input> { + &mut self.base + } +} + +impl<'input> PrimaryContextAttrs<'input> for GlobalCallContext<'input> {} + +impl<'input> GlobalCallContextExt<'input> { + fn new(ctx: &dyn PrimaryContextAttrs<'input>) -> Rc> { + Rc::new(PrimaryContextAll::GlobalCallContext( + BaseParserRuleContext::copy_from( + ctx, + GlobalCallContextExt { + leadingDot: None, + id: None, + op: None, + args: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn primary(&mut self) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = PrimaryContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog.base.enter_rule(_localctx.clone(), 16, RULE_primary); + let mut _localctx: Rc = _localctx; + let mut _la: isize = -1; + let result: Result<(), ANTLRError> = (|| { + recog.base.set_state(184); + recog.err_handler.sync(&mut recog.base)?; + match recog.interpreter.adaptive_predict(25, &mut recog.base)? { + 1 => { + let tmp = IdentContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 1); + _localctx = tmp; + { + recog.base.set_state(132); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la == DOT { + { + recog.base.set_state(131); + let tmp = recog.base.match_token(DOT, &mut recog.err_handler)?; + if let PrimaryContextAll::IdentContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.leadingDot = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + recog.base.set_state(134); + let tmp = recog.base.match_token(IDENTIFIER, &mut recog.err_handler)?; + if let PrimaryContextAll::IdentContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.id = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + 2 => { + let tmp = GlobalCallContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 2); + _localctx = tmp; + { + recog.base.set_state(136); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la == DOT { + { + recog.base.set_state(135); + let tmp = recog.base.match_token(DOT, &mut recog.err_handler)?; + if let PrimaryContextAll::GlobalCallContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.leadingDot = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + recog.base.set_state(138); + let tmp = recog.base.match_token(IDENTIFIER, &mut recog.err_handler)?; + if let PrimaryContextAll::GlobalCallContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.id = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + { + recog.base.set_state(139); + let tmp = recog.base.match_token(LPAREN, &mut recog.err_handler)?; + if let PrimaryContextAll::GlobalCallContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.op = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + recog.base.set_state(141); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if ((_la - 10) & !0x3f) == 0 + && ((1usize << (_la - 10)) + & ((1usize << (LBRACKET - 10)) + | (1usize << (LBRACE - 10)) + | (1usize << (LPAREN - 10)) + | (1usize << (DOT - 10)) + | (1usize << (MINUS - 10)) + | (1usize << (EXCLAM - 10)) + | (1usize << (CEL_TRUE - 10)) + | (1usize << (CEL_FALSE - 10)) + | (1usize << (NUL - 10)) + | (1usize << (NUM_FLOAT - 10)) + | (1usize << (NUM_INT - 10)) + | (1usize << (NUM_UINT - 10)) + | (1usize << (STRING - 10)) + | (1usize << (BYTES - 10)) + | (1usize << (IDENTIFIER - 10)))) + != 0 + { + { + /*InvokeRule exprList*/ + recog.base.set_state(140); + let tmp = recog.exprList()?; + if let PrimaryContextAll::GlobalCallContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.args = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + recog.base.set_state(143); + recog.base.match_token(RPAREN, &mut recog.err_handler)?; + } + } + } + 3 => { + let tmp = NestedContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 3); + _localctx = tmp; + { + recog.base.set_state(144); + recog.base.match_token(LPAREN, &mut recog.err_handler)?; + + /*InvokeRule expr*/ + recog.base.set_state(145); + let tmp = recog.expr()?; + if let PrimaryContextAll::NestedContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.e = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + recog.base.set_state(146); + recog.base.match_token(RPAREN, &mut recog.err_handler)?; + } + } + 4 => { + let tmp = CreateListContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 4); + _localctx = tmp; + { + recog.base.set_state(148); + let tmp = recog.base.match_token(LBRACKET, &mut recog.err_handler)?; + if let PrimaryContextAll::CreateListContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.op = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + recog.base.set_state(150); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if ((_la - 10) & !0x3f) == 0 + && ((1usize << (_la - 10)) + & ((1usize << (LBRACKET - 10)) + | (1usize << (LBRACE - 10)) + | (1usize << (LPAREN - 10)) + | (1usize << (DOT - 10)) + | (1usize << (MINUS - 10)) + | (1usize << (EXCLAM - 10)) + | (1usize << (QUESTIONMARK - 10)) + | (1usize << (CEL_TRUE - 10)) + | (1usize << (CEL_FALSE - 10)) + | (1usize << (NUL - 10)) + | (1usize << (NUM_FLOAT - 10)) + | (1usize << (NUM_INT - 10)) + | (1usize << (NUM_UINT - 10)) + | (1usize << (STRING - 10)) + | (1usize << (BYTES - 10)) + | (1usize << (IDENTIFIER - 10)))) + != 0 + { + { + /*InvokeRule listInit*/ + recog.base.set_state(149); + let tmp = recog.listInit()?; + if let PrimaryContextAll::CreateListContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.elems = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + recog.base.set_state(153); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la == COMMA { + { + recog.base.set_state(152); + recog.base.match_token(COMMA, &mut recog.err_handler)?; + } + } + + recog.base.set_state(155); + recog.base.match_token(RPRACKET, &mut recog.err_handler)?; + } + } + 5 => { + let tmp = CreateStructContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 5); + _localctx = tmp; + { + recog.base.set_state(156); + let tmp = recog.base.match_token(LBRACE, &mut recog.err_handler)?; + if let PrimaryContextAll::CreateStructContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.op = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + recog.base.set_state(158); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if ((_la - 10) & !0x3f) == 0 + && ((1usize << (_la - 10)) + & ((1usize << (LBRACKET - 10)) + | (1usize << (LBRACE - 10)) + | (1usize << (LPAREN - 10)) + | (1usize << (DOT - 10)) + | (1usize << (MINUS - 10)) + | (1usize << (EXCLAM - 10)) + | (1usize << (QUESTIONMARK - 10)) + | (1usize << (CEL_TRUE - 10)) + | (1usize << (CEL_FALSE - 10)) + | (1usize << (NUL - 10)) + | (1usize << (NUM_FLOAT - 10)) + | (1usize << (NUM_INT - 10)) + | (1usize << (NUM_UINT - 10)) + | (1usize << (STRING - 10)) + | (1usize << (BYTES - 10)) + | (1usize << (IDENTIFIER - 10)))) + != 0 + { + { + /*InvokeRule mapInitializerList*/ + recog.base.set_state(157); + let tmp = recog.mapInitializerList()?; + if let PrimaryContextAll::CreateStructContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.entries = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + recog.base.set_state(161); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la == COMMA { + { + recog.base.set_state(160); + recog.base.match_token(COMMA, &mut recog.err_handler)?; + } + } + + recog.base.set_state(163); + recog.base.match_token(RBRACE, &mut recog.err_handler)?; + } + } + 6 => { + let tmp = CreateMessageContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 6); + _localctx = tmp; + { + recog.base.set_state(165); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la == DOT { + { + recog.base.set_state(164); + let tmp = recog.base.match_token(DOT, &mut recog.err_handler)?; + if let PrimaryContextAll::CreateMessageContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.leadingDot = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + recog.base.set_state(167); + let tmp = recog.base.match_token(IDENTIFIER, &mut recog.err_handler)?; + if let PrimaryContextAll::CreateMessageContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.IDENTIFIER = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + let temp = if let PrimaryContextAll::CreateMessageContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.IDENTIFIER.clone().unwrap() + } else { + unreachable!("cant cast"); + }; + if let PrimaryContextAll::CreateMessageContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.ids.push(temp); + } else { + unreachable!("cant cast"); + } + recog.base.set_state(172); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + while _la == DOT { + { + { + recog.base.set_state(168); + let tmp = + recog.base.match_token(DOT, &mut recog.err_handler)?; + if let PrimaryContextAll::CreateMessageContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.s16 = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + let temp = if let PrimaryContextAll::CreateMessageContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.s16.clone().unwrap() + } else { + unreachable!("cant cast"); + }; + if let PrimaryContextAll::CreateMessageContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.ops.push(temp); + } else { + unreachable!("cant cast"); + } + recog.base.set_state(169); + let tmp = recog + .base + .match_token(IDENTIFIER, &mut recog.err_handler)?; + if let PrimaryContextAll::CreateMessageContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.IDENTIFIER = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + let temp = if let PrimaryContextAll::CreateMessageContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.IDENTIFIER.clone().unwrap() + } else { + unreachable!("cant cast"); + }; + if let PrimaryContextAll::CreateMessageContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.ids.push(temp); + } else { + unreachable!("cant cast"); + } + } + } + recog.base.set_state(174); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + } + recog.base.set_state(175); + let tmp = recog.base.match_token(LBRACE, &mut recog.err_handler)?; + if let PrimaryContextAll::CreateMessageContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.op = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + + recog.base.set_state(177); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if ((_la - 20) & !0x3f) == 0 + && ((1usize << (_la - 20)) + & ((1usize << (QUESTIONMARK - 20)) + | (1usize << (IDENTIFIER - 20)) + | (1usize << (ESC_IDENTIFIER - 20)))) + != 0 + { + { + /*InvokeRule fieldInitializerList*/ + recog.base.set_state(176); + let tmp = recog.fieldInitializerList()?; + if let PrimaryContextAll::CreateMessageContext(ctx) = + cast_mut::<_, PrimaryContextAll>(&mut _localctx) + { + ctx.entries = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + recog.base.set_state(180); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la == COMMA { + { + recog.base.set_state(179); + recog.base.match_token(COMMA, &mut recog.err_handler)?; + } + } + + recog.base.set_state(182); + recog.base.match_token(RBRACE, &mut recog.err_handler)?; + } + } + 7 => { + let tmp = ConstantLiteralContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 7); + _localctx = tmp; + { + /*InvokeRule literal*/ + recog.base.set_state(183); + recog.literal()?; + } + } + + _ => {} + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} +//------------------- exprList ---------------- +pub type ExprListContextAll<'input> = ExprListContext<'input>; + +pub type ExprListContext<'input> = BaseParserRuleContext<'input, ExprListContextExt<'input>>; + +#[derive(Clone)] +pub struct ExprListContextExt<'input> { + pub expr: Option>>, + pub e: Vec>>, + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for ExprListContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for ExprListContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_exprList(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_exprList(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for ExprListContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_exprList(self); + } +} + +impl<'input> CustomRuleContext<'input> for ExprListContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_exprList + } + //fn type_rule_index() -> usize where Self: Sized { RULE_exprList } +} +antlr4rust::tid! {ExprListContextExt<'a>} + +impl<'input> ExprListContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + ExprListContextExt { + expr: None, + e: Vec::new(), + ph: PhantomData, + }, + )) + } +} + +pub trait ExprListContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ + fn expr_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + fn expr(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.child_of_type(i) + } + /// Retrieves all `TerminalNode`s corresponding to token COMMA in current rule + fn COMMA_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + /// Retrieves 'i's TerminalNode corresponding to token COMMA, starting from 0. + /// Returns `None` if number of children corresponding to token COMMA is less or equal than `i`. + fn COMMA(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.get_token(COMMA, i) + } +} + +impl<'input> ExprListContextAttrs<'input> for ExprListContext<'input> {} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn exprList(&mut self) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = ExprListContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog.base.enter_rule(_localctx.clone(), 18, RULE_exprList); + let mut _localctx: Rc = _localctx; + let mut _la: isize = -1; + let result: Result<(), ANTLRError> = (|| { + //recog.base.enter_outer_alt(_localctx.clone(), 1); + recog.base.enter_outer_alt(None, 1); + { + /*InvokeRule expr*/ + recog.base.set_state(186); + let tmp = recog.expr()?; + cast_mut::<_, ExprListContext>(&mut _localctx).expr = Some(tmp.clone()); + + let temp = cast_mut::<_, ExprListContext>(&mut _localctx) + .expr + .clone() + .unwrap(); + cast_mut::<_, ExprListContext>(&mut _localctx).e.push(temp); + + recog.base.set_state(191); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + while _la == COMMA { + { + { + recog.base.set_state(187); + recog.base.match_token(COMMA, &mut recog.err_handler)?; + + /*InvokeRule expr*/ + recog.base.set_state(188); + let tmp = recog.expr()?; + cast_mut::<_, ExprListContext>(&mut _localctx).expr = Some(tmp.clone()); + + let temp = cast_mut::<_, ExprListContext>(&mut _localctx) + .expr + .clone() + .unwrap(); + cast_mut::<_, ExprListContext>(&mut _localctx).e.push(temp); + } + } + recog.base.set_state(193); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + } + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} +//------------------- listInit ---------------- +pub type ListInitContextAll<'input> = ListInitContext<'input>; + +pub type ListInitContext<'input> = BaseParserRuleContext<'input, ListInitContextExt<'input>>; + +#[derive(Clone)] +pub struct ListInitContextExt<'input> { + pub optExpr: Option>>, + pub elems: Vec>>, + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for ListInitContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for ListInitContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_listInit(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_listInit(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for ListInitContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_listInit(self); + } +} + +impl<'input> CustomRuleContext<'input> for ListInitContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_listInit + } + //fn type_rule_index() -> usize where Self: Sized { RULE_listInit } +} +antlr4rust::tid! {ListInitContextExt<'a>} + +impl<'input> ListInitContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + ListInitContextExt { + optExpr: None, + elems: Vec::new(), + ph: PhantomData, + }, + )) + } +} + +pub trait ListInitContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ + fn optExpr_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + fn optExpr(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.child_of_type(i) + } + /// Retrieves all `TerminalNode`s corresponding to token COMMA in current rule + fn COMMA_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + /// Retrieves 'i's TerminalNode corresponding to token COMMA, starting from 0. + /// Returns `None` if number of children corresponding to token COMMA is less or equal than `i`. + fn COMMA(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.get_token(COMMA, i) + } +} + +impl<'input> ListInitContextAttrs<'input> for ListInitContext<'input> {} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn listInit(&mut self) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = ListInitContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog.base.enter_rule(_localctx.clone(), 20, RULE_listInit); + let mut _localctx: Rc = _localctx; + let result: Result<(), ANTLRError> = (|| { + let mut _alt: isize; + //recog.base.enter_outer_alt(_localctx.clone(), 1); + recog.base.enter_outer_alt(None, 1); + { + /*InvokeRule optExpr*/ + recog.base.set_state(194); + let tmp = recog.optExpr()?; + cast_mut::<_, ListInitContext>(&mut _localctx).optExpr = Some(tmp.clone()); + + let temp = cast_mut::<_, ListInitContext>(&mut _localctx) + .optExpr + .clone() + .unwrap(); + cast_mut::<_, ListInitContext>(&mut _localctx) + .elems + .push(temp); + + recog.base.set_state(199); + recog.err_handler.sync(&mut recog.base)?; + _alt = recog.interpreter.adaptive_predict(27, &mut recog.base)?; + while { _alt != 2 && _alt != INVALID_ALT } { + if _alt == 1 { + { + { + recog.base.set_state(195); + recog.base.match_token(COMMA, &mut recog.err_handler)?; + + /*InvokeRule optExpr*/ + recog.base.set_state(196); + let tmp = recog.optExpr()?; + cast_mut::<_, ListInitContext>(&mut _localctx).optExpr = + Some(tmp.clone()); + + let temp = cast_mut::<_, ListInitContext>(&mut _localctx) + .optExpr + .clone() + .unwrap(); + cast_mut::<_, ListInitContext>(&mut _localctx) + .elems + .push(temp); + } + } + } + recog.base.set_state(201); + recog.err_handler.sync(&mut recog.base)?; + _alt = recog.interpreter.adaptive_predict(27, &mut recog.base)?; + } + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} +//------------------- fieldInitializerList ---------------- +pub type FieldInitializerListContextAll<'input> = FieldInitializerListContext<'input>; + +pub type FieldInitializerListContext<'input> = + BaseParserRuleContext<'input, FieldInitializerListContextExt<'input>>; + +#[derive(Clone)] +pub struct FieldInitializerListContextExt<'input> { + pub optField: Option>>, + pub fields: Vec>>, + pub s21: Option>, + pub cols: Vec>, + pub expr: Option>>, + pub values: Vec>>, + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for FieldInitializerListContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for FieldInitializerListContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_fieldInitializerList(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_fieldInitializerList(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for FieldInitializerListContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_fieldInitializerList(self); + } +} + +impl<'input> CustomRuleContext<'input> for FieldInitializerListContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_fieldInitializerList + } + //fn type_rule_index() -> usize where Self: Sized { RULE_fieldInitializerList } +} +antlr4rust::tid! {FieldInitializerListContextExt<'a>} + +impl<'input> FieldInitializerListContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + FieldInitializerListContextExt { + s21: None, + cols: Vec::new(), + optField: None, + expr: None, + fields: Vec::new(), + values: Vec::new(), + ph: PhantomData, + }, + )) + } +} + +pub trait FieldInitializerListContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ + fn optField_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + fn optField(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.child_of_type(i) + } + /// Retrieves all `TerminalNode`s corresponding to token COLON in current rule + fn COLON_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + /// Retrieves 'i's TerminalNode corresponding to token COLON, starting from 0. + /// Returns `None` if number of children corresponding to token COLON is less or equal than `i`. + fn COLON(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.get_token(COLON, i) + } + fn expr_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + fn expr(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.child_of_type(i) + } + /// Retrieves all `TerminalNode`s corresponding to token COMMA in current rule + fn COMMA_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + /// Retrieves 'i's TerminalNode corresponding to token COMMA, starting from 0. + /// Returns `None` if number of children corresponding to token COMMA is less or equal than `i`. + fn COMMA(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.get_token(COMMA, i) + } +} + +impl<'input> FieldInitializerListContextAttrs<'input> for FieldInitializerListContext<'input> {} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn fieldInitializerList( + &mut self, + ) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = + FieldInitializerListContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog + .base + .enter_rule(_localctx.clone(), 22, RULE_fieldInitializerList); + let mut _localctx: Rc = _localctx; + let result: Result<(), ANTLRError> = (|| { + let mut _alt: isize; + //recog.base.enter_outer_alt(_localctx.clone(), 1); + recog.base.enter_outer_alt(None, 1); + { + /*InvokeRule optField*/ + recog.base.set_state(202); + let tmp = recog.optField()?; + cast_mut::<_, FieldInitializerListContext>(&mut _localctx).optField = + Some(tmp.clone()); + + let temp = cast_mut::<_, FieldInitializerListContext>(&mut _localctx) + .optField + .clone() + .unwrap(); + cast_mut::<_, FieldInitializerListContext>(&mut _localctx) + .fields + .push(temp); + + recog.base.set_state(203); + let tmp = recog.base.match_token(COLON, &mut recog.err_handler)?; + cast_mut::<_, FieldInitializerListContext>(&mut _localctx).s21 = Some(tmp.clone()); + + let temp = cast_mut::<_, FieldInitializerListContext>(&mut _localctx) + .s21 + .clone() + .unwrap(); + cast_mut::<_, FieldInitializerListContext>(&mut _localctx) + .cols + .push(temp); + + /*InvokeRule expr*/ + recog.base.set_state(204); + let tmp = recog.expr()?; + cast_mut::<_, FieldInitializerListContext>(&mut _localctx).expr = Some(tmp.clone()); + + let temp = cast_mut::<_, FieldInitializerListContext>(&mut _localctx) + .expr + .clone() + .unwrap(); + cast_mut::<_, FieldInitializerListContext>(&mut _localctx) + .values + .push(temp); + + recog.base.set_state(212); + recog.err_handler.sync(&mut recog.base)?; + _alt = recog.interpreter.adaptive_predict(28, &mut recog.base)?; + while { _alt != 2 && _alt != INVALID_ALT } { + if _alt == 1 { + { + { + recog.base.set_state(205); + recog.base.match_token(COMMA, &mut recog.err_handler)?; + + /*InvokeRule optField*/ + recog.base.set_state(206); + let tmp = recog.optField()?; + cast_mut::<_, FieldInitializerListContext>(&mut _localctx) + .optField = Some(tmp.clone()); + + let temp = + cast_mut::<_, FieldInitializerListContext>(&mut _localctx) + .optField + .clone() + .unwrap(); + cast_mut::<_, FieldInitializerListContext>(&mut _localctx) + .fields + .push(temp); + + recog.base.set_state(207); + let tmp = recog.base.match_token(COLON, &mut recog.err_handler)?; + cast_mut::<_, FieldInitializerListContext>(&mut _localctx).s21 = + Some(tmp.clone()); + + let temp = + cast_mut::<_, FieldInitializerListContext>(&mut _localctx) + .s21 + .clone() + .unwrap(); + cast_mut::<_, FieldInitializerListContext>(&mut _localctx) + .cols + .push(temp); + + /*InvokeRule expr*/ + recog.base.set_state(208); + let tmp = recog.expr()?; + cast_mut::<_, FieldInitializerListContext>(&mut _localctx).expr = + Some(tmp.clone()); + + let temp = + cast_mut::<_, FieldInitializerListContext>(&mut _localctx) + .expr + .clone() + .unwrap(); + cast_mut::<_, FieldInitializerListContext>(&mut _localctx) + .values + .push(temp); + } + } + } + recog.base.set_state(214); + recog.err_handler.sync(&mut recog.base)?; + _alt = recog.interpreter.adaptive_predict(28, &mut recog.base)?; + } + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} +//------------------- optField ---------------- +pub type OptFieldContextAll<'input> = OptFieldContext<'input>; + +pub type OptFieldContext<'input> = BaseParserRuleContext<'input, OptFieldContextExt<'input>>; + +#[derive(Clone)] +pub struct OptFieldContextExt<'input> { + pub opt: Option>, + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for OptFieldContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for OptFieldContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_optField(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_optField(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for OptFieldContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_optField(self); + } +} + +impl<'input> CustomRuleContext<'input> for OptFieldContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_optField + } + //fn type_rule_index() -> usize where Self: Sized { RULE_optField } +} +antlr4rust::tid! {OptFieldContextExt<'a>} + +impl<'input> OptFieldContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + OptFieldContextExt { + opt: None, + ph: PhantomData, + }, + )) + } +} + +pub trait OptFieldContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ + fn escapeIdent(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } + /// Retrieves first TerminalNode corresponding to token QUESTIONMARK + /// Returns `None` if there is no child corresponding to token QUESTIONMARK + fn QUESTIONMARK(&self) -> Option>> + where + Self: Sized, + { + self.get_token(QUESTIONMARK, 0) + } +} + +impl<'input> OptFieldContextAttrs<'input> for OptFieldContext<'input> {} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn optField(&mut self) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = OptFieldContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog.base.enter_rule(_localctx.clone(), 24, RULE_optField); + let mut _localctx: Rc = _localctx; + let mut _la: isize = -1; + let result: Result<(), ANTLRError> = (|| { + //recog.base.enter_outer_alt(_localctx.clone(), 1); + recog.base.enter_outer_alt(None, 1); + { + recog.base.set_state(216); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la == QUESTIONMARK { + { + recog.base.set_state(215); + let tmp = recog + .base + .match_token(QUESTIONMARK, &mut recog.err_handler)?; + cast_mut::<_, OptFieldContext>(&mut _localctx).opt = Some(tmp.clone()); + } + } + + /*InvokeRule escapeIdent*/ + recog.base.set_state(218); + recog.escapeIdent()?; + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} +//------------------- mapInitializerList ---------------- +pub type MapInitializerListContextAll<'input> = MapInitializerListContext<'input>; + +pub type MapInitializerListContext<'input> = + BaseParserRuleContext<'input, MapInitializerListContextExt<'input>>; + +#[derive(Clone)] +pub struct MapInitializerListContextExt<'input> { + pub optExpr: Option>>, + pub keys: Vec>>, + pub s21: Option>, + pub cols: Vec>, + pub expr: Option>>, + pub values: Vec>>, + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for MapInitializerListContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for MapInitializerListContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_mapInitializerList(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_mapInitializerList(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for MapInitializerListContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_mapInitializerList(self); + } +} + +impl<'input> CustomRuleContext<'input> for MapInitializerListContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_mapInitializerList + } + //fn type_rule_index() -> usize where Self: Sized { RULE_mapInitializerList } +} +antlr4rust::tid! {MapInitializerListContextExt<'a>} + +impl<'input> MapInitializerListContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + MapInitializerListContextExt { + s21: None, + cols: Vec::new(), + optExpr: None, + expr: None, + keys: Vec::new(), + values: Vec::new(), + ph: PhantomData, + }, + )) + } +} + +pub trait MapInitializerListContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ + fn optExpr_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + fn optExpr(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.child_of_type(i) + } + /// Retrieves all `TerminalNode`s corresponding to token COLON in current rule + fn COLON_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + /// Retrieves 'i's TerminalNode corresponding to token COLON, starting from 0. + /// Returns `None` if number of children corresponding to token COLON is less or equal than `i`. + fn COLON(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.get_token(COLON, i) + } + fn expr_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + fn expr(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.child_of_type(i) + } + /// Retrieves all `TerminalNode`s corresponding to token COMMA in current rule + fn COMMA_all(&self) -> Vec>> + where + Self: Sized, + { + self.children_of_type() + } + /// Retrieves 'i's TerminalNode corresponding to token COMMA, starting from 0. + /// Returns `None` if number of children corresponding to token COMMA is less or equal than `i`. + fn COMMA(&self, i: usize) -> Option>> + where + Self: Sized, + { + self.get_token(COMMA, i) + } +} + +impl<'input> MapInitializerListContextAttrs<'input> for MapInitializerListContext<'input> {} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn mapInitializerList( + &mut self, + ) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = + MapInitializerListContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog + .base + .enter_rule(_localctx.clone(), 26, RULE_mapInitializerList); + let mut _localctx: Rc = _localctx; + let result: Result<(), ANTLRError> = (|| { + let mut _alt: isize; + //recog.base.enter_outer_alt(_localctx.clone(), 1); + recog.base.enter_outer_alt(None, 1); + { + /*InvokeRule optExpr*/ + recog.base.set_state(220); + let tmp = recog.optExpr()?; + cast_mut::<_, MapInitializerListContext>(&mut _localctx).optExpr = + Some(tmp.clone()); + + let temp = cast_mut::<_, MapInitializerListContext>(&mut _localctx) + .optExpr + .clone() + .unwrap(); + cast_mut::<_, MapInitializerListContext>(&mut _localctx) + .keys + .push(temp); + + recog.base.set_state(221); + let tmp = recog.base.match_token(COLON, &mut recog.err_handler)?; + cast_mut::<_, MapInitializerListContext>(&mut _localctx).s21 = Some(tmp.clone()); + + let temp = cast_mut::<_, MapInitializerListContext>(&mut _localctx) + .s21 + .clone() + .unwrap(); + cast_mut::<_, MapInitializerListContext>(&mut _localctx) + .cols + .push(temp); + + /*InvokeRule expr*/ + recog.base.set_state(222); + let tmp = recog.expr()?; + cast_mut::<_, MapInitializerListContext>(&mut _localctx).expr = Some(tmp.clone()); + + let temp = cast_mut::<_, MapInitializerListContext>(&mut _localctx) + .expr + .clone() + .unwrap(); + cast_mut::<_, MapInitializerListContext>(&mut _localctx) + .values + .push(temp); + + recog.base.set_state(230); + recog.err_handler.sync(&mut recog.base)?; + _alt = recog.interpreter.adaptive_predict(30, &mut recog.base)?; + while { _alt != 2 && _alt != INVALID_ALT } { + if _alt == 1 { + { + { + recog.base.set_state(223); + recog.base.match_token(COMMA, &mut recog.err_handler)?; + + /*InvokeRule optExpr*/ + recog.base.set_state(224); + let tmp = recog.optExpr()?; + cast_mut::<_, MapInitializerListContext>(&mut _localctx).optExpr = + Some(tmp.clone()); + + let temp = cast_mut::<_, MapInitializerListContext>(&mut _localctx) + .optExpr + .clone() + .unwrap(); + cast_mut::<_, MapInitializerListContext>(&mut _localctx) + .keys + .push(temp); + + recog.base.set_state(225); + let tmp = recog.base.match_token(COLON, &mut recog.err_handler)?; + cast_mut::<_, MapInitializerListContext>(&mut _localctx).s21 = + Some(tmp.clone()); + + let temp = cast_mut::<_, MapInitializerListContext>(&mut _localctx) + .s21 + .clone() + .unwrap(); + cast_mut::<_, MapInitializerListContext>(&mut _localctx) + .cols + .push(temp); + + /*InvokeRule expr*/ + recog.base.set_state(226); + let tmp = recog.expr()?; + cast_mut::<_, MapInitializerListContext>(&mut _localctx).expr = + Some(tmp.clone()); + + let temp = cast_mut::<_, MapInitializerListContext>(&mut _localctx) + .expr + .clone() + .unwrap(); + cast_mut::<_, MapInitializerListContext>(&mut _localctx) + .values + .push(temp); + } + } + } + recog.base.set_state(232); + recog.err_handler.sync(&mut recog.base)?; + _alt = recog.interpreter.adaptive_predict(30, &mut recog.base)?; + } + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} +//------------------- escapeIdent ---------------- +#[derive(Debug)] +pub enum EscapeIdentContextAll<'input> { + EscapedIdentifierContext(EscapedIdentifierContext<'input>), + SimpleIdentifierContext(SimpleIdentifierContext<'input>), + Error(EscapeIdentContext<'input>), +} +antlr4rust::tid! {EscapeIdentContextAll<'a>} + +impl<'input> antlr4rust::parser_rule_context::DerefSeal for EscapeIdentContextAll<'input> {} + +impl<'input> CELParserContext<'input> for EscapeIdentContextAll<'input> {} + +impl<'input> Deref for EscapeIdentContextAll<'input> { + type Target = dyn EscapeIdentContextAttrs<'input> + 'input; + fn deref(&self) -> &Self::Target { + use EscapeIdentContextAll::*; + match self { + EscapedIdentifierContext(inner) => inner, + SimpleIdentifierContext(inner) => inner, + Error(inner) => inner, + } + } +} +impl<'input, 'a> Visitable + 'a> for EscapeIdentContextAll<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + if !matches!(self, EscapeIdentContextAll::Error(_)) { + self.deref().accept(visitor) + } + } +} +impl<'input, 'a> Listenable + 'a> for EscapeIdentContextAll<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + self.deref().enter(listener) + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + self.deref().exit(listener) + } +} + +pub type EscapeIdentContext<'input> = BaseParserRuleContext<'input, EscapeIdentContextExt<'input>>; + +#[derive(Clone)] +pub struct EscapeIdentContextExt<'input> { + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for EscapeIdentContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for EscapeIdentContext<'input> {} + +impl<'input, 'a> Visitable + 'a> for EscapeIdentContext<'input> {} + +impl<'input> CustomRuleContext<'input> for EscapeIdentContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_escapeIdent + } + //fn type_rule_index() -> usize where Self: Sized { RULE_escapeIdent } +} +antlr4rust::tid! {EscapeIdentContextExt<'a>} + +impl<'input> EscapeIdentContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(EscapeIdentContextAll::Error( + BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + EscapeIdentContextExt { ph: PhantomData }, + ), + )) + } +} + +pub trait EscapeIdentContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ +} + +impl<'input> EscapeIdentContextAttrs<'input> for EscapeIdentContext<'input> {} + +pub type EscapedIdentifierContext<'input> = + BaseParserRuleContext<'input, EscapedIdentifierContextExt<'input>>; + +pub trait EscapedIdentifierContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token ESC_IDENTIFIER + /// Returns `None` if there is no child corresponding to token ESC_IDENTIFIER + fn ESC_IDENTIFIER(&self) -> Option>> + where + Self: Sized, + { + self.get_token(ESC_IDENTIFIER, 0) + } +} + +impl<'input> EscapedIdentifierContextAttrs<'input> for EscapedIdentifierContext<'input> {} + +pub struct EscapedIdentifierContextExt<'input> { + base: EscapeIdentContextExt<'input>, + pub id: Option>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {EscapedIdentifierContextExt<'a>} + +impl<'input> CELParserContext<'input> for EscapedIdentifierContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for EscapedIdentifierContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_EscapedIdentifier(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_EscapedIdentifier(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for EscapedIdentifierContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_EscapedIdentifier(self); + } +} + +impl<'input> CustomRuleContext<'input> for EscapedIdentifierContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_escapeIdent + } + //fn type_rule_index() -> usize where Self: Sized { RULE_escapeIdent } +} + +impl<'input> Borrow> for EscapedIdentifierContext<'input> { + fn borrow(&self) -> &EscapeIdentContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for EscapedIdentifierContext<'input> { + fn borrow_mut(&mut self) -> &mut EscapeIdentContextExt<'input> { + &mut self.base + } +} + +impl<'input> EscapeIdentContextAttrs<'input> for EscapedIdentifierContext<'input> {} + +impl<'input> EscapedIdentifierContextExt<'input> { + fn new(ctx: &dyn EscapeIdentContextAttrs<'input>) -> Rc> { + Rc::new(EscapeIdentContextAll::EscapedIdentifierContext( + BaseParserRuleContext::copy_from( + ctx, + EscapedIdentifierContextExt { + id: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type SimpleIdentifierContext<'input> = + BaseParserRuleContext<'input, SimpleIdentifierContextExt<'input>>; + +pub trait SimpleIdentifierContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token IDENTIFIER + /// Returns `None` if there is no child corresponding to token IDENTIFIER + fn IDENTIFIER(&self) -> Option>> + where + Self: Sized, + { + self.get_token(IDENTIFIER, 0) + } +} + +impl<'input> SimpleIdentifierContextAttrs<'input> for SimpleIdentifierContext<'input> {} + +pub struct SimpleIdentifierContextExt<'input> { + base: EscapeIdentContextExt<'input>, + pub id: Option>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {SimpleIdentifierContextExt<'a>} + +impl<'input> CELParserContext<'input> for SimpleIdentifierContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for SimpleIdentifierContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_SimpleIdentifier(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_SimpleIdentifier(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for SimpleIdentifierContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_SimpleIdentifier(self); + } +} + +impl<'input> CustomRuleContext<'input> for SimpleIdentifierContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_escapeIdent + } + //fn type_rule_index() -> usize where Self: Sized { RULE_escapeIdent } +} + +impl<'input> Borrow> for SimpleIdentifierContext<'input> { + fn borrow(&self) -> &EscapeIdentContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for SimpleIdentifierContext<'input> { + fn borrow_mut(&mut self) -> &mut EscapeIdentContextExt<'input> { + &mut self.base + } +} + +impl<'input> EscapeIdentContextAttrs<'input> for SimpleIdentifierContext<'input> {} + +impl<'input> SimpleIdentifierContextExt<'input> { + fn new(ctx: &dyn EscapeIdentContextAttrs<'input>) -> Rc> { + Rc::new(EscapeIdentContextAll::SimpleIdentifierContext( + BaseParserRuleContext::copy_from( + ctx, + SimpleIdentifierContextExt { + id: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn escapeIdent(&mut self) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = EscapeIdentContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog + .base + .enter_rule(_localctx.clone(), 28, RULE_escapeIdent); + let mut _localctx: Rc = _localctx; + let result: Result<(), ANTLRError> = (|| { + recog.base.set_state(235); + recog.err_handler.sync(&mut recog.base)?; + match recog.base.input.la(1) { + IDENTIFIER => { + let tmp = SimpleIdentifierContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 1); + _localctx = tmp; + { + recog.base.set_state(233); + let tmp = recog.base.match_token(IDENTIFIER, &mut recog.err_handler)?; + if let EscapeIdentContextAll::SimpleIdentifierContext(ctx) = + cast_mut::<_, EscapeIdentContextAll>(&mut _localctx) + { + ctx.id = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + ESC_IDENTIFIER => { + let tmp = EscapedIdentifierContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 2); + _localctx = tmp; + { + recog.base.set_state(234); + let tmp = recog + .base + .match_token(ESC_IDENTIFIER, &mut recog.err_handler)?; + if let EscapeIdentContextAll::EscapedIdentifierContext(ctx) = + cast_mut::<_, EscapeIdentContextAll>(&mut _localctx) + { + ctx.id = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + _ => Err(ANTLRError::NoAltError(NoViableAltError::new( + &mut recog.base, + )))?, + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} +//------------------- optExpr ---------------- +pub type OptExprContextAll<'input> = OptExprContext<'input>; + +pub type OptExprContext<'input> = BaseParserRuleContext<'input, OptExprContextExt<'input>>; + +#[derive(Clone)] +pub struct OptExprContextExt<'input> { + pub opt: Option>, + pub e: Option>>, + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for OptExprContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for OptExprContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_optExpr(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_optExpr(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for OptExprContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_optExpr(self); + } +} + +impl<'input> CustomRuleContext<'input> for OptExprContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_optExpr + } + //fn type_rule_index() -> usize where Self: Sized { RULE_optExpr } +} +antlr4rust::tid! {OptExprContextExt<'a>} + +impl<'input> OptExprContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + OptExprContextExt { + opt: None, + e: None, + ph: PhantomData, + }, + )) + } +} + +pub trait OptExprContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ + fn expr(&self) -> Option>> + where + Self: Sized, + { + self.child_of_type(0) + } + /// Retrieves first TerminalNode corresponding to token QUESTIONMARK + /// Returns `None` if there is no child corresponding to token QUESTIONMARK + fn QUESTIONMARK(&self) -> Option>> + where + Self: Sized, + { + self.get_token(QUESTIONMARK, 0) + } +} + +impl<'input> OptExprContextAttrs<'input> for OptExprContext<'input> {} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn optExpr(&mut self) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = OptExprContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog.base.enter_rule(_localctx.clone(), 30, RULE_optExpr); + let mut _localctx: Rc = _localctx; + let mut _la: isize = -1; + let result: Result<(), ANTLRError> = (|| { + //recog.base.enter_outer_alt(_localctx.clone(), 1); + recog.base.enter_outer_alt(None, 1); + { + recog.base.set_state(238); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la == QUESTIONMARK { + { + recog.base.set_state(237); + let tmp = recog + .base + .match_token(QUESTIONMARK, &mut recog.err_handler)?; + cast_mut::<_, OptExprContext>(&mut _localctx).opt = Some(tmp.clone()); + } + } + + /*InvokeRule expr*/ + recog.base.set_state(240); + let tmp = recog.expr()?; + cast_mut::<_, OptExprContext>(&mut _localctx).e = Some(tmp.clone()); + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} +//------------------- literal ---------------- +#[derive(Debug)] +pub enum LiteralContextAll<'input> { + BytesContext(BytesContext<'input>), + UintContext(UintContext<'input>), + NullContext(NullContext<'input>), + BoolFalseContext(BoolFalseContext<'input>), + StringContext(StringContext<'input>), + DoubleContext(DoubleContext<'input>), + BoolTrueContext(BoolTrueContext<'input>), + IntContext(IntContext<'input>), + Error(LiteralContext<'input>), +} +antlr4rust::tid! {LiteralContextAll<'a>} + +impl<'input> antlr4rust::parser_rule_context::DerefSeal for LiteralContextAll<'input> {} + +impl<'input> CELParserContext<'input> for LiteralContextAll<'input> {} + +impl<'input> Deref for LiteralContextAll<'input> { + type Target = dyn LiteralContextAttrs<'input> + 'input; + fn deref(&self) -> &Self::Target { + use LiteralContextAll::*; + match self { + BytesContext(inner) => inner, + UintContext(inner) => inner, + NullContext(inner) => inner, + BoolFalseContext(inner) => inner, + StringContext(inner) => inner, + DoubleContext(inner) => inner, + BoolTrueContext(inner) => inner, + IntContext(inner) => inner, + Error(inner) => inner, + } + } +} +impl<'input, 'a> Visitable + 'a> for LiteralContextAll<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + if !matches!(self, LiteralContextAll::Error(_)) { + self.deref().accept(visitor) + } + } +} +impl<'input, 'a> Listenable + 'a> for LiteralContextAll<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + self.deref().enter(listener) + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + self.deref().exit(listener) + } +} + +pub type LiteralContext<'input> = BaseParserRuleContext<'input, LiteralContextExt<'input>>; + +#[derive(Clone)] +pub struct LiteralContextExt<'input> { + ph: PhantomData<&'input str>, +} + +impl<'input> CELParserContext<'input> for LiteralContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for LiteralContext<'input> {} + +impl<'input, 'a> Visitable + 'a> for LiteralContext<'input> {} + +impl<'input> CustomRuleContext<'input> for LiteralContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_literal + } + //fn type_rule_index() -> usize where Self: Sized { RULE_literal } +} +antlr4rust::tid! {LiteralContextExt<'a>} + +impl<'input> LiteralContextExt<'input> { + fn new( + parent: Option + 'input>>, + invoking_state: isize, + ) -> Rc> { + Rc::new(LiteralContextAll::Error( + BaseParserRuleContext::new_parser_ctx( + parent, + invoking_state, + LiteralContextExt { ph: PhantomData }, + ), + )) + } +} + +pub trait LiteralContextAttrs<'input>: + CELParserContext<'input> + BorrowMut> +{ +} + +impl<'input> LiteralContextAttrs<'input> for LiteralContext<'input> {} + +pub type BytesContext<'input> = BaseParserRuleContext<'input, BytesContextExt<'input>>; + +pub trait BytesContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token BYTES + /// Returns `None` if there is no child corresponding to token BYTES + fn BYTES(&self) -> Option>> + where + Self: Sized, + { + self.get_token(BYTES, 0) + } +} + +impl<'input> BytesContextAttrs<'input> for BytesContext<'input> {} + +pub struct BytesContextExt<'input> { + base: LiteralContextExt<'input>, + pub tok: Option>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {BytesContextExt<'a>} + +impl<'input> CELParserContext<'input> for BytesContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for BytesContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_Bytes(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_Bytes(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for BytesContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_Bytes(self); + } +} + +impl<'input> CustomRuleContext<'input> for BytesContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_literal + } + //fn type_rule_index() -> usize where Self: Sized { RULE_literal } +} + +impl<'input> Borrow> for BytesContext<'input> { + fn borrow(&self) -> &LiteralContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for BytesContext<'input> { + fn borrow_mut(&mut self) -> &mut LiteralContextExt<'input> { + &mut self.base + } +} + +impl<'input> LiteralContextAttrs<'input> for BytesContext<'input> {} + +impl<'input> BytesContextExt<'input> { + fn new(ctx: &dyn LiteralContextAttrs<'input>) -> Rc> { + Rc::new(LiteralContextAll::BytesContext( + BaseParserRuleContext::copy_from( + ctx, + BytesContextExt { + tok: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type UintContext<'input> = BaseParserRuleContext<'input, UintContextExt<'input>>; + +pub trait UintContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token NUM_UINT + /// Returns `None` if there is no child corresponding to token NUM_UINT + fn NUM_UINT(&self) -> Option>> + where + Self: Sized, + { + self.get_token(NUM_UINT, 0) + } +} + +impl<'input> UintContextAttrs<'input> for UintContext<'input> {} + +pub struct UintContextExt<'input> { + base: LiteralContextExt<'input>, + pub tok: Option>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {UintContextExt<'a>} + +impl<'input> CELParserContext<'input> for UintContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for UintContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_Uint(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_Uint(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for UintContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_Uint(self); + } +} + +impl<'input> CustomRuleContext<'input> for UintContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_literal + } + //fn type_rule_index() -> usize where Self: Sized { RULE_literal } +} + +impl<'input> Borrow> for UintContext<'input> { + fn borrow(&self) -> &LiteralContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for UintContext<'input> { + fn borrow_mut(&mut self) -> &mut LiteralContextExt<'input> { + &mut self.base + } +} + +impl<'input> LiteralContextAttrs<'input> for UintContext<'input> {} + +impl<'input> UintContextExt<'input> { + fn new(ctx: &dyn LiteralContextAttrs<'input>) -> Rc> { + Rc::new(LiteralContextAll::UintContext( + BaseParserRuleContext::copy_from( + ctx, + UintContextExt { + tok: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type NullContext<'input> = BaseParserRuleContext<'input, NullContextExt<'input>>; + +pub trait NullContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token NUL + /// Returns `None` if there is no child corresponding to token NUL + fn NUL(&self) -> Option>> + where + Self: Sized, + { + self.get_token(NUL, 0) + } +} + +impl<'input> NullContextAttrs<'input> for NullContext<'input> {} + +pub struct NullContextExt<'input> { + base: LiteralContextExt<'input>, + pub tok: Option>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {NullContextExt<'a>} + +impl<'input> CELParserContext<'input> for NullContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for NullContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_Null(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_Null(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for NullContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_Null(self); + } +} + +impl<'input> CustomRuleContext<'input> for NullContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_literal + } + //fn type_rule_index() -> usize where Self: Sized { RULE_literal } +} + +impl<'input> Borrow> for NullContext<'input> { + fn borrow(&self) -> &LiteralContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for NullContext<'input> { + fn borrow_mut(&mut self) -> &mut LiteralContextExt<'input> { + &mut self.base + } +} + +impl<'input> LiteralContextAttrs<'input> for NullContext<'input> {} + +impl<'input> NullContextExt<'input> { + fn new(ctx: &dyn LiteralContextAttrs<'input>) -> Rc> { + Rc::new(LiteralContextAll::NullContext( + BaseParserRuleContext::copy_from( + ctx, + NullContextExt { + tok: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type BoolFalseContext<'input> = BaseParserRuleContext<'input, BoolFalseContextExt<'input>>; + +pub trait BoolFalseContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token CEL_FALSE + /// Returns `None` if there is no child corresponding to token CEL_FALSE + fn CEL_FALSE(&self) -> Option>> + where + Self: Sized, + { + self.get_token(CEL_FALSE, 0) + } +} + +impl<'input> BoolFalseContextAttrs<'input> for BoolFalseContext<'input> {} + +pub struct BoolFalseContextExt<'input> { + base: LiteralContextExt<'input>, + pub tok: Option>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {BoolFalseContextExt<'a>} + +impl<'input> CELParserContext<'input> for BoolFalseContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for BoolFalseContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_BoolFalse(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_BoolFalse(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for BoolFalseContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_BoolFalse(self); + } +} + +impl<'input> CustomRuleContext<'input> for BoolFalseContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_literal + } + //fn type_rule_index() -> usize where Self: Sized { RULE_literal } +} + +impl<'input> Borrow> for BoolFalseContext<'input> { + fn borrow(&self) -> &LiteralContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for BoolFalseContext<'input> { + fn borrow_mut(&mut self) -> &mut LiteralContextExt<'input> { + &mut self.base + } +} + +impl<'input> LiteralContextAttrs<'input> for BoolFalseContext<'input> {} + +impl<'input> BoolFalseContextExt<'input> { + fn new(ctx: &dyn LiteralContextAttrs<'input>) -> Rc> { + Rc::new(LiteralContextAll::BoolFalseContext( + BaseParserRuleContext::copy_from( + ctx, + BoolFalseContextExt { + tok: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type StringContext<'input> = BaseParserRuleContext<'input, StringContextExt<'input>>; + +pub trait StringContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token STRING + /// Returns `None` if there is no child corresponding to token STRING + fn STRING(&self) -> Option>> + where + Self: Sized, + { + self.get_token(STRING, 0) + } +} + +impl<'input> StringContextAttrs<'input> for StringContext<'input> {} + +pub struct StringContextExt<'input> { + base: LiteralContextExt<'input>, + pub tok: Option>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {StringContextExt<'a>} + +impl<'input> CELParserContext<'input> for StringContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for StringContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_String(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_String(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for StringContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_String(self); + } +} + +impl<'input> CustomRuleContext<'input> for StringContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_literal + } + //fn type_rule_index() -> usize where Self: Sized { RULE_literal } +} + +impl<'input> Borrow> for StringContext<'input> { + fn borrow(&self) -> &LiteralContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for StringContext<'input> { + fn borrow_mut(&mut self) -> &mut LiteralContextExt<'input> { + &mut self.base + } +} + +impl<'input> LiteralContextAttrs<'input> for StringContext<'input> {} + +impl<'input> StringContextExt<'input> { + fn new(ctx: &dyn LiteralContextAttrs<'input>) -> Rc> { + Rc::new(LiteralContextAll::StringContext( + BaseParserRuleContext::copy_from( + ctx, + StringContextExt { + tok: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type DoubleContext<'input> = BaseParserRuleContext<'input, DoubleContextExt<'input>>; + +pub trait DoubleContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token NUM_FLOAT + /// Returns `None` if there is no child corresponding to token NUM_FLOAT + fn NUM_FLOAT(&self) -> Option>> + where + Self: Sized, + { + self.get_token(NUM_FLOAT, 0) + } + /// Retrieves first TerminalNode corresponding to token MINUS + /// Returns `None` if there is no child corresponding to token MINUS + fn MINUS(&self) -> Option>> + where + Self: Sized, + { + self.get_token(MINUS, 0) + } +} + +impl<'input> DoubleContextAttrs<'input> for DoubleContext<'input> {} + +pub struct DoubleContextExt<'input> { + base: LiteralContextExt<'input>, + pub sign: Option>, + pub tok: Option>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {DoubleContextExt<'a>} + +impl<'input> CELParserContext<'input> for DoubleContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for DoubleContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_Double(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_Double(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for DoubleContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_Double(self); + } +} + +impl<'input> CustomRuleContext<'input> for DoubleContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_literal + } + //fn type_rule_index() -> usize where Self: Sized { RULE_literal } +} + +impl<'input> Borrow> for DoubleContext<'input> { + fn borrow(&self) -> &LiteralContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for DoubleContext<'input> { + fn borrow_mut(&mut self) -> &mut LiteralContextExt<'input> { + &mut self.base + } +} + +impl<'input> LiteralContextAttrs<'input> for DoubleContext<'input> {} + +impl<'input> DoubleContextExt<'input> { + fn new(ctx: &dyn LiteralContextAttrs<'input>) -> Rc> { + Rc::new(LiteralContextAll::DoubleContext( + BaseParserRuleContext::copy_from( + ctx, + DoubleContextExt { + sign: None, + tok: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type BoolTrueContext<'input> = BaseParserRuleContext<'input, BoolTrueContextExt<'input>>; + +pub trait BoolTrueContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token CEL_TRUE + /// Returns `None` if there is no child corresponding to token CEL_TRUE + fn CEL_TRUE(&self) -> Option>> + where + Self: Sized, + { + self.get_token(CEL_TRUE, 0) + } +} + +impl<'input> BoolTrueContextAttrs<'input> for BoolTrueContext<'input> {} + +pub struct BoolTrueContextExt<'input> { + base: LiteralContextExt<'input>, + pub tok: Option>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {BoolTrueContextExt<'a>} + +impl<'input> CELParserContext<'input> for BoolTrueContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for BoolTrueContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_BoolTrue(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_BoolTrue(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for BoolTrueContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_BoolTrue(self); + } +} + +impl<'input> CustomRuleContext<'input> for BoolTrueContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_literal + } + //fn type_rule_index() -> usize where Self: Sized { RULE_literal } +} + +impl<'input> Borrow> for BoolTrueContext<'input> { + fn borrow(&self) -> &LiteralContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for BoolTrueContext<'input> { + fn borrow_mut(&mut self) -> &mut LiteralContextExt<'input> { + &mut self.base + } +} + +impl<'input> LiteralContextAttrs<'input> for BoolTrueContext<'input> {} + +impl<'input> BoolTrueContextExt<'input> { + fn new(ctx: &dyn LiteralContextAttrs<'input>) -> Rc> { + Rc::new(LiteralContextAll::BoolTrueContext( + BaseParserRuleContext::copy_from( + ctx, + BoolTrueContextExt { + tok: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +pub type IntContext<'input> = BaseParserRuleContext<'input, IntContextExt<'input>>; + +pub trait IntContextAttrs<'input>: CELParserContext<'input> { + /// Retrieves first TerminalNode corresponding to token NUM_INT + /// Returns `None` if there is no child corresponding to token NUM_INT + fn NUM_INT(&self) -> Option>> + where + Self: Sized, + { + self.get_token(NUM_INT, 0) + } + /// Retrieves first TerminalNode corresponding to token MINUS + /// Returns `None` if there is no child corresponding to token MINUS + fn MINUS(&self) -> Option>> + where + Self: Sized, + { + self.get_token(MINUS, 0) + } +} + +impl<'input> IntContextAttrs<'input> for IntContext<'input> {} + +pub struct IntContextExt<'input> { + base: LiteralContextExt<'input>, + pub sign: Option>, + pub tok: Option>, + ph: PhantomData<&'input str>, +} + +antlr4rust::tid! {IntContextExt<'a>} + +impl<'input> CELParserContext<'input> for IntContext<'input> {} + +impl<'input, 'a> Listenable + 'a> for IntContext<'input> { + fn enter(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.enter_every_rule(self); + listener.enter_Int(self); + } + fn exit(&self, listener: &mut (dyn CELListener<'input> + 'a)) { + listener.exit_Int(self); + listener.exit_every_rule(self); + } +} + +impl<'input, 'a> Visitable + 'a> for IntContext<'input> { + fn accept(&self, visitor: &mut (dyn CELVisitor<'input> + 'a)) { + visitor.visit_Int(self); + } +} + +impl<'input> CustomRuleContext<'input> for IntContextExt<'input> { + type TF = LocalTokenFactory<'input>; + type Ctx = CELParserContextType; + fn get_rule_index(&self) -> usize { + RULE_literal + } + //fn type_rule_index() -> usize where Self: Sized { RULE_literal } +} + +impl<'input> Borrow> for IntContext<'input> { + fn borrow(&self) -> &LiteralContextExt<'input> { + &self.base + } +} +impl<'input> BorrowMut> for IntContext<'input> { + fn borrow_mut(&mut self) -> &mut LiteralContextExt<'input> { + &mut self.base + } +} + +impl<'input> LiteralContextAttrs<'input> for IntContext<'input> {} + +impl<'input> IntContextExt<'input> { + fn new(ctx: &dyn LiteralContextAttrs<'input>) -> Rc> { + Rc::new(LiteralContextAll::IntContext( + BaseParserRuleContext::copy_from( + ctx, + IntContextExt { + sign: None, + tok: None, + base: ctx.borrow().clone(), + ph: PhantomData, + }, + ), + )) + } +} + +impl<'input, I, H> CELParser<'input, I, H> +where + I: TokenStream<'input, TF = LocalTokenFactory<'input>> + TidAble<'input>, + H: ErrorStrategy<'input, BaseParserType<'input, I>>, +{ + pub fn literal(&mut self) -> Result>, ANTLRError> { + let mut recog = self; + let _parentctx = recog.ctx.take(); + let mut _localctx = LiteralContextExt::new(_parentctx.clone(), recog.base.get_state()); + recog.base.enter_rule(_localctx.clone(), 32, RULE_literal); + let mut _localctx: Rc = _localctx; + let mut _la: isize = -1; + let result: Result<(), ANTLRError> = (|| { + recog.base.set_state(256); + recog.err_handler.sync(&mut recog.base)?; + match recog.interpreter.adaptive_predict(35, &mut recog.base)? { + 1 => { + let tmp = IntContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 1); + _localctx = tmp; + { + recog.base.set_state(243); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la == MINUS { + { + recog.base.set_state(242); + let tmp = recog.base.match_token(MINUS, &mut recog.err_handler)?; + if let LiteralContextAll::IntContext(ctx) = + cast_mut::<_, LiteralContextAll>(&mut _localctx) + { + ctx.sign = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + recog.base.set_state(245); + let tmp = recog.base.match_token(NUM_INT, &mut recog.err_handler)?; + if let LiteralContextAll::IntContext(ctx) = + cast_mut::<_, LiteralContextAll>(&mut _localctx) + { + ctx.tok = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + 2 => { + let tmp = UintContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 2); + _localctx = tmp; + { + recog.base.set_state(246); + let tmp = recog.base.match_token(NUM_UINT, &mut recog.err_handler)?; + if let LiteralContextAll::UintContext(ctx) = + cast_mut::<_, LiteralContextAll>(&mut _localctx) + { + ctx.tok = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + 3 => { + let tmp = DoubleContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 3); + _localctx = tmp; + { + recog.base.set_state(248); + recog.err_handler.sync(&mut recog.base)?; + _la = recog.base.input.la(1); + if _la == MINUS { + { + recog.base.set_state(247); + let tmp = recog.base.match_token(MINUS, &mut recog.err_handler)?; + if let LiteralContextAll::DoubleContext(ctx) = + cast_mut::<_, LiteralContextAll>(&mut _localctx) + { + ctx.sign = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + recog.base.set_state(250); + let tmp = recog.base.match_token(NUM_FLOAT, &mut recog.err_handler)?; + if let LiteralContextAll::DoubleContext(ctx) = + cast_mut::<_, LiteralContextAll>(&mut _localctx) + { + ctx.tok = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + 4 => { + let tmp = StringContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 4); + _localctx = tmp; + { + recog.base.set_state(251); + let tmp = recog.base.match_token(STRING, &mut recog.err_handler)?; + if let LiteralContextAll::StringContext(ctx) = + cast_mut::<_, LiteralContextAll>(&mut _localctx) + { + ctx.tok = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + 5 => { + let tmp = BytesContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 5); + _localctx = tmp; + { + recog.base.set_state(252); + let tmp = recog.base.match_token(BYTES, &mut recog.err_handler)?; + if let LiteralContextAll::BytesContext(ctx) = + cast_mut::<_, LiteralContextAll>(&mut _localctx) + { + ctx.tok = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + 6 => { + let tmp = BoolTrueContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 6); + _localctx = tmp; + { + recog.base.set_state(253); + let tmp = recog.base.match_token(CEL_TRUE, &mut recog.err_handler)?; + if let LiteralContextAll::BoolTrueContext(ctx) = + cast_mut::<_, LiteralContextAll>(&mut _localctx) + { + ctx.tok = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + 7 => { + let tmp = BoolFalseContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 7); + _localctx = tmp; + { + recog.base.set_state(254); + let tmp = recog.base.match_token(CEL_FALSE, &mut recog.err_handler)?; + if let LiteralContextAll::BoolFalseContext(ctx) = + cast_mut::<_, LiteralContextAll>(&mut _localctx) + { + ctx.tok = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + 8 => { + let tmp = NullContextExt::new(&**_localctx); + recog.base.enter_outer_alt(Some(tmp.clone()), 8); + _localctx = tmp; + { + recog.base.set_state(255); + let tmp = recog.base.match_token(NUL, &mut recog.err_handler)?; + if let LiteralContextAll::NullContext(ctx) = + cast_mut::<_, LiteralContextAll>(&mut _localctx) + { + ctx.tok = Some(tmp.clone()); + } else { + unreachable!("cant cast"); + } + } + } + + _ => {} + } + Ok(()) + })(); + match result { + Ok(_) => {} + Err(e @ ANTLRError::FallThrough(_)) => return Err(e), + Err(ref re) => { + //_localctx.exception = re; + recog.err_handler.report_error(&mut recog.base, re); + recog.err_handler.recover(&mut recog.base, re)?; + } + } + recog.base.exit_rule(); + + Ok(_localctx) + } +} + +lazy_static! { + static ref _ATN: Arc = + Arc::new(ATNDeserializer::new(None).deserialize(_serializedATN.chars())); + static ref _decision_to_DFA: Arc>> = { + let mut dfa = Vec::new(); + let size = _ATN.decision_to_state.len(); + for i in 0..size { + dfa.push(DFA::new(_ATN.clone(), _ATN.get_decision_state(i), i as isize).into()) + } + Arc::new(dfa) + }; +} + +const _serializedATN: &str = + "\x03\u{608b}\u{a72a}\u{8133}\u{b9ed}\u{417c}\u{3be7}\u{7786}\u{5964}\x03\ + \x27\u{105}\x04\x02\x09\x02\x04\x03\x09\x03\x04\x04\x09\x04\x04\x05\x09\ + \x05\x04\x06\x09\x06\x04\x07\x09\x07\x04\x08\x09\x08\x04\x09\x09\x09\x04\ + \x0a\x09\x0a\x04\x0b\x09\x0b\x04\x0c\x09\x0c\x04\x0d\x09\x0d\x04\x0e\x09\ + \x0e\x04\x0f\x09\x0f\x04\x10\x09\x10\x04\x11\x09\x11\x04\x12\x09\x12\x03\ + \x02\x03\x02\x03\x02\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x05\ + \x03\x2e\x0a\x03\x03\x04\x03\x04\x03\x04\x07\x04\x33\x0a\x04\x0c\x04\x0e\ + \x04\x36\x0b\x04\x03\x05\x03\x05\x03\x05\x07\x05\x3b\x0a\x05\x0c\x05\x0e\ + \x05\x3e\x0b\x05\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x07\x06\ + \x46\x0a\x06\x0c\x06\x0e\x06\x49\x0b\x06\x03\x07\x03\x07\x03\x07\x03\x07\ + \x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x07\x07\x54\x0a\x07\x0c\x07\x0e\ + \x07\x57\x0b\x07\x03\x08\x03\x08\x06\x08\x5b\x0a\x08\x0d\x08\x0e\x08\x5c\ + \x03\x08\x03\x08\x06\x08\x61\x0a\x08\x0d\x08\x0e\x08\x62\x03\x08\x05\x08\ + \x66\x0a\x08\x03\x09\x03\x09\x03\x09\x03\x09\x03\x09\x03\x09\x05\x09\x6e\ + \x0a\x09\x03\x09\x03\x09\x03\x09\x03\x09\x03\x09\x03\x09\x05\x09\x76\x0a\ + \x09\x03\x09\x03\x09\x03\x09\x03\x09\x05\x09\x7c\x0a\x09\x03\x09\x03\x09\ + \x03\x09\x07\x09\u{81}\x0a\x09\x0c\x09\x0e\x09\u{84}\x0b\x09\x03\x0a\x05\ + \x0a\u{87}\x0a\x0a\x03\x0a\x03\x0a\x05\x0a\u{8b}\x0a\x0a\x03\x0a\x03\x0a\ + \x03\x0a\x05\x0a\u{90}\x0a\x0a\x03\x0a\x03\x0a\x03\x0a\x03\x0a\x03\x0a\x03\ + \x0a\x03\x0a\x05\x0a\u{99}\x0a\x0a\x03\x0a\x05\x0a\u{9c}\x0a\x0a\x03\x0a\ + \x03\x0a\x03\x0a\x05\x0a\u{a1}\x0a\x0a\x03\x0a\x05\x0a\u{a4}\x0a\x0a\x03\ + \x0a\x03\x0a\x05\x0a\u{a8}\x0a\x0a\x03\x0a\x03\x0a\x03\x0a\x07\x0a\u{ad}\ + \x0a\x0a\x0c\x0a\x0e\x0a\u{b0}\x0b\x0a\x03\x0a\x03\x0a\x05\x0a\u{b4}\x0a\ + \x0a\x03\x0a\x05\x0a\u{b7}\x0a\x0a\x03\x0a\x03\x0a\x05\x0a\u{bb}\x0a\x0a\ + \x03\x0b\x03\x0b\x03\x0b\x07\x0b\u{c0}\x0a\x0b\x0c\x0b\x0e\x0b\u{c3}\x0b\ + \x0b\x03\x0c\x03\x0c\x03\x0c\x07\x0c\u{c8}\x0a\x0c\x0c\x0c\x0e\x0c\u{cb}\ + \x0b\x0c\x03\x0d\x03\x0d\x03\x0d\x03\x0d\x03\x0d\x03\x0d\x03\x0d\x03\x0d\ + \x07\x0d\u{d5}\x0a\x0d\x0c\x0d\x0e\x0d\u{d8}\x0b\x0d\x03\x0e\x05\x0e\u{db}\ + \x0a\x0e\x03\x0e\x03\x0e\x03\x0f\x03\x0f\x03\x0f\x03\x0f\x03\x0f\x03\x0f\ + \x03\x0f\x03\x0f\x07\x0f\u{e7}\x0a\x0f\x0c\x0f\x0e\x0f\u{ea}\x0b\x0f\x03\ + \x10\x03\x10\x05\x10\u{ee}\x0a\x10\x03\x11\x05\x11\u{f1}\x0a\x11\x03\x11\ + \x03\x11\x03\x12\x05\x12\u{f6}\x0a\x12\x03\x12\x03\x12\x03\x12\x05\x12\u{fb}\ + \x0a\x12\x03\x12\x03\x12\x03\x12\x03\x12\x03\x12\x03\x12\x05\x12\u{103}\ + \x0a\x12\x03\x12\x02\x05\x0a\x0c\x10\x13\x02\x04\x06\x08\x0a\x0c\x0e\x10\ + \x12\x14\x16\x18\x1a\x1c\x1e\x20\x22\x02\x05\x03\x02\x03\x09\x03\x02\x19\ + \x1b\x04\x02\x14\x14\x18\x18\x02\u{124}\x02\x24\x03\x02\x02\x02\x04\x27\ + \x03\x02\x02\x02\x06\x2f\x03\x02\x02\x02\x08\x37\x03\x02\x02\x02\x0a\x3f\ + \x03\x02\x02\x02\x0c\x4a\x03\x02\x02\x02\x0e\x65\x03\x02\x02\x02\x10\x67\ + \x03\x02\x02\x02\x12\u{ba}\x03\x02\x02\x02\x14\u{bc}\x03\x02\x02\x02\x16\ + \u{c4}\x03\x02\x02\x02\x18\u{cc}\x03\x02\x02\x02\x1a\u{da}\x03\x02\x02\x02\ + \x1c\u{de}\x03\x02\x02\x02\x1e\u{ed}\x03\x02\x02\x02\x20\u{f0}\x03\x02\x02\ + \x02\x22\u{102}\x03\x02\x02\x02\x24\x25\x05\x04\x03\x02\x25\x26\x07\x02\ + \x02\x03\x26\x03\x03\x02\x02\x02\x27\x2d\x05\x06\x04\x02\x28\x29\x07\x16\ + \x02\x02\x29\x2a\x05\x06\x04\x02\x2a\x2b\x07\x17\x02\x02\x2b\x2c\x05\x04\ + \x03\x02\x2c\x2e\x03\x02\x02\x02\x2d\x28\x03\x02\x02\x02\x2d\x2e\x03\x02\ + \x02\x02\x2e\x05\x03\x02\x02\x02\x2f\x34\x05\x08\x05\x02\x30\x31\x07\x0b\ + \x02\x02\x31\x33\x05\x08\x05\x02\x32\x30\x03\x02\x02\x02\x33\x36\x03\x02\ + \x02\x02\x34\x32\x03\x02\x02\x02\x34\x35\x03\x02\x02\x02\x35\x07\x03\x02\ + \x02\x02\x36\x34\x03\x02\x02\x02\x37\x3c\x05\x0a\x06\x02\x38\x39\x07\x0a\ + \x02\x02\x39\x3b\x05\x0a\x06\x02\x3a\x38\x03\x02\x02\x02\x3b\x3e\x03\x02\ + \x02\x02\x3c\x3a\x03\x02\x02\x02\x3c\x3d\x03\x02\x02\x02\x3d\x09\x03\x02\ + \x02\x02\x3e\x3c\x03\x02\x02\x02\x3f\x40\x08\x06\x01\x02\x40\x41\x05\x0c\ + \x07\x02\x41\x47\x03\x02\x02\x02\x42\x43\x0c\x03\x02\x02\x43\x44\x09\x02\ + \x02\x02\x44\x46\x05\x0a\x06\x04\x45\x42\x03\x02\x02\x02\x46\x49\x03\x02\ + \x02\x02\x47\x45\x03\x02\x02\x02\x47\x48\x03\x02\x02\x02\x48\x0b\x03\x02\ + \x02\x02\x49\x47\x03\x02\x02\x02\x4a\x4b\x08\x07\x01\x02\x4b\x4c\x05\x0e\ + \x08\x02\x4c\x55\x03\x02\x02\x02\x4d\x4e\x0c\x04\x02\x02\x4e\x4f\x09\x03\ + \x02\x02\x4f\x54\x05\x0c\x07\x05\x50\x51\x0c\x03\x02\x02\x51\x52\x09\x04\ + \x02\x02\x52\x54\x05\x0c\x07\x04\x53\x4d\x03\x02\x02\x02\x53\x50\x03\x02\ + \x02\x02\x54\x57\x03\x02\x02\x02\x55\x53\x03\x02\x02\x02\x55\x56\x03\x02\ + \x02\x02\x56\x0d\x03\x02\x02\x02\x57\x55\x03\x02\x02\x02\x58\x66\x05\x10\ + \x09\x02\x59\x5b\x07\x15\x02\x02\x5a\x59\x03\x02\x02\x02\x5b\x5c\x03\x02\ + \x02\x02\x5c\x5a\x03\x02\x02\x02\x5c\x5d\x03\x02\x02\x02\x5d\x5e\x03\x02\ + \x02\x02\x5e\x66\x05\x10\x09\x02\x5f\x61\x07\x14\x02\x02\x60\x5f\x03\x02\ + \x02\x02\x61\x62\x03\x02\x02\x02\x62\x60\x03\x02\x02\x02\x62\x63\x03\x02\ + \x02\x02\x63\x64\x03\x02\x02\x02\x64\x66\x05\x10\x09\x02\x65\x58\x03\x02\ + \x02\x02\x65\x5a\x03\x02\x02\x02\x65\x60\x03\x02\x02\x02\x66\x0f\x03\x02\ + \x02\x02\x67\x68\x08\x09\x01\x02\x68\x69\x05\x12\x0a\x02\x69\u{82}\x03\x02\ + \x02\x02\x6a\x6b\x0c\x05\x02\x02\x6b\x6d\x07\x12\x02\x02\x6c\x6e\x07\x16\ + \x02\x02\x6d\x6c\x03\x02\x02\x02\x6d\x6e\x03\x02\x02\x02\x6e\x6f\x03\x02\ + \x02\x02\x6f\u{81}\x05\x1e\x10\x02\x70\x71\x0c\x04\x02\x02\x71\x72\x07\x12\ + \x02\x02\x72\x73\x07\x26\x02\x02\x73\x75\x07\x10\x02\x02\x74\x76\x05\x14\ + \x0b\x02\x75\x74\x03\x02\x02\x02\x75\x76\x03\x02\x02\x02\x76\x77\x03\x02\ + \x02\x02\x77\u{81}\x07\x11\x02\x02\x78\x79\x0c\x03\x02\x02\x79\x7b\x07\x0c\ + \x02\x02\x7a\x7c\x07\x16\x02\x02\x7b\x7a\x03\x02\x02\x02\x7b\x7c\x03\x02\ + \x02\x02\x7c\x7d\x03\x02\x02\x02\x7d\x7e\x05\x04\x03\x02\x7e\x7f\x07\x0d\ + \x02\x02\x7f\u{81}\x03\x02\x02\x02\u{80}\x6a\x03\x02\x02\x02\u{80}\x70\x03\ + \x02\x02\x02\u{80}\x78\x03\x02\x02\x02\u{81}\u{84}\x03\x02\x02\x02\u{82}\ + \u{80}\x03\x02\x02\x02\u{82}\u{83}\x03\x02\x02\x02\u{83}\x11\x03\x02\x02\ + \x02\u{84}\u{82}\x03\x02\x02\x02\u{85}\u{87}\x07\x12\x02\x02\u{86}\u{85}\ + \x03\x02\x02\x02\u{86}\u{87}\x03\x02\x02\x02\u{87}\u{88}\x03\x02\x02\x02\ + \u{88}\u{bb}\x07\x26\x02\x02\u{89}\u{8b}\x07\x12\x02\x02\u{8a}\u{89}\x03\ + \x02\x02\x02\u{8a}\u{8b}\x03\x02\x02\x02\u{8b}\u{8c}\x03\x02\x02\x02\u{8c}\ + \u{8d}\x07\x26\x02\x02\u{8d}\u{8f}\x07\x10\x02\x02\u{8e}\u{90}\x05\x14\x0b\ + \x02\u{8f}\u{8e}\x03\x02\x02\x02\u{8f}\u{90}\x03\x02\x02\x02\u{90}\u{91}\ + \x03\x02\x02\x02\u{91}\u{bb}\x07\x11\x02\x02\u{92}\u{93}\x07\x10\x02\x02\ + \u{93}\u{94}\x05\x04\x03\x02\u{94}\u{95}\x07\x11\x02\x02\u{95}\u{bb}\x03\ + \x02\x02\x02\u{96}\u{98}\x07\x0c\x02\x02\u{97}\u{99}\x05\x16\x0c\x02\u{98}\ + \u{97}\x03\x02\x02\x02\u{98}\u{99}\x03\x02\x02\x02\u{99}\u{9b}\x03\x02\x02\ + \x02\u{9a}\u{9c}\x07\x13\x02\x02\u{9b}\u{9a}\x03\x02\x02\x02\u{9b}\u{9c}\ + \x03\x02\x02\x02\u{9c}\u{9d}\x03\x02\x02\x02\u{9d}\u{bb}\x07\x0d\x02\x02\ + \u{9e}\u{a0}\x07\x0e\x02\x02\u{9f}\u{a1}\x05\x1c\x0f\x02\u{a0}\u{9f}\x03\ + \x02\x02\x02\u{a0}\u{a1}\x03\x02\x02\x02\u{a1}\u{a3}\x03\x02\x02\x02\u{a2}\ + \u{a4}\x07\x13\x02\x02\u{a3}\u{a2}\x03\x02\x02\x02\u{a3}\u{a4}\x03\x02\x02\ + \x02\u{a4}\u{a5}\x03\x02\x02\x02\u{a5}\u{bb}\x07\x0f\x02\x02\u{a6}\u{a8}\ + \x07\x12\x02\x02\u{a7}\u{a6}\x03\x02\x02\x02\u{a7}\u{a8}\x03\x02\x02\x02\ + \u{a8}\u{a9}\x03\x02\x02\x02\u{a9}\u{ae}\x07\x26\x02\x02\u{aa}\u{ab}\x07\ + \x12\x02\x02\u{ab}\u{ad}\x07\x26\x02\x02\u{ac}\u{aa}\x03\x02\x02\x02\u{ad}\ + \u{b0}\x03\x02\x02\x02\u{ae}\u{ac}\x03\x02\x02\x02\u{ae}\u{af}\x03\x02\x02\ + \x02\u{af}\u{b1}\x03\x02\x02\x02\u{b0}\u{ae}\x03\x02\x02\x02\u{b1}\u{b3}\ + \x07\x0e\x02\x02\u{b2}\u{b4}\x05\x18\x0d\x02\u{b3}\u{b2}\x03\x02\x02\x02\ + \u{b3}\u{b4}\x03\x02\x02\x02\u{b4}\u{b6}\x03\x02\x02\x02\u{b5}\u{b7}\x07\ + \x13\x02\x02\u{b6}\u{b5}\x03\x02\x02\x02\u{b6}\u{b7}\x03\x02\x02\x02\u{b7}\ + \u{b8}\x03\x02\x02\x02\u{b8}\u{bb}\x07\x0f\x02\x02\u{b9}\u{bb}\x05\x22\x12\ + \x02\u{ba}\u{86}\x03\x02\x02\x02\u{ba}\u{8a}\x03\x02\x02\x02\u{ba}\u{92}\ + \x03\x02\x02\x02\u{ba}\u{96}\x03\x02\x02\x02\u{ba}\u{9e}\x03\x02\x02\x02\ + \u{ba}\u{a7}\x03\x02\x02\x02\u{ba}\u{b9}\x03\x02\x02\x02\u{bb}\x13\x03\x02\ + \x02\x02\u{bc}\u{c1}\x05\x04\x03\x02\u{bd}\u{be}\x07\x13\x02\x02\u{be}\u{c0}\ + \x05\x04\x03\x02\u{bf}\u{bd}\x03\x02\x02\x02\u{c0}\u{c3}\x03\x02\x02\x02\ + \u{c1}\u{bf}\x03\x02\x02\x02\u{c1}\u{c2}\x03\x02\x02\x02\u{c2}\x15\x03\x02\ + \x02\x02\u{c3}\u{c1}\x03\x02\x02\x02\u{c4}\u{c9}\x05\x20\x11\x02\u{c5}\u{c6}\ + \x07\x13\x02\x02\u{c6}\u{c8}\x05\x20\x11\x02\u{c7}\u{c5}\x03\x02\x02\x02\ + \u{c8}\u{cb}\x03\x02\x02\x02\u{c9}\u{c7}\x03\x02\x02\x02\u{c9}\u{ca}\x03\ + \x02\x02\x02\u{ca}\x17\x03\x02\x02\x02\u{cb}\u{c9}\x03\x02\x02\x02\u{cc}\ + \u{cd}\x05\x1a\x0e\x02\u{cd}\u{ce}\x07\x17\x02\x02\u{ce}\u{d6}\x05\x04\x03\ + \x02\u{cf}\u{d0}\x07\x13\x02\x02\u{d0}\u{d1}\x05\x1a\x0e\x02\u{d1}\u{d2}\ + \x07\x17\x02\x02\u{d2}\u{d3}\x05\x04\x03\x02\u{d3}\u{d5}\x03\x02\x02\x02\ + \u{d4}\u{cf}\x03\x02\x02\x02\u{d5}\u{d8}\x03\x02\x02\x02\u{d6}\u{d4}\x03\ + \x02\x02\x02\u{d6}\u{d7}\x03\x02\x02\x02\u{d7}\x19\x03\x02\x02\x02\u{d8}\ + \u{d6}\x03\x02\x02\x02\u{d9}\u{db}\x07\x16\x02\x02\u{da}\u{d9}\x03\x02\x02\ + \x02\u{da}\u{db}\x03\x02\x02\x02\u{db}\u{dc}\x03\x02\x02\x02\u{dc}\u{dd}\ + \x05\x1e\x10\x02\u{dd}\x1b\x03\x02\x02\x02\u{de}\u{df}\x05\x20\x11\x02\u{df}\ + \u{e0}\x07\x17\x02\x02\u{e0}\u{e8}\x05\x04\x03\x02\u{e1}\u{e2}\x07\x13\x02\ + \x02\u{e2}\u{e3}\x05\x20\x11\x02\u{e3}\u{e4}\x07\x17\x02\x02\u{e4}\u{e5}\ + \x05\x04\x03\x02\u{e5}\u{e7}\x03\x02\x02\x02\u{e6}\u{e1}\x03\x02\x02\x02\ + \u{e7}\u{ea}\x03\x02\x02\x02\u{e8}\u{e6}\x03\x02\x02\x02\u{e8}\u{e9}\x03\ + \x02\x02\x02\u{e9}\x1d\x03\x02\x02\x02\u{ea}\u{e8}\x03\x02\x02\x02\u{eb}\ + \u{ee}\x07\x26\x02\x02\u{ec}\u{ee}\x07\x27\x02\x02\u{ed}\u{eb}\x03\x02\x02\ + \x02\u{ed}\u{ec}\x03\x02\x02\x02\u{ee}\x1f\x03\x02\x02\x02\u{ef}\u{f1}\x07\ + \x16\x02\x02\u{f0}\u{ef}\x03\x02\x02\x02\u{f0}\u{f1}\x03\x02\x02\x02\u{f1}\ + \u{f2}\x03\x02\x02\x02\u{f2}\u{f3}\x05\x04\x03\x02\u{f3}\x21\x03\x02\x02\ + \x02\u{f4}\u{f6}\x07\x14\x02\x02\u{f5}\u{f4}\x03\x02\x02\x02\u{f5}\u{f6}\ + \x03\x02\x02\x02\u{f6}\u{f7}\x03\x02\x02\x02\u{f7}\u{103}\x07\x22\x02\x02\ + \u{f8}\u{103}\x07\x23\x02\x02\u{f9}\u{fb}\x07\x14\x02\x02\u{fa}\u{f9}\x03\ + \x02\x02\x02\u{fa}\u{fb}\x03\x02\x02\x02\u{fb}\u{fc}\x03\x02\x02\x02\u{fc}\ + \u{103}\x07\x21\x02\x02\u{fd}\u{103}\x07\x24\x02\x02\u{fe}\u{103}\x07\x25\ + \x02\x02\u{ff}\u{103}\x07\x1c\x02\x02\u{100}\u{103}\x07\x1d\x02\x02\u{101}\ + \u{103}\x07\x1e\x02\x02\u{102}\u{f5}\x03\x02\x02\x02\u{102}\u{f8}\x03\x02\ + \x02\x02\u{102}\u{fa}\x03\x02\x02\x02\u{102}\u{fd}\x03\x02\x02\x02\u{102}\ + \u{fe}\x03\x02\x02\x02\u{102}\u{ff}\x03\x02\x02\x02\u{102}\u{100}\x03\x02\ + \x02\x02\u{102}\u{101}\x03\x02\x02\x02\u{103}\x23\x03\x02\x02\x02\x26\x2d\ + \x34\x3c\x47\x53\x55\x5c\x62\x65\x6d\x75\x7b\u{80}\u{82}\u{86}\u{8a}\u{8f}\ + \u{98}\u{9b}\u{a0}\u{a3}\u{a7}\u{ae}\u{b3}\u{b6}\u{ba}\u{c1}\u{c9}\u{d6}\ + \u{da}\u{e8}\u{ed}\u{f0}\u{f5}\u{fa}\u{102}"; diff --git a/vendor/cel/src/parser/gen/celvisitor.rs b/vendor/cel/src/parser/gen/celvisitor.rs new file mode 100644 index 0000000..e1421a7 --- /dev/null +++ b/vendor/cel/src/parser/gen/celvisitor.rs @@ -0,0 +1,829 @@ +#![allow(nonstandard_style)] +// Generated from /Users/asnaps/src/github.com/clarkmcc/cel-rust/antlr/src/gen/CEL.g4 by ANTLR 4.8 +use super::celparser::*; +use antlr4rust::tree::{ParseTreeVisitor, ParseTreeVisitorCompat}; + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by {@link CELParser}. + */ +pub trait CELVisitor<'input>: ParseTreeVisitor<'input, CELParserContextType> { + /** + * Visit a parse tree produced by {@link CELParser#start}. + * @param ctx the parse tree + */ + fn visit_start(&mut self, ctx: &StartContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#expr}. + * @param ctx the parse tree + */ + fn visit_expr(&mut self, ctx: &ExprContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#conditionalOr}. + * @param ctx the parse tree + */ + fn visit_conditionalOr(&mut self, ctx: &ConditionalOrContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#conditionalAnd}. + * @param ctx the parse tree + */ + fn visit_conditionalAnd(&mut self, ctx: &ConditionalAndContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#relation}. + * @param ctx the parse tree + */ + fn visit_relation(&mut self, ctx: &RelationContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#calc}. + * @param ctx the parse tree + */ + fn visit_calc(&mut self, ctx: &CalcContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code MemberExpr} + * labeled alternative in {@link CELParser#unary}. + * @param ctx the parse tree + */ + fn visit_MemberExpr(&mut self, ctx: &MemberExprContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code LogicalNot} + * labeled alternative in {@link CELParser#unary}. + * @param ctx the parse tree + */ + fn visit_LogicalNot(&mut self, ctx: &LogicalNotContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Negate} + * labeled alternative in {@link CELParser#unary}. + * @param ctx the parse tree + */ + fn visit_Negate(&mut self, ctx: &NegateContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code MemberCall} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn visit_MemberCall(&mut self, ctx: &MemberCallContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Select} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn visit_Select(&mut self, ctx: &SelectContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code PrimaryExpr} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn visit_PrimaryExpr(&mut self, ctx: &PrimaryExprContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Index} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn visit_Index(&mut self, ctx: &IndexContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Ident} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_Ident(&mut self, ctx: &IdentContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code GlobalCall} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_GlobalCall(&mut self, ctx: &GlobalCallContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Nested} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_Nested(&mut self, ctx: &NestedContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code CreateList} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_CreateList(&mut self, ctx: &CreateListContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code CreateStruct} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_CreateStruct(&mut self, ctx: &CreateStructContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code CreateMessage} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_CreateMessage(&mut self, ctx: &CreateMessageContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code ConstantLiteral} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_ConstantLiteral(&mut self, ctx: &ConstantLiteralContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#exprList}. + * @param ctx the parse tree + */ + fn visit_exprList(&mut self, ctx: &ExprListContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#listInit}. + * @param ctx the parse tree + */ + fn visit_listInit(&mut self, ctx: &ListInitContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#fieldInitializerList}. + * @param ctx the parse tree + */ + fn visit_fieldInitializerList(&mut self, ctx: &FieldInitializerListContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#optField}. + * @param ctx the parse tree + */ + fn visit_optField(&mut self, ctx: &OptFieldContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#mapInitializerList}. + * @param ctx the parse tree + */ + fn visit_mapInitializerList(&mut self, ctx: &MapInitializerListContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code SimpleIdentifier} + * labeled alternative in {@link CELParser#escapeIdent}. + * @param ctx the parse tree + */ + fn visit_SimpleIdentifier(&mut self, ctx: &SimpleIdentifierContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code EscapedIdentifier} + * labeled alternative in {@link CELParser#escapeIdent}. + * @param ctx the parse tree + */ + fn visit_EscapedIdentifier(&mut self, ctx: &EscapedIdentifierContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#optExpr}. + * @param ctx the parse tree + */ + fn visit_optExpr(&mut self, ctx: &OptExprContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Int} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_Int(&mut self, ctx: &IntContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Uint} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_Uint(&mut self, ctx: &UintContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Double} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_Double(&mut self, ctx: &DoubleContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code String} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_String(&mut self, ctx: &StringContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Bytes} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_Bytes(&mut self, ctx: &BytesContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code BoolTrue} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_BoolTrue(&mut self, ctx: &BoolTrueContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code BoolFalse} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_BoolFalse(&mut self, ctx: &BoolFalseContext<'input>) { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Null} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_Null(&mut self, ctx: &NullContext<'input>) { + self.visit_children(ctx) + } +} + +pub trait CELVisitorCompat<'input>: + ParseTreeVisitorCompat<'input, Node = CELParserContextType> +{ + /** + * Visit a parse tree produced by {@link CELParser#start}. + * @param ctx the parse tree + */ + fn visit_start(&mut self, ctx: &StartContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#expr}. + * @param ctx the parse tree + */ + fn visit_expr(&mut self, ctx: &ExprContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#conditionalOr}. + * @param ctx the parse tree + */ + fn visit_conditionalOr(&mut self, ctx: &ConditionalOrContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#conditionalAnd}. + * @param ctx the parse tree + */ + fn visit_conditionalAnd(&mut self, ctx: &ConditionalAndContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#relation}. + * @param ctx the parse tree + */ + fn visit_relation(&mut self, ctx: &RelationContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#calc}. + * @param ctx the parse tree + */ + fn visit_calc(&mut self, ctx: &CalcContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code MemberExpr} + * labeled alternative in {@link CELParser#unary}. + * @param ctx the parse tree + */ + fn visit_MemberExpr(&mut self, ctx: &MemberExprContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code LogicalNot} + * labeled alternative in {@link CELParser#unary}. + * @param ctx the parse tree + */ + fn visit_LogicalNot(&mut self, ctx: &LogicalNotContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Negate} + * labeled alternative in {@link CELParser#unary}. + * @param ctx the parse tree + */ + fn visit_Negate(&mut self, ctx: &NegateContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code MemberCall} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn visit_MemberCall(&mut self, ctx: &MemberCallContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Select} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn visit_Select(&mut self, ctx: &SelectContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code PrimaryExpr} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn visit_PrimaryExpr(&mut self, ctx: &PrimaryExprContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Index} + * labeled alternative in {@link CELParser#member}. + * @param ctx the parse tree + */ + fn visit_Index(&mut self, ctx: &IndexContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Ident} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_Ident(&mut self, ctx: &IdentContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code GlobalCall} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_GlobalCall(&mut self, ctx: &GlobalCallContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Nested} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_Nested(&mut self, ctx: &NestedContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code CreateList} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_CreateList(&mut self, ctx: &CreateListContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code CreateStruct} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_CreateStruct(&mut self, ctx: &CreateStructContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code CreateMessage} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_CreateMessage(&mut self, ctx: &CreateMessageContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code ConstantLiteral} + * labeled alternative in {@link CELParser#primary}. + * @param ctx the parse tree + */ + fn visit_ConstantLiteral(&mut self, ctx: &ConstantLiteralContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#exprList}. + * @param ctx the parse tree + */ + fn visit_exprList(&mut self, ctx: &ExprListContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#listInit}. + * @param ctx the parse tree + */ + fn visit_listInit(&mut self, ctx: &ListInitContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#fieldInitializerList}. + * @param ctx the parse tree + */ + fn visit_fieldInitializerList( + &mut self, + ctx: &FieldInitializerListContext<'input>, + ) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#optField}. + * @param ctx the parse tree + */ + fn visit_optField(&mut self, ctx: &OptFieldContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#mapInitializerList}. + * @param ctx the parse tree + */ + fn visit_mapInitializerList( + &mut self, + ctx: &MapInitializerListContext<'input>, + ) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code SimpleIdentifier} + * labeled alternative in {@link CELParser#escapeIdent}. + * @param ctx the parse tree + */ + fn visit_SimpleIdentifier(&mut self, ctx: &SimpleIdentifierContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code EscapedIdentifier} + * labeled alternative in {@link CELParser#escapeIdent}. + * @param ctx the parse tree + */ + fn visit_EscapedIdentifier(&mut self, ctx: &EscapedIdentifierContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by {@link CELParser#optExpr}. + * @param ctx the parse tree + */ + fn visit_optExpr(&mut self, ctx: &OptExprContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Int} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_Int(&mut self, ctx: &IntContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Uint} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_Uint(&mut self, ctx: &UintContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Double} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_Double(&mut self, ctx: &DoubleContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code String} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_String(&mut self, ctx: &StringContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Bytes} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_Bytes(&mut self, ctx: &BytesContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code BoolTrue} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_BoolTrue(&mut self, ctx: &BoolTrueContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code BoolFalse} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_BoolFalse(&mut self, ctx: &BoolFalseContext<'input>) -> Self::Return { + self.visit_children(ctx) + } + + /** + * Visit a parse tree produced by the {@code Null} + * labeled alternative in {@link CELParser#literal}. + * @param ctx the parse tree + */ + fn visit_Null(&mut self, ctx: &NullContext<'input>) -> Self::Return { + self.visit_children(ctx) + } +} + +impl<'input, T> CELVisitor<'input> for T +where + T: CELVisitorCompat<'input>, +{ + fn visit_start(&mut self, ctx: &StartContext<'input>) { + let result = ::visit_start(self, ctx); + *::temp_result(self) = result; + } + + fn visit_expr(&mut self, ctx: &ExprContext<'input>) { + let result = ::visit_expr(self, ctx); + *::temp_result(self) = result; + } + + fn visit_conditionalOr(&mut self, ctx: &ConditionalOrContext<'input>) { + let result = ::visit_conditionalOr(self, ctx); + *::temp_result(self) = result; + } + + fn visit_conditionalAnd(&mut self, ctx: &ConditionalAndContext<'input>) { + let result = ::visit_conditionalAnd(self, ctx); + *::temp_result(self) = result; + } + + fn visit_relation(&mut self, ctx: &RelationContext<'input>) { + let result = ::visit_relation(self, ctx); + *::temp_result(self) = result; + } + + fn visit_calc(&mut self, ctx: &CalcContext<'input>) { + let result = ::visit_calc(self, ctx); + *::temp_result(self) = result; + } + + fn visit_MemberExpr(&mut self, ctx: &MemberExprContext<'input>) { + let result = ::visit_MemberExpr(self, ctx); + *::temp_result(self) = result; + } + + fn visit_LogicalNot(&mut self, ctx: &LogicalNotContext<'input>) { + let result = ::visit_LogicalNot(self, ctx); + *::temp_result(self) = result; + } + + fn visit_Negate(&mut self, ctx: &NegateContext<'input>) { + let result = ::visit_Negate(self, ctx); + *::temp_result(self) = result; + } + + fn visit_MemberCall(&mut self, ctx: &MemberCallContext<'input>) { + let result = ::visit_MemberCall(self, ctx); + *::temp_result(self) = result; + } + + fn visit_Select(&mut self, ctx: &SelectContext<'input>) { + let result = ::visit_Select(self, ctx); + *::temp_result(self) = result; + } + + fn visit_PrimaryExpr(&mut self, ctx: &PrimaryExprContext<'input>) { + let result = ::visit_PrimaryExpr(self, ctx); + *::temp_result(self) = result; + } + + fn visit_Index(&mut self, ctx: &IndexContext<'input>) { + let result = ::visit_Index(self, ctx); + *::temp_result(self) = result; + } + + fn visit_Ident(&mut self, ctx: &IdentContext<'input>) { + let result = ::visit_Ident(self, ctx); + *::temp_result(self) = result; + } + + fn visit_GlobalCall(&mut self, ctx: &GlobalCallContext<'input>) { + let result = ::visit_GlobalCall(self, ctx); + *::temp_result(self) = result; + } + + fn visit_Nested(&mut self, ctx: &NestedContext<'input>) { + let result = ::visit_Nested(self, ctx); + *::temp_result(self) = result; + } + + fn visit_CreateList(&mut self, ctx: &CreateListContext<'input>) { + let result = ::visit_CreateList(self, ctx); + *::temp_result(self) = result; + } + + fn visit_CreateStruct(&mut self, ctx: &CreateStructContext<'input>) { + let result = ::visit_CreateStruct(self, ctx); + *::temp_result(self) = result; + } + + fn visit_CreateMessage(&mut self, ctx: &CreateMessageContext<'input>) { + let result = ::visit_CreateMessage(self, ctx); + *::temp_result(self) = result; + } + + fn visit_ConstantLiteral(&mut self, ctx: &ConstantLiteralContext<'input>) { + let result = ::visit_ConstantLiteral(self, ctx); + *::temp_result(self) = result; + } + + fn visit_exprList(&mut self, ctx: &ExprListContext<'input>) { + let result = ::visit_exprList(self, ctx); + *::temp_result(self) = result; + } + + fn visit_listInit(&mut self, ctx: &ListInitContext<'input>) { + let result = ::visit_listInit(self, ctx); + *::temp_result(self) = result; + } + + fn visit_fieldInitializerList(&mut self, ctx: &FieldInitializerListContext<'input>) { + let result = ::visit_fieldInitializerList(self, ctx); + *::temp_result(self) = result; + } + + fn visit_optField(&mut self, ctx: &OptFieldContext<'input>) { + let result = ::visit_optField(self, ctx); + *::temp_result(self) = result; + } + + fn visit_mapInitializerList(&mut self, ctx: &MapInitializerListContext<'input>) { + let result = ::visit_mapInitializerList(self, ctx); + *::temp_result(self) = result; + } + + fn visit_SimpleIdentifier(&mut self, ctx: &SimpleIdentifierContext<'input>) { + let result = ::visit_SimpleIdentifier(self, ctx); + *::temp_result(self) = result; + } + + fn visit_EscapedIdentifier(&mut self, ctx: &EscapedIdentifierContext<'input>) { + let result = ::visit_EscapedIdentifier(self, ctx); + *::temp_result(self) = result; + } + + fn visit_optExpr(&mut self, ctx: &OptExprContext<'input>) { + let result = ::visit_optExpr(self, ctx); + *::temp_result(self) = result; + } + + fn visit_Int(&mut self, ctx: &IntContext<'input>) { + let result = ::visit_Int(self, ctx); + *::temp_result(self) = result; + } + + fn visit_Uint(&mut self, ctx: &UintContext<'input>) { + let result = ::visit_Uint(self, ctx); + *::temp_result(self) = result; + } + + fn visit_Double(&mut self, ctx: &DoubleContext<'input>) { + let result = ::visit_Double(self, ctx); + *::temp_result(self) = result; + } + + fn visit_String(&mut self, ctx: &StringContext<'input>) { + let result = ::visit_String(self, ctx); + *::temp_result(self) = result; + } + + fn visit_Bytes(&mut self, ctx: &BytesContext<'input>) { + let result = ::visit_Bytes(self, ctx); + *::temp_result(self) = result; + } + + fn visit_BoolTrue(&mut self, ctx: &BoolTrueContext<'input>) { + let result = ::visit_BoolTrue(self, ctx); + *::temp_result(self) = result; + } + + fn visit_BoolFalse(&mut self, ctx: &BoolFalseContext<'input>) { + let result = ::visit_BoolFalse(self, ctx); + *::temp_result(self) = result; + } + + fn visit_Null(&mut self, ctx: &NullContext<'input>) { + let result = ::visit_Null(self, ctx); + *::temp_result(self) = result; + } +} diff --git a/vendor/cel/src/parser/gen/mod.rs b/vendor/cel/src/parser/gen/mod.rs new file mode 100644 index 0000000..2890dbc --- /dev/null +++ b/vendor/cel/src/parser/gen/mod.rs @@ -0,0 +1,7 @@ +pub(crate) mod cellexer; +pub use cellexer::*; +mod cellistener; +mod celparser; +pub use celparser::*; +mod celvisitor; +pub use celvisitor::*; diff --git a/vendor/cel/src/parser/macros.rs b/vendor/cel/src/parser/macros.rs new file mode 100644 index 0000000..eaf7cf0 --- /dev/null +++ b/vendor/cel/src/parser/macros.rs @@ -0,0 +1,342 @@ +use crate::common::ast::{operators, CallExpr, ComprehensionExpr, Expr, IdedExpr, ListExpr}; +use crate::common::value::CelVal::{Boolean, Int}; +use crate::parser::{MacroExprHelper, ParseError}; + +pub type MacroExpander = fn( + helper: &mut MacroExprHelper, + target: Option, + args: Vec, +) -> Result; + +pub fn find_expander( + func_name: &str, + target: Option<&IdedExpr>, + args: &[IdedExpr], +) -> Option { + match func_name { + operators::HAS if args.len() == 1 && target.is_none() => Some(has_macro_expander), + operators::EXISTS if args.len() == 2 && target.is_some() => Some(exists_macro_expander), + operators::ALL if args.len() == 2 && target.is_some() => Some(all_macro_expander), + operators::EXISTS_ONE | "existsOne" if args.len() == 2 && target.is_some() => { + Some(exists_one_macro_expander) + } + operators::MAP if (args.len() == 2 || args.len() == 3) && target.is_some() => { + Some(map_macro_expander) + } + operators::FILTER if args.len() == 2 && target.is_some() => Some(filter_macro_expander), + _ => None, + } +} + +fn has_macro_expander( + helper: &mut MacroExprHelper, + target: Option, + mut args: Vec, +) -> Result { + if target.is_some() { + unreachable!("Got a target when expecting `None`!") + } + if args.len() != 1 { + unreachable!("Expected a single arg!") + } + + let ided_expr = args.remove(0); + match ided_expr.expr { + Expr::Select(mut select) => { + select.test = true; + Ok(helper.next_expr(Expr::Select(select))) + } + _ => Err(ParseError { + source: None, + pos: helper.pos_for(ided_expr.id).unwrap_or_default(), + msg: "invalid argument to has() macro".to_string(), + expr_id: 0, + source_info: None, + }), + } +} + +fn exists_macro_expander( + helper: &mut MacroExprHelper, + target: Option, + mut args: Vec, +) -> Result { + if target.is_none() { + unreachable!("Expected a target, but got `None`!") + } + if args.len() != 2 { + unreachable!("Expected two args!") + } + + let mut arguments = vec![args.remove(1)]; + let v = extract_ident(args.remove(0), helper)?; + + let init = helper.next_expr(Expr::Literal(Boolean(false))); + let result_binding = "@result".to_string(); + let accu_ident = helper.next_expr(Expr::Ident(result_binding.clone())); + let arg = helper.next_expr(Expr::Call(CallExpr { + func_name: operators::LOGICAL_NOT.to_string(), + target: None, + args: vec![accu_ident], + })); + let condition = helper.next_expr(Expr::Call(CallExpr { + func_name: operators::NOT_STRICTLY_FALSE.to_string(), + target: None, + args: vec![arg], + })); + + arguments.insert(0, helper.next_expr(Expr::Ident(result_binding.clone()))); + let step = helper.next_expr(Expr::Call(CallExpr { + func_name: operators::LOGICAL_OR.to_string(), + target: None, + args: arguments, + })); + + let result = helper.next_expr(Expr::Ident(result_binding.clone())); + + Ok( + helper.next_expr(Expr::Comprehension(Box::new(ComprehensionExpr { + iter_range: target.unwrap(), + iter_var: v, + iter_var2: None, + accu_var: result_binding, + accu_init: init, + loop_cond: condition, + loop_step: step, + result, + }))), + ) +} +fn all_macro_expander( + helper: &mut MacroExprHelper, + target: Option, + mut args: Vec, +) -> Result { + if target.is_none() { + unreachable!("Expected a target, but got `None`!") + } + if args.len() != 2 { + unreachable!("Expected two args!") + } + + let mut arguments = vec![args.remove(1)]; + let v = extract_ident(args.remove(0), helper)?; + + let init = helper.next_expr(Expr::Literal(Boolean(true))); + let result_binding = "@result".to_string(); + let accu_ident = helper.next_expr(Expr::Ident(result_binding.clone())); + let condition = helper.next_expr(Expr::Call(CallExpr { + func_name: operators::NOT_STRICTLY_FALSE.to_string(), + target: None, + args: vec![accu_ident], + })); + + arguments.insert(0, helper.next_expr(Expr::Ident(result_binding.clone()))); + let step = helper.next_expr(Expr::Call(CallExpr { + func_name: operators::LOGICAL_AND.to_string(), + target: None, + args: arguments, + })); + + let result = helper.next_expr(Expr::Ident(result_binding.clone())); + + Ok( + helper.next_expr(Expr::Comprehension(Box::new(ComprehensionExpr { + iter_range: target.unwrap(), + iter_var: v, + iter_var2: None, + accu_var: result_binding, + accu_init: init, + loop_cond: condition, + loop_step: step, + result, + }))), + ) +} + +fn exists_one_macro_expander( + helper: &mut MacroExprHelper, + target: Option, + mut args: Vec, +) -> Result { + if target.is_none() { + unreachable!("Expected a target, but got `None`!") + } + if args.len() != 2 { + unreachable!("Expected two args!") + } + + let mut arguments = vec![args.remove(1)]; + let v = extract_ident(args.remove(0), helper)?; + + let init = helper.next_expr(Expr::Literal(Int(0))); + let result_binding = "@result".to_string(); + let condition = helper.next_expr(Expr::Literal(Boolean(true))); + + let args = vec![ + helper.next_expr(Expr::Ident(result_binding.clone())), + helper.next_expr(Expr::Literal(Int(1))), + ]; + arguments.push(helper.next_expr(Expr::Call(CallExpr { + func_name: operators::ADD.to_string(), + target: None, + args, + }))); + arguments.push(helper.next_expr(Expr::Ident(result_binding.clone()))); + + let step = helper.next_expr(Expr::Call(CallExpr { + func_name: operators::CONDITIONAL.to_string(), + target: None, + args: arguments, + })); + + let accu = helper.next_expr(Expr::Ident(result_binding.clone())); + let one = helper.next_expr(Expr::Literal(Int(1))); + let result = helper.next_expr(Expr::Call(CallExpr { + func_name: operators::EQUALS.to_string(), + target: None, + args: vec![accu, one], + })); + + Ok( + helper.next_expr(Expr::Comprehension(Box::new(ComprehensionExpr { + iter_range: target.unwrap(), + iter_var: v, + iter_var2: None, + accu_var: result_binding, + accu_init: init, + loop_cond: condition, + loop_step: step, + result, + }))), + ) +} + +fn map_macro_expander( + helper: &mut MacroExprHelper, + target: Option, + mut args: Vec, +) -> Result { + if target.is_none() { + unreachable!("Expected a target, but got `None`!") + } + if args.len() != 2 && args.len() != 3 { + unreachable!("Expected two or three args!") + } + + let func = args.pop().unwrap(); + let v = extract_ident(args.remove(0), helper)?; + + let init = helper.next_expr(Expr::List(ListExpr { elements: vec![] })); + let result_binding = "@result".to_string(); + let condition = helper.next_expr(Expr::Literal(Boolean(true))); + + let filter = args.pop(); + + let args = vec![ + helper.next_expr(Expr::Ident(result_binding.clone())), + helper.next_expr(Expr::List(ListExpr { + elements: vec![func], + })), + ]; + let step = helper.next_expr(Expr::Call(CallExpr { + func_name: operators::ADD.to_string(), + target: None, + args, + })); + + let step = match filter { + Some(filter) => { + let accu = helper.next_expr(Expr::Ident(result_binding.clone())); + helper.next_expr(Expr::Call(CallExpr { + func_name: operators::CONDITIONAL.to_string(), + target: None, + args: vec![filter, step, accu], + })) + } + None => step, + }; + + let result = helper.next_expr(Expr::Ident(result_binding.clone())); + + Ok( + helper.next_expr(Expr::Comprehension(Box::new(ComprehensionExpr { + iter_range: target.unwrap(), + iter_var: v, + iter_var2: None, + accu_var: result_binding, + accu_init: init, + loop_cond: condition, + loop_step: step, + result, + }))), + ) +} + +fn filter_macro_expander( + helper: &mut MacroExprHelper, + target: Option, + mut args: Vec, +) -> Result { + if target.is_none() { + unreachable!("Expected a target, but got `None`!") + } + if args.len() != 2 { + unreachable!("Expected two args!") + } + + let var = args.remove(0); + let v = extract_ident(var.clone(), helper)?; + let filter = args.pop().unwrap(); + + let init = helper.next_expr(Expr::List(ListExpr { elements: vec![] })); + let result_binding = "@result".to_string(); + let condition = helper.next_expr(Expr::Literal(Boolean(true))); + + let args = vec![ + helper.next_expr(Expr::Ident(result_binding.clone())), + helper.next_expr(Expr::List(ListExpr { + elements: vec![var], + })), + ]; + let step = helper.next_expr(Expr::Call(CallExpr { + func_name: operators::ADD.to_string(), + target: None, + args, + })); + + let accu = helper.next_expr(Expr::Ident(result_binding.clone())); + let step = helper.next_expr(Expr::Call(CallExpr { + func_name: operators::CONDITIONAL.to_string(), + target: None, + args: vec![filter, step, accu], + })); + + let result = helper.next_expr(Expr::Ident(result_binding.clone())); + + Ok( + helper.next_expr(Expr::Comprehension(Box::new(ComprehensionExpr { + iter_range: target.unwrap(), + iter_var: v, + iter_var2: None, + accu_var: result_binding, + accu_init: init, + loop_cond: condition, + loop_step: step, + result, + }))), + ) +} + +fn extract_ident(expr: IdedExpr, helper: &mut MacroExprHelper) -> Result { + match expr.expr { + Expr::Ident(ident) => Ok(ident), + _ => Err(ParseError { + source: None, + pos: helper.pos_for(expr.id).unwrap_or_default(), + msg: "argument must be a simple name".to_string(), + expr_id: 0, + source_info: None, + }), + } +} diff --git a/vendor/cel/src/parser/mod.rs b/vendor/cel/src/parser/mod.rs new file mode 100644 index 0000000..85ab7d2 --- /dev/null +++ b/vendor/cel/src/parser/mod.rs @@ -0,0 +1,15 @@ +#![allow(clippy::module_inception)] +#[allow(clippy::all)] +mod gen; + +pub mod references; + +pub use crate::common::ast::IdedExpr as Expression; + +mod macros; +mod parse; +#[allow(non_snake_case)] +mod parser; + +pub use parser::*; +pub use references::ExpressionReferences; diff --git a/vendor/cel/src/parser/parse.rs b/vendor/cel/src/parser/parse.rs new file mode 100644 index 0000000..3c2b2cd --- /dev/null +++ b/vendor/cel/src/parser/parse.rs @@ -0,0 +1,531 @@ +use std::iter::Enumerate; +use std::num::ParseIntError; +use std::str::Chars; + +/// Error type of [unescape](unescape). +#[derive(Debug, PartialEq)] +pub enum ParseSequenceError { + // #[error("invalid escape {escape} at {index} in {string}")] + InvalidEscape { + escape: String, + index: usize, + string: String, + }, + // #[error("\\u could not be parsed at {index} in {string}: {source}")] + InvalidUnicode { + // #[source] + source: ParseUnicodeError, + index: usize, + string: String, + }, + MissingOpeningQuote, + MissingClosingQuote, +} + +/// Source error type of [ParseError::InvalidUnicode](ParseError::InvalidUnicode). +#[derive(Debug, PartialEq, Clone)] +pub enum ParseUnicodeError { + // #[error("could not parse {string} as u32 hex: {source}")] + Hex { + // #[source] + source: ParseIntError, + string: String, + }, + Oct { + // #[source] + source: ParseIntError, + string: String, + }, + // #[error("could not parse {value} as a unicode char")] + Unicode { + value: u32, + }, +} + +pub fn parse_bytes(s: &str) -> Result, ParseSequenceError> { + let mut chars = s.chars().enumerate(); + let mut res: Vec = Vec::with_capacity(s.len()); + + while let Some((idx, c)) = chars.next() { + if c == '\\' { + match chars.next() { + None => { + return Err(ParseSequenceError::InvalidEscape { + escape: format!("{c}"), + index: idx, + string: String::from(s), + }); + } + Some((idx, c2)) => { + let byte: u8 = match c2 { + 'x' => { + let hex: String = [ + chars + .next() + .ok_or(ParseSequenceError::InvalidEscape { + escape: "\\x".to_string(), + index: idx, + string: s.to_string(), + })? + .1, + chars + .next() + .ok_or(ParseSequenceError::InvalidEscape { + escape: "\\x".to_string(), + index: idx, + string: s.to_string(), + })? + .1, + ] + .iter() + .collect(); + u8::from_str_radix(&hex, 16).map_err(|_| { + ParseSequenceError::InvalidEscape { + escape: hex, + index: idx, + string: s.to_string(), + } + })? + } + n if ('0'..='3').contains(&n) => { + let octal: String = [ + n, + chars + .next() + .ok_or(ParseSequenceError::InvalidEscape { + escape: format!("\\{n}"), + index: idx, + string: s.to_string(), + })? + .1, + chars + .next() + .ok_or(ParseSequenceError::InvalidEscape { + escape: format!("\\{n}"), + index: idx, + string: s.to_string(), + })? + .1, + ] + .iter() + .collect(); + u8::from_str_radix(&octal, 8).map_err(|_| { + ParseSequenceError::InvalidEscape { + escape: octal, + index: idx, + string: s.to_string(), + } + })? + } + _ => { + return Err(ParseSequenceError::InvalidEscape { + escape: format!("{c}{c2}"), + index: idx, + string: String::from(s), + }); + } + }; + + res.push(byte); + continue; + } + }; + } + let size = c.len_utf8(); + let mut buffer = [0; 4]; + c.encode_utf8(&mut buffer); + res.extend_from_slice(&buffer[..size]); + } + Ok(res) +} + +/// Parse the provided quoted string. +/// This function was adopted from [snailquote](https://docs.rs/snailquote/latest/snailquote/). +/// +/// # Details +/// +/// Parses a single or double quoted string and interprets escape sequences such as +/// '\n', '\r', '\'', etc. +/// +/// Supports raw strings prefixed with `r` or `R` in which case all escape sequences are ignored./// +/// +/// The full set of supported escapes between quotes may be found below: +/// +/// | Escape | Code | Description | +/// |------------|------------|------------------------------------------| +/// | \a | 0x07 | Bell | +/// | \b | 0x08 | Backspace | +/// | \v | 0x0B | Vertical tab | +/// | \f | 0x0C | Form feed | +/// | \n | 0x0A | Newline | +/// | \r | 0x0D | Carriage return | +/// | \t | 0x09 | Tab | +/// | \\ | 0x5C | Backslash | +/// | \? | 0x?? | Question mark | +/// | \" | 0x22 | Double quote | +/// | \' | 0x27 | Single quote | +/// | \` | 0x60 | Backtick | +/// | \xDD | 0xDD | Unicode character with hex code DD | +/// | \uDDDD | 0xDDDD | Unicode character with hex code DDDD | +/// | \UDDDDDDDD | 0xDDDDDDDD | Unicode character with hex code DDDDDDDD | +/// | \DDD | 0DDD | Unicode character with octal code DDD | +/// +/// # Errors +/// +/// The returned result can display a human readable error if the string cannot be parsed as a +/// valid quoted string. +pub fn parse_string(s: &str) -> Result { + let mut chars = s.chars().enumerate(); + let res = String::with_capacity(s.len()); + + match chars.next() { + Some((_, c)) if c == 'r' || c == 'R' => parse_raw_string(&mut chars, res), + Some((_, c)) if c == '\'' || c == '"' => parse_quoted_string(s, &mut chars, res, c), + _ => Err(ParseSequenceError::MissingOpeningQuote), + } +} + +fn parse_raw_string( + chars: &mut Enumerate, + mut res: String, +) -> Result { + let mut in_single_quotes = false; + let mut in_double_quotes = false; + + while let Some((_, c)) = chars.next() { + let in_quotes = in_single_quotes || in_double_quotes; + + if c == '\\' && in_quotes { + match chars.next() { + Some((_, c2)) => { + match c2 { + '"' => { + if in_single_quotes { + res.push(c); + } + } + '\'' => { + if in_double_quotes { + res.push(c); + } + } + _ => { + res.push(c); + } + }; + res.push(c2); + continue; + } + _ => { + res.push(c); + continue; + } + }; + } else if c == '\'' { + if in_double_quotes { + res.push(c); + continue; + } + + in_single_quotes = !in_single_quotes; + continue; + } else if c == '"' { + if in_single_quotes { + res.push(c); + continue; + } + + in_double_quotes = !in_double_quotes; + continue; + } else if !in_quotes { + return Err(ParseSequenceError::MissingOpeningQuote); + } + + res.push(c); + } + + Ok(res) +} + +fn parse_quoted_string( + s: &str, + mut chars: &mut Enumerate, + mut res: String, + quote: char, +) -> Result { + let mut in_single_quotes = quote == '\''; + let mut in_double_quotes = quote == '"'; + + while let Some((idx, c)) = chars.next() { + let in_quotes = in_single_quotes || in_double_quotes; + + if c == '\\' && in_quotes { + match chars.next() { + None => { + return Err(ParseSequenceError::InvalidEscape { + escape: format!("{c}"), + index: idx, + string: String::from(s), + }); + } + Some((idx, c2)) => { + let mut push_escape_character = false; + + let value = match c2 { + 'a' => '\u{07}', + 'b' => '\u{08}', + 'v' => '\u{0B}', + 'f' => '\u{0C}', + 'n' => '\n', + 'r' => '\r', + 't' => '\t', + '\\' => c2, + '?' => c2, + '\'' => { + push_escape_character = in_double_quotes; + c2 + } + '"' => { + push_escape_character = in_single_quotes; + c2 + } + '`' => c2, + 'x' | 'u' | 'U' => { + let length = match c2 { + 'x' => 2, + 'u' => 4, + 'U' => 8, + _ => unreachable!(), + }; + + parse_unicode_hex(length, &mut chars).map_err(|x| { + ParseSequenceError::InvalidUnicode { + source: x.clone(), + index: idx, + string: String::from(s), + } + })? + } + n if ('0'..='3').contains(&n) => parse_unicode_oct(&n, &mut chars) + .map_err(|x| ParseSequenceError::InvalidUnicode { + source: x.clone(), + index: idx, + string: String::from(s), + })?, + _ => { + return Err(ParseSequenceError::InvalidEscape { + escape: format!("{c}{c2}"), + index: idx, + string: String::from(s), + }); + } + }; + + if push_escape_character { + res.push(c); + } + + res.push(value); + + continue; + } + }; + } else if c == '\'' { + if in_double_quotes { + res.push(c); + continue; + } + + in_single_quotes = !in_single_quotes; + continue; + } else if c == '"' { + if in_single_quotes { + res.push(c); + continue; + } + + in_double_quotes = !in_double_quotes; + continue; + } else if !in_quotes { + return Err(ParseSequenceError::MissingOpeningQuote); + } + + res.push(c); + } + + // Ensure string has a closing quote + if in_single_quotes || in_double_quotes { + return Err(ParseSequenceError::MissingClosingQuote); + } + + Ok(res) +} + +fn parse_unicode_hex(length: usize, chars: &mut I) -> Result +where + I: Iterator, +{ + let unicode_seq: String = chars.take(length).map(|(_, c)| c).collect(); + + u32::from_str_radix(&unicode_seq, 16) + .map_err(|e| ParseUnicodeError::Hex { + source: e, + string: unicode_seq, + }) + .and_then(|u| char::from_u32(u).ok_or(ParseUnicodeError::Unicode { value: u })) +} + +fn parse_unicode_oct(first_char: &char, chars: &mut I) -> Result +where + I: Iterator, +{ + let mut unicode_seq: String = String::with_capacity(3); + unicode_seq.push(*first_char); + chars.take(2).for_each(|(_, c)| unicode_seq.push(c)); + + u32::from_str_radix(&unicode_seq, 8) + .map_err(|e| ParseUnicodeError::Oct { + source: e, + string: unicode_seq, + }) + .and_then(|u| { + if u <= 255 { + char::from_u32(u).ok_or(ParseUnicodeError::Unicode { value: u }) + } else { + Err(ParseUnicodeError::Unicode { value: u }) + } + }) +} + +#[cfg(test)] +mod tests { + use super::{parse_bytes, parse_string, ParseSequenceError}; + + #[test] + fn single_quotes_interprets_escapes() { + let tests: Vec<(&str, Result)> = vec![ + ("'Hello \\a'", Ok(String::from("Hello \u{07}"))), + ("'Hello \\b'", Ok(String::from("Hello \u{08}"))), + ("'Hello \\v'", Ok(String::from("Hello \u{0b}"))), + ("'Hello \\f'", Ok(String::from("Hello \u{0c}"))), + ("'Hello \\n'", Ok(String::from("Hello \u{0a}"))), + ("'Hello \\r'", Ok(String::from("Hello \u{0d}"))), + ("'Hello \\t'", Ok(String::from("Hello \u{09}"))), + ("'Hello \\\\'", Ok(String::from("Hello \\"))), + ("'Hello \\?'", Ok(String::from("Hello ?"))), + ("'Hello \"'", Ok(String::from("Hello \""))), + ("'Hello \\''", Ok(String::from("Hello '"))), + ("'Hello \\`'", Ok(String::from("Hello `"))), + ("'Hello \\x20'", Ok(String::from("Hello "))), + ("'Hello \\u270c'", Ok(String::from("Hello ✌"))), + ("'Hello \\U0001f431'", Ok(String::from("Hello 🐱"))), + ("'Hello \\040'", Ok(String::from("Hello "))), + ( + "Missing closing quote'", + Err(ParseSequenceError::MissingOpeningQuote), + ), + ( + "'Missing closing quote", + Err(ParseSequenceError::MissingClosingQuote), + ), + // Testing octal value is out of range + ( + "'\\440'", + Err(ParseSequenceError::InvalidEscape { + escape: String::from("\\4"), + index: 2, + string: String::from("'\\440'"), + }), + ), + ]; + + for (s, expected) in tests { + let result = parse_string(s); + assert_eq!(result, expected); + } + } + + #[test] + fn double_quotes_interprets_escapes() { + let tests: Vec<(&str, Result)> = vec![ + ("\"Hello \\a\"", Ok(String::from("Hello \u{07}"))), + ("\"Hello \\b\"", Ok(String::from("Hello \u{08}"))), + ("\"Hello \\v\"", Ok(String::from("Hello \u{0b}"))), + ("\"Hello \\f\"", Ok(String::from("Hello \u{0c}"))), + ("\"Hello \\n\"", Ok(String::from("Hello \u{0a}"))), + ("\"Hello \\r\"", Ok(String::from("Hello \u{0d}"))), + ("\"Hello \\t\"", Ok(String::from("Hello \u{09}"))), + ("\"Hello \\\\\"", Ok(String::from("Hello \\"))), + ("\"Hello \\?\"", Ok(String::from("Hello ?"))), + ("\"Hello \\\"\"", Ok(String::from("Hello \""))), + ("\"Hello \\'\"", Ok(String::from("Hello \\'"))), + ("\"Hello \\`\"", Ok(String::from("Hello `"))), + ("\"Hello \\x20 \"", Ok(String::from("Hello "))), + ("\"Hello \\x60\"", Ok(String::from("Hello `"))), + ("\"Hello \\u270c\"", Ok(String::from("Hello ✌"))), + ("\"Hello \\U0001f431\"", Ok(String::from("Hello 🐱"))), + ("\"Hello \\040\"", Ok(String::from("Hello "))), + ( + "Missing closing quote\"", + Err(ParseSequenceError::MissingOpeningQuote), + ), + ( + "\"Missing closing quote", + Err(ParseSequenceError::MissingClosingQuote), + ), + // Testing octal value is out of range + ( + "\"\\440\"", + Err(ParseSequenceError::InvalidEscape { + escape: String::from("\\4"), + index: 2, + string: String::from("\"\\440\""), + }), + ), + ]; + + for (s, expected) in tests { + let result = parse_string(s); + assert_eq!(result, expected, "Testing {s}"); + } + } + + #[test] + fn raw_string_does_not_interpret_escapes() { + let tests: Vec<(&str, Result)> = vec![ + // Raw string in double quotes + // r"Hello \a \" ' \' \U0001f431 " => Hello \a " ' \' \U0001f431 + // R"Hello \a \" ' \' \U0001f431 " => Hello \a " ' \' \U0001f431 + ( + "r\"Hello \\a \\\" ' \\' \\U0001f431 \"", + Ok(String::from("Hello \\a \" ' \\' \\U0001f431 ")), + ), + ( + "R\"Hello \\a \\\" ' \\' \\U0001f431 \"", + Ok(String::from("Hello \\a \" ' \\' \\U0001f431 ")), + ), + // Raw string in single quotes + // r'Hello \a \" " \' \U0001f431 ' => Hello \a \" " ' \U0001f431 + // R'Hello \a \" " \' \U0001f431 ' => Hello \a \" " ' \U0001f431 + ( + "r'Hello \\a \\\" \" \\' \\U0001f431 '", + Ok(String::from("Hello \\a \\\" \" ' \\U0001f431 ")), + ), + ( + "R'Hello \\a \\\" \" \\' \\U0001f431 '", + Ok(String::from("Hello \\a \\\" \" ' \\U0001f431 ")), + ), + ]; + + for (s, expected) in tests { + let result = parse_string(s); + assert_eq!(result, expected, "Testing {s}"); + } + } + + #[test] + fn parses_bytes() { + let bytes = parse_bytes("abc💖\\xFF\\376").expect("Must parse!"); + assert_eq!([97, 98, 99, 240, 159, 146, 150, 255, 254], *bytes) + } +} diff --git a/vendor/cel/src/parser/parser.rs b/vendor/cel/src/parser/parser.rs new file mode 100644 index 0000000..e276700 --- /dev/null +++ b/vendor/cel/src/parser/parser.rs @@ -0,0 +1,1986 @@ +use crate::common::ast; +use crate::common::ast::{ + operators, CallExpr, EntryExpr, Expr, IdedEntryExpr, IdedExpr, ListExpr, MapEntryExpr, MapExpr, + SelectExpr, SourceInfo, StructExpr, StructFieldExpr, +}; +use crate::common::value::CelVal; +use crate::parser::gen::{ + BoolFalseContext, BoolTrueContext, BytesContext, CalcContext, CalcContextAttrs, + ConditionalAndContext, ConditionalOrContext, ConstantLiteralContext, + ConstantLiteralContextAttrs, CreateListContext, CreateMessageContext, CreateStructContext, + DoubleContext, ExprContext, FieldInitializerListContext, GlobalCallContext, IdentContext, + IndexContext, IndexContextAttrs, IntContext, ListInitContextAll, LogicalNotContext, + LogicalNotContextAttrs, MapInitializerListContextAll, MemberCallContext, + MemberCallContextAttrs, MemberExprContext, MemberExprContextAttrs, NegateContext, + NegateContextAttrs, NestedContext, NullContext, OptFieldContextAttrs, PrimaryExprContext, + PrimaryExprContextAttrs, RelationContext, RelationContextAttrs, SelectContext, + SelectContextAttrs, StartContext, StartContextAttrs, StringContext, UintContext, +}; +use crate::parser::{gen, macros, parse}; +use antlr4rust::common_token_stream::CommonTokenStream; +use antlr4rust::error_listener::ErrorListener; +use antlr4rust::errors::ANTLRError; +use antlr4rust::parser::ParserNodeType; +use antlr4rust::parser_rule_context::ParserRuleContext; +use antlr4rust::recognizer::Recognizer; +use antlr4rust::token::{CommonToken, Token}; +use antlr4rust::token_factory::TokenFactory; +use antlr4rust::tree::{ParseTree, ParseTreeVisitorCompat, VisitChildren}; +use antlr4rust::{InputStream, Parser as AntlrParser}; +use std::cell::RefCell; +use std::error::Error; +use std::fmt::Display; +use std::mem; +use std::ops::Deref; +use std::rc::Rc; +use std::sync::Arc; + +pub struct MacroExprHelper<'a> { + helper: &'a mut ParserHelper, + id: u64, +} + +impl MacroExprHelper<'_> { + pub fn next_expr(&mut self, expr: Expr) -> IdedExpr { + self.helper.next_expr_for(self.id, expr) + } + + pub(crate) fn pos_for(&self, id: u64) -> Option<(isize, isize)> { + self.helper.source_info.pos_for(id) + } +} + +#[derive(Debug)] +pub struct ParseErrors { + pub errors: Vec, +} + +impl Display for ParseErrors { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for (i, e) in self.errors.iter().enumerate() { + if i != 0 { + writeln!(f)?; + } + write!(f, "{e}")?; + } + Ok(()) + } +} + +impl Error for ParseErrors {} + +#[allow(dead_code)] +#[derive(Debug)] +pub struct ParseError { + pub source: Option>, + pub pos: (isize, isize), + pub msg: String, + pub expr_id: u64, + pub source_info: Option>, +} + +impl Display for ParseError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "ERROR: :{}:{}: {}", + self.pos.0, self.pos.1, self.msg + )?; + if let Some(info) = &self.source_info { + if let Some(line) = info.snippet(self.pos.0 - 1) { + write!(f, "\n| {line}")?; + write!(f, "\n| {:.>width$}", "^", width = self.pos.1 as usize)?; + } + } + Ok(()) + } +} + +impl Error for ParseError {} + +pub struct Parser { + ast: ast::Ast, + helper: ParserHelper, + errors: Vec, +} + +impl Parser { + pub fn new() -> Self { + Self { + ast: ast::Ast { + expr: IdedExpr::default(), + }, + helper: ParserHelper::default(), + errors: Vec::default(), + } + } + + fn new_logic_manager(&self, func: &str, term: IdedExpr) -> LogicManager { + LogicManager { + function: func.to_string(), + terms: vec![term], + ops: vec![], + } + } + + fn global_call_or_macro( + &mut self, + id: u64, + func_name: String, + args: Vec, + ) -> IdedExpr { + match macros::find_expander(&func_name, None, &args) { + None => IdedExpr { + id, + expr: Expr::Call(CallExpr { + target: None, + func_name, + args, + }), + }, + Some(expander) => { + let mut helper = MacroExprHelper { + helper: &mut self.helper, + id, + }; + match expander(&mut helper, None, args) { + Ok(expr) => expr, + Err(err) => self.report_parse_error(None, err), + } + } + } + } + + fn receiver_call_or_macro( + &mut self, + id: u64, + func_name: String, + target: IdedExpr, + args: Vec, + ) -> IdedExpr { + match macros::find_expander(&func_name, Some(&target), &args) { + None => IdedExpr { + id, + expr: Expr::Call(CallExpr { + target: Some(Box::new(target)), + func_name, + args, + }), + }, + Some(expander) => { + let mut helper = MacroExprHelper { + helper: &mut self.helper, + id, + }; + match expander(&mut helper, Some(target), args) { + Ok(expr) => expr, + Err(err) => self.report_parse_error(None, err), + } + } + } + } + + pub fn parse(mut self, source: &str) -> Result { + let source = source.trim(); + let parse_errors = Rc::new(RefCell::new(Vec::::new())); + let stream = InputStream::new(source); + let mut lexer = gen::CELLexer::new(stream); + lexer.remove_error_listeners(); + lexer.add_error_listener(Box::new(ParserErrorListener { + parse_errors: parse_errors.clone(), + })); + + // todo! might want to avoid this cloning here... + self.helper.source_info.source = source.into(); + + let mut prsr = gen::CELParser::new(CommonTokenStream::new(lexer)); + prsr.remove_error_listeners(); + prsr.add_error_listener(Box::new(ParserErrorListener { + parse_errors: parse_errors.clone(), + })); + let r = match prsr.start() { + Ok(t) => Ok(self.visit(t.deref())), + Err(e) => Err(ParseError { + source: Some(Box::new(e)), + pos: (0, 0), + msg: "UNKNOWN".to_string(), + expr_id: 0, + source_info: None, + }), + }; + + let info = self.helper.source_info; + let source_info = Arc::new(info); + + let mut errors = parse_errors.take(); + errors.extend(self.errors); + errors.sort_by(|a, b| a.pos.cmp(&b.pos)); + + if errors.is_empty() { + r.map_err(|e| ParseErrors { errors: vec![e] }) + } else { + Err(ParseErrors { + errors: errors + .into_iter() + .map(|mut e: ParseError| { + e.source_info = Some(source_info.clone()); + e + }) + .collect(), + }) + } + } + + fn field_initializer_list( + &mut self, + ctx: &FieldInitializerListContext<'_>, + ) -> Vec { + let mut fields = Vec::with_capacity(ctx.fields.len()); + for (i, field) in ctx.fields.iter().enumerate() { + if i >= ctx.cols.len() || i >= ctx.values.len() { + return vec![]; + } + let id = self.helper.next_id(&ctx.cols[i]); + + match field.escapeIdent() { + None => { + self.report_error::( + field.start().deref(), + None, + "unsupported ident type", + ); + continue; + } + Some(ident) => { + let field_name = ident.get_text().to_string(); + let value = self.visit(ctx.values[i].as_ref()); + if let Some(opt) = &field.opt { + self.report_error::( + opt.as_ref(), + None, + "unsupported syntax '?'", + ); + continue; + } + fields.push(IdedEntryExpr { + id, + expr: EntryExpr::StructField(StructFieldExpr { + field: field_name, + value, + optional: false, + }), + }); + } + } + } + fields + } + + fn map_initializer_list(&mut self, ctx: &MapInitializerListContextAll) -> Vec { + if ctx.keys.is_empty() { + return vec![]; + } + let mut entries = Vec::with_capacity(ctx.cols.len()); + let keys = &ctx.keys; + let vals = &ctx.values; + for (i, col) in ctx.cols.iter().enumerate() { + if i >= keys.len() || i >= vals.len() { + return vec![]; + } + let id = self.helper.next_id(col); + let key = self.visit(keys[i].as_ref()); + if let Some(opt) = &keys[i].opt { + self.report_error::(opt.as_ref(), None, "unsupported syntax '?'"); + continue; + } + let value = self.visit(vals[i].as_ref()); + entries.push(IdedEntryExpr { + id, + expr: EntryExpr::MapEntry(MapEntryExpr { + key, + value, + optional: false, + }), + }) + } + entries + } + + fn list_initializer_list(&mut self, ctx: &ListInitContextAll) -> Vec { + let mut list = Vec::default(); + for e in &ctx.elems { + match &e.e { + None => return Vec::default(), + Some(exp) => { + if let Some(opt) = &e.opt { + self.report_error::( + opt.as_ref(), + None, + "unsupported syntax '?'", + ); + continue; + } + list.push(self.visit(exp.as_ref())); + } + } + } + list + } + + fn report_error>( + &mut self, + token: &CommonToken, + e: Option, + s: S, + ) -> IdedExpr { + let error = ParseError { + source: e.map(|e| e.into()), + pos: (token.line, token.column + 1), + msg: s.into(), + expr_id: 0, + source_info: None, + }; + self.report_parse_error(Some(token), error) + } + + fn report_parse_error(&mut self, token: Option<&CommonToken>, mut e: ParseError) -> IdedExpr { + let expr = if let Some(token) = token { + self.helper.next_expr(token, Expr::default()) + } else { + IdedExpr { + id: 0, + expr: Expr::default(), + } + }; + e.expr_id = expr.id; + self.errors.push(e); + expr + } +} + +struct ParserErrorListener { + parse_errors: Rc>>, +} + +impl<'a, T: Recognizer<'a>> ErrorListener<'a, T> for ParserErrorListener { + fn syntax_error( + &self, + _recognizer: &T, + _offending_symbol: Option<&>::Inner>, + line: isize, + column: isize, + msg: &str, + _error: Option<&ANTLRError>, + ) { + self.parse_errors.borrow_mut().push(ParseError { + source: None, + pos: (line, column + 1), + msg: format!("Syntax error: {msg}"), + expr_id: 0, + source_info: None, + }) + } +} + +impl Default for Parser { + fn default() -> Self { + Self::new() + } +} + +impl ParseTreeVisitorCompat<'_> for Parser { + type Node = gen::CELParserContextType; + type Return = IdedExpr; + fn temp_result(&mut self) -> &mut Self::Return { + &mut self.ast.expr + } + + fn visit(&mut self, node: &>::Type) -> Self::Return { + //println!("{node:?}"); + self.visit_node(node); + mem::take(self.temp_result()) + } + + fn aggregate_results(&self, _aggregate: Self::Return, next: Self::Return) -> Self::Return { + next + } +} + +impl gen::CELVisitorCompat<'_> for Parser { + fn visit_start(&mut self, ctx: &StartContext<'_>) -> Self::Return { + match &ctx.expr() { + None => self.report_error::( + ctx.start().deref(), + None, + "No `ExprContextAll`!", + ), + Some(expr) => self.visit(expr.as_ref()), + } + } + + fn visit_expr(&mut self, ctx: &ExprContext<'_>) -> Self::Return { + match &ctx.op { + None => match &ctx.e { + None => self.report_error::( + ctx.start().deref(), + None, + "No `ConditionalOrContextAll`!", + ), + Some(e) => ::visit(self, e.as_ref()), + }, + Some(op) => { + if let (Some(e), Some(e1), Some(e2)) = (&ctx.e, &ctx.e1, &ctx.e2) { + let result = self.visit(e.as_ref()); + let op_id = self.helper.next_id(op); + let if_true = self.visit(e1.as_ref()); + let if_false = self.visit(e2.as_ref()); + self.global_call_or_macro( + op_id, + operators::CONDITIONAL.to_string(), + vec![result, if_true, if_false], + ) + } else { + self.report_error::( + ctx.start().deref(), + None, + format!( + "Incomplete `ExprContext` for `{}` expression!", + operators::CONDITIONAL + ), + ) + } + } + } + } + + fn visit_conditionalOr(&mut self, ctx: &ConditionalOrContext<'_>) -> Self::Return { + let result = match &ctx.e { + None => { + self.report_error::( + ctx.start().deref(), + None, + "No `ConditionalAndContextAll`!", + ); + IdedExpr::default() + } + Some(e) => ::visit(self, e.as_ref()), + }; + if ctx.ops.is_empty() { + result + } else { + let mut l = self.new_logic_manager(operators::LOGICAL_OR, result); + let rest = &ctx.e1; + if ctx.ops.len() > rest.len() { + // why is >= not ok? + self.report_error::( + &ctx.start(), + None, + "unexpected character, wanted '||'", + ); + return IdedExpr::default(); + } + for (i, op) in ctx.ops.iter().enumerate() { + let next = self.visit(rest[i].deref()); + let op_id = self.helper.next_id(op); + l.add_term(op_id, next) + } + l.expr() + } + } + + fn visit_conditionalAnd(&mut self, ctx: &ConditionalAndContext<'_>) -> Self::Return { + let result = match &ctx.e { + None => self.report_error::( + ctx.start().deref(), + None, + "No `RelationContextAll`!", + ), + Some(e) => ::visit(self, e.as_ref()), + }; + if ctx.ops.is_empty() { + result + } else { + let mut l = self.new_logic_manager(operators::LOGICAL_AND, result); + let rest = &ctx.e1; + if ctx.ops.len() > rest.len() { + // why is >= not ok? + self.report_error::( + &ctx.start(), + None, + "unexpected character, wanted '&&'", + ); + return IdedExpr::default(); + } + for (i, op) in ctx.ops.iter().enumerate() { + let next = self.visit(rest[i].deref()); + let op_id = self.helper.next_id(op); + l.add_term(op_id, next) + } + l.expr() + } + } + + fn visit_relation(&mut self, ctx: &RelationContext<'_>) -> Self::Return { + if ctx.op.is_none() { + match ctx.calc() { + None => self.report_error::( + ctx.start().deref(), + None, + "No `CalcContextAll`!", + ), + Some(calc) => ::visit(self, calc.as_ref()), + } + } else { + match &ctx.op { + None => ::visit_children(self, ctx), + Some(op) => { + if let (Some(lhs), Some(rhs)) = (ctx.relation(0), ctx.relation(1)) { + let lhs = self.visit(lhs.as_ref()); + let op_id = self.helper.next_id(op.as_ref()); + let rhs = self.visit(rhs.as_ref()); + match operators::find_operator(op.get_text()) { + None => { + self.report_error::( + op.as_ref(), + None, + format!("Unknown `{}` operator!", op.get_text()), + ); + IdedExpr::default() + } + Some(op) => { + self.global_call_or_macro(op_id, op.to_string(), vec![lhs, rhs]) + } + } + } else { + self.report_error::( + ctx.start().deref(), + None, + format!("Incomplete `RelationContext` for `{:?}`!", ctx.op), + ) + } + } + } + } + } + + fn visit_calc(&mut self, ctx: &CalcContext<'_>) -> Self::Return { + match &ctx.op { + None => match &ctx.unary() { + None => self.report_error::( + ctx.start().deref(), + None, + "No `UnaryContextAll`!", + ), + Some(unary) => self.visit(unary.as_ref()), + }, + Some(op) => { + if let (Some(lhs), Some(rhs)) = (ctx.calc(0), ctx.calc(1)) { + let lhs = self.visit(lhs.as_ref()); + let op_id = self.helper.next_id(op); + let rhs = self.visit(rhs.as_ref()); + match operators::find_operator(op.get_text()) { + None => self.report_error::( + op, + None, + format!("Unknown `{}` operator!", op.get_text()), + ), + Some(op) => { + self.global_call_or_macro(op_id, op.to_string(), vec![lhs, rhs]) + } + } + } else { + self.report_error::( + ctx.start().deref(), + None, + "Incomplete `CalcContext`!", + ) + } + } + } + } + + fn visit_MemberExpr(&mut self, ctx: &MemberExprContext<'_>) -> Self::Return { + match &ctx.member() { + None => { + self.report_error::(&ctx.start(), None, "No `MemberContextAll`!") + } + Some(ctx) => ::visit(self, ctx.as_ref()), + } + } + + fn visit_LogicalNot(&mut self, ctx: &LogicalNotContext<'_>) -> Self::Return { + match &ctx.member() { + None => { + self.report_error::(&ctx.start(), None, "No `MemberContextAll`!"); + IdedExpr::default() + } + Some(member) => { + if ctx.ops.len().is_multiple_of(2) { + self.visit(member.as_ref()); + } + let op_id = self.helper.next_id(&ctx.ops[0]); + let target = self.visit(member.as_ref()); + self.global_call_or_macro(op_id, operators::LOGICAL_NOT.to_string(), vec![target]) + } + } + } + + fn visit_Negate(&mut self, ctx: &NegateContext<'_>) -> Self::Return { + match &ctx.member() { + None => { + self.report_error::(&ctx.start(), None, "No `MemberContextAll`!") + } + Some(member) => { + if ctx.ops.len().is_multiple_of(2) { + self.visit(member.as_ref()); + } + let op_id = self.helper.next_id(&ctx.ops[0]); + let target = self.visit(member.as_ref()); + self.global_call_or_macro(op_id, operators::NEGATE.to_string(), vec![target]) + } + } + } + + fn visit_MemberCall(&mut self, ctx: &MemberCallContext<'_>) -> Self::Return { + if let (Some(operand), Some(id), Some(open)) = (&ctx.member(), &ctx.id, &ctx.open) { + let operand = self.visit(operand.as_ref()); + let id = id.get_text(); + let op_id = self.helper.next_id(open.as_ref()); + let args = ctx + .args + .iter() + .flat_map(|arg| &arg.e) + .map(|arg| self.visit(arg.deref())) + .collect::>(); + self.receiver_call_or_macro(op_id, id.to_string(), operand, args) + } else { + self.report_error::( + &ctx.start(), + None, + "Incomplete `MemberCallContext`!", + ) + } + } + + fn visit_Select(&mut self, ctx: &SelectContext<'_>) -> Self::Return { + if let (Some(member), Some(id), Some(op)) = (&ctx.member(), &ctx.id, &ctx.op) { + let operand = self.visit(member.as_ref()); + let field = id.get_text(); + if let Some(_opt) = &ctx.opt { + return self.report_error::( + op.as_ref(), + None, + "unsupported syntax '.?'", + ); + } + self.helper.next_expr( + op.as_ref(), + Expr::Select(SelectExpr { + operand: Box::new(operand), + field, + test: false, + }), + ) + } else { + self.report_error::(&ctx.start(), None, "Incomplete `SelectContext`!") + } + } + + fn visit_PrimaryExpr(&mut self, ctx: &PrimaryExprContext<'_>) -> Self::Return { + match &ctx.primary() { + None => { + self.report_error::(&ctx.start(), None, "No `PrimaryContextAll`!") + } + Some(primary) => ::visit(self, primary.as_ref()), + } + } + + fn visit_Index(&mut self, ctx: &IndexContext<'_>) -> Self::Return { + if let (Some(member), Some(index)) = (&ctx.member(), &ctx.index) { + let target = self.visit(member.as_ref()); + match &ctx.op { + None => self.report_error::(&ctx.start(), None, "No `Index`!"), + Some(op) => { + let op_id = self.helper.next_id(op); + let index = self.visit(index.as_ref()); + if let Some(_opt) = &ctx.opt { + return self.report_error::( + op.as_ref(), + None, + "unsupported syntax '[?'", + ); + } + self.global_call_or_macro( + op_id, + operators::INDEX.to_string(), + vec![target, index], + ) + } + } + } else { + self.report_error::(&ctx.start(), None, "Incomplete `IndexContext`!") + } + } + + fn visit_Ident(&mut self, ctx: &IdentContext<'_>) -> Self::Return { + match &ctx.id { + None => { + self.report_error::(&ctx.start(), None, "No `Identifier`!"); + IdedExpr::default() + } + Some(id) => { + let ident = id.clone().text; + self.helper + .next_expr(id.deref(), Expr::Ident(ident.to_string())) + } + } + } + + fn visit_GlobalCall(&mut self, ctx: &GlobalCallContext<'_>) -> Self::Return { + match &ctx.id { + None => IdedExpr::default(), + Some(id) => { + let mut id = id.get_text().to_string(); + if ctx.leadingDot.is_some() { + id = format!(".{id}"); + } + let op_id = self.helper.next_id_for_token(ctx.op.as_deref()); + let args = ctx + .args + .iter() + .flat_map(|arg| &arg.e) + .map(|arg| self.visit(arg.deref())) + .collect::>(); + self.global_call_or_macro(op_id, id, args) + } + } + } + + fn visit_Nested(&mut self, ctx: &NestedContext<'_>) -> Self::Return { + match &ctx.e { + None => { + self.report_error::( + ctx.start().deref(), + None, + "No `ExprContextAll`!", + ); + IdedExpr::default() + } + Some(e) => self.visit(e.as_ref()), + } + } + + fn visit_CreateList(&mut self, ctx: &CreateListContext<'_>) -> Self::Return { + let list_id = self.helper.next_id_for_token(ctx.op.as_deref()); + let elements = match &ctx.elems { + None => Vec::default(), + Some(elements) => self.list_initializer_list(elements.deref()), + }; + IdedExpr { + id: list_id, + expr: Expr::List(ListExpr { elements }), + } + } + + fn visit_CreateStruct(&mut self, ctx: &CreateStructContext<'_>) -> Self::Return { + let struct_id = self.helper.next_id_for_token(ctx.op.as_deref()); + let entries = match &ctx.entries { + Some(entries) => self.map_initializer_list(entries.deref()), + None => Vec::default(), + }; + IdedExpr { + id: struct_id, + expr: Expr::Map(MapExpr { entries }), + } + } + + fn visit_CreateMessage(&mut self, ctx: &CreateMessageContext<'_>) -> Self::Return { + let mut message_name = String::new(); + for id in &ctx.ids { + if !message_name.is_empty() { + message_name.push('.'); + } + message_name.push_str(id.get_text()); + } + if ctx.leadingDot.is_some() { + message_name = format!(".{message_name}"); + } + let op_id = match &ctx.op { + None => { + self.report_error::(&ctx.start(), None, "No `CommonToken`!"); + return IdedExpr::default(); + } + Some(op) => self.helper.next_id(op.as_ref()), + }; + let entries = match &ctx.entries { + None => vec![], + Some(entries) => self.field_initializer_list(entries), + }; + IdedExpr { + id: op_id, + expr: Expr::Struct(StructExpr { + type_name: message_name, + entries, + }), + } + } + + fn visit_ConstantLiteral(&mut self, ctx: &ConstantLiteralContext<'_>) -> Self::Return { + ::visit( + self, + ctx.literal().as_deref().expect("Has to have literal!"), + ) + } + + fn visit_Int(&mut self, ctx: &IntContext<'_>) -> Self::Return { + let string = ctx.get_text(); + let token = ctx.tok.as_ref().expect("Has to have int!"); + let val = match if let Some(string) = string.strip_prefix("0x") { + i64::from_str_radix(string, 16) + } else { + string.parse::() + } { + Ok(v) => v, + Err(e) => return self.report_error(token, Some(e), "invalid int literal"), + }; + self.helper + .next_expr(token, Expr::Literal(CelVal::Int(val))) + } + + fn visit_Uint(&mut self, ctx: &UintContext<'_>) -> Self::Return { + let mut string = ctx.get_text(); + string.truncate(string.len() - 1); + let token = ctx.tok.as_ref().expect("Has to have uint!"); + let val = match if let Some(string) = string.strip_prefix("0x") { + u64::from_str_radix(string, 16) + } else { + string.parse::() + } { + Ok(v) => v, + Err(e) => return self.report_error(token, Some(e), "invalid uint literal"), + }; + self.helper + .next_expr(token, Expr::Literal(CelVal::UInt(val))) + } + + fn visit_Double(&mut self, ctx: &DoubleContext<'_>) -> Self::Return { + let string = ctx.get_text(); + let token = ctx.tok.as_ref().expect("Has to have double!"); + match string.parse::() { + Ok(d) if d.is_finite() => self + .helper + .next_expr(token, Expr::Literal(CelVal::Double(d))), + Err(e) => self.report_error(token, Some(e), "invalid double literal"), + _ => self.report_error(token, None::, "invalid double literal"), + } + } + + fn visit_String(&mut self, ctx: &StringContext<'_>) -> Self::Return { + let token = ctx.tok.as_deref().expect("Has to have string!"); + match parse::parse_string(&ctx.get_text()) { + Ok(string) => self + .helper + .next_expr(token, Expr::Literal(CelVal::String(string))), + Err(e) => self.report_error::( + token, + None, + format!("invalid string literal: {e:?}"), + ), + } + } + + fn visit_Bytes(&mut self, ctx: &BytesContext<'_>) -> Self::Return { + let token = ctx.tok.as_deref().expect("Has to have bytes!"); + let string = ctx.get_text(); + match parse::parse_bytes(&string[2..string.len() - 1]) { + Ok(bytes) => self + .helper + .next_expr(token, Expr::Literal(CelVal::Bytes(bytes))), + Err(e) => { + self.report_error::( + token, + None, + format!("invalid bytes literal: {e:?}"), + ); + IdedExpr::default() + } + } + } + + fn visit_BoolTrue(&mut self, ctx: &BoolTrueContext<'_>) -> Self::Return { + self.helper.next_expr( + ctx.tok.as_deref().expect("Has to be `true`!"), + Expr::Literal(CelVal::Boolean(true)), + ) + } + + fn visit_BoolFalse(&mut self, ctx: &BoolFalseContext<'_>) -> Self::Return { + self.helper.next_expr( + ctx.tok.as_deref().expect("Has to be `false`!"), + Expr::Literal(CelVal::Boolean(false)), + ) + } + + fn visit_Null(&mut self, ctx: &NullContext<'_>) -> Self::Return { + self.helper.next_expr( + ctx.tok.as_deref().expect("Has to be `null`!"), + Expr::Literal(CelVal::Null), + ) + } +} + +pub struct ParserHelper { + source_info: SourceInfo, + next_id: u64, +} + +impl Default for ParserHelper { + fn default() -> Self { + Self { + source_info: SourceInfo::default(), + next_id: 1, + } + } +} + +impl ParserHelper { + fn next_id(&mut self, token: &CommonToken) -> u64 { + let id = self.next_id; + self.source_info + .add_offset(id, token.start as u32, token.stop as u32); + self.next_id += 1; + id + } + + fn next_id_for_token(&mut self, token: Option<&CommonToken>) -> u64 { + match token { + None => 0, + Some(token) => self.next_id(token), + } + } + + fn next_id_for(&mut self, id: u64) -> u64 { + let (start, stop) = self.source_info.offset_for(id).expect("invalid offset"); + let id = self.next_id; + self.source_info.add_offset(id, start, stop); + self.next_id += 1; + id + } + + pub fn next_expr(&mut self, token: &CommonToken, expr: Expr) -> IdedExpr { + IdedExpr { + id: self.next_id(token), + expr, + } + } + + pub fn next_expr_for(&mut self, id: u64, expr: Expr) -> IdedExpr { + IdedExpr { + id: self.next_id_for(id), + expr, + } + } +} + +struct LogicManager { + function: String, + terms: Vec, + ops: Vec, +} + +impl LogicManager { + pub(crate) fn expr(mut self) -> IdedExpr { + if self.terms.len() == 1 { + self.terms.pop().expect("expected at least one term") + } else { + self.balanced_tree(0, self.ops.len() - 1) + } + } + + pub(crate) fn add_term(&mut self, op_id: u64, expr: IdedExpr) { + self.terms.push(expr); + self.ops.push(op_id); + } + + fn balanced_tree(&mut self, lo: usize, hi: usize) -> IdedExpr { + let mid = (lo + hi).div_ceil(2); + + let left = if mid == lo { + mem::take(&mut self.terms[mid]) + } else { + self.balanced_tree(lo, mid - 1) + }; + + let right = if mid == hi { + mem::take(&mut self.terms[mid + 1]) + } else { + self.balanced_tree(mid + 1, hi) + }; + + IdedExpr { + id: self.ops[mid], + expr: Expr::Call(CallExpr { + target: None, + func_name: self.function.clone(), + args: vec![left, right], + }), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::common::ast::{ComprehensionExpr, EntryExpr, Expr}; + use crate::IdedExpr; + use std::iter; + + struct TestInfo { + // I contains the input expression to be parsed. + i: &'static str, + + // P contains the type/id adorned debug output of the expression tree. + p: &'static str, + + // E contains the expected error output for a failed parse, or "" if the parse is expected to be successful. + e: &'static str, + // L contains the expected source adorned debug output of the expression tree. + // l: String, + + // M contains the expected adorned debug output of the macro calls map + // m: String, + + // Opts contains the list of options to be configured with the parser before parsing the expression. + // Opts []Option + } + + #[test] + fn test_bad_input() { + let expressions = [ + "1 + ()", "/", ".", "@foo", "x(1,)", "\x0a", "\n", "", "!-\u{1}", + ]; + for expr in expressions { + assert!( + Parser::new().parse(expr).is_err(), + "Expression `{}` should not parse", + expr + ); + } + } + + #[test] + fn test() { + let test_cases = [ + TestInfo { + i: r#""A""#, + p: r#""A"^#1:*expr.Constant_StringValue#"#, + e: "", + }, + TestInfo { + i: r#"true"#, + p: r#"true^#1:*expr.Constant_BoolValue#"#, + e: "", + }, + TestInfo { + i: r#"false"#, + p: r#"false^#1:*expr.Constant_BoolValue#"#, + e: "", + }, + TestInfo { + i: "0", + p: "0^#1:*expr.Constant_Int64Value#", + e: "", + }, + TestInfo { + i: "42", + p: "42^#1:*expr.Constant_Int64Value#", + e: "", + }, + TestInfo { + i: "0xF", + p: "15^#1:*expr.Constant_Int64Value#", + e: "", + }, + TestInfo { + i: "0u", + p: "0u^#1:*expr.Constant_Uint64Value#", + e: "", + }, + TestInfo { + i: "23u", + p: "23u^#1:*expr.Constant_Uint64Value#", + e: "", + }, + TestInfo { + i: "24u", + p: "24u^#1:*expr.Constant_Uint64Value#", + e: "", + }, + TestInfo { + i: "0xFu", + p: "15u^#1:*expr.Constant_Uint64Value#", + e: "", + }, + TestInfo { + i: "-1", + p: "-1^#1:*expr.Constant_Int64Value#", + e: "", + }, + TestInfo { + i: "4--4", + p: r#"_-_( + 4^#1:*expr.Constant_Int64Value#, + -4^#3:*expr.Constant_Int64Value# +)^#2:*expr.Expr_CallExpr#"#, + e: "", + }, + TestInfo { + i: "4--4.1", + p: r#"_-_( + 4^#1:*expr.Constant_Int64Value#, + -4.1^#3:*expr.Constant_DoubleValue# +)^#2:*expr.Expr_CallExpr#"#, + e: "", + }, + TestInfo { + i: r#"b"abc""#, + p: r#"b"abc"^#1:*expr.Constant_BytesValue#"#, + e: "", + }, + TestInfo { + i: "23.39", + p: "23.39^#1:*expr.Constant_DoubleValue#", + e: "", + }, + TestInfo { + i: "!a", + p: "!_( + a^#2:*expr.Expr_IdentExpr# +)^#1:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "null", + p: "null^#1:*expr.Constant_NullValue#", + e: "", + }, + TestInfo { + i: "a", + p: "a^#1:*expr.Expr_IdentExpr#", + e: "", + }, + TestInfo { + i: "a?b:c", + p: "_?_:_( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr#, + c^#4:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a || b", + p: "_||_( + a^#1:*expr.Expr_IdentExpr#, + b^#2:*expr.Expr_IdentExpr# +)^#3:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a || b || c || d || e || f ", + p: "_||_( + _||_( + _||_( + a^#1:*expr.Expr_IdentExpr#, + b^#2:*expr.Expr_IdentExpr# + )^#3:*expr.Expr_CallExpr#, + c^#4:*expr.Expr_IdentExpr# + )^#5:*expr.Expr_CallExpr#, + _||_( + _||_( + d^#6:*expr.Expr_IdentExpr#, + e^#8:*expr.Expr_IdentExpr# + )^#9:*expr.Expr_CallExpr#, + f^#10:*expr.Expr_IdentExpr# + )^#11:*expr.Expr_CallExpr# +)^#7:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a && b", + p: "_&&_( + a^#1:*expr.Expr_IdentExpr#, + b^#2:*expr.Expr_IdentExpr# +)^#3:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a && b && c && d && e && f && g", + p: "_&&_( + _&&_( + _&&_( + a^#1:*expr.Expr_IdentExpr#, + b^#2:*expr.Expr_IdentExpr# + )^#3:*expr.Expr_CallExpr#, + _&&_( + c^#4:*expr.Expr_IdentExpr#, + d^#6:*expr.Expr_IdentExpr# + )^#7:*expr.Expr_CallExpr# + )^#5:*expr.Expr_CallExpr#, + _&&_( + _&&_( + e^#8:*expr.Expr_IdentExpr#, + f^#10:*expr.Expr_IdentExpr# + )^#11:*expr.Expr_CallExpr#, + g^#12:*expr.Expr_IdentExpr# + )^#13:*expr.Expr_CallExpr# +)^#9:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a && b && c && d || e && f && g && h", + p: "_||_( + _&&_( + _&&_( + a^#1:*expr.Expr_IdentExpr#, + b^#2:*expr.Expr_IdentExpr# + )^#3:*expr.Expr_CallExpr#, + _&&_( + c^#4:*expr.Expr_IdentExpr#, + d^#6:*expr.Expr_IdentExpr# + )^#7:*expr.Expr_CallExpr# + )^#5:*expr.Expr_CallExpr#, + _&&_( + _&&_( + e^#8:*expr.Expr_IdentExpr#, + f^#9:*expr.Expr_IdentExpr# + )^#10:*expr.Expr_CallExpr#, + _&&_( + g^#11:*expr.Expr_IdentExpr#, + h^#13:*expr.Expr_IdentExpr# + )^#14:*expr.Expr_CallExpr# + )^#12:*expr.Expr_CallExpr# +)^#15:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a + b", + p: "_+_( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a - b", + p: "_-_( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a * b", + p: "_*_( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a / b", + p: "_/_( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a % b", + p: "_%_( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a in b", + p: "@in( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a == b", + p: "_==_( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a != b", + p: "_!=_( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a > b", + p: "_>_( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a >= b", + p: "_>=_( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a < b", + p: "_<_( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a <= b", + p: "_<=_( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a.b", + p: "a^#1:*expr.Expr_IdentExpr#.b^#2:*expr.Expr_SelectExpr#", + e: "", + }, + TestInfo { + i: "a.b.c", + p: "a^#1:*expr.Expr_IdentExpr#.b^#2:*expr.Expr_SelectExpr#.c^#3:*expr.Expr_SelectExpr#", + e: "", + }, + TestInfo { + i: "a[b]", + p: "_[_]( + a^#1:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "(a)", + p: "a^#1:*expr.Expr_IdentExpr#", + e: "", + }, + TestInfo { + i: "((a))", + p: "a^#1:*expr.Expr_IdentExpr#", + e: "", + }, + TestInfo { + i: "a()", + p: "a()^#1:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a(b)", + p: "a( + b^#2:*expr.Expr_IdentExpr# +)^#1:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a(b, c)", + p: "a( + b^#2:*expr.Expr_IdentExpr#, + c^#3:*expr.Expr_IdentExpr# +)^#1:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a.b()", + p: "a^#1:*expr.Expr_IdentExpr#.b()^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "a.b(c)", + p: "a^#1:*expr.Expr_IdentExpr#.b( + c^#3:*expr.Expr_IdentExpr# +)^#2:*expr.Expr_CallExpr#", + e: "", + }, + TestInfo { + i: "foo{ }", + p: "foo{}^#1:*expr.Expr_StructExpr#", + e: "", + }, + TestInfo { + i: "foo{ a:b }", + p: "foo{ + a:b^#3:*expr.Expr_IdentExpr#^#2:*expr.Expr_CreateStruct_Entry# +}^#1:*expr.Expr_StructExpr#", + e: "", + }, + TestInfo { + i: "foo{ a:b, c:d }", + p: "foo{ + a:b^#3:*expr.Expr_IdentExpr#^#2:*expr.Expr_CreateStruct_Entry#, + c:d^#5:*expr.Expr_IdentExpr#^#4:*expr.Expr_CreateStruct_Entry# +}^#1:*expr.Expr_StructExpr#", + e: "", + }, + TestInfo { + i: "{}", + p: "{}^#1:*expr.Expr_StructExpr#", + e: "", + }, + TestInfo { + i: "{a: b, c: d}", + p: "{ + a^#3:*expr.Expr_IdentExpr#:b^#4:*expr.Expr_IdentExpr#^#2:*expr.Expr_CreateStruct_Entry#, + c^#6:*expr.Expr_IdentExpr#:d^#7:*expr.Expr_IdentExpr#^#5:*expr.Expr_CreateStruct_Entry# +}^#1:*expr.Expr_StructExpr#", + e: "", + }, + TestInfo { + i: "[]", + p: "[]^#1:*expr.Expr_ListExpr#", + e: "", + }, + TestInfo { + i: "[a]", + p: "[ + a^#2:*expr.Expr_IdentExpr# +]^#1:*expr.Expr_ListExpr#", + e: "", + }, + TestInfo { + i: "[a, b, c]", + p: "[ + a^#2:*expr.Expr_IdentExpr#, + b^#3:*expr.Expr_IdentExpr#, + c^#4:*expr.Expr_IdentExpr# +]^#1:*expr.Expr_ListExpr#", + e: "", + }, + TestInfo { + i: "has(m.f)", + p: "m^#2:*expr.Expr_IdentExpr#.f~test-only~^#4:*expr.Expr_SelectExpr#", + e: "", + }, + TestInfo { + i: "m.exists(v, f)", + p: "__comprehension__( +// Variable +v, +// Target +m^#1:*expr.Expr_IdentExpr#, +// Accumulator +@result, +// Init +false^#5:*expr.Constant_BoolValue#, +// LoopCondition +@not_strictly_false( + !_( + @result^#6:*expr.Expr_IdentExpr# + )^#7:*expr.Expr_CallExpr# +)^#8:*expr.Expr_CallExpr#, +// LoopStep +_||_( + @result^#9:*expr.Expr_IdentExpr#, + f^#4:*expr.Expr_IdentExpr# +)^#10:*expr.Expr_CallExpr#, +// Result +@result^#11:*expr.Expr_IdentExpr#)^#12:*expr.Expr_ComprehensionExpr#", + e: "", + }, + TestInfo { + i: "m.all(v, f)", + p: "__comprehension__( +// Variable +v, +// Target +m^#1:*expr.Expr_IdentExpr#, +// Accumulator +@result, +// Init +true^#5:*expr.Constant_BoolValue#, +// LoopCondition +@not_strictly_false( + @result^#6:*expr.Expr_IdentExpr# +)^#7:*expr.Expr_CallExpr#, +// LoopStep +_&&_( + @result^#8:*expr.Expr_IdentExpr#, + f^#4:*expr.Expr_IdentExpr# +)^#9:*expr.Expr_CallExpr#, +// Result +@result^#10:*expr.Expr_IdentExpr#)^#11:*expr.Expr_ComprehensionExpr#", + e: "", + }, + TestInfo { + i: "m.existsOne(v, f)", + p: "__comprehension__( +// Variable +v, +// Target +m^#1:*expr.Expr_IdentExpr#, +// Accumulator +@result, +// Init +0^#5:*expr.Constant_Int64Value#, +// LoopCondition +true^#6:*expr.Constant_BoolValue#, +// LoopStep +_?_:_( + f^#4:*expr.Expr_IdentExpr#, + _+_( + @result^#7:*expr.Expr_IdentExpr#, + 1^#8:*expr.Constant_Int64Value# + )^#9:*expr.Expr_CallExpr#, + @result^#10:*expr.Expr_IdentExpr# +)^#11:*expr.Expr_CallExpr#, +// Result +_==_( + @result^#12:*expr.Expr_IdentExpr#, + 1^#13:*expr.Constant_Int64Value# +)^#14:*expr.Expr_CallExpr#)^#15:*expr.Expr_ComprehensionExpr#", + e: "", + }, + TestInfo { + i: "m.map(v, f)", + p: "__comprehension__( +// Variable +v, +// Target +m^#1:*expr.Expr_IdentExpr#, +// Accumulator +@result, +// Init +[]^#5:*expr.Expr_ListExpr#, +// LoopCondition +true^#6:*expr.Constant_BoolValue#, +// LoopStep +_+_( + @result^#7:*expr.Expr_IdentExpr#, + [ + f^#4:*expr.Expr_IdentExpr# + ]^#8:*expr.Expr_ListExpr# +)^#9:*expr.Expr_CallExpr#, +// Result +@result^#10:*expr.Expr_IdentExpr#)^#11:*expr.Expr_ComprehensionExpr#", + e: "", + }, + TestInfo { + i: "m.map(v, p, f)", + p: "__comprehension__( +// Variable +v, +// Target +m^#1:*expr.Expr_IdentExpr#, +// Accumulator +@result, +// Init +[]^#6:*expr.Expr_ListExpr#, +// LoopCondition +true^#7:*expr.Constant_BoolValue#, +// LoopStep +_?_:_( + p^#4:*expr.Expr_IdentExpr#, + _+_( + @result^#8:*expr.Expr_IdentExpr#, + [ + f^#5:*expr.Expr_IdentExpr# + ]^#9:*expr.Expr_ListExpr# + )^#10:*expr.Expr_CallExpr#, + @result^#11:*expr.Expr_IdentExpr# +)^#12:*expr.Expr_CallExpr#, +// Result +@result^#13:*expr.Expr_IdentExpr#)^#14:*expr.Expr_ComprehensionExpr#", + e: "", + }, + TestInfo { + i: "m.filter(v, p)", + p: "__comprehension__( +// Variable +v, +// Target +m^#1:*expr.Expr_IdentExpr#, +// Accumulator +@result, +// Init +[]^#5:*expr.Expr_ListExpr#, +// LoopCondition +true^#6:*expr.Constant_BoolValue#, +// LoopStep +_?_:_( + p^#4:*expr.Expr_IdentExpr#, + _+_( + @result^#7:*expr.Expr_IdentExpr#, + [ + v^#3:*expr.Expr_IdentExpr# + ]^#8:*expr.Expr_ListExpr# + )^#9:*expr.Expr_CallExpr#, + @result^#10:*expr.Expr_IdentExpr# +)^#11:*expr.Expr_CallExpr#, +// Result +@result^#12:*expr.Expr_IdentExpr#)^#13:*expr.Expr_ComprehensionExpr#", + e: "", + }, + // Parse error tests + TestInfo { + i: "0xFFFFFFFFFFFFFFFFF", + p: "", + e: "ERROR: :1:1: invalid int literal +| 0xFFFFFFFFFFFFFFFFF +| ^", + }, + TestInfo { + i: "0xFFFFFFFFFFFFFFFFFu", + p: "", + e: "ERROR: :1:1: invalid uint literal +| 0xFFFFFFFFFFFFFFFFFu +| ^", + }, + TestInfo { + i: "1.99e90000009", + p: "", + e: "ERROR: :1:1: invalid double literal +| 1.99e90000009 +| ^", + }, + TestInfo { + i: "{", + p: "", + e: "ERROR: :1:2: Syntax error: mismatched input '' expecting {'[', '{', '}', '(', '.', ',', '-', '!', '?', 'true', 'false', 'null', NUM_FLOAT, NUM_INT, NUM_UINT, STRING, BYTES, IDENTIFIER} +| { +| .^", + }, + TestInfo { + i: "*@a | b", + p: "", + e: "ERROR: :1:1: Syntax error: extraneous input '*' expecting {'[', '{', '(', '.', '-', '!', 'true', 'false', 'null', NUM_FLOAT, NUM_INT, NUM_UINT, STRING, BYTES, IDENTIFIER} +| *@a | b +| ^ +ERROR: :1:2: Syntax error: token recognition error at: '@' +| *@a | b +| .^ +ERROR: :1:5: Syntax error: token recognition error at: '| ' +| *@a | b +| ....^ +ERROR: :1:7: Syntax error: extraneous input 'b' expecting +| *@a | b +| ......^", + }, + TestInfo { + i: "a | b", + p: "", + e: "ERROR: :1:3: Syntax error: token recognition error at: '| ' +| a | b +| ..^ +ERROR: :1:5: Syntax error: extraneous input 'b' expecting +| a | b +| ....^", + }, + TestInfo { + i: "a.?b && a[?b]", + p: "", + e: "ERROR: :1:2: unsupported syntax '.?' +| a.?b && a[?b] +| .^ +ERROR: :1:10: unsupported syntax '[?' +| a.?b && a[?b] +| .........^", + }, + TestInfo { + i: "a.?b && a[?b]", + p: "", + e: "ERROR: :1:2: unsupported syntax '.?' +| a.?b && a[?b] +| .^ +ERROR: :1:10: unsupported syntax '[?' +| a.?b && a[?b] +| .........^", + }, + TestInfo { + i: "Msg{?field: value} && {?'key': value}", + p: "", + e: "ERROR: :1:5: unsupported syntax '?' +| Msg{?field: value} && {?'key': value} +| ....^ +ERROR: :1:24: unsupported syntax '?' +| Msg{?field: value} && {?'key': value} +| .......................^", + }, + TestInfo { + i: "has(m)", + p: "", + e: "ERROR: :1:5: invalid argument to has() macro +| has(m) +| ....^" + }, + TestInfo { + i: "1.all(2, 3)", + p: "", + e: "ERROR: :1:7: argument must be a simple name +| 1.all(2, 3) +| ......^", + }, + ]; + + for test_case in test_cases { + let parser = Parser::new(); + let result = parser.parse(test_case.i); + if !test_case.p.is_empty() { + assert_eq!( + to_go_like_string(result.as_ref().expect("Expected an AST")), + test_case.p, + "Expr `{}` failed", + test_case.i + ); + } + + if !test_case.e.is_empty() { + assert_eq!( + format!("{}", result.as_ref().expect_err("Expected an Err!")), + test_case.e, + "Error on `{}` failed", + test_case.i + ) + } + } + } + + fn to_go_like_string(expr: &IdedExpr) -> String { + let mut writer = DebugWriter::default(); + writer.buffer(expr); + writer.done() + } + + struct DebugWriter { + buffer: String, + indents: usize, + line_start: bool, + } + + impl Default for DebugWriter { + fn default() -> Self { + Self { + buffer: String::default(), + indents: 0, + line_start: true, + } + } + } + + impl DebugWriter { + fn buffer(&mut self, expr: &IdedExpr) -> &Self { + let e = match &expr.expr { + Expr::Unspecified => "UNSPECIFIED!", + Expr::Call(call) => { + if let Some(target) = &call.target { + self.buffer(target); + self.push("."); + } + self.push(call.func_name.as_str()); + self.push("("); + if !call.args.is_empty() { + self.inc_indent(); + self.newline(); + for i in 0..call.args.len() { + if i > 0 { + self.push(","); + self.newline(); + } + self.buffer(&call.args[i]); + } + self.dec_indent(); + self.newline(); + } + self.push(")"); + &format!("^#{}:{}#", expr.id, "*expr.Expr_CallExpr") + } + Expr::Comprehension(comprehension) => { + self.push("__comprehension__(\n"); + self.push_comprehension(comprehension); + &format!(")^#{}:{}#", expr.id, "*expr.Expr_ComprehensionExpr") + } + Expr::Ident(id) => &format!("{}^#{}:{}#", id, expr.id, "*expr.Expr_IdentExpr"), + Expr::List(list) => { + self.push("["); + if !list.elements.is_empty() { + self.inc_indent(); + self.newline(); + for (i, element) in list.elements.iter().enumerate() { + if i > 0 { + self.push(","); + self.newline(); + } + self.buffer(element); + } + self.dec_indent(); + self.newline(); + } + self.push("]"); + &format!("^#{}:{}#", expr.id, "*expr.Expr_ListExpr") + } + Expr::Literal(val) => match val { + CelVal::String(s) => { + &format!("\"{s}\"^#{}:{}#", expr.id, "*expr.Constant_StringValue") + } + CelVal::Boolean(b) => { + &format!("{b}^#{}:{}#", expr.id, "*expr.Constant_BoolValue") + } + CelVal::Int(i) => &format!("{i}^#{}:{}#", expr.id, "*expr.Constant_Int64Value"), + CelVal::UInt(u) => { + &format!("{u}u^#{}:{}#", expr.id, "*expr.Constant_Uint64Value") + } + CelVal::Double(f) => { + &format!("{f}^#{}:{}#", expr.id, "*expr.Constant_DoubleValue") + } + CelVal::Bytes(bytes) => &format!( + "b\"{}\"^#{}:{}#", + String::from_utf8_lossy(bytes), + expr.id, + "*expr.Constant_BytesValue" + ), + CelVal::Null => &format!("null^#{}:{}#", expr.id, "*expr.Constant_NullValue"), + t => &format!("WUT? {t:?}"), + }, + Expr::Map(map) => { + self.push("{"); + self.inc_indent(); + if !map.entries.is_empty() { + self.newline(); + } + for (i, entry) in map.entries.iter().enumerate() { + match &entry.expr { + EntryExpr::StructField(_) => panic!("WAT?!"), + EntryExpr::MapEntry(e) => { + self.buffer(&e.key); + self.push(":"); + self.buffer(&e.value); + self.push(&format!( + "^#{}:{}#", + entry.id, "*expr.Expr_CreateStruct_Entry" + )); + } + } + if i < map.entries.len() - 1 { + self.push(","); + } + self.newline(); + } + self.dec_indent(); + self.push("}"); + &format!("^#{}:{}#", expr.id, "*expr.Expr_StructExpr") + } + Expr::Select(select) => { + self.buffer(select.operand.deref()); + let suffix = if select.test { "~test-only~" } else { "" }; + &format!( + ".{}{}^#{}:{}#", + select.field, suffix, expr.id, "*expr.Expr_SelectExpr" + ) + } + Expr::Struct(s) => { + self.push(&s.type_name); + self.push("{"); + self.inc_indent(); + if !s.entries.is_empty() { + self.newline(); + } + for (i, entry) in s.entries.iter().enumerate() { + match &entry.expr { + EntryExpr::StructField(field) => { + self.push(&field.field); + self.push(":"); + self.buffer(&field.value); + self.push(&format!( + "^#{}:{}#", + entry.id, "*expr.Expr_CreateStruct_Entry" + )); + } + EntryExpr::MapEntry(_) => panic!("WAT?!"), + } + if i < s.entries.len() - 1 { + self.push(","); + } + self.newline(); + } + self.dec_indent(); + self.push("}"); + &format!("^#{}:{}#", expr.id, "*expr.Expr_StructExpr") + } + }; + self.push(e); + self + } + + fn push(&mut self, literal: &str) { + self.indent(); + self.buffer.push_str(literal); + } + + fn indent(&mut self) { + if self.line_start { + self.line_start = false; + self.buffer.push_str( + iter::repeat_n(" ", self.indents) + .collect::() + .as_str(), + ) + } + } + + fn newline(&mut self) { + self.buffer.push('\n'); + self.line_start = true; + } + + fn inc_indent(&mut self) { + self.indents += 1; + } + + fn dec_indent(&mut self) { + self.indents -= 1; + } + + fn done(self) -> String { + self.buffer + } + + fn push_comprehension(&mut self, comprehension: &ComprehensionExpr) { + self.push("// Variable\n"); + self.push(comprehension.iter_var.as_str()); + self.push(",\n"); + self.push("// Target\n"); + self.buffer(&comprehension.iter_range); + self.push(",\n"); + self.push("// Accumulator\n"); + self.push(comprehension.accu_var.as_str()); + self.push(",\n"); + self.push("// Init\n"); + self.buffer(&comprehension.accu_init); + self.push(",\n"); + self.push("// LoopCondition\n"); + self.buffer(&comprehension.loop_cond); + self.push(",\n"); + self.push("// LoopStep\n"); + self.buffer(&comprehension.loop_step); + self.push(",\n"); + self.push("// Result\n"); + self.buffer(&comprehension.result); + } + } +} diff --git a/vendor/cel/src/parser/references.rs b/vendor/cel/src/parser/references.rs new file mode 100644 index 0000000..db8f674 --- /dev/null +++ b/vendor/cel/src/parser/references.rs @@ -0,0 +1,155 @@ +use std::collections::HashSet; + +use crate::common::ast::{Expr, IdedExpr}; + +/// A collection of all the references that an expression makes to variables and functions. +pub struct ExpressionReferences<'expr> { + variables: HashSet<&'expr str>, + functions: HashSet<&'expr str>, +} + +impl ExpressionReferences<'_> { + /// Returns true if the expression references the provided variable name. + /// + /// # Example + /// ```rust + /// # use cel::parser::Parser; + /// let expression = Parser::new().parse("foo.bar == true").unwrap(); + /// let references = expression.references(); + /// assert!(references.has_variable("foo")); + /// ``` + pub fn has_variable(&self, name: impl AsRef) -> bool { + self.variables.contains(name.as_ref()) + } + + /// Returns true if the expression references the provided function name. + /// + /// # Example + /// ```rust + /// # use cel::parser::Parser; + /// let expression = Parser::new().parse("size(foo) > 0").unwrap(); + /// let references = expression.references(); + /// assert!(references.has_function("size")); + /// ``` + pub fn has_function(&self, name: impl AsRef) -> bool { + self.functions.contains(name.as_ref()) + } + + /// Returns a list of all variables referenced in the expression. + /// + /// # Example + /// ```rust + /// # use cel::parser::Parser; + /// let expression = Parser::new().parse("foo.bar == true").unwrap(); + /// let references = expression.references(); + /// assert_eq!(vec!["foo"], references.variables()); + /// ``` + pub fn variables(&self) -> Vec<&str> { + self.variables.iter().copied().collect() + } + + /// Returns a list of all functions referenced in the expression. + /// + /// # Example + /// ```rust + /// # use cel::parser::Parser; + /// let expression = Parser::new().parse("size(foo) > 0").unwrap(); + /// let references = expression.references(); + /// assert!(references.functions().contains(&"_>_")); + /// assert!(references.functions().contains(&"size")); + /// ``` + pub fn functions(&self) -> Vec<&str> { + self.functions.iter().copied().collect() + } +} + +impl IdedExpr { + /// Returns a set of all variables and functions referenced in the expression. + /// + /// # Example + /// ```rust + /// # use cel::parser::Parser; + /// let expression = Parser::new().parse("foo && size(foo) > 0").unwrap(); + /// let references = expression.references(); + /// + /// assert!(references.has_variable("foo")); + /// assert!(references.has_function("size")); + /// ``` + pub fn references(&self) -> ExpressionReferences<'_> { + let mut variables = HashSet::new(); + let mut functions = HashSet::new(); + self._references(&mut variables, &mut functions); + ExpressionReferences { + variables, + functions, + } + } + + /// Internal recursive function to collect all variable and function references in the expression. + fn _references<'expr>( + &'expr self, + variables: &mut HashSet<&'expr str>, + functions: &mut HashSet<&'expr str>, + ) { + match &self.expr { + Expr::Unspecified => {} + Expr::Call(call) => { + functions.insert(&call.func_name); + if let Some(target) = &call.target { + target._references(variables, functions); + } + for arg in &call.args { + arg._references(variables, functions); + } + } + Expr::Comprehension(comp) => { + comp.iter_range._references(variables, functions); + comp.accu_init._references(variables, functions); + comp.loop_cond._references(variables, functions); + comp.loop_step._references(variables, functions); + comp.result._references(variables, functions); + } + Expr::Ident(name) => { + // todo! Might want to make this "smarter" (are we in a comprehension?) and better encode these in const + if !name.starts_with('@') { + variables.insert(name); + } + } + Expr::List(list) => { + for elem in &list.elements { + elem._references(variables, functions); + } + } + Expr::Literal(_) => {} + Expr::Map(map) => { + for entry in &map.entries { + match &entry.expr { + crate::common::ast::EntryExpr::StructField(field) => { + field.value._references(variables, functions); + } + crate::common::ast::EntryExpr::MapEntry(map_entry) => { + map_entry.key._references(variables, functions); + map_entry.value._references(variables, functions); + } + } + } + } + Expr::Select(select) => { + select.operand._references(variables, functions); + } + Expr::Struct(struct_expr) => { + for entry in &struct_expr.entries { + match &entry.expr { + crate::common::ast::EntryExpr::StructField(field) => { + field.value._references(variables, functions); + } + crate::common::ast::EntryExpr::MapEntry(map_entry) => { + map_entry.key._references(variables, functions); + map_entry.value._references(variables, functions); + } + } + } + } + } + } +} diff --git a/vendor/cel/src/resolvers.rs b/vendor/cel/src/resolvers.rs new file mode 100644 index 0000000..d0e7fae --- /dev/null +++ b/vendor/cel/src/resolvers.rs @@ -0,0 +1,64 @@ +use crate::parser::Expression; +use crate::{ExecutionError, FunctionContext, ResolveResult, Value}; + +/// Resolver knows how to resolve a [`Value`] from a [`FunctionContext`]. +/// At their core, resolvers are responsible for taking Expressions and +/// turned them into values, but this trait allows us to abstract away +/// some of the complexity surrounding how the expression is obtained in +/// the first place. +/// +/// For example, the [`Argument`] resolver takes an index and resolves the +/// corresponding argument from the [`FunctionContext`]. Resolver makes it +/// easy to (1) get the expression for a specific argument index, (2) +/// return an error if the argument is missing, and (3) resolve the expression +/// into a value. +pub trait Resolver { + fn resolve(&self, ctx: &FunctionContext) -> ResolveResult; +} + +impl Resolver for Expression { + fn resolve(&self, ctx: &FunctionContext) -> ResolveResult { + Value::resolve(self, ctx.ptx) + } +} + +/// Argument is a [`Resolver`] that resolves to the nth argument. +/// +/// # Example +/// ```skip +/// let arg0 = ftx.resolve(Argument(0))?; +/// ``` +pub(crate) struct Argument(pub usize); + +impl Resolver for Argument { + fn resolve(&self, ctx: &FunctionContext) -> ResolveResult { + let index = self.0; + let arg = ctx + .args + .get(index) + .ok_or(ExecutionError::invalid_argument_count( + index + 1, + ctx.args.len(), + ))?; + Value::resolve(arg, ctx.ptx) + } +} + +/// A resolver for all arguments passed to a function. Each argument will be +/// resolved and then returned as a [`Value::List`] +/// +/// # Example +/// ```skip +/// let args = ftx.resolve(AllArguments)?; +/// ``` +pub(crate) struct AllArguments; + +impl Resolver for AllArguments { + fn resolve(&self, ctx: &FunctionContext) -> ResolveResult { + let mut args = Vec::with_capacity(ctx.args.len()); + for arg in ctx.args.iter() { + args.push(Value::resolve(arg, ctx.ptx)?); + } + Ok(Value::List(args.into())) + } +} diff --git a/vendor/cel/src/ser.rs b/vendor/cel/src/ser.rs new file mode 100644 index 0000000..c2146e3 --- /dev/null +++ b/vendor/cel/src/ser.rs @@ -0,0 +1,1375 @@ +// The serde_json crate implements a Serializer for its own Value enum, that is +// almost exactly the same to our Value enum, so this is more or less copied +// from [serde_json](https://github.com/serde-rs/json/blob/master/src/value/ser.rs), +// also mentioned in the [serde documentation](https://serde.rs/). + +use crate::{objects::Key, Value}; +use serde::{ + ser::{self, Impossible}, + Serialize, +}; +use std::{collections::HashMap, fmt::Display, iter::FromIterator, sync::Arc}; +use thiserror::Error; + +#[cfg(feature = "chrono")] +use chrono::FixedOffset; +#[cfg(feature = "chrono")] +use serde::ser::SerializeStruct; + +pub struct Serializer; +pub struct KeySerializer; + +/// A wrapper Duration type which allows conversion to [Value::Duration] for +/// types using automatic conversion with [serde::Serialize]. +/// +/// # Examples +/// +/// ``` +/// use cel::{Context, Duration, Program}; +/// use serde::Serialize; +/// +/// #[derive(Serialize)] +/// struct MyStruct { +/// dur: Duration, +/// } +/// +/// let mut context = Context::default(); +/// +/// // MyStruct will be implicitly serialized into the CEL appropriate types +/// context +/// .add_variable( +/// "foo", +/// MyStruct { +/// dur: chrono::Duration::hours(2).into(), +/// }, +/// ) +/// .unwrap(); +/// +/// let program = Program::compile("foo.dur == duration('2h')").unwrap(); +/// let value = program.execute(&context).unwrap(); +/// assert_eq!(value, true.into()); +/// ``` +#[cfg(feature = "chrono")] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub struct Duration(pub chrono::Duration); + +#[cfg(feature = "chrono")] +impl Duration { + // Since serde can't natively represent durations, we serialize a special + // newtype to indicate we want to rebuild the duration in the result, while + // remaining compatible with most other Serializer implementations. + const NAME: &str = "$__cel_private_Duration"; + const STRUCT_NAME: &str = "Duration"; + const SECS_FIELD: &str = "secs"; + const NANOS_FIELD: &str = "nanos"; +} + +#[cfg(feature = "chrono")] +impl From for chrono::Duration { + fn from(value: Duration) -> Self { + value.0 + } +} + +#[cfg(feature = "chrono")] +impl From for Duration { + fn from(value: chrono::Duration) -> Self { + Self(value) + } +} + +#[cfg(feature = "chrono")] +impl ser::Serialize for Duration { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: ser::Serializer, + { + // chrono::Duration's Serialize impl isn't stable yet and relies on + // private fields, so attempt to mimic serde's default impl for std + // Duration. + struct DurationProxy(chrono::Duration); + impl Serialize for DurationProxy { + fn serialize( + &self, + serializer: S, + ) -> std::result::Result { + let mut s = serializer.serialize_struct(Duration::STRUCT_NAME, 2)?; + s.serialize_field(Duration::SECS_FIELD, &self.0.num_seconds())?; + s.serialize_field( + Duration::NANOS_FIELD, + &(self.0.num_nanoseconds().unwrap_or(0) % 1_000_000_000), + )?; + s.end() + } + } + serializer.serialize_newtype_struct(Self::NAME, &DurationProxy(self.0)) + } +} + +/// A wrapper Timestamp type which allows conversion to [Value::Timestamp] for +/// types using automatic conversion with [serde::Serialize]. +/// +/// # Examples +/// +/// ``` +/// use cel::{Context, Timestamp, Program}; +/// use serde::Serialize; +/// +/// #[derive(Serialize)] +/// struct MyStruct { +/// ts: Timestamp, +/// } +/// +/// let mut context = Context::default(); +/// +/// // MyStruct will be implicitly serialized into the CEL appropriate types +/// context +/// .add_variable( +/// "foo", +/// MyStruct { +/// ts: chrono::DateTime::parse_from_rfc3339("2025-01-01T00:00:00Z") +/// .unwrap() +/// .into(), +/// }, +/// ) +/// .unwrap(); +/// +/// let program = Program::compile("foo.ts == timestamp('2025-01-01T00:00:00Z')").unwrap(); +/// let value = program.execute(&context).unwrap(); +/// assert_eq!(value, true.into()); +/// ``` +#[cfg(feature = "chrono")] +#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub struct Timestamp(pub chrono::DateTime); + +#[cfg(feature = "chrono")] +impl Timestamp { + // Since serde can't natively represent timestamps, we serialize a special + // newtype to indicate we want to rebuild the timestamp in the result, + // while remaining compatible with most other Serializer implementations. + const NAME: &str = "$__cel_private_Timestamp"; +} + +#[cfg(feature = "chrono")] +impl From for chrono::DateTime { + fn from(value: Timestamp) -> Self { + value.0 + } +} + +#[cfg(feature = "chrono")] +impl From> for Timestamp { + fn from(value: chrono::DateTime) -> Self { + Self(value) + } +} + +#[cfg(feature = "chrono")] +impl ser::Serialize for Timestamp { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: ser::Serializer, + { + serializer.serialize_newtype_struct(Self::NAME, &self.0) + } +} + +#[derive(Error, Debug, PartialEq, Clone)] +pub enum SerializationError { + InvalidKey(String), + SerdeError(String), +} + +impl ser::Error for SerializationError { + fn custom(msg: T) -> Self + where + T: std::fmt::Display, + { + SerializationError::SerdeError(msg.to_string()) + } +} + +impl Display for SerializationError { + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SerializationError::SerdeError(msg) => formatter.write_str(msg), + SerializationError::InvalidKey(msg) => formatter.write_str(msg), + } + } +} + +pub type Result = std::result::Result; + +pub fn to_value(value: T) -> Result +where + T: Serialize, +{ + value.serialize(Serializer) +} + +impl ser::Serializer for Serializer { + type Ok = Value; + type Error = SerializationError; + + type SerializeSeq = SerializeVec; + type SerializeTuple = SerializeVec; + type SerializeTupleStruct = SerializeVec; + type SerializeTupleVariant = SerializeTupleVariant; + type SerializeMap = SerializeMap; + type SerializeStruct = SerializeMap; + type SerializeStructVariant = SerializeStructVariant; + + fn serialize_bool(self, v: bool) -> Result { + Ok(Value::Bool(v)) + } + + fn serialize_i8(self, v: i8) -> Result { + self.serialize_i64(i64::from(v)) + } + + fn serialize_i16(self, v: i16) -> Result { + self.serialize_i64(i64::from(v)) + } + + fn serialize_i32(self, v: i32) -> Result { + self.serialize_i64(i64::from(v)) + } + + fn serialize_i64(self, v: i64) -> Result { + Ok(Value::Int(v)) + } + + fn serialize_u8(self, v: u8) -> Result { + self.serialize_u64(u64::from(v)) + } + + fn serialize_u16(self, v: u16) -> Result { + self.serialize_u64(u64::from(v)) + } + + fn serialize_u32(self, v: u32) -> Result { + self.serialize_u64(u64::from(v)) + } + + fn serialize_u64(self, v: u64) -> Result { + Ok(Value::UInt(v)) + } + + fn serialize_f32(self, v: f32) -> Result { + self.serialize_f64(f64::from(v)) + } + + fn serialize_f64(self, v: f64) -> Result { + Ok(Value::Float(v)) + } + + fn serialize_char(self, v: char) -> Result { + self.serialize_str(&v.to_string()) + } + + fn serialize_str(self, v: &str) -> Result { + Ok(Value::String(Arc::new(v.to_string()))) + } + + fn serialize_bytes(self, v: &[u8]) -> Result { + Ok(Value::Bytes(Arc::new(v.to_vec()))) + } + + fn serialize_none(self) -> Result { + self.serialize_unit() + } + + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_unit(self) -> Result { + Ok(Value::Null) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + self.serialize_unit() + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result { + self.serialize_str(variant) + } + + fn serialize_newtype_struct(self, name: &'static str, value: &T) -> Result + where + T: ?Sized + Serialize, + { + match name { + #[cfg(feature = "chrono")] + Duration::NAME => value.serialize(TimeSerializer::Duration), + #[cfg(feature = "chrono")] + Timestamp::NAME => value.serialize(TimeSerializer::Timestamp), + _ => value.serialize(self), + } + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + Ok(HashMap::from_iter([(variant.to_string(), value.serialize(Serializer)?)]).into()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Ok(SerializeVec { + vec: Vec::with_capacity(_len.unwrap_or(0)), + }) + } + + fn serialize_tuple(self, len: usize) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + _len: usize, + ) -> Result { + Ok(SerializeTupleVariant { + name: String::from(variant), + vec: Vec::with_capacity(_len), + }) + } + + fn serialize_map(self, _len: Option) -> Result { + Ok(SerializeMap { + map: HashMap::new(), + next_key: None, + }) + } + + fn serialize_struct(self, _name: &'static str, len: usize) -> Result { + self.serialize_map(Some(len)) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + _len: usize, + ) -> Result { + Ok(SerializeStructVariant { + name: String::from(variant), + map: HashMap::new(), + }) + } +} + +pub struct SerializeVec { + vec: Vec, +} + +pub struct SerializeTupleVariant { + name: String, + vec: Vec, +} + +pub struct SerializeMap { + map: HashMap, + next_key: Option, +} + +pub struct SerializeStructVariant { + name: String, + map: HashMap, +} + +#[cfg(feature = "chrono")] +#[derive(Debug, Default)] +struct SerializeTimestamp { + secs: i64, + nanos: i32, +} + +impl ser::SerializeSeq for SerializeVec { + type Ok = Value; + type Error = SerializationError; + + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.vec.push(to_value(value)?); + Ok(()) + } + + fn end(self) -> Result { + Ok(Value::List(Arc::new(self.vec))) + } +} + +impl ser::SerializeTuple for SerializeVec { + type Ok = Value; + type Error = SerializationError; + + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + serde::ser::SerializeSeq::end(self) + } +} + +impl ser::SerializeTupleStruct for SerializeVec { + type Ok = Value; + type Error = SerializationError; + + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + serde::ser::SerializeSeq::end(self) + } +} + +impl ser::SerializeTupleVariant for SerializeTupleVariant { + type Ok = Value; + type Error = SerializationError; + + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.vec.push(to_value(value)?); + Ok(()) + } + + fn end(self) -> Result { + let map = HashMap::from_iter([(self.name, Arc::new(self.vec))]); + Ok(map.into()) + } +} + +impl ser::SerializeMap for SerializeMap { + type Ok = Value; + type Error = SerializationError; + + fn serialize_key(&mut self, key: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.next_key = Some(key.serialize(KeySerializer)?); + Ok(()) + } + + fn serialize_value(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.map.insert( + self.next_key.clone().ok_or_else(|| { + SerializationError::InvalidKey( + "serialize_value called before serialize_key".to_string(), + ) + })?, + value.serialize(Serializer)?, + ); + Ok(()) + } + + fn end(self) -> Result { + Ok(self.map.into()) + } +} + +impl ser::SerializeStruct for SerializeMap { + type Ok = Value; + type Error = SerializationError; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + serde::ser::SerializeMap::serialize_entry(self, key, value) + } + + fn end(self) -> Result { + serde::ser::SerializeMap::end(self) + } +} + +impl ser::SerializeStructVariant for SerializeStructVariant { + type Ok = Value; + type Error = SerializationError; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.map + .insert(key.serialize(KeySerializer)?, to_value(value)?); + Ok(()) + } + + fn end(self) -> Result { + let map: HashMap = HashMap::from_iter([(self.name, self.map.into())]); + Ok(map.into()) + } +} + +#[cfg(feature = "chrono")] +impl ser::SerializeStruct for SerializeTimestamp { + type Ok = Value; + type Error = SerializationError; + fn serialize_field( + &mut self, + key: &'static str, + value: &T, + ) -> std::result::Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + match key { + Duration::SECS_FIELD => { + let Value::Int(val) = value.serialize(Serializer)? else { + return Err(SerializationError::SerdeError( + "invalid type of value in timestamp struct".to_owned(), + )); + }; + self.secs = val; + Ok(()) + } + Duration::NANOS_FIELD => { + let Value::Int(val) = value.serialize(Serializer)? else { + return Err(SerializationError::SerdeError( + "invalid type of value in timestamp struct".to_owned(), + )); + }; + self.nanos = val.try_into().map_err(|_| { + SerializationError::SerdeError( + "timestamp struct nanos field is invalid".to_owned(), + ) + })?; + Ok(()) + } + _ => Err(SerializationError::SerdeError( + "invalid field in duration struct".to_owned(), + )), + } + } + + fn end(self) -> std::result::Result { + Ok(chrono::Duration::seconds(self.secs) + .checked_add(&chrono::Duration::nanoseconds(self.nanos.into())) + .unwrap() + .into()) + } +} + +impl ser::Serializer for KeySerializer { + type Ok = Key; + type Error = SerializationError; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeTupleVariant = Impossible; + type SerializeMap = Impossible; + type SerializeStruct = Impossible; + type SerializeStructVariant = Impossible; + + fn serialize_bool(self, v: bool) -> Result { + Ok(Key::Bool(v)) + } + + fn serialize_i8(self, v: i8) -> Result { + self.serialize_i64(i64::from(v)) + } + + fn serialize_i16(self, v: i16) -> Result { + self.serialize_i64(i64::from(v)) + } + + fn serialize_i32(self, v: i32) -> Result { + self.serialize_i64(i64::from(v)) + } + + fn serialize_i64(self, v: i64) -> Result { + Ok(Key::Int(v)) + } + + fn serialize_u8(self, v: u8) -> Result { + self.serialize_u64(u64::from(v)) + } + + fn serialize_u16(self, v: u16) -> Result { + self.serialize_u64(u64::from(v)) + } + + fn serialize_u32(self, v: u32) -> Result { + self.serialize_u64(u64::from(v)) + } + + fn serialize_u64(self, v: u64) -> Result { + Ok(Key::Uint(v)) + } + + fn serialize_f32(self, _v: f32) -> Result { + Err(SerializationError::InvalidKey( + "Float is not supported".to_string(), + )) + } + + fn serialize_f64(self, _v: f64) -> Result { + Err(SerializationError::InvalidKey( + "Float is not supported".to_string(), + )) + } + + fn serialize_char(self, v: char) -> Result { + self.serialize_str(&v.to_string()) + } + + fn serialize_str(self, v: &str) -> Result { + Ok(Key::String(Arc::new(v.to_string()))) + } + + fn serialize_bytes(self, _v: &[u8]) -> Result { + Err(SerializationError::InvalidKey( + "Bytes are not supported".to_string(), + )) + } + + fn serialize_none(self) -> Result { + Err(SerializationError::InvalidKey( + "None is not supported".to_string(), + )) + } + + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_unit(self) -> Result { + Err(SerializationError::InvalidKey( + "Null is not supported".to_string(), + )) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(SerializationError::InvalidKey( + "Empty unit structs are not supported".to_string(), + )) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result { + Ok(Key::String(Arc::new(variant.to_string()))) + } + + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(KeySerializer) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + Err(SerializationError::InvalidKey( + "Newtype variant is not supported".to_string(), + )) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(SerializationError::InvalidKey( + "Sequences are not supported".to_string(), + )) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(SerializationError::InvalidKey( + "Tuples are not supported".to_string(), + )) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(SerializationError::InvalidKey( + "Structs are not supported".to_string(), + )) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(SerializationError::InvalidKey( + "Tuple variants are not supported".to_string(), + )) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(SerializationError::InvalidKey( + "Map variants are not supported".to_string(), + )) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Err(SerializationError::InvalidKey( + "Structs are not supported".to_string(), + )) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(SerializationError::InvalidKey( + "Struct variants are not supported".to_string(), + )) + } +} + +#[cfg(feature = "chrono")] +#[derive(Debug)] +enum TimeSerializer { + Duration, + Timestamp, +} + +#[cfg(feature = "chrono")] +impl ser::Serializer for TimeSerializer { + type Ok = Value; + type Error = SerializationError; + + type SerializeStruct = SerializeTimestamp; + + // Should never be used, so just reuse existing. + type SerializeSeq = SerializeVec; + type SerializeTuple = SerializeVec; + type SerializeTupleStruct = SerializeVec; + type SerializeTupleVariant = SerializeTupleVariant; + type SerializeMap = SerializeMap; + type SerializeStructVariant = SerializeStructVariant; + + fn serialize_struct(self, name: &'static str, len: usize) -> Result { + if !matches!(self, Self::Duration { .. }) || name != Duration::STRUCT_NAME { + return Err(SerializationError::SerdeError( + "expected Duration struct with Duration marker newtype struct".to_owned(), + )); + } + if len != 2 { + return Err(SerializationError::SerdeError( + "expected Duration struct to have 2 fields".to_owned(), + )); + } + Ok(SerializeTimestamp::default()) + } + + fn serialize_str(self, v: &str) -> Result { + if !matches!(self, Self::Timestamp) { + return Err(SerializationError::SerdeError( + "expected Timestamp string with Timestamp marker newtype struct".to_owned(), + )); + } + Ok(v.parse::>() + .map_err(|e| SerializationError::SerdeError(e.to_string()))? + .into()) + } + + fn serialize_bool(self, _v: bool) -> Result { + unreachable!() + } + + fn serialize_i8(self, _v: i8) -> Result { + unreachable!() + } + + fn serialize_i16(self, _v: i16) -> Result { + unreachable!() + } + + fn serialize_i32(self, _v: i32) -> Result { + unreachable!() + } + + fn serialize_i64(self, _v: i64) -> Result { + unreachable!() + } + + fn serialize_u8(self, _v: u8) -> Result { + unreachable!() + } + + fn serialize_u16(self, _v: u16) -> Result { + unreachable!() + } + + fn serialize_u32(self, _v: u32) -> Result { + unreachable!() + } + + fn serialize_u64(self, _v: u64) -> Result { + unreachable!() + } + + fn serialize_f32(self, _v: f32) -> Result { + unreachable!() + } + + fn serialize_f64(self, _v: f64) -> Result { + unreachable!() + } + + fn serialize_char(self, _v: char) -> Result { + unreachable!() + } + + fn serialize_bytes(self, _v: &[u8]) -> Result { + unreachable!() + } + + fn serialize_none(self) -> Result { + unreachable!() + } + + fn serialize_some(self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + unreachable!() + } + + fn serialize_unit(self) -> Result { + unreachable!() + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + unreachable!() + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result { + unreachable!() + } + + fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + unreachable!() + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + unreachable!() + } + + fn serialize_seq(self, _len: Option) -> Result { + unreachable!() + } + + fn serialize_tuple(self, _len: usize) -> Result { + unreachable!() + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + unreachable!() + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + unreachable!() + } + + fn serialize_map(self, _len: Option) -> Result { + unreachable!() + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + unreachable!() + } +} + +#[cfg(test)] +mod tests { + use crate::{objects::Key, to_value, Value}; + use crate::{Context, Program}; + use serde::Serialize; + use serde_bytes::Bytes; + use std::{collections::HashMap, iter::FromIterator, sync::Arc}; + + #[cfg(feature = "chrono")] + use super::{Duration, Timestamp}; + + macro_rules! primitive_test { + ($functionName:ident, $strValue: literal, $value: expr) => { + #[test] + fn $functionName() { + let program = Program::compile($strValue).unwrap(); + let result = program.execute(&Context::default()); + assert_eq!(Value::from($value), result.unwrap()); + } + }; + } + + primitive_test!(test_u64_zero, "0u", 0_u64); + primitive_test!(test_i64_zero, "0", 0_i64); + primitive_test!(test_f64_zero, "0.0", 0_f64); + //primitive_test!(test_f64_zero, "0.", 0_f64); this test fails + primitive_test!(test_bool_false, "false", false); + primitive_test!(test_bool_true, "true", true); + primitive_test!(test_string_empty, "\"\"", ""); + primitive_test!(test_string_non_empty, "\"test\"", "test"); + primitive_test!(test_byte_ones, r#"b"\001\001""#, vec!(1_u8, 1_u8)); + // primitive_test!(test_triple_double_quoted_string, #"r"""""""#, ""); + // primitive_test!(test_triple_single_quoted_string, "r''''''", ""); + primitive_test!(test_utf8_character_as_bytes, "b'ÿ'", vec!(195_u8, 191_u8)); + + #[test] + fn test_json_data_conversion() { + #[derive(Serialize)] + struct TestPrimitives { + bool: bool, + u8: u8, + u16: u16, + u32: u32, + u64: u64, + int8: i8, + int16: i16, + int32: i32, + int64: i64, + f32: f32, + f64: f64, + char: char, + string: String, + bytes: &'static Bytes, + } + + let test = TestPrimitives { + bool: true, + int8: 8_i8, + int16: 16_i16, + int32: 32_i32, + int64: 64_i64, + u8: 8_u8, + u16: 16_u16, + u32: 32_u32, + u64: 64_u64, + f32: 0.32_f32, + f64: 0.64_f64, + char: 'a', + string: "string".to_string(), + bytes: Bytes::new(&[1_u8, 1_u8, 1_u8, 1_u8]), + }; + + let serialized = to_value(test).unwrap(); + let expected: Value = HashMap::from_iter([ + (Key::String(Arc::new("bool".to_string())), Value::Bool(true)), + (Key::String(Arc::new("int8".to_string())), Value::Int(8)), + (Key::String(Arc::new("int16".to_string())), Value::Int(16)), + (Key::String(Arc::new("int32".to_string())), Value::Int(32)), + (Key::String(Arc::new("int64".to_string())), Value::Int(64)), + (Key::String(Arc::new("u8".to_string())), Value::UInt(8)), + (Key::String(Arc::new("u16".to_string())), Value::UInt(16)), + (Key::String(Arc::new("u32".to_string())), Value::UInt(32)), + (Key::String(Arc::new("u64".to_string())), Value::UInt(64)), + ( + Key::String(Arc::new("f32".to_string())), + Value::Float(f64::from(0.32_f32)), + ), + (Key::String(Arc::new("f64".to_string())), Value::Float(0.64)), + ( + Key::String(Arc::new("char".to_string())), + Value::String(Arc::new("a".to_string())), + ), + ( + Key::String(Arc::new("string".to_string())), + Value::String(Arc::new("string".to_string())), + ), + ( + Key::String(Arc::new("bytes".to_string())), + Value::Bytes(Arc::new(vec![1, 1, 1, 1])), + ), + ]) + .into(); + + // Test with CEL because iterator is not implemented for Value::Map + let program = + Program::compile("expected.all(key, serialized[key] == expected[key])").unwrap(); + let mut context = Context::default(); + context.add_variable("expected", expected).unwrap(); + context.add_variable("serialized", serialized).unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, true.into()) + } + + #[derive(Serialize)] + enum TestCompoundTypes { + Unit, + Newtype(u32), + Wrapped(Option), + Tuple(u32, u32), + Struct { + a: i32, + nested: HashMap>>, + }, + Map(HashMap), + } + #[test] + fn test_unit() { + let unit = to_value(TestCompoundTypes::Unit).unwrap(); + let expected: Value = "Unit".into(); + let program = Program::compile("test == expected").unwrap(); + let mut context = Context::default(); + context.add_variable("expected", expected).unwrap(); + context.add_variable("test", unit).unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, true.into()) + } + #[test] + fn test_newtype() { + let newtype = to_value(TestCompoundTypes::Newtype(32)).unwrap(); + let expected: Value = HashMap::from([("Newtype", Value::UInt(32))]).into(); + let program = Program::compile("test == expected").unwrap(); + let mut context = Context::default(); + context.add_variable("expected", expected).unwrap(); + context.add_variable("test", newtype).unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, true.into()) + } + #[test] + fn test_options() { + // Test Option serialization + let wrapped = to_value(TestCompoundTypes::Wrapped(None)).unwrap(); + let expected: Value = HashMap::from([("Wrapped", Value::Null)]).into(); + let program = Program::compile("test == expected").unwrap(); + let mut context = Context::default(); + context.add_variable("expected", expected).unwrap(); + context.add_variable("test", wrapped).unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, true.into()); + + let wrapped = to_value(TestCompoundTypes::Wrapped(Some(8))).unwrap(); + let expected: Value = HashMap::from([("Wrapped", Value::UInt(8))]).into(); + let program = Program::compile("test == expected").unwrap(); + let mut context = Context::default(); + context.add_variable("expected", expected).unwrap(); + context.add_variable("test", wrapped).unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, true.into()) + } + + #[test] + fn test_tuples() { + // Test Tuple serialization + let tuple = to_value(TestCompoundTypes::Tuple(12, 16)).unwrap(); + let expected: Value = HashMap::from([( + "Tuple", + Value::List(Arc::new(vec![12_u64.into(), 16_u64.into()])), + )]) + .into(); + let program = Program::compile("test == expected").unwrap(); + let mut context = Context::default(); + context.add_variable("expected", expected).unwrap(); + context.add_variable("test", tuple).unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, true.into()) + } + + #[test] + fn test_structs() { + // Test Struct serialization + let test_struct = TestCompoundTypes::Struct { + a: 32_i32, + nested: HashMap::from_iter([( + true, + HashMap::from_iter([( + "Test".to_string(), + vec!["a".to_string(), "b".to_string(), "c".to_string()], + )]), + )]), + }; + let expected: Value = HashMap::::from([( + "Struct".into(), + HashMap::::from_iter([ + ("a".into(), 32_i32.into()), + ( + "nested".into(), + HashMap::::from_iter([( + true.into(), + HashMap::::from_iter([( + "Test".into(), + vec!["a".to_string(), "b".to_string(), "c".to_string()].into(), + )]) + .into(), + )]) + .into(), + ), + ]) + .into(), + )]) + .into(); + let program = Program::compile("expected.all(key, test[key] == expected[key])").unwrap(); + let mut context = Context::default(); + context.add_variable("expected", expected).unwrap(); + context.add_variable("test", test_struct).unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, true.into()); + } + + #[test] + fn test_maps() { + // Test Map serialization + let map = to_value(TestCompoundTypes::Map( + HashMap::::from_iter([( + "Test".to_string(), + Bytes::new(&[0_u8, 0_u8, 0_u8, 0_u8]), + )]), + )) + .unwrap(); + let expected: Value = HashMap::from([( + "Map", + HashMap::::from_iter([( + "Test".into(), + Value::Bytes(Arc::new(vec![0_u8, 0_u8, 0_u8, 0_u8])), + )]), + )]) + .into(); + assert_eq!(map, expected) + } + + #[cfg(feature = "chrono")] + #[derive(Serialize)] + struct TestTimeTypes { + dur: Duration, + ts: Timestamp, + } + + #[cfg(feature = "chrono")] + #[test] + fn test_time_types() { + use chrono::FixedOffset; + + let tests = to_value([ + TestTimeTypes { + dur: chrono::Duration::milliseconds(1527).into(), + ts: chrono::DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00") + .unwrap() + .into(), + }, + // Let's test chrono::Duration's particular handling around math + // and negatives and timestamps from BCE. + TestTimeTypes { + dur: chrono::Duration::milliseconds(-1527).into(), + ts: "-0001-12-01T00:00:00-08:00" + .parse::>() + .unwrap() + .into(), + }, + TestTimeTypes { + dur: (chrono::Duration::seconds(1) - chrono::Duration::nanoseconds(1000000001)) + .into(), + ts: chrono::DateTime::parse_from_rfc3339("0001-12-01T00:00:00+08:00") + .unwrap() + .into(), + }, + TestTimeTypes { + dur: (chrono::Duration::seconds(-1) + chrono::Duration::nanoseconds(1000000001)) + .into(), + ts: chrono::DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00") + .unwrap() + .into(), + }, + ]) + .unwrap(); + let expected: Value = vec![ + Value::Map( + HashMap::<_, Value>::from([ + ("dur", chrono::Duration::milliseconds(1527).into()), + ( + "ts", + chrono::DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00") + .unwrap() + .into(), + ), + ]) + .into(), + ), + Value::Map( + HashMap::<_, Value>::from([ + ("dur", chrono::Duration::nanoseconds(-1527000000).into()), + ( + "ts", + "-0001-12-01T00:00:00-08:00" + .parse::>() + .unwrap() + .into(), + ), + ]) + .into(), + ), + Value::Map( + HashMap::<_, Value>::from([ + ("dur", chrono::Duration::nanoseconds(-1).into()), + ( + "ts", + chrono::DateTime::parse_from_rfc3339("0001-12-01T00:00:00+08:00") + .unwrap() + .into(), + ), + ]) + .into(), + ), + Value::Map( + HashMap::<_, Value>::from([ + ("dur", chrono::Duration::nanoseconds(1).into()), + ( + "ts", + chrono::DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00") + .unwrap() + .into(), + ), + ]) + .into(), + ), + ] + .into(); + assert_eq!(tests, expected); + + let program = Program::compile("test == expected").unwrap(); + let mut context = Context::default(); + context.add_variable("expected", expected).unwrap(); + context.add_variable("test", tests).unwrap(); + let value = program.execute(&context).unwrap(); + assert_eq!(value, true.into()); + } + + #[cfg(feature = "chrono")] + #[cfg(feature = "json")] + #[test] + fn test_time_json() { + use chrono::FixedOffset; + + // Test that Durations and Timestamps serialize correctly with + // serde_json. + let tests = [ + TestTimeTypes { + dur: chrono::Duration::milliseconds(1527).into(), + ts: chrono::DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00") + .unwrap() + .into(), + }, + TestTimeTypes { + dur: chrono::Duration::milliseconds(-1527).into(), + ts: "-0001-12-01T00:00:00-08:00" + .parse::>() + .unwrap() + .into(), + }, + TestTimeTypes { + dur: (chrono::Duration::seconds(1) - chrono::Duration::nanoseconds(1000000001)) + .into(), + ts: chrono::DateTime::parse_from_rfc3339("0001-12-01T00:00:00+08:00") + .unwrap() + .into(), + }, + TestTimeTypes { + dur: (chrono::Duration::seconds(-1) + chrono::Duration::nanoseconds(1000000001)) + .into(), + ts: chrono::DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00") + .unwrap() + .into(), + }, + ]; + + let expect = "[\ +{\"dur\":{\"secs\":1,\"nanos\":527000000},\"ts\":\"1996-12-19T16:39:57-08:00\"},\ +{\"dur\":{\"secs\":-1,\"nanos\":-527000000},\"ts\":\"-0001-12-01T00:00:00-08:00\"},\ +{\"dur\":{\"secs\":0,\"nanos\":-1},\"ts\":\"0001-12-01T00:00:00+08:00\"},\ +{\"dur\":{\"secs\":0,\"nanos\":1},\"ts\":\"1996-12-19T16:39:57-08:00\"}\ +]"; + let actual = serde_json::to_string(&tests).unwrap(); + assert_eq!(actual, expect); + } +} diff --git a/vendor/cel/src/types/map.rs b/vendor/cel/src/types/map.rs new file mode 100644 index 0000000..2d0fa30 --- /dev/null +++ b/vendor/cel/src/types/map.rs @@ -0,0 +1,19 @@ +use crate::objects::{Key, Value}; +use std::fmt::Debug; + +/// A trait for map-like values that can provide CEL-compatible key lookup and +/// iteration semantics. +pub trait MapValue: Debug + Send + Sync { + /// Returns the value for the given key if present. + fn get(&self, key: &Key) -> Option; + + /// Returns true if the key exists in the map. + fn contains_key(&self, key: &Key) -> bool; + + /// Returns the number of entries in the map. + fn len(&self) -> usize; + + /// Returns an iterator over key/value pairs. Implementations may clone the + /// underlying data as needed. + fn iter(&self) -> Box + '_>; +} diff --git a/vendor/cel/src/types/mod.rs b/vendor/cel/src/types/mod.rs new file mode 100644 index 0000000..1d7f53b --- /dev/null +++ b/vendor/cel/src/types/mod.rs @@ -0,0 +1 @@ +pub mod map;