1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 use crate::metadata::{checksum_metadata, codes};
6 use crate::*;
7 use anyhow::{bail, ensure, Context, Result};
8
read_metadata(data: &[u8]) -> Result<Metadata>9 pub fn read_metadata(data: &[u8]) -> Result<Metadata> {
10 MetadataReader::new(data).read_metadata()
11 }
12
13 // Read a metadata type, this is pub so that we can test it in the metadata fixture
read_metadata_type(data: &[u8]) -> Result<Type>14 pub fn read_metadata_type(data: &[u8]) -> Result<Type> {
15 MetadataReader::new(data).read_type()
16 }
17
18 /// Helper struct for read_metadata()
19 struct MetadataReader<'a> {
20 // This points to the initial data we were passed in
21 initial_data: &'a [u8],
22 // This points to the remaining data to be read
23 buf: &'a [u8],
24 }
25
26 impl<'a> MetadataReader<'a> {
new(data: &'a [u8]) -> Self27 fn new(data: &'a [u8]) -> Self {
28 Self {
29 initial_data: data,
30 buf: data,
31 }
32 }
33
34 // Read a top-level metadata item
35 //
36 // This consumes self because MetadataReader is only intended to read a single item.
read_metadata(mut self) -> Result<Metadata>37 fn read_metadata(mut self) -> Result<Metadata> {
38 let value = self.read_u8()?;
39 Ok(match value {
40 codes::NAMESPACE => NamespaceMetadata {
41 crate_name: self.read_string()?,
42 name: self.read_string()?,
43 }
44 .into(),
45 codes::UDL_FILE => UdlFile {
46 module_path: self.read_string()?,
47 namespace: self.read_string()?,
48 file_stub: self.read_string()?,
49 }
50 .into(),
51 codes::FUNC => self.read_func()?.into(),
52 codes::CONSTRUCTOR => self.read_constructor()?.into(),
53 codes::METHOD => self.read_method()?.into(),
54 codes::RECORD => self.read_record()?.into(),
55 codes::ENUM => self.read_enum()?.into(),
56 codes::INTERFACE => self.read_object(ObjectImpl::Struct)?.into(),
57 codes::TRAIT_INTERFACE => self.read_object(ObjectImpl::Trait)?.into(),
58 codes::CALLBACK_TRAIT_INTERFACE => self.read_object(ObjectImpl::CallbackTrait)?.into(),
59 codes::CALLBACK_INTERFACE => self.read_callback_interface()?.into(),
60 codes::TRAIT_METHOD => self.read_trait_method()?.into(),
61 codes::UNIFFI_TRAIT => self.read_uniffi_trait()?.into(),
62 _ => bail!("Unexpected metadata code: {value:?}"),
63 })
64 }
65
read_u8(&mut self) -> Result<u8>66 fn read_u8(&mut self) -> Result<u8> {
67 if !self.buf.is_empty() {
68 let value = self.buf[0];
69 self.buf = &self.buf[1..];
70 Ok(value)
71 } else {
72 bail!("Buffer is empty")
73 }
74 }
75
peek_u8(&mut self) -> Result<u8>76 fn peek_u8(&mut self) -> Result<u8> {
77 if !self.buf.is_empty() {
78 Ok(self.buf[0])
79 } else {
80 bail!("Buffer is empty")
81 }
82 }
83
read_u16(&mut self) -> Result<u16>84 fn read_u16(&mut self) -> Result<u16> {
85 if self.buf.len() >= 2 {
86 // read the value as little-endian
87 let value = u16::from_le_bytes([self.buf[0], self.buf[1]]);
88 self.buf = &self.buf[2..];
89 Ok(value)
90 } else {
91 bail!("Not enough data left in buffer to read a u16 value");
92 }
93 }
94
read_u32(&mut self) -> Result<u32>95 fn read_u32(&mut self) -> Result<u32> {
96 if self.buf.len() >= 4 {
97 // read the value as little-endian
98 let value = self.buf[0] as u32
99 + ((self.buf[1] as u32) << 8)
100 + ((self.buf[2] as u32) << 16)
101 + ((self.buf[3] as u32) << 24);
102 self.buf = &self.buf[4..];
103 Ok(value)
104 } else {
105 bail!("Not enough data left in buffer to read a u32 value");
106 }
107 }
108
read_bool(&mut self) -> Result<bool>109 fn read_bool(&mut self) -> Result<bool> {
110 Ok(self.read_u8()? == 1)
111 }
112
read_string(&mut self) -> Result<String>113 fn read_string(&mut self) -> Result<String> {
114 let size = self.read_u8()? as usize;
115 let slice;
116 (slice, self.buf) = self.buf.split_at(size);
117 String::from_utf8(slice.into()).context("Invalid string data")
118 }
119
read_long_string(&mut self) -> Result<String>120 fn read_long_string(&mut self) -> Result<String> {
121 let size = self.read_u16()? as usize;
122 let slice;
123 (slice, self.buf) = self.buf.split_at(size);
124 String::from_utf8(slice.into()).context("Invalid string data")
125 }
126
read_optional_long_string(&mut self) -> Result<Option<String>>127 fn read_optional_long_string(&mut self) -> Result<Option<String>> {
128 Ok(Some(self.read_long_string()?).filter(|str| !str.is_empty()))
129 }
130
read_type(&mut self) -> Result<Type>131 fn read_type(&mut self) -> Result<Type> {
132 let value = self.read_u8()?;
133 Ok(match value {
134 codes::TYPE_U8 => Type::UInt8,
135 codes::TYPE_I8 => Type::Int8,
136 codes::TYPE_U16 => Type::UInt16,
137 codes::TYPE_I16 => Type::Int16,
138 codes::TYPE_U32 => Type::UInt32,
139 codes::TYPE_I32 => Type::Int32,
140 codes::TYPE_U64 => Type::UInt64,
141 codes::TYPE_I64 => Type::Int64,
142 codes::TYPE_F32 => Type::Float32,
143 codes::TYPE_F64 => Type::Float64,
144 codes::TYPE_BOOL => Type::Boolean,
145 codes::TYPE_STRING => Type::String,
146 codes::TYPE_DURATION => Type::Duration,
147 codes::TYPE_SYSTEM_TIME => Type::Timestamp,
148 codes::TYPE_RECORD => Type::Record {
149 module_path: self.read_string()?,
150 name: self.read_string()?,
151 },
152 codes::TYPE_ENUM => Type::Enum {
153 module_path: self.read_string()?,
154 name: self.read_string()?,
155 },
156 codes::TYPE_INTERFACE => Type::Object {
157 module_path: self.read_string()?,
158 name: self.read_string()?,
159 imp: ObjectImpl::Struct,
160 },
161 codes::TYPE_TRAIT_INTERFACE => Type::Object {
162 module_path: self.read_string()?,
163 name: self.read_string()?,
164 imp: ObjectImpl::Trait,
165 },
166 codes::TYPE_CALLBACK_TRAIT_INTERFACE => Type::Object {
167 module_path: self.read_string()?,
168 name: self.read_string()?,
169 imp: ObjectImpl::CallbackTrait,
170 },
171 codes::TYPE_CALLBACK_INTERFACE => Type::CallbackInterface {
172 module_path: self.read_string()?,
173 name: self.read_string()?,
174 },
175 codes::TYPE_CUSTOM => Type::Custom {
176 module_path: self.read_string()?,
177 name: self.read_string()?,
178 builtin: Box::new(self.read_type()?),
179 },
180 codes::TYPE_OPTION => Type::Optional {
181 inner_type: Box::new(self.read_type()?),
182 },
183 codes::TYPE_VEC => {
184 let inner_type = self.read_type()?;
185 if inner_type == Type::UInt8 {
186 Type::Bytes
187 } else {
188 Type::Sequence {
189 inner_type: Box::new(inner_type),
190 }
191 }
192 }
193 codes::TYPE_HASH_MAP => Type::Map {
194 key_type: Box::new(self.read_type()?),
195 value_type: Box::new(self.read_type()?),
196 },
197 codes::TYPE_UNIT => bail!("Unexpected TYPE_UNIT"),
198 codes::TYPE_RESULT => bail!("Unexpected TYPE_RESULT"),
199 _ => bail!("Unexpected metadata type code: {value:?}"),
200 })
201 }
202
read_optional_type(&mut self) -> Result<Option<Type>>203 fn read_optional_type(&mut self) -> Result<Option<Type>> {
204 Ok(match self.peek_u8()? {
205 codes::TYPE_UNIT => {
206 _ = self.read_u8();
207 None
208 }
209 _ => Some(self.read_type()?),
210 })
211 }
212
read_return_type(&mut self) -> Result<(Option<Type>, Option<Type>)>213 fn read_return_type(&mut self) -> Result<(Option<Type>, Option<Type>)> {
214 Ok(match self.peek_u8()? {
215 codes::TYPE_UNIT => {
216 _ = self.read_u8();
217 (None, None)
218 }
219 codes::TYPE_RESULT => {
220 _ = self.read_u8();
221 (self.read_optional_type()?, self.read_optional_type()?)
222 }
223 _ => (Some(self.read_type()?), None),
224 })
225 }
226
read_func(&mut self) -> Result<FnMetadata>227 fn read_func(&mut self) -> Result<FnMetadata> {
228 let module_path = self.read_string()?;
229 let name = self.read_string()?;
230 let is_async = self.read_bool()?;
231 let inputs = self.read_inputs()?;
232 let (return_type, throws) = self.read_return_type()?;
233 let docstring = self.read_optional_long_string()?;
234 Ok(FnMetadata {
235 module_path,
236 name,
237 is_async,
238 inputs,
239 return_type,
240 throws,
241 docstring,
242 checksum: self.calc_checksum(),
243 })
244 }
245
read_constructor(&mut self) -> Result<ConstructorMetadata>246 fn read_constructor(&mut self) -> Result<ConstructorMetadata> {
247 let module_path = self.read_string()?;
248 let self_name = self.read_string()?;
249 let name = self.read_string()?;
250 let is_async = self.read_bool()?;
251 let inputs = self.read_inputs()?;
252 let (return_type, throws) = self.read_return_type()?;
253 let docstring = self.read_optional_long_string()?;
254
255 return_type
256 .filter(|t| {
257 matches!(
258 t,
259 Type::Object { name, imp: ObjectImpl::Struct, .. } if name == &self_name
260 )
261 })
262 .context("Constructor return type must be Arc<Self>")?;
263
264 Ok(ConstructorMetadata {
265 module_path,
266 self_name,
267 is_async,
268 name,
269 inputs,
270 throws,
271 checksum: self.calc_checksum(),
272 docstring,
273 })
274 }
275
read_method(&mut self) -> Result<MethodMetadata>276 fn read_method(&mut self) -> Result<MethodMetadata> {
277 let module_path = self.read_string()?;
278 let self_name = self.read_string()?;
279 let name = self.read_string()?;
280 let is_async = self.read_bool()?;
281 let inputs = self.read_inputs()?;
282 let (return_type, throws) = self.read_return_type()?;
283 let docstring = self.read_optional_long_string()?;
284 Ok(MethodMetadata {
285 module_path,
286 self_name,
287 name,
288 is_async,
289 inputs,
290 return_type,
291 throws,
292 takes_self_by_arc: false, // not emitted by macros
293 checksum: self.calc_checksum(),
294 docstring,
295 })
296 }
297
read_record(&mut self) -> Result<RecordMetadata>298 fn read_record(&mut self) -> Result<RecordMetadata> {
299 Ok(RecordMetadata {
300 module_path: self.read_string()?,
301 name: self.read_string()?,
302 fields: self.read_fields()?,
303 docstring: self.read_optional_long_string()?,
304 })
305 }
306
read_enum(&mut self) -> Result<EnumMetadata>307 fn read_enum(&mut self) -> Result<EnumMetadata> {
308 let module_path = self.read_string()?;
309 let name = self.read_string()?;
310 let forced_flatness = match self.read_u8()? {
311 0 => None,
312 1 => Some(false),
313 2 => Some(true),
314 _ => unreachable!("invalid flatness"),
315 };
316 let discr_type = if self.read_bool()? {
317 Some(self.read_type()?)
318 } else {
319 None
320 };
321 let variants = if forced_flatness == Some(true) {
322 self.read_flat_variants()?
323 } else {
324 self.read_variants()?
325 };
326
327 Ok(EnumMetadata {
328 module_path,
329 name,
330 forced_flatness,
331 discr_type,
332 variants,
333 non_exhaustive: self.read_bool()?,
334 docstring: self.read_optional_long_string()?,
335 })
336 }
337
read_object(&mut self, imp: ObjectImpl) -> Result<ObjectMetadata>338 fn read_object(&mut self, imp: ObjectImpl) -> Result<ObjectMetadata> {
339 Ok(ObjectMetadata {
340 module_path: self.read_string()?,
341 name: self.read_string()?,
342 imp,
343 docstring: self.read_optional_long_string()?,
344 })
345 }
346
read_uniffi_trait(&mut self) -> Result<UniffiTraitMetadata>347 fn read_uniffi_trait(&mut self) -> Result<UniffiTraitMetadata> {
348 let code = self.read_u8()?;
349 let mut read_metadata_method = || -> Result<MethodMetadata> {
350 let code = self.read_u8()?;
351 ensure!(code == codes::METHOD, "expected METHOD but read {code}");
352 self.read_method()
353 };
354
355 Ok(match UniffiTraitDiscriminants::from(code)? {
356 UniffiTraitDiscriminants::Debug => UniffiTraitMetadata::Debug {
357 fmt: read_metadata_method()?,
358 },
359 UniffiTraitDiscriminants::Display => UniffiTraitMetadata::Display {
360 fmt: read_metadata_method()?,
361 },
362 UniffiTraitDiscriminants::Eq => UniffiTraitMetadata::Eq {
363 eq: read_metadata_method()?,
364 ne: read_metadata_method()?,
365 },
366 UniffiTraitDiscriminants::Hash => UniffiTraitMetadata::Hash {
367 hash: read_metadata_method()?,
368 },
369 })
370 }
371
read_callback_interface(&mut self) -> Result<CallbackInterfaceMetadata>372 fn read_callback_interface(&mut self) -> Result<CallbackInterfaceMetadata> {
373 Ok(CallbackInterfaceMetadata {
374 module_path: self.read_string()?,
375 name: self.read_string()?,
376 docstring: self.read_optional_long_string()?,
377 })
378 }
379
read_trait_method(&mut self) -> Result<TraitMethodMetadata>380 fn read_trait_method(&mut self) -> Result<TraitMethodMetadata> {
381 let module_path = self.read_string()?;
382 let trait_name = self.read_string()?;
383 let index = self.read_u32()?;
384 let name = self.read_string()?;
385 let is_async = self.read_bool()?;
386 let inputs = self.read_inputs()?;
387 let (return_type, throws) = self.read_return_type()?;
388 let docstring = self.read_optional_long_string()?;
389 Ok(TraitMethodMetadata {
390 module_path,
391 trait_name,
392 index,
393 name,
394 is_async,
395 inputs,
396 return_type,
397 throws,
398 takes_self_by_arc: false, // not emitted by macros
399 checksum: self.calc_checksum(),
400 docstring,
401 })
402 }
403
read_fields(&mut self) -> Result<Vec<FieldMetadata>>404 fn read_fields(&mut self) -> Result<Vec<FieldMetadata>> {
405 let len = self.read_u8()?;
406 (0..len)
407 .map(|_| {
408 let name = self.read_string()?;
409 let ty = self.read_type()?;
410 let default = self.read_optional_default(&name, &ty)?;
411 Ok(FieldMetadata {
412 name,
413 ty,
414 default,
415 docstring: self.read_optional_long_string()?,
416 })
417 })
418 .collect()
419 }
420
read_variants(&mut self) -> Result<Vec<VariantMetadata>>421 fn read_variants(&mut self) -> Result<Vec<VariantMetadata>> {
422 let len = self.read_u8()?;
423 (0..len)
424 .map(|_| {
425 Ok(VariantMetadata {
426 name: self.read_string()?,
427 discr: self.read_optional_default("<variant-value>", &Type::UInt64)?,
428 fields: self.read_fields()?,
429 docstring: self.read_optional_long_string()?,
430 })
431 })
432 .collect()
433 }
434
read_flat_variants(&mut self) -> Result<Vec<VariantMetadata>>435 fn read_flat_variants(&mut self) -> Result<Vec<VariantMetadata>> {
436 let len = self.read_u8()?;
437 (0..len)
438 .map(|_| {
439 Ok(VariantMetadata {
440 name: self.read_string()?,
441 discr: None,
442 fields: vec![],
443 docstring: self.read_optional_long_string()?,
444 })
445 })
446 .collect()
447 }
448
read_inputs(&mut self) -> Result<Vec<FnParamMetadata>>449 fn read_inputs(&mut self) -> Result<Vec<FnParamMetadata>> {
450 let len = self.read_u8()?;
451 (0..len)
452 .map(|_| {
453 let name = self.read_string()?;
454 let ty = self.read_type()?;
455 let default = self.read_optional_default(&name, &ty)?;
456 Ok(FnParamMetadata {
457 name,
458 ty,
459 default,
460 // not emitted by macros
461 by_ref: false,
462 optional: false,
463 })
464 })
465 .collect()
466 }
467
calc_checksum(&self) -> Option<u16>468 fn calc_checksum(&self) -> Option<u16> {
469 let bytes_read = self.initial_data.len() - self.buf.len();
470 let metadata_buf = &self.initial_data[..bytes_read];
471 Some(checksum_metadata(metadata_buf))
472 }
473
read_optional_default(&mut self, name: &str, ty: &Type) -> Result<Option<LiteralMetadata>>474 fn read_optional_default(&mut self, name: &str, ty: &Type) -> Result<Option<LiteralMetadata>> {
475 if self.read_bool()? {
476 Ok(Some(self.read_default(name, ty)?))
477 } else {
478 Ok(None)
479 }
480 }
481
read_default(&mut self, name: &str, ty: &Type) -> Result<LiteralMetadata>482 fn read_default(&mut self, name: &str, ty: &Type) -> Result<LiteralMetadata> {
483 let literal_kind = self.read_u8()?;
484
485 Ok(match literal_kind {
486 codes::LIT_STR => {
487 ensure!(
488 matches!(ty, Type::String),
489 "field {name} of type {ty:?} can't have a default value of type string"
490 );
491 LiteralMetadata::String(self.read_string()?)
492 }
493 codes::LIT_INT => {
494 let base10_digits = self.read_string()?;
495 // procmacros emit the type for discriminant values based purely on whether the constant
496 // is positive or negative.
497 let ty = if !base10_digits.is_empty()
498 && base10_digits.as_bytes()[0] == b'-'
499 && ty == &Type::UInt64
500 {
501 &Type::Int64
502 } else {
503 ty
504 };
505 macro_rules! parse_int {
506 ($ty:ident, $variant:ident) => {
507 LiteralMetadata::$variant(
508 base10_digits
509 .parse::<$ty>()
510 .with_context(|| {
511 format!("parsing default for field {name}: {base10_digits}")
512 })?
513 .into(),
514 Radix::Decimal,
515 ty.to_owned(),
516 )
517 };
518 }
519
520 match ty {
521 Type::UInt8 => parse_int!(u8, UInt),
522 Type::Int8 => parse_int!(i8, Int),
523 Type::UInt16 => parse_int!(u16, UInt),
524 Type::Int16 => parse_int!(i16, Int),
525 Type::UInt32 => parse_int!(u32, UInt),
526 Type::Int32 => parse_int!(i32, Int),
527 Type::UInt64 => parse_int!(u64, UInt),
528 Type::Int64 => parse_int!(i64, Int),
529 _ => {
530 bail!("field {name} of type {ty:?} can't have a default value of type integer");
531 }
532 }
533 }
534 codes::LIT_FLOAT => match ty {
535 Type::Float32 | Type::Float64 => {
536 LiteralMetadata::Float(self.read_string()?, ty.to_owned())
537 }
538 _ => {
539 bail!("field {name} of type {ty:?} can't have a default value of type float");
540 }
541 },
542 codes::LIT_BOOL => LiteralMetadata::Boolean(self.read_bool()?),
543 codes::LIT_NONE => match ty {
544 Type::Optional { .. } => LiteralMetadata::None,
545 _ => bail!("field {name} of type {ty:?} can't have a default value of None"),
546 },
547 codes::LIT_SOME => match ty {
548 Type::Optional { inner_type, .. } => LiteralMetadata::Some {
549 inner: Box::new(self.read_default(name, inner_type)?),
550 },
551 _ => bail!("field {name} of type {ty:?} can't have a default value of None"),
552 },
553 codes::LIT_EMPTY_SEQ => LiteralMetadata::EmptySequence,
554 _ => bail!("Unexpected literal kind code: {literal_kind:?}"),
555 })
556 }
557 }
558