// Copyright 2019 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 source

import (
	"context"
	"fmt"
	"os"
	"regexp"
	"time"

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/analysis/passes/asmdecl"
	"golang.org/x/tools/go/analysis/passes/assign"
	"golang.org/x/tools/go/analysis/passes/atomic"
	"golang.org/x/tools/go/analysis/passes/atomicalign"
	"golang.org/x/tools/go/analysis/passes/bools"
	"golang.org/x/tools/go/analysis/passes/buildtag"
	"golang.org/x/tools/go/analysis/passes/cgocall"
	"golang.org/x/tools/go/analysis/passes/composite"
	"golang.org/x/tools/go/analysis/passes/copylock"
	"golang.org/x/tools/go/analysis/passes/deepequalerrors"
	"golang.org/x/tools/go/analysis/passes/errorsas"
	"golang.org/x/tools/go/analysis/passes/httpresponse"
	"golang.org/x/tools/go/analysis/passes/loopclosure"
	"golang.org/x/tools/go/analysis/passes/lostcancel"
	"golang.org/x/tools/go/analysis/passes/nilfunc"
	"golang.org/x/tools/go/analysis/passes/printf"
	"golang.org/x/tools/go/analysis/passes/shift"
	"golang.org/x/tools/go/analysis/passes/sortslice"
	"golang.org/x/tools/go/analysis/passes/stdmethods"
	"golang.org/x/tools/go/analysis/passes/structtag"
	"golang.org/x/tools/go/analysis/passes/testinggoroutine"
	"golang.org/x/tools/go/analysis/passes/tests"
	"golang.org/x/tools/go/analysis/passes/unmarshal"
	"golang.org/x/tools/go/analysis/passes/unreachable"
	"golang.org/x/tools/go/analysis/passes/unsafeptr"
	"golang.org/x/tools/go/analysis/passes/unusedresult"
	"golang.org/x/tools/internal/lsp/analysis/fillreturns"
	"golang.org/x/tools/internal/lsp/analysis/fillstruct"
	"golang.org/x/tools/internal/lsp/analysis/nonewvars"
	"golang.org/x/tools/internal/lsp/analysis/noresultvalues"
	"golang.org/x/tools/internal/lsp/analysis/simplifycompositelit"
	"golang.org/x/tools/internal/lsp/analysis/simplifyrange"
	"golang.org/x/tools/internal/lsp/analysis/simplifyslice"
	"golang.org/x/tools/internal/lsp/analysis/undeclaredname"
	"golang.org/x/tools/internal/lsp/analysis/unusedparams"
	"golang.org/x/tools/internal/lsp/diff"
	"golang.org/x/tools/internal/lsp/diff/myers"
	"golang.org/x/tools/internal/lsp/protocol"
	errors "golang.org/x/xerrors"
)

// DefaultOptions is the options that are used for Gopls execution independent
// of any externally provided configuration (LSP initialization, command
// invokation, etc.).
func DefaultOptions() Options {
	var commands []string
	for _, c := range Commands {
		commands = append(commands, c.Name)
	}
	return Options{
		ClientOptions: ClientOptions{
			InsertTextFormat:                  protocol.PlainTextTextFormat,
			PreferredContentFormat:            protocol.Markdown,
			ConfigurationSupported:            true,
			DynamicConfigurationSupported:     true,
			DynamicWatchedFilesSupported:      true,
			LineFoldingOnly:                   false,
			HierarchicalDocumentSymbolSupport: true,
		},
		ServerOptions: ServerOptions{
			SupportedCodeActions: map[FileKind]map[protocol.CodeActionKind]bool{
				Go: {
					protocol.SourceFixAll:          true,
					protocol.SourceOrganizeImports: true,
					protocol.QuickFix:              true,
					protocol.RefactorRewrite:       true,
					protocol.RefactorExtract:       true,
				},
				Mod: {
					protocol.SourceOrganizeImports: true,
				},
				Sum: {},
			},
			SupportedCommands: commands,
		},
		UserOptions: UserOptions{
			Env:                     os.Environ(),
			HoverKind:               FullDocumentation,
			LinkTarget:              "pkg.go.dev",
			LinksInHover:            true,
			Matcher:                 Fuzzy,
			SymbolMatcher:           SymbolFuzzy,
			DeepCompletion:          true,
			UnimportedCompletion:    true,
			CompletionDocumentation: true,
			EnabledCodeLens: map[string]bool{
				CommandGenerate.Name:          true,
				CommandRegenerateCgo.Name:     true,
				CommandTidy.Name:              true,
				CommandToggleDetails.Name:     false,
				CommandUpgradeDependency.Name: true,
				CommandVendor.Name:            true,
			},
			ExpandWorkspaceToModule: true,
		},
		DebuggingOptions: DebuggingOptions{
			CompletionBudget:   100 * time.Millisecond,
			LiteralCompletions: true,
		},
		ExperimentalOptions: ExperimentalOptions{
			TempModfile: true,
		},
		Hooks: Hooks{
			ComputeEdits:         myers.ComputeEdits,
			URLRegexp:            urlRegexp(),
			DefaultAnalyzers:     defaultAnalyzers(),
			TypeErrorAnalyzers:   typeErrorAnalyzers(),
			ConvenienceAnalyzers: convenienceAnalyzers(),
			GoDiff:               true,
		},
	}
}

