Skip to main content

fidl_fuchsia_process_lifecycle/
fidl_fuchsia_process_lifecycle.rs

1// WARNING: This file is machine generated by fidlgen.
2
3#![warn(clippy::all)]
4#![allow(unused_parens, unused_mut, unused_imports, nonstandard_style)]
5
6use bitflags::bitflags;
7use fidl::client::QueryResponseFut;
8use fidl::encoding::{MessageBufFor, ProxyChannelBox, ResourceDialect};
9use fidl::endpoints::{ControlHandle as _, Responder as _};
10pub use fidl_fuchsia_process_lifecycle_common::*;
11use futures::future::{self, MaybeDone, TryFutureExt};
12use zx_status;
13
14#[derive(Debug, Default, PartialEq)]
15pub struct LifecycleOnEscrowRequest {
16    /// Escrow the outgoing directory server endpoint. Whenever the
17    /// component is started again, this will be returned as the
18    /// `PA_DIRECTORY_REQUEST` processargs entry.
19    pub outgoing_dir: Option<fidl::endpoints::ServerEnd<fidl_fuchsia_io::DirectoryMarker>>,
20    /// Escrow some user defined state. Whenever the component is started
21    /// again, this will be returned as the `PA_ESCROWED_DICTIONARY`
22    /// processargs entry.
23    ///
24    /// The framework will not wait for any signals on these objects.
25    ///
26    /// ## Example
27    ///
28    /// Let's say a component needs to escrow an event pair that represents
29    /// the result of some expensive calculation. It can create a
30    /// dictionary, put the event pair inside with an appropriate key
31    /// (e.g. `"my_event_pair"`), then check for that entry on startup.
32    /// Note that this is deprecated, please use
33    /// `escrowed_dictionary_handle` instead.
34    pub escrowed_dictionary: Option<fidl_fuchsia_component_sandbox::DictionaryRef>,
35    /// Escrow some user defined state. Whenever the component is started
36    /// again, this will be returned as the `PA_ESCROWED_DICTIONARY`
37    /// processargs entry.
38    ///
39    /// The framework will not wait for any signals on these objects.
40    ///
41    /// ## Example
42    ///
43    /// Let's say a component needs to escrow an event pair that represents
44    /// the result of some expensive calculation. It can create a
45    /// dictionary, put the event pair inside with an appropriate key
46    /// (e.g. `"my_event_pair"`), then check for that entry on startup.
47    pub escrowed_dictionary_handle: Option<fidl::EventPair>,
48    /// Recoverable bytes when this component stops running. Used to track
49    /// how much memory is saved when a component is escrowed, which is only
50    /// used for development purposes.
51    pub recoverable_bytes: Option<u64>,
52    #[doc(hidden)]
53    pub __source_breaking: fidl::marker::SourceBreaking,
54}
55
56impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect> for LifecycleOnEscrowRequest {}
57
58#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
59pub struct LifecycleMarker;
60
61impl fidl::endpoints::ProtocolMarker for LifecycleMarker {
62    type Proxy = LifecycleProxy;
63    type RequestStream = LifecycleRequestStream;
64    #[cfg(target_os = "fuchsia")]
65    type SynchronousProxy = LifecycleSynchronousProxy;
66
67    const DEBUG_NAME: &'static str = "(anonymous) Lifecycle";
68}
69
70pub trait LifecycleProxyInterface: Send + Sync {
71    fn r#stop(&self) -> Result<(), fidl::Error>;
72}
73#[derive(Debug)]
74#[cfg(target_os = "fuchsia")]
75pub struct LifecycleSynchronousProxy {
76    client: fidl::client::sync::Client,
77}
78
79#[cfg(target_os = "fuchsia")]
80impl fidl::endpoints::SynchronousProxy for LifecycleSynchronousProxy {
81    type Proxy = LifecycleProxy;
82    type Protocol = LifecycleMarker;
83
84    fn from_channel(inner: fidl::Channel) -> Self {
85        Self::new(inner)
86    }
87
88    fn into_channel(self) -> fidl::Channel {
89        self.client.into_channel()
90    }
91
92    fn as_channel(&self) -> &fidl::Channel {
93        self.client.as_channel()
94    }
95}
96
97#[cfg(target_os = "fuchsia")]
98impl LifecycleSynchronousProxy {
99    pub fn new(channel: fidl::Channel) -> Self {
100        Self { client: fidl::client::sync::Client::new(channel) }
101    }
102
103    pub fn into_channel(self) -> fidl::Channel {
104        self.client.into_channel()
105    }
106
107    /// Waits until an event arrives and returns it. It is safe for other
108    /// threads to make concurrent requests while waiting for an event.
109    pub fn wait_for_event(
110        &self,
111        deadline: zx::MonotonicInstant,
112    ) -> Result<LifecycleEvent, fidl::Error> {
113        LifecycleEvent::decode(self.client.wait_for_event::<LifecycleMarker>(deadline)?)
114    }
115
116    /// The process must clean up its state in preparation for termination, and
117    /// must close the channel hosting the `Lifecycle` protocol when it is
118    /// ready to be terminated. The process should exit after it completes its
119    /// cleanup. At the discretion of the system the process may be terminated
120    /// before it closes the `Lifecycle` channel.
121    pub fn r#stop(&self) -> Result<(), fidl::Error> {
122        self.client.send::<fidl::encoding::EmptyPayload>(
123            (),
124            0x64b176f1744c6f15,
125            fidl::encoding::DynamicFlags::empty(),
126        )
127    }
128}
129
130#[cfg(target_os = "fuchsia")]
131impl From<LifecycleSynchronousProxy> for zx::NullableHandle {
132    fn from(value: LifecycleSynchronousProxy) -> Self {
133        value.into_channel().into()
134    }
135}
136
137#[cfg(target_os = "fuchsia")]
138impl From<fidl::Channel> for LifecycleSynchronousProxy {
139    fn from(value: fidl::Channel) -> Self {
140        Self::new(value)
141    }
142}
143
144#[cfg(target_os = "fuchsia")]
145impl fidl::endpoints::FromClient for LifecycleSynchronousProxy {
146    type Protocol = LifecycleMarker;
147
148    fn from_client(value: fidl::endpoints::ClientEnd<LifecycleMarker>) -> Self {
149        Self::new(value.into_channel())
150    }
151}
152
153#[derive(Debug, Clone)]
154pub struct LifecycleProxy {
155    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
156}
157
158impl fidl::endpoints::Proxy for LifecycleProxy {
159    type Protocol = LifecycleMarker;
160
161    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
162        Self::new(inner)
163    }
164
165    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
166        self.client.into_channel().map_err(|client| Self { client })
167    }
168
169    fn as_channel(&self) -> &::fidl::AsyncChannel {
170        self.client.as_channel()
171    }
172}
173
174impl LifecycleProxy {
175    /// Create a new Proxy for fuchsia.process.lifecycle/Lifecycle.
176    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
177        let protocol_name = <LifecycleMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
178        Self { client: fidl::client::Client::new(channel, protocol_name) }
179    }
180
181    /// Get a Stream of events from the remote end of the protocol.
182    ///
183    /// # Panics
184    ///
185    /// Panics if the event stream was already taken.
186    pub fn take_event_stream(&self) -> LifecycleEventStream {
187        LifecycleEventStream { event_receiver: self.client.take_event_receiver() }
188    }
189
190    /// The process must clean up its state in preparation for termination, and
191    /// must close the channel hosting the `Lifecycle` protocol when it is
192    /// ready to be terminated. The process should exit after it completes its
193    /// cleanup. At the discretion of the system the process may be terminated
194    /// before it closes the `Lifecycle` channel.
195    pub fn r#stop(&self) -> Result<(), fidl::Error> {
196        LifecycleProxyInterface::r#stop(self)
197    }
198}
199
200impl LifecycleProxyInterface for LifecycleProxy {
201    fn r#stop(&self) -> Result<(), fidl::Error> {
202        self.client.send::<fidl::encoding::EmptyPayload>(
203            (),
204            0x64b176f1744c6f15,
205            fidl::encoding::DynamicFlags::empty(),
206        )
207    }
208}
209
210pub struct LifecycleEventStream {
211    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
212}
213
214impl std::marker::Unpin for LifecycleEventStream {}
215
216impl futures::stream::FusedStream for LifecycleEventStream {
217    fn is_terminated(&self) -> bool {
218        self.event_receiver.is_terminated()
219    }
220}
221
222impl futures::Stream for LifecycleEventStream {
223    type Item = Result<LifecycleEvent, fidl::Error>;
224
225    fn poll_next(
226        mut self: std::pin::Pin<&mut Self>,
227        cx: &mut std::task::Context<'_>,
228    ) -> std::task::Poll<Option<Self::Item>> {
229        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
230            &mut self.event_receiver,
231            cx
232        )?) {
233            Some(buf) => std::task::Poll::Ready(Some(LifecycleEvent::decode(buf))),
234            None => std::task::Poll::Ready(None),
235        }
236    }
237}
238
239#[derive(Debug)]
240pub enum LifecycleEvent {
241    OnEscrow { payload: LifecycleOnEscrowRequest },
242}
243
244impl LifecycleEvent {
245    #[allow(irrefutable_let_patterns)]
246    pub fn into_on_escrow(self) -> Option<LifecycleOnEscrowRequest> {
247        if let LifecycleEvent::OnEscrow { payload } = self { Some((payload)) } else { None }
248    }
249
250    /// Decodes a message buffer as a [`LifecycleEvent`].
251    fn decode(
252        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
253    ) -> Result<LifecycleEvent, fidl::Error> {
254        let (bytes, _handles) = buf.split_mut();
255        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
256        debug_assert_eq!(tx_header.tx_id, 0);
257        match tx_header.ordinal {
258            0x3de9c2fcb734ed48 => {
259                let mut out = fidl::new_empty!(
260                    LifecycleOnEscrowRequest,
261                    fidl::encoding::DefaultFuchsiaResourceDialect
262                );
263                fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<LifecycleOnEscrowRequest>(&tx_header, _body_bytes, _handles, &mut out)?;
264                Ok((LifecycleEvent::OnEscrow { payload: out }))
265            }
266            _ => Err(fidl::Error::UnknownOrdinal {
267                ordinal: tx_header.ordinal,
268                protocol_name: <LifecycleMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
269            }),
270        }
271    }
272}
273
274/// A Stream of incoming requests for fuchsia.process.lifecycle/Lifecycle.
275pub struct LifecycleRequestStream {
276    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
277    is_terminated: bool,
278}
279
280impl std::marker::Unpin for LifecycleRequestStream {}
281
282impl futures::stream::FusedStream for LifecycleRequestStream {
283    fn is_terminated(&self) -> bool {
284        self.is_terminated
285    }
286}
287
288impl fidl::endpoints::RequestStream for LifecycleRequestStream {
289    type Protocol = LifecycleMarker;
290    type ControlHandle = LifecycleControlHandle;
291
292    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
293        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
294    }
295
296    fn control_handle(&self) -> Self::ControlHandle {
297        LifecycleControlHandle { inner: self.inner.clone() }
298    }
299
300    fn into_inner(
301        self,
302    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
303    {
304        (self.inner, self.is_terminated)
305    }
306
307    fn from_inner(
308        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
309        is_terminated: bool,
310    ) -> Self {
311        Self { inner, is_terminated }
312    }
313}
314
315impl futures::Stream for LifecycleRequestStream {
316    type Item = Result<LifecycleRequest, fidl::Error>;
317
318    fn poll_next(
319        mut self: std::pin::Pin<&mut Self>,
320        cx: &mut std::task::Context<'_>,
321    ) -> std::task::Poll<Option<Self::Item>> {
322        let this = &mut *self;
323        if this.inner.check_shutdown(cx) {
324            this.is_terminated = true;
325            return std::task::Poll::Ready(None);
326        }
327        if this.is_terminated {
328            panic!("polled LifecycleRequestStream after completion");
329        }
330        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
331            |bytes, handles| {
332                match this.inner.channel().read_etc(cx, bytes, handles) {
333                    std::task::Poll::Ready(Ok(())) => {}
334                    std::task::Poll::Pending => return std::task::Poll::Pending,
335                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
336                        this.is_terminated = true;
337                        return std::task::Poll::Ready(None);
338                    }
339                    std::task::Poll::Ready(Err(e)) => {
340                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
341                            e.into(),
342                        ))));
343                    }
344                }
345
346                // A message has been received from the channel
347                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
348
349                std::task::Poll::Ready(Some(match header.ordinal {
350                    0x64b176f1744c6f15 => {
351                        header.validate_request_tx_id(fidl::MethodType::OneWay)?;
352                        let mut req = fidl::new_empty!(
353                            fidl::encoding::EmptyPayload,
354                            fidl::encoding::DefaultFuchsiaResourceDialect
355                        );
356                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
357                        let control_handle = LifecycleControlHandle { inner: this.inner.clone() };
358                        Ok(LifecycleRequest::Stop { control_handle })
359                    }
360                    _ => Err(fidl::Error::UnknownOrdinal {
361                        ordinal: header.ordinal,
362                        protocol_name:
363                            <LifecycleMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
364                    }),
365                }))
366            },
367        )
368    }
369}
370
371/// A component can implement the Lifecycle protocol to be notified of lifecycle
372/// events. It can also store some state in the framework, to be redelivered to
373/// the component the next time it is started (a practice called "escrowing").
374///
375/// The ELF Runner uses this protocol to communicate lifecycle changes
376/// to the component, for more details on how it uses this protocol see:
377/// https://fuchsia.dev/fuchsia-src/concepts/components/v2/elf_runner#lifecycle
378#[derive(Debug)]
379pub enum LifecycleRequest {
380    /// The process must clean up its state in preparation for termination, and
381    /// must close the channel hosting the `Lifecycle` protocol when it is
382    /// ready to be terminated. The process should exit after it completes its
383    /// cleanup. At the discretion of the system the process may be terminated
384    /// before it closes the `Lifecycle` channel.
385    Stop { control_handle: LifecycleControlHandle },
386}
387
388impl LifecycleRequest {
389    #[allow(irrefutable_let_patterns)]
390    pub fn into_stop(self) -> Option<(LifecycleControlHandle)> {
391        if let LifecycleRequest::Stop { control_handle } = self {
392            Some((control_handle))
393        } else {
394            None
395        }
396    }
397
398    /// Name of the method defined in FIDL
399    pub fn method_name(&self) -> &'static str {
400        match *self {
401            LifecycleRequest::Stop { .. } => "stop",
402        }
403    }
404}
405
406#[derive(Debug, Clone)]
407pub struct LifecycleControlHandle {
408    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
409}
410
411impl fidl::endpoints::ControlHandle for LifecycleControlHandle {
412    fn shutdown(&self) {
413        self.inner.shutdown()
414    }
415
416    fn shutdown_with_epitaph(&self, status: zx_status::Status) {
417        self.inner.shutdown_with_epitaph(status)
418    }
419
420    fn is_closed(&self) -> bool {
421        self.inner.channel().is_closed()
422    }
423    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
424        self.inner.channel().on_closed()
425    }
426
427    #[cfg(target_os = "fuchsia")]
428    fn signal_peer(
429        &self,
430        clear_mask: zx::Signals,
431        set_mask: zx::Signals,
432    ) -> Result<(), zx_status::Status> {
433        use fidl::Peered;
434        self.inner.channel().signal_peer(clear_mask, set_mask)
435    }
436}
437
438impl LifecycleControlHandle {
439    pub fn send_on_escrow(&self, mut payload: LifecycleOnEscrowRequest) -> Result<(), fidl::Error> {
440        self.inner.send::<LifecycleOnEscrowRequest>(
441            &mut payload,
442            0,
443            0x3de9c2fcb734ed48,
444            fidl::encoding::DynamicFlags::empty(),
445        )
446    }
447}
448
449mod internal {
450    use super::*;
451
452    impl LifecycleOnEscrowRequest {
453        #[inline(always)]
454        fn max_ordinal_present(&self) -> u64 {
455            if let Some(_) = self.recoverable_bytes {
456                return 4;
457            }
458            if let Some(_) = self.escrowed_dictionary_handle {
459                return 3;
460            }
461            if let Some(_) = self.escrowed_dictionary {
462                return 2;
463            }
464            if let Some(_) = self.outgoing_dir {
465                return 1;
466            }
467            0
468        }
469    }
470
471    impl fidl::encoding::ResourceTypeMarker for LifecycleOnEscrowRequest {
472        type Borrowed<'a> = &'a mut Self;
473        fn take_or_borrow<'a>(
474            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
475        ) -> Self::Borrowed<'a> {
476            value
477        }
478    }
479
480    unsafe impl fidl::encoding::TypeMarker for LifecycleOnEscrowRequest {
481        type Owned = Self;
482
483        #[inline(always)]
484        fn inline_align(_context: fidl::encoding::Context) -> usize {
485            8
486        }
487
488        #[inline(always)]
489        fn inline_size(_context: fidl::encoding::Context) -> usize {
490            16
491        }
492    }
493
494    unsafe impl
495        fidl::encoding::Encode<
496            LifecycleOnEscrowRequest,
497            fidl::encoding::DefaultFuchsiaResourceDialect,
498        > for &mut LifecycleOnEscrowRequest
499    {
500        unsafe fn encode(
501            self,
502            encoder: &mut fidl::encoding::Encoder<
503                '_,
504                fidl::encoding::DefaultFuchsiaResourceDialect,
505            >,
506            offset: usize,
507            mut depth: fidl::encoding::Depth,
508        ) -> fidl::Result<()> {
509            encoder.debug_check_bounds::<LifecycleOnEscrowRequest>(offset);
510            // Vector header
511            let max_ordinal: u64 = self.max_ordinal_present();
512            encoder.write_num(max_ordinal, offset);
513            encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
514            // Calling encoder.out_of_line_offset(0) is not allowed.
515            if max_ordinal == 0 {
516                return Ok(());
517            }
518            depth.increment()?;
519            let envelope_size = 8;
520            let bytes_len = max_ordinal as usize * envelope_size;
521            #[allow(unused_variables)]
522            let offset = encoder.out_of_line_offset(bytes_len);
523            let mut _prev_end_offset: usize = 0;
524            if 1 > max_ordinal {
525                return Ok(());
526            }
527
528            // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
529            // are envelope_size bytes.
530            let cur_offset: usize = (1 - 1) * envelope_size;
531
532            // Zero reserved fields.
533            encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
534
535            // Safety:
536            // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
537            // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
538            //   envelope_size bytes, there is always sufficient room.
539            fidl::encoding::encode_in_envelope_optional::<
540                fidl::encoding::Endpoint<
541                    fidl::endpoints::ServerEnd<fidl_fuchsia_io::DirectoryMarker>,
542                >,
543                fidl::encoding::DefaultFuchsiaResourceDialect,
544            >(
545                self.outgoing_dir.as_mut().map(
546                    <fidl::encoding::Endpoint<
547                        fidl::endpoints::ServerEnd<fidl_fuchsia_io::DirectoryMarker>,
548                    > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
549                ),
550                encoder,
551                offset + cur_offset,
552                depth,
553            )?;
554
555            _prev_end_offset = cur_offset + envelope_size;
556            if 2 > max_ordinal {
557                return Ok(());
558            }
559
560            // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
561            // are envelope_size bytes.
562            let cur_offset: usize = (2 - 1) * envelope_size;
563
564            // Zero reserved fields.
565            encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
566
567            // Safety:
568            // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
569            // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
570            //   envelope_size bytes, there is always sufficient room.
571            fidl::encoding::encode_in_envelope_optional::<fidl_fuchsia_component_sandbox::DictionaryRef, fidl::encoding::DefaultFuchsiaResourceDialect>(
572            self.escrowed_dictionary.as_mut().map(<fidl_fuchsia_component_sandbox::DictionaryRef as fidl::encoding::ResourceTypeMarker>::take_or_borrow),
573            encoder, offset + cur_offset, depth
574        )?;
575
576            _prev_end_offset = cur_offset + envelope_size;
577            if 3 > max_ordinal {
578                return Ok(());
579            }
580
581            // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
582            // are envelope_size bytes.
583            let cur_offset: usize = (3 - 1) * envelope_size;
584
585            // Zero reserved fields.
586            encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
587
588            // Safety:
589            // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
590            // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
591            //   envelope_size bytes, there is always sufficient room.
592            fidl::encoding::encode_in_envelope_optional::<
593                fidl::encoding::HandleType<
594                    fidl::EventPair,
595                    { fidl::ObjectType::EVENTPAIR.into_raw() },
596                    2147483648,
597                >,
598                fidl::encoding::DefaultFuchsiaResourceDialect,
599            >(
600                self.escrowed_dictionary_handle.as_mut().map(
601                    <fidl::encoding::HandleType<
602                        fidl::EventPair,
603                        { fidl::ObjectType::EVENTPAIR.into_raw() },
604                        2147483648,
605                    > as fidl::encoding::ResourceTypeMarker>::take_or_borrow,
606                ),
607                encoder,
608                offset + cur_offset,
609                depth,
610            )?;
611
612            _prev_end_offset = cur_offset + envelope_size;
613            if 4 > max_ordinal {
614                return Ok(());
615            }
616
617            // Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
618            // are envelope_size bytes.
619            let cur_offset: usize = (4 - 1) * envelope_size;
620
621            // Zero reserved fields.
622            encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
623
624            // Safety:
625            // - bytes_len is calculated to fit envelope_size*max(member.ordinal).
626            // - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
627            //   envelope_size bytes, there is always sufficient room.
628            fidl::encoding::encode_in_envelope_optional::<
629                u64,
630                fidl::encoding::DefaultFuchsiaResourceDialect,
631            >(
632                self.recoverable_bytes
633                    .as_ref()
634                    .map(<u64 as fidl::encoding::ValueTypeMarker>::borrow),
635                encoder,
636                offset + cur_offset,
637                depth,
638            )?;
639
640            _prev_end_offset = cur_offset + envelope_size;
641
642            Ok(())
643        }
644    }
645
646    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
647        for LifecycleOnEscrowRequest
648    {
649        #[inline(always)]
650        fn new_empty() -> Self {
651            Self::default()
652        }
653
654        unsafe fn decode(
655            &mut self,
656            decoder: &mut fidl::encoding::Decoder<
657                '_,
658                fidl::encoding::DefaultFuchsiaResourceDialect,
659            >,
660            offset: usize,
661            mut depth: fidl::encoding::Depth,
662        ) -> fidl::Result<()> {
663            decoder.debug_check_bounds::<Self>(offset);
664            let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
665                None => return Err(fidl::Error::NotNullable),
666                Some(len) => len,
667            };
668            // Calling decoder.out_of_line_offset(0) is not allowed.
669            if len == 0 {
670                return Ok(());
671            };
672            depth.increment()?;
673            let envelope_size = 8;
674            let bytes_len = len * envelope_size;
675            let offset = decoder.out_of_line_offset(bytes_len)?;
676            // Decode the envelope for each type.
677            let mut _next_ordinal_to_read = 0;
678            let mut next_offset = offset;
679            let end_offset = offset + bytes_len;
680            _next_ordinal_to_read += 1;
681            if next_offset >= end_offset {
682                return Ok(());
683            }
684
685            // Decode unknown envelopes for gaps in ordinals.
686            while _next_ordinal_to_read < 1 {
687                fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
688                _next_ordinal_to_read += 1;
689                next_offset += envelope_size;
690            }
691
692            let next_out_of_line = decoder.next_out_of_line();
693            let handles_before = decoder.remaining_handles();
694            if let Some((inlined, num_bytes, num_handles)) =
695                fidl::encoding::decode_envelope_header(decoder, next_offset)?
696            {
697                let member_inline_size = <fidl::encoding::Endpoint<
698                    fidl::endpoints::ServerEnd<fidl_fuchsia_io::DirectoryMarker>,
699                > as fidl::encoding::TypeMarker>::inline_size(
700                    decoder.context
701                );
702                if inlined != (member_inline_size <= 4) {
703                    return Err(fidl::Error::InvalidInlineBitInEnvelope);
704                }
705                let inner_offset;
706                let mut inner_depth = depth.clone();
707                if inlined {
708                    decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
709                    inner_offset = next_offset;
710                } else {
711                    inner_offset = decoder.out_of_line_offset(member_inline_size)?;
712                    inner_depth.increment()?;
713                }
714                let val_ref = self.outgoing_dir.get_or_insert_with(|| {
715                    fidl::new_empty!(
716                        fidl::encoding::Endpoint<
717                            fidl::endpoints::ServerEnd<fidl_fuchsia_io::DirectoryMarker>,
718                        >,
719                        fidl::encoding::DefaultFuchsiaResourceDialect
720                    )
721                });
722                fidl::decode!(
723                    fidl::encoding::Endpoint<
724                        fidl::endpoints::ServerEnd<fidl_fuchsia_io::DirectoryMarker>,
725                    >,
726                    fidl::encoding::DefaultFuchsiaResourceDialect,
727                    val_ref,
728                    decoder,
729                    inner_offset,
730                    inner_depth
731                )?;
732                if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
733                {
734                    return Err(fidl::Error::InvalidNumBytesInEnvelope);
735                }
736                if handles_before != decoder.remaining_handles() + (num_handles as usize) {
737                    return Err(fidl::Error::InvalidNumHandlesInEnvelope);
738                }
739            }
740
741            next_offset += envelope_size;
742            _next_ordinal_to_read += 1;
743            if next_offset >= end_offset {
744                return Ok(());
745            }
746
747            // Decode unknown envelopes for gaps in ordinals.
748            while _next_ordinal_to_read < 2 {
749                fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
750                _next_ordinal_to_read += 1;
751                next_offset += envelope_size;
752            }
753
754            let next_out_of_line = decoder.next_out_of_line();
755            let handles_before = decoder.remaining_handles();
756            if let Some((inlined, num_bytes, num_handles)) =
757                fidl::encoding::decode_envelope_header(decoder, next_offset)?
758            {
759                let member_inline_size = <fidl_fuchsia_component_sandbox::DictionaryRef as fidl::encoding::TypeMarker>::inline_size(decoder.context);
760                if inlined != (member_inline_size <= 4) {
761                    return Err(fidl::Error::InvalidInlineBitInEnvelope);
762                }
763                let inner_offset;
764                let mut inner_depth = depth.clone();
765                if inlined {
766                    decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
767                    inner_offset = next_offset;
768                } else {
769                    inner_offset = decoder.out_of_line_offset(member_inline_size)?;
770                    inner_depth.increment()?;
771                }
772                let val_ref = self.escrowed_dictionary.get_or_insert_with(|| {
773                    fidl::new_empty!(
774                        fidl_fuchsia_component_sandbox::DictionaryRef,
775                        fidl::encoding::DefaultFuchsiaResourceDialect
776                    )
777                });
778                fidl::decode!(
779                    fidl_fuchsia_component_sandbox::DictionaryRef,
780                    fidl::encoding::DefaultFuchsiaResourceDialect,
781                    val_ref,
782                    decoder,
783                    inner_offset,
784                    inner_depth
785                )?;
786                if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
787                {
788                    return Err(fidl::Error::InvalidNumBytesInEnvelope);
789                }
790                if handles_before != decoder.remaining_handles() + (num_handles as usize) {
791                    return Err(fidl::Error::InvalidNumHandlesInEnvelope);
792                }
793            }
794
795            next_offset += envelope_size;
796            _next_ordinal_to_read += 1;
797            if next_offset >= end_offset {
798                return Ok(());
799            }
800
801            // Decode unknown envelopes for gaps in ordinals.
802            while _next_ordinal_to_read < 3 {
803                fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
804                _next_ordinal_to_read += 1;
805                next_offset += envelope_size;
806            }
807
808            let next_out_of_line = decoder.next_out_of_line();
809            let handles_before = decoder.remaining_handles();
810            if let Some((inlined, num_bytes, num_handles)) =
811                fidl::encoding::decode_envelope_header(decoder, next_offset)?
812            {
813                let member_inline_size = <fidl::encoding::HandleType<
814                    fidl::EventPair,
815                    { fidl::ObjectType::EVENTPAIR.into_raw() },
816                    2147483648,
817                > as fidl::encoding::TypeMarker>::inline_size(
818                    decoder.context
819                );
820                if inlined != (member_inline_size <= 4) {
821                    return Err(fidl::Error::InvalidInlineBitInEnvelope);
822                }
823                let inner_offset;
824                let mut inner_depth = depth.clone();
825                if inlined {
826                    decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
827                    inner_offset = next_offset;
828                } else {
829                    inner_offset = decoder.out_of_line_offset(member_inline_size)?;
830                    inner_depth.increment()?;
831                }
832                let val_ref =
833                self.escrowed_dictionary_handle.get_or_insert_with(|| fidl::new_empty!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect));
834                fidl::decode!(fidl::encoding::HandleType<fidl::EventPair, { fidl::ObjectType::EVENTPAIR.into_raw() }, 2147483648>, fidl::encoding::DefaultFuchsiaResourceDialect, val_ref, decoder, inner_offset, inner_depth)?;
835                if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
836                {
837                    return Err(fidl::Error::InvalidNumBytesInEnvelope);
838                }
839                if handles_before != decoder.remaining_handles() + (num_handles as usize) {
840                    return Err(fidl::Error::InvalidNumHandlesInEnvelope);
841                }
842            }
843
844            next_offset += envelope_size;
845            _next_ordinal_to_read += 1;
846            if next_offset >= end_offset {
847                return Ok(());
848            }
849
850            // Decode unknown envelopes for gaps in ordinals.
851            while _next_ordinal_to_read < 4 {
852                fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
853                _next_ordinal_to_read += 1;
854                next_offset += envelope_size;
855            }
856
857            let next_out_of_line = decoder.next_out_of_line();
858            let handles_before = decoder.remaining_handles();
859            if let Some((inlined, num_bytes, num_handles)) =
860                fidl::encoding::decode_envelope_header(decoder, next_offset)?
861            {
862                let member_inline_size =
863                    <u64 as fidl::encoding::TypeMarker>::inline_size(decoder.context);
864                if inlined != (member_inline_size <= 4) {
865                    return Err(fidl::Error::InvalidInlineBitInEnvelope);
866                }
867                let inner_offset;
868                let mut inner_depth = depth.clone();
869                if inlined {
870                    decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
871                    inner_offset = next_offset;
872                } else {
873                    inner_offset = decoder.out_of_line_offset(member_inline_size)?;
874                    inner_depth.increment()?;
875                }
876                let val_ref = self.recoverable_bytes.get_or_insert_with(|| {
877                    fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect)
878                });
879                fidl::decode!(
880                    u64,
881                    fidl::encoding::DefaultFuchsiaResourceDialect,
882                    val_ref,
883                    decoder,
884                    inner_offset,
885                    inner_depth
886                )?;
887                if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize)
888                {
889                    return Err(fidl::Error::InvalidNumBytesInEnvelope);
890                }
891                if handles_before != decoder.remaining_handles() + (num_handles as usize) {
892                    return Err(fidl::Error::InvalidNumHandlesInEnvelope);
893                }
894            }
895
896            next_offset += envelope_size;
897
898            // Decode the remaining unknown envelopes.
899            while next_offset < end_offset {
900                _next_ordinal_to_read += 1;
901                fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
902                next_offset += envelope_size;
903            }
904
905            Ok(())
906        }
907    }
908}