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

// Package signature defines types representing interface and method signatures.
package signature

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

// Interface describes the signature of an interface.
type Interface struct {
	Name    string
	PkgPath string
	Doc     string
	Embeds  []Embed  // No special ordering.
	Methods []Method // Ordered by method name.
}

func (Interface) __VDLReflect(struct {
	Name string `vdl:"signature.Interface"`
}) {
}

// Embed describes the signature of an embedded interface.
type Embed struct {
	Name    string
	PkgPath string
	Doc     string
}

func (Embed) __VDLReflect(struct {
	Name string `vdl:"signature.Embed"`
}) {
}

// Method describes the signature of an interface method.
type Method struct {
	Name      string
	Doc       string
	InArgs    []Arg        // Input arguments
	OutArgs   []Arg        // Output arguments
	InStream  *Arg         // Input stream (optional)
	OutStream *Arg         // Output stream (optional)
	Tags      []*vdl.Value // Method tags
}

func (Method) __VDLReflect(struct {
	Name string `vdl:"signature.Method"`
}) {
}

// Arg describes the signature of a single argument.
type Arg struct {
	Name string
	Doc  string
	Type *vdl.Type // Type of the argument.
}

func (Arg) __VDLReflect(struct {
	Name string `vdl:"signature.Arg"`
}) {
}

func init() {
	vdl.Register((*Interface)(nil))
	vdl.Register((*Embed)(nil))
	vdl.Register((*Method)(nil))
	vdl.Register((*Arg)(nil))
}
