-
Notifications
You must be signed in to change notification settings - Fork 135
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Store documents in a memdb-backed table (#771)
* internal/document: Decouple document types * internal/state: Decouple document state into memdb * internal/filesystem: reduce impl to simple OS FS + interface for DocumentStore Previously filesystem package had two major use cases, to offer a unified io/fs.FS interface for e.g. parsing *.tf or *.tfvars, which was implemented mostly via external library (spf13/afero). Secondly it also provided a direct full access to the "in-memory layer" of the filesystem for RPC handlers (e.g. didOpen, didChange, didClose, ...). These use cases rarely overlap throughout the codebase and so this lead to unnecessary imports of the `filesystem` package in places where we only needed either the OS-level FS or in-mem FS, but almost never both. This decoupling allows us to import `filesystem` or `state.DocumentStore` separately. Also, as we no longer need the in-mem backend of afero, it makes more sense to just reimplement the small part of the 3rd party library instead. * internal/hcl: Update references * internal/lsp: Update references * internal/source: Update references * internal/terraform: update references * internal/*: Update RPC handlers + custom cmds * replace last occurence of afero with osFs * internal/document: add tests and comments to Handle+DirHandle * internal/uri: refactor & add comments * internal/uri: introduce MustParseURI * internal/uri: account for VSCode's over-escaping of colon * internal/document: clean up handle logic & normalize URIs before saving * internal/uri: account for drive-letter normalization in VSCode
- Loading branch information
1 parent
6659c80
commit 9906c49
Showing
111 changed files
with
2,514 additions
and
2,415 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package document | ||
|
||
import ( | ||
"bytes" | ||
|
||
"github.com/hashicorp/terraform-ls/internal/source" | ||
) | ||
|
||
type Change interface { | ||
Text() string | ||
Range() *Range | ||
} | ||
|
||
type Changes []Change | ||
|
||
func ApplyChanges(original []byte, changes Changes) ([]byte, error) { | ||
if len(changes) == 0 { | ||
return original, nil | ||
} | ||
|
||
var buf bytes.Buffer | ||
_, err := buf.Write(original) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
for _, ch := range changes { | ||
err := applyDocumentChange(&buf, ch) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
return buf.Bytes(), nil | ||
} | ||
|
||
func applyDocumentChange(buf *bytes.Buffer, change Change) error { | ||
// if the range is nil, we assume it is full content change | ||
if change.Range() == nil { | ||
buf.Reset() | ||
_, err := buf.WriteString(change.Text()) | ||
return err | ||
} | ||
|
||
lines := source.MakeSourceLines("", buf.Bytes()) | ||
|
||
startByte, err := ByteOffsetForPos(lines, change.Range().Start) | ||
if err != nil { | ||
return err | ||
} | ||
endByte, err := ByteOffsetForPos(lines, change.Range().End) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
diff := endByte - startByte | ||
if diff > 0 { | ||
buf.Grow(diff) | ||
} | ||
|
||
beforeChange := make([]byte, startByte, startByte) | ||
copy(beforeChange, buf.Bytes()) | ||
afterBytes := buf.Bytes()[endByte:] | ||
afterChange := make([]byte, len(afterBytes), len(afterBytes)) | ||
copy(afterChange, afterBytes) | ||
|
||
buf.Reset() | ||
|
||
_, err = buf.Write(beforeChange) | ||
if err != nil { | ||
return err | ||
} | ||
_, err = buf.WriteString(change.Text()) | ||
if err != nil { | ||
return err | ||
} | ||
_, err = buf.Write(afterChange) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.