// Copyright 2024 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.

package golang

// This file defines a simple HTML rendering of package documentation
// in imitation of the style of pkg.go.dev.
//
// The current implementation is just a starting point and a
// placeholder for a more sophisticated one.
//
// TODO(adonovan):
// - rewrite using html/template.
//   Or factor with golang.org/x/pkgsite/internal/godoc/dochtml.
// - emit breadcrumbs for parent + sibling packages.
// - list promoted methods---we have type information!
// - gather Example tests, following go/doc and pkgsite.
// - add option for doc.AllDecls: show non-exported symbols too.
// - style the <li> bullets in the index as invisible.
// - add push notifications such as didChange -> reload.
// - there appears to be a maximum file size beyond which the
//   "source.doc" code action is not offered. Remove that.
// - modify JS httpGET function to give a transient visual indication
//   when clicking a source link that the editor is being navigated
//   (in case it doesn't raise itself, like VS Code).
// - move this into a new package, golang/web, and then
//   split out the various helpers without fear of polluting
//   the golang package namespace?
// - show "Deprecated" chip when appropriate.

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/doc"
	"go/doc/comment"
	"go/format"
	"go/token"
	"go/types"
	"html"
	"iter"
	"path/filepath"
	"slices"
	"strings"

	"golang.org/x/tools/go/ast/astutil"
	"golang.org/x/tools/gopls/internal/cache"
	"golang.org/x/tools/gopls/internal/cache/parsego"
	"golang.org/x/tools/gopls/internal/protocol"
	goplsastutil "golang.org/x/tools/gopls/internal/util/astutil"
	"golang.org/x/tools/gopls/internal/util/bug"
	"golang.org/x/tools/gopls/internal/util/safetoken"
	"golang.org/x/tools/internal/stdlib"
	"golang.org/x/tools/internal/typesinternal"
)

// DocFragment finds the package and (optionally) symbol identified by
// the current selection, and returns the package path and the
// optional symbol URL fragment (e.g. "#Buffer.Len") for a symbol,
// along with a title for the code action.
//
// It is called once to offer the code action, and again when the
// command is executed. This is slightly inefficient but ensures that
// the title and package/symbol logic are consistent in all cases.
//
// It returns zeroes if there is nothing to see here (e.g. reference to a builtin).
func DocFragment(pkg *cache.Package, pgf *parsego.File, start, end token.Pos) (pkgpath PackagePath, fragment, title string) {
	thing := thingAtPoint(pkg, pgf, start, end)

	makeTitle := func(kind string, imp *types.Package, name string) string {
		title := "Browse documentation for " + kind + " "
		if imp != nil && imp != pkg.Types() {
			title += imp.Name() + "."
		}
		return title + name
	}

	wholePackage := func(pkg *types.Package) (PackagePath, string, string) {
		// External test packages don't have /pkg doc pages,
		// so instead show the doc for the package under test.
		// (This named-based heuristic is imperfect.)
		if forTest := strings.TrimSuffix(pkg.Path(), "_test"); forTest != pkg.Path() {
			return PackagePath(forTest), "", makeTitle("package", nil, filepath.Base(forTest))
		}

		return PackagePath(pkg.Path()), "", makeTitle("package", nil, pkg.Name())
	}

	// Conceptually, we check cases in the order:
	// 1. symbol
	// 2. package
	// 3. enclosing
	// but the logic of cases 1 and 3 are identical, hence the odd factoring.

	// Imported package?
	if thing.pkg != nil && thing.symbol == nil {
		return wholePackage(thing.pkg)
	}

	// Symbol?
	var sym types.Object
	if thing.symbol != nil {
		sym = thing.symbol // reference to a symbol
	} else if thing.enclosing != nil {
		sym = thing.enclosing // selection is within a declaration of a symbol
	}
	if sym == nil {
		return wholePackage(pkg.Types()) // no symbol
	}

	// Built-in (error.Error, append or unsafe).
	// TODO(adonovan): handle builtins in /pkg viewer.
	if sym.Pkg() == nil {
		return "", "", "" // nothing to see here
	}
	pkgpath = PackagePath(sym.Pkg().Path())

	// Unexported? Show enclosing type or package.
	if !sym.Exported() {
		// Unexported method of exported type?
		if fn, ok := sym.(*types.Func); ok {
			if recv := fn.Type().(*types.Signature).Recv(); recv != nil {
				_, named := typesinternal.ReceiverNamed(recv)
				if named != nil && named.Obj().Exported() {
					sym = named.Obj()
					goto below
				}
			}
		}

		return wholePackage(sym.Pkg())
	below:
	}

	// Reference to symbol in external test package?
	// Short-circuit: see comment in wholePackage.
	if strings.HasSuffix(string(pkgpath), "_test") {
		return wholePackage(pkg.Types())
	}

	// package-level symbol?
	if isPackageLevel(sym) {
		return pkgpath, sym.Name(), makeTitle(objectKind(sym), sym.Pkg(), sym.Name())
	}

	// Inv: sym is field or method, or local.
	switch sym := sym.(type) {
	case *types.Func: // => method
		sig := sym.Type().(*types.Signature)
		isPtr, named := typesinternal.ReceiverNamed(sig.Recv())
		if named != nil {
			if !named.Obj().Exported() {
				return wholePackage(sym.Pkg()) // exported method of unexported type
			}
			name := fmt.Sprintf("(%s%s).%s",
				strings.Repeat("*", btoi(isPtr)), // for *T
				named.Obj().Name(),
				sym.Name())
			fragment := named.Obj().Name() + "." + sym.Name()
			return pkgpath, fragment, makeTitle("method", sym.Pkg(), name)
		}

	case *types.Var:
		if sym.IsField() {
			// TODO(adonovan): support fields.
			// The Var symbol doesn't include the struct
			// type, so we need to use the logic from
			// Hover. (This isn't important for
			// DocFragment as fields don't have fragments,
			// but it matters to the grand unification of
			// Hover/Definition/DocFragment.
		}
	}

	// Field, non-exported method, or local declaration:
	// just show current package.
	return wholePackage(pkg.Types())
}

