// Code generated by fidlgen; DO NOT EDIT.

package inheritancewithrecursivedecl

import (
	_bindings "syscall/zx/fidl"
)

type parentWithCtxFirstRequest struct {
	_       struct{}                      `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	Request ParentWithCtxInterfaceRequest `fidl_offset_v1:"0" fidl_handle_subtype:"4" fidl_bounds:"0"`
}

var _mparentWithCtxFirstRequest = _bindings.CreateLazyMarshaler(parentWithCtxFirstRequest{})

func (msg *parentWithCtxFirstRequest) Marshaler() _bindings.Marshaler {
	return _mparentWithCtxFirstRequest
}

type childWithCtxFirstRequest struct {
	_       struct{}                      `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	Request ParentWithCtxInterfaceRequest `fidl_offset_v1:"0" fidl_handle_subtype:"4" fidl_bounds:"0"`
}

var _mchildWithCtxFirstRequest = _bindings.CreateLazyMarshaler(childWithCtxFirstRequest{})

func (msg *childWithCtxFirstRequest) Marshaler() _bindings.Marshaler {
	return _mchildWithCtxFirstRequest
}

type childWithCtxSecondRequest struct {
	_       struct{}                      `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	Request ParentWithCtxInterfaceRequest `fidl_offset_v1:"0" fidl_handle_subtype:"4" fidl_bounds:"0"`
}

var _mchildWithCtxSecondRequest = _bindings.CreateLazyMarshaler(childWithCtxSecondRequest{})

func (msg *childWithCtxSecondRequest) Marshaler() _bindings.Marshaler {
	return _mchildWithCtxSecondRequest
}

const (
	ParentFirstOrdinal uint64 = 0x2a592d0a81dac39b
)

type ParentWithCtxInterface _bindings.ChannelProxy

func (p *ParentWithCtxInterface) First(ctx_ _bindings.Context, request ParentWithCtxInterfaceRequest) error {
	req_ := &parentWithCtxFirstRequest{
		Request: request,
	}
	err_ := ((*_bindings.ChannelProxy)(p)).Send(ParentFirstOrdinal, req_)
	return err_
}

type ParentWithCtx interface {
	First(ctx_ _bindings.Context, request ParentWithCtxInterfaceRequest) 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 ParentFirstOrdinal:
		in_ := parentWithCtxFirstRequest{}
		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.First(args_.Ctx, in_.Request)
		return nil, false, err_
	}
	return nil, false, _bindings.ErrUnknownOrdinal
}

type ParentEventProxy _bindings.ChannelProxy

const (
	ChildFirstOrdinal  uint64 = 0x2a592d0a81dac39b
	ChildSecondOrdinal uint64 = 0x6cba5c5e01fee86
)

type ChildWithCtxInterface _bindings.ChannelProxy

func (p *ChildWithCtxInterface) First(ctx_ _bindings.Context, request ParentWithCtxInterfaceRequest) error {
	req_ := &childWithCtxFirstRequest{
		Request: request,
	}
	err_ := ((*_bindings.ChannelProxy)(p)).Send(ChildFirstOrdinal, req_)
	return err_
}

func (p *ChildWithCtxInterface) Second(ctx_ _bindings.Context, request ParentWithCtxInterfaceRequest) error {
	req_ := &childWithCtxSecondRequest{
		Request: request,
	}
	err_ := ((*_bindings.ChannelProxy)(p)).Send(ChildSecondOrdinal, req_)
	return err_
}

type ChildWithCtx interface {
	First(ctx_ _bindings.Context, request ParentWithCtxInterfaceRequest) error
	Second(ctx_ _bindings.Context, request ParentWithCtxInterfaceRequest) error
}

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 {
	case ChildFirstOrdinal:
		in_ := childWithCtxFirstRequest{}
		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.First(args_.Ctx, in_.Request)
		return nil, false, err_
	case ChildSecondOrdinal:
		in_ := childWithCtxSecondRequest{}
		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.Second(args_.Ctx, in_.Request)
		return nil, false, err_
	}
	return nil, false, _bindings.ErrUnknownOrdinal
}

type ChildEventProxy _bindings.ChannelProxy
