Skip to content

Commit fcadc2d

Browse files
authored
LSP fix file imports for user defined WKT (#4093)
1 parent 2adfdc0 commit fcadc2d

File tree

1 file changed

+13
-14
lines changed

1 file changed

+13
-14
lines changed

private/buf/buflsp/file.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -361,15 +361,15 @@ func (f *file) IndexImports(ctx context.Context) {
361361
if f.importToFile != nil {
362362
return
363363
}
364-
importables, err := f.findImportable(ctx)
364+
fileInfos, err := f.getWorkspaceFileInfos(ctx)
365365
if err != nil {
366366
f.lsp.logger.Error(
367367
"failed to get importable files",
368368
slog.String("file", f.uri.Filename()),
369369
)
370370
}
371371
f.importToFile = make(map[string]*file)
372-
for _, importable := range importables {
372+
for _, importable := range fileInfos {
373373
if importable.ExternalPath() == f.uri.Filename() {
374374
f.objectInfo = importable
375375
if err := f.ReadFromDisk(ctx); err != nil {
@@ -396,39 +396,38 @@ func (f *file) IndexImports(ctx context.Context) {
396396
}
397397
}
398398

399-
// findImportable finds all files that can potentially be imported by the proto file, f.
399+
// getWorkspaceFileInfos returns all files within the workspace.
400400
//
401401
// Note that this performs no validation on these files, because those files might be open in the
402402
// editor and might contain invalid syntax at the moment. We only want to get their paths and nothing
403403
// more.
404404
//
405405
// This operation requires RefreshWorkspace.
406-
func (f *file) findImportable(ctx context.Context) ([]storage.ObjectInfo, error) {
407-
// This does not use Controller.GetImportableImageFileInfos because that function does
408-
// not specify which of the files it returns are well-known types. We can use heuristics
409-
// based on the path to try and guess which files are well-known types, but this can be
410-
// fragile. Instead we explicitly walk the well-known types bucket instead.
411-
//
412-
// We track the imports in a map to dedup by import path.
413-
imports := make(map[string]storage.ObjectInfo)
406+
func (f *file) getWorkspaceFileInfos(ctx context.Context) ([]storage.ObjectInfo, error) {
407+
seen := make(map[string]struct{})
408+
var fileInfos []storage.ObjectInfo
414409
for _, module := range f.workspace.Modules() {
415410
if err := module.WalkFileInfos(ctx, func(fileInfo bufmodule.FileInfo) error {
416411
if fileInfo.FileType() != bufmodule.FileTypeProto {
417412
return nil
418413
}
419-
imports[fileInfo.Path()] = fileInfo
414+
fileInfos = append(fileInfos, fileInfo)
415+
seen[fileInfo.Path()] = struct{}{}
420416
return nil
421417
}); err != nil {
422418
return nil, err
423419
}
424420
}
421+
// Add all wellknown types if not provided within the workspace.
425422
if err := f.lsp.wktBucket.Walk(ctx, "", func(objectInfo storage.ObjectInfo) error {
426-
imports[objectInfo.Path()] = wktObjectInfo{objectInfo}
423+
if _, ok := seen[objectInfo.Path()]; !ok {
424+
fileInfos = append(fileInfos, wktObjectInfo{objectInfo})
425+
}
427426
return nil
428427
}); err != nil {
429428
return nil, err
430429
}
431-
return xslices.MapValuesToSlice(imports), nil
430+
return fileInfos, nil
432431
}
433432

434433
// RefreshIR queries for the IR of the file and the IR of each import file.

0 commit comments

Comments
 (0)