// thing describes the package or symbol denoted by a selection.
//
// TODO(adonovan): Hover, Definition, and References all start by
// identifying the selected object. Let's achieve a better factoring
// of the common parts using this structure, including uniform
// treatment of doc links, linkname, and suchlike.
type thing struct {
	// At most one of these fields is set.
	// (The 'enclosing' field is a fallback for when neither
	// of the first two is set.)
	symbol    types.Object   // referenced symbol
	pkg       *types.Package // referenced package
	enclosing types.Object   // package-level symbol or method decl enclosing selection
}

func thingAtPoint(pkg *cache.Package, pgf *parsego.File, start, end token.Pos) thing {
	path, _ := astutil.PathEnclosingInterval(pgf.File, start, end)

	// In an import spec?
	if len(path) >= 3 { // [...ImportSpec GenDecl File]
		if spec, ok := path[len(path)-3].(*ast.ImportSpec); ok {
			if pkgname := pkg.TypesInfo().PkgNameOf(spec); pkgname != nil {
				return thing{pkg: pkgname.Imported()}
			}
		}
	}

	// Definition or reference to symbol?
	var obj types.Object
	if id, ok := path[0].(*ast.Ident); ok {
		obj = pkg.TypesInfo().ObjectOf(id)

		// Treat use to PkgName like ImportSpec.
		if pkgname, ok := obj.(*types.PkgName); ok {
			return thing{pkg: pkgname.Imported()}
		}

	} else if sel, ok := path[0].(*ast.SelectorExpr); ok {
		// e.g. selection is "fmt.Println" or just a portion ("mt.Prin")
		obj = pkg.TypesInfo().Uses[sel.Sel]
	}
	if obj != nil {
		return thing{symbol: obj}
	}

	// Find enclosing declaration.
	if n := len(path); n > 1 {
		switch decl := path[n-2].(type) {
		case *ast.FuncDecl:
			// method?
			if fn := pkg.TypesInfo().Defs[decl.Name]; fn != nil {
				return thing{enclosing: fn}
			}

		case *ast.GenDecl:
			// path=[... Spec? GenDecl File]
			for _, spec := range decl.Specs {
				if n > 2 && spec == path[n-3] {
					var name *ast.Ident
					switch spec := spec.(type) {
					case *ast.ValueSpec:
						// var, const: use first name
						name = spec.Names[0]
					case *ast.TypeSpec:
						name = spec.Name
					}
					if name != nil {
						return thing{enclosing: pkg.TypesInfo().Defs[name]}
					}
					break
				}
			}
		}
	}

	return thing{} // nothing to see here
}

