aidl_parser/
ast.rs

1use core::fmt;
2use std::collections::HashMap;
3
4use serde_derive::{Deserialize, Serialize};
5
6#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
7pub struct Aidl {
8    pub package: Package,
9    pub imports: Vec<Import>,
10    pub declared_parcelables: Vec<Import>,
11    pub item: Item,
12}
13
14pub type ItemKey = String;
15pub type ItemKeyRef<'a> = &'a str;
16
17impl Aidl {
18    // TODO: cache it
19    pub fn get_key(&self) -> ItemKey {
20        format!("{}.{}", self.package.name, self.item.get_name())
21    }
22}
23
24#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
25pub struct Position {
26    pub offset: usize,
27
28    /// 1-based line and column
29    pub line_col: (usize, usize),
30}
31
32impl Position {
33    pub(crate) fn new(lookup: &line_col::LineColLookup, offset: usize) -> Self {
34        Position {
35            offset,
36            line_col: lookup.get_by_cluster(offset),
37        }
38    }
39}
40
41#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
42pub struct Range {
43    pub start: Position,
44    pub end: Position,
45}
46
47impl Range {
48    pub(crate) fn new(lookup: &line_col::LineColLookup, start: usize, end: usize) -> Self {
49        let start = Position::new(lookup, start);
50        let end = Position::new(lookup, end);
51
52        Range { start, end }
53    }
54}
55
56#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
57pub struct Package {
58    pub name: String,
59    pub symbol_range: Range,
60    pub full_range: Range,
61}
62
63#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
64pub struct Import {
65    pub path: String,
66    pub name: String,
67    pub symbol_range: Range,
68    pub full_range: Range,
69}
70
71impl Import {
72    // TODO: cache it?
73    pub fn get_qualified_name(&self) -> String {
74        if self.path.is_empty() {
75            self.name.clone()
76        } else {
77            format!("{}.{}", self.path, self.name)
78        }
79    }
80}
81
82#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
83#[serde(rename_all = "snake_case")]
84pub enum InterfaceElement {
85    Const(Const),
86    Method(Method),
87}
88
89impl InterfaceElement {
90    pub fn as_method(&self) -> Option<&Method> {
91        match &self {
92            InterfaceElement::Method(m) => Some(m),
93            _ => None,
94        }
95    }
96
97    pub fn get_name(&self) -> &str {
98        match self {
99            InterfaceElement::Const(c) => &c.name,
100            InterfaceElement::Method(m) => &m.name,
101        }
102    }
103
104    pub fn get_symbol_range(&self) -> &Range {
105        match self {
106            InterfaceElement::Const(c) => &c.symbol_range,
107            InterfaceElement::Method(m) => &m.symbol_range,
108        }
109    }
110}
111
112#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
113#[serde(rename_all = "snake_case")]
114pub enum ResolvedItemKind {
115    Interface,
116    Parcelable,
117    Enum,
118    ForwardDeclaredParcelable,
119    UnknownImport,
120}
121
122#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
123#[serde(rename_all = "snake_case")]
124pub enum Item {
125    Interface(Interface),
126    Parcelable(Parcelable),
127    Enum(Enum),
128}
129
130impl Item {
131    pub fn as_interface(&self) -> Option<&Interface> {
132        match &self {
133            Item::Interface(i) => Some(i),
134            _ => None,
135        }
136    }
137
138    pub fn as_parcelable(&self) -> Option<&Parcelable> {
139        match &self {
140            Item::Parcelable(p) => Some(p),
141            _ => None,
142        }
143    }
144
145    pub fn as_enum(&self) -> Option<&Enum> {
146        match &self {
147            Item::Enum(e) => Some(e),
148            _ => None,
149        }
150    }
151
152    pub fn get_kind(&self) -> ResolvedItemKind {
153        match self {
154            Item::Interface(_) => ResolvedItemKind::Interface,
155            Item::Parcelable(_) => ResolvedItemKind::Parcelable,
156            Item::Enum(_) => ResolvedItemKind::Enum,
157        }
158    }
159
160    pub fn get_name(&self) -> &str {
161        match self {
162            Item::Interface(i) => &i.name,
163            Item::Parcelable(p) => &p.name,
164            Item::Enum(e) => &e.name,
165        }
166    }
167
168    pub fn get_symbol_range(&self) -> &Range {
169        match self {
170            Item::Interface(i) => &i.symbol_range,
171            Item::Parcelable(p) => &p.symbol_range,
172            Item::Enum(e) => &e.symbol_range,
173        }
174    }
175
176    pub fn get_full_range(&self) -> &Range {
177        match self {
178            Item::Interface(i) => &i.full_range,
179            Item::Parcelable(p) => &p.full_range,
180            Item::Enum(e) => &e.full_range,
181        }
182    }
183}
184
185#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
186pub struct Interface {
187    pub oneway: bool,
188    pub name: String,
189    pub elements: Vec<InterfaceElement>,
190    #[serde(default, skip_serializing_if = "Vec::is_empty")]
191    pub annotations: Vec<Annotation>,
192    #[serde(default, skip_serializing_if = "Option::is_none")]
193    pub doc: Option<String>,
194    pub full_range: Range,
195    pub symbol_range: Range,
196}
197
198#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
199pub struct Parcelable {
200    pub name: String,
201    pub elements: Vec<ParcelableElement>,
202    #[serde(default, skip_serializing_if = "Vec::is_empty")]
203    pub annotations: Vec<Annotation>,
204    #[serde(default, skip_serializing_if = "Option::is_none")]
205    pub doc: Option<String>,
206    pub full_range: Range,
207    pub symbol_range: Range,
208}
209
210#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
211pub struct Enum {
212    pub name: String,
213    pub elements: Vec<EnumElement>,
214    #[serde(default, skip_serializing_if = "Vec::is_empty")]
215    pub annotations: Vec<Annotation>,
216    #[serde(default, skip_serializing_if = "Option::is_none")]
217    pub doc: Option<String>,
218    pub full_range: Range,
219    pub symbol_range: Range,
220}
221
222#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
223pub struct Const {
224    pub name: String,
225    #[serde(rename = "type")]
226    pub const_type: Type,
227    pub value: String,
228    #[serde(default, skip_serializing_if = "Vec::is_empty")]
229    pub annotations: Vec<Annotation>,
230    #[serde(default, skip_serializing_if = "Option::is_none")]
231    pub doc: Option<String>,
232    pub symbol_range: Range,
233    pub full_range: Range,
234}
235
236#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
237pub struct Method {
238    #[serde(default, skip_serializing_if = "BoolExt::is_true")]
239    pub oneway: bool,
240    pub name: String,
241    pub return_type: Type,
242    pub args: Vec<Arg>,
243    #[serde(default, skip_serializing_if = "Vec::is_empty")]
244    pub annotations: Vec<Annotation>,
245    #[serde(default, skip_serializing_if = "Option::is_none")]
246    pub transact_code: Option<u32>,
247    #[serde(default, skip_serializing_if = "Option::is_none")]
248    pub doc: Option<String>,
249    pub symbol_range: Range,
250    pub full_range: Range,
251    pub transact_code_range: Range,
252    pub oneway_range: Range,
253}
254
255#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
256pub struct Arg {
257    #[serde(default, skip_serializing_if = "Direction::is_unspecified")]
258    pub direction: Direction,
259    pub name: Option<String>,
260    #[serde(rename = "type")]
261    pub arg_type: Type,
262    #[serde(default, skip_serializing_if = "Vec::is_empty")]
263    pub annotations: Vec<Annotation>,
264    #[serde(default, skip_serializing_if = "Option::is_none")]
265    pub doc: Option<String>,
266    pub symbol_range: Range,
267    pub full_range: Range,
268}
269
270#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
271#[serde(rename_all = "snake_case")]
272pub enum Direction {
273    In(Range),
274    Out(Range),
275    InOut(Range),
276    Unspecified,
277}
278
279impl Direction {
280    fn is_unspecified(&self) -> bool {
281        matches!(self, Self::Unspecified)
282    }
283}
284
285impl Default for Direction {
286    fn default() -> Self {
287        Direction::Unspecified
288    }
289}
290
291impl fmt::Display for Direction {
292    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
293        match self {
294            Direction::In(_) => write!(f, "in"),
295            Direction::Out(_) => write!(f, "out"),
296            Direction::InOut(_) => write!(f, "inout"),
297            Direction::Unspecified => Ok(()),
298        }
299    }
300}
301
302#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
303#[serde(rename_all = "snake_case")]
304pub enum ParcelableElement {
305    Const(Const),
306    Field(Field),
307}
308
309impl ParcelableElement {
310    pub fn as_field(&self) -> Option<&Field> {
311        match &self {
312            ParcelableElement::Field(f) => Some(f),
313            _ => None,
314        }
315    }
316
317    pub fn get_name(&self) -> &str {
318        match self {
319            ParcelableElement::Const(c) => &c.name,
320            ParcelableElement::Field(f) => &f.name,
321        }
322    }
323
324    pub fn get_symbol_range(&self) -> &Range {
325        match self {
326            ParcelableElement::Const(c) => &c.symbol_range,
327            ParcelableElement::Field(f) => &f.symbol_range,
328        }
329    }
330}
331
332#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
333pub struct Field {
334    pub name: String,
335    #[serde(rename = "type")]
336    pub field_type: Type,
337    #[serde(default, skip_serializing_if = "Option::is_none")]
338    pub value: Option<String>,
339    #[serde(default, skip_serializing_if = "Vec::is_empty")]
340    pub annotations: Vec<Annotation>,
341    #[serde(default, skip_serializing_if = "Option::is_none")]
342    pub doc: Option<String>,
343    pub symbol_range: Range,
344    pub full_range: Range,
345}
346
347impl Field {
348    pub fn get_signature(&self) -> String {
349        format!("{} {}", self.field_type.name, self.name,)
350    }
351}
352
353#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
354pub struct EnumElement {
355    pub name: String,
356    #[serde(default, skip_serializing_if = "Option::is_none")]
357    pub value: Option<String>,
358    #[serde(default, skip_serializing_if = "Option::is_none")]
359    pub doc: Option<String>,
360    pub symbol_range: Range,
361    pub full_range: Range,
362}
363
364#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
365pub struct Annotation {
366    pub name: String,
367    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
368    pub key_values: HashMap<String, Option<String>>,
369}
370
371#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
372#[serde(rename_all = "snake_case")]
373pub enum TypeKind {
374    Primitive,
375    Void,
376    Array,
377    Map,
378    List,
379    String,
380    CharSequence,
381    AndroidType(AndroidTypeKind),
382    ResolvedItem(String, ResolvedItemKind),
383    Unresolved,
384}
385
386/// Android (or Java) built-in types which do not require explicit import
387#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
388#[serde(rename_all = "snake_case")]
389pub enum AndroidTypeKind {
390    IBinder,
391    FileDescriptor,
392    ParcelFileDescriptor,
393    ParcelableHolder,
394}
395
396impl AndroidTypeKind {
397    fn get_all() -> Vec<Self> {
398        Vec::from([
399            Self::IBinder,
400            Self::FileDescriptor,
401            Self::ParcelFileDescriptor,
402            Self::ParcelableHolder,
403        ])
404    }
405
406    pub fn from_type_name(name: &str) -> Option<Self> {
407        Self::get_all()
408            .into_iter()
409            .find(|at| at.get_name() == name || (at.can_be_qualified() && at.get_qualified_name() == name))
410    }
411
412    pub fn from_name(name: &str) -> Option<Self> {
413        Self::get_all()
414            .into_iter()
415            .find(|at| at.get_name() == name)
416    }
417
418    pub fn from_qualified_name(qualified_name: &str) -> Option<Self> {
419        Self::get_all()
420            .into_iter()
421            .find(|at| at.get_qualified_name() == qualified_name)
422    }
423
424    pub fn get_name(&self) -> &str {
425        match self {
426            AndroidTypeKind::IBinder => "IBinder",
427            AndroidTypeKind::FileDescriptor => "FileDescriptor",
428            AndroidTypeKind::ParcelFileDescriptor => "ParcelFileDescriptor",
429            AndroidTypeKind::ParcelableHolder => "ParcelableHolder",
430        }
431    }
432
433    // If the type can be used with qualified name, e.g. MyMethod(in android.os.IBinder)
434    pub fn can_be_qualified(&self) -> bool {
435        match self {
436            AndroidTypeKind::IBinder => false,
437            AndroidTypeKind::FileDescriptor => false,
438            AndroidTypeKind::ParcelFileDescriptor => true,
439            AndroidTypeKind::ParcelableHolder => false,
440        }
441    }
442
443    pub fn must_be_imported(&self) -> bool {
444        match self {
445            AndroidTypeKind::IBinder => true,
446            AndroidTypeKind::FileDescriptor => true,
447            AndroidTypeKind::ParcelFileDescriptor => true,
448            AndroidTypeKind::ParcelableHolder => true,
449        }
450    }
451    
452    pub fn get_qualified_name(&self) -> &str {
453        match self {
454            AndroidTypeKind::IBinder => "android.os.IBinder",
455            AndroidTypeKind::FileDescriptor => "java.os.FileDescriptor",
456            AndroidTypeKind::ParcelFileDescriptor => "android.os.ParcelFileDescriptor",
457            AndroidTypeKind::ParcelableHolder => "android.os.ParcelableHolder",
458        }
459    }
460}
461
462#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
463pub struct Type {
464    pub name: String,
465    pub kind: TypeKind,
466    #[serde(default, skip_serializing_if = "Vec::is_empty")]
467    pub generic_types: Vec<Type>,
468    pub symbol_range: Range,
469    pub full_range: Range,
470}
471
472impl Type {
473    pub fn simple_type<S: Into<String>>(
474        name: S,
475        kind: TypeKind,
476        lookup: &line_col::LineColLookup,
477        start: usize,
478        end: usize,
479    ) -> Self {
480        Type {
481            name: name.into(),
482            kind,
483            generic_types: Vec::new(),
484            symbol_range: Range::new(lookup, start, end),
485            full_range: Range::new(lookup, start, end),
486        }
487    }
488
489    pub fn array(
490        param: Type,
491        lookup: &line_col::LineColLookup,
492        start: usize,
493        end: usize,
494        fr_start: usize,
495        fr_end: usize,
496    ) -> Self {
497        Type {
498            name: "Array".to_owned(),
499            kind: TypeKind::Array,
500            generic_types: Vec::from([param]),
501            symbol_range: Range::new(lookup, start, end),
502            full_range: Range::new(lookup, fr_start, fr_end),
503        }
504    }
505
506    pub fn list(
507        param: Type,
508        lookup: &line_col::LineColLookup,
509        start: usize,
510        end: usize,
511        fr_start: usize,
512        fr_end: usize,
513    ) -> Self {
514        Type {
515            name: "List".to_owned(),
516            kind: TypeKind::List,
517            generic_types: Vec::from([param]),
518            symbol_range: Range::new(lookup, start, end),
519            full_range: Range::new(lookup, fr_start, fr_end),
520        }
521    }
522
523    pub fn non_generic_list(lookup: &line_col::LineColLookup, start: usize, end: usize) -> Self {
524        Type {
525            name: "List".to_owned(),
526            kind: TypeKind::List,
527            generic_types: Vec::new(),
528            symbol_range: Range::new(lookup, start, end),
529            full_range: Range::new(lookup, start, end),
530        }
531    }
532
533    pub fn map(
534        key_param: Type,
535        value_param: Type,
536        lookup: &line_col::LineColLookup,
537        start: usize,
538        end: usize,
539        fr_start: usize,
540        fr_end: usize,
541    ) -> Self {
542        Type {
543            name: "Map".to_owned(),
544            kind: TypeKind::Map,
545            generic_types: Vec::from([key_param, value_param]),
546            symbol_range: Range::new(lookup, start, end),
547            full_range: Range::new(lookup, fr_start, fr_end),
548        }
549    }
550
551    pub fn non_generic_map(lookup: &line_col::LineColLookup, start: usize, end: usize) -> Self {
552        Type {
553            name: "Map".to_owned(),
554            kind: TypeKind::Map,
555            generic_types: Vec::new(),
556            symbol_range: Range::new(lookup, start, end),
557            full_range: Range::new(lookup, start, end),
558        }
559    }
560}
561
562trait BoolExt {
563    fn is_true(&self) -> bool;
564}
565
566impl BoolExt for bool {
567    fn is_true(&self) -> bool {
568        *self
569    }
570}