// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Except for this comment, this file is a verbatim copy of the file
// with the same name in $GOROOT/src/go/internal/gccgoimporter, with
// a small modification in parseInterface to support older Go versions.

package gccgoimporter

import (
	"bytes"
	"errors"
	"fmt"
	"go/constant"
	"go/token"
	"go/types"
	"io"
	"strconv"
	"strings"
	"text/scanner"
	"unicode/utf8"
)

type parser struct {
	scanner  *scanner.Scanner
	version  string                    // format version
	tok      rune                      // current token
	lit      string                    // literal string; only valid for Ident, Int, String tokens
	pkgpath  string                    // package path of imported package
	pkgname  string                    // name of imported package
	pkg      *types.Package            // reference to imported package
	imports  map[string]*types.Package // package path -> package object
	typeList []types.Type              // type number -> type
	typeData []string                  // unparsed type data (v3 and later)
	fixups   []fixupRecord             // fixups to apply at end of parsing
	initdata InitData                  // package init priority data
	aliases  map[int]string            // maps saved type number to alias name
}

// When reading export data it's possible to encounter a defined type
// N1 with an underlying defined type N2 while we are still reading in
// that defined type N2; see issues #29006 and #29198 for instances
// of this. Example:
//
//   type N1 N2
//   type N2 struct {
//      ...
//      p *N1
//   }
//
// To handle such cases, the parser generates a fixup record (below) and
// delays setting of N1's underlying type until parsing is complete, at
// which point fixups are applied.

type fixupRecord struct {
	toUpdate *types.Named // type to modify when fixup is processed
	target   types.Type   // type that was incomplete when fixup was created
}

func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) {
	p.scanner = new(scanner.Scanner)
	p.initScanner(filename, src)
	p.imports = imports
	p.aliases = make(map[int]string)
	p.typeList = make([]types.Type, 1 /* type numbers start at 1 */, 16)
}

func (p *parser) initScanner(filename string, src io.Reader) {
	p.scanner.Init(src)
	p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
	p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings
	p.scanner.Whitespace = 1<<'\t' | 1<<' '
	p.scanner.Filename = filename // for good error messages
	p.next()
}

type importError struct {
	pos scanner.Position
	err error
}

func (e importError) Error() string {
	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
}

func (p *parser) error(err interface{}) {
	if s, ok := err.(string); ok {
		err = errors.New(s)
	}
	// panic with a runtime.Error if err is not an error
	panic(importError{p.scanner.Pos(), err.(error)})
}

func (p *parser) errorf(format string, args ...interface{}) {
	p.error(fmt.Errorf(format, args...))
}

func (p *parser) expect(tok rune) string {
	lit := p.lit
	if p.tok != tok {
		p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
	}
	p.next()
	return lit
}

func (p *parser) expectEOL() {
	if p.version == "v1" || p.version == "v2" {
		p.expect(';')
	}
	p.expect('\n')
}

func (p *parser) expectKeyword(keyword string) {
	lit := p.expect(scanner.Ident)
	if lit != keyword {
		p.errorf("expected keyword %s, got %q", keyword, lit)
	}
}

func (p *parser) parseString() string {
	str, err := strconv.Unquote(p.expect(scanner.String))
	if err != nil {
		p.error(err)
	}
	return str
}

// unquotedString     = { unquotedStringChar } .
// unquotedStringChar = <neither a whitespace nor a ';' char> .
func (p *parser) parseUnquotedString() string {
	if p.tok == scanner.EOF {
		p.error("unexpected EOF")
	}
	var buf bytes.Buffer
	buf.WriteString(p.scanner.TokenText())
	// This loop needs to examine each character before deciding whether to consume it. If we see a semicolon,
	// we need to let it be consumed by p.next().
	for ch := p.scanner.Peek(); ch != '\n' && ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
		buf.WriteRune(ch)
		p.scanner.Next()
	}
	p.next()
	return buf.String()
}

func (p *parser) next() {
	p.tok = p.scanner.Scan()
	switch p.tok {
	case scanner.Ident, scanner.Int, scanner.Float, scanner.String, '·':
		p.lit = p.scanner.TokenText()
	default:
		p.lit = ""
	}
}

func (p *parser) parseQualifiedName() (path, name string) {
	return p.parseQualifiedNameStr(p.parseString())
}

