// 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.
// Package: groups

// Package groups defines interfaces for managing access control groups.  Groups
// can be referenced by BlessingPatterns (e.g. in AccessLists).
package groups

import (
	"fmt"
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/i18n"
	"v.io/v23/rpc"
	"v.io/v23/security/access"
	"v.io/v23/services/permissions"
	"v.io/v23/vdl"
	"v.io/v23/verror"
)

var _ = __VDLInit() // Must be first; see __VDLInit comments for details.

//////////////////////////////////////////////////
// Type definitions

// BlessingPatternChunk is a substring of a BlessingPattern. As with
// BlessingPatterns, BlessingPatternChunks may contain references to groups.
// However, they may be restricted in other ways. For example, in the future
// BlessingPatterns may support "$" terminators, but these may be disallowed for
// BlessingPatternChunks.
type BlessingPatternChunk string

func (BlessingPatternChunk) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/groups.BlessingPatternChunk"`
}) {
}

func (x BlessingPatternChunk) VDLIsZero() bool {
	return x == ""
}

func (x BlessingPatternChunk) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueString(__VDLType_string_1, string(x)); err != nil {
		return err
	}
	return nil
}

func (x *BlessingPatternChunk) VDLRead(dec vdl.Decoder) error {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		*x = BlessingPatternChunk(value)
	}
	return nil
}

type GetRequest struct {
}

func (GetRequest) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/groups.GetRequest"`
}) {
}

func (x GetRequest) VDLIsZero() bool {
	return x == GetRequest{}
}

func (x GetRequest) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_2); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *GetRequest) VDLRead(dec vdl.Decoder) error {
	*x = GetRequest{}
	if err := dec.StartValue(__VDLType_struct_2); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

type GetResponse struct {
	Entries map[BlessingPatternChunk]struct{}
}

func (GetResponse) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/groups.GetResponse"`
}) {
}

func (x GetResponse) VDLIsZero() bool {
	if len(x.Entries) != 0 {
		return false
	}
	return true
}

func (x GetResponse) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_3); err != nil {
		return err
	}
	if len(x.Entries) != 0 {
		if err := enc.NextField("Entries"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_set_1(enc, x.Entries); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_set_1(enc vdl.Encoder, x map[BlessingPatternChunk]struct{}) error {
	if err := enc.StartValue(__VDLType_set_4); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key := range x {
		if err := enc.NextEntryValueString(__VDLType_string_1, string(key)); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *GetResponse) VDLRead(dec vdl.Decoder) error {
	*x = GetResponse{}
	if err := dec.StartValue(__VDLType_struct_3); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Entries":
			if err := __VDLReadAnon_set_1(dec, &x.Entries); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_set_1(dec vdl.Decoder, x *map[BlessingPatternChunk]struct{}) error {
	if err := dec.StartValue(__VDLType_set_4); err != nil {
		return err
	}
	var tmpMap map[BlessingPatternChunk]struct{}
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(map[BlessingPatternChunk]struct{}, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			if tmpMap == nil {
				tmpMap = make(map[BlessingPatternChunk]struct{})
			}
			tmpMap[BlessingPatternChunk(key)] = struct{}{}
		}
	}
}

// ApproximationType defines the type of approximation desired when a Relate
// call encounters an error (inaccessible or undefined group in a blessing
// pattern, cyclic group definitions, storage errors, invalid patterns
// etc). "Under" is used for blessing patterns in "Allow" clauses in an
// AccessList, while "Over" is used for blessing patterns in "Deny" clauses.
type ApproximationType int

const (
	ApproximationTypeUnder ApproximationType = iota
	ApproximationTypeOver
)

// ApproximationTypeAll holds all labels for ApproximationType.
var ApproximationTypeAll = [...]ApproximationType{ApproximationTypeUnder, ApproximationTypeOver}

// ApproximationTypeFromString creates a ApproximationType from a string label.
func ApproximationTypeFromString(label string) (x ApproximationType, err error) {
	err = x.Set(label)
	return
}

// Set assigns label to x.
func (x *ApproximationType) Set(label string) error {
	switch label {
	case "Under", "under":
		*x = ApproximationTypeUnder
		return nil
	case "Over", "over":
		*x = ApproximationTypeOver
		return nil
	}
	*x = -1
	return fmt.Errorf("unknown label %q in groups.ApproximationType", label)
}

// String returns the string label of x.
func (x ApproximationType) String() string {
	switch x {
	case ApproximationTypeUnder:
		return "Under"
	case ApproximationTypeOver:
		return "Over"
	}
	return ""
}

func (ApproximationType) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/groups.ApproximationType"`
	Enum struct{ Under, Over string }
}) {
}

func (x ApproximationType) VDLIsZero() bool {
	return x == ApproximationTypeUnder
}

func (x ApproximationType) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueString(__VDLType_enum_5, x.String()); err != nil {
		return err
	}
	return nil
}

