Ident node handler. Invoked after child nodes are processed.
| 792 | // Ident node handler. |
| 793 | // Invoked after child nodes are processed. |
| 794 | void PostVisitIdent(const cel::Expr& expr, |
| 795 | const cel::IdentExpr& ident_expr) override { |
| 796 | if (!progress_status_.ok()) { |
| 797 | return; |
| 798 | } |
| 799 | absl::string_view path = ident_expr.name(); |
| 800 | if (!ValidateOrError( |
| 801 | !path.empty(), |
| 802 | "Invalid expression: identifier 'name' must not be empty")) { |
| 803 | return; |
| 804 | } |
| 805 | |
| 806 | // Check if this is a local variable first (since it should shadow most |
| 807 | // other interpretations). |
| 808 | SlotLookupResult slot = LookupSlot(path); |
| 809 | |
| 810 | if (slot.subexpression >= 0) { |
| 811 | auto* subexpression = |
| 812 | program_builder_.GetExtractedSubexpression(slot.subexpression); |
| 813 | if (subexpression == nullptr) { |
| 814 | SetProgressStatusError( |
| 815 | absl::InternalError("bad subexpression reference")); |
| 816 | return; |
| 817 | } |
| 818 | if (subexpression->IsRecursive()) { |
| 819 | const auto& program = subexpression->recursive_program(); |
| 820 | SetRecursiveStep( |
| 821 | CreateDirectLazyInitStep(slot.slot, program.step.get(), expr.id()), |
| 822 | program.depth + 1); |
| 823 | } else { |
| 824 | // Off by one since mainline expression will be index 0. |
| 825 | AddStep( |
| 826 | CreateLazyInitStep(slot.slot, slot.subexpression + 1, expr.id())); |
| 827 | } |
| 828 | return; |
| 829 | } else if (slot.slot >= 0) { |
| 830 | if (options_.max_recursion_depth != 0) { |
| 831 | SetRecursiveStep( |
| 832 | CreateDirectSlotIdentStep(ident_expr.name(), slot.slot, expr.id()), |
| 833 | 1); |
| 834 | } else { |
| 835 | AddStep( |
| 836 | CreateIdentStepForSlot(ident_expr.name(), slot.slot, expr.id())); |
| 837 | } |
| 838 | return; |
| 839 | } |
| 840 | |
| 841 | // Attempt to resolve a select expression as a namespaced identifier for an |
| 842 | // enum or type constant value. |
| 843 | absl::optional<cel::Value> const_value; |
| 844 | int64_t select_root_id = -1; |
| 845 | std::string path_candidate; |
| 846 | |
| 847 | while (!namespace_stack_.empty()) { |
| 848 | const auto& select_node = namespace_stack_.front(); |
| 849 | // Generate path in format "<ident>.<field 0>.<field 1>...". |
| 850 | const cel::Expr* select_expr = select_node.first; |
| 851 | path_candidate = absl::StrCat(path, ".", select_node.second); |
nothing calls this directly
no test coverage detected