cedar_policy_validator/cedar_schema/
parser.rs1use std::sync::Arc;
20
21use lalrpop_util::lalrpop_mod;
22use miette::Diagnostic;
23use thiserror::Error;
24
25use super::{
26 ast::Schema,
27 err::{self, ParseError, ParseErrors, SchemaWarning, ToJsonSchemaErrors},
28 to_json_schema::cedar_schema_to_json_schema,
29};
30use crate::json_schema;
31use cedar_policy_core::extensions::Extensions;
32
33lalrpop_mod!(
34 #[allow(warnings, unused, missing_docs, missing_debug_implementations)]
35 #[allow(clippy::unwrap_used)]
37 #[allow(clippy::indexing_slicing)]
39 #[allow(clippy::unreachable)]
41 #[allow(clippy::panic)]
43 pub grammar,
44 "/src/cedar_schema/grammar.rs"
45);
46
47fn parse_collect_errors<'a, P, T>(
51 parser: &P,
52 parse: impl FnOnce(
53 &P,
54 &mut Vec<err::RawErrorRecovery<'a>>,
55 &Arc<str>,
56 &'a str,
57 ) -> Result<T, err::RawParseError<'a>>,
58 text: &'a str,
59) -> Result<T, err::ParseErrors> {
60 let mut errs = Vec::new();
61 let result = parse(parser, &mut errs, &Arc::from(text), text);
62
63 let errors = errs
64 .into_iter()
65 .map(|rc| ParseError::from_raw_error_recovery(rc, Arc::from(text)))
66 .collect::<Vec<ParseError>>();
67 let parsed = match result {
68 Ok(parsed) => parsed,
69 Err(e) => {
70 return Err(ParseErrors::new(
71 ParseError::from_raw_parse_error(e, Arc::from(text)),
72 errors,
73 ));
74 }
75 };
76 match ParseErrors::from_iter(errors) {
77 Some(errors) => Err(errors),
78 None => Ok(parsed),
80 }
81}
82
83lazy_static::lazy_static! {
85 static ref SCHEMA_PARSER: grammar::SchemaParser = grammar::SchemaParser::new();
86 static ref TYPE_PARSER: grammar::TypeParser = grammar::TypeParser::new();
87}
88
89#[derive(Debug, Diagnostic, Error)]
93#[non_exhaustive]
94pub enum CedarSchemaParseErrors {
95 #[error(transparent)]
97 #[diagnostic(transparent)]
98 SyntaxError(#[from] err::ParseErrors),
99 #[error(transparent)]
101 #[diagnostic(transparent)]
102 JsonError(#[from] ToJsonSchemaErrors),
103}
104
105pub fn parse_cedar_schema_fragment<'a>(
108 src: &str,
109 extensions: &Extensions<'a>,
110) -> Result<
111 (
112 json_schema::Fragment<crate::RawName>,
113 impl Iterator<Item = SchemaWarning> + 'a,
114 ),
115 CedarSchemaParseErrors,
116> {
117 let ast: Schema = parse_collect_errors(&*SCHEMA_PARSER, grammar::SchemaParser::parse, src)?;
118 let tuple = cedar_schema_to_json_schema(ast, extensions)?;
119 Ok(tuple)
120}
121
122pub fn parse_schema(text: &str) -> Result<Schema, err::ParseErrors> {
124 parse_collect_errors(&*SCHEMA_PARSER, grammar::SchemaParser::parse, text)
125}