// Options holds various configuration that affects Gopls execution, organized
// by the nature or origin of the settings.
type Options struct {
	ClientOptions
	ServerOptions
	UserOptions
	DebuggingOptions
	ExperimentalOptions
	Hooks
}

// ClientOptions holds LSP-specific configuration that is provided by the
// client.
type ClientOptions struct {
	InsertTextFormat                  protocol.InsertTextFormat
	ConfigurationSupported            bool
	DynamicConfigurationSupported     bool
	DynamicWatchedFilesSupported      bool
	PreferredContentFormat            protocol.MarkupKind
	LineFoldingOnly                   bool
	HierarchicalDocumentSymbolSupport bool
}

// ServerOptions holds LSP-specific configuration that is provided by the
// server.
type ServerOptions struct {
	SupportedCodeActions map[FileKind]map[protocol.CodeActionKind]bool
	SupportedCommands    []string
}

// UserOptions holds custom Gopls configuration (not part of the LSP) that is
// modified by the client.
type UserOptions struct {
	// Env is the current set of environment overrides on this view.
	Env []string

	// BuildFlags is used to adjust the build flags applied to the view.
	BuildFlags []string

	// HoverKind specifies the format of the content for hover requests.
	HoverKind HoverKind

	// UserEnabledAnalyses specifies analyses that the user would like to enable
	// or disable. A map of the names of analysis passes that should be
	// enabled/disabled. A full list of analyzers that gopls uses can be found
	// [here](analyzers.md).
	//
	// Example Usage:
	// ...
	// "analyses": {
	//   "unreachable": false, // Disable the unreachable analyzer.
	//   "unusedparams": true  // Enable the unusedparams analyzer.
	// }
	UserEnabledAnalyses map[string]bool

	// EnabledCodeLens specifies which codelens are enabled, keyed by the gopls
	// command that they provide.
	EnabledCodeLens map[string]bool

	// StaticCheck enables additional analyses from staticcheck.io.
	StaticCheck bool

	// LinkTarget is the website used for documentation. If empty, no link is
	// provided.
	LinkTarget string

	// LinksInHover toggles the presence of links to documentation in hover.
	LinksInHover bool

	// ImportShortcut specifies whether import statements should link to
	// documentation or go to definitions. The default is both.
	ImportShortcut ImportShortcut

	// LocalPrefix is used to specify goimports's -local behavior.
	LocalPrefix string

	// Matcher specifies the type of matcher to use for completion requests.
	Matcher Matcher

	// SymbolMatcher specifies the type of matcher to use for symbol requests.
	SymbolMatcher SymbolMatcher

	// SymbolStyle specifies what style of symbols to return in symbol requests
	// (package qualified, fully qualified, etc).
	SymbolStyle SymbolStyle

	// DeepCompletion allows completion to perform nested searches through
	// possible candidates.
	DeepCompletion bool

	// UnimportedCompletion enables completion for unimported packages.
	UnimportedCompletion bool

	// CompletionDocumentation returns additional documentation with completion
	// requests.
	CompletionDocumentation bool

	// Placeholders adds placeholders to parameters and structs in completion
	// results.
	Placeholders bool

	// Gofumpt indicates if we should run gofumpt formatting.
	Gofumpt bool

	// ExpandWorkspaceToModule is true if we should expand the scope of the
	// workspace to include the modules containing the workspace folders.
	ExpandWorkspaceToModule bool
}

type ImportShortcut int

const (
	Both ImportShortcut = iota
	Link
	Definition
)

func (s ImportShortcut) ShowLinks() bool {
	return s == Both || s == Link
}

