1// Copyright 2021 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 command defines the interface provided by gopls for the
6// workspace/executeCommand LSP request.
7//
8// This interface is fully specified by the Interface type, provided it
9// conforms to the restrictions outlined in its doc string.
10//
11// Bindings for server-side command dispatch and client-side serialization are
12// also provided by this package, via code generation.
13package command
14
15//go:generate go run -tags=generate generate.go
16
17import (
18	"context"
19
20	"golang.org/x/tools/internal/lsp/protocol"
21)
22
23// Interface defines the interface gopls exposes for the
24// workspace/executeCommand request.
25//
26// This interface is used to generate marshaling/unmarshaling code, dispatch,
27// and documentation, and so has some additional restrictions:
28//  1. All method arguments must be JSON serializable.
29//  2. Methods must return either error or (T, error), where T is a
30//     JSON serializable type.
31//  3. The first line of the doc string is special. Everything after the colon
32//     is considered the command 'Title'.
33//     TODO(rFindley): reconsider this -- Title may be unnecessary.
34type Interface interface {
35	// ApplyFix: Apply a fix
36	//
37	// Applies a fix to a region of source code.
38	ApplyFix(context.Context, ApplyFixArgs) error
39	// Test: Run test(s) (legacy)
40	//
41	// Runs `go test` for a specific set of test or benchmark functions.
42	Test(context.Context, protocol.DocumentURI, []string, []string) error
43
44	// TODO: deprecate Test in favor of RunTests below.
45
46	// Test: Run test(s)
47	//
48	// Runs `go test` for a specific set of test or benchmark functions.
49	RunTests(context.Context, RunTestsArgs) error
50
51	// Generate: Run go generate
52	//
53	// Runs `go generate` for a given directory.
54	Generate(context.Context, GenerateArgs) error
55
56	// RegenerateCgo: Regenerate cgo
57	//
58	// Regenerates cgo definitions.
59	RegenerateCgo(context.Context, URIArg) error
60
61	// Tidy: Run go mod tidy
62	//
63	// Runs `go mod tidy` for a module.
64	Tidy(context.Context, URIArgs) error
65
66	// Vendor: Run go mod vendor
67	//
68	// Runs `go mod vendor` for a module.
69	Vendor(context.Context, URIArg) error
70
71	// UpdateGoSum: Update go.sum
72	//
73	// Updates the go.sum file for a module.
74	UpdateGoSum(context.Context, URIArgs) error
75
76	// CheckUpgrades: Check for upgrades
77	//
78	// Checks for module upgrades.
79	CheckUpgrades(context.Context, CheckUpgradesArgs) error
80
81	// AddDependency: Add dependency
82	//
83	// Adds a dependency to the go.mod file for a module.
84	AddDependency(context.Context, DependencyArgs) error
85
86	// UpgradeDependency: Upgrade dependency
87	//
88	// Upgrades a dependency in the go.mod file for a module.
89	UpgradeDependency(context.Context, DependencyArgs) error
90
91	// RemoveDependency: Remove dependency
92	//
93	// Removes a dependency from the go.mod file of a module.
94	RemoveDependency(context.Context, RemoveDependencyArgs) error
95
96	// GoGetPackage: go get package
97	//
98	// Runs `go get` to fetch a package.
99	GoGetPackage(context.Context, GoGetPackageArgs) error
100
101	// GCDetails: Toggle gc_details
102	//
103	// Toggle the calculation of gc annotations.
104	GCDetails(context.Context, protocol.DocumentURI) error
105
106	// TODO: deprecate GCDetails in favor of ToggleGCDetails below.
107
108	// ToggleGCDetails: Toggle gc_details
109	//
110	// Toggle the calculation of gc annotations.
111	ToggleGCDetails(context.Context, URIArg) error
112
113	// GenerateGoplsMod: Generate gopls.mod
114	//
115	// (Re)generate the gopls.mod file for a workspace.
116	GenerateGoplsMod(context.Context, URIArg) error
117
118	ListKnownPackages(context.Context, URIArg) (ListKnownPackagesResult, error)
119
120	AddImport(context.Context, AddImportArgs) (AddImportResult, error)
121
122	WorkspaceMetadata(context.Context) (WorkspaceMetadataResult, error)
123
124	StartDebugging(context.Context, DebuggingArgs) (DebuggingResult, error)
125}
126
127type RunTestsArgs struct {
128	// The test file containing the tests to run.
129	URI protocol.DocumentURI
130
131	// Specific test names to run, e.g. TestFoo.
132	Tests []string
133
134	// Specific benchmarks to run, e.g. BenchmarkFoo.
135	Benchmarks []string
136}
137
138type GenerateArgs struct {
139	// URI for the directory to generate.
140	Dir protocol.DocumentURI
141
142	// Whether to generate recursively (go generate ./...)
143	Recursive bool
144}
145
146// TODO(rFindley): document the rest of these once the docgen is fleshed out.
147
148type ApplyFixArgs struct {
149	// The fix to apply.
150	Fix string
151	// The file URI for the document to fix.
152	URI protocol.DocumentURI
153	// The document range to scan for fixes.
154	Range protocol.Range
155}
156
157type URIArg struct {
158	// The file URI.
159	URI protocol.DocumentURI
160}
161
162type URIArgs struct {
163	// The file URIs.
164	URIs []protocol.DocumentURI
165}
166
167type CheckUpgradesArgs struct {
168	// The go.mod file URI.
169	URI protocol.DocumentURI
170	// The modules to check.
171	Modules []string
172}
173
174type DependencyArgs struct {
175	// The go.mod file URI.
176	URI protocol.DocumentURI
177	// Additional args to pass to the go command.
178	GoCmdArgs []string
179	// Whether to add a require directive.
180	AddRequire bool
181}
182
183type RemoveDependencyArgs struct {
184	// The go.mod file URI.
185	URI protocol.DocumentURI
186	// The module path to remove.
187	ModulePath     string
188	OnlyDiagnostic bool
189}
190
191type GoGetPackageArgs struct {
192	// Any document URI within the relevant module.
193	URI protocol.DocumentURI
194	// The package to go get.
195	Pkg        string
196	AddRequire bool
197}
198
199// TODO (Marwan): document :)
200
201type AddImportArgs struct {
202	ImportPath string
203	URI        protocol.DocumentURI
204}
205
206type AddImportResult struct {
207	Edits []protocol.TextDocumentEdit
208}
209
210type ListKnownPackagesResult struct {
211	Packages []string
212}
213
214type WorkspaceMetadataArgs struct {
215}
216
217type WorkspaceMetadataResult struct {
218	Workspaces []Workspace
219}
220
221type Workspace struct {
222	Name      string
223	ModuleDir string
224}
225
226type DebuggingArgs struct {
227	// Optional: the address (including port) for the debug server to listen on.
228	// If not provided, the debug server will bind to "localhost:0", and the
229	// full debug URL will be contained in the result.
230	//
231	// If there is more than one gopls instance along the serving path (i.e. you
232	// are using a daemon), each gopls instance will attempt to start debugging.
233	// If Addr specifies a port, only the daemon will be able to bind to that
234	// port, and each intermediate gopls instance will fail to start debugging.
235	// For this reason it is recommended not to specify a port (or equivalently,
236	// to specify ":0").
237	//
238	// If the server was already debugging this field has no effect, and the
239	// result will contain the previously configured debug URL(s).
240	Addr string
241}
242
243type DebuggingResult struct {
244	// The URLs to use to access the debug servers, for all gopls instances in
245	// the serving path. For the common case of a single gopls instance (i.e. no
246	// daemon), this will be exactly one address.
247	//
248	// In the case of one or more gopls instances forwarding the LSP to a daemon,
249	// URLs will contain debug addresses for each server in the serving path, in
250	// serving order. The daemon debug address will be the last entry in the
251	// slice. If any intermediate gopls instance fails to start debugging, no
252	// error will be returned but the debug URL for that server in the URLs slice
253	// will be empty.
254	URLs []string
255}
256