| 211 | bool HasErrors() const { return error_count_ != 0; } |
| 212 | |
| 213 | std::string ErrorMessage() { |
| 214 | // Errors are collected as they are encountered, not by their location |
| 215 | // within the source. To have a more stable error message as implementation |
| 216 | // details change, we sort the collected errors by their source location |
| 217 | // first. |
| 218 | std::stable_sort( |
| 219 | errors_.begin(), errors_.end(), |
| 220 | [](const ParserError& lhs, const ParserError& rhs) -> bool { |
| 221 | auto lhs_begin = PositiveOrMax(lhs.range.begin); |
| 222 | auto lhs_end = PositiveOrMax(lhs.range.end); |
| 223 | auto rhs_begin = PositiveOrMax(rhs.range.begin); |
| 224 | auto rhs_end = PositiveOrMax(rhs.range.end); |
| 225 | return lhs_begin < rhs_begin || |
| 226 | (lhs_begin == rhs_begin && lhs_end < rhs_end); |
| 227 | }); |
| 228 | // Build the summary error message using the sorted errors. |
| 229 | bool errors_truncated = error_count_ > 100; |
| 230 | std::vector<std::string> messages; |
| 231 | messages.reserve( |
| 232 | errors_.size() + |
| 233 | errors_truncated); // Reserve space for the transform and an |
| 234 | // additional element when truncation occurs. |
| 235 | std::transform(errors_.begin(), errors_.end(), std::back_inserter(messages), |
| 236 | [this](const ParserError& error) { |
| 237 | return cel::DisplayParserError(source_, error); |
| 238 | }); |
| 239 | if (errors_truncated) { |
| 240 | messages.emplace_back( |
| 241 | absl::StrCat(error_count_ - 100, " more errors were truncated.")); |
| 242 | } |
| 243 | return absl::StrJoin(messages, "\n"); |
| 244 | } |
| 245 | |
| 246 | void AddMacroCall(int64_t macro_id, absl::string_view function, |
| 247 | absl::optional<Expr> target, std::vector<Expr> arguments) { |
nothing calls this directly
no test coverage detected