forked from google/cel-java
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathActivation.java
More file actions
153 lines (133 loc) · 4.6 KB
/
Activation.java
File metadata and controls
153 lines (133 loc) · 4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package dev.cel.runtime;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.protobuf.ByteString;
import com.google.protobuf.ByteString.ByteIterator;
import dev.cel.common.annotations.Internal;
import java.util.Map;
import org.jspecify.annotations.Nullable;
/**
* An object which allows to bind names to values.
*
* <p>CEL Library Internals. Do Not Use.
*/
@Internal
public abstract class Activation implements GlobalResolver {
/** Resolves the given name to its value. Returns null if resolution fails. */
@Override
public abstract @Nullable Object resolve(String name);
/** An empty binder which resolves everything to null. */
public static final Activation EMPTY =
new Activation() {
@Override
public @Nullable Object resolve(String name) {
return GlobalResolver.EMPTY.resolve(name);
}
@Override
public String toString() {
return GlobalResolver.EMPTY.toString();
}
};
/** Creates a binder which binds the given name to the value. */
public static Activation of(final String name, Object value) {
return new Activation() {
@Override
public @Nullable Object resolve(String theName) {
if (theName.equals(name)) {
// TODO: Decouple
return RuntimeHelpers.maybeAdaptPrimitive(value);
}
return null;
}
@Override
public String toString() {
// TODO: Remove.
if (value instanceof ByteString) {
ByteString bs = (ByteString) value;
StringBuilder val = new StringBuilder();
val.append("[");
for (ByteIterator i = bs.iterator(); i.hasNext(); ) {
byte b = i.nextByte();
val.append(b);
if (i.hasNext()) {
val.append(", ");
}
}
val.append("]");
return String.format("{%s=%s}", name, val);
}
return String.format("{%s=%s}", name, value);
}
};
}
/** Creates a binder which binds the given name to the supplier. */
public static Activation of(final String name, final Supplier<?> supplier) {
return new Activation() {
@Override
public @Nullable Object resolve(String theName) {
if (theName.equals(name)) {
return RuntimeHelpers.maybeAdaptPrimitive(supplier.get());
}
return null;
}
@Override
public String toString() {
return String.format("{%s=%s}", name, supplier.get());
}
};
}
/** Creates a binder backed up by a map. */
public static Activation copyOf(Map<String, ?> map) {
@SuppressWarnings("unchecked")
final ImmutableMap<String, Object> copy =
(map instanceof ImmutableMap)
? (ImmutableMap<String, Object>) map
: map.entrySet().stream()
// ImmutableMaps are null-hostile, but the Activation is not, so make sure that null
// values and entries are skipped.
.filter(entry -> entry.getKey() != null && entry.getValue() != null)
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
return new Activation() {
@Override
public @Nullable Object resolve(String name) {
return RuntimeHelpers.maybeAdaptPrimitive(copy.get(name));
}
@Override
public String toString() {
return copy.toString();
}
};
}
/**
* Extends this binder by another binder. Names will be attempted to first resolve in the other
* binder, then in this binder.
*/
public Activation extend(final Activation activation) {
final Activation outer = this;
return new Activation() {
@Override
public @Nullable Object resolve(String name) {
Object value = activation.resolve(name);
return value != null ? value : outer.resolve(name);
}
@Override
public String toString() {
return activation + " +> " + outer;
}
};
}
}