in internal/lsp/source/options.go [766:1029]
func (o *Options) set(name string, value interface{}, seen map[string]struct{}) OptionResult {
// Flatten the name in case we get options with a hierarchy.
split := strings.Split(name, ".")
name = split[len(split)-1]
result := OptionResult{Name: name, Value: value}
if _, ok := seen[name]; ok {
result.errorf("duplicate configuration for %s", name)
}
seen[name] = struct{}{}
switch name {
case "env":
menv, ok := value.(map[string]interface{})
if !ok {
result.errorf("invalid type %T, expect map", value)
break
}
if o.Env == nil {
o.Env = make(map[string]string)
}
for k, v := range menv {
o.Env[k] = fmt.Sprint(v)
}
case "buildFlags":
iflags, ok := value.([]interface{})
if !ok {
result.errorf("invalid type %T, expect list", value)
break
}
flags := make([]string, 0, len(iflags))
for _, flag := range iflags {
flags = append(flags, fmt.Sprintf("%s", flag))
}
o.BuildFlags = flags
case "directoryFilters":
ifilters, ok := value.([]interface{})
if !ok {
result.errorf("invalid type %T, expect list", value)
break
}
var filters []string
for _, ifilter := range ifilters {
filter := fmt.Sprint(ifilter)
if filter[0] != '+' && filter[0] != '-' {
result.errorf("invalid filter %q, must start with + or -", filter)
return result
}
filters = append(filters, strings.TrimRight(filepath.FromSlash(filter), "/"))
}
o.DirectoryFilters = filters
case "memoryMode":
if s, ok := result.asOneOf(
string(ModeNormal),
string(ModeDegradeClosed),
); ok {
o.MemoryMode = MemoryMode(s)
}
case "completionDocumentation":
result.setBool(&o.CompletionDocumentation)
case "usePlaceholders":
result.setBool(&o.UsePlaceholders)
case "deepCompletion":
result.setBool(&o.DeepCompletion)
case "completeUnimported":
result.setBool(&o.CompleteUnimported)
case "completionBudget":
result.setDuration(&o.CompletionBudget)
case "matcher":
if s, ok := result.asOneOf(
string(Fuzzy),
string(CaseSensitive),
string(CaseInsensitive),
); ok {
o.Matcher = Matcher(s)
}
case "symbolMatcher":
if s, ok := result.asOneOf(
string(SymbolFuzzy),
string(SymbolFastFuzzy),
string(SymbolCaseInsensitive),
string(SymbolCaseSensitive),
); ok {
o.SymbolMatcher = SymbolMatcher(s)
}
case "symbolStyle":
if s, ok := result.asOneOf(
string(FullyQualifiedSymbols),
string(PackageQualifiedSymbols),
string(DynamicSymbols),
); ok {
o.SymbolStyle = SymbolStyle(s)
}
case "hoverKind":
if s, ok := result.asOneOf(
string(NoDocumentation),
string(SingleLine),
string(SynopsisDocumentation),
string(FullDocumentation),
string(Structured),
); ok {
o.HoverKind = HoverKind(s)
}
case "linkTarget":
result.setString(&o.LinkTarget)
case "linksInHover":
result.setBool(&o.LinksInHover)
case "importShortcut":
if s, ok := result.asOneOf(string(Both), string(Link), string(Definition)); ok {
o.ImportShortcut = ImportShortcut(s)
}
case "analyses":
result.setBoolMap(&o.Analyses)
case "annotations":
result.setAnnotationMap(&o.Annotations)
case "codelenses", "codelens":
var lensOverrides map[string]bool
result.setBoolMap(&lensOverrides)
if result.Error == nil {
if o.Codelenses == nil {
o.Codelenses = make(map[string]bool)
}
for lens, enabled := range lensOverrides {
o.Codelenses[lens] = enabled
}
}
// codelens is deprecated, but still works for now.
// TODO(rstambler): Remove this for the gopls/v0.7.0 release.
if name == "codelens" {
result.State = OptionDeprecated
result.Replacement = "codelenses"
}
case "staticcheck":
result.setBool(&o.Staticcheck)
case "local":
result.setString(&o.Local)
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 "semanticTokens":
result.setBool(&o.SemanticTokens)
case "expandWorkspaceToModule":
result.setBool(&o.ExpandWorkspaceToModule)
case "experimentalPostfixCompletions":
result.setBool(&o.ExperimentalPostfixCompletions)
case "experimentalWorkspaceModule":
result.setBool(&o.ExperimentalWorkspaceModule)
case "experimentalTemplateSupport": // remove after June 2022
result.State = OptionDeprecated
case "templateExtensions":
if iexts, ok := value.([]interface{}); ok {
ans := []string{}
for _, x := range iexts {
ans = append(ans, fmt.Sprint(x))
}
o.TemplateExtensions = ans
break
}
if value == nil {
o.TemplateExtensions = nil
break
}
result.errorf(fmt.Sprintf("unexpected type %T not []string", value))
case "experimentalDiagnosticsDelay", "diagnosticsDelay":
if name == "experimentalDiagnosticsDelay" {
result.State = OptionDeprecated
result.Replacement = "diagnosticsDelay"
}
result.setDuration(&o.DiagnosticsDelay)
case "experimentalWatchedFileDelay":
result.setDuration(&o.ExperimentalWatchedFileDelay)
case "experimentalPackageCacheKey":
result.setBool(&o.ExperimentalPackageCacheKey)
case "allowModfileModifications":
result.setBool(&o.AllowModfileModifications)
case "allowImplicitNetworkAccess":
result.setBool(&o.AllowImplicitNetworkAccess)
case "experimentalUseInvalidMetadata":
result.setBool(&o.ExperimentalUseInvalidMetadata)
case "allExperiments":
// This setting should be handled before all of the other options are
// processed, so do nothing here.
// 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
}