// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file was auto-generated by the vanadium vdl tool.
// Source: b.vdl

package b

import (
	// VDL system imports
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/vdl"

	// VDL user imports
	"v.io/v23/security/access"
	"v.io/x/ref/test/discovery/a"
)

// AnotherServiceClientMethods is the client interface
// containing AnotherService methods.
type AnotherServiceClientMethods interface {
	a.AServiceClientMethods
	AnotherMethod(*context.T, ...rpc.CallOpt) error
}

// AnotherServiceClientStub adds universal methods to AnotherServiceClientMethods.
type AnotherServiceClientStub interface {
	AnotherServiceClientMethods
	rpc.UniversalServiceMethods
}

// AnotherServiceClient returns a client stub for AnotherService.
func AnotherServiceClient(name string) AnotherServiceClientStub {
	return implAnotherServiceClientStub{name, a.AServiceClient(name)}
}

type implAnotherServiceClientStub struct {
	name string

	a.AServiceClientStub
}

func (c implAnotherServiceClientStub) AnotherMethod(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "AnotherMethod", nil, nil, opts...)
	return
}

// AnotherServiceServerMethods is the interface a server writer
// implements for AnotherService.
type AnotherServiceServerMethods interface {
	a.AServiceServerMethods
	AnotherMethod(*context.T, rpc.ServerCall) error
}

// AnotherServiceServerStubMethods is the server interface containing
// AnotherService methods, as expected by rpc.Server.
// There is no difference between this interface and AnotherServiceServerMethods
// since there are no streaming methods.
type AnotherServiceServerStubMethods AnotherServiceServerMethods

// AnotherServiceServerStub adds universal methods to AnotherServiceServerStubMethods.
type AnotherServiceServerStub interface {
	AnotherServiceServerStubMethods
	// Describe the AnotherService interfaces.
	Describe__() []rpc.InterfaceDesc
}

// AnotherServiceServer returns a server stub for AnotherService.
// It converts an implementation of AnotherServiceServerMethods into
// an object that may be used by rpc.Server.
func AnotherServiceServer(impl AnotherServiceServerMethods) AnotherServiceServerStub {
	stub := implAnotherServiceServerStub{
		impl:               impl,
		AServiceServerStub: a.AServiceServer(impl),
	}
	// Initialize GlobState; always check the stub itself first, to handle the
	// case where the user has the Glob method defined in their VDL source.
	if gs := rpc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := rpc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type implAnotherServiceServerStub struct {
	impl AnotherServiceServerMethods
	a.AServiceServerStub
	gs *rpc.GlobState
}

func (s implAnotherServiceServerStub) AnotherMethod(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.AnotherMethod(ctx, call)
}

func (s implAnotherServiceServerStub) Globber() *rpc.GlobState {
	return s.gs
}

func (s implAnotherServiceServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{AnotherServiceDesc, a.AServiceDesc}
}

// AnotherServiceDesc describes the AnotherService interface.
var AnotherServiceDesc rpc.InterfaceDesc = descAnotherService

// descAnotherService hides the desc to keep godoc clean.
var descAnotherService = rpc.InterfaceDesc{
	Name:    "AnotherService",
	PkgPath: "v.io/x/ref/test/discovery/b",
	Embeds: []rpc.EmbedDesc{
		{"AService", "v.io/x/ref/test/discovery/a", ``},
	},
	Methods: []rpc.MethodDesc{
		{
			Name: "AnotherMethod",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}
