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 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 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 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#[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 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}