func (p *parser) parseUnquotedQualifiedName() (path, name string) {
	return p.parseQualifiedNameStr(p.parseUnquotedString())
}

// qualifiedName = [ ["."] unquotedString "." ] unquotedString .
//
// The above production uses greedy matching.
func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) {
	parts := strings.Split(unquotedName, ".")
	if parts[0] == "" {
		parts = parts[1:]
	}

	switch len(parts) {
	case 0:
		p.errorf("malformed qualified name: %q", unquotedName)
	case 1:
		// unqualified name
		pkgpath = p.pkgpath
		name = parts[0]
	default:
		// qualified name, which may contain periods
		pkgpath = strings.Join(parts[0:len(parts)-1], ".")
		name = parts[len(parts)-1]
	}

	return
}

// getPkg returns the package for a given path. If the package is
// not found but we have a package name, create the package and
// add it to the p.imports map.
//
func (p *parser) getPkg(pkgpath, name string) *types.Package {
	// package unsafe is not in the imports map - handle explicitly
	if pkgpath == "unsafe" {
		return types.Unsafe
	}
	pkg := p.imports[pkgpath]
	if pkg == nil && name != "" {
		pkg = types.NewPackage(pkgpath, name)
		p.imports[pkgpath] = pkg
	}
	return pkg
}

// parseExportedName is like parseQualifiedName, but
// the package path is resolved to an imported *types.Package.
//
// ExportedName = string [string] .
func (p *parser) parseExportedName() (pkg *types.Package, name string) {
	path, name := p.parseQualifiedName()
	var pkgname string
	if p.tok == scanner.String {
		pkgname = p.parseString()
	}
	pkg = p.getPkg(path, pkgname)
	if pkg == nil {
		p.errorf("package %s (path = %q) not found", name, path)
	}
	return
}

// Name = QualifiedName | "?" .
func (p *parser) parseName() string {
	if p.tok == '?' {
		// Anonymous.
		p.next()
		return ""
	}
	// The package path is redundant for us. Don't try to parse it.
	_, name := p.parseUnquotedQualifiedName()
	return name
}

func deref(typ types.Type) types.Type {
	if p, _ := typ.(*types.Pointer); p != nil {
		typ = p.Elem()
	}
	return typ
}

// Field = Name Type [string] .
func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
	name := p.parseName()
	typ, n := p.parseTypeExtended(pkg)
	anon := false
	if name == "" {
		anon = true
		// Alias?
		if aname, ok := p.aliases[n]; ok {
			name = aname
		} else {
			switch typ := deref(typ).(type) {
			case *types.Basic:
				name = typ.Name()
			case *types.Named:
				name = typ.Obj().Name()
			default:
				p.error("anonymous field expected")
			}
		}
	}
	field = types.NewField(token.NoPos, pkg, name, typ, anon)
	if p.tok == scanner.String {
		tag = p.parseString()
	}
	return
}

// Param = Name ["..."] Type .
func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) {
	name := p.parseName()
	if p.tok == '<' && p.scanner.Peek() == 'e' {
		// EscInfo = "<esc:" int ">" . (optional and ignored)
		p.next()
		p.expectKeyword("esc")
		p.expect(':')
		p.expect(scanner.Int)
		p.expect('>')
	}
	if p.tok == '.' {
		p.next()
		p.expect('.')
		p.expect('.')
		isVariadic = true
	}
	typ := p.parseType(pkg)
	if isVariadic {
		typ = types.NewSlice(typ)
	}
	param = types.NewParam(token.NoPos, pkg, name, typ)
	return
}

// Var = Name Type .
func (p *parser) parseVar(pkg *types.Package) *types.Var {
	name := p.parseName()
	return types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
}

// Conversion = "convert" "(" Type "," ConstValue ")" .
func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) {
	p.expectKeyword("convert")
	p.expect('(')
	typ = p.parseType(pkg)
	p.expect(',')
	val, _ = p.parseConstValue(pkg)
	p.expect(')')
	return
}