func (x *ApproximationType) VDLRead(dec vdl.Decoder) error {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		if err := x.Set(value); err != nil {
			return err
		}
	}
	return nil
}

// Approximation contains information about membership approximations made
// during a Relate call.
type Approximation struct {
	Reason  string
	Details string
}

func (Approximation) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/groups.Approximation"`
}) {
}

func (x Approximation) VDLIsZero() bool {
	return x == Approximation{}
}

func (x Approximation) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_6); err != nil {
		return err
	}
	if x.Reason != "" {
		if err := enc.NextFieldValueString("Reason", vdl.StringType, x.Reason); err != nil {
			return err
		}
	}
	if x.Details != "" {
		if err := enc.NextFieldValueString("Details", vdl.StringType, x.Details); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Approximation) VDLRead(dec vdl.Decoder) error {
	*x = Approximation{}
	if err := dec.StartValue(__VDLType_struct_6); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Reason":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Reason = value
			}
		case "Details":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Details = value
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

//////////////////////////////////////////////////
// Error definitions

var (
	ErrNoBlessings         = verror.Register("v.io/v23/services/groups.NoBlessings", verror.NoRetry, "{1:}{2:} No blessings recognized; cannot create group Permissions")
	ErrExcessiveContention = verror.Register("v.io/v23/services/groups.ExcessiveContention", verror.RetryBackoff, "{1:}{2:} Gave up after encountering excessive contention; try again later")
	ErrCycleFound          = verror.Register("v.io/v23/services/groups.CycleFound", verror.NoRetry, "{1:}{2:} Found cycle in group definitions{:_}")
)

// NewErrNoBlessings returns an error with the ErrNoBlessings ID.
func NewErrNoBlessings(ctx *context.T) error {
	return verror.New(ErrNoBlessings, ctx)
}

// NewErrExcessiveContention returns an error with the ErrExcessiveContention ID.
func NewErrExcessiveContention(ctx *context.T) error {
	return verror.New(ErrExcessiveContention, ctx)
}

// NewErrCycleFound returns an error with the ErrCycleFound ID.
func NewErrCycleFound(ctx *context.T) error {
	return verror.New(ErrCycleFound, ctx)
}

//////////////////////////////////////////////////
// Interface definitions

// GroupReaderClientMethods is the client interface
// containing GroupReader methods.
//
// GroupReader implements methods to read or query a group's membership
// information.
type GroupReaderClientMethods interface {
	// Relate determines the relationships between the provided blessing
	// names and the members of the group.
	//
	// Given an input set of blessing names and a group defined by a set of
	// blessing patterns S, for each blessing name B in the input, Relate(B)
	// returns a set of "remainders" consisting of every blessing name B"
	// such that there exists some B' for which B = B' B" and B' is in S,
	// and "" if B is a member of S.
	//
	// For example, if a group is defined as S = {n1, n1:n2, n1:n2:n3}, then
	// Relate(n1:n2) = {n2, ""}.
	//
	// reqVersion specifies the expected version of the group's membership
	// information. If this version is set and matches the Group's current
	// version, the response will indicate that fact but will otherwise be
	// empty.
	//
	// visitedGroups is the set of groups already visited in a particular
	// chain of Relate calls, and is used to detect the presence of
	// cycles. When a cycle is detected, it is treated just like any other
	// error, and the result is approximated.
	//
	// Relate also returns information about all the errors encountered that
	// resulted in approximations, if any.
	//
	// TODO(hpucha): scrub "Approximation" for preserving privacy. Flesh
	// versioning out further. Other args we may need: option to Get() the
	// membership set when allowed (to avoid an extra RPC), options related
	// to caching this information.
	Relate(_ *context.T, blessings map[string]struct{}, hint ApproximationType, reqVersion string, visitedGroups map[string]struct{}, _ ...rpc.CallOpt) (remainder map[string]struct{}, approximations []Approximation, version string, _ error)
	// Get returns all entries in the group.
	// TODO(sadovsky): Flesh out this API.
	Get(_ *context.T, req GetRequest, reqVersion string, _ ...rpc.CallOpt) (res GetResponse, version string, _ error)
}

