@@ -285,6 +285,155 @@ std::unique_ptr<DirectExpressionStep> CreateDirectLogicStep(
285285 }
286286}
287287
288+ class DirectNotStep : public DirectExpressionStep {
289+ public:
290+ explicit DirectNotStep (std::unique_ptr<DirectExpressionStep> operand,
291+ int64_t expr_id)
292+ : DirectExpressionStep(expr_id), operand_(std::move(operand)) {}
293+ absl::Status Evaluate (ExecutionFrameBase& frame, Value& result,
294+ AttributeTrail& attribute_trail) const override ;
295+
296+ private:
297+ std::unique_ptr<DirectExpressionStep> operand_;
298+ };
299+
300+ absl::Status DirectNotStep::Evaluate (ExecutionFrameBase& frame, Value& result,
301+ AttributeTrail& attribute_trail) const {
302+ CEL_RETURN_IF_ERROR (operand_->Evaluate (frame, result, attribute_trail));
303+
304+ if (frame.unknown_processing_enabled ()) {
305+ if (frame.attribute_utility ().CheckForUnknownPartial (attribute_trail)) {
306+ result = frame.attribute_utility ().CreateUnknownSet (
307+ attribute_trail.attribute ());
308+ return absl::OkStatus ();
309+ }
310+ }
311+
312+ switch (result.kind ()) {
313+ case ValueKind::kBool :
314+ result = BoolValue{!result.GetBool ().NativeValue ()};
315+ break ;
316+ case ValueKind::kUnknown :
317+ case ValueKind::kError :
318+ // just forward.
319+ break ;
320+ default :
321+ result = frame.value_manager ().CreateErrorValue (
322+ CreateNoMatchingOverloadError (cel::builtin::kNot ));
323+ break ;
324+ }
325+
326+ return absl::OkStatus ();
327+ }
328+
329+ class IterativeNotStep : public ExpressionStepBase {
330+ public:
331+ explicit IterativeNotStep (int64_t expr_id) : ExpressionStepBase(expr_id) {}
332+
333+ absl::Status Evaluate (ExecutionFrame* frame) const override ;
334+ };
335+
336+ absl::Status IterativeNotStep::Evaluate (ExecutionFrame* frame) const {
337+ if (!frame->value_stack ().HasEnough (1 )) {
338+ return absl::InternalError (" Value stack underflow" );
339+ }
340+ const Value& operand = frame->value_stack ().Peek ();
341+
342+ if (frame->unknown_processing_enabled ()) {
343+ const AttributeTrail& attribute_trail =
344+ frame->value_stack ().PeekAttribute ();
345+ if (frame->attribute_utility ().CheckForUnknownPartial (attribute_trail)) {
346+ frame->value_stack ().PopAndPush (
347+ frame->attribute_utility ().CreateUnknownSet (
348+ attribute_trail.attribute ()));
349+ return absl::OkStatus ();
350+ }
351+ }
352+
353+ switch (operand.kind ()) {
354+ case ValueKind::kBool :
355+ frame->value_stack ().PopAndPush (
356+ BoolValue{!operand.GetBool ().NativeValue ()});
357+ break ;
358+ case ValueKind::kUnknown :
359+ case ValueKind::kError :
360+ // just forward.
361+ break ;
362+ default :
363+ frame->value_stack ().PopAndPush (frame->value_factory ().CreateErrorValue (
364+ CreateNoMatchingOverloadError (cel::builtin::kNot )));
365+ break ;
366+ }
367+
368+ return absl::OkStatus ();
369+ }
370+
371+ class DirectNotStrictlyFalseStep : public DirectExpressionStep {
372+ public:
373+ explicit DirectNotStrictlyFalseStep (
374+ std::unique_ptr<DirectExpressionStep> operand, int64_t expr_id)
375+ : DirectExpressionStep(expr_id), operand_(std::move(operand)) {}
376+ absl::Status Evaluate (ExecutionFrameBase& frame, Value& result,
377+ AttributeTrail& attribute_trail) const override ;
378+
379+ private:
380+ std::unique_ptr<DirectExpressionStep> operand_;
381+ };
382+
383+ absl::Status DirectNotStrictlyFalseStep::Evaluate (
384+ ExecutionFrameBase& frame, Value& result,
385+ AttributeTrail& attribute_trail) const {
386+ CEL_RETURN_IF_ERROR (operand_->Evaluate (frame, result, attribute_trail));
387+
388+ switch (result.kind ()) {
389+ case ValueKind::kBool :
390+ // just forward.
391+ break ;
392+ case ValueKind::kUnknown :
393+ case ValueKind::kError :
394+ result = BoolValue (true );
395+ break ;
396+ default :
397+ result = frame.value_manager ().CreateErrorValue (
398+ CreateNoMatchingOverloadError (cel::builtin::kNot ));
399+ break ;
400+ }
401+
402+ return absl::OkStatus ();
403+ }
404+
405+ class IterativeNotStrictlyFalseStep : public ExpressionStepBase {
406+ public:
407+ explicit IterativeNotStrictlyFalseStep (int64_t expr_id)
408+ : ExpressionStepBase(expr_id) {}
409+
410+ absl::Status Evaluate (ExecutionFrame* frame) const override ;
411+ };
412+
413+ absl::Status IterativeNotStrictlyFalseStep::Evaluate (
414+ ExecutionFrame* frame) const {
415+ if (!frame->value_stack ().HasEnough (1 )) {
416+ return absl::InternalError (" Value stack underflow" );
417+ }
418+ const Value& operand = frame->value_stack ().Peek ();
419+
420+ switch (operand.kind ()) {
421+ case ValueKind::kBool :
422+ // just forward.
423+ break ;
424+ case ValueKind::kUnknown :
425+ case ValueKind::kError :
426+ frame->value_stack ().PopAndPush (BoolValue (true ));
427+ break ;
428+ default :
429+ frame->value_stack ().PopAndPush (frame->value_factory ().CreateErrorValue (
430+ CreateNoMatchingOverloadError (cel::builtin::kNot )));
431+ break ;
432+ }
433+
434+ return absl::OkStatus ();
435+ }
436+
288437} // namespace
289438
290439// Factory method for "And" Execution step
@@ -315,4 +464,27 @@ absl::StatusOr<std::unique_ptr<ExpressionStep>> CreateOrStep(int64_t expr_id) {
315464 return std::make_unique<LogicalOpStep>(OpType::kOr , expr_id);
316465}
317466
467+ // Factory method for recursive logical not "!" Execution step
468+ std::unique_ptr<DirectExpressionStep> CreateDirectNotStep (
469+ std::unique_ptr<DirectExpressionStep> operand, int64_t expr_id) {
470+ return std::make_unique<DirectNotStep>(std::move (operand), expr_id);
471+ }
472+
473+ // Factory method for iterative logical not "!" Execution step
474+ std::unique_ptr<ExpressionStep> CreateNotStep (int64_t expr_id) {
475+ return std::make_unique<IterativeNotStep>(expr_id);
476+ }
477+
478+ // Factory method for recursive logical "@not_strictly_false" Execution step.
479+ std::unique_ptr<DirectExpressionStep> CreateDirectNotStrictlyFalseStep (
480+ std::unique_ptr<DirectExpressionStep> operand, int64_t expr_id) {
481+ return std::make_unique<DirectNotStrictlyFalseStep>(std::move (operand),
482+ expr_id);
483+ }
484+
485+ // Factory method for iterative logical "@not_strictly_false" Execution step.
486+ std::unique_ptr<ExpressionStep> CreateNotStrictlyFalseStep (int64_t expr_id) {
487+ return std::make_unique<IterativeNotStrictlyFalseStep>(expr_id);
488+ }
489+
318490} // namespace google::api::expr::runtime
0 commit comments