// Code generated by fidlgen; DO NOT EDIT.

package foreigntypeinresponseusedthroughcompose

import (
	bottom "fidl/bottom"
	middle "fidl/middle"
	_bindings "syscall/zx/fidl"
)

type topWithCtxGetFooResponse struct {
	_   struct{}   `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	Foo bottom.Foo `fidl_offset_v1:"0"`
}

var _mtopWithCtxGetFooResponse = _bindings.CreateLazyMarshaler(topWithCtxGetFooResponse{})

func (msg *topWithCtxGetFooResponse) Marshaler() _bindings.Marshaler {
	return _mtopWithCtxGetFooResponse
}

const (
	TopGetFooOrdinal uint64 = 0x6ae8d19bc98f3d92
)

type TopWithCtxInterface _bindings.ChannelProxy

func (p *TopWithCtxInterface) GetFoo(ctx_ _bindings.Context) (bottom.Foo, error) {
	var req_ _bindings.Message
	resp_ := &topWithCtxGetFooResponse{}
	err_ := ((*_bindings.ChannelProxy)(p)).Call(TopGetFooOrdinal, req_, resp_)
	return resp_.Foo, err_
}

type TopWithCtx interface {
	GetFoo(ctx_ _bindings.Context) (bottom.Foo, error)
}

type TopWithCtxTransitionalBase struct{}

type TopWithCtxInterfaceRequest _bindings.InterfaceRequest

func NewTopWithCtxInterfaceRequest() (TopWithCtxInterfaceRequest, *TopWithCtxInterface, error) {
	req, cli, err := _bindings.NewInterfaceRequest()
	return TopWithCtxInterfaceRequest(req), (*TopWithCtxInterface)(cli), err
}

type TopWithCtxStub struct {
	Impl TopWithCtx
}

func (s_ *TopWithCtxStub) Dispatch(args_ _bindings.DispatchArgs) (_bindings.Message, bool, error) {
	switch args_.Ordinal {
	case TopGetFooOrdinal:
		foo, err_ := s_.Impl.GetFoo(args_.Ctx)
		out_ := topWithCtxGetFooResponse{}
		out_.Foo = foo
		return &out_, true, err_
	}
	return nil, false, _bindings.ErrUnknownOrdinal
}

type TopEventProxy _bindings.ChannelProxy
