Skip to content

Commit

Permalink
feat(validator): box direct recursive children
Browse files Browse the repository at this point in the history
  • Loading branch information
6d7a committed Sep 18, 2024
1 parent 85b70f2 commit 48706ce
Show file tree
Hide file tree
Showing 15 changed files with 235 additions and 26 deletions.
35 changes: 35 additions & 0 deletions rasn-compiler-tests/tests/edge_cases.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,41 @@
#![allow(non_camel_case_types)]
use rasn_compiler::prelude::RasnBackend;
use rasn_compiler_tests::e2e_pdu;

#[test]
fn recursion() {
println!(
"{}",
rasn_compiler::Compiler::<RasnBackend, _>::new()
.add_asn_literal(
r#"
TestModule DEFINITIONS AUTOMATIC TAGS::= BEGIN
Filter ::= CHOICE {
and [0] SET SIZE (1..MAX) OF filter Filter,
or [1] SET SIZE (1..MAX) OF filter Filter,
not [2] Filter,
equalityMatch [3] AttributeValueAssertion,
...
}
AttributeValueAssertion ::= SEQUENCE {
attributeDesc AttributeDescription,
assertionValue AssertionValue }
AssertionValue ::= OCTET STRING
AttributeDescription ::= LDAPString
LDAPString ::= [UNIVERSAL 4] IMPLICIT UTF8String
END
"#
)
.compile_to_string()
.unwrap()
.generated
)
}

