| 69 | } |
| 70 | |
| 71 | absl::StatusOr<Value> MapInsertMap( |
| 72 | const MapValue& map, const MapValue& value, |
| 73 | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
| 74 | google::protobuf::MessageFactory* absl_nonnull message_factory, |
| 75 | google::protobuf::Arena* absl_nonnull arena) { |
| 76 | if (auto mutable_map_value = common_internal::AsMutableMapValue(map); |
| 77 | mutable_map_value) { |
| 78 | // Fast path, runtime has given us a mutable map. We can mutate it directly |
| 79 | // and return it. |
| 80 | CEL_RETURN_IF_ERROR( |
| 81 | value.ForEach( |
| 82 | [&mutable_map_value](const Value& key, |
| 83 | const Value& value) -> absl::StatusOr<bool> { |
| 84 | CEL_RETURN_IF_ERROR(mutable_map_value->Put(key, value)); |
| 85 | return true; |
| 86 | }, |
| 87 | descriptor_pool, message_factory, arena)) |
| 88 | .With(ErrorValueReturn()); |
| 89 | return map; |
| 90 | } |
| 91 | // Slow path, we have to make a copy. |
| 92 | auto builder = NewMapValueBuilder(arena); |
| 93 | if (auto size = map.Size(); size.ok()) { |
| 94 | builder->Reserve(*size + 1); |
| 95 | } else { |
| 96 | size.IgnoreError(); |
| 97 | } |
| 98 | CEL_RETURN_IF_ERROR( |
| 99 | map.ForEach( |
| 100 | [&builder](const Value& key, |
| 101 | const Value& value) -> absl::StatusOr<bool> { |
| 102 | CEL_RETURN_IF_ERROR(builder->Put(key, value)); |
| 103 | return true; |
| 104 | }, |
| 105 | descriptor_pool, message_factory, arena)) |
| 106 | .With(ErrorValueReturn()); |
| 107 | CEL_RETURN_IF_ERROR( |
| 108 | value.ForEach( |
| 109 | [&builder](const Value& key, |
| 110 | const Value& value) -> absl::StatusOr<bool> { |
| 111 | CEL_RETURN_IF_ERROR(builder->Put(key, value)); |
| 112 | return true; |
| 113 | }, |
| 114 | descriptor_pool, message_factory, arena)) |
| 115 | .With(ErrorValueReturn()); |
| 116 | return std::move(*builder).Build(); |
| 117 | } |
| 118 | |
| 119 | } // namespace |
| 120 | |