| // Copyright 2021 The Verible Authors. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| // | |
| #ifndef VERILOG_TOOLS_LS_LSP_PARSE_BUFFER_H | |
| #define VERILOG_TOOLS_LS_LSP_PARSE_BUFFER_H | |
| #include <cstdint> | |
| #include "common/lsp/lsp-text-buffer.h" | |
| #include "verilog/analysis/verilog_analyzer.h" | |
| #include "verilog/analysis/verilog_linter.h" | |
| // ParseBuffer and BufferTrackerContainer are tracking fully parsed content | |
| // and are corresponding to verible::lsp::EditTextBuffer and | |
| // verible::lsp::BufferCollection that are responsible for tracking the | |
| // bare editor text. | |
| namespace verilog { | |
| // A parsed buffer collects all the artifacts generated from a text buffer | |
| // from parsing or running the linter. | |
| // | |
| // Right now, the ParsedBuffer is synchronously filling its internal structure | |
| // on construction, but plan is to do that on-demand and possibly with | |
| // std::future<>s evaluated in separate threads. | |
| class ParsedBuffer { | |
| public: | |
| ParsedBuffer(int64_t version, absl::string_view uri, | |
| absl::string_view content); | |
| bool parsed_successfully() const { | |
| return parser_->LexStatus().ok() && parser_->ParseStatus().ok(); | |
| } | |
| const verilog::VerilogAnalyzer &parser() const { return *parser_; } | |
| const std::vector<verible::LintRuleStatus> &lint_result() const { | |
| return lint_statuses_; | |
| } | |
| int64_t version() const { return version_; } | |
| const std::string &uri() const { return uri_; } | |
| private: | |
| const int64_t version_; | |
| const std::string uri_; | |
| const std::unique_ptr<verilog::VerilogAnalyzer> parser_; | |
| std::vector<verible::LintRuleStatus> lint_statuses_; | |
| }; | |
| // A buffer tracker tracks the EditTextBuffer content and keeps up to | |
| // two versions of ParsedBuffers - the latest, that might have parse errors, | |
| // and the last known good that parsed without errors (if available). | |
| class BufferTracker { | |
| public: | |
| void Update(const std::string &filename, | |
| const verible::lsp::EditTextBuffer &txt); | |
| const ParsedBuffer *current() const { return current_.get(); } | |
| const ParsedBuffer *last_good() const { return last_good_.get(); } | |
| private: | |
| // The same ParsedBuffer can in both, current and last_good, or last_good can | |
| // be an older version. Use shared_ptr to keep track of the reference count. | |
| std::shared_ptr<ParsedBuffer> current_; | |
| std::shared_ptr<ParsedBuffer> last_good_; | |
| }; | |
| // Container holding all buffer trackers keyed by file uri. | |
| // This is the correspondent to verible::lsp::BufferCollection that | |
| // internally stores | |
| class BufferTrackerContainer { | |
| public: | |
| // Return a callback that allows to subscribe to an lsp::BufferCollection | |
| // to update our internal state whenever the editor state changes. | |
| // (internally, they exercise Update() and Remove()) | |
| verible::lsp::BufferCollection::UriBufferCallback GetSubscriptionCallback(); | |
| // Add a change listener for clients of ours interested in updated fresly | |
| // parsed content. | |
| using ChangeCallback = | |
| std::function<void(const std::string &uri, const BufferTracker &tracker)>; | |
| void SetChangeListener(const ChangeCallback &cb) { change_listener_ = cb; } | |
| // Given the URI, find the associated parse buffer if it exists. | |
| const BufferTracker *FindBufferTrackerOrNull(const std::string &uri) const; | |
| private: | |
| // Update internal state of the given "uri" with the content of the text | |
| // buffer. Return the buffer tracker. | |
| BufferTracker *Update(const std::string &uri, | |
| const verible::lsp::EditTextBuffer &txt); | |
| // Remove the buffer tracker for the given "uri". | |
| void Remove(const std::string &uri) { buffers_.erase(uri); } | |
| ChangeCallback change_listener_ = nullptr; | |
| std::unordered_map<std::string, std::unique_ptr<BufferTracker>> buffers_; | |
| }; | |
| } // namespace verilog | |
| #endif // VERILOG_TOOLS_LS_LSP_PARSE_BUFFER_H |