// GroupReaderClientStub adds universal methods to GroupReaderClientMethods.
type GroupReaderClientStub interface {
	GroupReaderClientMethods
	rpc.UniversalServiceMethods
}

// GroupReaderClient returns a client stub for GroupReader.
func GroupReaderClient(name string) GroupReaderClientStub {
	return implGroupReaderClientStub{name}
}

type implGroupReaderClientStub struct {
	name string
}

func (c implGroupReaderClientStub) Relate(ctx *context.T, i0 map[string]struct{}, i1 ApproximationType, i2 string, i3 map[string]struct{}, opts ...rpc.CallOpt) (o0 map[string]struct{}, o1 []Approximation, o2 string, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Relate", []interface{}{i0, i1, i2, i3}, []interface{}{&o0, &o1, &o2}, opts...)
	return
}

func (c implGroupReaderClientStub) Get(ctx *context.T, i0 GetRequest, i1 string, opts ...rpc.CallOpt) (o0 GetResponse, o1 string, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Get", []interface{}{i0, i1}, []interface{}{&o0, &o1}, opts...)
	return
}

// GroupReaderServerMethods is the interface a server writer
// implements for GroupReader.
//
// GroupReader implements methods to read or query a group's membership
// information.
type GroupReaderServerMethods interface {
	// Relate determines the relationships between the provided blessing
	// names and the members of the group.
	//
	// Given an input set of blessing names and a group defined by a set of
	// blessing patterns S, for each blessing name B in the input, Relate(B)
	// returns a set of "remainders" consisting of every blessing name B"
	// such that there exists some B' for which B = B' B" and B' is in S,
	// and "" if B is a member of S.
	//
	// For example, if a group is defined as S = {n1, n1:n2, n1:n2:n3}, then
	// Relate(n1:n2) = {n2, ""}.
	//
	// reqVersion specifies the expected version of the group's membership
	// information. If this version is set and matches the Group's current
	// version, the response will indicate that fact but will otherwise be
	// empty.
	//
	// visitedGroups is the set of groups already visited in a particular
	// chain of Relate calls, and is used to detect the presence of
	// cycles. When a cycle is detected, it is treated just like any other
	// error, and the result is approximated.
	//
	// Relate also returns information about all the errors encountered that
	// resulted in approximations, if any.
	//
	// TODO(hpucha): scrub "Approximation" for preserving privacy. Flesh
	// versioning out further. Other args we may need: option to Get() the
	// membership set when allowed (to avoid an extra RPC), options related
	// to caching this information.
	Relate(_ *context.T, _ rpc.ServerCall, blessings map[string]struct{}, hint ApproximationType, reqVersion string, visitedGroups map[string]struct{}) (remainder map[string]struct{}, approximations []Approximation, version string, _ error)
	// Get returns all entries in the group.
	// TODO(sadovsky): Flesh out this API.
	Get(_ *context.T, _ rpc.ServerCall, req GetRequest, reqVersion string) (res GetResponse, version string, _ error)
}

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

// GroupReaderServerStub adds universal methods to GroupReaderServerStubMethods.
type GroupReaderServerStub interface {
	GroupReaderServerStubMethods
	// Describe the GroupReader interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implGroupReaderServerStub) Relate(ctx *context.T, call rpc.ServerCall, i0 map[string]struct{}, i1 ApproximationType, i2 string, i3 map[string]struct{}) (map[string]struct{}, []Approximation, string, error) {
	return s.impl.Relate(ctx, call, i0, i1, i2, i3)
}

func (s implGroupReaderServerStub) Get(ctx *context.T, call rpc.ServerCall, i0 GetRequest, i1 string) (GetResponse, string, error) {
	return s.impl.Get(ctx, call, i0, i1)
}

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

func (s implGroupReaderServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{GroupReaderDesc}
}

// GroupReaderDesc describes the GroupReader interface.
var GroupReaderDesc rpc.InterfaceDesc = descGroupReader

