// Code generated by fidlgen; DO NOT EDIT.

package json

import (
	_bindings "syscall/zx/fidl"
)

type superWithCtxFooRequest struct {
	_ struct{} `fidl:"s" fidl_size_v1:"16" fidl_alignment_v1:"8"`
	S string   `fidl_offset_v1:"0" fidl_bounds:""`
}

var _msuperWithCtxFooRequest = _bindings.CreateLazyMarshaler(superWithCtxFooRequest{})

func (msg *superWithCtxFooRequest) Marshaler() _bindings.Marshaler {
	return _msuperWithCtxFooRequest
}

type superWithCtxFooResponse struct {
	_ struct{} `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	Y int64    `fidl_offset_v1:"0"`
}

var _msuperWithCtxFooResponse = _bindings.CreateLazyMarshaler(superWithCtxFooResponse{})

func (msg *superWithCtxFooResponse) Marshaler() _bindings.Marshaler {
	return _msuperWithCtxFooResponse
}

type subWithCtxFooRequest struct {
	_ struct{} `fidl:"s" fidl_size_v1:"16" fidl_alignment_v1:"8"`
	S string   `fidl_offset_v1:"0" fidl_bounds:""`
}

var _msubWithCtxFooRequest = _bindings.CreateLazyMarshaler(subWithCtxFooRequest{})

func (msg *subWithCtxFooRequest) Marshaler() _bindings.Marshaler {
	return _msubWithCtxFooRequest
}

type subWithCtxFooResponse struct {
	_ struct{} `fidl:"s" fidl_size_v1:"8" fidl_alignment_v1:"8"`
	Y int64    `fidl_offset_v1:"0"`
}

var _msubWithCtxFooResponse = _bindings.CreateLazyMarshaler(subWithCtxFooResponse{})

func (msg *subWithCtxFooResponse) Marshaler() _bindings.Marshaler {
	return _msubWithCtxFooResponse
}

const (
	SuperFooOrdinal    uint64 = 0x2f16c1bc00000000
	SuperFooGenOrdinal uint64 = 0x4f6c089228ba7c92
)

type SuperWithCtxInterface _bindings.ChannelProxy

func (p *SuperWithCtxInterface) Foo(ctx_ _bindings.Context, s string) (int64, error) {
	req_ := &superWithCtxFooRequest{
		S: s,
	}
	resp_ := &superWithCtxFooResponse{}
	err_ := ((*_bindings.ChannelProxy)(p)).Call(SuperFooGenOrdinal, req_, resp_, SuperFooOrdinal, SuperFooGenOrdinal)
	return resp_.Y, err_
}

type SuperWithCtx interface {
	Foo(ctx_ _bindings.Context, s string) (int64, error)
}

type SuperWithCtxTransitionalBase struct{}

type SuperWithCtxInterfaceRequest _bindings.InterfaceRequest

func NewSuperWithCtxInterfaceRequest() (SuperWithCtxInterfaceRequest, *SuperWithCtxInterface, error) {
	req, cli, err := _bindings.NewInterfaceRequest()
	return SuperWithCtxInterfaceRequest(req), (*SuperWithCtxInterface)(cli), err
}

type SuperWithCtxStub struct {
	Impl SuperWithCtx
}

func (s_ *SuperWithCtxStub) Dispatch(args_ _bindings.DispatchArgs) (_bindings.Message, bool, error) {
	switch args_.Ordinal {
	case SuperFooOrdinal:
		fallthrough
	case SuperFooGenOrdinal:
		in_ := superWithCtxFooRequest{}
		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_
		}
		y, err_ := s_.Impl.Foo(args_.Ctx, in_.S)
		out_ := superWithCtxFooResponse{}
		out_.Y = y
		return &out_, true, err_
	}
	return nil, false, _bindings.ErrUnknownOrdinal
}

type SuperService struct {
	_bindings.BindingSet
}

func (s *SuperService) EventProxyFor(key _bindings.BindingKey) (*SuperEventProxy, bool) {
	pxy, err := s.BindingSet.ProxyFor(key)
	return (*SuperEventProxy)(pxy), err
}

type SuperEventProxy _bindings.ChannelProxy

const (
	SubFooOrdinal    uint64 = 0x2f16c1bc00000000
	SubFooGenOrdinal uint64 = 0x4f6c089228ba7c92
)

type SubWithCtxInterface _bindings.ChannelProxy

func (p *SubWithCtxInterface) Foo(ctx_ _bindings.Context, s string) (int64, error) {
	req_ := &subWithCtxFooRequest{
		S: s,
	}
	resp_ := &subWithCtxFooResponse{}
	err_ := ((*_bindings.ChannelProxy)(p)).Call(SubFooGenOrdinal, req_, resp_, SubFooOrdinal, SubFooGenOrdinal)
	return resp_.Y, err_
}

type SubWithCtx interface {
	Foo(ctx_ _bindings.Context, s string) (int64, error)
}

type SubWithCtxTransitionalBase struct{}

type SubWithCtxInterfaceRequest _bindings.InterfaceRequest

func NewSubWithCtxInterfaceRequest() (SubWithCtxInterfaceRequest, *SubWithCtxInterface, error) {
	req, cli, err := _bindings.NewInterfaceRequest()
	return SubWithCtxInterfaceRequest(req), (*SubWithCtxInterface)(cli), err
}

type SubWithCtxStub struct {
	Impl SubWithCtx
}

func (s_ *SubWithCtxStub) Dispatch(args_ _bindings.DispatchArgs) (_bindings.Message, bool, error) {
	switch args_.Ordinal {
	case SubFooOrdinal:
		fallthrough
	case SubFooGenOrdinal:
		in_ := subWithCtxFooRequest{}
		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_
		}
		y, err_ := s_.Impl.Foo(args_.Ctx, in_.S)
		out_ := subWithCtxFooResponse{}
		out_.Y = y
		return &out_, true, err_
	}
	return nil, false, _bindings.ErrUnknownOrdinal
}

type SubService struct {
	_bindings.BindingSet
}

func (s *SubService) EventProxyFor(key _bindings.BindingKey) (*SubEventProxy, bool) {
	pxy, err := s.BindingSet.ProxyFor(key)
	return (*SubEventProxy)(pxy), err
}

type SubEventProxy _bindings.ChannelProxy
