// 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: rps

// Package rps defines interfaces for playing the game Rock-Paper-Scissors.  It
// is an example of a simple Vanadium service.
//
// http://en.wikipedia.org/wiki/Rock-paper-scissors
//
// There are three different roles in the game:
//
// 1. Judge: A judge enforces the rules of the game and decides who the winner
// is. At the end of the game, the judge reports the final score to all the
// score keepers.
//
// 2. Player: A player can ask a judge to start a new game, it can challenge
// another player, and it can play a game.
//
// 3. ScoreKeeper: A score keeper receives the final score for a game after it
// ended.
package rps

import (
	"fmt"
	"io"
	"time"
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/security/access"
	"v.io/v23/vdl"
	vdltime "v.io/v23/vdlroot/time"
)

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

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

// A GameId is used to uniquely identify a game within one Judge.
type GameId struct {
	Id string
}

func (GameId) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/examples/rps.GameId"`
}) {
}

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

func (x GameId) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	if x.Id != "" {
		if err := enc.NextFieldValueString(0, vdl.StringType, x.Id); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *GameId) VDLRead(dec vdl.Decoder) error {
	*x = GameId{}
	if err := dec.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_1 {
			index = __VDLType_struct_1.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Id = value
			}
		}
	}
}

type GameTypeTag byte

func (GameTypeTag) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/examples/rps.GameTypeTag"`
}) {
}

func (x GameTypeTag) VDLIsZero() bool {
	return x == 0
}

func (x GameTypeTag) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueUint(__VDLType_byte_2, uint64(x)); err != nil {
		return err
	}
	return nil
}

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

// GameOptions specifies the parameters of a game.
type GameOptions struct {
	NumRounds int32       // The number of rounds that a player must win to win the game.
	GameType  GameTypeTag // The type of game to play: Classic or LizardSpock.
}

func (GameOptions) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/examples/rps.GameOptions"`
}) {
}

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

func (x GameOptions) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_3); err != nil {
		return err
	}
	if x.NumRounds != 0 {
		if err := enc.NextFieldValueInt(0, vdl.Int32Type, int64(x.NumRounds)); err != nil {
			return err
		}
	}
	if x.GameType != 0 {
		if err := enc.NextFieldValueUint(1, __VDLType_byte_2, uint64(x.GameType)); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *GameOptions) VDLRead(dec vdl.Decoder) error {
	*x = GameOptions{}
	if err := dec.StartValue(__VDLType_struct_3); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_3 {
			index = __VDLType_struct_3.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueInt(32); {
			case err != nil:
				return err
			default:
				x.NumRounds = int32(value)
			}
		case 1:
			switch value, err := dec.ReadValueUint(8); {
			case err != nil:
				return err
			default:
				x.GameType = GameTypeTag(value)
			}
		}
	}
}

// TODO(toddw): Replace Unused with the unnamed empty struct{}.
type Unused struct {
}

func (Unused) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/examples/rps.Unused"`
}) {
}

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

func (x Unused) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_4); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Unused) VDLRead(dec vdl.Decoder) error {
	*x = Unused{}
	if err := dec.StartValue(__VDLType_struct_4); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_4 {
			index = __VDLType_struct_4.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		}
	}
}

type (
	// PlayerAction represents any single field of the PlayerAction union type.
	PlayerAction interface {
		// Index returns the field index.
		Index() int
		// Interface returns the field value as an interface.
		Interface() interface{}
		// Name returns the field name.
		Name() string
		// __VDLReflect describes the PlayerAction union type.
		__VDLReflect(__PlayerActionReflect)
		VDLIsZero() bool
		VDLWrite(vdl.Encoder) error
	}
	// PlayerActionMove represents field Move of the PlayerAction union type.
	PlayerActionMove struct{ Value string } // The move that the player wants to make.
	// PlayerActionQuit represents field Quit of the PlayerAction union type.
	PlayerActionQuit struct{ Value Unused } // Indicates that the player is quitting the game.
	// __PlayerActionReflect describes the PlayerAction union type.
	__PlayerActionReflect struct {
		Name  string `vdl:"v.io/x/ref/examples/rps.PlayerAction"`
		Type  PlayerAction
		Union struct {
			Move PlayerActionMove
			Quit PlayerActionQuit
		}
	}
)

func (x PlayerActionMove) Index() int                         { return 0 }
func (x PlayerActionMove) Interface() interface{}             { return x.Value }
func (x PlayerActionMove) Name() string                       { return "Move" }
func (x PlayerActionMove) __VDLReflect(__PlayerActionReflect) {}

func (x PlayerActionQuit) Index() int                         { return 1 }
func (x PlayerActionQuit) Interface() interface{}             { return x.Value }
func (x PlayerActionQuit) Name() string                       { return "Quit" }
func (x PlayerActionQuit) __VDLReflect(__PlayerActionReflect) {}

func (x PlayerActionMove) VDLIsZero() bool {
	return x.Value == ""
}