func (s ImportShortcut) ShowDefinition() bool {
	return s == Both || s == Definition
}

type completionOptions struct {
	deepCompletion    bool
	unimported        bool
	documentation     bool
	fullDocumentation bool
	placeholders      bool
	literal           bool
	matcher           Matcher
	budget            time.Duration
}

// Hooks contains configuration that is provided to the Gopls command by the
// main package.
type Hooks struct {
	GoDiff               bool
	ComputeEdits         diff.ComputeEdits
	URLRegexp            *regexp.Regexp
	DefaultAnalyzers     map[string]Analyzer
	TypeErrorAnalyzers   map[string]Analyzer
	ConvenienceAnalyzers map[string]Analyzer
	GofumptFormat        func(ctx context.Context, src []byte) ([]byte, error)
}

func (o Options) AddDefaultAnalyzer(a *analysis.Analyzer) {
	o.DefaultAnalyzers[a.Name] = Analyzer{Analyzer: a, enabled: true}
}

// ExperimentalOptions defines configuration for features under active
// development. WARNING: This configuration will be changed in the future. It
// only exists while these features are under development.
type ExperimentalOptions struct {
	// TempModfile controls the use of the -modfile flag in Go 1.14.
	TempModfile bool

	// VerboseWorkDoneProgress controls whether the LSP server should send
	// progress reports for all work done outside the scope of an RPC.
	VerboseWorkDoneProgress bool

	// Annotations suppress various kinds of optimization diagnostics
	// that would be reported by the gc_details command.
	//   noNilcheck suppresses display of nilchecks.
	//   noEscape suppresses escape choices.
	//   noInline suppresses inlining choices.
	//   noBounds suppresses bounds checking diagnositcs.
	Annotations map[string]bool
}

// DebuggingOptions should not affect the logical execution of Gopls, but may
// be altered for debugging purposes.
type DebuggingOptions struct {
	VerboseOutput bool

	// CompletionBudget is the soft latency goal for completion requests. Most
	// requests finish in a couple milliseconds, but in some cases deep
	// completions can take much longer. As we use up our budget we
	// dynamically reduce the search scope to ensure we return timely
	// results. Zero means unlimited.
	CompletionBudget time.Duration

	// LiteralCompletions controls whether literal candidates such as
	// "&someStruct{}" are offered. Tests disable this flag to simplify
	// their expected values.
	LiteralCompletions bool
}

type Matcher int

const (
	Fuzzy = Matcher(iota)
	CaseInsensitive
	CaseSensitive
)

type SymbolMatcher int

const (
	SymbolFuzzy = SymbolMatcher(iota)
	SymbolCaseInsensitive
	SymbolCaseSensitive
)

type SymbolStyle int

const (
	PackageQualifiedSymbols = SymbolStyle(iota)
	FullyQualifiedSymbols
	DynamicSymbols
)

type HoverKind int

const (
	SingleLine = HoverKind(iota)
	NoDocumentation
	SynopsisDocumentation
	FullDocumentation

	// Structured is an experimental setting that returns a structured hover format.
	// This format separates the signature from the documentation, so that the client
	// can do more manipulation of these fields.
	//
	// This should only be used by clients that support this behavior.
	Structured
)

type OptionResults []OptionResult

type OptionResult struct {
	Name  string
	Value interface{}
	Error error

	State       OptionState
	Replacement string
}

type OptionState int

const (
	OptionHandled = OptionState(iota)
	OptionDeprecated
	OptionUnexpected
)

type LinkTarget string

func SetOptions(options *Options, opts interface{}) OptionResults {
	var results OptionResults
	switch opts := opts.(type) {
	case nil:
	case map[string]interface{}:
		for name, value := range opts {
			results = append(results, options.set(name, value))
		}
	default:
		results = append(results, OptionResult{
			Value: opts,
			Error: errors.Errorf("Invalid options type %T", opts),
		})
	}
	return results
}

