Upgrade uniffi_meta to 0.27.1 am: f09579be27

Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/uniffi_meta/+/3075925

Change-Id: I3b6becf6262ef229231c0ae980452698a8e73149
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 1c28374..c684c40 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "d5332be35ef497255f7ce49debfd917f6a1009c7"
+    "sha1": "0ecafdc06799205caf1432b93787a9c1f810a168"
   },
   "path_in_vcs": "uniffi_meta"
 }
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
deleted file mode 100644
index 32c931a..0000000
--- a/Cargo.lock
+++ /dev/null
@@ -1,76 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "anyhow"
-version = "1.0.81"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
-
-[[package]]
-name = "bytes"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.79"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "siphasher"
-version = "0.3.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
-
-[[package]]
-name = "syn"
-version = "2.0.53"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "unicode-ident"
-version = "1.0.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
-
-[[package]]
-name = "uniffi_checksum_derive"
-version = "0.26.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72775b3afa6adb30e0c92b3107858d2fcb0ff1a417ac242db1f648b0e2dd0ef2"
-dependencies = [
- "quote",
- "syn",
-]
-
-[[package]]
-name = "uniffi_meta"
-version = "0.26.1"
-dependencies = [
- "anyhow",
- "bytes",
- "siphasher",
- "uniffi_checksum_derive",
-]
diff --git a/Cargo.toml b/Cargo.toml
index 4816c8e..04d8170 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,7 +12,7 @@
 [package]
 edition = "2021"
 name = "uniffi_meta"
-version = "0.26.1"
+version = "0.27.1"
 description = "uniffi_meta"
 homepage = "https://mozilla.github.io/uniffi-rs"
 readme = "README.md"
@@ -33,4 +33,4 @@
 version = "0.3"
 
 [dependencies.uniffi_checksum_derive]
-version = "0.26.1"
+version = "0.27.1"
diff --git a/METADATA b/METADATA
index d2b56a1..efbf491 100644
--- a/METADATA
+++ b/METADATA
@@ -7,14 +7,14 @@
   }
   identifier {
     type: "Archive"
-    value: "https://static.crates.io/crates/uniffi_meta/uniffi_meta-0.26.1.crate"
+    value: "https://static.crates.io/crates/uniffi_meta/uniffi_meta-0.27.1.crate"
     primary_source: true
   }
-  version: "0.26.1"
+  version: "0.27.1"
   license_type: RECIPROCAL
   last_upgrade_date {
     year: 2024
-    month: 3
-    day: 21
+    month: 5
+    day: 6
   }
 }
