1<%
2    def parameters_as_arg_list():
3        return ", ".join([ parameter(p, ref="&&") for p in method.parameters ])
4
5    def parameters_as_list(transform=lambda p: p.camelCase):
6        return ", ".join([ transform(p) for p in method.parameters ])
7
8    def parameters_types_as_list():
9        return ", ".join([ p.cppTypeParam(interface.name, full=True)
10                for p in method.parameters ])
11
12    def parameter(p, defaultValue=False, ref=""):
13        r = "%s%s %s" % (p.cppTypeParam(interface.name), ref, p.camelCase)
14        if defaultValue:
15            r += default_value(p)
16        return r
17
18    def default_value(p):
19        if p.defaultValue != None:
20            return " = " + str(p.defaultValue)
21        else:
22            return ""
23
24    def interface_name():
25        return interface.name.split('.').pop()
26
27    def error_namespace(e):
28        n = e.split('.');
29        n.pop(); # Remove error name.
30
31        n = map((lambda x: interface.name if x == "self" else x), n);
32        return '::'.join('.'.join(n).split('.'));
33
34    def error_name(e):
35        return e.split('.').pop();
36
37    def error_include(e):
38        l = error_namespace(e).split('::')
39        l.pop() # Remove "Error"
40        return '/'.join(l) + '/error.hpp';
41%>
42###
43### Emit 'header'
44###
45    % if ptype == 'header':
46        /** @brief Implementation for ${ method.name }
47         *  ${ method.description.strip() }
48    % if len(method.parameters) != 0:
49         *
50        % for p in method.parameters:
51         *  @param[in] ${p.camelCase} - ${p.description.strip()}
52        % endfor
53    % endif
54    % if len(method.returns) != 0:
55         *
56        % for r in method.returns:
57         *  @return ${r.camelCase}[${r.cppTypeParam(interface.name)}] \
58- ${r.description.strip()}
59        % endfor
60    % endif
61         */
62        virtual ${method.cpp_return_type(interface)} ${ method.camelCase }(
63            ${ method.get_parameters_str(interface) }) = 0;
64###
65### Emit 'callback-header'
66###
67    % elif ptype == 'callback-header':
68        /** @brief sd-bus callback for ${ method.name }
69         */
70        static int _callback_${ method.CamelCase }(
71            sd_bus_message*, void*, sd_bus_error*);
72###
73### Emit 'vtable'
74###
75    % elif ptype == 'vtable':
76    vtable::method("${method.name}",
77                   details::${interface_name()}::_param_${ method.CamelCase }
78                        .data(),
79                   details::${interface_name()}::_return_${ method.CamelCase }
80                        .data(),
81        % if method.cpp_flags:
82                   _callback_${method.CamelCase},
83                   ${method.cpp_flags}),
84        % else:
85                   _callback_${method.CamelCase}),
86        % endif
87###
88### Emit 'callback-cpp'
89###
90    % elif ptype == 'callback-cpp':
91int ${interface_name()}::_callback_${ method.CamelCase }(
92        sd_bus_message* msg, void* context, sd_bus_error* error)
93{
94    auto o = static_cast<${interface_name()}*>(context);
95
96    % if method.errors:
97    try
98    % endif
99    {
100        return sdbusplus::sdbuspp::method_callback\
101    % if len(method.returns) > 1:
102<true>\
103    % endif
104(
105                msg, o->_intf, error,
106                std::function(
107                    [=](${parameters_as_arg_list()})
108                    {
109                        return o->${ method.camelCase }(
110                                ${parameters_as_list()});
111                    }
112                ));
113    }
114    % for e in method.errors:
115    catch(const sdbusplus::${error_namespace(e)}::${error_name(e)}& e)
116    {
117        return o->_intf->sd_bus_error_set(error, e.name(), e.description());
118    }
119    % endfor
120
121    return 0;
122}
123
124namespace details
125{
126namespace ${interface_name()}
127{
128static const auto _param_${ method.CamelCase } =
129    % if len(method.parameters) == 0:
130        utility::tuple_to_array(std::make_tuple('\0'));
131    % else:
132        utility::tuple_to_array(message::types::type_id<
133                ${ parameters_types_as_list() }>());
134    % endif
135static const auto _return_${ method.CamelCase } =
136    % if len(method.returns) == 0:
137        utility::tuple_to_array(std::make_tuple('\0'));
138    % else:
139        utility::tuple_to_array(message::types::type_id<
140                ${ method.returns_as_list(interface, full=True) }>());
141    % endif
142}
143}
144    % elif ptype == 'callback-cpp-includes':
145        % for e in method.errors:
146#include <${error_include(e)}>
147        % endfor
148    % elif ptype == 'callback-hpp-includes':
149        % for i in interface.enum_includes(method.returns + method.parameters):
150#include <${i}>
151        % endfor
152    % endif
153