13#include <unordered_map>
32 : consumer_(std::move(
consumer)), all_warnings_disabled_{false} {}
51 template <
typename... T>
52 void Report(std::string_view diag, T &&...args) {
54 if (!IsEnabled(diag)) {
57 const auto &templ =
DiagFor(diag);
60 const auto in_flight_level = ComputeLevel(diag);
62 ReportHelper(templ, in_flight_level, std::forward<T>(args)...);
65 auto diag_str = std::string{diag};
66 if (!diag_counts_.contains(diag_str)) {
67 diag_counts_.insert({diag_str, 0});
69 diag_counts_[diag_str] += 1;
72 template <
typename... T>
73 void ReportPartner(std::string_view diag, std::size_t partner_index, T &&...args) {
74 const auto &parent_templ =
DiagFor(diag);
76 if (partner_index >= parent_templ.partner_diags().size()) {
77 Panic(fmt::format(
"partner index {} out of bounds for diag {}", partner_index, diag));
81 if (!IsEnabled(diag)) {
85 const auto &partner_templ = parent_templ.partner_diags().at(partner_index);
86 const auto in_flight_level = partner_templ.level();
88 ReportHelper(partner_templ, in_flight_level, std::forward<T>(args)...);
92 auto Style(
const T &t, fmt::text_style ts)
const {
93 return fmt::styled(t, consumer_->IsATty() ? ts : fmt::text_style{});
97 auto Bold(
const T &t)
const {
98 return Style(t, fmt::emphasis::bold);
104 std::unique_ptr<DiagConsumer> consumer_;
105 bool all_warnings_disabled_;
106 std::unordered_map<std::string, std::set<DiagLevel>> enabled_at_level_;
107 std::unordered_map<std::string, std::uint64_t> diag_counts_;
108 std::vector<InFlightDiag> in_flight_diags_;
110 template <
typename... T>
113 std::vector<std::string> raw_msg;
115 raw_msg = templ.
BuildDynamicMsg(*
this, in_flight_level, std::forward<T>(args)...);
116 }
catch (
const std::exception &e) {
117 Panic(fmt::format(
"{} build_message failed: {}:", templ.
name(), e.what()));
121 if (raw_msg.empty()) {
122 Panic(fmt::format(
"diagnostic {} raw_msg vector was empty", templ.
name()));
124 const std::string constructed_msg = ConstructMsgStr(in_flight_level, templ, raw_msg);
127 const auto in_flight = InFlightDiag{in_flight_level, constructed_msg, templ};
128 in_flight_diags_.push_back(in_flight);
129 consumer_->Consume(in_flight);
132 [[nodiscard]]
DiagLevel ComputeLevel(std::string_view diag)
const;
134 [[nodiscard]]
bool IsEnabled(std::string_view diag)
const;
136 [[nodiscard]] std::string ConstructMsgStr(
DiagLevel in_flight_level,
const DiagTempl &templ,
137 const std::vector<std::string> &msg)
const;
A customizable consumer for diagnostic messages.
Coordinates the generation and consumption of diagnostic messages.
std::uint64_t InFlightCountForLevel(DiagLevel level) const
void DisableAllWarnings()
void ReportPartner(std::string_view diag, std::size_t partner_index, T &&...args)
void DisableAtLevel(std::string_view diag, DiagLevel override)
void EnableAtLevel(std::string_view diag, DiagLevel override)
std::uint64_t InFlightCountFor(std::string_view diag) const
DiagEngine(std::unique_ptr< DiagConsumer > consumer)
auto Bold(const T &t) const
void UpgradeEnabledWarningsToErr()
DiagLevel EnabledAt(std::string_view diag) const
auto Style(const T &t, fmt::text_style ts) const
const DiagConsumer & consumer() const
void Report(std::string_view diag, T &&...args)
Defines a reusable template for standardized diagnostic reporting.
std::vector< std::string > BuildDynamicMsg(const DiagEngine &eng, const DiagLevel in_flight_level, Args &&...args) const
Builds a dynamic message for this DiagTempl based on the configured message builder.
std::string_view name() const
A DiagConsumer implementation that simply ignores the provided diagnostic.
void Panic(const StringViewSourceLoc &s) noexcept
DiagTempl DiagFor(std::string_view name)
Retrieves the DiagTempl corresponding to a given diagnostic name.