internal/lsp: Check if user's editor support rename operation

Change-Id: Iadda768e93eda1d53fa00a5ff8a28013a575ef57
Reviewed-on: https://go-review.googlesource.com/c/tools/+/419774
Run-TryBot: Dylan Le <dungtuanle@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
diff --git a/internal/lsp/source/rename.go b/internal/lsp/source/rename.go
index 503422a..b6f0e65 100644
--- a/internal/lsp/source/rename.go
+++ b/internal/lsp/source/rename.go
@@ -49,6 +49,29 @@
 // the prepare fails. Probably we could eliminate the redundancy in returning
 // two errors, but for now this is done defensively.
 func PrepareRename(ctx context.Context, snapshot Snapshot, f FileHandle, pp protocol.Position) (_ *PrepareItem, usererr, err error) {
+	fileRenameSupported := false
+	for _, op := range snapshot.View().Options().SupportedResourceOperations {
+		if op == protocol.Rename {
+			fileRenameSupported = true
+			break
+		}
+	}
+
+	// Find position of the package name declaration
+	pgf, err := snapshot.ParseGo(ctx, f, ParseFull)
+	if err != nil {
+		return nil, err, err
+	}
+	inPackageName, err := isInPackageName(ctx, snapshot, f, pgf, pp)
+	if err != nil {
+		return nil, err, err
+	}
+
+	if inPackageName && !fileRenameSupported {
+		err := errors.New("can't rename packages: LSP client does not support file renaming")
+		return nil, err, err
+	}
+
 	ctx, done := event.Start(ctx, "source.PrepareRename")
 	defer done()