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