func (x PlayerActionQuit) VDLIsZero() bool {
	return false
}

func (x PlayerActionMove) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_5); err != nil {
		return err
	}
	if err := enc.NextFieldValueString(0, vdl.StringType, x.Value); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x PlayerActionQuit) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_5); err != nil {
		return err
	}
	if err := enc.NextField(1); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func VDLReadPlayerAction(dec vdl.Decoder, x *PlayerAction) error {
	if err := dec.StartValue(__VDLType_union_5); err != nil {
		return err
	}
	decType := dec.Type()
	index, err := dec.NextField()
	switch {
	case err != nil:
		return err
	case index == -1:
		return fmt.Errorf("missing field in union %T, from %v", x, decType)
	}
	if decType != __VDLType_union_5 {
		name := decType.Field(index).Name
		index = __VDLType_union_5.FieldIndexByName(name)
		if index == -1 {
			return fmt.Errorf("field %q not in union %T, from %v", name, x, decType)
		}
	}
	switch index {
	case 0:
		var field PlayerActionMove
		switch value, err := dec.ReadValueString(); {
		case err != nil:
			return err
		default:
			field.Value = value
		}
		*x = field
	case 1:
		var field PlayerActionQuit
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	}
	switch index, err := dec.NextField(); {
	case err != nil:
		return err
	case index != -1:
		return fmt.Errorf("extra field %d in union %T, from %v", index, x, dec.Type())
	}
	return dec.FinishValue()
}

type PlayersMoves [2]string

func (PlayersMoves) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/examples/rps.PlayersMoves"`
}) {
}

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

func (x PlayersMoves) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_array_6); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntryValueString(vdl.StringType, elem); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *PlayersMoves) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(__VDLType_array_6); err != nil {
		return err
	}
	for index := 0; index < 2; index++ {
		switch done, elem, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			return fmt.Errorf("short array, got len %d < 2 %T)", index, *x)
		default:
			x[index] = elem
		}
	}
	switch done, err := dec.NextEntry(); {
	case err != nil:
		return err
	case !done:
		return fmt.Errorf("long array, got len > 2 %T", *x)
	}
	return dec.FinishValue()
}

// WinnerTag is a type used to indicate whether a round or a game was a draw,
// was won by player 1 or was won by player 2.
type WinnerTag byte

func (WinnerTag) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/examples/rps.WinnerTag"`
}) {
}

func (x WinnerTag) VDLIsZero() bool {
	return x == 0
}

func (x WinnerTag) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueUint(__VDLType_byte_7, uint64(x)); err != nil {
		return err
	}
	return nil
}

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

// Round represents the state of a round.
type Round struct {
	Moves     PlayersMoves // Each player's move.
	Comment   string       // A text comment from judge about the round.
	Winner    WinnerTag    // Who won the round.
	StartTime time.Time    // The time at which the round started.
	EndTime   time.Time    // The time at which the round ended.
}

func (Round) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/examples/rps.Round"`
}) {
}

func (x Round) VDLIsZero() bool {
	if x.Moves != (PlayersMoves{}) {
		return false
	}
	if x.Comment != "" {
		return false
	}
	if x.Winner != 0 {
		return false
	}
	if !x.StartTime.IsZero() {
		return false
	}
	if !x.EndTime.IsZero() {
		return false
	}
	return true
}

func (x Round) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_8); err != nil {
		return err
	}
	if x.Moves != (PlayersMoves{}) {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := x.Moves.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Comment != "" {
		if err := enc.NextFieldValueString(1, vdl.StringType, x.Comment); err != nil {
			return err
		}
	}
	if x.Winner != 0 {
		if err := enc.NextFieldValueUint(2, __VDLType_byte_7, uint64(x.Winner)); err != nil {
			return err
		}
	}
	if !x.StartTime.IsZero() {
		if err := enc.NextField(3); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.StartTime); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if !x.EndTime.IsZero() {
		if err := enc.NextField(4); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.EndTime); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Round) VDLRead(dec vdl.Decoder) error {
	*x = Round{}
	if err := dec.StartValue(__VDLType_struct_8); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_8 {
			index = __VDLType_struct_8.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := x.Moves.VDLRead(dec); err != nil {
				return err
			}
		case 1:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Comment = value
			}
		case 2:
			switch value, err := dec.ReadValueUint(8); {
			case err != nil:
				return err
			default:
				x.Winner = WinnerTag(value)
			}
		case 3:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.StartTime); err != nil {
				return err
			}
		case 4:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.EndTime); err != nil {
				return err
			}
		}
	}
}

type ScoreCard struct {
	Opts      GameOptions // The game options.
	Judge     string      // The name of the judge.
	Players   []string    // The name of the players.
	Rounds    []Round     // The outcome of each round.
	StartTime time.Time   // The time at which the game started.
	EndTime   time.Time   // The time at which the game ended.
	Winner    WinnerTag   // Who won the game.
}