// Web is an abstraction of gopls' web server.
type Web interface {
	// PkgURL forms URLs of package or symbol documentation.
	PkgURL(viewID string, path PackagePath, fragment string) protocol.URI

	// SrcURL forms URLs that cause the editor to open a file at a specific position.
	SrcURL(filename string, line, col8 int) protocol.URI
}

// PackageDocHTML formats the package documentation page.
//
// The posURL function returns a URL that when visited, has the side
// effect of causing gopls to direct the client editor to navigate to
// the specified file/line/column position, in UTF-8 coordinates.
func PackageDocHTML(viewID string, pkg *cache.Package, web Web) ([]byte, error) {
	// We can't use doc.NewFromFiles (even with doc.PreserveAST
	// mode) as it calls ast.NewPackage which assumes that each
	// ast.File has an ast.Scope and resolves identifiers to
	// (deprecated) ast.Objects. (This is golang/go#66290.)
	// But doc.New only requires pkg.{Name,Files},
	// so we just boil it down.
	//
	// The only loss is doc.classifyExamples.
	// TODO(adonovan): simulate that too.
	fileMap := make(map[string]*ast.File)
	for _, f := range pkg.Syntax() {
		fileMap[pkg.FileSet().File(f.Pos()).Name()] = f
	}
	astpkg := &ast.Package{
		Name:  pkg.Types().Name(),
		Files: fileMap,
	}
	// PreserveAST mode only half works (golang/go#66449): it still
	// mutates ASTs when filtering out non-exported symbols.
	// As a workaround, enable AllDecls to suppress filtering,
	// and do it ourselves.
	mode := doc.PreserveAST | doc.AllDecls
	docpkg := doc.New(astpkg, pkg.Types().Path(), mode)

	// Discard non-exported symbols.
	// TODO(adonovan): do this conditionally, and expose option in UI.
	const showUnexported = false
	if !showUnexported {
		var (
			unexported   = func(name string) bool { return !token.IsExported(name) }
			filterValues = func(slice *[]*doc.Value) {
				delValue := func(v *doc.Value) bool {
					v.Names = slices.DeleteFunc(v.Names, unexported)
					return len(v.Names) == 0
				}
				*slice = slices.DeleteFunc(*slice, delValue)
			}
			filterFuncs = func(funcs *[]*doc.Func) {
				*funcs = slices.DeleteFunc(*funcs, func(v *doc.Func) bool {
					return unexported(v.Name)
				})
			}
		)
		filterValues(&docpkg.Consts)
		filterValues(&docpkg.Vars)
		filterFuncs(&docpkg.Funcs)
		docpkg.Types = slices.DeleteFunc(docpkg.Types, func(t *doc.Type) bool {
			filterValues(&t.Consts)
			filterValues(&t.Vars)
			filterFuncs(&t.Funcs)
			filterFuncs(&t.Methods)
			return unexported(t.Name)
		})
	}

	var docHTML func(comment string) []byte
	{
		// Adapt doc comment parser and printer
		// to our representation of Go packages
		// so that doc links (e.g. "[fmt.Println]")
		// become valid links.

		printer := docpkg.Printer()
		printer.DocLinkURL = func(link *comment.DocLink) string {
			path := pkg.Metadata().PkgPath
			if link.ImportPath != "" {
				path = PackagePath(link.ImportPath)
			}
			fragment := link.Name
			if link.Recv != "" {
				fragment = link.Recv + "." + link.Name
			}
			return web.PkgURL(viewID, path, fragment)
		}
		parser := docpkg.Parser()
		parser.LookupPackage = func(name string) (importPath string, ok bool) {
			// Ambiguous: different files in the same
			// package may have different import mappings,
			// but the hook doesn't provide the file context.
			// TODO(adonovan): conspire with docHTML to
			// pass the doc comment's enclosing file through
			// a shared variable, so that we can compute
			// the correct per-file mapping.
			//
			// TODO(adonovan): check for PkgName.Name
			// matches, but also check for
			// PkgName.Imported.Namer matches, since some
			// packages are typically imported under a
			// non-default name (e.g. pathpkg "path") but
			// may be referred to in doc links using their
			// canonical name.
			for _, f := range pkg.Syntax() {
				for _, imp := range f.Imports {
					pkgName := pkg.TypesInfo().PkgNameOf(imp)
					if pkgName != nil && pkgName.Name() == name {
						return pkgName.Imported().Path(), true
					}
				}
			}
			return "", false
		}
		parser.LookupSym = func(recv, name string) (ok bool) {
			// package-level decl?
			if recv == "" {
				return pkg.Types().Scope().Lookup(name) != nil
			}

			// method?
			tname, ok := pkg.Types().Scope().Lookup(recv).(*types.TypeName)
			if !ok {
				return false
			}
			m, _, _ := types.LookupFieldOrMethod(tname.Type(), true, pkg.Types(), name)
			return is[*types.Func](m)
		}
		docHTML = func(comment string) []byte {
			return printer.HTML(parser.Parse(comment))
		}
	}

	scope := pkg.Types().Scope()
	escape := html.EscapeString

	title := fmt.Sprintf("%s package - %s - Gopls packages",
		pkg.Types().Name(), escape(pkg.Types().Path()))

	var buf bytes.Buffer
	buf.WriteString(`<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>` + title + `</title>
  <link rel="stylesheet" href="/assets/common.css">
  <script src="/assets/common.js"></script>
  <style>
.lit { color: darkgreen; }

header {
  position: sticky;
  top: 0;
  left: 0;
  width: 100%;
  padding: 0.3em;
}

.Documentation-sinceVersion {
  font-weight: normal;
  color: #808080;
  float: right;
}

#pkgsite { height: 1.5em; }

#hdr-Selector {
  margin-right: 0.3em;
  float: right;
  min-width: 25em;
  padding: 0.3em;
}
  </style>
  <script type='text/javascript'>
window.addEventListener('load', function() {
	// Hook up the navigation selector.
	document.getElementById('hdr-Selector').onchange = (e) => {
		window.location.href = e.target.value;
	};
});
  </script>
</head>
<body>
<header>
<select id='hdr-Selector'>
<optgroup label="Documentation">
  <option label="Overview" value="#hdr-Overview"/>
  <option label="Index" value="#hdr-Index"/>
  <option label="Constants" value="#hdr-Constants"/>
  <option label="Variables" value="#hdr-Variables"/>
  <option label="Functions" value="#hdr-Functions"/>
  <option label="Types" value="#hdr-Types"/>
  <option label="Source Files" value="#hdr-SourceFiles"/>
</optgroup>
`)

	// -- header select element --

	// option emits an <option> for the specified symbol.
	//
	// recvType is the apparent receiver type, which may
	// differ from ReceiverNamed(obj.Signature.Recv).Name
	// for promoted methods.
	option := func(obj types.Object, recvType string) {
		// Render functions/methods as "(recv) Method(p1, ..., pN)".
		fragment := obj.Name()

		// format parameter names (p1, ..., pN)
		label := obj.Name() // for a type
		if fn, ok := obj.(*types.Func); ok {
			var buf strings.Builder
			sig := fn.Type().(*types.Signature)
			if sig.Recv() != nil {
				fmt.Fprintf(&buf, "(%s) ", sig.Recv().Name())
				fragment = recvType + "." + fn.Name()
			}
			fmt.Fprintf(&buf, "%s(", fn.Name())
			for i := 0; i < sig.Params().Len(); i++ {
				if i > 0 {
					buf.WriteString(", ")
				}
				name := sig.Params().At(i).Name()
				if name == "" {
					name = "_"
				}
				buf.WriteString(name)
			}
			buf.WriteByte(')')
			label = buf.String()
		}

		fmt.Fprintf(&buf, "  <option label='%s' value='#%s'/>\n", label, fragment)
	}

	// index of functions
	fmt.Fprintf(&buf, "<optgroup label='Functions'>\n")
	for _, fn := range docpkg.Funcs {
		option(scope.Lookup(fn.Name), "")
	}
	fmt.Fprintf(&buf, "</optgroup>\n")

	// index of types
	fmt.Fprintf(&buf, "<optgroup label='Types'>\n")
	for _, doctype := range docpkg.Types {
		option(scope.Lookup(doctype.Name), "")
	}
	fmt.Fprintf(&buf, "</optgroup>\n")

	// index of constructors and methods of each type
	for _, doctype := range docpkg.Types {
		tname := scope.Lookup(doctype.Name).(*types.TypeName)
		if len(doctype.Funcs)+len(doctype.Methods) > 0 {
			fmt.Fprintf(&buf, "<optgroup label='type %s'>\n", doctype.Name)
			for _, docfn := range doctype.Funcs {
				option(scope.Lookup(docfn.Name), "")
			}
			for _, docmethod := range doctype.Methods {
				method, _, _ := types.LookupFieldOrMethod(tname.Type(), true, tname.Pkg(), docmethod.Name)
				option(method, doctype.Name)
			}
			fmt.Fprintf(&buf, "</optgroup>\n")
		}
	}
	fmt.Fprintf(&buf, "</select>\n")
	fmt.Fprintf(&buf, "</header>\n")

	// -- main element --

	// nodeHTML returns HTML markup for a syntax tree.
	// It replaces referring identifiers with links,
	// and adds style spans for strings and comments.
	nodeHTML := func(n ast.Node) string {

		// linkify returns the appropriate URL (if any) for an identifier.
		linkify := func(id *ast.Ident) protocol.URI {
			if obj, ok := pkg.TypesInfo().Uses[id]; ok && obj.Pkg() != nil {
				// imported package name?
				if pkgname, ok := obj.(*types.PkgName); ok {
					// TODO(adonovan): do this for Defs of PkgName too.
					return web.PkgURL(viewID, PackagePath(pkgname.Imported().Path()), "")
				}

				// package-level symbol?
				if obj.Parent() == obj.Pkg().Scope() {
					if obj.Pkg() == pkg.Types() {
						return "#" + obj.Name() // intra-package ref
					} else {
						return web.PkgURL(viewID, PackagePath(obj.Pkg().Path()), obj.Name())
					}
				}

				// method of package-level named type?
				if fn, ok := obj.(*types.Func); ok {
					sig := fn.Type().(*types.Signature)
					if sig.Recv() != nil {
						_, named := typesinternal.ReceiverNamed(sig.Recv())
						if named != nil {
							fragment := named.Obj().Name() + "." + fn.Name()
							return web.PkgURL(viewID, PackagePath(fn.Pkg().Path()), fragment)
						}
					}
					return ""
				}

				// TODO(adonovan): field of package-level named struct type.
				// (Requires an index, since there's no way to
				// get from Var to Named.)
			}
			return ""
		}

		// Splice spans into HTML-escaped segments of the
		// original source buffer (which is usually but not
		// necessarily formatted).
		//
		// (For expedience we don't use the more sophisticated
		// approach taken by cmd/godoc and pkgsite's render
		// package, which emit the text, spans, and comments
		// in one traversal of the syntax tree.)
		//
		// TODO(adonovan): splice styled spans around comments too.
		//
		// TODO(adonovan): pkgsite prints specs from grouped
		// type decls like "type ( T1; T2 )" to make them
		// appear as separate decls. We should too.
		var buf bytes.Buffer
		for _, file := range pkg.CompiledGoFiles() {
			if goplsastutil.NodeContains(file.File, n.Pos()) {
				pos := n.Pos()

				// emit emits source in the interval [pos:to] and updates pos.
				emit := func(to token.Pos) {
					// Ident and BasicLit always have a valid pos.
					// (Failure means the AST has been corrupted.)
					if !to.IsValid() {
						bug.Reportf("invalid Pos")
					}
					start, err := safetoken.Offset(file.Tok, pos)
					if err != nil {
						bug.Reportf("invalid start Pos: %v", err)
					}
					end, err := safetoken.Offset(file.Tok, to)
					if err != nil {
						bug.Reportf("invalid end Pos: %v", err)
					}
					buf.WriteString(escape(string(file.Src[start:end])))
					pos = to
				}
				ast.Inspect(n, func(n ast.Node) bool {
					switch n := n.(type) {
					case *ast.Ident:
						emit(n.Pos())
						pos = n.End()
						if url := linkify(n); url != "" {
							fmt.Fprintf(&buf, "<a class='id' href='%s'>%s</a>", url, escape(n.Name))
						} else {
							buf.WriteString(escape(n.Name)) // plain
						}

					case *ast.BasicLit:
						emit(n.Pos())
						pos = n.End()
						fmt.Fprintf(&buf, "<span class='lit'>%s</span>", escape(n.Value))
					}
					return true
				})
				emit(n.End())
				return buf.String()
			}
		}

		// Original source not found.
		// Format the node without adornments.
		if err := format.Node(&buf, pkg.FileSet(), n); err != nil {
			// e.g. BadDecl?
			buf.Reset()
			fmt.Fprintf(&buf, "formatting error: %v", err)
		}
		return escape(buf.String())
	}

	// fnString is like fn.String() except that it:
	// - shows the receiver name;
	// - uses space "(T) M()" not dot "(T).M()" after receiver;
	// - doesn't bother with the special case for interface receivers
	//   since it is unreachable for the methods in go/doc.
	// - elides parameters after the first three: f(a, b, c, ...).
	fnString := func(fn *types.Func) string {
		pkgRelative := typesinternal.NameRelativeTo(pkg.Types())

		sig := fn.Type().(*types.Signature)

		// Emit "func (recv T) F".
		var buf bytes.Buffer
		buf.WriteString("func ")
		if recv := sig.Recv(); recv != nil {
			buf.WriteByte('(')
			if recv.Name() != "" {
				buf.WriteString(recv.Name())
				buf.WriteByte(' ')
			}
			types.WriteType(&buf, recv.Type(), pkgRelative)
			buf.WriteByte(')')
			buf.WriteByte(' ') // (ObjectString uses a '.' here)
		} else if pkg := fn.Pkg(); pkg != nil {
			if s := pkgRelative(pkg); s != "" {
				buf.WriteString(s)
				buf.WriteByte('.')
			}
		}
		buf.WriteString(fn.Name())

		// Emit signature.
		//
		// Elide parameters after the third one.
		// WriteSignature is too complex to fork, so we replace
		// parameters 4+ with "invalid type", format,
		// then post-process the string.
		if sig.Params().Len() > 3 {

			// Clone each TypeParam as NewSignatureType modifies them (#67294).
			cloneTparams := func(seq *types.TypeParamList) []*types.TypeParam {
				slice := make([]*types.TypeParam, seq.Len())
				for i := range slice {
					tparam := seq.At(i)
					slice[i] = types.NewTypeParam(tparam.Obj(), tparam.Constraint())
				}
				return slice
			}

			sig = types.NewSignatureType(
				sig.Recv(),
				cloneTparams(sig.RecvTypeParams()),
				cloneTparams(sig.TypeParams()),
				types.NewTuple(append(
					slices.Collect(tupleVariables(sig.Params()))[:3],
					types.NewVar(0, nil, "", types.Typ[types.Invalid]))...),
				sig.Results(),
				false) // any final ...T parameter is truncated
		}
		types.WriteSignature(&buf, sig, pkgRelative)
		return strings.ReplaceAll(buf.String(), ", invalid type)", ", ...)")
	}

	fmt.Fprintf(&buf, "<main>\n")

	// package name
	fmt.Fprintf(&buf, "<h1 id='hdr-Overview'>Package %s</h1>\n", pkg.Types().Name())

	// import path
	fmt.Fprintf(&buf, "<pre class='code'>import %q</pre>\n", pkg.Types().Path())

	// link to same package in pkg.go.dev
	fmt.Fprintf(&buf, "<div><a href=%q title='View in pkg.go.dev'><img id='pkgsite' src='/assets/go-logo-blue.svg'/></a>\n",
		"https://pkg.go.dev/"+string(pkg.Types().Path()))

	// package doc
	fmt.Fprintf(&buf, "<div class='comment'>%s</div>\n", docHTML(docpkg.Doc))

	// symbol index
	fmt.Fprintf(&buf, "<h2 id='hdr-Index'>Index</h2>\n")
	fmt.Fprintf(&buf, "<ul>\n")
	if len(docpkg.Consts) > 0 {
		fmt.Fprintf(&buf, "<li><a href='#hdr-Constants'>Constants</a></li>\n")
	}
	if len(docpkg.Vars) > 0 {
		fmt.Fprintf(&buf, "<li><a href='#hdr-Variables'>Variables</a></li>\n")
	}
	for _, fn := range docpkg.Funcs {
		obj := scope.Lookup(fn.Name).(*types.Func)
		fmt.Fprintf(&buf, "<li><a href='#%s'>%s</a></li>\n",
			obj.Name(), escape(fnString(obj)))
	}
	for _, doctype := range docpkg.Types {
		tname := scope.Lookup(doctype.Name).(*types.TypeName)
		fmt.Fprintf(&buf, "<li><a href='#%[1]s'>type %[1]s</a></li>\n",
			tname.Name())

		if len(doctype.Funcs)+len(doctype.Methods) > 0 {
			fmt.Fprintf(&buf, "<ul>\n")

			// constructors
			for _, docfn := range doctype.Funcs {
				obj := scope.Lookup(docfn.Name).(*types.Func)
				fmt.Fprintf(&buf, "<li><a href='#%s'>%s</a></li>\n",
					docfn.Name, escape(fnString(obj)))
			}
			// methods
			for _, docmethod := range doctype.Methods {
				method, _, _ := types.LookupFieldOrMethod(tname.Type(), true, tname.Pkg(), docmethod.Name)
				fmt.Fprintf(&buf, "<li><a href='#%s.%s'>%s</a></li>\n",
					doctype.Name,
					docmethod.Name,
					escape(fnString(method.(*types.Func))))
			}
			fmt.Fprintf(&buf, "</ul>\n")
		}
	}
	// TODO(adonovan): add index of Examples here.
	fmt.Fprintf(&buf, "</ul>\n")

	// constants and variables
	values := func(vals []*doc.Value) {
		for _, v := range vals {
			// anchors
			for _, name := range v.Names {
				fmt.Fprintf(&buf, "<a id='%s'></a>\n", escape(name))
			}

			// declaration
			decl2 := *v.Decl // shallow copy
			decl2.Doc = nil
			fmt.Fprintf(&buf, "<pre class='code'>%s</pre>\n", nodeHTML(&decl2))

			// comment (if any)
			fmt.Fprintf(&buf, "<div class='comment'>%s</div>\n", docHTML(v.Doc))
		}
	}
	fmt.Fprintf(&buf, "<h2 id='hdr-Constants'>Constants</h2>\n")
	if len(docpkg.Consts) == 0 {
		fmt.Fprintf(&buf, "<div>(no constants)</div>\n")
	} else {
		values(docpkg.Consts)
	}
	fmt.Fprintf(&buf, "<h2 id='hdr-Variables'>Variables</h2>\n")
	if len(docpkg.Vars) == 0 {
		fmt.Fprintf(&buf, "<div>(no variables)</div>\n")
	} else {
		values(docpkg.Vars)
	}

	// addedInHTML returns an HTML division containing the Go release version at
	// which this obj became available.
	addedInHTML := func(obj types.Object) string {
		if sym := StdSymbolOf(obj); sym != nil && sym.Version != stdlib.Version(0) {
			return fmt.Sprintf("<span class='Documentation-sinceVersion'>added in %v</span>", sym.Version)
		}
		return ""
	}

	// package-level functions
	fmt.Fprintf(&buf, "<h2 id='hdr-Functions'>Functions</h2>\n")
	// funcs emits a list of package-level functions,
	// possibly organized beneath the type they construct.
	funcs := func(funcs []*doc.Func) {
		for _, docfn := range funcs {
			obj := scope.Lookup(docfn.Name).(*types.Func)

			fmt.Fprintf(&buf, "<h3 id='%s'>func %s %s</h3>\n",
				docfn.Name, objHTML(pkg.FileSet(), web, obj), addedInHTML(obj))

			// decl: func F(params) results
			fmt.Fprintf(&buf, "<pre class='code'>%s</pre>\n",
				nodeHTML(docfn.Decl.Type))

			// comment (if any)
			fmt.Fprintf(&buf, "<div class='comment'>%s</div>\n", docHTML(docfn.Doc))
		}
	}
	funcs(docpkg.Funcs)

	// types and their subelements
	fmt.Fprintf(&buf, "<h2 id='hdr-Types'>Types</h2>\n")
	for _, doctype := range docpkg.Types {
		tname := scope.Lookup(doctype.Name).(*types.TypeName)

		// title and source link
		fmt.Fprintf(&buf, "<h3 id='%s'>type %s %s</h3>\n",
			doctype.Name, objHTML(pkg.FileSet(), web, tname), addedInHTML(tname))

		// declaration
		// TODO(adonovan): excise non-exported struct fields somehow.
		decl2 := *doctype.Decl // shallow copy
		decl2.Doc = nil
		fmt.Fprintf(&buf, "<pre class='code'>%s</pre>\n", nodeHTML(&decl2))

		// comment (if any)
		fmt.Fprintf(&buf, "<div class='comment'>%s</div>\n", docHTML(doctype.Doc))

		// subelements
		values(doctype.Consts) // constants of type T
		values(doctype.Vars)   // vars of type T
		funcs(doctype.Funcs)   // constructors of T

		// methods on T
		for _, docmethod := range doctype.Methods {
			method, _, _ := types.LookupFieldOrMethod(tname.Type(), true, tname.Pkg(), docmethod.Name)
			fmt.Fprintf(&buf, "<h4 id='%s.%s'>func (%s) %s %s</h4>\n",
				doctype.Name, docmethod.Name,
				docmethod.Orig, // T or *T
				objHTML(pkg.FileSet(), web, method), addedInHTML(method))

			// decl: func (x T) M(params) results
			fmt.Fprintf(&buf, "<pre class='code'>%s</pre>\n",
				nodeHTML(docmethod.Decl.Type))

			// comment (if any)
			fmt.Fprintf(&buf, "<div class='comment'>%s</div>\n",
				docHTML(docmethod.Doc))
		}
	}

	// source files
	fmt.Fprintf(&buf, "<h2 id='hdr-SourceFiles'>Source files</h2>\n")
	for _, filename := range docpkg.Filenames {
		fmt.Fprintf(&buf, "<div class='comment'>%s</div>\n",
			sourceLink(filepath.Base(filename), web.SrcURL(filename, 1, 1)))
	}

	fmt.Fprintf(&buf, "</main>\n")
	fmt.Fprintf(&buf, "</body>\n")
	fmt.Fprintf(&buf, "</html>\n")

	return buf.Bytes(), nil
}

// tupleVariables returns a go1.23 iterator over the variables of a tuple type.
//
// Example: for v := range tuple.Variables() { ... }
// TODO(adonovan): use t.Variables in go1.24.
func tupleVariables(t *types.Tuple) iter.Seq[*types.Var] {
	return func(yield func(v *types.Var) bool) {
		for i := range t.Len() {
			if !yield(t.At(i)) {
				break
			}
		}
	}
}
