1use std::cell::RefCell;
7use std::collections::HashMap;
8
9use crate::error::{pest_error_to_diagnostic, AidlError, ParseError};
10
11use convert_case::{Case, Casing};
12
13use pest::Parser;
14#[derive(pest_derive::Parser)]
15#[grammar = "aidl.pest"]
16pub struct AIDLParser;
17
18use crate::const_expr::{ConstExpr, ValueType};
19use crate::type_generator;
20use crate::Namespace;
21
22#[derive(Debug, Clone)]
23pub enum SymbolType {
24 EnumMember,
25 InterfaceConstant,
26 }
28
29#[derive(Debug, Clone)]
30pub struct Symbol {
31 #[allow(dead_code)]
32 pub name: String,
33 pub value: crate::const_expr::ConstExpr,
34 #[allow(dead_code)]
35 pub symbol_type: SymbolType,
36 #[allow(dead_code)]
37 pub namespace: Option<String>,
38}
39
40thread_local! {
41 static DECLARATION_MAP: RefCell<HashMap<Namespace, Declaration>> = RefCell::new(HashMap::new());
42 #[allow(clippy::missing_const_for_thread_local)]
43 static NAMESPACE_STACK: RefCell<Vec<Namespace>> = RefCell::new(Vec::new());
44 static DOCUMENT: RefCell<Document> = RefCell::new(Document::new());
45
46 static SYMBOL_TABLE: RefCell<HashMap<String, Symbol>> = RefCell::new(HashMap::new());
48
49 #[allow(clippy::missing_const_for_thread_local)]
51 static CURRENT_SOURCE_NAME: RefCell<String> = RefCell::new(String::new());
52 #[allow(clippy::missing_const_for_thread_local)]
53 static CURRENT_SOURCE_TEXT: RefCell<String> = RefCell::new(String::new());
54}
55
56fn make_parse_error(message: impl Into<String>, start: usize, end: usize) -> AidlError {
58 let filename = CURRENT_SOURCE_NAME.with(|name| name.borrow().clone());
59 let source = CURRENT_SOURCE_TEXT.with(|text| text.borrow().clone());
60 AidlError::from(ParseError {
61 src: miette::NamedSource::new(filename, source),
62 span: miette::SourceSpan::new(start.into(), end - start),
63 message: message.into(),
64 help: None,
65 })
66}
67
68#[derive(Debug, Clone)]
71pub struct SourceContext {
72 pub filename: String,
73 pub source: String,
74}
75
76impl SourceContext {
77 pub fn new(filename: impl Into<String>, source: impl Into<String>) -> Self {
78 Self {
79 filename: filename.into(),
80 source: source.into(),
81 }
82 }
83}
84
85pub struct SourceGuard;
88
89impl SourceGuard {
90 pub fn new(filename: &str, source: &str) -> Self {
91 CURRENT_SOURCE_NAME.with(|name| *name.borrow_mut() = filename.to_string());
92 CURRENT_SOURCE_TEXT.with(|text| *text.borrow_mut() = source.to_string());
93 SourceGuard
94 }
95}
96
97impl Drop for SourceGuard {
98 fn drop(&mut self) {
99 CURRENT_SOURCE_NAME.with(|name| name.borrow_mut().clear());
100 CURRENT_SOURCE_TEXT.with(|text| text.borrow_mut().clear());
101 }
102}
103
104pub fn current_source_name() -> String {
106 CURRENT_SOURCE_NAME.with(|name| name.borrow().clone())
107}
108
109pub fn current_source_text() -> String {
111 CURRENT_SOURCE_TEXT.with(|text| text.borrow().clone())
112}
113
114pub struct NamespaceGuard();
115
116impl NamespaceGuard {
117 pub fn new(ns: &Namespace) -> Self {
118 NAMESPACE_STACK.with(|vec| {
119 vec.borrow_mut().push(ns.clone());
120 });
121 Self()
122 }
123}
124
125impl Drop for NamespaceGuard {
126 fn drop(&mut self) {
127 NAMESPACE_STACK.with(|vec| {
128 vec.borrow_mut().pop();
129 });
130 }
131}
132
133pub fn current_namespace() -> Namespace {
134 NAMESPACE_STACK.with(|stack| stack.borrow().last().cloned().unwrap_or_default())
135}
136
137pub fn set_current_document(document: &Document) {
138 DOCUMENT.with(|doc| {
139 let mut doc = doc.borrow_mut();
140
141 doc.package = document.package.clone();
142 doc.imports = document.imports.clone();
143 })
144}
145
146fn make_ns_candidate(ns: &Namespace, name: &Namespace) -> Vec<Namespace> {
147 let mut res = Vec::new();
148
149 let mut curr_ns = ns.clone();
150 curr_ns.push_ns(name);
151 res.push(curr_ns.clone());
152
153 if name.ns.len() > 1 {
154 curr_ns.pop(); res.push(curr_ns);
156 }
157
158 res
159}
160
161#[derive(Debug)]
162pub struct LookupDecl {
163 pub decl: Declaration,
164 pub ns: Namespace,
165 pub name: Namespace,
166}
167
168pub fn lookup_decl_from_name(name: &str, style: &str) -> Option<LookupDecl> {
169 let mut namespace = Namespace::new(name, style);
170
171 let mut ns_vec = Vec::new();
172
173 let mut curr_ns = current_namespace();
175 ns_vec.append(&mut make_ns_candidate(&curr_ns, &namespace));
176
177 curr_ns.pop(); ns_vec.append(&mut make_ns_candidate(&curr_ns, &namespace));
179
180 DOCUMENT.with(|curr_doc| {
182 let curr_doc = curr_doc.borrow();
183
184 if let Some(package) = &curr_doc.package {
185 let package_ns = Namespace::new(package, Namespace::AIDL);
186 ns_vec.append(&mut make_ns_candidate(&package_ns, &namespace));
187 }
188
189 if let Some(imported) = curr_doc.imports.get(&namespace.ns[0]) {
190 let mut new_ns = Namespace::new(imported, Namespace::AIDL);
191 new_ns.ns.extend_from_slice(&namespace.ns[1..]);
192 ns_vec.push(new_ns);
193 }
194 });
195
196 let (decl, ns) = DECLARATION_MAP.with(|hashmap| {
197 for ns in &ns_vec {
198 if let Some(decl) = hashmap.borrow().get(ns) {
199 return Some((decl.clone(), ns.clone()));
200 }
201 }
202
203 let curr_ns = current_namespace();
204 if let Some(decl) = hashmap.borrow().get(&curr_ns) {
205 return Some((decl.clone(), curr_ns));
206 }
207
208 None
209 })?;
210
211 if namespace.ns.len() > 2 {
213 namespace.ns.drain(0..namespace.ns.len() - 2);
214 }
215
216 Some(LookupDecl {
217 decl,
218 ns,
219 name: namespace,
220 })
221}
222
223fn make_const_expr(const_expr: Option<&ConstExpr>, lookup_decl: &LookupDecl) -> ConstExpr {
224 if let Some(expr) = const_expr {
225 expr.clone()
226 } else {
227 let ns = current_namespace().relative_mod(&lookup_decl.ns);
228
229 let name = if !ns.is_empty() {
230 format!(
231 "{}{}{}",
232 ns,
233 Namespace::RUST,
234 lookup_decl.name.to_string(Namespace::RUST)
235 )
236 } else {
237 lookup_decl.name.to_string(Namespace::RUST)
238 };
239 ConstExpr::new(ValueType::Name(name))
240 }
241}
242
243fn lookup_name_from_decl(decl: &Declaration, lookup_decl: &LookupDecl) -> Option<ConstExpr> {
244 let lookup_ident = lookup_decl.name.ns.last().unwrap().to_owned();
245 match decl {
246 Declaration::Variable(decl) => {
247 if decl.identifier == lookup_ident {
248 Some(make_const_expr(decl.const_expr.as_ref(), lookup_decl))
249 } else {
250 None
251 }
252 }
253 Declaration::Interface(ref decl) => {
254 for var in &decl.constant_list {
255 if var.identifier == lookup_ident {
256 return Some(make_const_expr(var.const_expr.as_ref(), lookup_decl));
257 }
258 }
259 lookup_name_members(&decl.members, lookup_decl)
260 }
261
262 Declaration::Parcelable(ref decl) => lookup_name_members(&decl.members, lookup_decl),
263
264 Declaration::Enum(ref decl) => {
265 for enumerator in &decl.enumerator_list {
266 if enumerator.identifier == lookup_ident {
267 return Some(make_const_expr(None, lookup_decl));
268 }
269 }
270 lookup_name_members(&decl.members, lookup_decl)
271 }
272
273 Declaration::Union(ref decl) => lookup_name_members(&decl.members, lookup_decl),
274 }
275}
276
277fn lookup_name_members(members: &Vec<Declaration>, lookup_decl: &LookupDecl) -> Option<ConstExpr> {
278 for decl in members {
279 if let Some(expr) = lookup_name_from_decl(decl, lookup_decl) {
280 return Some(expr);
281 }
282 }
283 None
284}
285
286pub fn register_symbol(
288 name: &str,
289 value: ConstExpr,
290 symbol_type: SymbolType,
291 namespace: Option<&str>,
292) {
293 let symbol = Symbol {
294 name: name.to_string(),
295 value,
296 symbol_type,
297 namespace: namespace.map(|s| s.to_string()),
298 };
299
300 SYMBOL_TABLE.with(|table| {
301 let mut table = table.borrow_mut();
302
303 table.insert(name.to_string(), symbol.clone());
305
306 if let Some(ns) = namespace {
308 let qualified_name = format!("{}.{}", ns, name);
309 table.insert(qualified_name, symbol);
310 }
311 });
312}
313
314pub fn name_to_const_expr(name: &str) -> Option<ConstExpr> {
319 let symbol_result =
321 SYMBOL_TABLE.with(|table| table.borrow().get(name).map(|symbol| symbol.value.clone()));
322
323 if symbol_result.is_some() {
324 return symbol_result;
325 }
326
327 if name.contains('.') {
332 if let Some(lookup_decl) = lookup_decl_from_name(name, Namespace::AIDL) {
333 if let Some(expr) = lookup_name_from_decl(&lookup_decl.decl, &lookup_decl) {
334 return Some(expr);
335 }
336 }
337 }
338
339 let alternative_formats = generate_name_variants(name);
341 for variant in alternative_formats {
342 let variant_result = SYMBOL_TABLE.with(|table| {
343 table
344 .borrow()
345 .get(&variant)
346 .map(|symbol| symbol.value.clone())
347 });
348 if variant_result.is_some() {
349 return variant_result;
350 }
351 }
352
353 if let Some(lookup_decl) = lookup_decl_from_name(name, Namespace::AIDL) {
355 return lookup_name_from_decl(&lookup_decl.decl, &lookup_decl);
356 }
357
358 None
359}
360
361fn generate_name_variants(name: &str) -> Vec<String> {
363 let mut variants = Vec::new();
364
365 if name.contains('.') {
368 let parts: Vec<&str> = name.split('.').collect();
369 for i in 0..parts.len() {
370 variants.push(parts[i..].join("."));
371 }
372 } else {
373 let current_ns = current_namespace().to_string(crate::Namespace::AIDL);
375
376 if !current_ns.is_empty() {
377 variants.push(format!("{}.{}", current_ns, name));
378 }
379 variants.push(name.to_string());
380 }
381
382 variants
383}
384
385#[derive(Debug)]
386pub struct Document {
387 pub package: Option<String>,
388 pub imports: HashMap<String, String>,
389 pub decls: Vec<Declaration>,
390}
391
392impl Document {
393 fn new() -> Self {
394 Self {
395 package: None,
396 imports: HashMap::new(),
397 decls: Vec::new(),
398 }
399 }
400}
401
402#[derive(Debug, Default, Clone)]
403pub struct VariableDecl {
404 pub constant: bool,
405 pub annotation_list: Vec<Annotation>,
406 pub r#type: Type,
407 pub identifier: String,
408 pub const_expr: Option<ConstExpr>,
409}
410
411impl VariableDecl {
412 pub fn identifier(&self) -> String {
413 self.identifier.to_owned()
414 }
415
416 pub fn const_identifier(&self) -> String {
417 self.identifier.to_uppercase()
418 }
419
420 pub fn union_identifier(&self) -> String {
421 self.identifier.to_case(Case::UpperCamel)
422 }
423
424 pub fn member_init(&self) -> String {
425 "Default::default()".into()
426 }
427}
428
429#[derive(Debug, Default, Clone)]
430pub struct InterfaceDecl {
431 pub namespace: Namespace,
432 pub annotation_list: Vec<Annotation>,
433 pub oneway: bool,
434 pub name: String,
435 pub name_span: Option<(usize, usize)>,
436 pub method_list: Vec<MethodDecl>,
437 pub constant_list: Vec<VariableDecl>,
438 pub members: Vec<Declaration>,
439}
440
441impl InterfaceDecl {
442 pub fn pre_process(&mut self) {
443 for decl in &mut self.constant_list {
444 decl.const_expr = decl
445 .const_expr
446 .as_ref()
447 .map(|expr| expr.calculate().unwrap_or_else(|_| expr.clone()));
448 }
449 }
450}
451
452#[derive(Debug, Default, Clone)]
453pub struct ParcelableDecl {
454 pub annotation_list: Vec<Annotation>,
455 pub namespace: Namespace,
456 pub name: String,
457 pub type_params: Vec<String>,
458 pub cpp_header: String,
459 pub ndk_header: String,
460 pub rust_type: String,
461 pub members: Vec<Declaration>,
462 }
464
465impl ParcelableDecl {
466 pub fn pre_process(&mut self) {
467 for decl in &mut self.members {
468 if let Declaration::Variable(decl) = decl {
469 decl.const_expr = decl
470 .const_expr
471 .as_ref()
472 .map(|expr| expr.calculate().unwrap_or_else(|_| expr.clone()));
473 }
474 }
475 }
476}
477
478#[derive(Debug, Default, Clone)]
479pub enum Direction {
480 #[default]
481 None,
482 In,
483 Out,
484 Inout,
485}
486
487#[derive(Debug, Default, Clone)]
488pub struct Arg {
489 pub direction: Direction,
490 pub direction_span: Option<(usize, usize)>,
491 pub r#type: Type,
492 pub identifier: String,
493}
494
495impl Arg {
496 pub fn to_generator(&self) -> Result<type_generator::TypeGenerator, crate::error::AidlError> {
497 let generator = type_generator::TypeGenerator::new_with_type(&self.r#type)?;
498
499 Ok(generator
500 .direction_at(&self.direction, self.direction_span)?
501 .identifier(&self.identifier))
502 }
503
504 pub fn is_mutable(&self) -> bool {
520 match self.direction {
521 Direction::Inout | Direction::Out => true,
522 Direction::In => false,
523 _ => false,
524 }
525 }
526}
527
528#[derive(Debug, Default, Clone)]
529pub struct MethodDecl {
530 pub annotation_list: Vec<Annotation>,
531 pub oneway: bool,
532 pub r#type: Type,
533 pub identifier: String,
534 pub identifier_span: Option<(usize, usize)>,
535 pub arg_list: Vec<Arg>,
536 pub intvalue: Option<i64>,
537 pub intvalue_span: Option<(usize, usize)>,
538}
539
540#[derive(Debug, Clone)]
541pub enum Declaration {
542 Parcelable(ParcelableDecl),
543 Interface(InterfaceDecl),
544 Enum(EnumDecl),
545 Union(UnionDecl),
546 Variable(VariableDecl),
547}
548
549impl Declaration {
550 pub fn is_variable(&self) -> Option<&VariableDecl> {
551 if let Declaration::Variable(decl) = self {
552 Some(decl)
553 } else {
554 None
555 }
556 }
557
558 pub fn namespace(&self) -> &Namespace {
559 match self {
560 Declaration::Parcelable(decl) => &decl.namespace,
561 Declaration::Interface(decl) => &decl.namespace,
562 Declaration::Enum(decl) => &decl.namespace,
563 Declaration::Union(decl) => &decl.namespace,
564 _ => unreachable!(),
565 }
566 }
567
568 pub fn set_namespace(&mut self, namespace: Namespace) {
569 match self {
570 Declaration::Parcelable(decl) => decl.namespace = namespace,
571 Declaration::Interface(decl) => decl.namespace = namespace,
572 Declaration::Enum(decl) => decl.namespace = namespace,
573 Declaration::Union(decl) => decl.namespace = namespace,
574 _ => unreachable!(),
575 }
576 }
577
578 pub fn name(&self) -> &str {
579 match self {
580 Declaration::Parcelable(decl) => &decl.name,
581 Declaration::Interface(decl) => &decl.name,
582 Declaration::Enum(decl) => &decl.name,
583 Declaration::Union(decl) => &decl.name,
584 _ => unreachable!(),
585 }
586 }
587
588 pub fn members_mut(&mut self) -> &mut Vec<Declaration> {
589 match self {
590 Declaration::Parcelable(decl) => &mut decl.members,
591 Declaration::Interface(decl) => &mut decl.members,
592 Declaration::Enum(decl) => &mut decl.members,
593 Declaration::Union(decl) => &mut decl.members,
594 _ => unreachable!(),
595 }
596 }
597}
598
599#[derive(Debug, Clone)]
600pub struct Parameter {
601 identifier: String,
602 const_expr: ConstExpr,
603}
604
605#[derive(Debug, Default, Clone)]
606pub struct Annotation {
607 pub annotation: String,
608 pub const_expr: Option<ConstExpr>,
609 pub parameter_list: Vec<Parameter>,
610 pub annotation_span: Option<(usize, usize)>,
611}
612
613#[derive(Debug, Clone)]
614pub enum Generic {
615 Type1 {
616 type_args1: Vec<Type>,
617 non_array_type: NonArrayType,
618 type_args2: Vec<Type>,
619 },
620 Type2 {
621 non_array_type: NonArrayType,
622 type_args: Vec<Type>,
623 },
624 Type3 {
625 type_args: Vec<Type>,
626 },
627}
628
629impl Generic {
644 pub fn to_value_type(&self) -> Result<ValueType, crate::error::AidlError> {
645 let generator = match self {
646 Generic::Type1 {
647 type_args1,
648 non_array_type: _,
649 type_args2: _,
650 } => type_generator::TypeGenerator::new_with_type(&type_args1[0])?,
651 Generic::Type2 {
652 non_array_type,
653 type_args: _,
654 } => type_generator::TypeGenerator::new(non_array_type)?,
655 Generic::Type3 { type_args } => {
656 type_generator::TypeGenerator::new_with_type(&type_args[0])?
657 }
658 };
659
660 Ok(generator.value_type)
661 }
662}
663
664#[derive(Debug, Default, Clone)]
665pub struct NonArrayType {
666 pub name: String,
667 pub generic: Option<Box<Generic>>,
668 pub name_span: Option<(usize, usize)>,
669}
670
671#[derive(Debug, Default, Clone)]
672pub struct ArrayType {
673 pub const_expr: Option<ConstExpr>,
674}
675
676#[derive(Debug, Default, Clone)]
677pub struct Type {
678 pub annotation_list: Vec<Annotation>,
679 pub non_array_type: NonArrayType,
680 pub array_types: Vec<ArrayType>,
681}
682
683impl Type {
684 pub fn to_generator(&self) -> Result<type_generator::TypeGenerator, crate::error::AidlError> {
685 type_generator::TypeGenerator::new_with_type(self)
686 }
687}
688
689#[derive(PartialEq)]
690pub enum AnnotationType {
691 IsNullable,
692 JavaOnly,
693 RustDerive,
694 VintfStability,
695}
696
697pub fn check_annotation_list(
698 annotation_list: &Vec<Annotation>,
699 query_type: AnnotationType,
700) -> (bool, String) {
701 for annotation in annotation_list {
702 match query_type {
703 AnnotationType::VintfStability if annotation.annotation == "@VintfStability" => {
704 return (true, "".to_owned())
705 }
706 AnnotationType::IsNullable if annotation.annotation == "@nullable" => {
707 return (true, "".to_owned())
708 }
709 AnnotationType::JavaOnly if annotation.annotation.starts_with("@JavaOnly") => {
710 return (true, "".to_owned())
711 }
712 AnnotationType::RustDerive if annotation.annotation == "@RustDerive" => {
713 let mut derives = Vec::new();
714
715 for param in &annotation.parameter_list {
716 if param.const_expr.to_bool().unwrap_or(false) {
717 derives.push(param.identifier.to_owned())
718 }
719 }
720
721 return (true, derives.join(","));
722 }
723 _ => {}
724 }
725 }
726
727 (false, "".to_owned())
728}
729
730pub fn get_descriptor_from_annotation_list(annotation_list: &Vec<Annotation>) -> Option<String> {
731 for annotation in annotation_list {
732 if annotation.annotation == "@Descriptor" {
733 for param in &annotation.parameter_list {
734 if param.identifier == "value" {
735 return Some(param.const_expr.to_value_string());
736 }
737 }
738 }
739 }
740
741 None
742}
743
744pub fn get_backing_type(
745 annotation_list: &Vec<Annotation>,
746 name_span: Option<(usize, usize)>,
747) -> Result<type_generator::TypeGenerator, crate::error::AidlError> {
748 for annotation in annotation_list {
750 if annotation.annotation == "@Backing" {
751 for param in &annotation.parameter_list {
752 if param.identifier == "type" {
753 return type_generator::TypeGenerator::new(&NonArrayType {
754 name: param.const_expr.to_value_string().trim_matches('"').into(),
756 generic: None,
757 name_span,
758 });
759 }
760 }
761 }
762 }
763
764 type_generator::TypeGenerator::new(&NonArrayType {
765 name: "byte".into(),
767 generic: None,
768 name_span: None,
769 })
770}
771
772fn parse_unary(mut pairs: pest::iterators::Pairs<Rule>) -> Result<ConstExpr, AidlError> {
773 let operator = pairs.next().unwrap().as_str().to_owned();
774 let factor = parse_factor(pairs.next().unwrap().into_inner().next().unwrap())?;
775 Ok(ConstExpr::new_unary(&operator, factor))
776}
777
778fn parse_intvalue(arg_value: &str, span: (usize, usize)) -> Result<ConstExpr, AidlError> {
779 let mut is_u8 = false;
780 let mut is_long = false;
781
782 let (value, radix) = if arg_value.starts_with("0x") || arg_value.starts_with("0X") {
783 (&arg_value[2..], 16)
784 } else {
785 (arg_value, 10)
786 };
787
788 let value = if value.ends_with('l') || value.ends_with('L') {
789 is_long = true;
790 &value[..value.len() - 1]
791 } else if let Some(stripped) = value.strip_suffix("u8") {
792 is_u8 = true;
793 stripped
794 } else {
795 value
796 };
797
798 if radix == 16 {
799 if is_u8 {
800 let parsed_value = u8::from_str_radix(value, radix).map_err(|err| {
801 make_parse_error(
802 format!("invalid u8 hex literal '{arg_value}': {err}"),
803 span.0,
804 span.1,
805 )
806 })?;
807 Ok(ConstExpr::new(ValueType::Byte(parsed_value as _)))
808 } else if !is_long {
809 if let Ok(parsed_value) = u32::from_str_radix(value, radix) {
810 Ok(ConstExpr::new(ValueType::Int32(parsed_value as i32 as _)))
811 } else {
812 let parsed_value = u64::from_str_radix(value, radix).map_err(|err| {
813 make_parse_error(
814 format!("invalid hex literal '{arg_value}': {err}"),
815 span.0,
816 span.1,
817 )
818 })?;
819 Ok(ConstExpr::new(ValueType::Int64(parsed_value as i64 as _)))
820 }
821 } else {
822 let parsed_value = u64::from_str_radix(value, radix).map_err(|err| {
823 make_parse_error(
824 format!("invalid hex literal '{arg_value}': {err}"),
825 span.0,
826 span.1,
827 )
828 })?;
829 Ok(ConstExpr::new(ValueType::Int64(parsed_value as i64 as _)))
830 }
831 } else {
832 let parsed_value = i64::from_str_radix(value, radix).map_err(|err| {
833 make_parse_error(
834 format!("invalid integer literal '{arg_value}': {err}"),
835 span.0,
836 span.1,
837 )
838 })?;
839 if is_u8 {
840 if parsed_value > u8::MAX.into() || parsed_value < 0 {
841 return Err(make_parse_error(
842 format!("u8 literal overflow: {parsed_value} is out of range (0..=255)"),
843 span.0,
844 span.1,
845 ));
846 }
847 Ok(ConstExpr::new(ValueType::Byte(parsed_value as i8 as _)))
848 } else if is_long {
849 Ok(ConstExpr::new(ValueType::Int64(parsed_value as _)))
850 } else if parsed_value <= i8::MAX.into() && parsed_value >= i8::MIN.into() {
851 Ok(ConstExpr::new(ValueType::Byte(parsed_value as i8 as _)))
852 } else if parsed_value <= i32::MAX.into() && parsed_value >= i32::MIN.into() {
853 Ok(ConstExpr::new(ValueType::Int32(parsed_value as i32 as _)))
854 } else {
855 Ok(ConstExpr::new(ValueType::Int64(parsed_value as _)))
856 }
857 }
858}
859
860fn parse_value(pair: pest::iterators::Pair<Rule>) -> Result<ConstExpr, AidlError> {
861 match pair.as_rule() {
862 Rule::qualified_name => Ok(ConstExpr::new(ValueType::Name(pair.as_str().into()))),
863 Rule::HEXVALUE | Rule::INTVALUE => {
864 let span = pair.as_span();
865 parse_intvalue(pair.as_str(), (span.start(), span.end()))
866 }
867 Rule::FLOATVALUE => {
868 let span = pair.as_span();
869 let value = pair.as_str();
870 let value = if let Some(stripped) = value.strip_suffix('f') {
871 stripped
872 } else {
873 value
874 };
875 let f = value.parse::<f64>().map_err(|_| {
876 make_parse_error(
877 format!("invalid float literal: {}", pair.as_str()),
878 span.start(),
879 span.end(),
880 )
881 })?;
882 Ok(ConstExpr::new(ValueType::Double(f as _)))
883 }
884 Rule::TRUE_LITERAL => Ok(ConstExpr::new(ValueType::Bool(true))),
885 Rule::FALSE_LITERAL => Ok(ConstExpr::new(ValueType::Bool(false))),
886 _ => unreachable!("Unexpected rule in parse_value(): {}", pair),
887 }
888}
889
890fn parse_factor(pair: pest::iterators::Pair<Rule>) -> Result<ConstExpr, AidlError> {
891 match pair.as_rule() {
893 Rule::expression => parse_expression(pair.clone().into_inner()),
894 Rule::unary => parse_unary(pair.into_inner()),
895 Rule::value => parse_value(pair.into_inner().next().unwrap()),
896 _ => unreachable!("Unexpected rule in parse_factor(): {}", pair),
897 }
898}
899
900fn parse_expression_term(pair: pest::iterators::Pair<Rule>) -> Result<ConstExpr, AidlError> {
901 match pair.as_rule() {
902 Rule::equality
903 | Rule::comparison
904 | Rule::bitwise_or
905 | Rule::bitwise_xor
906 | Rule::bitwise_and
907 | Rule::shift
908 | Rule::arith
909 | Rule::logical_or
910 | Rule::logical_and => parse_expression(pair.clone().into_inner()),
911 Rule::factor => parse_factor(pair.into_inner().next().unwrap()),
912 _ => unreachable!("Unexpected rule in Rule::parse_expression_into: {}", pair),
913 }
914}
915
916fn parse_expression(mut pairs: pest::iterators::Pairs<Rule>) -> Result<ConstExpr, AidlError> {
917 let mut lhs = parse_expression_term(pairs.next().unwrap())?;
918
919 while let Some(pair) = pairs.next() {
920 let op = pair.as_str().to_owned();
921 let rhs = parse_expression_term(pairs.next().unwrap())?;
922
923 lhs = ConstExpr::new_expr(lhs, &op, rhs)
924 }
925
926 Ok(lhs)
927}
928
929fn parse_string_term(pair: pest::iterators::Pair<Rule>) -> ConstExpr {
930 match pair.as_rule() {
931 Rule::C_STR => {
932 let string = pair.as_str();
933 ConstExpr::new(ValueType::String(string[1..string.len() - 1].into()))
934 }
935 Rule::qualified_name => ConstExpr::new(ValueType::Name(pair.as_str().into())),
936 _ => unreachable!("Unexpected rule in Rule::parse_string_term: {}", pair),
937 }
938}
939
940fn parse_string_expr(pairs: pest::iterators::Pairs<Rule>) -> Result<ConstExpr, AidlError> {
941 let mut expr: Option<ConstExpr> = None;
942
943 for pair in pairs {
944 match pair.as_rule() {
945 Rule::string_term => {
946 let term = parse_string_term(pair.into_inner().next().unwrap());
947 expr = match expr {
948 Some(expr) => Some(ConstExpr::new_expr(expr, "+", term)),
949 None => Some(term),
950 }
951 }
952 _ => unreachable!("Unexpected rule in Rule::parse_string_expr: {}", pair),
953 }
954 }
955
956 Ok(expr.expect("internal: empty string_expr"))
957}
958
959fn parse_const_expr(pair: pest::iterators::Pair<Rule>) -> Result<ConstExpr, AidlError> {
960 match pair.as_rule() {
961 Rule::constant_value_list => {
962 let mut value_list = Vec::new();
963 for pair in pair.into_inner() {
964 match pair.as_rule() {
965 Rule::const_expr => {
966 value_list.push(parse_const_expr(pair.into_inner().next().unwrap())?);
967 }
968 _ => unreachable!("Unexpected rule in Rule::constant_value_list: {}", pair),
969 }
970 }
971 Ok(ConstExpr::new(ValueType::Array(value_list)))
972 }
973
974 Rule::CHARVALUE => {
975 let mut found = false;
976 let mut has_backslash = false;
977 for ch in pair.as_str().chars() {
978 if !found && ch == '\'' {
979 found = true;
980 } else if found {
981 if !has_backslash && ch == '\\' {
982 has_backslash = true;
983 } else {
984 return Ok(ConstExpr::new(ValueType::Char(ch)));
985 }
986 }
987 }
988 unreachable!()
989 }
990
991 Rule::expression => parse_expression(pair.clone().into_inner()),
992
993 Rule::string_expr => parse_string_expr(pair.into_inner()),
994
995 _ => unreachable!("Unexpected rule in parse_const_expr(): {}", pair),
996 }
997}
998
999fn parse_parameter(pairs: pest::iterators::Pairs<Rule>) -> Result<Parameter, AidlError> {
1000 let mut parameter = Parameter {
1001 identifier: "".to_string(),
1002 const_expr: ConstExpr::default(),
1003 };
1004
1005 for pair in pairs {
1006 match pair.as_rule() {
1007 Rule::identifier => {
1008 parameter.identifier = pair.as_str().into();
1009 }
1010 Rule::const_expr => {
1011 parameter.const_expr = parse_const_expr(pair.into_inner().next().unwrap())?;
1012 }
1013 _ => unreachable!("Unexpected rule in parse_parameter(): {}", pair),
1014 }
1015 }
1016
1017 Ok(parameter)
1018}
1019
1020fn parse_parameter_list(pairs: pest::iterators::Pairs<Rule>) -> Result<Vec<Parameter>, AidlError> {
1021 let mut list = Vec::new();
1022 for pair in pairs {
1023 list.push(parse_parameter(pair.into_inner())?);
1024 }
1025
1026 Ok(list)
1027}
1028
1029fn parse_annotation(pairs: pest::iterators::Pairs<Rule>) -> Result<Annotation, AidlError> {
1030 let mut annotation = Annotation::default();
1031 for pair in pairs {
1032 match pair.as_rule() {
1033 Rule::ANNOTATION => {
1034 let span = pair.as_span();
1035 annotation.annotation = pair.as_str().into();
1036 annotation.annotation_span = Some((span.start(), span.end()));
1037 }
1038
1039 Rule::const_expr => {
1040 annotation.const_expr = Some(parse_const_expr(pair.into_inner().next().unwrap())?);
1041 }
1042
1043 Rule::parameter_list => {
1044 annotation.parameter_list = parse_parameter_list(pair.into_inner())?;
1045 }
1046
1047 _ => unreachable!("Unexpected rule in parse_annotation(): {}", pair),
1048 }
1049 }
1050
1051 Ok(annotation)
1052}
1053
1054fn parse_annotation_list(
1055 pairs: pest::iterators::Pairs<Rule>,
1056) -> Result<Vec<Annotation>, AidlError> {
1057 let mut annotation_list = Vec::new();
1058 for pair in pairs {
1059 annotation_list.push(parse_annotation(pair.into_inner())?);
1060 }
1061
1062 Ok(annotation_list)
1063}
1064
1065fn parse_type_args(pairs: pest::iterators::Pairs<Rule>) -> Result<Vec<Type>, AidlError> {
1066 let mut res = Vec::new();
1067
1068 for pair in pairs {
1069 match pair.as_rule() {
1070 Rule::r#type => res.push(parse_type(pair.into_inner())?),
1071 _ => unreachable!("Unexpected rule in parse_type_args(): {}", pair),
1072 }
1073 }
1074
1075 Ok(res)
1076}
1077
1078fn parse_non_array_type(pairs: pest::iterators::Pairs<Rule>) -> Result<NonArrayType, AidlError> {
1079 let mut non_array_type = NonArrayType::default();
1080
1081 for pair in pairs {
1082 match pair.as_rule() {
1083 Rule::qualified_name => {
1084 let span = pair.as_span();
1085 non_array_type.name = pair.as_str().into();
1086 non_array_type.name_span = Some((span.start(), span.end()));
1087 }
1088 Rule::generic_type1 => {
1089 let mut pairs = pair.into_inner();
1090 let generic = Generic::Type1 {
1091 type_args1: parse_type_args(pairs.next().unwrap().into_inner())?,
1092 non_array_type: parse_non_array_type(pairs.next().unwrap().into_inner())?,
1093 type_args2: parse_type_args(pairs.next().unwrap().into_inner())?,
1094 };
1095
1096 non_array_type.generic = Some(Box::new(generic));
1097 }
1098
1099 Rule::generic_type2 => {
1100 let mut pairs = pair.into_inner();
1101 let generic = Generic::Type2 {
1102 non_array_type: parse_non_array_type(pairs.next().unwrap().into_inner())?,
1103 type_args: parse_type_args(pairs.next().unwrap().into_inner())?,
1104 };
1105
1106 non_array_type.generic = Some(Box::new(generic));
1107 }
1108 Rule::generic_type3 => {
1109 let mut pairs = pair.into_inner();
1110 let generic = Generic::Type3 {
1111 type_args: parse_type_args(pairs.next().unwrap().into_inner())?,
1112 };
1113
1114 non_array_type.generic = Some(Box::new(generic));
1115 }
1116 _ => {
1117 unreachable!();
1118 }
1119 }
1120 }
1121
1122 Ok(non_array_type)
1123}
1124
1125fn parse_array_type(pairs: pest::iterators::Pairs<Rule>) -> Result<ArrayType, AidlError> {
1126 let mut array_type = ArrayType::default();
1127
1128 for pair in pairs {
1129 match pair.as_rule() {
1130 Rule::const_expr => {
1131 array_type.const_expr = Some(parse_const_expr(pair.into_inner().next().unwrap())?);
1132 }
1133 _ => unreachable!("Unexpected rule in parse_array_type(): {}", pair),
1134 }
1135 }
1136
1137 Ok(array_type)
1138}
1139
1140fn parse_type(pairs: pest::iterators::Pairs<Rule>) -> Result<Type, AidlError> {
1141 let mut r#type = Type::default();
1142
1143 for pair in pairs {
1144 match pair.as_rule() {
1145 Rule::annotation_list => {
1146 r#type.annotation_list = parse_annotation_list(pair.into_inner())?;
1147 }
1148 Rule::non_array_type => {
1149 r#type.non_array_type = parse_non_array_type(pair.into_inner())?;
1150 }
1151 Rule::array_type => {
1152 r#type
1153 .array_types
1154 .push(parse_array_type(pair.into_inner())?);
1155 }
1156 _ => {
1157 unreachable!("Unexpected rule in parse_type(): {}", pair);
1158 }
1159 }
1160 }
1161
1162 Ok(r#type)
1163}
1164
1165fn parse_variable_decl(
1166 pairs: pest::iterators::Pairs<Rule>,
1167 constant: bool,
1168) -> Result<VariableDecl, AidlError> {
1169 let mut decl = VariableDecl {
1170 constant,
1171 ..Default::default()
1172 };
1173
1174 for pair in pairs {
1175 match pair.as_rule() {
1176 Rule::annotation_list => {
1177 decl.annotation_list = parse_annotation_list(pair.into_inner())?;
1178 }
1179 Rule::r#type => {
1180 decl.r#type = parse_type(pair.into_inner())?;
1181 }
1182 Rule::identifier => {
1183 decl.identifier = pair.as_str().into();
1184 }
1185 Rule::const_expr => match pair.into_inner().next() {
1186 Some(pair) => decl.const_expr = Some(parse_const_expr(pair)?),
1187 None => decl.const_expr = None,
1188 },
1189 _ => unreachable!(
1190 "Unexpected rule in parse_variable_decl(): {}\t{}",
1191 pair,
1192 pair.as_str()
1193 ),
1194 }
1195 }
1196
1197 Ok(decl)
1198}
1199
1200fn parse_arg(pairs: pest::iterators::Pairs<Rule>) -> Result<Arg, AidlError> {
1201 let mut arg = Arg::default();
1202
1203 for pair in pairs {
1204 match pair.as_rule() {
1205 Rule::direction => {
1206 let span = pair.as_span();
1207 arg.direction = match pair.as_str() {
1208 "in" => Direction::In,
1209 "out" => Direction::Out,
1210 "inout" => Direction::Inout,
1211 _ => {
1212 return Err(make_parse_error(
1213 format!("unsupported direction: {}", pair.as_str()),
1214 span.start(),
1215 span.end(),
1216 ));
1217 }
1218 };
1219 arg.direction_span = Some((span.start(), span.end()));
1220 }
1221 Rule::r#type => {
1222 arg.r#type = parse_type(pair.into_inner())?;
1223 }
1224 Rule::identifier => {
1225 arg.identifier = pair.as_str().into();
1226 }
1227 _ => unreachable!("Unexpected rule in parse_arg(): {}", pair),
1228 }
1229 }
1230
1231 Ok(arg)
1232}
1233
1234fn parse_method_decl(pairs: pest::iterators::Pairs<Rule>) -> Result<MethodDecl, AidlError> {
1235 let mut decl = MethodDecl::default();
1236
1237 for pair in pairs {
1238 match pair.as_rule() {
1239 Rule::annotation_list => {
1240 decl.annotation_list = parse_annotation_list(pair.into_inner())?;
1241 }
1242 Rule::ONEWAY => {
1243 decl.oneway = true;
1244 }
1245 Rule::r#type => {
1246 decl.r#type = parse_type(pair.into_inner())?;
1247 }
1248 Rule::identifier => {
1249 let span = pair.as_span();
1250 decl.identifier = pair.as_str().into();
1251 decl.identifier_span = Some((span.start(), span.end()));
1252 }
1253 Rule::arg_list => {
1254 for pair in pair.into_inner() {
1255 match pair.as_rule() {
1256 Rule::arg => {
1257 decl.arg_list.push(parse_arg(pair.into_inner())?);
1258 }
1259 _ => unreachable!(
1260 "Unexpected rule in parse_method_decl(): {}, \"{}\"",
1261 pair,
1262 pair.as_str()
1263 ),
1264 }
1265 }
1266 }
1267 Rule::INTVALUE => {
1268 let span = pair.as_span();
1269 let expr = parse_intvalue(pair.as_str(), (span.start(), span.end()))?
1270 .calculate()
1271 .map_err(|e| make_parse_error(e.message, span.start(), span.end()))?;
1272 decl.intvalue = Some(match expr.value {
1273 ValueType::Byte(v) => v as _,
1274 ValueType::Int32(v) => v as _,
1275 ValueType::Int64(v) => v,
1276 _ => unreachable!(
1277 "Unexpected Expression in parse_method_decl(): {}, \"{}\"",
1278 pair,
1279 pair.as_str()
1280 ),
1281 });
1282 decl.intvalue_span = Some((span.start(), span.end()));
1283 }
1284 _ => unreachable!(
1285 "Unexpected rule in parse_method_decl(): {}, \"{}\"",
1286 pair,
1287 pair.as_str()
1288 ),
1289 }
1290 }
1291
1292 Ok(decl)
1293}
1294
1295fn parse_interface_members(
1296 pairs: pest::iterators::Pairs<Rule>,
1297 interface: &mut InterfaceDecl,
1298) -> Result<(), AidlError> {
1299 for pair in pairs {
1300 match pair.as_rule() {
1301 Rule::method_decl => {
1302 interface
1303 .method_list
1304 .push(parse_method_decl(pair.into_inner())?);
1305 }
1306
1307 Rule::constant_decl => {
1308 interface
1309 .constant_list
1310 .push(parse_variable_decl(pair.into_inner(), true)?);
1311 }
1312
1313 Rule::interface_members => {
1314 parse_interface_members(pair.into_inner(), interface)?;
1315 }
1316
1317 Rule::decl => {
1318 interface
1319 .members
1320 .append(&mut parse_decl(pair.into_inner())?);
1321 }
1322
1323 _ => unreachable!("Unexpected rule in parse_interface_members(): {}", pair),
1324 }
1325 }
1326 Ok(())
1327}
1328
1329fn parse_interface_decl(
1330 annotation_list: Vec<Annotation>,
1331 pairs: pest::iterators::Pairs<Rule>,
1332) -> Result<Declaration, AidlError> {
1333 let mut interface = InterfaceDecl {
1334 annotation_list,
1335 ..Default::default()
1336 };
1337
1338 for pair in pairs {
1339 match pair.as_rule() {
1340 Rule::ONEWAY => {
1341 interface.oneway = true;
1342 }
1343
1344 Rule::qualified_name => {
1345 let span = pair.as_span();
1346 interface.name = pair.as_str().into();
1347 interface.name_span = Some((span.start(), span.end()));
1348 }
1349
1350 Rule::interface_members => {
1351 parse_interface_members(pair.into_inner(), &mut interface)?;
1352 }
1353
1354 _ => unreachable!("Unexpected rule in parse_interface_decl(): {}", pair),
1355 }
1356 }
1357
1358 Ok(Declaration::Interface(interface))
1359}
1360
1361fn parse_parcelable_members(
1362 pairs: pest::iterators::Pairs<Rule>,
1363) -> Result<Vec<Declaration>, AidlError> {
1364 let mut res = Vec::new();
1365
1366 for pair in pairs {
1367 match pair.as_rule() {
1368 Rule::variable_decl => {
1369 res.push(Declaration::Variable(parse_variable_decl(
1370 pair.into_inner(),
1371 false,
1372 )?));
1373 }
1374 Rule::constant_decl => {
1375 res.push(Declaration::Variable(parse_variable_decl(
1376 pair.into_inner(),
1377 true,
1378 )?));
1379 }
1380 Rule::decl => res.append(&mut parse_decl(pair.into_inner())?),
1381 _ => unreachable!("Unexpected rule in parse_parcelable_members(): {}", pair),
1382 }
1383 }
1384
1385 Ok(res)
1386}
1387
1388fn parse_optional_type_params(pairs: pest::iterators::Pairs<Rule>) -> Vec<String> {
1389 let mut res = Vec::new();
1390
1391 for pair in pairs {
1392 match pair.as_rule() {
1393 Rule::identifier => res.push(pair.as_str().into()),
1394 _ => unreachable!("Unexpected rule in parse_optional_type_params(): {}", pair),
1395 }
1396 }
1397
1398 res
1399}
1400
1401fn parse_unstructured_parcelable(
1402 parcelable: &mut ParcelableDecl,
1403 mut pairs: pest::iterators::Pairs<Rule>,
1404) -> Result<(), AidlError> {
1405 enum HeaderType {
1406 CppHeader,
1407 NdkHeader,
1408 RustType,
1409 }
1410
1411 let (first, second) = pairs
1412 .next()
1413 .zip(pairs.next())
1414 .expect("Incomplete rule in parse_unstructured_parcelable()");
1415
1416 let header = match first.as_rule() {
1417 Rule::CPP_HEADER => HeaderType::CppHeader,
1418 Rule::NDK_HEADER => HeaderType::NdkHeader,
1419 Rule::RUST_TYPE => HeaderType::RustType,
1420 _ => unreachable!(
1421 "Unexpected rule in parse_unstructured_parcelable(): {}",
1422 first
1423 ),
1424 };
1425
1426 match second.as_rule() {
1427 Rule::C_STR => {
1428 let str = second.as_str();
1429 let str = str[1..str.len() - 1].into();
1430 match header {
1431 HeaderType::CppHeader => parcelable.cpp_header = str,
1432 HeaderType::NdkHeader => parcelable.ndk_header = str,
1433 HeaderType::RustType => parcelable.rust_type = str,
1434 }
1435 }
1436 _ => unreachable!(
1437 "Unexpected rule in parse_unstructured_parcelable(): {}",
1438 second
1439 ),
1440 }
1441
1442 Ok(())
1443}
1444
1445fn parse_parcelable_decl(
1446 annotation_list: Vec<Annotation>,
1447 pairs: pest::iterators::Pairs<Rule>,
1448) -> Result<Declaration, AidlError> {
1449 let mut parcelable = ParcelableDecl {
1450 annotation_list,
1451 ..Default::default()
1452 };
1453
1454 for pair in pairs {
1455 match pair.as_rule() {
1456 Rule::qualified_name => {
1457 parcelable.name = pair.as_str().into();
1458 }
1459
1460 Rule::optional_type_params => {
1461 parcelable.type_params = parse_optional_type_params(pair.into_inner());
1462 }
1463
1464 Rule::parcelable_members => {
1465 parcelable
1466 .members
1467 .append(&mut parse_parcelable_members(pair.into_inner())?);
1468 }
1469
1470 Rule::optional_unstructured_headers => {
1471 parse_unstructured_parcelable(&mut parcelable, pair.into_inner())?;
1472 }
1473
1474 _ => unreachable!("Unexpected rule in parse_parcelable_decl(): {}", pair),
1475 }
1476 }
1477
1478 Ok(Declaration::Parcelable(parcelable))
1479}
1480
1481#[derive(Debug, Default, Clone)]
1482pub struct Enumerator {
1483 pub identifier: String,
1484 pub const_expr: Option<ConstExpr>,
1485}
1486
1487#[derive(Debug, Default, Clone)]
1488pub struct EnumDecl {
1489 pub namespace: Namespace,
1490 pub annotation_list: Vec<Annotation>,
1491 pub name: String,
1492 pub name_span: Option<(usize, usize)>,
1493 pub enumerator_list: Vec<Enumerator>,
1494 pub members: Vec<Declaration>,
1495}
1496
1497fn parse_enumerator(pairs: pest::iterators::Pairs<Rule>) -> Result<Enumerator, AidlError> {
1498 let mut res = Enumerator::default();
1499
1500 for pair in pairs {
1501 match pair.as_rule() {
1502 Rule::identifier => {
1503 res.identifier = pair.as_str().into();
1504 }
1505 Rule::const_expr => {
1506 res.const_expr = Some(parse_const_expr(pair.into_inner().next().unwrap())?);
1507 }
1508 _ => unreachable!("Unexpected rule in parse_enumerator(): {}", pair),
1509 }
1510 }
1511
1512 Ok(res)
1513}
1514
1515fn parse_enum_decl(
1516 annotation_list: Vec<Annotation>,
1517 pairs: pest::iterators::Pairs<Rule>,
1518) -> Result<Declaration, AidlError> {
1519 let mut enum_decl = EnumDecl {
1520 annotation_list: annotation_list.clone(),
1521 ..Default::default()
1522 };
1523
1524 for pair in pairs {
1525 match pair.as_rule() {
1526 Rule::qualified_name => {
1527 let span = pair.as_span();
1528 enum_decl.name = pair.as_str().into();
1529 enum_decl.name_span = Some((span.start(), span.end()));
1530 }
1531 Rule::enumerator => enum_decl
1532 .enumerator_list
1533 .push(parse_enumerator(pair.into_inner())?),
1534 _ => unreachable!("Unexpected rule in parse_enum_decl(): {}", pair),
1535 }
1536 }
1537
1538 Ok(Declaration::Enum(enum_decl))
1539}
1540
1541#[derive(Debug, Default, Clone)]
1542pub struct UnionDecl {
1543 pub namespace: Namespace,
1544 pub annotation_list: Vec<Annotation>,
1545 pub name: String,
1546 pub name_span: Option<(usize, usize)>,
1547 pub type_params: Vec<String>,
1548 pub members: Vec<Declaration>,
1549}
1550
1551fn parse_union_decl(
1552 annotation_list: Vec<Annotation>,
1553 pairs: pest::iterators::Pairs<Rule>,
1554) -> Result<Declaration, AidlError> {
1555 let mut union_decl = UnionDecl {
1556 annotation_list,
1557 ..Default::default()
1558 };
1559
1560 for pair in pairs {
1561 match pair.as_rule() {
1562 Rule::qualified_name => {
1563 let span = pair.as_span();
1564 union_decl.name = pair.as_str().into();
1565 union_decl.name_span = Some((span.start(), span.end()));
1566 }
1567 Rule::optional_type_params => {
1568 union_decl.type_params = parse_optional_type_params(pair.into_inner());
1569 }
1570 Rule::parcelable_members => {
1571 union_decl.members = parse_parcelable_members(pair.into_inner())?;
1572 }
1573 _ => unreachable!("Unexpected rule in parse_union_decl(): {}", pair),
1574 }
1575 }
1576 Ok(Declaration::Union(union_decl))
1577}
1578
1579fn parse_decl(pairs: pest::iterators::Pairs<Rule>) -> Result<Vec<Declaration>, AidlError> {
1580 let mut annotation_list = Vec::new();
1581 let mut declarations = Vec::new();
1582
1583 for pair in pairs {
1584 match pair.as_rule() {
1585 Rule::annotation_list => {
1586 annotation_list = parse_annotation_list(pair.into_inner())?;
1587 }
1588 Rule::interface_decl => {
1589 declarations.push(parse_interface_decl(
1590 annotation_list.clone(),
1591 pair.into_inner(),
1592 )?);
1593 }
1594
1595 Rule::parcelable_decl => {
1596 declarations.push(parse_parcelable_decl(
1597 annotation_list.clone(),
1598 pair.into_inner(),
1599 )?);
1600 }
1601 Rule::enum_decl => {
1602 declarations.push(parse_enum_decl(annotation_list.clone(), pair.into_inner())?);
1603 }
1604 Rule::union_decl => {
1605 declarations.push(parse_union_decl(
1606 annotation_list.clone(),
1607 pair.into_inner(),
1608 )?);
1609 }
1610
1611 _ => unreachable!("Unexpected rule in parse_decl(): {}", pair),
1612 };
1613 }
1614
1615 Ok(declarations)
1616}
1617
1618pub fn calculate_namespace(decl: &mut Declaration, mut namespace: Namespace) {
1619 if decl.is_variable().is_some() {
1620 return;
1621 }
1622
1623 namespace.push(decl.name());
1624
1625 decl.set_namespace(namespace.clone());
1626
1627 DECLARATION_MAP.with(|hashmap| {
1628 hashmap.borrow_mut().insert(namespace.clone(), decl.clone());
1629 });
1630
1631 for decl in decl.members_mut() {
1632 calculate_namespace(decl, namespace.clone());
1633 }
1634}
1635
1636pub fn parse_document(ctx: &SourceContext) -> Result<Document, AidlError> {
1637 let _guard = SourceGuard::new(&ctx.filename, &ctx.source);
1638 let mut document = Document::new();
1639
1640 match AIDLParser::parse(Rule::document, &ctx.source) {
1641 Ok(pairs) => {
1642 for pair in pairs {
1643 match pair.as_rule() {
1644 Rule::package => {
1645 document.package = Some(pair.into_inner().next().unwrap().as_str().into());
1646 }
1647
1648 Rule::imports => {
1649 for pair in pair.into_inner() {
1650 let import = pair.as_str().to_string();
1651 let key = match import.rfind('.') {
1652 Some(idx) => &import[(idx + 1)..],
1653 None => &import,
1654 };
1655 document.imports.insert(key.into(), import);
1656 }
1657 }
1658
1659 Rule::decl => {
1660 document.decls.append(&mut parse_decl(pair.into_inner())?);
1661 }
1662
1663 Rule::EOI => {}
1664
1665 _ => {
1666 unreachable!("Unexpected rule in parse_document(): {}", pair)
1667 }
1668 }
1669 }
1670
1671 }
1673 Err(err) => {
1674 return Err(pest_error_to_diagnostic(err, &ctx.filename, &ctx.source).into());
1675 }
1676 }
1677
1678 let namespace = if let Some(ref package) = document.package {
1679 Namespace::new(package, Namespace::AIDL)
1680 } else {
1681 Namespace::default()
1682 };
1683
1684 for decl in &mut document.decls {
1685 calculate_namespace(decl, namespace.clone());
1686 }
1687
1688 Ok(document)
1689}
1690
1691pub fn reset() {
1692 DECLARATION_MAP.with(|hashmap| {
1693 hashmap.borrow_mut().clear();
1694 });
1695 NAMESPACE_STACK.with(|stack| {
1696 stack.borrow_mut().clear();
1697 });
1698 DOCUMENT.with(|doc| {
1699 *doc.borrow_mut() = Document::new();
1700 });
1701 SYMBOL_TABLE.with(|table| {
1702 table.borrow_mut().clear();
1703 });
1704}
1705
1706#[cfg(test)]
1707mod tests {
1708 use super::*;
1709 use std::error::Error;
1710
1711 #[test]
1712 fn test_parse_string_expr() -> Result<(), Box<dyn Error>> {
1713 let mut res =
1714 AIDLParser::parse(Rule::string_expr, r##""Hello" + " World""##).map_err(|err| {
1715 println!("{err}");
1716 err
1717 })?;
1718
1719 let expr = parse_string_expr(res.next().unwrap().into_inner())?;
1720 assert_eq!(
1721 expr,
1722 ConstExpr::new_expr(
1723 ConstExpr::new(ValueType::String("Hello".into())),
1724 "+",
1725 ConstExpr::new(ValueType::String(" World".into()))
1726 )
1727 );
1728
1729 Ok(())
1730 }
1731
1732 #[test]
1733 fn test_parse_expression() -> Result<(), Box<dyn Error>> {
1734 let mut res =
1735 AIDLParser::parse(Rule::expression, r##"1 + -3 * 2 << 2 | 4"##).map_err(|err| {
1736 println!("{err}");
1737 err
1738 })?;
1739
1740 let expr = parse_expression(res.next().unwrap().into_inner())?;
1741 assert_eq!(
1771 expr.calculate().unwrap(),
1772 ConstExpr::new(ValueType::Int64(-20))
1773 );
1774
1775 Ok(())
1776 }
1777
1778 #[test]
1779 fn test_namespace_guard() {
1780 let _ns_1 = NamespaceGuard::new(&Namespace::new("1.1", Namespace::AIDL));
1781 {
1782 assert_eq!(current_namespace(), Namespace::new("1.1", Namespace::AIDL));
1783 let _ns_2 = NamespaceGuard::new(&Namespace::new("2.2", Namespace::AIDL));
1784 {
1785 assert_eq!(current_namespace(), Namespace::new("2.2", Namespace::AIDL));
1786 let _ns_3 = NamespaceGuard::new(&Namespace::new("3.3", Namespace::AIDL));
1787 assert_eq!(current_namespace(), Namespace::new("3.3", Namespace::AIDL));
1788 }
1789 assert_eq!(current_namespace(), Namespace::new("2.2", Namespace::AIDL));
1790 }
1791 }
1792
1793 #[test]
1795 fn test_source_guard_cleanup_on_drop() {
1796 {
1797 let _guard = SourceGuard::new("test.aidl", "source text");
1798 assert_eq!(current_source_name(), "test.aidl");
1799 assert_eq!(current_source_text(), "source text");
1800 }
1801 assert_eq!(current_source_name(), "");
1803 assert_eq!(current_source_text(), "");
1804 }
1805
1806 #[test]
1808 fn test_source_guard_cleanup_on_panic() {
1809 let result = std::panic::catch_unwind(|| {
1810 let _guard = SourceGuard::new("panic.aidl", "panic source");
1811 panic!("intentional panic to test cleanup");
1812 });
1813 assert!(result.is_err());
1814 assert_eq!(current_source_name(), "");
1815 assert_eq!(current_source_text(), "");
1816 }
1817}