func (ScoreCard) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/examples/rps.ScoreCard"`
}) {
}

func (x ScoreCard) VDLIsZero() bool {
	if x.Opts != (GameOptions{}) {
		return false
	}
	if x.Judge != "" {
		return false
	}
	if len(x.Players) != 0 {
		return false
	}
	if len(x.Rounds) != 0 {
		return false
	}
	if !x.StartTime.IsZero() {
		return false
	}
	if !x.EndTime.IsZero() {
		return false
	}
	if x.Winner != 0 {
		return false
	}
	return true
}

func (x ScoreCard) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_10); err != nil {
		return err
	}
	if x.Opts != (GameOptions{}) {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := x.Opts.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Judge != "" {
		if err := enc.NextFieldValueString(1, vdl.StringType, x.Judge); err != nil {
			return err
		}
	}
	if len(x.Players) != 0 {
		if err := enc.NextField(2); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Players); err != nil {
			return err
		}
	}
	if len(x.Rounds) != 0 {
		if err := enc.NextField(3); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_2(enc, x.Rounds); err != nil {
			return err
		}
	}
	if !x.StartTime.IsZero() {
		if err := enc.NextField(4); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.StartTime); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if !x.EndTime.IsZero() {
		if err := enc.NextField(5); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.EndTime); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Winner != 0 {
		if err := enc.NextFieldValueUint(6, __VDLType_byte_7, uint64(x.Winner)); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_1(enc vdl.Encoder, x []string) error {
	if err := enc.StartValue(__VDLType_list_11); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntryValueString(vdl.StringType, elem); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_2(enc vdl.Encoder, x []Round) error {
	if err := enc.StartValue(__VDLType_list_12); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := elem.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ScoreCard) VDLRead(dec vdl.Decoder) error {
	*x = ScoreCard{}
	if err := dec.StartValue(__VDLType_struct_10); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_10 {
			index = __VDLType_struct_10.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := x.Opts.VDLRead(dec); err != nil {
				return err
			}
		case 1:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Judge = value
			}
		case 2:
			if err := __VDLReadAnon_list_1(dec, &x.Players); err != nil {
				return err
			}
		case 3:
			if err := __VDLReadAnon_list_2(dec, &x.Rounds); err != nil {
				return err
			}
		case 4:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.StartTime); err != nil {
				return err
			}
		case 5:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.EndTime); err != nil {
				return err
			}
		case 6:
			switch value, err := dec.ReadValueUint(8); {
			case err != nil:
				return err
			default:
				x.Winner = WinnerTag(value)
			}
		}
	}
}

func __VDLReadAnon_list_1(dec vdl.Decoder, x *[]string) error {
	if err := dec.StartValue(__VDLType_list_11); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]string, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, elem, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			*x = append(*x, elem)
		}
	}
}

func __VDLReadAnon_list_2(dec vdl.Decoder, x *[]Round) error {
	if err := dec.StartValue(__VDLType_list_12); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]Round, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			var elem Round
			if err := elem.VDLRead(dec); err != nil {
				return err
			}
			*x = append(*x, elem)
		}
	}
}

type (
	// JudgeAction represents any single field of the JudgeAction union type.
	JudgeAction interface {
		// Index returns the field index.
		Index() int
		// Interface returns the field value as an interface.
		Interface() interface{}
		// Name returns the field name.
		Name() string
		// __VDLReflect describes the JudgeAction union type.
		__VDLReflect(__JudgeActionReflect)
		VDLIsZero() bool
		VDLWrite(vdl.Encoder) error
	}
	// JudgeActionPlayerNum represents field PlayerNum of the JudgeAction union type.
	JudgeActionPlayerNum struct{ Value int32 } // The player's number.
	// JudgeActionOpponentName represents field OpponentName of the JudgeAction union type.
	JudgeActionOpponentName struct{ Value string } // The name of the opponent.
	// JudgeActionMoveOptions represents field MoveOptions of the JudgeAction union type.
	JudgeActionMoveOptions struct{ Value []string } // A list of allowed moves that the player must choose from.
	// JudgeActionRoundResult represents field RoundResult of the JudgeAction union type.
	JudgeActionRoundResult struct{ Value Round } // The result of the previous round.
	// JudgeActionScore represents field Score of the JudgeAction union type.
	JudgeActionScore struct{ Value ScoreCard } // The result of the game.
	// __JudgeActionReflect describes the JudgeAction union type.
	__JudgeActionReflect struct {
		Name  string `vdl:"v.io/x/ref/examples/rps.JudgeAction"`
		Type  JudgeAction
		Union struct {
			PlayerNum    JudgeActionPlayerNum
			OpponentName JudgeActionOpponentName
			MoveOptions  JudgeActionMoveOptions
			RoundResult  JudgeActionRoundResult
			Score        JudgeActionScore
		}
	}
)

