// 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: a.vdl

package a

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"
)

// AServiceClientMethods is the client interface
// containing AService methods.
type AServiceClientMethods interface {
	AMethod(*context.T, ...rpc.CallOpt) error
}

// AServiceClientStub adds universal methods to AServiceClientMethods.
type AServiceClientStub interface {
	AServiceClientMethods
	rpc.UniversalServiceMethods
}

// AServiceClient returns a client stub for AService.
func AServiceClient(name string) AServiceClientStub {
	return implAServiceClientStub{name}
}

type implAServiceClientStub struct {
	name string
}

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

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

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

// AServiceServerStub adds universal methods to AServiceServerStubMethods.
type AServiceServerStub interface {
	AServiceServerStubMethods
	// Describe the AService interfaces.
	Describe__() []rpc.InterfaceDesc
}

// AServiceServer returns a server stub for AService.
// It converts an implementation of AServiceServerMethods into
// an object that may be used by rpc.Server.
func AServiceServer(impl AServiceServerMethods) AServiceServerStub {
	stub := implAServiceServerStub{
		impl: 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 implAServiceServerStub struct {
	impl AServiceServerMethods
	gs   *rpc.GlobState
}

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

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

func (s implAServiceServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{AServiceDesc}
}

// AServiceDesc describes the AService interface.
var AServiceDesc rpc.InterfaceDesc = descAService

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