tools/gopls: register semantic tokens statically

Not all clients support dynamic registration for semantic tokens, so
register the semantic tokens provider statically.

Gopls had used dynamic unregistration to disable semantic token
processing when the user turned off the option, but this is not
needed as the option is checked before processing semantic tokens.

Fixes: golang/go#54531

Change-Id: Ic10e8b7252e008f30c3bfb9c4f1af78d5762857b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/462215
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Peter Weinberger <pjw@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go
index af9aff9..d55e103 100644
--- a/gopls/internal/lsp/general.go
+++ b/gopls/internal/lsp/general.go
@@ -159,6 +159,14 @@
 			ReferencesProvider:        true,
 			RenameProvider:            renameOpts,
 			SelectionRangeProvider:    protocol.SelectionRangeRegistrationOptions{},
+			SemanticTokensProvider: protocol.SemanticTokensOptions{
+				Range: true,
+				Full:  true,
+				Legend: protocol.SemanticTokensLegend{
+					TokenTypes:     s.session.Options().SemanticTypes,
+					TokenModifiers: s.session.Options().SemanticMods,
+				},
+			},
 			SignatureHelpProvider: protocol.SignatureHelpOptions{
 				TriggerCharacters: []string{"(", ","},
 			},
@@ -213,9 +221,6 @@
 			Method: "workspace/didChangeConfiguration",
 		})
 	}
-	if options.SemanticTokens && options.DynamicRegistrationSemanticTokensSupported {
-		registrations = append(registrations, semanticTokenRegistration(options.SemanticTypes, options.SemanticMods))
-	}
 	if len(registrations) > 0 {
 		if err := s.client.RegisterCapability(ctx, &protocol.RegistrationParams{
 			Registrations: registrations,
diff --git a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/options.go
index 88a3678..a32ed12 100644
--- a/gopls/internal/lsp/source/options.go
+++ b/gopls/internal/lsp/source/options.go
@@ -753,7 +753,8 @@
 	o.LineFoldingOnly = fr.LineFoldingOnly
 	// Check if the client supports hierarchical document symbols.
 	o.HierarchicalDocumentSymbolSupport = caps.TextDocument.DocumentSymbol.HierarchicalDocumentSymbolSupport
-	// Check if the client supports semantic tokens
+
+	// Client's semantic tokens
 	o.SemanticTypes = caps.TextDocument.SemanticTokens.TokenTypes
 	o.SemanticMods = caps.TextDocument.SemanticTokens.TokenModifiers
 	// we don't need Requests, as we support full functionality
diff --git a/gopls/internal/lsp/workspace.go b/gopls/internal/lsp/workspace.go
index f2df9c1..c50ae32 100644
--- a/gopls/internal/lsp/workspace.go
+++ b/gopls/internal/lsp/workspace.go
@@ -46,7 +46,6 @@
 func (s *Server) didChangeConfiguration(ctx context.Context, _ *protocol.DidChangeConfigurationParams) error {
 	// Apply any changes to the session-level settings.
 	options := s.session.Options().Clone()
-	semanticTokensRegistered := options.SemanticTokens
 	if err := s.fetchConfig(ctx, "", "", options); err != nil {
 		return err
 	}
@@ -75,26 +74,6 @@
 	// An options change may have affected the detected Go version.
 	s.checkViewGoVersions()
 
-	registration := semanticTokenRegistration(options.SemanticTypes, options.SemanticMods)
-	// Update any session-specific registrations or unregistrations.
-	if !semanticTokensRegistered && options.SemanticTokens {
-		if err := s.client.RegisterCapability(ctx, &protocol.RegistrationParams{
-			Registrations: []protocol.Registration{registration},
-		}); err != nil {
-			return err
-		}
-	} else if semanticTokensRegistered && !options.SemanticTokens {
-		if err := s.client.UnregisterCapability(ctx, &protocol.UnregistrationParams{
-			Unregisterations: []protocol.Unregistration{
-				{
-					ID:     registration.ID,
-					Method: registration.Method,
-				},
-			},
-		}); err != nil {
-			return err
-		}
-	}
 	return nil
 }