func (x JudgeActionPlayerNum) Index() int                        { return 0 }
func (x JudgeActionPlayerNum) Interface() interface{}            { return x.Value }
func (x JudgeActionPlayerNum) Name() string                      { return "PlayerNum" }
func (x JudgeActionPlayerNum) __VDLReflect(__JudgeActionReflect) {}

func (x JudgeActionOpponentName) Index() int                        { return 1 }
func (x JudgeActionOpponentName) Interface() interface{}            { return x.Value }
func (x JudgeActionOpponentName) Name() string                      { return "OpponentName" }
func (x JudgeActionOpponentName) __VDLReflect(__JudgeActionReflect) {}

func (x JudgeActionMoveOptions) Index() int                        { return 2 }
func (x JudgeActionMoveOptions) Interface() interface{}            { return x.Value }
func (x JudgeActionMoveOptions) Name() string                      { return "MoveOptions" }
func (x JudgeActionMoveOptions) __VDLReflect(__JudgeActionReflect) {}

func (x JudgeActionRoundResult) Index() int                        { return 3 }
func (x JudgeActionRoundResult) Interface() interface{}            { return x.Value }
func (x JudgeActionRoundResult) Name() string                      { return "RoundResult" }
func (x JudgeActionRoundResult) __VDLReflect(__JudgeActionReflect) {}

func (x JudgeActionScore) Index() int                        { return 4 }
func (x JudgeActionScore) Interface() interface{}            { return x.Value }
func (x JudgeActionScore) Name() string                      { return "Score" }
func (x JudgeActionScore) __VDLReflect(__JudgeActionReflect) {}

func (x JudgeActionPlayerNum) VDLIsZero() bool {
	return x.Value == 0
}

func (x JudgeActionOpponentName) VDLIsZero() bool {
	return false
}

func (x JudgeActionMoveOptions) VDLIsZero() bool {
	return false
}

func (x JudgeActionRoundResult) VDLIsZero() bool {
	return false
}

func (x JudgeActionScore) VDLIsZero() bool {
	return false
}

func (x JudgeActionPlayerNum) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_13); err != nil {
		return err
	}
	if err := enc.NextFieldValueInt(0, vdl.Int32Type, int64(x.Value)); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x JudgeActionOpponentName) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_13); err != nil {
		return err
	}
	if err := enc.NextFieldValueString(1, vdl.StringType, x.Value); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x JudgeActionMoveOptions) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_13); err != nil {
		return err
	}
	if err := enc.NextField(2); err != nil {
		return err
	}
	if err := __VDLWriteAnon_list_1(enc, x.Value); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x JudgeActionRoundResult) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_13); err != nil {
		return err
	}
	if err := enc.NextField(3); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x JudgeActionScore) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_13); err != nil {
		return err
	}
	if err := enc.NextField(4); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func VDLReadJudgeAction(dec vdl.Decoder, x *JudgeAction) error {
	if err := dec.StartValue(__VDLType_union_13); err != nil {
		return err
	}
	decType := dec.Type()
	index, err := dec.NextField()
	switch {
	case err != nil:
		return err
	case index == -1:
		return fmt.Errorf("missing field in union %T, from %v", x, decType)
	}
	if decType != __VDLType_union_13 {
		name := decType.Field(index).Name
		index = __VDLType_union_13.FieldIndexByName(name)
		if index == -1 {
			return fmt.Errorf("field %q not in union %T, from %v", name, x, decType)
		}
	}
	switch index {
	case 0:
		var field JudgeActionPlayerNum
		switch value, err := dec.ReadValueInt(32); {
		case err != nil:
			return err
		default:
			field.Value = int32(value)
		}
		*x = field
	case 1:
		var field JudgeActionOpponentName
		switch value, err := dec.ReadValueString(); {
		case err != nil:
			return err
		default:
			field.Value = value
		}
		*x = field
	case 2:
		var field JudgeActionMoveOptions
		if err := __VDLReadAnon_list_1(dec, &field.Value); err != nil {
			return err
		}
		*x = field
	case 3:
		var field JudgeActionRoundResult
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case 4:
		var field JudgeActionScore
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	}
	switch index, err := dec.NextField(); {
	case err != nil:
		return err
	case index != -1:
		return fmt.Errorf("extra field %d in union %T, from %v", index, x, dec.Type())
	}
	return dec.FinishValue()
}

// PlayResult is the value returned by the Play method. It indicates the outcome of the game.
type PlayResult struct {
	YouWon bool // True if the player receiving the result won the game.
}

func (PlayResult) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/examples/rps.PlayResult"`
}) {
}

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

func (x PlayResult) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_14); err != nil {
		return err
	}
	if x.YouWon {
		if err := enc.NextFieldValueBool(0, vdl.BoolType, x.YouWon); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *PlayResult) VDLRead(dec vdl.Decoder) error {
	*x = PlayResult{}
	if err := dec.StartValue(__VDLType_struct_14); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_14 {
			index = __VDLType_struct_14.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.YouWon = value
			}
		}
	}
}