func (o *Options) ForClientCapabilities(caps protocol.ClientCapabilities) {
	// Check if the client supports snippets in completion items.
	if c := caps.TextDocument.Completion; c.CompletionItem.SnippetSupport {
		o.InsertTextFormat = protocol.SnippetTextFormat
	}
	// Check if the client supports configuration messages.
	o.ConfigurationSupported = caps.Workspace.Configuration
	o.DynamicConfigurationSupported = caps.Workspace.DidChangeConfiguration.DynamicRegistration
	o.DynamicWatchedFilesSupported = caps.Workspace.DidChangeWatchedFiles.DynamicRegistration

	// Check which types of content format are supported by this client.
	if hover := caps.TextDocument.Hover; len(hover.ContentFormat) > 0 {
		o.PreferredContentFormat = hover.ContentFormat[0]
	}
	// Check if the client supports only line folding.
	fr := caps.TextDocument.FoldingRange
	o.LineFoldingOnly = fr.LineFoldingOnly
	// Check if the client supports hierarchical document symbols.
	o.HierarchicalDocumentSymbolSupport = caps.TextDocument.DocumentSymbol.HierarchicalDocumentSymbolSupport
}

func (o *Options) set(name string, value interface{}) OptionResult {
	result := OptionResult{Name: name, Value: value}
	switch name {
	case "env":
		menv, ok := value.(map[string]interface{})
		if !ok {
			result.errorf("invalid config gopls.env type %T", value)
			break
		}
		for k, v := range menv {
			o.Env = append(o.Env, fmt.Sprintf("%s=%s", k, v))
		}

	case "buildFlags":
		iflags, ok := value.([]interface{})
		if !ok {
			result.errorf("invalid config gopls.buildFlags type %T", value)
			break
		}
		flags := make([]string, 0, len(iflags))
		for _, flag := range iflags {
			flags = append(flags, fmt.Sprintf("%s", flag))
		}
		o.BuildFlags = flags

	case "completionDocumentation":
		result.setBool(&o.CompletionDocumentation)
	case "usePlaceholders":
		result.setBool(&o.Placeholders)
	case "deepCompletion":
		result.setBool(&o.DeepCompletion)
	case "completeUnimported":
		result.setBool(&o.UnimportedCompletion)
	case "completionBudget":
		if v, ok := result.asString(); ok {
			d, err := time.ParseDuration(v)
			if err != nil {
				result.errorf("failed to parse duration %q: %v", v, err)
				break
			}
			o.CompletionBudget = d
		}

	case "matcher":
		matcher, ok := result.asString()
		if !ok {
			break
		}
		switch matcher {
		case "fuzzy":
			o.Matcher = Fuzzy
		case "caseSensitive":
			o.Matcher = CaseSensitive
		default:
			o.Matcher = CaseInsensitive
		}

	case "symbolMatcher":
		matcher, ok := result.asString()
		if !ok {
			break
		}
		switch matcher {
		case "fuzzy":
			o.SymbolMatcher = SymbolFuzzy
		case "caseSensitive":
			o.SymbolMatcher = SymbolCaseSensitive
		default:
			o.SymbolMatcher = SymbolCaseInsensitive
		}

	case "symbolStyle":
		style, ok := result.asString()
		if !ok {
			break
		}
		switch style {
		case "full":
			o.SymbolStyle = FullyQualifiedSymbols
		case "dynamic":
			o.SymbolStyle = DynamicSymbols
		case "package":
			o.SymbolStyle = PackageQualifiedSymbols
		default:
			result.errorf("Unsupported symbol style %q", style)
		}

	case "hoverKind":
		hoverKind, ok := result.asString()
		if !ok {
			break
		}
		switch hoverKind {
		case "NoDocumentation":
			o.HoverKind = NoDocumentation
		case "SingleLine":
			o.HoverKind = SingleLine
		case "SynopsisDocumentation":
			o.HoverKind = SynopsisDocumentation
		case "FullDocumentation":
			o.HoverKind = FullDocumentation
		case "Structured":
			o.HoverKind = Structured
		default:
			result.errorf("Unsupported hover kind %q", hoverKind)
		}

	case "linkTarget":
		result.setString(&o.LinkTarget)

	case "linksInHover":
		result.setBool(&o.LinksInHover)

	case "importShortcut":
		var s string
		result.setString(&s)
		switch s {
		case "both":
			o.ImportShortcut = Both
		case "link":
			o.ImportShortcut = Link
		case "definition":
			o.ImportShortcut = Definition
		}

	case "analyses":
		result.setBoolMap(&o.UserEnabledAnalyses)

	case "annotations":
		result.setBoolMap(&o.Annotations)
		for k := range o.Annotations {
			switch k {
			case "noEscape", "noNilcheck", "noInline", "noBounds":
				continue
			default:
				result.Name += ":" + k // put mistake(s) in the message
				result.State = OptionUnexpected
			}
		}

	case "codelens":
		var lensOverrides map[string]bool
		result.setBoolMap(&lensOverrides)
		if result.Error == nil {
			if o.EnabledCodeLens == nil {
				o.EnabledCodeLens = make(map[string]bool)
			}
			for lens, enabled := range lensOverrides {
				o.EnabledCodeLens[lens] = enabled
			}
		}

	case "staticcheck":
		result.setBool(&o.StaticCheck)

	case "local":
		result.setString(&o.LocalPrefix)

	case "verboseOutput":
		result.setBool(&o.VerboseOutput)

	case "verboseWorkDoneProgress":
		result.setBool(&o.VerboseWorkDoneProgress)

	case "tempModfile":
		result.setBool(&o.TempModfile)

	case "gofumpt":
		result.setBool(&o.Gofumpt)

	case "expandWorkspaceToModule":
		result.setBool(&o.ExpandWorkspaceToModule)

	// Replaced settings.
	case "experimentalDisabledAnalyses":
		result.State = OptionDeprecated
		result.Replacement = "analyses"

	case "disableDeepCompletion":
		result.State = OptionDeprecated
		result.Replacement = "deepCompletion"

	case "disableFuzzyMatching":
		result.State = OptionDeprecated
		result.Replacement = "fuzzyMatching"

	case "wantCompletionDocumentation":
		result.State = OptionDeprecated
		result.Replacement = "completionDocumentation"

	case "wantUnimportedCompletions":
		result.State = OptionDeprecated
		result.Replacement = "completeUnimported"

	case "fuzzyMatching":
		result.State = OptionDeprecated
		result.Replacement = "matcher"

	case "caseSensitiveCompletion":
		result.State = OptionDeprecated
		result.Replacement = "matcher"

	// Deprecated settings.
	case "wantSuggestedFixes":
		result.State = OptionDeprecated

	case "noIncrementalSync":
		result.State = OptionDeprecated

	case "watchFileChanges":
		result.State = OptionDeprecated

	case "go-diff":
		result.State = OptionDeprecated

	default:
		result.State = OptionUnexpected
	}
	return result
}

