// Code generated by fidlgen; DO NOT EDIT.

package protocolrequest

import (
	_bindings "syscall/zx/fidl"
)

type parentWithCtxGetChildResponse struct {
	_ struct{}              `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	C ChildWithCtxInterface `fidl_offset_v1:"0" fidl_handle_subtype:"4"`
}

var _mparentWithCtxGetChildResponse = _bindings.CreateLazyMarshaler(parentWithCtxGetChildResponse{})

func (msg *parentWithCtxGetChildResponse) Marshaler() _bindings.Marshaler {
	return _mparentWithCtxGetChildResponse
}

type parentWithCtxGetChildRequestResponse struct {
	_ struct{}                     `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	R ChildWithCtxInterfaceRequest `fidl_offset_v1:"0" fidl_handle_subtype:"4" fidl_bounds:"0"`
}

var _mparentWithCtxGetChildRequestResponse = _bindings.CreateLazyMarshaler(parentWithCtxGetChildRequestResponse{})

func (msg *parentWithCtxGetChildRequestResponse) Marshaler() _bindings.Marshaler {
	return _mparentWithCtxGetChildRequestResponse
}

type parentWithCtxTakeChildRequest struct {
	_ struct{}              `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	C ChildWithCtxInterface `fidl_offset_v1:"0" fidl_handle_subtype:"4"`
}

var _mparentWithCtxTakeChildRequest = _bindings.CreateLazyMarshaler(parentWithCtxTakeChildRequest{})

func (msg *parentWithCtxTakeChildRequest) Marshaler() _bindings.Marshaler {
	return _mparentWithCtxTakeChildRequest
}

type parentWithCtxTakeChildRequestRequest struct {
	_ struct{}                     `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	R ChildWithCtxInterfaceRequest `fidl_offset_v1:"0" fidl_handle_subtype:"4" fidl_bounds:"0"`
}

var _mparentWithCtxTakeChildRequestRequest = _bindings.CreateLazyMarshaler(parentWithCtxTakeChildRequestRequest{})

func (msg *parentWithCtxTakeChildRequestRequest) Marshaler() _bindings.Marshaler {
	return _mparentWithCtxTakeChildRequestRequest
}

const ()

type ChildWithCtxInterface _bindings.ChannelProxy

type ChildWithCtx interface {
}

type ChildWithCtxTransitionalBase struct{}

type ChildWithCtxInterfaceRequest _bindings.InterfaceRequest

func NewChildWithCtxInterfaceRequest() (ChildWithCtxInterfaceRequest, *ChildWithCtxInterface, error) {
	req, cli, err := _bindings.NewInterfaceRequest()
	return ChildWithCtxInterfaceRequest(req), (*ChildWithCtxInterface)(cli), err
}

type ChildWithCtxStub struct {
	Impl ChildWithCtx
}

func (s_ *ChildWithCtxStub) Dispatch(args_ _bindings.DispatchArgs) (_bindings.Message, bool, error) {
	switch args_.Ordinal {
	}
	return nil, false, _bindings.ErrUnknownOrdinal
}

type ChildEventProxy _bindings.ChannelProxy

const (
	ParentGetChildOrdinal         uint64 = 0x6e0c789be8dbb77e
	ParentGetChildRequestOrdinal  uint64 = 0x193e7d6949a9df98
	ParentTakeChildOrdinal        uint64 = 0x5311bd7214c0f6e
	ParentTakeChildRequestOrdinal uint64 = 0x15dae312bad5a9cc
)

type ParentWithCtxInterface _bindings.ChannelProxy

func (p *ParentWithCtxInterface) GetChild(ctx_ _bindings.Context) (ChildWithCtxInterface, error) {
	var req_ _bindings.Message
	resp_ := &parentWithCtxGetChildResponse{}
	err_ := ((*_bindings.ChannelProxy)(p)).Call(ParentGetChildOrdinal, req_, resp_)
	return resp_.C, err_
}