//////////////////////////////////////////////////
// Const definitions

const Classic = GameTypeTag(0)     // Rock-Paper-Scissors
const LizardSpock = GameTypeTag(1) // Rock-Paper-Scissors-Lizard-Spock
const Draw = WinnerTag(0)
const Player1 = WinnerTag(1)
const Player2 = WinnerTag(2)

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

// JudgeClientMethods is the client interface
// containing Judge methods.
type JudgeClientMethods interface {
	// CreateGame creates a new game with the given game options and returns a game
	// identifier that can be used by the players to join the game.
	CreateGame(_ *context.T, Opts GameOptions, _ ...rpc.CallOpt) (GameId, error)
	// Play lets a player join an existing game and play.
	Play(_ *context.T, Id GameId, _ ...rpc.CallOpt) (JudgePlayClientCall, error)
}

// JudgeClientStub adds universal methods to JudgeClientMethods.
type JudgeClientStub interface {
	JudgeClientMethods
	rpc.UniversalServiceMethods
}

// JudgeClient returns a client stub for Judge.
func JudgeClient(name string) JudgeClientStub {
	return implJudgeClientStub{name}
}

type implJudgeClientStub struct {
	name string
}

func (c implJudgeClientStub) CreateGame(ctx *context.T, i0 GameOptions, opts ...rpc.CallOpt) (o0 GameId, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "CreateGame", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implJudgeClientStub) Play(ctx *context.T, i0 GameId, opts ...rpc.CallOpt) (ocall JudgePlayClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "Play", []interface{}{i0}, opts...); err != nil {
		return
	}
	ocall = &implJudgePlayClientCall{ClientCall: call}
	return
}

// JudgePlayClientStream is the client stream for Judge.Play.
type JudgePlayClientStream interface {
	// RecvStream returns the receiver side of the Judge.Play client stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() JudgeAction
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Judge.Play client stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors
		// encountered while sending, or if Send is called after Close or
		// the stream has been canceled.  Blocks if there is no buffer
		// space; will unblock when buffer space is available or after
		// the stream has been canceled.
		Send(item PlayerAction) error
		// Close indicates to the server that no more items will be sent;
		// server Recv calls will receive io.EOF after all sent items.
		// This is an optional call - e.g. a client might call Close if it
		// needs to continue receiving items from the server after it's
		// done sending.  Returns errors encountered while closing, or if
		// Close is called after the stream has been canceled.  Like Send,
		// blocks if there is no buffer space available.
		Close() error
	}
}

// JudgePlayClientCall represents the call returned from Judge.Play.
type JudgePlayClientCall interface {
	JudgePlayClientStream
	// Finish performs the equivalent of SendStream().Close, then blocks until
	// the server is done, and returns the positional return values for the call.
	//
	// Finish returns immediately if the call has been canceled; depending on the
	// timing the output could either be an error signaling cancelation, or the
	// valid positional return values from the server.
	//
	// Calling Finish is mandatory for releasing stream resources, unless the call
	// has been canceled or any of the other methods return an error.  Finish should
	// be called at most once.
	Finish() (PlayResult, error)
}

type implJudgePlayClientCall struct {
	rpc.ClientCall
	valRecv JudgeAction
	errRecv error
}

func (c *implJudgePlayClientCall) RecvStream() interface {
	Advance() bool
	Value() JudgeAction
	Err() error
} {
	return implJudgePlayClientCallRecv{c}
}

type implJudgePlayClientCallRecv struct {
	c *implJudgePlayClientCall
}

func (c implJudgePlayClientCallRecv) Advance() bool {
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implJudgePlayClientCallRecv) Value() JudgeAction {
	return c.c.valRecv
}
func (c implJudgePlayClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implJudgePlayClientCall) SendStream() interface {
	Send(item PlayerAction) error
	Close() error
} {
	return implJudgePlayClientCallSend{c}
}

type implJudgePlayClientCallSend struct {
	c *implJudgePlayClientCall
}

func (c implJudgePlayClientCallSend) Send(item PlayerAction) error {
	return c.c.Send(item)
}
func (c implJudgePlayClientCallSend) Close() error {
	return c.c.CloseSend()
}
func (c *implJudgePlayClientCall) Finish() (o0 PlayResult, err error) {
	err = c.ClientCall.Finish(&o0)
	return
}

// JudgeServerMethods is the interface a server writer
// implements for Judge.
type JudgeServerMethods interface {
	// CreateGame creates a new game with the given game options and returns a game
	// identifier that can be used by the players to join the game.
	CreateGame(_ *context.T, _ rpc.ServerCall, Opts GameOptions) (GameId, error)
	// Play lets a player join an existing game and play.
	Play(_ *context.T, _ JudgePlayServerCall, Id GameId) (PlayResult, error)
}