// descGroupReader hides the desc to keep godoc clean.
var descGroupReader = rpc.InterfaceDesc{
	Name:    "GroupReader",
	PkgPath: "v.io/v23/services/groups",
	Doc:     "// GroupReader implements methods to read or query a group's membership\n// information.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Relate",
			Doc:  "// Relate determines the relationships between the provided blessing\n// names and the members of the group.\n//\n// Given an input set of blessing names and a group defined by a set of\n// blessing patterns S, for each blessing name B in the input, Relate(B)\n// returns a set of \"remainders\" consisting of every blessing name B\"\n// such that there exists some B' for which B = B' B\" and B' is in S,\n// and \"\" if B is a member of S.\n//\n// For example, if a group is defined as S = {n1, n1:n2, n1:n2:n3}, then\n// Relate(n1:n2) = {n2, \"\"}.\n//\n// reqVersion specifies the expected version of the group's membership\n// information. If this version is set and matches the Group's current\n// version, the response will indicate that fact but will otherwise be\n// empty.\n//\n// visitedGroups is the set of groups already visited in a particular\n// chain of Relate calls, and is used to detect the presence of\n// cycles. When a cycle is detected, it is treated just like any other\n// error, and the result is approximated.\n//\n// Relate also returns information about all the errors encountered that\n// resulted in approximations, if any.\n//\n// TODO(hpucha): scrub \"Approximation\" for preserving privacy. Flesh\n// versioning out further. Other args we may need: option to Get() the\n// membership set when allowed (to avoid an extra RPC), options related\n// to caching this information.",
			InArgs: []rpc.ArgDesc{
				{"blessings", ``},     // map[string]struct{}
				{"hint", ``},          // ApproximationType
				{"reqVersion", ``},    // string
				{"visitedGroups", ``}, // map[string]struct{}
			},
			OutArgs: []rpc.ArgDesc{
				{"remainder", ``},      // map[string]struct{}
				{"approximations", ``}, // []Approximation
				{"version", ``},        // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Resolve"))},
		},
		{
			Name: "Get",
			Doc:  "// Get returns all entries in the group.\n// TODO(sadovsky): Flesh out this API.",
			InArgs: []rpc.ArgDesc{
				{"req", ``},        // GetRequest
				{"reqVersion", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"res", ``},     // GetResponse
				{"version", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// GroupClientMethods is the client interface
// containing Group methods.
//
// A group's version covers its Permissions as well as any other data stored in
// the group. Clients should treat versions as opaque identifiers. For both Get
// and Relate, if version is set and matches the Group's current version, the
// response will indicate that fact but will otherwise be empty.
type GroupClientMethods interface {
	// GroupReader implements methods to read or query a group's membership
	// information.
	GroupReaderClientMethods
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectClientMethods
	// Create creates a new group if it doesn't already exist.
	// If perms is nil, a default Permissions is used, providing Admin access to
	// the caller.
	// Create requires the caller to have Write permission at the GroupServer.
	Create(_ *context.T, perms access.Permissions, entries []BlessingPatternChunk, _ ...rpc.CallOpt) error
	// Delete deletes the group.
	// Permissions for all group-related methods except Create() are checked
	// against the Group object.
	Delete(_ *context.T, version string, _ ...rpc.CallOpt) error
	// Add adds an entry to the group.
	Add(_ *context.T, entry BlessingPatternChunk, version string, _ ...rpc.CallOpt) error
	// Remove removes an entry from the group.
	Remove(_ *context.T, entry BlessingPatternChunk, version string, _ ...rpc.CallOpt) error
}

// GroupClientStub adds universal methods to GroupClientMethods.
type GroupClientStub interface {
	GroupClientMethods
	rpc.UniversalServiceMethods
}

// GroupClient returns a client stub for Group.
func GroupClient(name string) GroupClientStub {
	return implGroupClientStub{name, GroupReaderClient(name), permissions.ObjectClient(name)}
}

type implGroupClientStub struct {
	name string

	GroupReaderClientStub
	permissions.ObjectClientStub
}

func (c implGroupClientStub) Create(ctx *context.T, i0 access.Permissions, i1 []BlessingPatternChunk, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Create", []interface{}{i0, i1}, nil, opts...)
	return
}

func (c implGroupClientStub) Delete(ctx *context.T, i0 string, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Delete", []interface{}{i0}, nil, opts...)
	return
}

func (c implGroupClientStub) Add(ctx *context.T, i0 BlessingPatternChunk, i1 string, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Add", []interface{}{i0, i1}, nil, opts...)
	return
}

func (c implGroupClientStub) Remove(ctx *context.T, i0 BlessingPatternChunk, i1 string, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Remove", []interface{}{i0, i1}, nil, opts...)
	return
}

// GroupServerMethods is the interface a server writer
// implements for Group.
//
// A group's version covers its Permissions as well as any other data stored in
// the group. Clients should treat versions as opaque identifiers. For both Get
// and Relate, if version is set and matches the Group's current version, the
// response will indicate that fact but will otherwise be empty.
type GroupServerMethods interface {
	// GroupReader implements methods to read or query a group's membership
	// information.
	GroupReaderServerMethods
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectServerMethods
	// Create creates a new group if it doesn't already exist.
	// If perms is nil, a default Permissions is used, providing Admin access to
	// the caller.
	// Create requires the caller to have Write permission at the GroupServer.
	Create(_ *context.T, _ rpc.ServerCall, perms access.Permissions, entries []BlessingPatternChunk) error
	// Delete deletes the group.
	// Permissions for all group-related methods except Create() are checked
	// against the Group object.
	Delete(_ *context.T, _ rpc.ServerCall, version string) error
	// Add adds an entry to the group.
	Add(_ *context.T, _ rpc.ServerCall, entry BlessingPatternChunk, version string) error
	// Remove removes an entry from the group.
	Remove(_ *context.T, _ rpc.ServerCall, entry BlessingPatternChunk, version string) error
}

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

// GroupServerStub adds universal methods to GroupServerStubMethods.
type GroupServerStub interface {
	GroupServerStubMethods
	// Describe the Group interfaces.
	Describe__() []rpc.InterfaceDesc
}

// GroupServer returns a server stub for Group.
// It converts an implementation of GroupServerMethods into
// an object that may be used by rpc.Server.
func GroupServer(impl GroupServerMethods) GroupServerStub {
	stub := implGroupServerStub{
		impl: impl,
		GroupReaderServerStub: GroupReaderServer(impl),
		ObjectServerStub:      permissions.ObjectServer(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 implGroupServerStub struct {
	impl GroupServerMethods
	GroupReaderServerStub
	permissions.ObjectServerStub
	gs *rpc.GlobState
}

func (s implGroupServerStub) Create(ctx *context.T, call rpc.ServerCall, i0 access.Permissions, i1 []BlessingPatternChunk) error {
	return s.impl.Create(ctx, call, i0, i1)
}

func (s implGroupServerStub) Delete(ctx *context.T, call rpc.ServerCall, i0 string) error {
	return s.impl.Delete(ctx, call, i0)
}

func (s implGroupServerStub) Add(ctx *context.T, call rpc.ServerCall, i0 BlessingPatternChunk, i1 string) error {
	return s.impl.Add(ctx, call, i0, i1)
}

func (s implGroupServerStub) Remove(ctx *context.T, call rpc.ServerCall, i0 BlessingPatternChunk, i1 string) error {
	return s.impl.Remove(ctx, call, i0, i1)
}

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

func (s implGroupServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{GroupDesc, GroupReaderDesc, permissions.ObjectDesc}
}

// GroupDesc describes the Group interface.
var GroupDesc rpc.InterfaceDesc = descGroup

// descGroup hides the desc to keep godoc clean.
var descGroup = rpc.InterfaceDesc{
	Name:    "Group",
	PkgPath: "v.io/v23/services/groups",
	Doc:     "// A group's version covers its Permissions as well as any other data stored in\n// the group. Clients should treat versions as opaque identifiers. For both Get\n// and Relate, if version is set and matches the Group's current version, the\n// response will indicate that fact but will otherwise be empty.",
	Embeds: []rpc.EmbedDesc{
		{"GroupReader", "v.io/v23/services/groups", "// GroupReader implements methods to read or query a group's membership\n// information."},
		{"Object", "v.io/v23/services/permissions", "// Object provides access control for Vanadium objects.\n//\n// Vanadium services implementing dynamic access control would typically embed\n// this interface and tag additional methods defined by the service with one of\n// Admin, Read, Write, Resolve etc. For example, the VDL definition of the\n// object would be:\n//\n//   package mypackage\n//\n//   import \"v.io/v23/security/access\"\n//   import \"v.io/v23/services/permissions\"\n//\n//   type MyObject interface {\n//     permissions.Object\n//     MyRead() (string, error) {access.Read}\n//     MyWrite(string) error    {access.Write}\n//   }\n//\n// If the set of pre-defined tags is insufficient, services may define their\n// own tag type and annotate all methods with this new type.\n//\n// Instead of embedding this Object interface, define SetPermissions and\n// GetPermissions in their own interface. Authorization policies will typically\n// respect annotations of a single type. For example, the VDL definition of an\n// object would be:\n//\n//  package mypackage\n//\n//  import \"v.io/v23/security/access\"\n//\n//  type MyTag string\n//\n//  const (\n//    Blue = MyTag(\"Blue\")\n//    Red  = MyTag(\"Red\")\n//  )\n//\n//  type MyObject interface {\n//    MyMethod() (string, error) {Blue}\n//\n//    // Allow clients to change access via the access.Object interface:\n//    SetPermissions(perms access.Permissions, version string) error         {Red}\n//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}\n//  }"},
	},
	Methods: []rpc.MethodDesc{
		{
			Name: "Create",
			Doc:  "// Create creates a new group if it doesn't already exist.\n// If perms is nil, a default Permissions is used, providing Admin access to\n// the caller.\n// Create requires the caller to have Write permission at the GroupServer.",
			InArgs: []rpc.ArgDesc{
				{"perms", ``},   // access.Permissions
				{"entries", ``}, // []BlessingPatternChunk
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Delete",
			Doc:  "// Delete deletes the group.\n// Permissions for all group-related methods except Create() are checked\n// against the Group object.",
			InArgs: []rpc.ArgDesc{
				{"version", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Add",
			Doc:  "// Add adds an entry to the group.",
			InArgs: []rpc.ArgDesc{
				{"entry", ``},   // BlessingPatternChunk
				{"version", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Remove",
			Doc:  "// Remove removes an entry from the group.",
			InArgs: []rpc.ArgDesc{
				{"entry", ``},   // BlessingPatternChunk
				{"version", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_string_1 *vdl.Type
	__VDLType_struct_2 *vdl.Type
	__VDLType_struct_3 *vdl.Type
	__VDLType_set_4    *vdl.Type
	__VDLType_enum_5   *vdl.Type
	__VDLType_struct_6 *vdl.Type
)

var __VDLInitCalled bool

// __VDLInit performs vdl initialization.  It is safe to call multiple times.
// If you have an init ordering issue, just insert the following line verbatim
// into your source files in this package, right after the "package foo" clause:
//
//    var _ = __VDLInit()
//
// The purpose of this function is to ensure that vdl initialization occurs in
// the right order, and very early in the init sequence.  In particular, vdl
// registration and package variable initialization needs to occur before
// functions like vdl.TypeOf will work properly.
//
// This function returns a dummy value, so that it can be used to initialize the
// first var in the file, to take advantage of Go's defined init order.
func __VDLInit() struct{} {
	if __VDLInitCalled {
		return struct{}{}
	}
	__VDLInitCalled = true

	// Register types.
	vdl.Register((*BlessingPatternChunk)(nil))
	vdl.Register((*GetRequest)(nil))
	vdl.Register((*GetResponse)(nil))
	vdl.Register((*ApproximationType)(nil))
	vdl.Register((*Approximation)(nil))

	// Initialize type definitions.
	__VDLType_string_1 = vdl.TypeOf((*BlessingPatternChunk)(nil))
	__VDLType_struct_2 = vdl.TypeOf((*GetRequest)(nil)).Elem()
	__VDLType_struct_3 = vdl.TypeOf((*GetResponse)(nil)).Elem()
	__VDLType_set_4 = vdl.TypeOf((*map[BlessingPatternChunk]struct{})(nil))
	__VDLType_enum_5 = vdl.TypeOf((*ApproximationType)(nil))
	__VDLType_struct_6 = vdl.TypeOf((*Approximation)(nil)).Elem()

	// Set error format strings.
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNoBlessings.ID), "{1:}{2:} No blessings recognized; cannot create group Permissions")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrExcessiveContention.ID), "{1:}{2:} Gave up after encountering excessive contention; try again later")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrCycleFound.ID), "{1:}{2:} Found cycle in group definitions{:_}")

	return struct{}{}
}
