Skip to main content

perfetto_sdk/protos/
mod.rs

1// Copyright (C) 2025 Rivos Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/// `common` protobufs.
16pub mod common;
17
18/// `config` protobufs.
19pub mod config;
20
21/// `trace` protobufs.
22#[allow(clippy::module_inception)]
23pub mod trace;
24
25/// Defines a protobuf enum.
26#[macro_export]
27macro_rules! pb_enum {
28    (
29        $name:ident {
30            $( $entry:ident : $id:literal ),+ $(,)?
31        }
32    ) => {
33        paste::paste! {
34            #[doc = concat!("Protobuf enum for `", stringify!($name), "`")]
35            #[allow(non_camel_case_types)]
36            #[repr(u32)]
37            #[derive(Debug, Clone, Copy, PartialEq, Eq)]
38            pub enum $name {
39                $(
40                    #[doc = concat!("Variant for `", stringify!($entry), "`")]
41                    [<$entry:camel>] = $id
42                ),*
43            }
44
45            impl From<$name> for u32 {
46                #[inline]
47                fn from(v: $name) -> u32 { v as u32 }
48            }
49
50            impl TryFrom<u32> for $name {
51                type Error = ();
52                fn try_from(v: u32) -> Result<Self, Self::Error> {
53                    match v {
54                        $(
55                            $id => Ok([<$name>]::[<$entry:camel>]),
56                        )*
57                        _ => Err(()),
58                    }
59                }
60            }
61        }
62    };
63}
64
65/// Defines a protobuf message.
66///
67/// Defines the type for a protobuf message. `name` is the name of the message type.
68#[macro_export]
69macro_rules! pb_msg {
70    // Empty message (no fields)
71    (
72        $name:ident {
73        }
74    ) => {
75        paste::paste! {
76            #[doc = concat!("Protobuf message struct for `", stringify!($name), "`")]
77            #[allow(non_camel_case_types)]
78            pub struct $name<'a, 'b> {
79                #[doc = concat!("PbMsg for protobuf message `", stringify!($name), "`")]
80                pub msg: &'a mut $crate::pb_msg::PbMsg<'b>,
81            }
82        }
83    };
84
85    // Message with fields
86    (
87        $name:ident {
88            $( $field:ident : $tp:tt, $kind:ident, $id:literal ),+ $(,)?
89        }
90    ) => {
91        paste::paste! {
92            #[doc = concat!("Protobuf field numbers for `", stringify!($name), "`")]
93            #[repr(u32)]
94            pub enum [<$name:camel FieldNumber>] {
95                $(
96                    #[doc = concat!("Field number for `", stringify!($field), "`")]
97                    [<$field:camel>] = $id
98                ),*
99            }
100        }
101
102        paste::paste! {
103            #[doc = concat!("Protobuf message struct for `", stringify!($name), "`")]
104            #[allow(non_camel_case_types)]
105            pub struct $name<'a, 'b> {
106                #[doc = concat!("PbMsg for protobuf message `", stringify!($name), "`")]
107                pub msg: &'a mut $crate::pb_msg::PbMsg<'b>,
108            }
109        }
110
111        impl<'a, 'b> $name<'a, 'b> {
112            $(
113                pb_msg!(@setter pub fn $name, $field, $id, $kind, $tp);
114            )*
115        }
116    };
117
118    // Cstr
119    (@decl $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, String) => {
120        paste::paste! {
121            #[doc = concat!("Set `", stringify!($field), "` field")]
122            $vis fn [<set_ $field>] (&mut self, value: impl Into<String>) -> &mut Self;
123        }
124    };
125    (@setter $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, String) => {
126        paste::paste! {
127            #[doc = concat!("Set `", stringify!($field), "` field")]
128            $vis fn [<set_ $field>] (&mut self, value: impl Into<String>) -> &mut Self {
129                let s: String = value.into();
130                self.msg.append_type2_field($id, s.as_bytes());
131                self
132            }
133        }
134    };
135
136    // float
137    (@decl $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, String) => {
138        paste::paste! {
139            #[doc = concat!("Set `", stringify!($field), "` field")]
140            $vis fn [<set_ $field>] (&mut self, value: f32) -> &mut Self;
141        }
142    };
143    (@setter $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, f32) => {
144        paste::paste! {
145            #[doc = concat!("Set `", stringify!($field), "` field")]
146            $vis fn [<set_ $field>] (&mut self, value: f32) -> &mut Self {
147                self.msg.append_float_field($id, value);
148                self
149            }
150        }
151    };
152
153    // double
154    (@decl $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, String) => {
155        paste::paste! {
156            #[doc = concat!("Set `", stringify!($field), "` field")]
157            $vis fn [<set_ $field>] (&mut self, value: f64) -> &mut Self;
158        }
159    };
160    (@setter $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, f64) => {
161        paste::paste! {
162            #[doc = concat!("Set `", stringify!($field), "` field")]
163            $vis fn [<set_ $field>] (&mut self, value: f64) -> &mut Self {
164                self.msg.append_double_field($id, value);
165                self
166            }
167        }
168    };
169
170    // Varint
171    (@decl $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, u32) => {
172        pb_msg!(@varint_decl $vis fn $name, $field, $id, u32);
173    };
174    (@setter $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, u32) => {
175        pb_msg!(@varint_setter $vis fn $name, $field, $id, u32);
176    };
177    (@decl $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, u64) => {
178        pb_msg!(@varint_decl $vis fn $name, $field, $id, u64);
179    };
180    (@setter $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, u64) => {
181        pb_msg!(@varint_setter $vis fn $name, $field, $id, u64);
182    };
183    (@decl $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, i32) => {
184        pb_msg!(@varint_decl $vis fn $name, $field, $id, i32);
185    };
186    (@setter $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, i32) => {
187        pb_msg!(@varint_setter $vis fn $name, $field, $id, i32);
188    };
189    (@decl $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, i64) => {
190        pb_msg!(@varint_decl $vis fn $name, $field, $id, i64);
191    };
192    (@setter $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, i64) => {
193        pb_msg!(@varint_setter $vis fn $name, $field, $id, i64);
194    };
195    (@decl $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, bool) => {
196        pb_msg!(@varint_decl $vis fn $name, $field, $id, bool);
197    };
198    (@setter $vis:vis fn $name:ident, $field:ident, $id: literal, primitive, bool) => {
199        pb_msg!(@varint_setter $vis fn $name, $field, $id, bool);
200    };
201
202    (@varint_decl $vis:vis fn $name:ident, $field:ident, $id: literal, $tp:tt) => {
203        paste::paste! {
204            #[doc = concat!("Set `", stringify!($field), "` field")]
205            $vis fn [<set_ $field>] (&mut self, value: $tp) -> &mut Self;
206        }
207    };
208    (@varint_setter $vis:vis fn $name:ident, $field:ident, $id: literal, $tp:tt) => {
209        paste::paste! {
210            #[doc = concat!("Set `", stringify!($field), "` field")]
211            $vis fn [<set_ $field>] (&mut self, value: $tp) -> &mut Self {
212                self.msg.append_type0_field($id, value as u64);
213                self
214            }
215        }
216    };
217
218    // Enum
219    (@decl $vis:vis fn $name:ident, $field:ident, $id: literal, enum, $tp:tt) => {
220        paste::paste! {
221            #[doc = concat!("Set `", stringify!($field), "` field")]
222            $vis fn [<set_ $field>] (&mut self, value: $tp) -> &mut Self;
223        }
224    };
225    (@setter $vis:vis fn $name:ident, $field:ident, $id: literal, enum, $tp:tt) => {
226        paste::paste! {
227            #[doc = concat!("Set `", stringify!($field), "` field")]
228            $vis fn [<set_ $field>] (&mut self, value: $tp) -> &mut Self {
229                self.msg.append_type0_field($id, value as u64);
230                self
231            }
232        }
233    };
234
235    // Fallback to message
236    (@decl $vis:vis fn $name:ident, $field:ident, $id: literal, msg, $tp:tt) => {
237        paste::paste! {
238            #[doc = concat!("Set `", stringify!($field), "` field")]
239            $vis fn [<set_ $field>] <F>(&mut self, cb: F) -> &mut Self
240            where
241                F: for<'p> Fn(&'p mut $tp);
242        }
243    };
244    (@setter $vis:vis fn $name:ident, $field:ident, $id: literal, msg, $tp:tt) => {
245        paste::paste! {
246            #[doc = concat!("Set `", stringify!($field), "` field")]
247            $vis fn [<set_ $field>] <F>(&mut self, cb: F) -> &mut Self
248            where
249                F: for<'p> Fn(&'p mut $tp),
250            {
251                self.msg.append_nested($id, |nested_msg| {
252                    let mut msg_field: $tp<'_, '_> = $tp {
253                        msg: nested_msg,
254                    };
255                    cb(&mut msg_field);
256                });
257                self
258            }
259        }
260    };
261}
262
263/// Defines extra fields for a protobuf message.
264#[macro_export]
265macro_rules! pb_msg_ext {
266    (
267        $name:ident {
268            $( $field:ident : $tp:tt, $kind:ident, $id:literal ),+ $(,)?
269        }
270    ) => {
271        paste::paste! {
272            #[doc = concat!("Protobuf extra field numbers for `", stringify!($name), "`")]
273            #[repr(u32)]
274            pub enum [<$name:camel ExtFieldNumber>] {
275                $(
276                    #[doc = concat!("Field number for `", stringify!($field), "`")]
277                    [<$field:camel>] = $id
278                ),*
279            }
280        }
281
282        paste::paste! {
283            #[doc = concat!("Protobuf extra message trait for `", stringify!($name), "`")]
284            #[allow(non_camel_case_types)]
285            pub trait [<$name Ext>]<'a, 'b> {
286                $(
287                    pb_msg!(@decl fn $name, $field, $id, $kind, $tp);
288                )*
289            }
290
291            impl<'a, 'b> [<$name Ext>]<'_, '_> for $name<'a, 'b> {
292                $(
293                    pb_msg!(@setter fn $name, $field, $id, $kind, $tp);
294                )*
295            }
296        }
297    };
298}