// ConstValue     = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion .
// FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) {
	// v3 changed to $false, $true, $convert, to avoid confusion
	// with variable names in inline function bodies.
	if p.tok == '$' {
		p.next()
		if p.tok != scanner.Ident {
			p.errorf("expected identifer after '$', got %s (%q)", scanner.TokenString(p.tok), p.lit)
		}
	}

	switch p.tok {
	case scanner.String:
		str := p.parseString()
		val = constant.MakeString(str)
		typ = types.Typ[types.UntypedString]
		return

	case scanner.Ident:
		b := false
		switch p.lit {
		case "false":
		case "true":
			b = true

		case "convert":
			return p.parseConversion(pkg)

		default:
			p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
		}

		p.next()
		val = constant.MakeBool(b)
		typ = types.Typ[types.UntypedBool]
		return
	}

	sign := ""
	if p.tok == '-' {
		p.next()
		sign = "-"
	}

	switch p.tok {
	case scanner.Int:
		val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0)
		if val == nil {
			p.error("could not parse integer literal")
		}

		p.next()
		if p.tok == '\'' {
			p.next()
			typ = types.Typ[types.UntypedRune]
		} else {
			typ = types.Typ[types.UntypedInt]
		}

	case scanner.Float:
		re := sign + p.lit
		p.next()

		var im string
		switch p.tok {
		case '+':
			p.next()
			im = p.expect(scanner.Float)

		case '-':
			p.next()
			im = "-" + p.expect(scanner.Float)

		case scanner.Ident:
			// re is in fact the imaginary component. Expect "i" below.
			im = re
			re = "0"

		default:
			val = constant.MakeFromLiteral(re, token.FLOAT, 0)
			if val == nil {
				p.error("could not parse float literal")
			}
			typ = types.Typ[types.UntypedFloat]
			return
		}

		p.expectKeyword("i")
		reval := constant.MakeFromLiteral(re, token.FLOAT, 0)
		if reval == nil {
			p.error("could not parse real component of complex literal")
		}
		imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0)
		if imval == nil {
			p.error("could not parse imag component of complex literal")
		}
		val = constant.BinaryOp(reval, token.ADD, imval)
		typ = types.Typ[types.UntypedComplex]

	default:
		p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
	}

	return
}

// Const = Name [Type] "=" ConstValue .
func (p *parser) parseConst(pkg *types.Package) *types.Const {
	name := p.parseName()
	var typ types.Type
	if p.tok == '<' {
		typ = p.parseType(pkg)
	}
	p.expect('=')
	val, vtyp := p.parseConstValue(pkg)
	if typ == nil {
		typ = vtyp
	}
	return types.NewConst(token.NoPos, pkg, name, typ, val)
}

// reserved is a singleton type used to fill type map slots that have
// been reserved (i.e., for which a type number has been parsed) but
// which don't have their actual type yet. When the type map is updated,
// the actual type must replace a reserved entry (or we have an internal
// error). Used for self-verification only - not required for correctness.
var reserved = new(struct{ types.Type })

// reserve reserves the type map entry n for future use.
func (p *parser) reserve(n int) {
	// Notes:
	// - for pre-V3 export data, the type numbers we see are
	//   guaranteed to be in increasing order, so we append a
	//   reserved entry onto the list.
	// - for V3+ export data, type numbers can appear in
	//   any order, however the 'types' section tells us the
	//   total number of types, hence typeList is pre-allocated.
	if len(p.typeData) == 0 {
		if n != len(p.typeList) {
			p.errorf("invalid type number %d (out of sync)", n)
		}
		p.typeList = append(p.typeList, reserved)
	} else {
		if p.typeList[n] != nil {
			p.errorf("previously visited type number %d", n)
		}
		p.typeList[n] = reserved
	}
}

// update sets the type map entries for the given type numbers nlist to t.
func (p *parser) update(t types.Type, nlist []int) {
	if len(nlist) != 0 {
		if t == reserved {
			p.errorf("internal error: update(%v) invoked on reserved", nlist)
		}
		if t == nil {
			p.errorf("internal error: update(%v) invoked on nil", nlist)
		}
	}
	for _, n := range nlist {
		if p.typeList[n] == t {
			continue
		}
		if p.typeList[n] != reserved {
			p.errorf("internal error: update(%v): %d not reserved", nlist, n)
		}
		p.typeList[n] = t
	}
}