e2e_pdu!(
distinguished_value_range,
r#" Restricted ::= Distinguished (second|fourth..sixth|eighth)
Expand Down
2 changes: 1 addition & 1 deletion rasn-compiler/src/generator/rasn/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,7 @@ impl Rasn {
.iter()
.map(|o| {
let (_, formatted_type_name) =
self.constraints_and_type_name(&o.ty, &o.name, &name.to_string())?;
self.constraints_and_type_name(&o.ty, &o.name, &name.to_string(), o.is_recursive)?;

let o_name = self.to_rust_enum_identifier(&o.name);
map.entry(formatted_type_name.to_string())
Expand Down
52 changes: 41 additions & 11 deletions rasn-compiler/src/generator/rasn/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,12 @@ impl Rasn {
extension_annotation: TokenStream,
) -> Result<(TokenStream, NameType), GeneratorError> {
let name = self.to_rust_snake_case(&member.name);
let (mut all_constraints, mut formatted_type_name) =
self.constraints_and_type_name(&member.ty, &member.name, parent_name)?;
let (mut all_constraints, mut formatted_type_name) = self.constraints_and_type_name(
&member.ty,
&member.name,
parent_name,
member.is_recursive,
)?;
all_constraints.append(&mut member.constraints.clone());
if (member.is_optional && member.default_value.is_none())
|| member.name.starts_with("ext_group_")
Expand Down Expand Up @@ -402,8 +406,12 @@ impl Rasn {
parent_name: &String,
extension_annotation: TokenStream,
) -> Result<TokenStream, GeneratorError> {
let (mut all_constraints, formatted_type_name) =
self.constraints_and_type_name(&member.ty, &member.name, parent_name)?;
let (mut all_constraints, formatted_type_name) = self.constraints_and_type_name(
&member.ty,
&member.name,
parent_name,
member.is_recursive,
)?;
all_constraints.append(&mut member.constraints.clone());
let range_annotations = self.format_range_annotations(
matches!(member.ty, ASN1Type::Integer(_)),
Expand Down Expand Up @@ -435,6 +443,7 @@ impl Rasn {
ty: &ASN1Type,
name: &String,
parent_name: &String,
is_recursive: bool,
) -> Result<(Vec<Constraint>, TokenStream), GeneratorError> {
Ok(match ty {
ASN1Type::Null => (vec![], quote!(())),
Expand Down Expand Up @@ -469,16 +478,29 @@ impl Rasn {
| ASN1Type::Choice(_)
| ASN1Type::Sequence(_)
| ASN1Type::SetOf(_)
| ASN1Type::Set(_) => (vec![], self.inner_name(name, parent_name).to_token_stream()),
| ASN1Type::Set(_) => {
let mut tokenized = self.inner_name(name, parent_name).to_token_stream();
if is_recursive {
tokenized = boxed_type(tokenized);
}
(vec![], tokenized)
}
ASN1Type::SequenceOf(s) => {
let (_, inner_type) =
self.constraints_and_type_name(&s.element_type, name, parent_name)?;
let (_, inner_type) = self.constraints_and_type_name(
&s.element_type,
name,
parent_name,
s.is_recursive,
)?;
(s.constraints().clone(), quote!(SequenceOf<#inner_type>))
}
ASN1Type::ElsewhereDeclaredType(e) => (
e.constraints.clone(),
self.to_rust_title_case(&e.identifier).to_token_stream(),
),
ASN1Type::ElsewhereDeclaredType(e) => {
let mut tokenized = self.to_rust_title_case(&e.identifier).to_token_stream();
if is_recursive {
tokenized = boxed_type(tokenized);
};
(e.constraints.clone(), tokenized)
}
ASN1Type::InformationObjectFieldReference(_)
| ASN1Type::EmbeddedPdv
| ASN1Type::External => (vec![], quote!(Any)),
Expand Down Expand Up @@ -1042,6 +1064,10 @@ impl Rasn {
}
}

fn boxed_type(tokens: TokenStream) -> TokenStream {
quote!(Box<#tokens>)
}

impl ASN1Value {
pub(crate) fn is_const_type(&self) -> bool {
match self {
Expand Down Expand Up @@ -1144,6 +1170,7 @@ mod tests {
constraints: vec![],
members: vec![
SequenceOrSetMember {
is_recursive: false,
name: "testMember0".into(),
tag: None,
ty: ASN1Type::Boolean(Boolean {
Expand All @@ -1154,6 +1181,7 @@ mod tests {
constraints: vec![]
},
SequenceOrSetMember {
is_recursive: false,
name: "testMember1".into(),
tag: None,
ty: ASN1Type::Integer(Integer {
Expand Down Expand Up @@ -1238,6 +1266,7 @@ mod tests {
constraints: vec![],
options: vec![
ChoiceOption {
is_recursive: false,
name: "testMember0".into(),
tag: None,
ty: ASN1Type::Boolean(Boolean {
Expand All @@ -1246,6 +1275,7 @@ mod tests {
constraints: vec![]
},
ChoiceOption {
is_recursive: false,
name: "testMember1".into(),
tag: None,
ty: ASN1Type::Integer(Integer {
Expand Down
2 changes: 1 addition & 1 deletion rasn-compiler/src/intermediate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ impl
comments: value.0.join("\n"),
name: value.1.into(),
parameterization: value.2,
associated_type: value.3.into(),
associated_type: value.3,
value: value.4,
index: None,
}
Expand Down
6 changes: 6 additions & 0 deletions rasn-compiler/src/intermediate/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,13 +275,15 @@ pub struct SequenceOrSetOf {
/// # ;
/// ```
pub element_type: Box<ASN1Type>,
pub is_recursive: bool,
}

impl From<(Option<Vec<Constraint>>, ASN1Type)> for SequenceOrSetOf {
fn from(value: (Option<Vec<Constraint>>, ASN1Type)) -> Self {
Self {
constraints: value.0.unwrap_or_default(),
element_type: Box::new(value.1),
is_recursive: false,
}
}
}
Expand Down Expand Up @@ -437,6 +439,7 @@ pub struct SequenceOrSetMember {
pub ty: ASN1Type,
pub default_value: Option<ASN1Value>,
pub is_optional: bool,
pub is_recursive: bool,
pub constraints: Vec<Constraint>,
}

Expand Down Expand Up @@ -466,6 +469,7 @@ impl
ty: value.2,
is_optional: value.4.is_some() || value.5.is_some(),
default_value: value.5,
is_recursive: false,
constraints: value.3.unwrap_or_default(),
}
}
Expand Down Expand Up @@ -537,6 +541,7 @@ pub struct ChoiceOption {
pub tag: Option<AsnTag>,
pub ty: ASN1Type,
pub constraints: Vec<Constraint>,
pub is_recursive: bool,
}

impl From<(&str, Option<AsnTag>, ASN1Type, Option<Vec<Constraint>>)> for ChoiceOption {
Expand All @@ -546,6 +551,7 @@ impl From<(&str, Option<AsnTag>, ASN1Type, Option<Vec<Constraint>>)> for ChoiceO
tag: value.1,
ty: value.2,
constraints: value.3.unwrap_or_default(),
is_recursive: false,
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions rasn-compiler/src/lexer/choice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,18 +135,21 @@ mod tests {
extensible: Some(2),
options: vec![
ChoiceOption {
is_recursive: false,
name: "normal".into(),
tag: None,
ty: ASN1Type::Null,
constraints: vec![]
},
ChoiceOption {
is_recursive: false,
name: "high".into(),
tag: None,
ty: ASN1Type::Null,
constraints: vec![]
},
ChoiceOption {
is_recursive: false,
name: "medium".into(),
tag: None,
ty: ASN1Type::Null,
Expand Down Expand Up @@ -178,6 +181,7 @@ mod tests {
extensible: Some(1,),
options: vec![
ChoiceOption {
is_recursive: false,
name: "glc".into(),
tag: None,
ty: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
Expand All @@ -188,6 +192,7 @@ mod tests {
constraints: vec![],
},
ChoiceOption {
is_recursive: false,
name: "avc".into(),
tag: None,
ty: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
Expand All @@ -198,6 +203,7 @@ mod tests {
constraints: vec![],
},
ChoiceOption {
is_recursive: false,
name: "rsc".into(),
tag: None,
ty: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
Expand All @@ -208,6 +214,7 @@ mod tests {
constraints: vec![],
},
ChoiceOption {
is_recursive: false,
name: "isc".into(),
tag: None,
ty: ASN1Type::ElsewhereDeclaredType(DeclarationElsewhere {
Expand Down
2 changes: 2 additions & 0 deletions rasn-compiler/src/lexer/information_object_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ mod tests {
extensible: None,
options: vec![
ChoiceOption {
is_recursive: false,
name: "local".into(),
tag: None,
ty: ASN1Type::Integer(Integer {
Expand All @@ -287,6 +288,7 @@ mod tests {
constraints: vec![]
},
ChoiceOption {
is_recursive: false,
name: "global".into(),
tag: None,
ty: ASN1Type::OctetString(OctetString {
Expand Down
Loading

0 comments on commit 48706ce

Please sign in to comment.