internal/lsp: report used semantic token order in registerCapability

The semantic token legend sent to the client in registerCapability
wasn't the one used when encoding semantic tokens.

If a client sent clientCapabilities support for token types and token
modifiers that wasn't ordered exactly as gopls defined them, all
semantic tokens was encoded incorrectly.

We now instead report the order used for encoding as legend in the
registerCapability request to the client.

Fixes golang/go#46244

Change-Id: I8273c9ed9d1f97a93c162d709f30df38bfd576aa
Reviewed-on: https://go-review.googlesource.com/c/tools/+/321029
Trust: Pontus Leitzler <leitzler@gmail.com>
Trust: Peter Weinberger <pjw@google.com>
Run-TryBot: Pontus Leitzler <leitzler@gmail.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Peter Weinberger <pjw@google.com>
diff --git a/internal/lsp/general.go b/internal/lsp/general.go
index 5bdc4bf..3c7bbfe 100644
--- a/internal/lsp/general.go
+++ b/internal/lsp/general.go
@@ -200,7 +200,7 @@
 			},
 		}
 		if options.SemanticTokens {
-			registrations = append(registrations, semanticTokenRegistration())
+			registrations = append(registrations, semanticTokenRegistration(options.SemanticTypes, options.SemanticMods))
 		}
 		if err := s.client.RegisterCapability(ctx, &protocol.RegistrationParams{
 			Registrations: registrations,
diff --git a/internal/lsp/workspace.go b/internal/lsp/workspace.go
index 093adc7..c239942 100644
--- a/internal/lsp/workspace.go
+++ b/internal/lsp/workspace.go
@@ -86,10 +86,11 @@
 		}()
 	}
 
+	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{semanticTokenRegistration()},
+			Registrations: []protocol.Registration{registration},
 		}); err != nil {
 			return err
 		}
@@ -97,8 +98,8 @@
 		if err := s.client.UnregisterCapability(ctx, &protocol.UnregistrationParams{
 			Unregisterations: []protocol.Unregistration{
 				{
-					ID:     semanticTokenRegistration().ID,
-					Method: semanticTokenRegistration().Method,
+					ID:     registration.ID,
+					Method: registration.Method,
 				},
 			},
 		}); err != nil {
@@ -108,7 +109,7 @@
 	return nil
 }
 
-func semanticTokenRegistration() protocol.Registration {
+func semanticTokenRegistration(tokenTypes, tokenModifiers []string) protocol.Registration {
 	return protocol.Registration{
 		ID:     "textDocument/semanticTokens",
 		Method: "textDocument/semanticTokens",
@@ -116,8 +117,8 @@
 			Legend: protocol.SemanticTokensLegend{
 				// TODO(pjw): trim these to what we use (and an unused one
 				// at position 0 of TokTypes, to catch typos)
-				TokenTypes:     SemanticTypes(),
-				TokenModifiers: SemanticModifiers(),
+				TokenTypes:     tokenTypes,
+				TokenModifiers: tokenModifiers,
 			},
 			Full:  true,
 			Range: true,