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