// Copyright (C) 2019 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Generated by {{GenerateArguments}}
// Do not modify this file directly.

package schema

// Opcode holds information about a specific SPIR-V opcode.
type Opcode struct {
	Opname   string
	Class    string
	Opcode   int
	Operands []Operand
}

// Operand contains information about a logical operand for an instruction.
type Operand struct {
	Kind       *OperandKind
	Name       string
	Quantifier Quantifier
}

// OperandKind contains information about a specific operand kind.
type OperandKind struct {
	Category   OperandCategory
	Kind       string
	Enumerants []Enumerant
	Bases      []*OperandKind
}

// Enumerant contains information about an enumerant in an enum.
type Enumerant struct {
	Enumerant    string
	Value        interface{}
	Capabilities []string
	Parameters   []Parameter
	Version      string
}

// Parameter contains information about a logical parameter for an enumerant.
type Parameter struct {
	Kind *OperandKind
	Name string
}

// Quantifier indicates the number of times the quantified term may appear.
type Quantifier string

const (
	// Once indicates the quantified term may appear exactly once.
	Once Quantifier = ""

	// ZeroOrOnce indicates the quantified term may appear zero or one
	// time; an optional term.
	ZeroOrOnce Quantifier = "?"

	// ZeroOrMany indicates the quantified term may appear any number of
	// times.
	ZeroOrMany Quantifier = "*"
)

// OperandCategory is an enumerator that groups operand kinds.
type OperandCategory string

const (
	// OperandCategoryBitEnum describes an operand kind where its value is a
	// mask, which is formed by combining the bits specified as enumerants in an
	// enum.
	OperandCategoryBitEnum = "BitEnum"

	// OperandCategoryValueEnum describes an operand kind where its value is an
	// enumerant from an enum.
	OperandCategoryValueEnum = "ValueEnum"

	// OperandCategoryID describes and operand kind where its value is an <id>
	// definition or reference.
	OperandCategoryID = "Id"

	// OperandCategoryLiteral describes and operand kind where its value is an
	// literal number or string.
	OperandCategoryLiteral = "Literal"

	// OperandCategoryComposite describes and operand kind where its value is
	// composed from operand values from the above categories.
	OperandCategoryComposite = "Composite"
)

// OpcodeMap is a map of opcode name to Opcode type.
type OpcodeMap map[string]*Opcode

var (
	// Opcodes is a map of opcode name to Opcode description.
	Opcodes = OpcodeMap {•{{range $i := .SPIRV.Instructions}}
		"{{$i.Opname}}": {{Title $i.Opname}},{{end}}
	}

	// ExtOpcodes is a map of extension name to Opcode description list.
	ExtOpcodes = map[string]OpcodeMap {•{{range $ext := .Extensions}}
		"{{$ext.Name}}": {•{{range $i := $ext.Instructions}}
			"{{$i.Opname}}": {{Global $ext.Name}}_{{$i.Opname}},{{end}}
		},{{end}}
	}

{{range $i := .SPIRV.Instructions}}	{{Title $i.Opname}} = &Opcode {
		Opname:   "{{$i.Opname}}",
		Operands: []Operand {•{{range $i := $i.Operands}}
			Operand {
				Kind:       OperandKind{{$i.Kind}},
				Name:       "{{Replace $i.Name "\n" " "}}",
				Quantifier: "{{$i.Quantifier}}",
			}, {{end}}
		},
	}
{{end}}
{{range $ext := .Extensions}}{{range $i := $ext.Instructions}}	{{Global $ext.Name}}_{{$i.Opname}} = &Opcode {
		Opname:   "{{$i.Opname}}",
		Operands: []Operand {•{{range $i := $i.Operands}}
			Operand {
				Kind:       OperandKind{{$i.Kind}},
				Name:       "{{Replace $i.Name "\n" " "}}",
				Quantifier: "{{$i.Quantifier}}",
			}, {{end}}
		},
	}
{{end}}{{end}}

{{range $o := .All.OperandKinds}}	OperandKind{{$o.Kind}} = &OperandKind {
		Kind:       "{{$o.Kind}}",
		Category:   "{{$o.Category}}",
		Enumerants: []Enumerant {•{{range $e := $o.Enumerants}}
			Enumerant{
				Enumerant:    "{{$e.Enumerant}}",
				Value:        {{$e.Value}},
				Capabilities: []string{•{{range $c := $e.Capabilities}}"{{$c}}",{{end}}•},
				Parameters:   []Parameter{•{{range $p := $e.Parameters}}{•OperandKind{{$p.Kind}}, "{{$p.Name}}"•},{{end}}•},
				Version:      "{{$e.Version}}",
			},{{end}}
		},
		Bases:      []*OperandKind {•{{range $b := $o.Bases}}OperandKind{{$b}},{{end}}•},
	}
{{end}}
)