diff --git a/README.md b/README.md
index bb72360..64ac348 100644
--- a/README.md
+++ b/README.md
@@ -14,12 +14,12 @@
 You can describe your object model in an [interface definition file](https://mozilla.github.io/uniffi-rs/udl_file_spec.html)
 or [by using proc-macros](https://mozilla.github.io/uniffi-rs/proc_macro/index.html).
 
-UniFFI is currently extensively by Mozilla in Firefox mobile and desktop browsers;
+UniFFI is currently used extensively by Mozilla in Firefox mobile and desktop browsers;
 written once in Rust, auto-generated bindings allow that functionality to be called
 from both Kotlin (for Android apps) and Swift (for iOS apps).
 It also has a growing community of users shipping various cool things to many users.
 
-UniFII comes with support for **Kotlin**, **Swift**, **Python** and **Ruby** with 3rd party bindings available for **C#** and **Golang**.
+UniFFI comes with support for **Kotlin**, **Swift**, **Python** and **Ruby** with 3rd party bindings available for **C#** and **Golang**.
 Additional foreign language bindings can be developed externally and we welcome contributions to list them here.
 See [Third-party foreign language bindings](#third-party-foreign-language-bindings).
 
@@ -62,6 +62,8 @@
 
 * [Plugin support for `.udl` files](https://github.com/Lonami/uniffi-dl) for the IDEA platform ([*uniffi-dl* in the JetBrains marketplace](https://plugins.jetbrains.com/plugin/20527-uniffi-dl)). It provides syntax highlighting, code folding, code completion, reference resolution and navigation (among others features) for the [UniFFI Definition Language (UDL)](https://mozilla.github.io/uniffi-rs/).
 * [cargo swift](https://github.com/antoniusnaumann/cargo-swift), a cargo plugin to build a Swift Package from Rust code. It provides an init command for setting up a UniFFI crate and a package command for building a Swift package from Rust code - without the need for additional configuration or build scripts.
+* [Cargo NDK Gradle Plugin](https://github.com/willir/cargo-ndk-android-gradle) allows you to build Rust code using [`cargo-ndk`](https://github.com/bbqsrc/cargo-ndk), which generally makes Android library builds less painful.
+* [`uniffi-starter`](https://github.com/ianthetechie/uniffi-starter) is a minimal project demonstrates a wide range of UniFFI in a complete project in a compact manner. It includes a full Android library build process, an XCFramework generation script, and example Swift package structure. 
 
 (Please open a PR if you think other resources should be listed!)
 
diff --git a/src/ffi_names.rs b/src/ffi_names.rs
index a58977b..5c931a0 100644
--- a/src/ffi_names.rs
+++ b/src/ffi_names.rs
@@ -46,9 +46,12 @@
 }
 
 /// FFI symbol name for the `init_callback` function for a callback interface
-pub fn init_callback_fn_symbol_name(namespace: &str, callback_interface_name: &str) -> String {
+pub fn init_callback_vtable_fn_symbol_name(
+    namespace: &str,
+    callback_interface_name: &str,
+) -> String {
     let callback_interface_name = callback_interface_name.to_ascii_lowercase();
-    format!("uniffi_{namespace}_fn_init_callback_{callback_interface_name}")
+    format!("uniffi_{namespace}_fn_init_callback_vtable_{callback_interface_name}")
 }
 
 /// FFI checksum symbol name for a top-level function
diff --git a/src/lib.rs b/src/lib.rs
index eb4cdca..90f7b2d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -23,7 +23,7 @@
 // `docs/uniffi-versioning.md` for details.
 //
 // Once we get to 1.0, then we'll need to update the scheme to something like 100 + major_version
-pub const UNIFFI_CONTRACT_VERSION: u32 = 25;
+pub const UNIFFI_CONTRACT_VERSION: u32 = 26;
 
 /// Similar to std::hash::Hash.
 ///
@@ -161,6 +161,7 @@
     pub module_path: String,
     pub self_name: String,
     pub name: String,
+    pub is_async: bool,
     pub inputs: Vec<FnParamMetadata>,
     pub throws: Option<Type>,
     pub checksum: Option<u16>,
@@ -270,13 +271,17 @@
     Enum(String, Type),
     EmptySequence,
     EmptyMap,
-    Null,
+    None,
+    Some { inner: Box<LiteralMetadata> },
 }
 
 impl LiteralMetadata {
     pub fn new_uint(v: u64) -> Self {
         LiteralMetadata::UInt(v, Radix::Decimal, Type::UInt64)
     }
+    pub fn new_int(v: i64) -> Self {
+        LiteralMetadata::Int(v, Radix::Decimal, Type::Int64)
+    }
 }
 
 // Represent the radix of integer literal values.
diff --git a/src/metadata.rs b/src/metadata.rs
index 66c2c63..9cfb77a 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -59,7 +59,9 @@
     pub const LIT_INT: u8 = 1;
     pub const LIT_FLOAT: u8 = 2;
     pub const LIT_BOOL: u8 = 3;
-    pub const LIT_NULL: u8 = 4;
+    pub const LIT_NONE: u8 = 4;
+    pub const LIT_SOME: u8 = 5;
+    pub const LIT_EMPTY_SEQ: u8 = 6;
 }
 
 // Create a checksum for a MetadataBuffer
diff --git a/src/reader.rs b/src/reader.rs
index 5a09d9d..6fec6cb 100644
--- a/src/reader.rs
+++ b/src/reader.rs
@@ -247,6 +247,7 @@
         let module_path = self.read_string()?;
         let self_name = self.read_string()?;
         let name = self.read_string()?;
+        let is_async = self.read_bool()?;
         let inputs = self.read_inputs()?;
         let (return_type, throws) = self.read_return_type()?;
         let docstring = self.read_optional_long_string()?;
@@ -263,6 +264,7 @@
         Ok(ConstructorMetadata {
             module_path,
             self_name,
+            is_async,
             name,
             inputs,
             throws,
@@ -405,7 +407,7 @@
             .map(|_| {
                 let name = self.read_string()?;
                 let ty = self.read_type()?;
-                let default = self.read_default(&name, &ty)?;
+                let default = self.read_optional_default(&name, &ty)?;
                 Ok(FieldMetadata {
                     name,
                     ty,
@@ -422,7 +424,7 @@
             .map(|_| {
                 Ok(VariantMetadata {
                     name: self.read_string()?,
-                    discr: self.read_default("<variant-value>", &Type::UInt64)?,
+                    discr: self.read_optional_default("<variant-value>", &Type::UInt64)?,
                     fields: self.read_fields()?,
                     docstring: self.read_optional_long_string()?,
                 })
@@ -448,13 +450,16 @@
         let len = self.read_u8()?;
         (0..len)
             .map(|_| {
+                let name = self.read_string()?;
+                let ty = self.read_type()?;
+                let default = self.read_optional_default(&name, &ty)?;
                 Ok(FnParamMetadata {
-                    name: self.read_string()?,
-                    ty: self.read_type()?,
+                    name,
+                    ty,
+                    default,
                     // not emitted by macros
                     by_ref: false,
                     optional: false,
-                    default: None,
                 })
             })
             .collect()
@@ -466,14 +471,18 @@
         Some(checksum_metadata(metadata_buf))
     }
 
-    fn read_default(&mut self, name: &str, ty: &Type) -> Result<Option<LiteralMetadata>> {
-        let has_default = self.read_bool()?;
-        if !has_default {
-            return Ok(None);
+    fn read_optional_default(&mut self, name: &str, ty: &Type) -> Result<Option<LiteralMetadata>> {
+        if self.read_bool()? {
+            Ok(Some(self.read_default(name, ty)?))
+        } else {
+            Ok(None)
         }
+    }
 
+    fn read_default(&mut self, name: &str, ty: &Type) -> Result<LiteralMetadata> {
         let literal_kind = self.read_u8()?;
-        Ok(Some(match literal_kind {
+
+        Ok(match literal_kind {
             codes::LIT_STR => {
                 ensure!(
                     matches!(ty, Type::String),
@@ -483,12 +492,24 @@
             }
             codes::LIT_INT => {
                 let base10_digits = self.read_string()?;
+                // procmacros emit the type for discriminant values based purely on whether the constant
+                // is positive or negative.
+                let ty = if !base10_digits.is_empty()
+                    && base10_digits.as_bytes()[0] == b'-'
+                    && ty == &Type::UInt64
+                {
+                    &Type::Int64
+                } else {
+                    ty
+                };
                 macro_rules! parse_int {
                     ($ty:ident, $variant:ident) => {
                         LiteralMetadata::$variant(
                             base10_digits
                                 .parse::<$ty>()
-                                .with_context(|| format!("parsing default for field {name}"))?
+                                .with_context(|| {
+                                    format!("parsing default for field {name}: {base10_digits}")
+                                })?
                                 .into(),
                             Radix::Decimal,
                             ty.to_owned(),
@@ -519,8 +540,18 @@
                 }
             },
             codes::LIT_BOOL => LiteralMetadata::Boolean(self.read_bool()?),
-            codes::LIT_NULL => LiteralMetadata::Null,
+            codes::LIT_NONE => match ty {
+                Type::Optional { .. } => LiteralMetadata::None,
+                _ => bail!("field {name} of type {ty:?} can't have a default value of None"),
+            },
+            codes::LIT_SOME => match ty {
+                Type::Optional { inner_type, .. } => LiteralMetadata::Some {
+                    inner: Box::new(self.read_default(name, inner_type)?),
+                },
+                _ => bail!("field {name} of type {ty:?} can't have a default value of None"),
+            },
+            codes::LIT_EMPTY_SEQ => LiteralMetadata::EmptySequence,
             _ => bail!("Unexpected literal kind code: {literal_kind:?}"),
-        }))
+        })
     }
 }