// NamedType = TypeName [ "=" ] Type { Method } .
// TypeName  = ExportedName .
// Method    = "func" "(" Param ")" Name ParamList ResultList [InlineBody] ";" .
func (p *parser) parseNamedType(nlist []int) types.Type {
	pkg, name := p.parseExportedName()
	scope := pkg.Scope()
	obj := scope.Lookup(name)
	if obj != nil && obj.Type() == nil {
		p.errorf("%v has nil type", obj)
	}

	// type alias
	if p.tok == '=' {
		p.next()
		p.aliases[nlist[len(nlist)-1]] = name
		if obj != nil {
			// use the previously imported (canonical) type
			t := obj.Type()
			p.update(t, nlist)
			p.parseType(pkg) // discard
			return t
		}
		t := p.parseType(pkg, nlist...)
		obj = types.NewTypeName(token.NoPos, pkg, name, t)
		scope.Insert(obj)
		return t
	}

	// defined type
	if obj == nil {
		// A named type may be referred to before the underlying type
		// is known - set it up.
		tname := types.NewTypeName(token.NoPos, pkg, name, nil)
		types.NewNamed(tname, nil, nil)
		scope.Insert(tname)
		obj = tname
	}

	// use the previously imported (canonical), or newly created type
	t := obj.Type()
	p.update(t, nlist)

	nt, ok := t.(*types.Named)
	if !ok {
		// This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
		pt := p.parseType(pkg)
		if pt != t {
			p.error("unexpected underlying type for non-named TypeName")
		}
		return t
	}

	underlying := p.parseType(pkg)
	if nt.Underlying() == nil {
		if underlying.Underlying() == nil {
			fix := fixupRecord{toUpdate: nt, target: underlying}
			p.fixups = append(p.fixups, fix)
		} else {
			nt.SetUnderlying(underlying.Underlying())
		}
	}

	if p.tok == '\n' {
		p.next()
		// collect associated methods
		for p.tok == scanner.Ident {
			p.expectKeyword("func")
			if p.tok == '/' {
				// Skip a /*nointerface*/ comment.
				p.expect('/')
				p.expect('*')
				p.expect(scanner.Ident)
				p.expect('*')
				p.expect('/')
			}
			p.expect('(')
			receiver, _ := p.parseParam(pkg)
			p.expect(')')
			name := p.parseName()
			params, isVariadic := p.parseParamList(pkg)
			results := p.parseResultList(pkg)
			p.skipInlineBody()
			p.expectEOL()

			sig := types.NewSignature(receiver, params, results, isVariadic)
			nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
		}
	}

	return nt
}

func (p *parser) parseInt64() int64 {
	lit := p.expect(scanner.Int)
	n, err := strconv.ParseInt(lit, 10, 64)
	if err != nil {
		p.error(err)
	}
	return n
}

func (p *parser) parseInt() int {
	lit := p.expect(scanner.Int)
	n, err := strconv.ParseInt(lit, 10, 0 /* int */)
	if err != nil {
		p.error(err)
	}
	return int(n)
}

// ArrayOrSliceType = "[" [ int ] "]" Type .
func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []int) types.Type {
	p.expect('[')
	if p.tok == ']' {
		p.next()

		t := new(types.Slice)
		p.update(t, nlist)

		*t = *types.NewSlice(p.parseType(pkg))
		return t
	}

	t := new(types.Array)
	p.update(t, nlist)

	len := p.parseInt64()
	p.expect(']')

	*t = *types.NewArray(p.parseType(pkg), len)
	return t
}

// MapType = "map" "[" Type "]" Type .
func (p *parser) parseMapType(pkg *types.Package, nlist []int) types.Type {
	p.expectKeyword("map")

	t := new(types.Map)
	p.update(t, nlist)

	p.expect('[')
	key := p.parseType(pkg)
	p.expect(']')
	elem := p.parseType(pkg)

	*t = *types.NewMap(key, elem)
	return t
}

// ChanType = "chan" ["<-" | "-<"] Type .
func (p *parser) parseChanType(pkg *types.Package, nlist []int) types.Type {
	p.expectKeyword("chan")

	t := new(types.Chan)
	p.update(t, nlist)

	dir := types.SendRecv
	switch p.tok {
	case '-':
		p.next()
		p.expect('<')
		dir = types.SendOnly

	case '<':
		// don't consume '<' if it belongs to Type
		if p.scanner.Peek() == '-' {
			p.next()
			p.expect('-')
			dir = types.RecvOnly
		}
	}

	*t = *types.NewChan(dir, p.parseType(pkg))
	return t
}

