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