func (r *OptionResult) errorf(msg string, values ...interface{}) {
	r.Error = errors.Errorf(msg, values...)
}

func (r *OptionResult) asBool() (bool, bool) {
	b, ok := r.Value.(bool)
	if !ok {
		r.errorf("Invalid type %T for bool option %q", r.Value, r.Name)
		return false, false
	}
	return b, true
}

func (r *OptionResult) setBool(b *bool) {
	if v, ok := r.asBool(); ok {
		*b = v
	}
}

func (r *OptionResult) setBoolMap(bm *map[string]bool) {
	all, ok := r.Value.(map[string]interface{})
	if !ok {
		r.errorf("Invalid type %T for map[string]interface{} option %q", r.Value, r.Name)
		return
	}
	m := make(map[string]bool)
	for a, enabled := range all {
		if enabled, ok := enabled.(bool); ok {
			m[a] = enabled
		} else {
			r.errorf("Invalid type %d for map key %q in option %q", a, r.Name)
			return
		}
	}
	*bm = m
}

func (r *OptionResult) asString() (string, bool) {
	b, ok := r.Value.(string)
	if !ok {
		r.errorf("Invalid type %T for string option %q", r.Value, r.Name)
		return "", false
	}
	return b, true
}

func (r *OptionResult) setString(s *string) {
	if v, ok := r.asString(); ok {
		*s = v
	}
}

// EnabledAnalyzers returns all of the analyzers enabled for the given
// snapshot.
func EnabledAnalyzers(snapshot Snapshot) (analyzers []Analyzer) {
	for _, a := range snapshot.View().Options().DefaultAnalyzers {
		if a.Enabled(snapshot.View()) {
			analyzers = append(analyzers, a)
		}
	}
	for _, a := range snapshot.View().Options().TypeErrorAnalyzers {
		if a.Enabled(snapshot.View()) {
			analyzers = append(analyzers, a)
		}
	}
	for _, a := range snapshot.View().Options().ConvenienceAnalyzers {
		if a.Enabled(snapshot.View()) {
			analyzers = append(analyzers, a)
		}
	}
	return analyzers
}