// StructType = "struct" "{" { Field } "}" .
func (p *parser) parseStructType(pkg *types.Package, nlist []int) types.Type {
	p.expectKeyword("struct")

	t := new(types.Struct)
	p.update(t, nlist)

	var fields []*types.Var
	var tags []string

	p.expect('{')
	for p.tok != '}' && p.tok != scanner.EOF {
		field, tag := p.parseField(pkg)
		p.expect(';')
		fields = append(fields, field)
		tags = append(tags, tag)
	}
	p.expect('}')

	*t = *types.NewStruct(fields, tags)
	return t
}

// ParamList = "(" [ { Parameter "," } Parameter ] ")" .
func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
	var list []*types.Var
	isVariadic := false

	p.expect('(')
	for p.tok != ')' && p.tok != scanner.EOF {
		if len(list) > 0 {
			p.expect(',')
		}
		par, variadic := p.parseParam(pkg)
		list = append(list, par)
		if variadic {
			if isVariadic {
				p.error("... not on final argument")
			}
			isVariadic = true
		}
	}
	p.expect(')')

	return types.NewTuple(list...), isVariadic
}

// ResultList = Type | ParamList .
func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
	switch p.tok {
	case '<':
		p.next()
		if p.tok == scanner.Ident && p.lit == "inl" {
			return nil
		}
		taa, _ := p.parseTypeAfterAngle(pkg)
		return types.NewTuple(types.NewParam(token.NoPos, pkg, "", taa))

	case '(':
		params, _ := p.parseParamList(pkg)
		return params

	default:
		return nil
	}
}

// FunctionType = ParamList ResultList .
func (p *parser) parseFunctionType(pkg *types.Package, nlist []int) *types.Signature {
	t := new(types.Signature)
	p.update(t, nlist)

	params, isVariadic := p.parseParamList(pkg)
	results := p.parseResultList(pkg)

	*t = *types.NewSignature(nil, params, results, isVariadic)
	return t
}

// Func = Name FunctionType [InlineBody] .
func (p *parser) parseFunc(pkg *types.Package) *types.Func {
	name := p.parseName()
	if strings.ContainsRune(name, '$') {
		// This is a Type$equal or Type$hash function, which we don't want to parse,
		// except for the types.
		p.discardDirectiveWhileParsingTypes(pkg)
		return nil
	}
	f := types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil))
	p.skipInlineBody()
	return f
}

// InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
func (p *parser) parseInterfaceType(pkg *types.Package, nlist []int) types.Type {
	p.expectKeyword("interface")

	t := new(types.Interface)
	p.update(t, nlist)

	var methods []*types.Func
	var embeddeds []types.Type

	p.expect('{')
	for p.tok != '}' && p.tok != scanner.EOF {
		if p.tok == '?' {
			p.next()
			embeddeds = append(embeddeds, p.parseType(pkg))
		} else {
			method := p.parseFunc(pkg)
			methods = append(methods, method)
		}
		p.expect(';')
	}
	p.expect('}')

	*t = *newInterface(methods, embeddeds)
	return t
}

// PointerType = "*" ("any" | Type) .
func (p *parser) parsePointerType(pkg *types.Package, nlist []int) types.Type {
	p.expect('*')
	if p.tok == scanner.Ident {
		p.expectKeyword("any")
		t := types.Typ[types.UnsafePointer]
		p.update(t, nlist)
		return t
	}

	t := new(types.Pointer)
	p.update(t, nlist)

	*t = *types.NewPointer(p.parseType(pkg))

	return t
}

// TypeSpec = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
func (p *parser) parseTypeSpec(pkg *types.Package, nlist []int) types.Type {
	switch p.tok {
	case scanner.String:
		return p.parseNamedType(nlist)

	case scanner.Ident:
		switch p.lit {
		case "map":
			return p.parseMapType(pkg, nlist)

		case "chan":
			return p.parseChanType(pkg, nlist)

		case "struct":
			return p.parseStructType(pkg, nlist)

		case "interface":
			return p.parseInterfaceType(pkg, nlist)
		}

	case '*':
		return p.parsePointerType(pkg, nlist)

	case '[':
		return p.parseArrayOrSliceType(pkg, nlist)

	case '(':
		return p.parseFunctionType(pkg, nlist)
	}

	p.errorf("expected type name or literal, got %s", scanner.TokenString(p.tok))
	return nil
}

