.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.1-0.20210319172145-bda8f5cee399 / internal / lsp / server.go
1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Package lsp implements LSP for gopls.
6 package lsp
7
8 import (
9         "context"
10         "fmt"
11         "sync"
12
13         "golang.org/x/tools/internal/jsonrpc2"
14         "golang.org/x/tools/internal/lsp/protocol"
15         "golang.org/x/tools/internal/lsp/source"
16         "golang.org/x/tools/internal/span"
17         errors "golang.org/x/xerrors"
18 )
19
20 const concurrentAnalyses = 1
21
22 // NewServer creates an LSP server and binds it to handle incoming client
23 // messages on on the supplied stream.
24 func NewServer(session source.Session, client protocol.Client) *Server {
25         return &Server{
26                 diagnostics:           map[span.URI]*fileReports{},
27                 gcOptimizationDetails: make(map[string]struct{}),
28                 watchedGlobPatterns:   make(map[string]struct{}),
29                 changedFiles:          make(map[span.URI]struct{}),
30                 session:               session,
31                 client:                client,
32                 diagnosticsSema:       make(chan struct{}, concurrentAnalyses),
33                 progress:              newProgressTracker(client),
34                 debouncer:             newDebouncer(),
35         }
36 }
37
38 type serverState int
39
40 const (
41         serverCreated      = serverState(iota)
42         serverInitializing // set once the server has received "initialize" request
43         serverInitialized  // set once the server has received "initialized" request
44         serverShutDown
45 )
46
47 func (s serverState) String() string {
48         switch s {
49         case serverCreated:
50                 return "created"
51         case serverInitializing:
52                 return "initializing"
53         case serverInitialized:
54                 return "initialized"
55         case serverShutDown:
56                 return "shutDown"
57         }
58         return fmt.Sprintf("(unknown state: %d)", int(s))
59 }
60
61 // Server implements the protocol.Server interface.
62 type Server struct {
63         client protocol.Client
64
65         stateMu sync.Mutex
66         state   serverState
67
68         session   source.Session
69         clientPID int
70
71         // notifications generated before serverInitialized
72         notifications []*protocol.ShowMessageParams
73
74         // changedFiles tracks files for which there has been a textDocument/didChange.
75         changedFilesMu sync.Mutex
76         changedFiles   map[span.URI]struct{}
77
78         // folders is only valid between initialize and initialized, and holds the
79         // set of folders to build views for when we are ready
80         pendingFolders []protocol.WorkspaceFolder
81
82         // watchedGlobPatterns is the set of glob patterns that we have requested
83         // the client watch on disk. It will be updated as the set of directories
84         // that the server should watch changes.
85         watchedGlobPatternsMu  sync.Mutex
86         watchedGlobPatterns    map[string]struct{}
87         watchRegistrationCount int
88
89         diagnosticsMu sync.Mutex
90         diagnostics   map[span.URI]*fileReports
91
92         // gcOptimizationDetails describes the packages for which we want
93         // optimization details to be included in the diagnostics. The key is the
94         // ID of the package.
95         gcOptimizationDetailsMu sync.Mutex
96         gcOptimizationDetails   map[string]struct{}
97
98         // diagnosticsSema limits the concurrency of diagnostics runs, which can be
99         // expensive.
100         diagnosticsSema chan struct{}
101
102         progress *progressTracker
103
104         // debouncer is used for debouncing diagnostics.
105         debouncer *debouncer
106
107         // When the workspace fails to load, we show its status through a progress
108         // report with an error message.
109         criticalErrorStatusMu sync.Mutex
110         criticalErrorStatus   *workDone
111 }
112
113 func (s *Server) workDoneProgressCancel(ctx context.Context, params *protocol.WorkDoneProgressCancelParams) error {
114         return s.progress.cancel(ctx, params.Token)
115 }
116
117 func (s *Server) nonstandardRequest(ctx context.Context, method string, params interface{}) (interface{}, error) {
118         switch method {
119         case "gopls/diagnoseFiles":
120                 paramMap := params.(map[string]interface{})
121                 for _, file := range paramMap["files"].([]interface{}) {
122                         snapshot, fh, ok, release, err := s.beginFileRequest(ctx, protocol.DocumentURI(file.(string)), source.UnknownKind)
123                         defer release()
124                         if !ok {
125                                 return nil, err
126                         }
127
128                         fileID, diagnostics, err := source.FileDiagnostics(ctx, snapshot, fh.URI())
129                         if err != nil {
130                                 return nil, err
131                         }
132                         if err := s.client.PublishDiagnostics(ctx, &protocol.PublishDiagnosticsParams{
133                                 URI:         protocol.URIFromSpanURI(fh.URI()),
134                                 Diagnostics: toProtocolDiagnostics(diagnostics),
135                                 Version:     fileID.Version,
136                         }); err != nil {
137                                 return nil, err
138                         }
139                 }
140                 if err := s.client.PublishDiagnostics(ctx, &protocol.PublishDiagnosticsParams{
141                         URI: "gopls://diagnostics-done",
142                 }); err != nil {
143                         return nil, err
144                 }
145                 return struct{}{}, nil
146         }
147         return nil, notImplemented(method)
148 }
149
150 func notImplemented(method string) error {
151         return errors.Errorf("%w: %q not yet implemented", jsonrpc2.ErrMethodNotFound, method)
152 }
153
154 //go:generate helper/helper -d protocol/tsserver.go -o server_gen.go -u .