func typeErrorAnalyzers() map[string]Analyzer {
	return map[string]Analyzer{
		fillreturns.Analyzer.Name: {
			Analyzer:       fillreturns.Analyzer,
			FixesError:     fillreturns.FixesError,
			HighConfidence: true,
			enabled:        true,
		},
		nonewvars.Analyzer.Name: {
			Analyzer:   nonewvars.Analyzer,
			FixesError: nonewvars.FixesError,
			enabled:    true,
		},
		noresultvalues.Analyzer.Name: {
			Analyzer:   noresultvalues.Analyzer,
			FixesError: noresultvalues.FixesError,
			enabled:    true,
		},
		undeclaredname.Analyzer.Name: {
			Analyzer:   undeclaredname.Analyzer,
			FixesError: undeclaredname.FixesError,
			Command:    CommandUndeclaredName,
			enabled:    true,
		},
	}
}

func convenienceAnalyzers() map[string]Analyzer {
	return map[string]Analyzer{
		fillstruct.Analyzer.Name: {
			Analyzer: fillstruct.Analyzer,
			Command:  CommandFillStruct,
			enabled:  true,
		},
	}
}

func defaultAnalyzers() map[string]Analyzer {
	return map[string]Analyzer{
		// The traditional vet suite:
		asmdecl.Analyzer.Name:      {Analyzer: asmdecl.Analyzer, enabled: true},
		assign.Analyzer.Name:       {Analyzer: assign.Analyzer, enabled: true},
		atomic.Analyzer.Name:       {Analyzer: atomic.Analyzer, enabled: true},
		atomicalign.Analyzer.Name:  {Analyzer: atomicalign.Analyzer, enabled: true},
		bools.Analyzer.Name:        {Analyzer: bools.Analyzer, enabled: true},
		buildtag.Analyzer.Name:     {Analyzer: buildtag.Analyzer, enabled: true},
		cgocall.Analyzer.Name:      {Analyzer: cgocall.Analyzer, enabled: true},
		composite.Analyzer.Name:    {Analyzer: composite.Analyzer, enabled: true},
		copylock.Analyzer.Name:     {Analyzer: copylock.Analyzer, enabled: true},
		errorsas.Analyzer.Name:     {Analyzer: errorsas.Analyzer, enabled: true},
		httpresponse.Analyzer.Name: {Analyzer: httpresponse.Analyzer, enabled: true},
		loopclosure.Analyzer.Name:  {Analyzer: loopclosure.Analyzer, enabled: true},
		lostcancel.Analyzer.Name:   {Analyzer: lostcancel.Analyzer, enabled: true},
		nilfunc.Analyzer.Name:      {Analyzer: nilfunc.Analyzer, enabled: true},
		printf.Analyzer.Name:       {Analyzer: printf.Analyzer, enabled: true},
		shift.Analyzer.Name:        {Analyzer: shift.Analyzer, enabled: true},
		stdmethods.Analyzer.Name:   {Analyzer: stdmethods.Analyzer, enabled: true},
		structtag.Analyzer.Name:    {Analyzer: structtag.Analyzer, enabled: true},
		tests.Analyzer.Name:        {Analyzer: tests.Analyzer, enabled: true},
		unmarshal.Analyzer.Name:    {Analyzer: unmarshal.Analyzer, enabled: true},
		unreachable.Analyzer.Name:  {Analyzer: unreachable.Analyzer, enabled: true},
		unsafeptr.Analyzer.Name:    {Analyzer: unsafeptr.Analyzer, enabled: true},
		unusedresult.Analyzer.Name: {Analyzer: unusedresult.Analyzer, enabled: true},

		// Non-vet analyzers:
		deepequalerrors.Analyzer.Name:  {Analyzer: deepequalerrors.Analyzer, enabled: true},
		sortslice.Analyzer.Name:        {Analyzer: sortslice.Analyzer, enabled: true},
		testinggoroutine.Analyzer.Name: {Analyzer: testinggoroutine.Analyzer, enabled: true},
		unusedparams.Analyzer.Name:     {Analyzer: unusedparams.Analyzer, enabled: false},

		// gofmt -s suite:
		simplifycompositelit.Analyzer.Name: {Analyzer: simplifycompositelit.Analyzer, enabled: true, HighConfidence: true},
		simplifyrange.Analyzer.Name:        {Analyzer: simplifyrange.Analyzer, enabled: true, HighConfidence: true},
		simplifyslice.Analyzer.Name:        {Analyzer: simplifyslice.Analyzer, enabled: true, HighConfidence: true},
	}
}

func urlRegexp() *regexp.Regexp {
	// Ensure links are matched as full words, not anywhere.
	re := regexp.MustCompile(`\b(http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?\b`)
	re.Longest()
	return re
}