const (
	// From gofrontend/go/export.h
	// Note that these values are negative in the gofrontend and have been made positive
	// in the gccgoimporter.
	gccgoBuiltinINT8       = 1
	gccgoBuiltinINT16      = 2
	gccgoBuiltinINT32      = 3
	gccgoBuiltinINT64      = 4
	gccgoBuiltinUINT8      = 5
	gccgoBuiltinUINT16     = 6
	gccgoBuiltinUINT32     = 7
	gccgoBuiltinUINT64     = 8
	gccgoBuiltinFLOAT32    = 9
	gccgoBuiltinFLOAT64    = 10
	gccgoBuiltinINT        = 11
	gccgoBuiltinUINT       = 12
	gccgoBuiltinUINTPTR    = 13
	gccgoBuiltinBOOL       = 15
	gccgoBuiltinSTRING     = 16
	gccgoBuiltinCOMPLEX64  = 17
	gccgoBuiltinCOMPLEX128 = 18
	gccgoBuiltinERROR      = 19
	gccgoBuiltinBYTE       = 20
	gccgoBuiltinRUNE       = 21
)

func lookupBuiltinType(typ int) types.Type {
	return [...]types.Type{
		gccgoBuiltinINT8:       types.Typ[types.Int8],
		gccgoBuiltinINT16:      types.Typ[types.Int16],
		gccgoBuiltinINT32:      types.Typ[types.Int32],
		gccgoBuiltinINT64:      types.Typ[types.Int64],
		gccgoBuiltinUINT8:      types.Typ[types.Uint8],
		gccgoBuiltinUINT16:     types.Typ[types.Uint16],
		gccgoBuiltinUINT32:     types.Typ[types.Uint32],
		gccgoBuiltinUINT64:     types.Typ[types.Uint64],
		gccgoBuiltinFLOAT32:    types.Typ[types.Float32],
		gccgoBuiltinFLOAT64:    types.Typ[types.Float64],
		gccgoBuiltinINT:        types.Typ[types.Int],
		gccgoBuiltinUINT:       types.Typ[types.Uint],
		gccgoBuiltinUINTPTR:    types.Typ[types.Uintptr],
		gccgoBuiltinBOOL:       types.Typ[types.Bool],
		gccgoBuiltinSTRING:     types.Typ[types.String],
		gccgoBuiltinCOMPLEX64:  types.Typ[types.Complex64],
		gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
		gccgoBuiltinERROR:      types.Universe.Lookup("error").Type(),
		gccgoBuiltinBYTE:       types.Universe.Lookup("byte").Type(),
		gccgoBuiltinRUNE:       types.Universe.Lookup("rune").Type(),
	}[typ]
}

// Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" .
//
// parseType updates the type map to t for all type numbers n.
//
func (p *parser) parseType(pkg *types.Package, n ...int) types.Type {
	p.expect('<')
	t, _ := p.parseTypeAfterAngle(pkg, n...)
	return t
}

// (*parser).Type after reading the "<".
func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...int) (t types.Type, n1 int) {
	p.expectKeyword("type")

	n1 = 0
	switch p.tok {
	case scanner.Int:
		n1 = p.parseInt()
		if p.tok == '>' {
			if len(p.typeData) > 0 && p.typeList[n1] == nil {
				p.parseSavedType(pkg, n1, n)
			}
			t = p.typeList[n1]
			if len(p.typeData) == 0 && t == reserved {
				p.errorf("invalid type cycle, type %d not yet defined (nlist=%v)", n1, n)
			}
			p.update(t, n)
		} else {
			p.reserve(n1)
			t = p.parseTypeSpec(pkg, append(n, n1))
		}

	case '-':
		p.next()
		n1 := p.parseInt()
		t = lookupBuiltinType(n1)
		p.update(t, n)

	default:
		p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
		return nil, 0
	}

	if t == nil || t == reserved {
		p.errorf("internal error: bad return from parseType(%v)", n)
	}

	p.expect('>')
	return
}

// parseTypeExtended is identical to parseType, but if the type in
// question is a saved type, returns the index as well as the type
// pointer (index returned is zero if we parsed a builtin).
func (p *parser) parseTypeExtended(pkg *types.Package, n ...int) (t types.Type, n1 int) {
	p.expect('<')
	t, n1 = p.parseTypeAfterAngle(pkg, n...)
	return
}

