| // 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 |