// JudgeServerStubMethods is the server interface containing
// Judge methods, as expected by rpc.Server.
// The only difference between this interface and JudgeServerMethods
// is the streaming methods.
type JudgeServerStubMethods interface {
	// CreateGame creates a new game with the given game options and returns a game
	// identifier that can be used by the players to join the game.
	CreateGame(_ *context.T, _ rpc.ServerCall, Opts GameOptions) (GameId, error)
	// Play lets a player join an existing game and play.
	Play(_ *context.T, _ *JudgePlayServerCallStub, Id GameId) (PlayResult, error)
}

// JudgeServerStub adds universal methods to JudgeServerStubMethods.
type JudgeServerStub interface {
	JudgeServerStubMethods
	// Describe the Judge interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implJudgeServerStub) CreateGame(ctx *context.T, call rpc.ServerCall, i0 GameOptions) (GameId, error) {
	return s.impl.CreateGame(ctx, call, i0)
}

func (s implJudgeServerStub) Play(ctx *context.T, call *JudgePlayServerCallStub, i0 GameId) (PlayResult, error) {
	return s.impl.Play(ctx, call, i0)
}

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

func (s implJudgeServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{JudgeDesc}
}

// JudgeDesc describes the Judge interface.
var JudgeDesc rpc.InterfaceDesc = descJudge

