golang.org/x/tools/gopls@v0.15.3/internal/cache/fs_overlay.go (about) 1 // Copyright 2023 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 cache 6 7 import ( 8 "context" 9 "sync" 10 11 "golang.org/x/tools/gopls/internal/file" 12 "golang.org/x/tools/gopls/internal/protocol" 13 ) 14 15 // An overlayFS is a file.Source that keeps track of overlays on top of a 16 // delegate FileSource. 17 type overlayFS struct { 18 delegate file.Source 19 20 mu sync.Mutex 21 overlays map[protocol.DocumentURI]*overlay 22 } 23 24 func newOverlayFS(delegate file.Source) *overlayFS { 25 return &overlayFS{ 26 delegate: delegate, 27 overlays: make(map[protocol.DocumentURI]*overlay), 28 } 29 } 30 31 // Overlays returns a new unordered array of overlays. 32 func (fs *overlayFS) Overlays() []*overlay { 33 fs.mu.Lock() 34 defer fs.mu.Unlock() 35 overlays := make([]*overlay, 0, len(fs.overlays)) 36 for _, overlay := range fs.overlays { 37 overlays = append(overlays, overlay) 38 } 39 return overlays 40 } 41 42 func (fs *overlayFS) ReadFile(ctx context.Context, uri protocol.DocumentURI) (file.Handle, error) { 43 fs.mu.Lock() 44 overlay, ok := fs.overlays[uri] 45 fs.mu.Unlock() 46 if ok { 47 return overlay, nil 48 } 49 return fs.delegate.ReadFile(ctx, uri) 50 } 51 52 // An overlay is a file open in the editor. It may have unsaved edits. 53 // It implements the file.Handle interface, and the implicit contract 54 // of the debug.FileTmpl template. 55 type overlay struct { 56 uri protocol.DocumentURI 57 content []byte 58 hash file.Hash 59 version int32 60 kind file.Kind 61 62 // saved is true if a file matches the state on disk, 63 // and therefore does not need to be part of the overlay sent to go/packages. 64 saved bool 65 } 66 67 func (o *overlay) URI() protocol.DocumentURI { return o.uri } 68 69 func (o *overlay) Identity() file.Identity { 70 return file.Identity{ 71 URI: o.uri, 72 Hash: o.hash, 73 } 74 } 75 76 func (o *overlay) Content() ([]byte, error) { return o.content, nil } 77 func (o *overlay) Version() int32 { return o.version } 78 func (o *overlay) SameContentsOnDisk() bool { return o.saved } 79 func (o *overlay) Kind() file.Kind { return o.kind }