Skip to content

Commit 371e043

Browse files
Stephen Robertscopybara-github
authored andcommitted
please run presubmits
PiperOrigin-RevId: 856612493
1 parent 777d089 commit 371e043

2 files changed

Lines changed: 69 additions & 0 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ java_library(
125125
"//common/annotations",
126126
"//common/values:cel_byte_string",
127127
"@maven//:com_google_guava_guava",
128+
"@maven//:com_google_protobuf_protobuf_java",
128129
],
129130
)
130131

common/src/main/java/dev/cel/common/ast/CelExprFactory.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,17 @@
1616

1717
import static com.google.common.base.Preconditions.checkArgument;
1818
import static com.google.common.base.Strings.isNullOrEmpty;
19+
import static com.google.common.collect.ImmutableList.toImmutableList;
1920

2021
import com.google.common.primitives.UnsignedLong;
22+
import com.google.protobuf.ByteString;
23+
import com.google.protobuf.Descriptors.EnumValueDescriptor;
24+
import com.google.protobuf.Descriptors.FieldDescriptor;
25+
import com.google.protobuf.Message;
2126
import dev.cel.common.annotations.Internal;
2227
import dev.cel.common.values.CelByteString;
2328
import java.util.Arrays;
29+
import java.util.List;
2430

2531
/** Factory for generating expression nodes. */
2632
@Internal
@@ -138,6 +144,68 @@ public final CelExpr.CelStruct.Entry newMessageField(String field, CelExpr value
138144
.build();
139145
}
140146

147+
/** Creates a new message {@link CelExpr} from a protobuf {@link Message}. */
148+
public final CelExpr newMessageValue(Message message) {
149+
return newMessage(
150+
message.getDescriptorForType().getFullName(),
151+
message.getAllFields().entrySet().stream()
152+
.map(entry -> newMessageFieldValue(entry.getKey(), entry.getValue()))
153+
.collect(toImmutableList()));
154+
}
155+
156+
private CelExpr.CelStruct.Entry newMessageFieldValue(FieldDescriptor field, Object value) {
157+
CelExpr fieldValue;
158+
if (field.isMapField()) {
159+
fieldValue = newMapFieldValue(field, value);
160+
} else if (field.isRepeated()) {
161+
fieldValue = newRepeatedFieldValue(field, value);
162+
} else {
163+
fieldValue = newSingularFieldValue(field, value);
164+
}
165+
return newMessageField(field.getName(), fieldValue);
166+
}
167+
168+
private CelExpr newMapFieldValue(FieldDescriptor field, Object value) {
169+
@SuppressWarnings("unchecked")
170+
List<Message> list = (List<Message>) value; // Safe cast per protobuf spec.
171+
FieldDescriptor keyField = field.getMessageType().findFieldByNumber(1);
172+
FieldDescriptor valueField = field.getMessageType().findFieldByNumber(2);
173+
return newMap(
174+
list.stream()
175+
.map(
176+
entryMsg ->
177+
newMapEntry(
178+
/* key= */ newSingularFieldValue(keyField, entryMsg.getField(keyField)),
179+
/* value= */ newSingularFieldValue(
180+
valueField, entryMsg.getField(valueField))))
181+
.collect(toImmutableList()));
182+
}
183+
184+
private CelExpr newRepeatedFieldValue(FieldDescriptor field, Object value) {
185+
@SuppressWarnings("unchecked")
186+
List<Object> list = (List<Object>) value; // Safe cast per protobuf spec.
187+
return newList(
188+
list.stream().map(v -> newSingularFieldValue(field, v)).collect(toImmutableList()));
189+
}
190+
191+
private CelExpr newSingularFieldValue(FieldDescriptor field, Object value) {
192+
return switch (field.getType()) {
193+
case DOUBLE -> newDoubleLiteral((Double) value);
194+
case FLOAT -> newDoubleLiteral(((Float) value).doubleValue());
195+
case INT64, SFIXED64, SINT64 -> newIntLiteral((Long) value);
196+
case UINT64, FIXED64 -> newUintLiteral((Long) value);
197+
case INT32, SFIXED32, SINT32 -> newIntLiteral(((Integer) value).longValue());
198+
case UINT32, FIXED32 -> newUintLiteral(((Integer) value).longValue());
199+
case BOOL -> newBoolLiteral((Boolean) value);
200+
case STRING -> newStringLiteral((String) value);
201+
case BYTES -> newBytesLiteral(((ByteString) value).toByteArray());
202+
case MESSAGE -> newMessageValue((Message) value);
203+
case ENUM -> newIntLiteral((long) ((EnumValueDescriptor) value).getNumber());
204+
case GROUP ->
205+
throw new UnsupportedOperationException("Legacy GROUP fields are not supported by CEL.");
206+
};
207+
}
208+
141209
/** Fold creates a fold for one variable comprehension instruction. */
142210
public final CelExpr fold(
143211
String iterVar,

0 commit comments

Comments
 (0)