sails_idl_parser/ffi/ast/
visitor.rs

1use super::*;
2use crate::{ast as raw_ast, ast::visitor as raw_visitor, ast::visitor::Visitor as RawVisitor};
3use std::ptr;
4use wrapper::VisitorWrapper;
5
6#[repr(C, packed)]
7pub struct Visitor {
8    visit_ctor: unsafe extern "C" fn(context: *const (), *const Ctor),
9    visit_service: unsafe extern "C" fn(context: *const (), *const Service),
10    visit_type: unsafe extern "C" fn(context: *const (), *const Type),
11    visit_vector_type_decl: unsafe extern "C" fn(context: *const (), *const TypeDecl),
12    visit_array_type_decl: unsafe extern "C" fn(context: *const (), *const TypeDecl, u32),
13    visit_map_type_decl: unsafe extern "C" fn(context: *const (), *const TypeDecl, *const TypeDecl),
14    visit_optional_type_decl: unsafe extern "C" fn(context: *const (), *const TypeDecl),
15    visit_result_type_decl:
16        unsafe extern "C" fn(context: *const (), *const TypeDecl, *const TypeDecl),
17    visit_primitive_type_id: unsafe extern "C" fn(context: *const (), PrimitiveType),
18    visit_user_defined_type_id: unsafe extern "C" fn(context: *const (), *const u8, u32),
19    visit_ctor_func: unsafe extern "C" fn(context: *const (), *const CtorFunc),
20    visit_service_func: unsafe extern "C" fn(context: *const (), *const ServiceFunc),
21    visit_service_event: unsafe extern "C" fn(context: *const (), *const ServiceEvent),
22    visit_func_param: unsafe extern "C" fn(context: *const (), *const FuncParam),
23    visit_func_output: unsafe extern "C" fn(context: *const (), *const TypeDecl),
24    visit_struct_def: unsafe extern "C" fn(context: *const (), *const StructDef),
25    visit_struct_field: unsafe extern "C" fn(context: *const (), *const StructField),
26    visit_enum_def: unsafe extern "C" fn(context: *const (), *const EnumDef),
27    visit_enum_variant: unsafe extern "C" fn(context: *const (), *const EnumVariant),
28}
29
30#[cfg(target_arch = "wasm32")]
31unsafe extern "C" {
32    fn visit_ctor(context: *const (), ctor: *const Ctor);
33    fn visit_service(context: *const (), service: *const Service);
34    fn visit_type(context: *const (), r#type: *const Type);
35    fn visit_vector_type_decl(context: *const (), item_type_decl: *const TypeDecl);
36    fn visit_array_type_decl(context: *const (), item_type_decl: *const TypeDecl, len: u32);
37    fn visit_map_type_decl(
38        context: *const (),
39        key_type_decl: *const TypeDecl,
40        value_type_decl: *const TypeDecl,
41    );
42    fn visit_optional_type_decl(context: *const (), optional_type_decl: *const TypeDecl);
43    fn visit_result_type_decl(
44        context: *const (),
45        ok_type_decl: *const TypeDecl,
46        err_type_decl: *const TypeDecl,
47    );
48    fn visit_primitive_type_id(context: *const (), primitive_type_id: PrimitiveType);
49    fn visit_user_defined_type_id(
50        context: *const (),
51        user_defined_type_id_ptr: *const u8,
52        user_defined_type_id_len: u32,
53    );
54    fn visit_ctor_func(context: *const (), func: *const CtorFunc);
55    fn visit_service_func(context: *const (), func: *const ServiceFunc);
56    fn visit_service_event(context: *const (), event: *const ServiceEvent);
57    fn visit_func_param(context: *const (), func_param: *const FuncParam);
58    fn visit_func_output(context: *const (), func_output: *const TypeDecl);
59    fn visit_struct_def(context: *const (), struct_def: *const StructDef);
60    fn visit_struct_field(context: *const (), struct_field: *const StructField);
61    fn visit_enum_def(context: *const (), enum_def: *const EnumDef);
62    fn visit_enum_variant(context: *const (), enum_variant: *const EnumVariant);
63}
64
65#[cfg(target_arch = "wasm32")]
66static VISITOR: Visitor = Visitor {
67    visit_ctor,
68    visit_service,
69    visit_type,
70    visit_vector_type_decl,
71    visit_array_type_decl,
72    visit_map_type_decl,
73    visit_optional_type_decl,
74    visit_result_type_decl,
75    visit_primitive_type_id,
76    visit_user_defined_type_id,
77    visit_ctor_func,
78    visit_service_func,
79    visit_service_event,
80    visit_func_param,
81    visit_func_output,
82    visit_struct_def,
83    visit_struct_field,
84    visit_enum_def,
85    visit_enum_variant,
86};
87
88macro_rules! deref {
89    ($expr:expr) => {{
90        if $expr.is_null() {
91            return ErrorCode::NullPtr;
92        }
93        unsafe { $expr.as_ref() }.unwrap()
94    }};
95}
96
97macro_rules! deref_visitor {
98    ($context:expr, $visitor:expr) => {
99        match VisitorWrapper::new($context, $visitor) {
100            Ok(visitor) => visitor,
101            Err(err) => return err,
102        }
103    };
104}
105
106#[cfg(target_arch = "wasm32")]
107#[unsafe(no_mangle)]
108extern "C" fn accept_program(program: *const Program, context: *const ()) -> ErrorCode {
109    accept_program_impl(program, context, &VISITOR)
110}
111
112#[cfg(not(target_arch = "wasm32"))]
113#[unsafe(no_mangle)]
114extern "C" fn accept_program(
115    program: *const Program,
116    context: *const (),
117    visitor: *const Visitor,
118) -> ErrorCode {
119    accept_program_impl(program, context, visitor)
120}
121
122fn accept_program_impl(
123    program: *const Program,
124    context: *const (),
125    visitor: *const Visitor,
126) -> ErrorCode {
127    let program = deref!(program);
128    let mut visitor = deref_visitor!(context, visitor);
129    raw_visitor::accept_program(program, &mut visitor);
130    ErrorCode::Ok
131}
132
133#[cfg(target_arch = "wasm32")]
134#[unsafe(no_mangle)]
135extern "C" fn accept_ctor(ctor: *const Ctor, context: *const ()) -> ErrorCode {
136    accept_ctor_impl(ctor, context, &VISITOR)
137}
138
139#[cfg(not(target_arch = "wasm32"))]
140#[unsafe(no_mangle)]
141extern "C" fn accept_ctor(
142    ctor: *const Ctor,
143    context: *const (),
144    visitor: *const Visitor,
145) -> ErrorCode {
146    accept_ctor_impl(ctor, context, visitor)
147}
148
149fn accept_ctor_impl(ctor: *const Ctor, context: *const (), visitor: *const Visitor) -> ErrorCode {
150    let ctor = deref!(ctor);
151    let mut visitor = deref_visitor!(context, visitor);
152    raw_visitor::accept_ctor(ctor.raw_ptr.as_ref(), &mut visitor);
153    ErrorCode::Ok
154}
155
156#[cfg(target_arch = "wasm32")]
157#[unsafe(no_mangle)]
158extern "C" fn accept_ctor_func(func: *const CtorFunc, context: *const ()) -> ErrorCode {
159    accept_ctor_func_impl(func, context, &VISITOR)
160}
161
162#[cfg(not(target_arch = "wasm32"))]
163#[unsafe(no_mangle)]
164extern "C" fn accept_ctor_func(
165    func: *const CtorFunc,
166    context: *const (),
167    visitor: *const Visitor,
168) -> ErrorCode {
169    accept_ctor_func_impl(func, context, visitor)
170}
171
172fn accept_ctor_func_impl(
173    func: *const CtorFunc,
174    context: *const (),
175    visitor: *const Visitor,
176) -> ErrorCode {
177    let func = deref!(func);
178    let mut visitor = deref_visitor!(context, visitor);
179    raw_visitor::accept_ctor_func(func.raw_ptr.as_ref(), &mut visitor);
180    ErrorCode::Ok
181}
182
183#[cfg(target_arch = "wasm32")]
184#[unsafe(no_mangle)]
185extern "C" fn accept_service(service: *const Service, context: *const ()) -> ErrorCode {
186    accept_service_impl(service, context, &VISITOR)
187}
188
189#[cfg(not(target_arch = "wasm32"))]
190#[unsafe(no_mangle)]
191extern "C" fn accept_service(
192    service: *const Service,
193    context: *const (),
194    visitor: *const Visitor,
195) -> ErrorCode {
196    accept_service_impl(service, context, visitor)
197}
198
199fn accept_service_impl(
200    service: *const Service,
201    context: *const (),
202    visitor: *const Visitor,
203) -> ErrorCode {
204    let service = deref!(service);
205    let mut visitor = deref_visitor!(context, visitor);
206    raw_visitor::accept_service(service.raw_ptr.as_ref(), &mut visitor);
207    ErrorCode::Ok
208}
209
210#[cfg(target_arch = "wasm32")]
211#[unsafe(no_mangle)]
212extern "C" fn accept_service_func(func: *const ServiceFunc, context: *const ()) -> ErrorCode {
213    accept_service_func_impl(func, context, &VISITOR)
214}
215
216#[cfg(not(target_arch = "wasm32"))]
217#[unsafe(no_mangle)]
218extern "C" fn accept_service_func(
219    func: *const ServiceFunc,
220    context: *const (),
221    visitor: *const Visitor,
222) -> ErrorCode {
223    accept_service_func_impl(func, context, visitor)
224}
225
226fn accept_service_func_impl(
227    func: *const ServiceFunc,
228    context: *const (),
229    visitor: *const Visitor,
230) -> ErrorCode {
231    let func = deref!(func);
232    let mut visitor = deref_visitor!(context, visitor);
233    raw_visitor::accept_service_func(func.raw_ptr.as_ref(), &mut visitor);
234    ErrorCode::Ok
235}
236
237#[cfg(target_arch = "wasm32")]
238#[unsafe(no_mangle)]
239extern "C" fn accept_service_event(event: *const ServiceEvent, context: *const ()) -> ErrorCode {
240    accept_service_event_impl(event, context, &VISITOR)
241}
242
243#[cfg(not(target_arch = "wasm32"))]
244#[unsafe(no_mangle)]
245extern "C" fn accept_service_event(
246    event: *const ServiceEvent,
247    context: *const (),
248    visitor: *const Visitor,
249) -> ErrorCode {
250    accept_service_event_impl(event, context, visitor)
251}
252
253fn accept_service_event_impl(
254    event: *const ServiceEvent,
255    context: *const (),
256    visitor: *const Visitor,
257) -> ErrorCode {
258    let event = deref!(event);
259    let mut visitor = deref_visitor!(context, visitor);
260    raw_visitor::accept_service_event(event.raw_ptr.as_ref(), &mut visitor);
261    ErrorCode::Ok
262}
263
264#[cfg(target_arch = "wasm32")]
265#[unsafe(no_mangle)]
266extern "C" fn accept_func_param(func_param: *const FuncParam, context: *const ()) -> ErrorCode {
267    accept_func_param_impl(func_param, context, &VISITOR)
268}
269
270#[cfg(not(target_arch = "wasm32"))]
271#[unsafe(no_mangle)]
272extern "C" fn accept_func_param(
273    func_param: *const FuncParam,
274    context: *const (),
275    visitor: *const Visitor,
276) -> ErrorCode {
277    accept_func_param_impl(func_param, context, visitor)
278}
279
280fn accept_func_param_impl(
281    func_param: *const FuncParam,
282    context: *const (),
283    visitor: *const Visitor,
284) -> ErrorCode {
285    let func_param = deref!(func_param);
286    let mut visitor = deref_visitor!(context, visitor);
287    raw_visitor::accept_func_param(func_param.raw_ptr.as_ref(), &mut visitor);
288    ErrorCode::Ok
289}
290
291#[cfg(target_arch = "wasm32")]
292#[unsafe(no_mangle)]
293extern "C" fn accept_type(r#type: *const Type, context: *const ()) -> ErrorCode {
294    accept_type_impl(r#type, context, &VISITOR)
295}
296
297#[cfg(not(target_arch = "wasm32"))]
298#[unsafe(no_mangle)]
299extern "C" fn accept_type(
300    r#type: *const Type,
301    context: *const (),
302    visitor: *const Visitor,
303) -> ErrorCode {
304    accept_type_impl(r#type, context, visitor)
305}
306
307fn accept_type_impl(r#type: *const Type, context: *const (), visitor: *const Visitor) -> ErrorCode {
308    let r#type = deref!(r#type);
309    let mut visitor = deref_visitor!(context, visitor);
310    raw_visitor::accept_type(r#type.raw_ptr.as_ref(), &mut visitor);
311    ErrorCode::Ok
312}
313
314#[cfg(target_arch = "wasm32")]
315#[unsafe(no_mangle)]
316extern "C" fn accept_type_decl(type_decl: *const TypeDecl, context: *const ()) -> ErrorCode {
317    accept_type_decl_impl(type_decl, context, &VISITOR)
318}
319
320#[cfg(not(target_arch = "wasm32"))]
321#[unsafe(no_mangle)]
322extern "C" fn accept_type_decl(
323    type_decl: *const TypeDecl,
324    context: *const (),
325    visitor: *const Visitor,
326) -> ErrorCode {
327    accept_type_decl_impl(type_decl, context, visitor)
328}
329
330fn accept_type_decl_impl(
331    type_decl: *const TypeDecl,
332    context: *const (),
333    visitor: *const Visitor,
334) -> ErrorCode {
335    let type_decl = deref!(type_decl);
336    let mut visitor = deref_visitor!(context, visitor);
337    raw_visitor::accept_type_decl(type_decl.raw_ptr.as_ref(), &mut visitor);
338    ErrorCode::Ok
339}
340
341#[cfg(target_arch = "wasm32")]
342#[unsafe(no_mangle)]
343extern "C" fn accept_struct_def(struct_def: *const StructDef, context: *const ()) -> ErrorCode {
344    accept_struct_def_impl(struct_def, context, &VISITOR)
345}
346
347#[cfg(not(target_arch = "wasm32"))]
348#[unsafe(no_mangle)]
349extern "C" fn accept_struct_def(
350    struct_def: *const StructDef,
351    context: *const (),
352    visitor: *const Visitor,
353) -> ErrorCode {
354    accept_struct_def_impl(struct_def, context, visitor)
355}
356
357fn accept_struct_def_impl(
358    struct_def: *const StructDef,
359    context: *const (),
360    visitor: *const Visitor,
361) -> ErrorCode {
362    let struct_def = deref!(struct_def);
363    let mut visitor = deref_visitor!(context, visitor);
364    raw_visitor::accept_struct_def(struct_def.raw_ptr.as_ref(), &mut visitor);
365    ErrorCode::Ok
366}
367
368#[cfg(target_arch = "wasm32")]
369#[unsafe(no_mangle)]
370extern "C" fn accept_struct_field(
371    struct_field: *const StructField,
372    context: *const (),
373) -> ErrorCode {
374    accept_struct_field_impl(struct_field, context, &VISITOR)
375}
376
377#[cfg(not(target_arch = "wasm32"))]
378#[unsafe(no_mangle)]
379extern "C" fn accept_struct_field(
380    struct_field: *const StructField,
381    context: *const (),
382    visitor: *const Visitor,
383) -> ErrorCode {
384    accept_struct_field_impl(struct_field, context, visitor)
385}
386
387fn accept_struct_field_impl(
388    struct_field: *const StructField,
389    context: *const (),
390    visitor: *const Visitor,
391) -> ErrorCode {
392    let struct_field = deref!(struct_field);
393    let mut visitor = deref_visitor!(context, visitor);
394    raw_visitor::accept_struct_field(struct_field.raw_ptr.as_ref(), &mut visitor);
395    ErrorCode::Ok
396}
397
398#[cfg(target_arch = "wasm32")]
399#[unsafe(no_mangle)]
400extern "C" fn accept_enum_def(enum_def: *const EnumDef, context: *const ()) -> ErrorCode {
401    accept_enum_def_impl(enum_def, context, &VISITOR)
402}
403
404#[cfg(not(target_arch = "wasm32"))]
405#[unsafe(no_mangle)]
406extern "C" fn accept_enum_def(
407    enum_def: *const EnumDef,
408    context: *const (),
409    visitor: *const Visitor,
410) -> ErrorCode {
411    accept_enum_def_impl(enum_def, context, visitor)
412}
413
414fn accept_enum_def_impl(
415    enum_def: *const EnumDef,
416    context: *const (),
417    visitor: *const Visitor,
418) -> ErrorCode {
419    let enum_def = deref!(enum_def);
420    let mut visitor = deref_visitor!(context, visitor);
421    raw_visitor::accept_enum_def(enum_def.raw_ptr.as_ref(), &mut visitor);
422    ErrorCode::Ok
423}
424
425#[cfg(target_arch = "wasm32")]
426#[unsafe(no_mangle)]
427extern "C" fn accept_enum_variant(
428    enum_variant: *const EnumVariant,
429    context: *const (),
430) -> ErrorCode {
431    accept_enum_variant_impl(enum_variant, context, &VISITOR)
432}
433
434#[cfg(not(target_arch = "wasm32"))]
435#[unsafe(no_mangle)]
436extern "C" fn accept_enum_variant(
437    enum_variant: *const EnumVariant,
438    context: *const (),
439    visitor: *const Visitor,
440) -> ErrorCode {
441    accept_enum_variant_impl(enum_variant, context, visitor)
442}
443
444fn accept_enum_variant_impl(
445    enum_variant: *const EnumVariant,
446    context: *const (),
447    visitor: *const Visitor,
448) -> ErrorCode {
449    let enum_variant = deref!(enum_variant);
450    let mut visitor = deref_visitor!(context, visitor);
451    raw_visitor::accept_enum_variant(enum_variant.raw_ptr.as_ref(), &mut visitor);
452    ErrorCode::Ok
453}
454
455mod wrapper {
456    use super::*;
457
458    macro_rules! fn_ptr_addr {
459        ($fn_ptr: expr) => {{
460            let fn_ptr_addr = $fn_ptr as *const ();
461            fn_ptr_addr
462        }};
463    }
464
465    pub(super) struct VisitorWrapper<'a> {
466        context: *const (),
467        visitor: &'a Visitor,
468    }
469
470    impl VisitorWrapper<'_> {
471        pub fn new(context: *const (), visitor: *const Visitor) -> Result<Self, ErrorCode> {
472            if visitor.is_null() {
473                return Err(ErrorCode::NullPtr);
474            }
475
476            Ok(Self {
477                context,
478                visitor: unsafe { visitor.as_ref() }.unwrap(),
479            })
480        }
481    }
482
483    impl<'ast> RawVisitor<'ast> for VisitorWrapper<'_> {
484        fn visit_ctor(&mut self, ctor: &'ast raw_ast::Ctor) {
485            if fn_ptr_addr!(self.visitor.visit_ctor).is_null() {
486                return raw_visitor::accept_ctor(ctor, self);
487            }
488            let ctor = Ctor {
489                raw_ptr: ctor.into(),
490            };
491            unsafe { (self.visitor.visit_ctor)(self.context, &ctor) };
492        }
493
494        fn visit_service(&mut self, service: &'ast raw_ast::Service) {
495            if fn_ptr_addr!(self.visitor.visit_service).is_null() {
496                return raw_visitor::accept_service(service, self);
497            }
498            let name_bytes = service.name().as_bytes();
499            let service = Service {
500                raw_ptr: service.into(),
501                name_ptr: name_bytes.as_ptr(),
502                name_len: name_bytes.len() as u32,
503            };
504            unsafe { (self.visitor.visit_service)(self.context, &service) };
505        }
506
507        fn visit_type(&mut self, r#type: &'ast raw_ast::Type) {
508            if fn_ptr_addr!(self.visitor.visit_type).is_null() {
509                return raw_visitor::accept_type(r#type, self);
510            }
511            let name_bytes = r#type.name().as_bytes();
512            let docs = r#type.docs().join("\n");
513            let docs_bytes = docs.as_bytes();
514
515            let r#type = Type {
516                name_ptr: name_bytes.as_ptr(),
517                name_len: name_bytes.len() as u32,
518                raw_ptr: r#type.into(),
519                docs_ptr: docs_bytes.as_ptr(),
520                docs_len: docs_bytes.len() as u32,
521            };
522            unsafe { (self.visitor.visit_type)(self.context, &r#type) };
523        }
524
525        fn visit_vector_type_decl(&mut self, item_type_decl: &'ast raw_ast::TypeDecl) {
526            if fn_ptr_addr!(self.visitor.visit_vector_type_decl).is_null() {
527                return raw_visitor::accept_type_decl(item_type_decl, self);
528            }
529            let item_type_decl = TypeDecl {
530                raw_ptr: item_type_decl.into(),
531            };
532            unsafe { (self.visitor.visit_vector_type_decl)(self.context, &item_type_decl) };
533        }
534
535        fn visit_array_type_decl(&mut self, item_type_decl: &'ast ast::TypeDecl, len: u32) {
536            if fn_ptr_addr!(self.visitor.visit_array_type_decl).is_null() {
537                return raw_visitor::accept_type_decl(item_type_decl, self);
538            }
539            let item_type_decl = TypeDecl {
540                raw_ptr: item_type_decl.into(),
541            };
542            unsafe { (self.visitor.visit_array_type_decl)(self.context, &item_type_decl, len) };
543        }
544
545        fn visit_map_type_decl(
546            &mut self,
547            key_type_decl: &'ast ast::TypeDecl,
548            value_type_decl: &'ast ast::TypeDecl,
549        ) {
550            if fn_ptr_addr!(self.visitor.visit_map_type_decl).is_null() {
551                raw_visitor::accept_type_decl(key_type_decl, self);
552                raw_visitor::accept_type_decl(value_type_decl, self);
553                return;
554            }
555            let key_type_decl = TypeDecl {
556                raw_ptr: key_type_decl.into(),
557            };
558            let value_type_decl = TypeDecl {
559                raw_ptr: value_type_decl.into(),
560            };
561            unsafe {
562                (self.visitor.visit_map_type_decl)(self.context, &key_type_decl, &value_type_decl)
563            };
564        }
565
566        fn visit_optional_type_decl(&mut self, optional_type_decl: &'ast raw_ast::TypeDecl) {
567            if fn_ptr_addr!(self.visitor.visit_optional_type_decl).is_null() {
568                return raw_visitor::accept_type_decl(optional_type_decl, self);
569            }
570            let optional_type_decl = TypeDecl {
571                raw_ptr: optional_type_decl.into(),
572            };
573            unsafe { (self.visitor.visit_optional_type_decl)(self.context, &optional_type_decl) };
574        }
575
576        fn visit_result_type_decl(
577            &mut self,
578            ok_type_decl: &'ast raw_ast::TypeDecl,
579            err_type_decl: &'ast raw_ast::TypeDecl,
580        ) {
581            if fn_ptr_addr!(self.visitor.visit_result_type_decl).is_null() {
582                raw_visitor::accept_type_decl(ok_type_decl, self);
583                raw_visitor::accept_type_decl(err_type_decl, self);
584                return;
585            }
586            let ok_type_decl = TypeDecl {
587                raw_ptr: ok_type_decl.into(),
588            };
589            let err_type_decl = TypeDecl {
590                raw_ptr: err_type_decl.into(),
591            };
592            unsafe {
593                (self.visitor.visit_result_type_decl)(self.context, &ok_type_decl, &err_type_decl)
594            };
595        }
596
597        fn visit_primitive_type_id(&mut self, primitive_type_id: raw_ast::PrimitiveType) {
598            if fn_ptr_addr!(self.visitor.visit_primitive_type_id).is_null() {
599                return;
600            }
601            unsafe { (self.visitor.visit_primitive_type_id)(self.context, primitive_type_id) };
602        }
603
604        fn visit_user_defined_type_id(&mut self, user_defined_type_id: &'ast str) {
605            if fn_ptr_addr!(self.visitor.visit_user_defined_type_id).is_null() {
606                return;
607            }
608            let user_defined_type_id = user_defined_type_id.as_bytes();
609            unsafe {
610                (self.visitor.visit_user_defined_type_id)(
611                    self.context,
612                    user_defined_type_id.as_ptr(),
613                    user_defined_type_id.len() as u32,
614                )
615            };
616        }
617
618        fn visit_ctor_func(&mut self, func: &'ast raw_ast::CtorFunc) {
619            if fn_ptr_addr!(self.visitor.visit_ctor_func).is_null() {
620                return raw_visitor::accept_ctor_func(func, self);
621            }
622            let func_name_bytes = func.name().as_bytes();
623            let docs = func.docs().join("\n");
624            let docs_bytes = docs.as_bytes();
625
626            let func = CtorFunc {
627                name_ptr: func_name_bytes.as_ptr(),
628                name_len: func_name_bytes.len() as u32,
629                raw_ptr: func.into(),
630                docs_ptr: docs_bytes.as_ptr(),
631                docs_len: docs_bytes.len() as u32,
632            };
633            unsafe { (self.visitor.visit_ctor_func)(self.context, &func) };
634        }
635
636        fn visit_service_func(&mut self, func: &'ast raw_ast::ServiceFunc) {
637            if fn_ptr_addr!(self.visitor.visit_service_func).is_null() {
638                return raw_visitor::accept_service_func(func, self);
639            }
640            let func_name_bytes = func.name().as_bytes();
641            let docs = func.docs().join("\n");
642            let docs_bytes = docs.as_bytes();
643
644            let func = ServiceFunc {
645                name_ptr: func_name_bytes.as_ptr(),
646                name_len: func_name_bytes.len() as u32,
647                is_query: func.is_query(),
648                raw_ptr: func.into(),
649                docs_ptr: docs_bytes.as_ptr(),
650                docs_len: docs_bytes.len() as u32,
651            };
652            unsafe { (self.visitor.visit_service_func)(self.context, &func) };
653        }
654
655        fn visit_service_event(&mut self, event: &'ast ast::ServiceEvent) {
656            if fn_ptr_addr!(self.visitor.visit_service_event).is_null() {
657                return raw_visitor::accept_service_event(event, self);
658            }
659            let event_name_bytes = event.name().as_bytes();
660            let docs = event.docs().join("\n");
661            let docs_bytes = docs.as_bytes();
662
663            let event = ServiceEvent {
664                name_ptr: event_name_bytes.as_ptr(),
665                name_len: event_name_bytes.len() as u32,
666                raw_ptr: event.into(),
667                docs_ptr: docs_bytes.as_ptr(),
668                docs_len: docs_bytes.len() as u32,
669            };
670            unsafe { (self.visitor.visit_service_event)(self.context, &event) };
671        }
672
673        fn visit_func_param(&mut self, func_param: &'ast raw_ast::FuncParam) {
674            if fn_ptr_addr!(self.visitor.visit_func_param).is_null() {
675                return raw_visitor::accept_func_param(func_param, self);
676            }
677            let func_param_name_bytes = func_param.name().as_bytes();
678            let func_param = FuncParam {
679                name_ptr: func_param_name_bytes.as_ptr(),
680                name_len: func_param_name_bytes.len() as u32,
681                raw_ptr: func_param.into(),
682            };
683            unsafe { (self.visitor.visit_func_param)(self.context, &func_param) };
684        }
685
686        fn visit_func_output(&mut self, func_output: &'ast raw_ast::TypeDecl) {
687            if fn_ptr_addr!(self.visitor.visit_func_output).is_null() {
688                return raw_visitor::accept_type_decl(func_output, self);
689            }
690            let func_output = TypeDecl {
691                raw_ptr: func_output.into(),
692            };
693            unsafe { (self.visitor.visit_func_output)(self.context, &func_output) };
694        }
695
696        fn visit_struct_def(&mut self, struct_def: &'ast raw_ast::StructDef) {
697            if fn_ptr_addr!(self.visitor.visit_struct_def).is_null() {
698                return raw_visitor::accept_struct_def(struct_def, self);
699            }
700            let struct_def = StructDef {
701                raw_ptr: struct_def.into(),
702            };
703            unsafe { (self.visitor.visit_struct_def)(self.context, &struct_def) };
704        }
705
706        fn visit_struct_field(&mut self, struct_field: &'ast raw_ast::StructField) {
707            if fn_ptr_addr!(self.visitor.visit_struct_field).is_null() {
708                return raw_visitor::accept_struct_field(struct_field, self);
709            }
710            let struct_field_name_bytes = struct_field.name().map(|n| n.as_bytes());
711            let docs = struct_field.docs().join("\n");
712            let docs_bytes = docs.as_bytes();
713
714            let struct_field = StructField {
715                name_ptr: struct_field_name_bytes.map_or(ptr::null(), |n| n.as_ptr()),
716                name_len: struct_field_name_bytes.map_or(0, |n| n.len() as u32),
717                raw_ptr: struct_field.into(),
718                docs_ptr: docs_bytes.as_ptr(),
719                docs_len: docs_bytes.len() as u32,
720            };
721            unsafe { (self.visitor.visit_struct_field)(self.context, &struct_field) };
722        }
723
724        fn visit_enum_def(&mut self, enum_def: &'ast raw_ast::EnumDef) {
725            if fn_ptr_addr!(self.visitor.visit_enum_def).is_null() {
726                return raw_visitor::accept_enum_def(enum_def, self);
727            }
728            let enum_def = EnumDef {
729                raw_ptr: enum_def.into(),
730            };
731            unsafe { (self.visitor.visit_enum_def)(self.context, &enum_def) };
732        }
733
734        fn visit_enum_variant(&mut self, enum_variant: &'ast raw_ast::EnumVariant) {
735            if fn_ptr_addr!(self.visitor.visit_enum_variant).is_null() {
736                return raw_visitor::accept_enum_variant(enum_variant, self);
737            }
738            let enum_variant_name_bytes = enum_variant.name().as_bytes();
739            let docs = enum_variant.docs().join("\n");
740            let docs_bytes = docs.as_bytes();
741
742            let enum_variant = EnumVariant {
743                name_ptr: enum_variant_name_bytes.as_ptr(),
744                name_len: enum_variant_name_bytes.len() as u32,
745                raw_ptr: enum_variant.into(),
746                docs_ptr: docs_bytes.as_ptr(),
747                docs_len: docs_bytes.len() as u32,
748            };
749            unsafe { (self.visitor.visit_enum_variant)(self.context, &enum_variant) };
750        }
751    }
752}