// Code generated by fidlgen; DO NOT EDIT.

package service

import (
	_bindings "syscall/zx/fidl"
)

const (
	FirstProtocolMethodOnFirstOrdinal uint64 = 0x5b76bb4db7c2bba4
)

type FirstProtocolWithCtxInterface _bindings.ChannelProxy

func (p *FirstProtocolWithCtxInterface) MethodOnFirst(ctx_ _bindings.Context) error {
	var req_ _bindings.Message
	err_ := ((*_bindings.ChannelProxy)(p)).Send(FirstProtocolMethodOnFirstOrdinal, req_)
	return err_
}

type FirstProtocolWithCtx interface {
	MethodOnFirst(ctx_ _bindings.Context) error
}

type FirstProtocolWithCtxTransitionalBase struct{}

type FirstProtocolWithCtxInterfaceRequest _bindings.InterfaceRequest

func NewFirstProtocolWithCtxInterfaceRequest() (FirstProtocolWithCtxInterfaceRequest, *FirstProtocolWithCtxInterface, error) {
	req, cli, err := _bindings.NewInterfaceRequest()
	return FirstProtocolWithCtxInterfaceRequest(req), (*FirstProtocolWithCtxInterface)(cli), err
}

type FirstProtocolWithCtxStub struct {
	Impl FirstProtocolWithCtx
}

func (s_ *FirstProtocolWithCtxStub) Dispatch(args_ _bindings.DispatchArgs) (_bindings.Message, bool, error) {
	switch args_.Ordinal {
	case FirstProtocolMethodOnFirstOrdinal:
		err_ := s_.Impl.MethodOnFirst(args_.Ctx)
		return nil, false, err_
	}
	return nil, false, _bindings.ErrUnknownOrdinal
}

type FirstProtocolEventProxy _bindings.ChannelProxy

const (
	SecondProtocolMethodOnSecondOrdinal uint64 = 0x54ea6448c1555a29
)

type SecondProtocolWithCtxInterface _bindings.ChannelProxy

func (p *SecondProtocolWithCtxInterface) MethodOnSecond(ctx_ _bindings.Context) error {
	var req_ _bindings.Message
	err_ := ((*_bindings.ChannelProxy)(p)).Send(SecondProtocolMethodOnSecondOrdinal, req_)
	return err_
}

type SecondProtocolWithCtx interface {
	MethodOnSecond(ctx_ _bindings.Context) error
}

type SecondProtocolWithCtxTransitionalBase struct{}

type SecondProtocolWithCtxInterfaceRequest _bindings.InterfaceRequest

func NewSecondProtocolWithCtxInterfaceRequest() (SecondProtocolWithCtxInterfaceRequest, *SecondProtocolWithCtxInterface, error) {
	req, cli, err := _bindings.NewInterfaceRequest()
	return SecondProtocolWithCtxInterfaceRequest(req), (*SecondProtocolWithCtxInterface)(cli), err
}

type SecondProtocolWithCtxStub struct {
	Impl SecondProtocolWithCtx
}

func (s_ *SecondProtocolWithCtxStub) Dispatch(args_ _bindings.DispatchArgs) (_bindings.Message, bool, error) {
	switch args_.Ordinal {
	case SecondProtocolMethodOnSecondOrdinal:
		err_ := s_.Impl.MethodOnSecond(args_.Ctx)
		return nil, false, err_
	}
	return nil, false, _bindings.ErrUnknownOrdinal
}

type SecondProtocolEventProxy _bindings.ChannelProxy
