| 947 | } |
| 948 | |
| 949 | google::protobuf::Message* StructFromValue(google::protobuf::Message* message, |
| 950 | const CelValue& value, google::protobuf::Arena* arena) { |
| 951 | if (!value.IsMap()) { |
| 952 | return nullptr; |
| 953 | } |
| 954 | const CelMap& map = *value.MapOrDie(); |
| 955 | absl::StatusOr<const CelList*> keys_or = map.ListKeys(arena); |
| 956 | if (!keys_or.ok()) { |
| 957 | // If map doesn't support listing keys, it can't pack into a Struct value. |
| 958 | // This will surface as a CEL error when the object creation expression |
| 959 | // fails. |
| 960 | return nullptr; |
| 961 | } |
| 962 | const CelList& keys = **keys_or; |
| 963 | CEL_ASSIGN_OR_RETURN( |
| 964 | auto reflection, |
| 965 | cel::well_known_types::GetStructReflection(message->GetDescriptor()), |
| 966 | _.With(IgnoreErrorAndReturnNullptr())); |
| 967 | for (int i = 0; i < keys.size(); i++) { |
| 968 | auto k = keys.Get(arena, i); |
| 969 | // If the key is not a string type, abort the conversion. |
| 970 | if (!k.IsString()) { |
| 971 | return nullptr; |
| 972 | } |
| 973 | absl::string_view key = k.StringOrDie().value(); |
| 974 | |
| 975 | auto v = map.Get(arena, k); |
| 976 | if (!v.has_value()) { |
| 977 | return nullptr; |
| 978 | } |
| 979 | auto* field = reflection.InsertField(message, key); |
| 980 | if (ValueFromValue(field, *v, arena) == nullptr) { |
| 981 | return nullptr; |
| 982 | } |
| 983 | } |
| 984 | return message; |
| 985 | } |
| 986 | |
| 987 | google::protobuf::Message* StructFromValue(const google::protobuf::Message* prototype, |
| 988 | const CelValue& value, google::protobuf::Arena* arena) { |
no test coverage detected