// Code generated by fidlgen; DO NOT EDIT.

package emptystruct

import (
	_bindings "syscall/zx/fidl"
)

type Empty struct {
	_ struct{} `fidl:"s" fidl_size_v1:"1" fidl_alignment_v1:"1"`
}

var _mEmpty = _bindings.CreateLazyMarshaler(Empty{})

func (msg *Empty) Marshaler() _bindings.Marshaler {
	return _mEmpty
}

type emptyProtocolWithCtxSendRequest struct {
	_ struct{} `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	E Empty    `fidl_offset_v1:"0"`
}

var _memptyProtocolWithCtxSendRequest = _bindings.CreateLazyMarshaler(emptyProtocolWithCtxSendRequest{})

func (msg *emptyProtocolWithCtxSendRequest) Marshaler() _bindings.Marshaler {
	return _memptyProtocolWithCtxSendRequest
}

type emptyProtocolWithCtxReceiveResponse struct {
	_ struct{} `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	E Empty    `fidl_offset_v1:"0"`
}

var _memptyProtocolWithCtxReceiveResponse = _bindings.CreateLazyMarshaler(emptyProtocolWithCtxReceiveResponse{})

func (msg *emptyProtocolWithCtxReceiveResponse) Marshaler() _bindings.Marshaler {
	return _memptyProtocolWithCtxReceiveResponse
}

type emptyProtocolWithCtxSendAndReceiveRequest struct {
	_ struct{} `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	E Empty    `fidl_offset_v1:"0"`
}

var _memptyProtocolWithCtxSendAndReceiveRequest = _bindings.CreateLazyMarshaler(emptyProtocolWithCtxSendAndReceiveRequest{})

func (msg *emptyProtocolWithCtxSendAndReceiveRequest) Marshaler() _bindings.Marshaler {
	return _memptyProtocolWithCtxSendAndReceiveRequest
}

type emptyProtocolWithCtxSendAndReceiveResponse struct {
	_ struct{} `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	E Empty    `fidl_offset_v1:"0"`
}

var _memptyProtocolWithCtxSendAndReceiveResponse = _bindings.CreateLazyMarshaler(emptyProtocolWithCtxSendAndReceiveResponse{})

func (msg *emptyProtocolWithCtxSendAndReceiveResponse) Marshaler() _bindings.Marshaler {
	return _memptyProtocolWithCtxSendAndReceiveResponse
}

const (
	EmptyProtocolSendOrdinal           uint64 = 0x1e4e78d0556b6f28
	EmptyProtocolReceiveOrdinal        uint64 = 0x45bd261c537791e0
	EmptyProtocolSendAndReceiveOrdinal uint64 = 0x56ca6bd78bac3571
)

type EmptyProtocolWithCtxInterface _bindings.ChannelProxy

func (p *EmptyProtocolWithCtxInterface) Send(ctx_ _bindings.Context, e Empty) error {
	req_ := &emptyProtocolWithCtxSendRequest{
		E: e,
	}
	err_ := ((*_bindings.ChannelProxy)(p)).Send(EmptyProtocolSendOrdinal, req_)
	return err_
}

func (p *EmptyProtocolWithCtxInterface) ExpectReceive(ctx_ _bindings.Context) (Empty, error) {
	resp_ := &emptyProtocolWithCtxReceiveResponse{}
	err_ := ((*_bindings.ChannelProxy)(p)).Recv(EmptyProtocolReceiveOrdinal, resp_)
	return resp_.E, err_
}

func (p *EmptyProtocolWithCtxInterface) SendAndReceive(ctx_ _bindings.Context, e Empty) (Empty, error) {
	req_ := &emptyProtocolWithCtxSendAndReceiveRequest{
		E: e,
	}
	resp_ := &emptyProtocolWithCtxSendAndReceiveResponse{}
	err_ := ((*_bindings.ChannelProxy)(p)).Call(EmptyProtocolSendAndReceiveOrdinal, req_, resp_)
	return resp_.E, err_
}

type EmptyProtocolWithCtx interface {
	Send(ctx_ _bindings.Context, e Empty) error
	SendAndReceive(ctx_ _bindings.Context, e Empty) (Empty, error)
}

type EmptyProtocolWithCtxTransitionalBase struct{}

type EmptyProtocolWithCtxInterfaceRequest _bindings.InterfaceRequest

func NewEmptyProtocolWithCtxInterfaceRequest() (EmptyProtocolWithCtxInterfaceRequest, *EmptyProtocolWithCtxInterface, error) {
	req, cli, err := _bindings.NewInterfaceRequest()
	return EmptyProtocolWithCtxInterfaceRequest(req), (*EmptyProtocolWithCtxInterface)(cli), err
}

type EmptyProtocolWithCtxStub struct {
	Impl EmptyProtocolWithCtx
}

func (s_ *EmptyProtocolWithCtxStub) Dispatch(args_ _bindings.DispatchArgs) (_bindings.Message, bool, error) {
	switch args_.Ordinal {
	case EmptyProtocolSendOrdinal:
		in_ := emptyProtocolWithCtxSendRequest{}
		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.Send(args_.Ctx, in_.E)
		return nil, false, err_
	case EmptyProtocolSendAndReceiveOrdinal:
		in_ := emptyProtocolWithCtxSendAndReceiveRequest{}
		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_
		}
		e, err_ := s_.Impl.SendAndReceive(args_.Ctx, in_.E)
		out_ := emptyProtocolWithCtxSendAndReceiveResponse{}
		out_.E = e
		return &out_, true, err_
	}
	return nil, false, _bindings.ErrUnknownOrdinal
}

type EmptyProtocolEventProxy _bindings.ChannelProxy

func (p *EmptyProtocolEventProxy) Receive(e Empty) error {
	event_ := &emptyProtocolWithCtxReceiveResponse{
		E: e,
	}
	return ((*_bindings.ChannelProxy)(p)).Send(EmptyProtocolReceiveOrdinal, event_)
}
