Repository: go
Issue: x/tools/internal/span: URI.IsFile() should support file:/absolute/path URIs
Labels: NeedsInvestigation,Tools

gopls v0.7.3 with Eclipse LSP4e 0.13.8 is breaking as LSP4e sends local file URIs with a single `/` (protocol trace below).  This causes [internal/span.URI.IsFile()](https://github.com/golang/tools/blob/e9000123914f47adec7b3e4c27e022ab6b7bf4b7/internal/span/uri.go#L23-L25) to reject the URI as a `file:` URI:
```golang
func (uri URI) IsFile() bool {
	return strings.HasPrefix(string(uri), "file://")
}
```

and leads to gopls [rejecting the workspace folder](https://github.com/golang/tools/blob/e9000123914f47adec7b3e4c27e022ab6b7bf4b7/internal/lsp/general.go#L68-L79):
```
unsupported URI schemes: [{file:/Users/bdealwis/Projects/Skaffold/repo-skaffold skaffold}] (gopls only supports file URIs)
```

The `file:` scheme an absolute path is a permitted value under [RFC8089 (_The "file" URI Scheme_)](https://datatracker.ietf.org/doc/html/rfc8089#section-2) as the `file-hier-part` can be a `local-path`, which in turn is an `path-absolute`

```
file-URI       = file-scheme ":" file-hier-part
file-scheme    = "file"
file-hier-part = ( "//" auth-path )
                     / local-path
local-path     = path-absolute
```

`path-absolute` is referenced from [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#appendix-A):
```
path-absolute = "/" [ segment-nz *( "/" segment ) ]
segment       = *pchar
segment-nz    = 1*pchar
```

Although the protocol trace shows Eclipse LSP4e is inconsistently using both `file:///` and `file:/` URIs, gopls should not reject permitted values.

And indeed Go's `net/url.Parse()` [has tests to ensure support of `file:/` URIs](https://github.com/golang/go/blob/f229e7031a6efb2f23241b5da000c3b3203081d6/src/cmd/go/internal/web/url_other_test.go#L20-L24).

<details>
<summary>pretty-printed protocol trace</summary>

```
[t=1636554142972] LSP4E to ca.mt.gore.server:
{
  "jsonrpc": "2.0",
  "id": "1",
  "method": "initialize",
  "params": {
    "processId": 58708,
    "rootPath": "/Users/bdealwis/Projects/Skaffold/repo-skaffold/",
    "rootUri": "file:///Users/bdealwis/Projects/Skaffold/repo-skaffold/",
    "initializationOptions": {
      "experimentalWorkspaceModule": false,
      "experimentalDiagnosticsDelay": "100ms",
      "codelenses": {
        "test": true
      }
    },
    "capabilities": {
      "workspace": {
        "applyEdit": true,
        "workspaceEdit": {
          "documentChanges": true,
          "resourceOperations": [
            "create",
            "delete",
            "rename"
          ],
          "failureHandling": "undo"
        },
        "symbol": {
          "dynamicRegistration": true
        },
        "executeCommand": {
          "dynamicRegistration": true
        },
        "workspaceFolders": true
      },
      "textDocument": {
        "synchronization": {
          "willSave": true,
          "willSaveWaitUntil": true,
          "didSave": true
        },
        "completion": {
          "completionItem": {
            "snippetSupport": true,
            "documentationFormat": [
              "markdown",
              "plaintext"
            ]
          }
        },
        "hover": {
          "contentFormat": [
            "markdown",
            "plaintext"
          ]
        },
        "signatureHelp": {},
        "references": {},
        "documentHighlight": {},
        "documentSymbol": {
          "symbolKind": {
            "valueSet": [18,17,5,14,9,10,22,24,8,1,12,11,20,6,2,3,21,16,19,25,4,7,15,23,26,13]
          },
          "hierarchicalDocumentSymbolSupport": true
        },
        "formatting": {
          "dynamicRegistration": true
        },
        "rangeFormatting": {},
        "definition": {
          "linkSupport": true
        },
        "typeDefinition": {
          "linkSupport": true
        },
        "codeAction": {
          "codeActionLiteralSupport": {
            "codeActionKind": {
              "valueSet": [
                "quickfix",
                "refactor",
                "refactor.extract",
                "refactor.inline",
                "refactor.rewrite",
                "source",
                "source.organizeImports"
              ]
            }
          },
          "dynamicRegistration": true
        },
        "codeLens": {},
        "documentLink": {},
        "colorProvider": {},
        "rename": {},
        "foldingRange": {}
      }
    },
    "clientName": "Eclipse IDE",
    "trace": "messages",
    "workspaceFolders": [
      {
        "uri": "file:/Users/bdealwis/Projects/Skaffold/repo-skaffold",
        "name": "skaffold"
      }
    ]
  }
}

[t=1636554143277] ca.mt.gore.server to LSP4E:
{
  "jsonrpc": "2.0",
  "error": {
    "code": 0,
    "message": "unsupported URI schemes: [{file:/Users/bdealwis/Projects/Skaffold/repo-skaffold skaffold}] (gopls only supports file URIs)"
  },
  "id": "1"
}
```

(`ca.mt.gore.server` is a [simple Eclipse plugin](https://github.com/briandealwis/gore) to install and configure `gopls` for Eclipse.)
</details>