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: retrieves a list of packages
119	// that are importable from the given URI.
120	ListKnownPackages(context.Context, URIArg) (ListKnownPackagesResult, error)
121
122	// AddImport: asks the server to add an import path to a given Go file.
123	// The method will call applyEdit on the client so that clients don't have
124	// to apply the edit themselves.
125	AddImport(context.Context, AddImportArgs) error
126
127	WorkspaceMetadata(context.Context) (WorkspaceMetadataResult, error)
128
129	StartDebugging(context.Context, DebuggingArgs) (DebuggingResult, error)
130}
131
132type RunTestsArgs struct {
133	// The test file containing the tests to run.
134	URI protocol.DocumentURI
135
136	// Specific test names to run, e.g. TestFoo.
137	Tests []string
138
139	// Specific benchmarks to run, e.g. BenchmarkFoo.
140	Benchmarks []string
141}
142
143type GenerateArgs struct {
144	// URI for the directory to generate.
145	Dir protocol.DocumentURI
146
147	// Whether to generate recursively (go generate ./...)
148	Recursive bool
149}
150
151// TODO(rFindley): document the rest of these once the docgen is fleshed out.
152
153type ApplyFixArgs struct {
154	// The fix to apply.
155	Fix string
156	// The file URI for the document to fix.
157	URI protocol.DocumentURI
158	// The document range to scan for fixes.
159	Range protocol.Range
160}
161
162type URIArg struct {
163	// The file URI.
164	URI protocol.DocumentURI
165}
166
167type URIArgs struct {
168	// The file URIs.
169	URIs []protocol.DocumentURI
170}
171
172type CheckUpgradesArgs struct {
173	// The go.mod file URI.
174	URI protocol.DocumentURI
175	// The modules to check.
176	Modules []string
177}
178
179type DependencyArgs struct {
180	// The go.mod file URI.
181	URI protocol.DocumentURI
182	// Additional args to pass to the go command.
183	GoCmdArgs []string
184	// Whether to add a require directive.
185	AddRequire bool
186}
187
188type RemoveDependencyArgs struct {
189	// The go.mod file URI.
190	URI protocol.DocumentURI
191	// The module path to remove.
192	ModulePath     string
193	OnlyDiagnostic bool
194}
195
196type GoGetPackageArgs struct {
197	// Any document URI within the relevant module.
198	URI protocol.DocumentURI
199	// The package to go get.
200	Pkg        string
201	AddRequire bool
202}
203
204type AddImportArgs struct {
205	// ImportPath is the target import path that should
206	// be added to the URI file
207	ImportPath string
208	// URI is the file that the ImportPath should be
209	// added to
210	URI protocol.DocumentURI
211}
212
213type ListKnownPackagesResult struct {
214	// Packages is a list of packages relative
215	// to the URIArg passed by the command request.
216	// In other words, it omits paths that are already
217	// imported or cannot be imported due to compiler
218	// restrictions.
219	Packages []string
220}
221
222type WorkspaceMetadataArgs struct {
223}
224
225type WorkspaceMetadataResult struct {
226	Workspaces []Workspace
227}
228
229type Workspace struct {
230	Name      string
231	ModuleDir string
232}
233
234type DebuggingArgs struct {
235	// Optional: the address (including port) for the debug server to listen on.
236	// If not provided, the debug server will bind to "localhost:0", and the
237	// full debug URL will be contained in the result.
238	//
239	// If there is more than one gopls instance along the serving path (i.e. you
240	// are using a daemon), each gopls instance will attempt to start debugging.
241	// If Addr specifies a port, only the daemon will be able to bind to that
242	// port, and each intermediate gopls instance will fail to start debugging.
243	// For this reason it is recommended not to specify a port (or equivalently,
244	// to specify ":0").
245	//
246	// If the server was already debugging this field has no effect, and the
247	// result will contain the previously configured debug URL(s).
248	Addr string
249}
250
251type DebuggingResult struct {
252	// The URLs to use to access the debug servers, for all gopls instances in
253	// the serving path. For the common case of a single gopls instance (i.e. no
254	// daemon), this will be exactly one address.
255	//
256	// In the case of one or more gopls instances forwarding the LSP to a daemon,
257	// URLs will contain debug addresses for each server in the serving path, in
258	// serving order. The daemon debug address will be the last entry in the
259	// slice. If any intermediate gopls instance fails to start debugging, no
260	// error will be returned but the debug URL for that server in the URLs slice
261	// will be empty.
262	URLs []string
263}
264