1use fidl_data_zx::{ObjType as ObjectType, Rights};
6use serde::de::{Deserialize as DeserializeIface, Deserializer};
7use serde_derive::Deserialize;
8use std::collections::HashMap;
9
10use std::sync::{Arc, Weak};
11
12use crate::error::{Error, Result};
13use crate::value::Value;
14
15trait Named {
18 fn name(&self) -> String;
19}
20
21impl<T: Named> Named for Arc<T> {
22 fn name(&self) -> String {
23 Arc::as_ref(self).name()
24 }
25}
26
27macro_rules! named {
28 ($ident:ty) => {
29 impl Named for $ident {
30 fn name(&self) -> String {
31 self.name.clone()
32 }
33 }
34 };
35}
36
37fn object_type<'de, D: Deserializer<'de>>(
39 deserializer: D,
40) -> std::result::Result<Option<ObjectType>, D::Error> {
41 Ok(Option::<u32>::deserialize(deserializer)?.map(|x| ObjectType::from_raw(x)).flatten())
42}
43
44fn composed_protocols<'de, D: Deserializer<'de>>(
46 deserializer: D,
47) -> std::result::Result<Vec<String>, D::Error> {
48 #[derive(Deserialize)]
49 struct ComposedProtocol {
50 name: String,
51 }
52 Ok(Vec::<ComposedProtocol>::deserialize(deserializer)?.into_iter().map(|x| x.name).collect())
53}
54
55fn rights<'de, D: Deserializer<'de>>(
57 deserializer: D,
58) -> std::result::Result<Option<Rights>, D::Error> {
59 if let Some(rights) = Option::<u32>::deserialize(deserializer)? {
60 Ok(Some(Rights::from_bits_truncate(rights)))
61 } else {
62 Ok(None)
63 }
64}
65
66fn hash_by_name<'de, D: Deserializer<'de>, T: Named + DeserializeIface<'de>>(
68 deserializer: D,
69) -> std::result::Result<HashMap<String, T>, D::Error> {
70 let mut ret = HashMap::new();
71 for item in Vec::<T>::deserialize(deserializer)? {
72 ret.insert(item.name().clone(), item);
73 }
74 Ok(ret)
75}
76
77fn hash_by_name_arc<'de, D: Deserializer<'de>, T: Named + DeserializeIface<'de>>(
79 deserializer: D,
80) -> std::result::Result<HashMap<String, Arc<T>>, D::Error> {
81 let mut ret = HashMap::new();
82 for item in Vec::<T>::deserialize(deserializer)? {
83 ret.insert(item.name().clone(), Arc::new(item));
84 }
85 Ok(ret)
86}
87
88fn hash_by_ordinal<'de, D: Deserializer<'de>>(
91 deserializer: D,
92) -> std::result::Result<HashMap<u64, TableOrUnionMember>, D::Error> {
93 let mut ret = HashMap::new();
94 for item in Vec::<TableOrUnionMember>::deserialize(deserializer)? {
95 ret.insert(item.ordinal, item);
96 }
97 Ok(ret)
98}
99
100fn extract_struct_size<'de, D: Deserializer<'de>>(
102 deserializer: D,
103) -> std::result::Result<usize, D::Error> {
104 Ok(TypeShape::deserialize(deserializer)?.inline_size)
105}
106
107fn extract_member_offset<'de, D: Deserializer<'de>>(
109 deserializer: D,
110) -> std::result::Result<usize, D::Error> {
111 Ok(MemberShape::deserialize(deserializer)?.offset)
112}
113
114#[derive(Deserialize)]
115struct Module {
116 name: String,
117 #[serde(deserialize_with = "hash_by_name")]
118 bits_declarations: HashMap<String, Bits>,
119 #[serde(deserialize_with = "hash_by_name")]
120 enum_declarations: HashMap<String, Enum>,
121 #[serde(deserialize_with = "hash_by_name")]
122 protocol_declarations: HashMap<String, Protocol>,
123 #[serde(deserialize_with = "hash_by_name")]
124 table_declarations: HashMap<String, TableOrUnion>,
125 #[serde(deserialize_with = "hash_by_name")]
126 struct_declarations: HashMap<String, Struct>,
127 #[serde(deserialize_with = "hash_by_name")]
128 union_declarations: HashMap<String, TableOrUnion>,
129 declarations: HashMap<String, String>,
130}
131
132#[derive(Deserialize)]
133pub struct TableOrUnion {
134 pub name: String,
135 pub strict: bool,
136 #[serde(deserialize_with = "hash_by_ordinal")]
137 pub members: HashMap<u64, TableOrUnionMember>,
138}
139named!(TableOrUnion);
140
141#[derive(Deserialize)]
142pub struct TableOrUnionMember {
143 pub name: String,
144 #[serde(rename = "type")]
145 pub ty: Type,
146 pub ordinal: u64,
147}
148
149#[derive(Deserialize)]
150#[serde(try_from = "EnumExpanded")]
151pub struct Enum {
152 pub name: String,
153 pub ty: Type,
154 pub strict: bool,
155 pub members: Vec<ValueMember>,
156}
157named!(Enum);
158
159#[derive(Deserialize)]
160#[serde(try_from = "BitsExpanded")]
161pub struct Bits {
162 pub name: String,
163 pub ty: Type,
164 pub strict: bool,
165 pub mask: u64,
166 pub members: Vec<ValueMember>,
167}
168named!(Bits);
169
170pub struct ValueMember {
171 pub name: String,
172 pub value: Value,
173}
174
175#[derive(Deserialize)]
176struct EnumExpanded {
177 name: String,
178 #[serde(rename = "type")]
179 ty: String,
180 strict: bool,
181 members: Vec<ValueMemberExpanded>,
182}
183
184#[derive(Deserialize)]
185struct BitsExpanded {
186 name: String,
187 #[serde(rename = "type")]
188 ty: Type,
189 strict: bool,
190 members: Vec<ValueMemberExpanded>,
191 mask: String,
192}
193
194#[derive(Deserialize)]
196struct ValueMemberExpanded {
197 name: String,
198 value: ValueBlock,
199}
200
201#[derive(Deserialize)]
202struct ValueBlock {
203 value: String,
204}
205
206#[derive(Debug)]
207enum ValueConvertError {
211 FloatError { _error: std::num::ParseFloatError },
212 IntError { _error: std::num::ParseIntError },
213 BadPrimitive { _error: String },
214}
215
216impl From<std::num::ParseFloatError> for ValueConvertError {
217 fn from(item: std::num::ParseFloatError) -> ValueConvertError {
218 ValueConvertError::FloatError { _error: item }
219 }
220}
221
222impl From<std::num::ParseIntError> for ValueConvertError {
223 fn from(item: std::num::ParseIntError) -> ValueConvertError {
224 ValueConvertError::IntError { _error: item }
225 }
226}
227
228impl std::fmt::Display for ValueConvertError {
229 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
230 std::fmt::Debug::fmt(self, f)
231 }
232}
233
234fn convert_expanded_value_member(
235 ty: &Type,
236 container: &str,
237 members: Vec<ValueMemberExpanded>,
238) -> std::result::Result<Vec<ValueMember>, ValueConvertError> {
239 type ConverterType = dyn Fn(String) -> std::result::Result<Value, ValueConvertError>;
240
241 let converter = match ty {
242 Type::U8 => (&|x: String| Ok(Value::U8(x.parse::<u8>()?))) as &ConverterType,
243 Type::U16 => (&|x: String| Ok(Value::U16(x.parse::<u16>()?))) as &ConverterType,
244 Type::U32 => (&|x: String| Ok(Value::U32(x.parse::<u32>()?))) as &ConverterType,
245 Type::U64 => (&|x: String| Ok(Value::U64(x.parse::<u64>()?))) as &ConverterType,
246 Type::I8 => (&|x: String| Ok(Value::I8(x.parse::<i8>()?))) as &ConverterType,
247 Type::I16 => (&|x: String| Ok(Value::I16(x.parse::<i16>()?))) as &ConverterType,
248 Type::I32 => (&|x: String| Ok(Value::I32(x.parse::<i32>()?))) as &ConverterType,
249 Type::I64 => (&|x: String| Ok(Value::I64(x.parse::<i64>()?))) as &ConverterType,
250 Type::F32 => (&|x: String| Ok(Value::F32(x.parse::<f32>()?))) as &ConverterType,
251 Type::F64 => (&|x: String| Ok(Value::F64(x.parse::<f64>()?))) as &ConverterType,
252 _ => return Err(ValueConvertError::BadPrimitive { _error: container.to_owned() }),
253 };
254
255 let mut result = Vec::new();
256
257 for member in members {
258 result.push(ValueMember { name: member.name, value: converter(member.value.value)? });
259 }
260
261 Ok(result)
262}
263
264impl TryFrom<EnumExpanded> for Enum {
265 type Error = ValueConvertError;
266
267 fn try_from(exp: EnumExpanded) -> std::result::Result<Enum, Self::Error> {
268 let (name, ty, strict, members) = (exp.name, exp.ty.into(), exp.strict, exp.members);
269 let members = convert_expanded_value_member(&ty, &name, members)?;
270 Ok(Enum { name, ty, strict, members })
271 }
272}
273
274impl TryFrom<BitsExpanded> for Bits {
275 type Error = ValueConvertError;
276
277 fn try_from(exp: BitsExpanded) -> std::result::Result<Bits, Self::Error> {
278 let (name, ty, strict, members, mask) =
279 (exp.name, exp.ty, exp.strict, exp.members, exp.mask);
280 let members = convert_expanded_value_member(&ty, &name, members)?;
281 let mask = mask.parse::<u64>()?;
282 Ok(Bits { name, ty, strict, members, mask })
283 }
284}
285
286#[derive(Deserialize)]
287pub struct Protocol {
288 pub name: String,
289 #[serde(deserialize_with = "hash_by_name_arc")]
290 pub methods: HashMap<String, Arc<Method>>,
291 #[serde(deserialize_with = "composed_protocols")]
292 pub composed_protocols: Vec<String>,
293}
294named!(Protocol);
295
296#[derive(Debug, Clone, Deserialize)]
297pub struct Struct {
298 pub name: String,
299 pub members: Vec<Member>,
300 #[serde(rename = "type_shape_v2", deserialize_with = "extract_struct_size")]
301 pub size: usize,
302}
303named!(Struct);
304
305#[derive(Debug, Clone, Deserialize)]
306pub struct Member {
307 pub name: String,
308 #[serde(rename = "type")]
309 pub ty: Type,
310 #[serde(rename = "field_shape_v2", deserialize_with = "extract_member_offset")]
311 pub offset: usize,
312}
313named!(Member);
314
315#[derive(Deserialize)]
316struct MemberShape {
317 offset: usize,
318}
319
320#[derive(Deserialize)]
321struct TypeShape {
322 inline_size: usize,
323}
324
325#[derive(Debug, Deserialize)]
326pub struct Method {
327 pub name: String,
328 pub ordinal: u64,
329 pub strict: bool,
330 pub has_request: bool,
331 #[serde(rename = "maybe_request_payload")]
332 pub request: Option<Type>,
333 pub has_response: bool,
334 #[serde(rename = "maybe_response_payload")]
335 pub response: Option<Type>,
336}
337named!(Method);
338
339#[derive(Clone, Deserialize, Debug)]
340#[serde(from = "TypeInfo")]
341pub enum Type {
342 Unknown(TypeInfo),
343 UnknownString(String),
344 FrameworkError,
345 Identifier { name: String, nullable: bool },
346 Bool,
347 U8,
348 U16,
349 U32,
350 U64,
351 I8,
352 I16,
353 I32,
354 I64,
355 F32,
356 F64,
357 Array(Box<Type>, usize),
358 Vector { ty: Box<Type>, nullable: bool, element_count: Option<usize> },
359 String { nullable: bool, byte_count: Option<usize> },
360 Handle { object_type: ObjectType, rights: Option<Rights>, nullable: bool },
361 Endpoint { role: EndpointRole, protocol: String, rights: Option<Rights>, nullable: bool },
362}
363
364impl Type {
365 pub fn inline_size(&self, ns: &Namespace) -> Result<usize> {
366 use Type::*;
367
368 match self {
369 Bool | U8 | I8 => Ok(1),
370 U16 | I16 => Ok(2),
371 FrameworkError | U32 | I32 | F32 | Handle { .. } | Endpoint { .. } => Ok(4),
372 U64 | I64 | F64 => Ok(8),
373 Vector { .. } | String { .. } => Ok(16),
374 Array(a, b) => Ok(a.inline_size(ns)? * b),
375 Identifier { name, nullable } => match ns.lookup(name)? {
376 LookupResult::Bits(b) => b.ty.inline_size(ns),
377 LookupResult::Enum(e) => e.ty.inline_size(ns),
378 LookupResult::Struct(s) => Ok(if *nullable { 8 } else { s.size }),
379 LookupResult::Table(_) => Ok(16),
380 LookupResult::Union(_) => Ok(16),
381 LookupResult::Protocol(_) => Err(Error::LibraryError(format!(
382 "Protocol names cannot be used as identifiers: {}",
383 name
384 ))),
385 },
386 Unknown(_) | UnknownString(_) => {
387 Err(Error::LibraryError("Cannot get size for unknown type.".to_owned()))
388 }
389 }
390 }
391
392 pub fn is_resolved(&self, ns: &Namespace) -> bool {
393 match self {
394 Type::Unknown(_) | Type::UnknownString(_) => false,
395 Type::Identifier { name, .. } => ns.lookup(name).is_ok(),
396 _ => true,
397 }
398 }
399}
400
401#[derive(Clone, Deserialize, Debug)]
402pub struct TypeInfo {
403 #[serde(rename = "kind_v2")]
404 pub kind: TypeKind,
405 #[serde(default)]
406 #[serde(rename = "obj_type")]
407 #[serde(deserialize_with = "object_type")]
408 pub object_type: Option<ObjectType>,
409 #[serde(default)]
410 #[serde(deserialize_with = "rights")]
411 pub rights: Option<Rights>,
412 pub identifier: Option<String>,
413 pub protocol: Option<String>,
414 pub role: Option<EndpointRole>,
415 pub subtype: Option<String>,
416 pub element_type: Box<Option<TypeInfo>>,
417 pub element_count: Option<usize>,
418 pub maybe_element_count: Option<usize>,
419 #[serde(default)]
420 pub nullable: bool,
421}
422
423#[derive(Clone, Deserialize, Debug)]
424#[serde(rename_all = "lowercase")]
425pub enum TypeKind {
426 Primitive,
427 Vector,
428 Array,
429 Handle,
430 Identifier,
431 String,
432 Endpoint,
433 Internal,
434
435 #[serde(untagged)]
436 Unknown(String),
437}
438
439#[derive(Clone, Deserialize, Debug)]
440#[serde(rename_all = "lowercase")]
441pub enum EndpointRole {
442 Client,
443 Server,
444}
445
446impl From<TypeInfo> for Type {
447 fn from(info: TypeInfo) -> Type {
448 let nullable = info.nullable;
449
450 match info.kind {
451 TypeKind::Primitive => {
452 let subtype = if let Some(x) = info.subtype.clone() {
453 x
454 } else {
455 return Type::Unknown(info);
456 };
457 match subtype.into() {
458 Type::UnknownString(_) => Type::Unknown(info),
459 ty @ _ => ty,
460 }
461 }
462 TypeKind::Vector => match *info.element_type {
463 Some(t) => Type::Vector {
464 ty: Box::new(t.into()),
465 nullable,
466 element_count: info.maybe_element_count,
467 },
468 _ => Type::Unknown(info),
469 },
470 TypeKind::Array => {
471 if info.element_type.is_some() && info.element_count.is_some() {
472 Type::Array(
473 Box::new(info.element_type.unwrap().into()),
474 info.element_count.unwrap(),
475 )
476 } else {
477 Type::Unknown(info)
478 }
479 }
480 TypeKind::Handle => {
481 if let Some(object_type) = info.object_type {
482 Type::Handle { object_type, rights: info.rights, nullable }
483 } else {
484 Type::Unknown(info)
485 }
486 }
487 TypeKind::Identifier => {
488 if let Some(identifier) = info.identifier {
489 Type::Identifier { name: identifier, nullable }
490 } else {
491 Type::Unknown(info)
492 }
493 }
494 TypeKind::String => Type::String { nullable, byte_count: info.maybe_element_count },
495 TypeKind::Endpoint => {
496 let Some(role) = info.role.clone() else { return Type::Unknown(info) };
497 let Some(protocol) = info.protocol.clone() else { return Type::Unknown(info) };
498 Type::Endpoint { role, protocol, rights: info.rights, nullable: info.nullable }
499 }
500 TypeKind::Internal => {
501 if info.subtype.as_deref() == Some("framework_error") {
502 Type::FrameworkError
503 } else {
504 Type::Unknown(info)
505 }
506 }
507 TypeKind::Unknown(_) => Type::Unknown(info),
508 }
509 }
510}
511
512impl From<&str> for Type {
513 fn from(name: &str) -> Type {
514 match name.as_ref() {
515 "bool" => Type::Bool,
516 "uint8" => Type::U8,
517 "uint16" => Type::U16,
518 "uint32" => Type::U32,
519 "uint64" => Type::U64,
520 "int8" => Type::I8,
521 "int16" => Type::I16,
522 "int32" => Type::I32,
523 "int64" => Type::I64,
524 "float32" => Type::F32,
525 "float64" => Type::F64,
526 _ => Type::UnknownString(name.to_owned()),
527 }
528 }
529}
530
531impl From<String> for Type {
532 fn from(name: String) -> Type {
533 name.as_str().into()
534 }
535}
536
537pub enum LookupResult<'a> {
538 Bits(&'a Bits),
539 Enum(&'a Enum),
540 Protocol(&'a Protocol),
541 Struct(&'a Struct),
542 Table(&'a TableOrUnion),
543 Union(&'a TableOrUnion),
544}
545
546#[derive(Default)]
548pub struct Namespace {
549 modules: HashMap<String, Module>,
550 methods_by_ordinal: HashMap<u64, (String, Weak<Method>)>,
551}
552
553impl Namespace {
554 pub fn new() -> Self {
556 Namespace { modules: HashMap::new(), methods_by_ordinal: HashMap::new() }
557 }
558
559 pub fn load(&mut self, data: &str) -> Result<()> {
561 let new_mod: Module = serde_json::from_str(data)?;
562
563 for protocol in new_mod.protocol_declarations.values() {
564 for method in protocol.methods.values() {
565 self.methods_by_ordinal
566 .insert(method.ordinal, (protocol.name(), Arc::downgrade(method)));
567 }
568 }
569
570 self.modules.insert(new_mod.name.clone(), new_mod);
571 Ok(())
572 }
573
574 pub fn lookup(&self, name: &str) -> Result<LookupResult<'_>> {
576 let halves: Vec<_> = name.split('/').collect();
577
578 if halves.len() != 2 {
579 return Err(Error::LibraryError(format!(
580 "Wrong number of path components in {}, expected 2",
581 name
582 )));
583 }
584
585 let module: &Module = match self.modules.get(halves[0]) {
586 Some(x) => x,
587 None => return Err(Error::LibraryError(format!("Module {} not found!", halves[0]))),
588 };
589
590 match module.declarations.get(name).map(|x| x.as_ref()) {
591 Some("bits") => match module.bits_declarations.get(name) {
592 Some(x) => Ok(LookupResult::Bits(x)),
593 None => {
594 Err(Error::LibraryError(format!("{} not found in bits declarations!", name)))
595 }
596 },
597 Some("enum") => match module.enum_declarations.get(name) {
598 Some(x) => Ok(LookupResult::Enum(x)),
599 None => {
600 Err(Error::LibraryError(format!("{} not found in enum declarations!", name)))
601 }
602 },
603 Some("protocol") => match module.protocol_declarations.get(name) {
604 Some(x) => Ok(LookupResult::Protocol(x)),
605 None => Err(Error::LibraryError(format!(
606 "{} not found in protocol declarations!",
607 name
608 ))),
609 },
610 Some("struct") => match module.struct_declarations.get(name) {
611 Some(x) => Ok(LookupResult::Struct(x)),
612 None => {
613 Err(Error::LibraryError(format!("{} not found in struct declarations!", name)))
614 }
615 },
616 Some("table") => match module.table_declarations.get(name) {
617 Some(x) => Ok(LookupResult::Table(x)),
618 None => {
619 Err(Error::LibraryError(format!("{} not found in table declarations!", name)))
620 }
621 },
622 Some("union") => match module.union_declarations.get(name) {
623 Some(x) => Ok(LookupResult::Union(x)),
624 None => {
625 Err(Error::LibraryError(format!("{} not found in union declarations!", name)))
626 }
627 },
628 Some(x) => Err(Error::LibraryError(format!("{} has unknown type {}!", name, x))),
629 None => Err(Error::LibraryError(format!("{} not found in {}!", name, module.name))),
630 }
631 }
632
633 pub fn inherits(&self, a: &str, b: &str) -> bool {
635 if a == b {
636 return true;
637 }
638
639 let Ok(LookupResult::Protocol(protocol)) = self.lookup(a) else {
640 return false;
641 };
642
643 for composed_protocol in protocol.composed_protocols.iter() {
644 if self.inherits(composed_protocol, b) {
645 return true;
646 }
647 }
648
649 false
650 }
651
652 pub fn lookup_method_ordinal(&self, ordinal: u64) -> Result<(String, Arc<Method>)> {
654 self.methods_by_ordinal
655 .get(&ordinal)
656 .and_then(|(x, y)| y.upgrade().map(|y| (x.clone(), y)))
657 .ok_or_else(|| Error::LibraryError(format!("No method with ordinal {}", ordinal)))
658 }
659}