Skip to content

Commit f645749

Browse files
l46kokcopybara-github
authored andcommitted
Implement ListValue, MapValue and OptionalValue
PiperOrigin-RevId: 584654587
1 parent 7cd0d73 commit f645749

File tree

9 files changed

+1124
-0
lines changed

9 files changed

+1124
-0
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@ CEL_VALUES_SOURCES = [
1414
"DoubleValue.java",
1515
"DurationValue.java",
1616
"EnumValue.java",
17+
"ImmutableListValue.java",
18+
"ImmutableMapValue.java",
1719
"IntValue.java",
20+
"ListValue.java",
21+
"MapValue.java",
1822
"NullValue.java",
23+
"OptionalValue.java",
1924
"StringValue.java",
2025
"StructValue.java",
2126
"TimestampValue.java",
@@ -46,6 +51,7 @@ java_library(
4651
"//common/types:type_providers",
4752
"@maven//:com_google_errorprone_error_prone_annotations",
4853
"@maven//:com_google_guava_guava",
54+
"@maven//:org_jspecify_jspecify",
4955
],
5056
)
5157

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
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.errorprone.annotations.Immutable;
19+
import java.util.Collection;
20+
import java.util.Iterator;
21+
import java.util.List;
22+
import java.util.ListIterator;
23+
24+
/**
25+
* ImmutableListValue is a representation of an immutable list containing zero or more {@link
26+
* CelValue}.
27+
*/
28+
@Immutable
29+
@SuppressWarnings(
30+
"PreferredInterfaceType") // We intentionally store List type to avoid copying on instantiation
31+
public final class ImmutableListValue<E extends CelValue> extends ListValue<E> {
32+
33+
@SuppressWarnings("Immutable") // ListValue APIs prohibit mutation.
34+
private final List<E> originalList;
35+
36+
@SuppressWarnings("Immutable") // The value is lazily populated only once via synchronization.
37+
private volatile ImmutableList<E> cachedImmutableList = null;
38+
39+
public static <E extends CelValue> ImmutableListValue<E> create(List<E> value) {
40+
return new ImmutableListValue<>(value);
41+
}
42+
43+
private ImmutableListValue(List<E> originalList) {
44+
this.originalList = ImmutableList.copyOf(originalList);
45+
}
46+
47+
@Override
48+
public ImmutableList<E> value() {
49+
if (cachedImmutableList == null) {
50+
synchronized (this) {
51+
if (cachedImmutableList == null) {
52+
cachedImmutableList = ImmutableList.copyOf(originalList);
53+
}
54+
}
55+
}
56+
57+
return cachedImmutableList;
58+
}
59+
60+
@Override
61+
public int size() {
62+
return originalList.size();
63+
}
64+
65+
@Override
66+
public boolean isEmpty() {
67+
return originalList.isEmpty();
68+
}
69+
70+
@Override
71+
public boolean contains(Object o) {
72+
return originalList.contains(o);
73+
}
74+
75+
@Override
76+
public Iterator<E> iterator() {
77+
return originalList.iterator();
78+
}
79+
80+
@Override
81+
public Object[] toArray() {
82+
return originalList.toArray();
83+
}
84+
85+
@Override
86+
public <T> T[] toArray(T[] a) {
87+
return originalList.toArray(a);
88+
}
89+
90+
@Override
91+
public boolean containsAll(Collection<?> c) {
92+
return originalList.containsAll(c);
93+
}
94+
95+
@Override
96+
public E get(int index) {
97+
return originalList.get(index);
98+
}
99+
100+
@Override
101+
public int indexOf(Object o) {
102+
return originalList.indexOf(o);
103+
}
104+
105+
@Override
106+
public int lastIndexOf(Object o) {
107+
return originalList.lastIndexOf(o);
108+
}
109+
110+
@Override
111+
public ListIterator<E> listIterator() {
112+
return originalList.listIterator();
113+
}
114+
115+
@Override
116+
public ListIterator<E> listIterator(int index) {
117+
return originalList.listIterator(index);
118+
}
119+
120+
@Override
121+
public List<E> subList(int fromIndex, int toIndex) {
122+
return originalList.subList(fromIndex, toIndex);
123+
}
124+
125+
@Override
126+
public int hashCode() {
127+
return originalList.hashCode();
128+
}
129+
130+
@Override
131+
public boolean equals(Object obj) {
132+
return originalList.equals(obj);
133+
}
134+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
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.base.Preconditions;
18+
import com.google.common.collect.ImmutableMap;
19+
import com.google.errorprone.annotations.Immutable;
20+
import java.util.Collection;
21+
import java.util.Map;
22+
import java.util.Set;
23+
24+
/**
25+
* MapValue is an abstract representation of an immutable map containing {@link CelValue} as keys
26+
* and values.
27+
*/
28+
@Immutable(containerOf = {"K", "V"})
29+
@SuppressWarnings(
30+
"PreferredInterfaceType") // We intentionally store List type to avoid copying on instantiation
31+
public final class ImmutableMapValue<K extends CelValue, V extends CelValue>
32+
extends MapValue<K, V> {
33+
34+
@SuppressWarnings("Immutable") // MapValue APIs prohibit mutation.
35+
private final Map<K, V> originalMap;
36+
37+
@SuppressWarnings("Immutable") // The value is lazily populated only once via synchronization.
38+
private volatile ImmutableMap<K, V> cachedImmutableMap = null;
39+
40+
public static <K extends CelValue, V extends CelValue> ImmutableMapValue<K, V> create(
41+
Map<K, V> value) {
42+
return new ImmutableMapValue<>(value);
43+
}
44+
45+
private ImmutableMapValue(Map<K, V> originalMap) {
46+
Preconditions.checkNotNull(originalMap);
47+
this.originalMap = originalMap;
48+
}
49+
50+
@Override
51+
public ImmutableMap<K, V> value() {
52+
if (cachedImmutableMap == null) {
53+
synchronized (this) {
54+
if (cachedImmutableMap == null) {
55+
cachedImmutableMap = ImmutableMap.copyOf(originalMap);
56+
}
57+
}
58+
}
59+
60+
return cachedImmutableMap;
61+
}
62+
63+
@Override
64+
public int size() {
65+
return originalMap.size();
66+
}
67+
68+
@Override
69+
public boolean isEmpty() {
70+
return originalMap.isEmpty();
71+
}
72+
73+
@Override
74+
public boolean containsKey(Object key) {
75+
return originalMap.containsKey(key);
76+
}
77+
78+
@Override
79+
public boolean containsValue(Object val) {
80+
return originalMap.containsValue(val);
81+
}
82+
83+
@Override
84+
public int hashCode() {
85+
return originalMap.hashCode();
86+
}
87+
88+
@Override
89+
public boolean equals(Object obj) {
90+
return originalMap.equals(obj);
91+
}
92+
93+
// Note that the following three methods are produced from the immutable map to avoid key/value
94+
// mutation.
95+
@Override
96+
public Set<K> keySet() {
97+
return value().keySet();
98+
}
99+
100+
@Override
101+
public Collection<V> values() {
102+
return value().values();
103+
}
104+
105+
@Override
106+
public Set<Entry<K, V>> entrySet() {
107+
return value().entrySet();
108+
}
109+
}

0 commit comments

Comments
 (0)