| 75 | } |
| 76 | |
| 77 | bool ValidateDurations(ValidationContext& context) { |
| 78 | bool valid = true; |
| 79 | for (const auto& node : |
| 80 | context.navigable_ast().Root().DescendantsPostorder()) { |
| 81 | if (node.node_kind() != NodeKind::kCall || |
| 82 | node.expr()->call_expr().function() != StandardFunctions::kDuration) { |
| 83 | continue; |
| 84 | } |
| 85 | if (node.children().size() != 1) { |
| 86 | // Checker should have already reported an error. |
| 87 | continue; |
| 88 | } |
| 89 | const NavigableAstNode& child = *node.children()[0]; |
| 90 | if (child.node_kind() != NodeKind::kConstant) { |
| 91 | // Not a literal, so nothing to do. |
| 92 | continue; |
| 93 | } |
| 94 | const Constant& constant = child.expr()->const_expr(); |
| 95 | if (!constant.has_string_value()) { |
| 96 | continue; |
| 97 | } |
| 98 | absl::Duration duration; |
| 99 | |
| 100 | absl::string_view duration_str = child.expr()->const_expr().string_value(); |
| 101 | if (!absl::ParseDuration(duration_str, &duration)) { |
| 102 | context.ReportErrorAt(child.expr()->id(), "invalid duration literal"); |
| 103 | valid = false; |
| 104 | continue; |
| 105 | } |
| 106 | |
| 107 | if (absl::Status status = internal::ValidateDuration(duration); |
| 108 | !status.ok()) { |
| 109 | context.ReportErrorAt( |
| 110 | child.expr()->id(), |
| 111 | absl::StrCat("invalid duration literal: ", status.message())); |
| 112 | valid = false; |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | return valid; |
| 117 | } |
| 118 | |
| 119 | } // namespace |
| 120 |
nothing calls this directly
no test coverage detected