// InlineBody = "<inl:NN>" .{NN}
// Reports whether a body was skipped.
func (p *parser) skipInlineBody() {
	// We may or may not have seen the '<' already, depending on
	// whether the function had a result type or not.
	if p.tok == '<' {
		p.next()
		p.expectKeyword("inl")
	} else if p.tok != scanner.Ident || p.lit != "inl" {
		return
	} else {
		p.next()
	}

	p.expect(':')
	want := p.parseInt()
	p.expect('>')

	defer func(w uint64) {
		p.scanner.Whitespace = w
	}(p.scanner.Whitespace)
	p.scanner.Whitespace = 0

	got := 0
	for got < want {
		r := p.scanner.Next()
		if r == scanner.EOF {
			p.error("unexpected EOF")
		}
		got += utf8.RuneLen(r)
	}
}

// Types = "types" maxp1 exportedp1 (offset length)* .
func (p *parser) parseTypes(pkg *types.Package) {
	maxp1 := p.parseInt()
	exportedp1 := p.parseInt()
	p.typeList = make([]types.Type, maxp1, maxp1)

	type typeOffset struct {
		offset int
		length int
	}
	var typeOffsets []typeOffset

	total := 0
	for i := 1; i < maxp1; i++ {
		len := p.parseInt()
		typeOffsets = append(typeOffsets, typeOffset{total, len})
		total += len
	}

	defer func(w uint64) {
		p.scanner.Whitespace = w
	}(p.scanner.Whitespace)
	p.scanner.Whitespace = 0

	// We should now have p.tok pointing to the final newline.
	// The next runes from the scanner should be the type data.

	var sb strings.Builder
	for sb.Len() < total {
		r := p.scanner.Next()
		if r == scanner.EOF {
			p.error("unexpected EOF")
		}
		sb.WriteRune(r)
	}
	allTypeData := sb.String()

	p.typeData = []string{""} // type 0, unused
	for _, to := range typeOffsets {
		p.typeData = append(p.typeData, allTypeData[to.offset:to.offset+to.length])
	}

	for i := 1; i < int(exportedp1); i++ {
		p.parseSavedType(pkg, i, []int{})
	}
}

// parseSavedType parses one saved type definition.
func (p *parser) parseSavedType(pkg *types.Package, i int, nlist []int) {
	defer func(s *scanner.Scanner, tok rune, lit string) {
		p.scanner = s
		p.tok = tok
		p.lit = lit
	}(p.scanner, p.tok, p.lit)

	p.scanner = new(scanner.Scanner)
	p.initScanner(p.scanner.Filename, strings.NewReader(p.typeData[i]))
	p.expectKeyword("type")
	id := p.parseInt()
	if id != i {
		p.errorf("type ID mismatch: got %d, want %d", id, i)
	}
	if p.typeList[i] == reserved {
		p.errorf("internal error: %d already reserved in parseSavedType", i)
	}
	if p.typeList[i] == nil {
		p.reserve(i)
		p.parseTypeSpec(pkg, append(nlist, i))
	}
	if p.typeList[i] == nil || p.typeList[i] == reserved {
		p.errorf("internal error: parseSavedType(%d,%v) reserved/nil", i, nlist)
	}
}

// PackageInit = unquotedString unquotedString int .
func (p *parser) parsePackageInit() PackageInit {
	name := p.parseUnquotedString()
	initfunc := p.parseUnquotedString()
	priority := -1
	if p.version == "v1" {
		priority = p.parseInt()
	}
	return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
}

// Throw away tokens until we see a ';'. If we see a '<', attempt to parse as a type.
func (p *parser) discardDirectiveWhileParsingTypes(pkg *types.Package) {
	for {
		switch p.tok {
		case '\n', ';':
			return
		case '<':
			p.parseType(pkg)
		case scanner.EOF:
			p.error("unexpected EOF")
		default:
			p.next()
		}
	}
}

// Create the package if we have parsed both the package path and package name.
func (p *parser) maybeCreatePackage() {
	if p.pkgname != "" && p.pkgpath != "" {
		p.pkg = p.getPkg(p.pkgpath, p.pkgname)
	}
}

