1717#include < cstddef>
1818#include < cstdint>
1919#include < memory>
20+ #include < optional>
2021#include < string>
2122#include < utility>
2223#include < vector>
@@ -1176,11 +1177,13 @@ class ResolveRewriter : public AstRewriterBase {
11761177 explicit ResolveRewriter (const ResolveVisitor& visitor,
11771178 const TypeInferenceContext& inference_context,
11781179 const CheckerOptions& options,
1179- Ast::ReferenceMap& references, Ast::TypeMap& types)
1180+ Ast::ReferenceMap& references, Ast::TypeMap& types,
1181+ ValidationResult::TypeMap& resolved_types)
11801182 : visitor_(visitor),
11811183 inference_context_(inference_context),
11821184 reference_map_(references),
11831185 type_map_(types),
1186+ resolved_types_(resolved_types),
11841187 options_(options) {}
11851188 bool PostVisitRewrite (Expr& expr) override {
11861189 bool rewritten = false ;
@@ -1235,6 +1238,7 @@ class ResolveRewriter : public AstRewriterBase {
12351238 return rewritten;
12361239 }
12371240 type_map_[expr.id ()] = *std::move (flattened_type);
1241+ resolved_types_[expr.id ()] = iter->second ;
12381242 rewritten = true ;
12391243 }
12401244
@@ -1249,23 +1253,28 @@ class ResolveRewriter : public AstRewriterBase {
12491253 const TypeInferenceContext& inference_context_;
12501254 Ast::ReferenceMap& reference_map_;
12511255 Ast::TypeMap& type_map_;
1256+ ValidationResult::TypeMap& resolved_types_;
12521257 const CheckerOptions& options_;
12531258};
12541259
12551260} // namespace
12561261
1257- absl::StatusOr<ValidationResult> TypeCheckerImpl::Check (
1258- std::unique_ptr<Ast> ast) const {
1259- google::protobuf::Arena type_arena;
1262+ absl::StatusOr<ValidationResult> TypeCheckerImpl::CheckImpl (
1263+ std::unique_ptr<Ast> ast, google::protobuf::Arena* arena) const {
1264+ std::optional<google::protobuf::Arena> type_arena;
1265+ if (arena == nullptr ) {
1266+ type_arena.emplace ();
1267+ arena = &(*type_arena);
1268+ }
12601269
12611270 std::vector<TypeCheckIssue> issues;
12621271 CEL_ASSIGN_OR_RETURN (auto generator,
12631272 NamespaceGenerator::Create (env_.container ()));
12641273
12651274 TypeInferenceContext type_inference_context (
1266- &type_arena , options_.enable_legacy_null_assignment );
1275+ arena , options_.enable_legacy_null_assignment );
12671276 ResolveVisitor visitor (std::move (generator), env_, *ast,
1268- type_inference_context, issues, &type_arena );
1277+ type_inference_context, issues, arena );
12691278
12701279 TraversalOptions opts;
12711280 opts.use_comprehension_callbacks = true ;
@@ -1310,9 +1319,10 @@ absl::StatusOr<ValidationResult> TypeCheckerImpl::Check(
13101319 // Apply updates as needed.
13111320 // Happens in a second pass to simplify validating that pointers haven't
13121321 // been invalidated by other updates.
1322+ ValidationResult::TypeMap resolved_types;
13131323 ResolveRewriter rewriter (visitor, type_inference_context, options_,
13141324 ast->mutable_reference_map (),
1315- ast->mutable_type_map ());
1325+ ast->mutable_type_map (), resolved_types );
13161326 AstRewrite (ast->mutable_root_expr (), rewriter);
13171327
13181328 CEL_RETURN_IF_ERROR (rewriter.status ());
@@ -1325,7 +1335,15 @@ absl::StatusOr<ValidationResult> TypeCheckerImpl::Check(
13251335 {cel::ExtensionSpec::Component::kRuntime }));
13261336 }
13271337
1328- return ValidationResult (std::move (ast), std::move (issues));
1338+ auto result = ValidationResult (std::move (ast), std::move (issues));
1339+ if (!type_arena.has_value ()) {
1340+ // cel::Type values will expire after this function returns when the local
1341+ // arena is destructed. Only set the resolved type map if we're using the
1342+ // caller's arena.
1343+ result.SetResolvedTypeMap (std::move (resolved_types));
1344+ }
1345+
1346+ return result;
13291347}
13301348
13311349std::unique_ptr<TypeCheckerBuilder> TypeCheckerImpl::ToBuilder () const {
0 commit comments