2626#include " eval/public/cel_function_adapter.h"
2727#include " eval/public/cel_value.h"
2828#include " eval/public/containers/container_backed_map_impl.h"
29+ #include " eval/public/containers/field_access.h"
2930#include " google/protobuf/arena.h"
3031#include " re2/re2.h"
3132
@@ -52,6 +53,32 @@ bool isPathValid(const std::string_view path) {
5253
5354namespace cel = google::api::expr::runtime;
5455
56+ cel::CelValue getField (
57+ google::protobuf::Arena* arena, cel::CelValue msgval, cel::CelValue nameval) {
58+ if (!msgval.IsMessage ()) {
59+ auto * error = google::protobuf::Arena::Create<cel::CelError>(
60+ arena, absl::StatusCode::kInvalidArgument , " expected a message value for first argument" );
61+ return cel::CelValue::CreateError (error);
62+ }
63+ if (!nameval.IsString ()) {
64+ auto * error = google::protobuf::Arena::Create<cel::CelError>(
65+ arena, absl::StatusCode::kInvalidArgument , " expected a string value for second argument" );
66+ return cel::CelValue::CreateError (error);
67+ }
68+ const auto * message = msgval.MessageOrDie ();
69+ auto name = nameval.StringOrDie ();
70+ const auto * field = message->GetDescriptor ()->FindFieldByName (name.value ());
71+ if (field == nullptr ) {
72+ auto * error = google::protobuf::Arena::Create<cel::CelError>(
73+ arena, absl::StatusCode::kInvalidArgument , " no such field" );
74+ return cel::CelValue::CreateError (error);
75+ }
76+ if (cel::CelValue result; cel::CreateValueFromSingleField (message, field, arena, &result).ok ()) {
77+ return result;
78+ }
79+ return cel::CelValue::CreateNull ();
80+ }
81+
5582cel::CelValue isNan (google::protobuf::Arena* arena, cel::CelValue rhs) {
5683 if (!rhs.IsDouble ()) {
5784 auto * error = google::protobuf::Arena::Create<cel::CelError>(
@@ -351,6 +378,11 @@ absl::Status RegisterExtraFuncs(
351378 ®istry);
352379 if (!status.ok ()) {
353380 return status;
381+ auto getFieldStatus =
382+ cel::FunctionAdapter<cel::CelValue, cel::CelValue, cel::CelValue>::CreateAndRegister (
383+ " getField" , false , &getField, ®istry);
384+ if (!getFieldStatus.ok ()) {
385+ return getFieldStatus;
354386 }
355387 auto isNanStatus = cel::FunctionAdapter<cel::CelValue, cel::CelValue>::CreateAndRegister (
356388 " isNan" , true , &isNan, ®istry);
0 commit comments