// InitDataDirective = ( "v1" | "v2" | "v3" ) ";" |
//                     "priority" int ";" |
//                     "init" { PackageInit } ";" |
//                     "checksum" unquotedString ";" .
func (p *parser) parseInitDataDirective() {
	if p.tok != scanner.Ident {
		// unexpected token kind; panic
		p.expect(scanner.Ident)
	}

	switch p.lit {
	case "v1", "v2", "v3":
		p.version = p.lit
		p.next()
		p.expect(';')
		p.expect('\n')

	case "priority":
		p.next()
		p.initdata.Priority = p.parseInt()
		p.expectEOL()

	case "init":
		p.next()
		for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
			p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
		}
		p.expectEOL()

	case "init_graph":
		p.next()
		// The graph data is thrown away for now.
		for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
			p.parseInt64()
			p.parseInt64()
		}
		p.expectEOL()

	case "checksum":
		// Don't let the scanner try to parse the checksum as a number.
		defer func(mode uint) {
			p.scanner.Mode = mode
		}(p.scanner.Mode)
		p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
		p.next()
		p.parseUnquotedString()
		p.expectEOL()

	default:
		p.errorf("unexpected identifier: %q", p.lit)
	}
}

// Directive = InitDataDirective |
//             "package" unquotedString [ unquotedString ] [ unquotedString ] ";" |
//             "pkgpath" unquotedString ";" |
//             "prefix" unquotedString ";" |
//             "import" unquotedString unquotedString string ";" |
//             "indirectimport" unquotedString unquotedstring ";" |
//             "func" Func ";" |
//             "type" Type ";" |
//             "var" Var ";" |
//             "const" Const ";" .
func (p *parser) parseDirective() {
	if p.tok != scanner.Ident {
		// unexpected token kind; panic
		p.expect(scanner.Ident)
	}

	switch p.lit {
	case "v1", "v2", "v3", "priority", "init", "init_graph", "checksum":
		p.parseInitDataDirective()

	case "package":
		p.next()
		p.pkgname = p.parseUnquotedString()
		p.maybeCreatePackage()
		if p.version != "v1" && p.tok != '\n' && p.tok != ';' {
			p.parseUnquotedString()
			p.parseUnquotedString()
		}
		p.expectEOL()

	case "pkgpath":
		p.next()
		p.pkgpath = p.parseUnquotedString()
		p.maybeCreatePackage()
		p.expectEOL()

	case "prefix":
		p.next()
		p.pkgpath = p.parseUnquotedString()
		p.expectEOL()

	case "import":
		p.next()
		pkgname := p.parseUnquotedString()
		pkgpath := p.parseUnquotedString()
		p.getPkg(pkgpath, pkgname)
		p.parseString()
		p.expectEOL()

	case "indirectimport":
		p.next()
		pkgname := p.parseUnquotedString()
		pkgpath := p.parseUnquotedString()
		p.getPkg(pkgpath, pkgname)
		p.expectEOL()

	case "types":
		p.next()
		p.parseTypes(p.pkg)
		p.expectEOL()

	case "func":
		p.next()
		fun := p.parseFunc(p.pkg)
		if fun != nil {
			p.pkg.Scope().Insert(fun)
		}
		p.expectEOL()

	case "type":
		p.next()
		p.parseType(p.pkg)
		p.expectEOL()

	case "var":
		p.next()
		v := p.parseVar(p.pkg)
		p.pkg.Scope().Insert(v)
		p.expectEOL()

	case "const":
		p.next()
		c := p.parseConst(p.pkg)
		p.pkg.Scope().Insert(c)
		p.expectEOL()

	default:
		p.errorf("unexpected identifier: %q", p.lit)
	}
}

// Package = { Directive } .
func (p *parser) parsePackage() *types.Package {
	for p.tok != scanner.EOF {
		p.parseDirective()
	}
	for _, f := range p.fixups {
		if f.target.Underlying() == nil {
			p.errorf("internal error: fixup can't be applied, loop required")
		}
		f.toUpdate.SetUnderlying(f.target.Underlying())
	}
	p.fixups = nil
	for _, typ := range p.typeList {
		if it, ok := typ.(*types.Interface); ok {
			it.Complete()
		}
	}
	p.pkg.MarkComplete()
	return p.pkg
}