// descJudge hides the desc to keep godoc clean.
var descJudge = rpc.InterfaceDesc{
	Name:    "Judge",
	PkgPath: "v.io/x/ref/examples/rps",
	Methods: []rpc.MethodDesc{
		{
			Name: "CreateGame",
			Doc:  "// CreateGame creates a new game with the given game options and returns a game\n// identifier that can be used by the players to join the game.",
			InArgs: []rpc.ArgDesc{
				{"Opts", ``}, // GameOptions
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // GameId
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Play",
			Doc:  "// Play lets a player join an existing game and play.",
			InArgs: []rpc.ArgDesc{
				{"Id", ``}, // GameId
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // PlayResult
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

// JudgePlayServerStream is the server stream for Judge.Play.
type JudgePlayServerStream interface {
	// RecvStream returns the receiver side of the Judge.Play server stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() PlayerAction
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Judge.Play server stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors encountered
		// while sending.  Blocks if there is no buffer space; will unblock when
		// buffer space is available.
		Send(item JudgeAction) error
	}
}

// JudgePlayServerCall represents the context passed to Judge.Play.
type JudgePlayServerCall interface {
	rpc.ServerCall
	JudgePlayServerStream
}

// JudgePlayServerCallStub is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements JudgePlayServerCall.
type JudgePlayServerCallStub struct {
	rpc.StreamServerCall
	valRecv PlayerAction
	errRecv error
}

// Init initializes JudgePlayServerCallStub from rpc.StreamServerCall.
func (s *JudgePlayServerCallStub) Init(call rpc.StreamServerCall) {
	s.StreamServerCall = call
}

// RecvStream returns the receiver side of the Judge.Play server stream.
func (s *JudgePlayServerCallStub) RecvStream() interface {
	Advance() bool
	Value() PlayerAction
	Err() error
} {
	return implJudgePlayServerCallRecv{s}
}

type implJudgePlayServerCallRecv struct {
	s *JudgePlayServerCallStub
}

func (s implJudgePlayServerCallRecv) Advance() bool {
	s.s.errRecv = s.s.Recv(&s.s.valRecv)
	return s.s.errRecv == nil
}
func (s implJudgePlayServerCallRecv) Value() PlayerAction {
	return s.s.valRecv
}
func (s implJudgePlayServerCallRecv) Err() error {
	if s.s.errRecv == io.EOF {
		return nil
	}
	return s.s.errRecv
}

// SendStream returns the send side of the Judge.Play server stream.
func (s *JudgePlayServerCallStub) SendStream() interface {
	Send(item JudgeAction) error
} {
	return implJudgePlayServerCallSend{s}
}

type implJudgePlayServerCallSend struct {
	s *JudgePlayServerCallStub
}

func (s implJudgePlayServerCallSend) Send(item JudgeAction) error {
	return s.s.Send(item)
}

// PlayerClientMethods is the client interface
// containing Player methods.
//
// Player can receive challenges from other players.
type PlayerClientMethods interface {
	// Challenge is used by other players to challenge this player to a game. If
	// the challenge is accepted, the method returns nil.
	Challenge(_ *context.T, Address string, Id GameId, Opts GameOptions, _ ...rpc.CallOpt) error
}

// PlayerClientStub adds universal methods to PlayerClientMethods.
type PlayerClientStub interface {
	PlayerClientMethods
	rpc.UniversalServiceMethods
}

// PlayerClient returns a client stub for Player.
func PlayerClient(name string) PlayerClientStub {
	return implPlayerClientStub{name}
}

type implPlayerClientStub struct {
	name string
}

func (c implPlayerClientStub) Challenge(ctx *context.T, i0 string, i1 GameId, i2 GameOptions, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Challenge", []interface{}{i0, i1, i2}, nil, opts...)
	return
}

// PlayerServerMethods is the interface a server writer
// implements for Player.
//
// Player can receive challenges from other players.
type PlayerServerMethods interface {
	// Challenge is used by other players to challenge this player to a game. If
	// the challenge is accepted, the method returns nil.
	Challenge(_ *context.T, _ rpc.ServerCall, Address string, Id GameId, Opts GameOptions) error
}

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

// PlayerServerStub adds universal methods to PlayerServerStubMethods.
type PlayerServerStub interface {
	PlayerServerStubMethods
	// Describe the Player interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implPlayerServerStub) Challenge(ctx *context.T, call rpc.ServerCall, i0 string, i1 GameId, i2 GameOptions) error {
	return s.impl.Challenge(ctx, call, i0, i1, i2)
}

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

func (s implPlayerServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{PlayerDesc}
}

// PlayerDesc describes the Player interface.
var PlayerDesc rpc.InterfaceDesc = descPlayer

// descPlayer hides the desc to keep godoc clean.
var descPlayer = rpc.InterfaceDesc{
	Name:    "Player",
	PkgPath: "v.io/x/ref/examples/rps",
	Doc:     "// Player can receive challenges from other players.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Challenge",
			Doc:  "// Challenge is used by other players to challenge this player to a game. If\n// the challenge is accepted, the method returns nil.",
			InArgs: []rpc.ArgDesc{
				{"Address", ``}, // string
				{"Id", ``},      // GameId
				{"Opts", ``},    // GameOptions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

// ScoreKeeperClientMethods is the client interface
// containing ScoreKeeper methods.
//
// ScoreKeeper receives the outcome of games from Judges.
type ScoreKeeperClientMethods interface {
	Record(_ *context.T, Score ScoreCard, _ ...rpc.CallOpt) error
}

// ScoreKeeperClientStub adds universal methods to ScoreKeeperClientMethods.
type ScoreKeeperClientStub interface {
	ScoreKeeperClientMethods
	rpc.UniversalServiceMethods
}

// ScoreKeeperClient returns a client stub for ScoreKeeper.
func ScoreKeeperClient(name string) ScoreKeeperClientStub {
	return implScoreKeeperClientStub{name}
}

type implScoreKeeperClientStub struct {
	name string
}

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

// ScoreKeeperServerMethods is the interface a server writer
// implements for ScoreKeeper.
//
// ScoreKeeper receives the outcome of games from Judges.
type ScoreKeeperServerMethods interface {
	Record(_ *context.T, _ rpc.ServerCall, Score ScoreCard) error
}

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

// ScoreKeeperServerStub adds universal methods to ScoreKeeperServerStubMethods.
type ScoreKeeperServerStub interface {
	ScoreKeeperServerStubMethods
	// Describe the ScoreKeeper interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implScoreKeeperServerStub) Record(ctx *context.T, call rpc.ServerCall, i0 ScoreCard) error {
	return s.impl.Record(ctx, call, i0)
}

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

func (s implScoreKeeperServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{ScoreKeeperDesc}
}

// ScoreKeeperDesc describes the ScoreKeeper interface.
var ScoreKeeperDesc rpc.InterfaceDesc = descScoreKeeper

// descScoreKeeper hides the desc to keep godoc clean.
var descScoreKeeper = rpc.InterfaceDesc{
	Name:    "ScoreKeeper",
	PkgPath: "v.io/x/ref/examples/rps",
	Doc:     "// ScoreKeeper receives the outcome of games from Judges.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Record",
			InArgs: []rpc.ArgDesc{
				{"Score", ``}, // ScoreCard
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

// RockPaperScissorsClientMethods is the client interface
// containing RockPaperScissors methods.
type RockPaperScissorsClientMethods interface {
	JudgeClientMethods
	// Player can receive challenges from other players.
	PlayerClientMethods
	// ScoreKeeper receives the outcome of games from Judges.
	ScoreKeeperClientMethods
}

// RockPaperScissorsClientStub adds universal methods to RockPaperScissorsClientMethods.
type RockPaperScissorsClientStub interface {
	RockPaperScissorsClientMethods
	rpc.UniversalServiceMethods
}

// RockPaperScissorsClient returns a client stub for RockPaperScissors.
func RockPaperScissorsClient(name string) RockPaperScissorsClientStub {
	return implRockPaperScissorsClientStub{name, JudgeClient(name), PlayerClient(name), ScoreKeeperClient(name)}
}

type implRockPaperScissorsClientStub struct {
	name string

	JudgeClientStub
	PlayerClientStub
	ScoreKeeperClientStub
}

// RockPaperScissorsServerMethods is the interface a server writer
// implements for RockPaperScissors.
type RockPaperScissorsServerMethods interface {
	JudgeServerMethods
	// Player can receive challenges from other players.
	PlayerServerMethods
	// ScoreKeeper receives the outcome of games from Judges.
	ScoreKeeperServerMethods
}

// RockPaperScissorsServerStubMethods is the server interface containing
// RockPaperScissors methods, as expected by rpc.Server.
// The only difference between this interface and RockPaperScissorsServerMethods
// is the streaming methods.
type RockPaperScissorsServerStubMethods interface {
	JudgeServerStubMethods
	// Player can receive challenges from other players.
	PlayerServerStubMethods
	// ScoreKeeper receives the outcome of games from Judges.
	ScoreKeeperServerStubMethods
}

// RockPaperScissorsServerStub adds universal methods to RockPaperScissorsServerStubMethods.
type RockPaperScissorsServerStub interface {
	RockPaperScissorsServerStubMethods
	// Describe the RockPaperScissors interfaces.
	Describe__() []rpc.InterfaceDesc
}

// RockPaperScissorsServer returns a server stub for RockPaperScissors.
// It converts an implementation of RockPaperScissorsServerMethods into
// an object that may be used by rpc.Server.
func RockPaperScissorsServer(impl RockPaperScissorsServerMethods) RockPaperScissorsServerStub {
	stub := implRockPaperScissorsServerStub{
		impl:                  impl,
		JudgeServerStub:       JudgeServer(impl),
		PlayerServerStub:      PlayerServer(impl),
		ScoreKeeperServerStub: ScoreKeeperServer(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 implRockPaperScissorsServerStub struct {
	impl RockPaperScissorsServerMethods
	JudgeServerStub
	PlayerServerStub
	ScoreKeeperServerStub
	gs *rpc.GlobState
}

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

func (s implRockPaperScissorsServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{RockPaperScissorsDesc, JudgeDesc, PlayerDesc, ScoreKeeperDesc}
}

// RockPaperScissorsDesc describes the RockPaperScissors interface.
var RockPaperScissorsDesc rpc.InterfaceDesc = descRockPaperScissors

// descRockPaperScissors hides the desc to keep godoc clean.
var descRockPaperScissors = rpc.InterfaceDesc{
	Name:    "RockPaperScissors",
	PkgPath: "v.io/x/ref/examples/rps",
	Embeds: []rpc.EmbedDesc{
		{"Judge", "v.io/x/ref/examples/rps", ``},
		{"Player", "v.io/x/ref/examples/rps", "// Player can receive challenges from other players."},
		{"ScoreKeeper", "v.io/x/ref/examples/rps", "// ScoreKeeper receives the outcome of games from Judges."},
	},
}

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_struct_1  *vdl.Type
	__VDLType_byte_2    *vdl.Type
	__VDLType_struct_3  *vdl.Type
	__VDLType_struct_4  *vdl.Type
	__VDLType_union_5   *vdl.Type
	__VDLType_array_6   *vdl.Type
	__VDLType_byte_7    *vdl.Type
	__VDLType_struct_8  *vdl.Type
	__VDLType_struct_9  *vdl.Type
	__VDLType_struct_10 *vdl.Type
	__VDLType_list_11   *vdl.Type
	__VDLType_list_12   *vdl.Type
	__VDLType_union_13  *vdl.Type
	__VDLType_struct_14 *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((*GameId)(nil))
	vdl.Register((*GameTypeTag)(nil))
	vdl.Register((*GameOptions)(nil))
	vdl.Register((*Unused)(nil))
	vdl.Register((*PlayerAction)(nil))
	vdl.Register((*PlayersMoves)(nil))
	vdl.Register((*WinnerTag)(nil))
	vdl.Register((*Round)(nil))
	vdl.Register((*ScoreCard)(nil))
	vdl.Register((*JudgeAction)(nil))
	vdl.Register((*PlayResult)(nil))

	// Initialize type definitions.
	__VDLType_struct_1 = vdl.TypeOf((*GameId)(nil)).Elem()
	__VDLType_byte_2 = vdl.TypeOf((*GameTypeTag)(nil))
	__VDLType_struct_3 = vdl.TypeOf((*GameOptions)(nil)).Elem()
	__VDLType_struct_4 = vdl.TypeOf((*Unused)(nil)).Elem()
	__VDLType_union_5 = vdl.TypeOf((*PlayerAction)(nil))
	__VDLType_array_6 = vdl.TypeOf((*PlayersMoves)(nil))
	__VDLType_byte_7 = vdl.TypeOf((*WinnerTag)(nil))
	__VDLType_struct_8 = vdl.TypeOf((*Round)(nil)).Elem()
	__VDLType_struct_9 = vdl.TypeOf((*vdltime.Time)(nil)).Elem()
	__VDLType_struct_10 = vdl.TypeOf((*ScoreCard)(nil)).Elem()
	__VDLType_list_11 = vdl.TypeOf((*[]string)(nil))
	__VDLType_list_12 = vdl.TypeOf((*[]Round)(nil))
	__VDLType_union_13 = vdl.TypeOf((*JudgeAction)(nil))
	__VDLType_struct_14 = vdl.TypeOf((*PlayResult)(nil)).Elem()

	return struct{}{}
}
