Skip to content

Commit 0834708

Browse files
l46kokcopybara-github
authored andcommitted
Add a converter to handle bi-directional conversion between CelValue to Java native objects
PiperOrigin-RevId: 584757169
1 parent 67b96ad commit 0834708

File tree

12 files changed

+765
-26
lines changed

12 files changed

+765
-26
lines changed

common/src/main/java/dev/cel/common/types/CelTypes.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,24 @@ public static Type createWrapper(Type type) {
192192
return createWrapper(type.getPrimitive());
193193
}
194194

195+
/** Checks if the fully-qualified protobuf type name is a wrapper type. */
196+
public static boolean isWrapperType(String typeName) {
197+
switch (typeName) {
198+
case BOOL_WRAPPER_MESSAGE:
199+
case BYTES_WRAPPER_MESSAGE:
200+
case DOUBLE_WRAPPER_MESSAGE:
201+
case FLOAT_WRAPPER_MESSAGE:
202+
case INT32_WRAPPER_MESSAGE:
203+
case INT64_WRAPPER_MESSAGE:
204+
case STRING_WRAPPER_MESSAGE:
205+
case UINT32_WRAPPER_MESSAGE:
206+
case UINT64_WRAPPER_MESSAGE:
207+
return true;
208+
default:
209+
return false;
210+
}
211+
}
212+
195213
/**
196214
* Create an abstract type indicating that the parameterized type may be contained within the
197215
* object.

common/src/main/java/dev/cel/common/values/BUILD.bazel

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ package(
1111
CEL_VALUES_SOURCES = [
1212
"BoolValue.java",
1313
"BytesValue.java",
14+
"CelValueConverter.java",
1415
"DoubleValue.java",
1516
"DurationValue.java",
1617
"EnumValue.java",
@@ -32,6 +33,7 @@ CEL_VALUES_SOURCES = [
3233

3334
# keep sorted
3435
PROTO_MESSAGE_VALUE_SOURCES = [
36+
"ProtoCelValueConverter.java",
3537
"ProtoMessageValue.java",
3638
]
3739

@@ -56,6 +58,7 @@ java_library(
5658
":cel_byte_string",
5759
":cel_value",
5860
"//:auto_value",
61+
"//common:options",
5962
"//common/annotations",
6063
"//common/types",
6164
"//common/types:type_providers",
@@ -85,12 +88,19 @@ java_library(
8588
":cel_value",
8689
":values",
8790
"//:auto_value",
91+
"//common:options",
92+
"//common/annotations",
8893
"//common/internal:cel_descriptor_pools",
94+
"//common/internal:dynamic_proto",
95+
"//common/internal:well_known_proto",
8996
"//common/types",
97+
"//common/types:cel_types",
9098
"//common/types:type_providers",
99+
"//common/values:cel_byte_string",
91100
"@maven//:com_google_errorprone_error_prone_annotations",
92101
"@maven//:com_google_guava_guava",
93102
"@maven//:com_google_protobuf_protobuf_java",
103+
"@maven//:com_google_protobuf_protobuf_java_util",
94104
"@maven//:org_jspecify_jspecify",
95105
],
96106
)
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package dev.cel.common.values;
16+
17+
import com.google.common.collect.ImmutableList;
18+
import com.google.common.collect.ImmutableMap;
19+
import com.google.common.primitives.UnsignedLong;
20+
import dev.cel.common.CelOptions;
21+
import dev.cel.common.annotations.Internal;
22+
import java.util.Map;
23+
import java.util.Map.Entry;
24+
25+
/**
26+
* {@code CelValueConverter} handles bidirectional conversion between native Java objects to {@link
27+
* CelValue}.
28+
*
29+
* <p>CEL Library Internals. Do Not Use.
30+
*/
31+
@SuppressWarnings("unchecked") // Unchecked cast of generics due to type-erasure (ex: MapValue).
32+
@Internal
33+
abstract class CelValueConverter {
34+
35+
protected final CelOptions celOptions;
36+
37+
/** Adapts a plain old Java Object to a {@link CelValue}. */
38+
public CelValue fromJavaObjectToCelValue(Object value) {
39+
if (value instanceof CelValue) {
40+
return (CelValue) value;
41+
}
42+
43+
if (value instanceof Iterable) {
44+
return toListValue((Iterable<Object>) value);
45+
} else if (value instanceof Map) {
46+
return toMapValue((Map<Object, Object>) value);
47+
}
48+
49+
return fromJavaPrimitiveToCelValue(value);
50+
}
51+
52+
/** Adapts a plain old Java Object that are considered primitives to a {@link CelValue}. */
53+
protected CelValue fromJavaPrimitiveToCelValue(Object value) {
54+
if (value instanceof Boolean) {
55+
return BoolValue.create((Boolean) value);
56+
} else if (value instanceof Long) {
57+
return IntValue.create((Long) value);
58+
} else if (value instanceof Integer) {
59+
return IntValue.create((Integer) value);
60+
} else if (value instanceof String) {
61+
return StringValue.create((String) value);
62+
} else if (value instanceof byte[]) {
63+
return BytesValue.create(CelByteString.of((byte[]) value));
64+
} else if (value instanceof Double) {
65+
return DoubleValue.create((Double) value);
66+
} else if (value instanceof Float) {
67+
return DoubleValue.create(Double.valueOf((Float) value));
68+
} else if (value instanceof UnsignedLong) {
69+
return UintValue.create((UnsignedLong) value);
70+
}
71+
72+
// Fall back to an Opaque value, as a custom class was supplied in the runtime. The legacy
73+
// interpreter allows this but this should not be allowed when a new runtime is introduced.
74+
// TODO: Migrate consumers to directly supply an appropriate CelValue.
75+
return OpaqueValue.create(value.toString(), value);
76+
}
77+
78+
private ListValue<CelValue> toListValue(Iterable<Object> iterable) {
79+
ImmutableList.Builder<CelValue> listBuilder = ImmutableList.builder();
80+
for (Object entry : iterable) {
81+
listBuilder.add(fromJavaObjectToCelValue(entry));
82+
}
83+
84+
return ImmutableListValue.create(listBuilder.build());
85+
}
86+
87+
private MapValue<CelValue, CelValue> toMapValue(Map<Object, Object> map) {
88+
ImmutableMap.Builder<CelValue, CelValue> mapBuilder = ImmutableMap.builder();
89+
for (Entry<Object, Object> entry : map.entrySet()) {
90+
CelValue mapKey = fromJavaObjectToCelValue(entry.getKey());
91+
CelValue mapValue = fromJavaObjectToCelValue(entry.getValue());
92+
mapBuilder.put(mapKey, mapValue);
93+
}
94+
95+
return ImmutableMapValue.create(mapBuilder.buildOrThrow());
96+
}
97+
98+
protected CelValueConverter(CelOptions celOptions) {
99+
this.celOptions = celOptions;
100+
}
101+
}

common/src/main/java/dev/cel/common/values/NullValue.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,6 @@ public CelType celType() {
4242
public boolean isZeroValue() {
4343
return true;
4444
}
45+
46+
private NullValue() {}
4547
}

0 commit comments

Comments
 (0)