Skip to main content

rsbinder_aidl/
generator.rs

1// Copyright 2022 Jeff Kim <hiking90@gmail.com>
2// SPDX-License-Identifier: Apache-2.0
3
4use serde::{Deserialize, Serialize};
5use std::error::Error;
6
7use tera::Tera;
8
9use crate::const_expr::{ConstExpr, InitParam, ValueType};
10use crate::parser::Direction;
11use crate::{add_indent, parser, Namespace};
12
13const ENUM_TEMPLATE: &str = r##"
14pub mod {{mod}} {
15    #![allow(non_upper_case_globals, non_snake_case)]
16    {{crate}}::declare_binder_enum! {
17        r#{{enum_name}} : [{{enum_type}}; {{enum_len}}] {
18    {%- for member in members %}
19            r#{{ member.0 }} = {{ member.1 }},
20    {%- endfor %}
21        }
22    }
23}
24"##;
25
26const UNION_TEMPLATE: &str = r#"
27pub mod {{mod}} {
28    #![allow(non_upper_case_globals, non_snake_case, dead_code)]
29    #[derive(Debug)]
30    {%- if derive|length > 0 %}
31    #[derive({{ derive }})]
32    {%- endif %}
33    pub enum r#{{union_name}} {
34    {%- for member in members %}
35        r#{{ member.0 }}({{ member.1 }}),
36    {%- endfor %}
37    }
38    {%- for member in const_members %}
39    pub const r#{{ member.0 }}: {{ member.1 }} = {{ member.2 }};
40    {%- endfor %}
41    impl Default for r#{{union_name}} {
42        fn default() -> Self {
43    {%- if members|length > 0 %}
44            Self::{{members[0][0]}}({{members[0][3]}})
45    {%- endif %}
46        }
47    }
48    impl {{crate}}::Parcelable for r#{{union_name}} {
49        fn write_to_parcel(&self, parcel: &mut {{crate}}::Parcel) -> {{crate}}::Result<()> {
50            match self {
51    {%- set counter = 0 %}
52    {%- for member in members %}
53                Self::r#{{member.0}}(v) => {
54                    parcel.write(&{{counter}}i32)?;
55                    parcel.write(v)
56                }
57    {%- set_global counter = counter + 1 %}
58    {%- endfor %}
59            }
60        }
61        fn read_from_parcel(&mut self, parcel: &mut {{crate}}::Parcel) -> {{crate}}::Result<()> {
62            let tag: i32 = parcel.read()?;
63            match tag {
64    {%- set counter = 0 %}
65    {%- for member in members %}
66                {{counter}} => {
67                    let value: {{member.1}} = parcel.read()?;
68                    *self = Self::r#{{member.0}}(value);
69                    Ok(())
70                }
71    {%- set_global counter = counter + 1 %}
72    {%- endfor %}
73                _ => Err({{crate}}::StatusCode::BadValue),
74            }
75        }
76    }
77    {{crate}}::impl_serialize_for_parcelable!(r#{{union_name}});
78    {{crate}}::impl_deserialize_for_parcelable!(r#{{union_name}});
79    impl {{crate}}::ParcelableMetadata for r#{{union_name}} {
80        fn descriptor() -> &'static str { "{{ namespace }}" }
81        {%- if is_vintf %}
82        fn stability(&self) -> {{crate}}::Stability { {{crate}}::Stability::Vintf }
83        {%- endif %}
84    }
85    {{crate}}::declare_binder_enum! {
86        Tag : [i32; {{ members|length }}] {
87    {%- set counter = 0 %}
88    {%- for member in members %}
89            r#{{ member.2 }} = {{ counter }},
90    {%- set_global counter = counter + 1 %}
91    {%- endfor %}
92        }
93    }
94    {%- if nested|length>0 %}
95    {{nested}}
96    {%- endif %}
97}
98"#;
99
100const PARCELABLE_TEMPLATE: &str = r#"
101pub mod {{mod}} {
102    #![allow(non_upper_case_globals, non_snake_case, dead_code)]
103    {%- for member in const_members %}
104    pub const r#{{ member.0 }}: {{ member.1 }} = {{ member.2 }};
105    {%- endfor %}
106    #[derive(Debug)]
107    {%- if derive|length > 0 %}
108    #[derive({{ derive }})]
109    {%- endif %}
110    pub struct {{name}} {
111    {%- for member in members %}
112        pub r#{{ member.0 }}: {{ member.1 }},
113    {%- endfor %}
114    }
115    impl Default for {{ name }} {
116        fn default() -> Self {
117            Self {
118            {%- for member in members %}
119                r#{{ member.0 }}: {{ member.2 }},
120            {%- endfor %}
121            }
122        }
123    }
124    impl {{crate}}::Parcelable for {{name}} {
125        fn write_to_parcel(&self, _parcel: &mut {{crate}}::Parcel) -> {{crate}}::Result<()> {
126            _parcel.sized_write(|_sub_parcel| {
127                {%- for member in members %}
128                _sub_parcel.write(&self.r#{{ member.0 }})?;
129                {%- endfor %}
130                Ok(())
131            })
132        }
133        fn read_from_parcel(&mut self, _parcel: &mut {{crate}}::Parcel) -> {{crate}}::Result<()> {
134            _parcel.sized_read(|_sub_parcel| {
135                {%- for member in members %}
136                self.r#{{ member.0 }} = _sub_parcel.read()?;
137                {%- endfor %}
138                Ok(())
139            })
140        }
141    }
142    {{crate}}::impl_serialize_for_parcelable!({{name}});
143    {{crate}}::impl_deserialize_for_parcelable!({{name}});
144    impl {{crate}}::ParcelableMetadata for {{name}} {
145        fn descriptor() -> &'static str { "{{namespace}}" }
146        {%- if is_vintf %}
147        fn stability(&self) -> {{crate}}::Stability { {{crate}}::Stability::Vintf }
148        {%- endif %}
149    }
150    {%- if nested|length>0 %}
151    {{nested}}
152    {%- endif %}
153}
154"#;
155
156const INTERFACE_TEMPLATE: &str = r#"
157pub mod {{mod}} {
158    #![allow(non_upper_case_globals, non_snake_case, dead_code)]
159    {%- for member in const_members %}
160    pub const r#{{ member.0 }}: {{ member.1 }} = {{ member.2 }};
161    {%- endfor %}
162    pub trait {{name}}: {{crate}}::Interface + Send {
163        fn descriptor() -> &'static str where Self: Sized { "{{ namespace }}" }
164        {%- for member in fn_members %}
165        fn r#{{ member.identifier }}({{ member.args }}) -> {{crate}}::status::Result<{{ member.return_type }}>;
166        {%- endfor %}
167        fn getDefaultImpl() -> Option<{{ name }}DefaultRef> where Self: Sized {
168            DEFAULT_IMPL.get().cloned()
169        }
170        fn setDefaultImpl(d: {{ name }}DefaultRef) -> {{ name }}DefaultRef where Self: Sized {
171            DEFAULT_IMPL.get_or_init(|| d).clone()
172        }
173    }
174    {%- if enabled_async %}
175    pub trait {{name}}Async<P>: {{crate}}::Interface + Send {
176        fn descriptor() -> &'static str where Self: Sized { "{{ namespace }}" }
177        {%- for member in fn_members %}
178        fn r#{{ member.identifier }}<'a>({{ member.args_async }}) -> {{crate}}::BoxFuture<'a, {{crate}}::status::Result<{{ member.return_type }}>>;
179        {%- endfor %}
180    }
181    #[::async_trait::async_trait]
182    pub trait {{name}}AsyncService: {{crate}}::Interface + Send {
183        fn descriptor() -> &'static str where Self: Sized { "{{ namespace }}" }
184        {%- for member in fn_members %}
185        async fn r#{{ member.identifier }}({{ member.args }}) -> {{crate}}::status::Result<{{ member.return_type }}>;
186        {%- endfor %}
187    }
188    impl {{bn_name}}
189    {
190        pub fn new_async_binder<T, R>(inner: T, rt: R) -> {{crate}}::Strong<dyn {{name}}>
191        where
192            T: {{name}}AsyncService + Sync + Send + 'static,
193            R: {{crate}}::BinderAsyncRuntime + Send + Sync + 'static,
194        {
195            struct Wrapper<T, R> {
196                _inner: T,
197                _rt: R,
198            }
199            impl<T, R> {{crate}}::Interface for Wrapper<T, R> where T: {{crate}}::Interface, R: Send + Sync {
200                fn as_binder(&self) -> {{crate}}::SIBinder { self._inner.as_binder() }
201                fn dump(&self, _writer: &mut dyn std::io::Write, _args: &[String]) -> {{crate}}::Result<()> { self._inner.dump(_writer, _args) }
202            }
203            impl<T, R> {{bn_name}}Adapter for Wrapper<T, R>
204            where
205                T: {{name}}AsyncService + Sync + Send + 'static,
206                R: {{crate}}::BinderAsyncRuntime + Send + Sync + 'static,
207            {
208                fn as_sync(&self) -> &dyn {{name}} {
209                    self
210                }
211                fn as_async(&self) -> &dyn {{name}}AsyncService {
212                    &self._inner
213                }
214            }
215            impl<T, R> {{name}} for Wrapper<T, R>
216            where
217                T: {{name}}AsyncService + Sync + Send + 'static,
218                R: {{crate}}::BinderAsyncRuntime + Send + Sync + 'static,
219            {
220                {%- for member in fn_members %}
221                fn r#{{ member.identifier }}({{ member.args }}) -> {{crate}}::status::Result<{{ member.return_type }}> {
222                    self._rt.block_on(self._inner.r#{{ member.identifier }}({{ member.func_call_params }}))
223                }
224                {%- endfor %}
225            }
226            let wrapped = Wrapper { _inner: inner, _rt: rt };
227            {%- if is_vintf %}
228            let binder = {{crate}}::native::Binder::new_with_stability({{bn_name}}(Box::new(wrapped)), {{crate}}::Stability::Vintf);
229            {%- else %}
230            let binder = {{crate}}::native::Binder::new_with_stability({{bn_name}}(Box::new(wrapped)), {{crate}}::Stability::default());
231            {%- endif %}
232            {{crate}}::Strong::new(Box::new(binder))
233        }
234    }
235    {%- endif %}
236    pub trait {{ name }}Default: Send + Sync {
237        {%- for member in fn_members %}
238        fn r#{{ member.identifier }}({{ member.args }}) -> {{crate}}::status::Result<{{ member.return_type }}> {
239            Err({{crate}}::StatusCode::UnknownTransaction.into())
240        }
241        {%- endfor %}
242    }
243    pub(crate) mod transactions {
244        {%- set counter = 0 %}
245        {%- for member in fn_members %}
246        {%- if member.has_explicit_code %}
247        pub(crate) const r#{{ member.identifier }}: {{crate}}::TransactionCode = {{crate}}::FIRST_CALL_TRANSACTION + {{ member.transaction_code }};
248        {%- else %}
249        pub(crate) const r#{{ member.identifier }}: {{crate}}::TransactionCode = {{crate}}::FIRST_CALL_TRANSACTION + {{ counter }};
250        {%- set_global counter = counter + 1 %}
251        {%- endif %}
252        {%- endfor %}
253    }
254    pub type {{ name }}DefaultRef = std::sync::Arc<dyn {{ name }}Default>;
255    static DEFAULT_IMPL: std::sync::OnceLock<{{ name }}DefaultRef> = std::sync::OnceLock::new();
256    {{crate}}::declare_binder_interface! {
257        {{ name }}["{{ namespace }}"] {
258            native: {
259                {{ bn_name }}(on_transact),
260                {%- if enabled_async %}
261                adapter: {{ bn_name }}Adapter,
262                r#async: {{ name }}AsyncService,
263                {%- endif %}
264            },
265            proxy: {{ bp_name }},
266            {%- if enabled_async %}
267            r#async: {{ name }}Async,
268            {%- endif %}
269        }
270    }
271    impl {{ bp_name }} {
272        {%- for member in fn_members %}
273        fn build_parcel_{{ member.identifier }}({{ member.args }}) -> {{crate}}::Result<{{crate}}::Parcel> {
274            {%- if member.write_funcs|length > 0 %}
275            let mut data = self.binder.as_proxy().unwrap().prepare_transact(true)?;
276            {%- for func in member.write_funcs %}
277            {{ func }}
278            {%- endfor %}
279            {%- else %}
280            let data = self.binder.as_proxy().unwrap().prepare_transact(true)?;
281            {%- endif %}
282            Ok(data)
283        }
284        fn read_response_{{ member.identifier }}({{ member.args }}, _aidl_reply: {{crate}}::Result<Option<{{crate}}::Parcel>>) -> {{crate}}::status::Result<{{ member.return_type }}> {
285            {%- if oneway or member.oneway %}
286            Ok(())
287            {%- else %}
288            if let Err({{crate}}::StatusCode::UnknownTransaction) = _aidl_reply {
289                if let Some(_aidl_default_impl) = <Self as {{name}}>::getDefaultImpl() {
290                  return _aidl_default_impl.r#{{ member.identifier }}({{ member.func_call_params }});
291                }
292            }
293            let mut _aidl_reply = _aidl_reply?.ok_or({{crate}}::StatusCode::UnexpectedNull)?;
294            let _status = _aidl_reply.read::<{{crate}}::Status>()?;
295            if !_status.is_ok() { return Err(_status); }
296            {%- if member.return_type != "()" %}
297            let _aidl_return: {{ member.return_type }} = _aidl_reply.read()?;
298            {%- endif %}
299            {%- for arg in member.read_onto_params %}
300            _aidl_reply.read_onto({{ arg }})?;
301            {%- endfor %}
302            {%- if member.return_type != "()" %}
303            Ok(_aidl_return)
304            {%- else %}
305            Ok(())
306            {%- endif %}
307            {%- endif %}
308        }
309        {%- endfor %}
310    }
311    impl {{ name }} for {{ bp_name }} {
312        {%- for member in fn_members %}
313        fn r#{{ member.identifier }}({{ member.args }}) -> {{crate}}::status::Result<{{ member.return_type }}> {
314            let _aidl_data = self.build_parcel_{{ member.identifier }}({{ member.func_call_params }})?;
315            let _aidl_reply = self.binder.as_proxy().unwrap().submit_transact(transactions::r#{{ member.identifier }}, &_aidl_data, {% if oneway or member.oneway %}{{crate}}::FLAG_ONEWAY | {% endif %}{{crate}}::FLAG_CLEAR_BUF);
316            {%- if member.func_call_params|length > 0 %}
317            self.read_response_{{ member.identifier }}({{ member.func_call_params }}, _aidl_reply)
318            {%- else %}
319            self.read_response_{{ member.identifier }}(_aidl_reply)
320            {%- endif %}
321        }
322        {%- endfor %}
323    }
324    {%- if enabled_async %}
325    impl<P: {{crate}}::BinderAsyncPool> {{name}}Async<P> for {{ bp_name }} {
326        {%- for member in fn_members %}
327        fn r#{{ member.identifier }}<'a>({{ member.args_async }}) -> {{crate}}::BoxFuture<'a, {{crate}}::status::Result<{{ member.return_type }}>> {
328            let _aidl_data = match self.build_parcel_{{ member.identifier }}({{ member.func_call_params }}) {
329                Ok(_aidl_data) => _aidl_data,
330                Err(err) => return Box::pin(std::future::ready(Err(err.into()))),
331            };
332            let binder = self.binder.clone();
333            P::spawn(
334                move || binder.as_proxy().unwrap().submit_transact(transactions::r#{{ member.identifier }}, &_aidl_data, {{crate}}::FLAG_CLEAR_BUF | {{crate}}::FLAG_PRIVATE_LOCAL),
335                move |_aidl_reply| async move {
336                    {%- if member.func_call_params|length > 0 %}
337                    self.read_response_{{ member.identifier }}({{ member.func_call_params }}, _aidl_reply)
338                    {%- else %}
339                    self.read_response_{{ member.identifier }}(_aidl_reply)
340                    {%- endif %}
341                }
342            )
343        }
344        {%- endfor %}
345    }
346    impl<P: {{crate}}::BinderAsyncPool> {{name}}Async<P> for {{crate}}::Binder<{{bn_name}}>
347    {
348        {%- for member in fn_members %}
349        fn r#{{ member.identifier }}<'a>({{ member.args_async }}) -> {{crate}}::BoxFuture<'a, {{crate}}::status::Result<{{ member.return_type }}>> {
350            self.0.as_async().r#{{ member.identifier }}({{ member.func_call_params }})
351        }
352        {%- endfor %}
353    }
354    {%- endif %}
355    impl {{ name }} for {{crate}}::Binder<{{ bn_name }}> {
356        {%- for member in fn_members %}
357        fn r#{{ member.identifier }}({{ member.args }}) -> {{crate}}::status::Result<{{ member.return_type }}> {
358            {%- if enabled_async %}
359            self.0.as_sync().r#{{ member.identifier }}({{ member.func_call_params }})
360            {%- else %}
361            self.0.r#{{ member.identifier }}({{ member.func_call_params }})
362            {%- endif %}
363        }
364        {%- endfor %}
365    }
366    fn on_transact(
367        _service: &dyn {{ name }}, _code: {{crate}}::TransactionCode, _reader: &mut {{crate}}::Parcel, _reply: &mut {{crate}}::Parcel) -> {{crate}}::Result<()> {
368        match _code {
369        {%- for member in fn_members %}
370            transactions::r#{{ member.identifier }} => {
371            {%- for decl in member.transaction_decls %}
372                {{ decl }}
373            {%- endfor %}
374                let _aidl_return = _service.r#{{ member.identifier }}({{ member.transaction_params }});
375            {%- if not oneway and not member.oneway %}
376                match &_aidl_return {
377                    Ok(_aidl_return) => {
378                        _reply.write(&{{crate}}::Status::from({{crate}}::StatusCode::Ok))?;
379                        {%- if member.transaction_has_return %}
380                        _reply.write(_aidl_return)?;
381                        {%- endif %}
382                        {%- for arg in member.transaction_write %}
383                        _reply.write(&{{ arg }})?;
384                        {%- endfor %}
385                    }
386                    Err(_aidl_status) => {
387                        _reply.write(_aidl_status)?;
388                    }
389                }
390            {%- endif %}
391                Ok(())
392            }
393        {%- endfor %}
394            _ => Err({{crate}}::StatusCode::UnknownTransaction),
395        }
396    }
397    {%- if nested|length>0 %}
398    {{nested}}
399    {%- endif %}
400}
401"#;
402
403fn template() -> &'static tera::Tera {
404    static TEMPLATES: std::sync::OnceLock<tera::Tera> = std::sync::OnceLock::new();
405
406    TEMPLATES.get_or_init(|| {
407        let mut tera = Tera::default();
408        tera.add_raw_template("enum", ENUM_TEMPLATE)
409            .expect("Failed to add enum template");
410        tera.add_raw_template("union", UNION_TEMPLATE)
411            .expect("Failed to add union template");
412        tera.add_raw_template("parcelable", PARCELABLE_TEMPLATE)
413            .expect("Failed to add parcelable template");
414        tera.add_raw_template("interface", INTERFACE_TEMPLATE)
415            .expect("Failed to add interface template");
416        tera
417    })
418}
419
420// lazy_static! {
421//     pub static ref TEMPLATES: Tera = {
422//         let mut tera = Tera::default();
423//         tera.add_raw_template("enum", ENUM_TEMPLATE)
424//             .expect("Failed to add enum template");
425//         tera.add_raw_template("union", UNION_TEMPLATE)
426//             .expect("Failed to add union template");
427//         tera.add_raw_template("parcelable", PARCELABLE_TEMPLATE)
428//             .expect("Failed to add parcelable template");
429//         tera.add_raw_template("interface", INTERFACE_TEMPLATE)
430//             .expect("Failed to add interface template");
431//         tera
432//     };
433// }
434
435#[derive(Serialize, Deserialize, Debug)]
436struct FnMembers {
437    identifier: String,
438    args: String,
439    args_async: String,
440    return_type: String,
441    write_funcs: Vec<String>,
442    func_call_params: String,
443    transaction_decls: Vec<String>,
444    transaction_write: Vec<String>,
445    transaction_params: String,
446    transaction_has_return: bool,
447    oneway: bool,
448    read_onto_params: Vec<String>,
449    transaction_code: u32,
450    has_explicit_code: bool,
451}
452
453fn make_fn_member(method: &parser::MethodDecl) -> Result<FnMembers, Box<dyn Error>> {
454    let mut func_call_params = String::new();
455    let mut args = "&self".to_string();
456    let mut args_async = "&'a self".to_string();
457    let mut write_funcs = Vec::new();
458    let mut transaction_decls = Vec::new();
459    let mut transaction_write = Vec::new();
460    let mut transaction_params = String::new();
461    let mut read_onto_params = Vec::new();
462    // let is_nullable = parser::check_annotation_list(&method.annotation_list, parser::AnnotationType::IsNullable).0;
463
464    method.arg_list.iter().for_each(|arg| {
465        let generator = arg.to_generator();
466
467        let type_decl_for_func = generator.type_decl_for_func();
468
469        let arg_str = format!(", {}: {}", generator.identifier, type_decl_for_func);
470
471        args += &arg_str;
472        args_async += &arg_str.replace('&', "&'a ");
473        func_call_params += &format!("{}, ", generator.identifier);
474
475        if !matches!(arg.direction, Direction::Out) {
476            let param = if type_decl_for_func.starts_with('&') {
477                generator.identifier.to_owned()
478            } else {
479                format!("&{}", generator.identifier)
480            };
481            write_funcs.push(format!("data.write({param})?;"));
482        } else if generator.is_variable_array() {
483            if generator.is_nullable {
484                write_funcs.push(format!(
485                    "data.write_slice_size({}.as_deref())?;",
486                    generator.identifier
487                ));
488            } else {
489                write_funcs.push(format!(
490                    "data.write_slice_size(Some({}))?;",
491                    generator.identifier
492                ));
493            }
494        }
495
496        transaction_decls.push(format!("let {};", generator.transaction_decl("_reader")));
497        if matches!(arg.direction, Direction::Out) && generator.is_variable_array() {
498            if generator.is_nullable {
499                transaction_decls.push(format!(
500                    "_reader.resize_nullable_out_vec(&mut {})?;",
501                    generator.identifier
502                ));
503            } else {
504                transaction_decls.push(format!(
505                    "_reader.resize_out_vec(&mut {})?;",
506                    generator.identifier
507                ));
508            }
509        }
510
511        if matches!(arg.direction, Direction::Out | Direction::Inout) {
512            transaction_write.push(generator.identifier.to_owned());
513            read_onto_params.push(generator.identifier.to_owned());
514        }
515        transaction_params += &format!("{}, ", generator.func_call_param());
516    });
517
518    let func_call_params = if func_call_params.chars().count() > 2 {
519        func_call_params
520            .chars()
521            .take(func_call_params.chars().count() - 2)
522            .collect::<String>()
523    } else {
524        func_call_params
525    };
526
527    let transaction_params = if transaction_params.chars().count() > 2 {
528        transaction_params
529            .chars()
530            .take(transaction_params.chars().count() - 2)
531            .collect::<String>()
532    } else {
533        transaction_params
534    };
535
536    let generator = if parser::check_annotation_list(
537        &method.annotation_list,
538        parser::AnnotationType::IsNullable,
539    )
540    .0
541    {
542        method.r#type.to_generator().nullable()
543    } else {
544        method.r#type.to_generator()
545    };
546
547    let return_type = generator.type_declaration(false);
548    let transaction_has_return = return_type != "()";
549
550    Ok(FnMembers {
551        // identifier: method.identifier.to_case(Case::Snake),
552        identifier: method.identifier.to_owned(),
553        args,
554        args_async,
555        return_type,
556        write_funcs,
557        func_call_params,
558        transaction_decls,
559        transaction_write,
560        transaction_params,
561        transaction_has_return,
562        oneway: method.oneway,
563        read_onto_params,
564        transaction_code: method.intvalue.unwrap_or(0) as u32,
565        has_explicit_code: method.intvalue.is_some(),
566    })
567}
568
569pub struct Generator {
570    enabled_async: bool,
571    is_crate: bool,
572}
573
574impl Generator {
575    pub fn new(enabled_async: bool, is_crate: bool) -> Self {
576        Self {
577            enabled_async,
578            is_crate,
579        }
580    }
581
582    fn get_crate_name(&self) -> &str {
583        if self.is_crate {
584            "crate"
585        } else {
586            "rsbinder"
587        }
588    }
589
590    fn new_context(&self) -> tera::Context {
591        let mut context = tera::Context::new();
592
593        context.insert("crate", self.get_crate_name());
594
595        context
596    }
597
598    /// Pre-register all enum member symbols from a document into the symbol table.
599    /// This ensures enum symbols are available before any code generation begins,
600    /// preventing incorrect resolution when multiple enums share the same member names.
601    pub fn pre_register_enums(document: &parser::Document) {
602        parser::set_current_document(document);
603        Self::pre_register_enum_decls(&document.decls);
604    }
605
606    fn pre_register_enum_decls(decls: &[parser::Declaration]) {
607        for decl in decls {
608            match decl {
609                parser::Declaration::Enum(enum_decl) => {
610                    let _ns = parser::NamespaceGuard::new(&enum_decl.namespace);
611                    Self::register_enum_members(enum_decl);
612                }
613                parser::Declaration::Parcelable(d) => Self::pre_register_enum_decls(&d.members),
614                parser::Declaration::Interface(d) => Self::pre_register_enum_decls(&d.members),
615                parser::Declaration::Union(d) => Self::pre_register_enum_decls(&d.members),
616                _ => {}
617            }
618        }
619    }
620
621    pub fn document(
622        &self,
623        document: &parser::Document,
624    ) -> Result<(String, String), Box<dyn Error>> {
625        parser::set_current_document(document);
626
627        let mut content = String::new();
628
629        content += &self.declarations(&document.decls, 0)?;
630
631        Ok((document.package.clone().unwrap_or_default(), content))
632    }
633
634    pub fn declarations(
635        &self,
636        decls: &Vec<parser::Declaration>,
637        indent: usize,
638    ) -> Result<String, Box<dyn Error>> {
639        let mut content = String::new();
640
641        for decl in decls {
642            match decl {
643                parser::Declaration::Interface(decl) => {
644                    let _ns = parser::NamespaceGuard::new(&decl.namespace);
645                    content += &self.decl_interface(decl, indent)?;
646                }
647
648                parser::Declaration::Parcelable(decl) => {
649                    let _ns = parser::NamespaceGuard::new(&decl.namespace);
650                    content += &self.decl_parcelable(decl, indent)?;
651                }
652
653                parser::Declaration::Variable(_decl) => {
654                    unreachable!("Unexpected Declaration::Variable : {:?}", _decl);
655                }
656
657                parser::Declaration::Enum(decl) => {
658                    let _ns = parser::NamespaceGuard::new(&decl.namespace);
659                    content += &self.decl_enum(decl, indent)?;
660                }
661
662                parser::Declaration::Union(decl) => {
663                    let _ns = parser::NamespaceGuard::new(&decl.namespace);
664                    content += &self.decl_union(decl, indent)?;
665                }
666            }
667        }
668
669        Ok(content)
670    }
671
672    fn decl_interface(
673        &self,
674        arg_decl: &parser::InterfaceDecl,
675        indent: usize,
676    ) -> Result<String, Box<dyn Error>> {
677        let mut decl = arg_decl.clone();
678
679        let is_empty =
680            parser::check_annotation_list(&decl.annotation_list, parser::AnnotationType::JavaOnly)
681                .0;
682        let is_vintf = parser::check_annotation_list(
683            &decl.annotation_list,
684            parser::AnnotationType::VintfStability,
685        )
686        .0;
687
688        decl.pre_process();
689
690        let mut const_members = Vec::new();
691        let mut fn_members = Vec::new();
692
693        if !is_empty {
694            // First pass: register all interface constants for resolution
695            for constant in decl.constant_list.iter() {
696                if let Some(const_expr) = &constant.const_expr {
697                    parser::register_symbol(
698                        &constant.identifier,
699                        const_expr.clone(),
700                        parser::SymbolType::InterfaceConstant,
701                        Some(&decl.name),
702                    );
703                }
704            }
705
706            // Second pass: process constants with resolved values
707            for constant in decl.constant_list.iter() {
708                let generator = constant.r#type.to_generator();
709                const_members.push((
710                    constant.const_identifier(),
711                    generator.const_type_decl(),
712                    generator.init_value(
713                        constant.const_expr.as_ref(),
714                        InitParam::builder().with_const(true),
715                    ),
716                ));
717            }
718
719            // === Transaction code validation (before fn_members loop) ===
720            {
721                let explicit_count = decl
722                    .method_list
723                    .iter()
724                    .filter(|m| m.intvalue.is_some())
725                    .count();
726
727                // AOSP rule: all-or-nothing
728                if explicit_count > 0 && explicit_count < decl.method_list.len() {
729                    return Err(format!(
730                        "Interface {}: either all methods must have explicitly assigned \
731                         transaction IDs or none of them should",
732                        decl.name
733                    )
734                    .into());
735                }
736
737                if explicit_count > 0 {
738                    // Detect duplicate transaction codes
739                    let mut seen = std::collections::HashMap::new();
740                    for method in decl.method_list.iter() {
741                        if let Some(code) = method.intvalue {
742                            if code < 0 {
743                                return Err(format!(
744                                    "Interface {}: method '{}' has negative transaction code {}",
745                                    decl.name, method.identifier, code
746                                )
747                                .into());
748                            }
749                            if code > u32::MAX as i64 {
750                                return Err(format!(
751                                    "Interface {}: method '{}' has transaction code {} exceeding u32 range",
752                                    decl.name, method.identifier, code
753                                ).into());
754                            }
755                            if let Some(prev_name) = seen.insert(code, &method.identifier) {
756                                return Err(format!(
757                                    "Interface {}: methods '{}' and '{}' have the same \
758                                     transaction code {}",
759                                    decl.name, prev_name, method.identifier, code
760                                )
761                                .into());
762                            }
763                        }
764                    }
765                }
766            }
767
768            for method in decl.method_list.iter() {
769                fn_members.push(make_fn_member(method)?);
770            }
771        }
772
773        let enabled_async = self.enabled_async;
774
775        let nested = &self.declarations(&decl.members, indent + 1)?;
776
777        let namespace = parser::get_descriptor_from_annotation_list(&decl.annotation_list)
778            .unwrap_or_else(|| decl.namespace.to_string(Namespace::AIDL));
779
780        let mut context = self.new_context();
781
782        context.insert("mod", &decl.name);
783        context.insert("name", &decl.name);
784        context.insert("namespace", &namespace);
785        context.insert("const_members", &const_members);
786        context.insert("fn_members", &fn_members);
787        context.insert("bn_name", &format!("Bn{}", &decl.name[1..]));
788        context.insert("bp_name", &format!("Bp{}", &decl.name[1..]));
789        context.insert("oneway", &decl.oneway);
790        context.insert("nested", &nested.trim());
791        context.insert("enabled_async", &enabled_async);
792        context.insert("is_vintf", &is_vintf);
793
794        let rendered = template()
795            .render("interface", &context)
796            .expect("Failed to render interface template");
797
798        Ok(add_indent(indent, rendered.trim()))
799    }
800
801    fn decl_parcelable(
802        &self,
803        arg_decl: &parser::ParcelableDecl,
804        indent: usize,
805    ) -> Result<String, Box<dyn Error>> {
806        let mut is_empty = false;
807        let mut decl = arg_decl.clone();
808
809        let is_vintf = parser::check_annotation_list(
810            &decl.annotation_list,
811            parser::AnnotationType::VintfStability,
812        )
813        .0;
814
815        if parser::check_annotation_list(&decl.annotation_list, parser::AnnotationType::JavaOnly).0
816        {
817            println!("Parcelable {} is only used for Java.", decl.name);
818            is_empty = true;
819            // return Ok(String::new())
820        }
821        if !decl.cpp_header.is_empty() {
822            println!(
823                "cpp_header {} for Parcelable {} is not supported.",
824                decl.cpp_header, decl.name
825            );
826            is_empty = true;
827            // return Ok(String::new())
828        }
829
830        decl.pre_process();
831
832        let mut constant_members = Vec::new();
833        let mut members = Vec::new();
834        let mut declations = Vec::new();
835
836        if !is_empty {
837            // Parse struct variables only.
838            for decl in &decl.members {
839                if let Some(var) = decl.is_variable() {
840                    println!("Parcelable variable: {var:?}");
841                    let generator = var.r#type.to_generator();
842
843                    if var.constant {
844                        constant_members.push((
845                            var.const_identifier(),
846                            generator.const_type_decl(),
847                            generator.init_value(
848                                var.const_expr.as_ref(),
849                                InitParam::builder().with_const(true),
850                            ),
851                        ));
852                    } else {
853                        let init_value = match generator.value_type {
854                            ValueType::Holder => Some(ConstExpr::new(ValueType::Holder)),
855                            _ => var.const_expr.clone(),
856                        };
857
858                        members.push((
859                            var.identifier(),
860                            generator.type_declaration(true),
861                            generator.init_value(
862                                init_value.as_ref(),
863                                InitParam::builder()
864                                    .with_const(false)
865                                    .with_vintf(is_vintf)
866                                    .with_crate_name(self.get_crate_name()),
867                            ),
868                        ))
869                    }
870                } else {
871                    declations.push(decl.clone());
872                }
873            }
874        }
875
876        let nested = &self.declarations(&declations, indent + 1)?;
877        let namespace = parser::get_descriptor_from_annotation_list(&decl.annotation_list)
878            .unwrap_or_else(|| decl.namespace.to_string(Namespace::AIDL));
879
880        let mut context = self.new_context();
881
882        context.insert("mod", &decl.name);
883        context.insert("name", &decl.name);
884        context.insert(
885            "derive",
886            &parser::check_annotation_list(
887                &decl.annotation_list,
888                parser::AnnotationType::RustDerive,
889            )
890            .1,
891        );
892        context.insert("namespace", &namespace);
893        context.insert("members", &members);
894        context.insert("const_members", &constant_members);
895        context.insert("nested", &nested.trim());
896        context.insert("is_vintf", &is_vintf);
897
898        let rendered = template()
899            .render("parcelable", &context)
900            .expect("Failed to render parcelable template");
901
902        Ok(add_indent(indent, rendered.trim()))
903    }
904
905    fn register_enum_members(decl: &parser::EnumDecl) {
906        if parser::check_annotation_list(&decl.annotation_list, parser::AnnotationType::JavaOnly).0
907        {
908            return;
909        }
910
911        let mut enum_val: i64 = 0;
912
913        for enumerator in &decl.enumerator_list {
914            let member_name = &enumerator.identifier;
915
916            if let Some(const_expr) = &enumerator.const_expr {
917                // Try to compute the value, but handle cases where it might reference other enum members
918                let calculated = const_expr.calculate();
919                let computed_val = match calculated.value {
920                    crate::const_expr::ValueType::Name(_) => {
921                        // This is an unresolved reference, use current enum_val as fallback
922                        enum_val
923                    }
924                    _ => calculated.to_i64(),
925                };
926
927                parser::register_symbol(
928                    member_name,
929                    crate::const_expr::ConstExpr::new(crate::const_expr::ValueType::Reference {
930                        enum_name: decl.name.clone(),
931                        member_name: member_name.to_string(),
932                        value: computed_val,
933                    }),
934                    parser::SymbolType::EnumMember,
935                    Some(&decl.name),
936                );
937
938                enum_val = computed_val;
939            } else {
940                parser::register_symbol(
941                    member_name,
942                    crate::const_expr::ConstExpr::new(crate::const_expr::ValueType::Reference {
943                        enum_name: decl.name.clone(),
944                        member_name: member_name.to_string(),
945                        value: enum_val,
946                    }),
947                    parser::SymbolType::EnumMember,
948                    Some(&decl.name),
949                );
950            }
951
952            enum_val += 1;
953        }
954    }
955
956    fn decl_enum(&self, decl: &parser::EnumDecl, indent: usize) -> Result<String, Box<dyn Error>> {
957        if parser::check_annotation_list(&decl.annotation_list, parser::AnnotationType::JavaOnly).0
958        {
959            return Ok(String::new());
960        }
961
962        let generator = &parser::get_backing_type(&decl.annotation_list);
963
964        let mut members = Vec::new();
965
966        // First pass: register all enum members with their names for resolution
967        Self::register_enum_members(decl);
968
969        // Second pass: resolve all values now that all members are registered
970        let mut enum_val: i64 = 0;
971        for enumerator in &decl.enumerator_list {
972            if let Some(const_expr) = &enumerator.const_expr {
973                enum_val = const_expr.calculate().to_i64();
974            }
975            members.push((enumerator.identifier.to_owned(), enum_val));
976            enum_val += 1;
977        }
978
979        let mut context = self.new_context();
980
981        context.insert("mod", &decl.name);
982        context.insert("enum_name", &decl.name);
983        context.insert(
984            "enum_type",
985            &generator
986                .clone()
987                .direction(&Direction::None)
988                .type_declaration(true),
989        );
990        context.insert("enum_len", &decl.enumerator_list.len());
991        context.insert("members", &members);
992
993        let rendered = template()
994            .render("enum", &context)
995            .expect("Failed to render enum template");
996
997        Ok(add_indent(indent, rendered.trim()))
998    }
999
1000    fn decl_union(
1001        &self,
1002        decl: &parser::UnionDecl,
1003        indent: usize,
1004    ) -> Result<String, Box<dyn Error>> {
1005        if parser::check_annotation_list(&decl.annotation_list, parser::AnnotationType::JavaOnly).0
1006        {
1007            return Ok(String::new());
1008        }
1009
1010        let is_vintf = parser::check_annotation_list(
1011            &decl.annotation_list,
1012            parser::AnnotationType::VintfStability,
1013        )
1014        .0;
1015
1016        let mut constant_members = Vec::new();
1017        let mut members = Vec::new();
1018        let mut declarations = Vec::new();
1019
1020        for member in &decl.members {
1021            if let parser::Declaration::Variable(var) = member {
1022                let generator = var.r#type.to_generator();
1023                if var.constant {
1024                    constant_members.push((
1025                        var.const_identifier(),
1026                        generator.const_type_decl(),
1027                        generator.init_value(
1028                            var.const_expr.as_ref(),
1029                            InitParam::builder().with_const(true),
1030                        ),
1031                    ));
1032                } else {
1033                    members.push((
1034                        var.union_identifier(),
1035                        generator.type_declaration(true),
1036                        var.identifier(),
1037                        generator.default_value(),
1038                    ));
1039                }
1040            } else {
1041                declarations.push(member.clone());
1042            }
1043        }
1044
1045        let nested = &self.declarations(&declarations, indent + 1)?;
1046        let namespace = parser::get_descriptor_from_annotation_list(&decl.annotation_list)
1047            .unwrap_or_else(|| decl.namespace.to_string(Namespace::AIDL));
1048
1049        let mut context = self.new_context();
1050
1051        context.insert("mod", &decl.name);
1052        context.insert("union_name", &decl.name);
1053        context.insert(
1054            "derive",
1055            &parser::check_annotation_list(
1056                &decl.annotation_list,
1057                parser::AnnotationType::RustDerive,
1058            )
1059            .1,
1060        );
1061        context.insert("namespace", &namespace);
1062        context.insert("members", &members);
1063        context.insert("const_members", &constant_members);
1064        context.insert("nested", &nested.trim());
1065        context.insert("is_vintf", &is_vintf);
1066
1067        let rendered = template()
1068            .render("union", &context)
1069            .expect("Failed to render union template");
1070
1071        Ok(add_indent(indent, rendered.trim()))
1072    }
1073}