func (p *ParentWithCtxInterface) GetChildRequest(ctx_ _bindings.Context) (ChildWithCtxInterfaceRequest, error) {
	var req_ _bindings.Message
	resp_ := &parentWithCtxGetChildRequestResponse{}
	err_ := ((*_bindings.ChannelProxy)(p)).Call(ParentGetChildRequestOrdinal, req_, resp_)
	return resp_.R, err_
}

func (p *ParentWithCtxInterface) TakeChild(ctx_ _bindings.Context, c ChildWithCtxInterface) error {
	req_ := &parentWithCtxTakeChildRequest{
		C: c,
	}
	err_ := ((*_bindings.ChannelProxy)(p)).Send(ParentTakeChildOrdinal, req_)
	return err_
}

func (p *ParentWithCtxInterface) TakeChildRequest(ctx_ _bindings.Context, r ChildWithCtxInterfaceRequest) error {
	req_ := &parentWithCtxTakeChildRequestRequest{
		R: r,
	}
	err_ := ((*_bindings.ChannelProxy)(p)).Send(ParentTakeChildRequestOrdinal, req_)
	return err_
}

type ParentWithCtx interface {
	GetChild(ctx_ _bindings.Context) (ChildWithCtxInterface, error)
	GetChildRequest(ctx_ _bindings.Context) (ChildWithCtxInterfaceRequest, error)
	TakeChild(ctx_ _bindings.Context, c ChildWithCtxInterface) error
	TakeChildRequest(ctx_ _bindings.Context, r ChildWithCtxInterfaceRequest) error
}

type ParentWithCtxTransitionalBase struct{}

type ParentWithCtxInterfaceRequest _bindings.InterfaceRequest

func NewParentWithCtxInterfaceRequest() (ParentWithCtxInterfaceRequest, *ParentWithCtxInterface, error) {
	req, cli, err := _bindings.NewInterfaceRequest()
	return ParentWithCtxInterfaceRequest(req), (*ParentWithCtxInterface)(cli), err
}

type ParentWithCtxStub struct {
	Impl ParentWithCtx
}

func (s_ *ParentWithCtxStub) Dispatch(args_ _bindings.DispatchArgs) (_bindings.Message, bool, error) {
	switch args_.Ordinal {
	case ParentGetChildOrdinal:
		c, err_ := s_.Impl.GetChild(args_.Ctx)
		out_ := parentWithCtxGetChildResponse{}
		out_.C = c
		return &out_, true, err_
	case ParentGetChildRequestOrdinal:
		r, err_ := s_.Impl.GetChildRequest(args_.Ctx)
		out_ := parentWithCtxGetChildRequestResponse{}
		out_.R = r
		return &out_, true, err_
	case ParentTakeChildOrdinal:
		in_ := parentWithCtxTakeChildRequest{}
		marshalerCtx, ok := _bindings.GetMarshalerContext(args_.Ctx)
		if !ok {
			return nil, false, _bindings.ErrMissingMarshalerContext
		}
		if _, _, err_ := _bindings.UnmarshalWithContext2(marshalerCtx, args_.Bytes, args_.HandleInfos, &in_); err_ != nil {
			return nil, false, err_
		}
		err_ := s_.Impl.TakeChild(args_.Ctx, in_.C)
		return nil, false, err_
	case ParentTakeChildRequestOrdinal:
		in_ := parentWithCtxTakeChildRequestRequest{}
		marshalerCtx, ok := _bindings.GetMarshalerContext(args_.Ctx)
		if !ok {
			return nil, false, _bindings.ErrMissingMarshalerContext
		}
		if _, _, err_ := _bindings.UnmarshalWithContext2(marshalerCtx, args_.Bytes, args_.HandleInfos, &in_); err_ != nil {
			return nil, false, err_
		}
		err_ := s_.Impl.TakeChildRequest(args_.Ctx, in_.R)
		return nil, false, err_
	}
	return nil, false, _bindings.ErrUnknownOrdinal
}

type ParentEventProxy _bindings.ChannelProxy
