Skip to content

Commit 90322d7

Browse files
author
John Chadwick
committed
Implement getField CEL function
I'm proposing this as an eventual replacement (before 1.0) of our hack around the fact that the `in` identifier is reserved in CEL. We need this for protovalidate-cc especially so we can start removing our cel-cpp patches. Protovalidate PR: bufbuild/protovalidate#352
1 parent 43fb8f6 commit 90322d7

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

src/main/java/build/buf/protovalidate/CustomDeclarations.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ static List<Decl> create() {
3838
// Add 'now' variable declaration
3939
decls.add(Decls.newVar("now", Decls.newObjectType(TimestampT.TimestampType.typeName())));
4040

41+
// Add 'getField' function declaration
42+
decls.add(
43+
Decls.newFunction(
44+
"getField",
45+
Decls.newOverload(
46+
"get_field_any_string", Arrays.asList(Decls.Any, Decls.String), Decls.Any)));
47+
4148
// Add 'isIp' function declaration
4249
decls.add(
4350
Decls.newFunction(

src/main/java/build/buf/protovalidate/CustomOverload.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import com.google.common.base.Splitter;
1919
import com.google.common.net.InetAddresses;
2020
import com.google.common.primitives.Bytes;
21+
import com.google.protobuf.Descriptors;
22+
import com.google.protobuf.Message;
2123
import inet.ipaddr.IPAddress;
2224
import inet.ipaddr.IPAddressString;
2325
import jakarta.mail.internet.AddressException;
@@ -35,6 +37,7 @@
3537
import org.projectnessie.cel.common.types.ListT;
3638
import org.projectnessie.cel.common.types.StringT;
3739
import org.projectnessie.cel.common.types.Types;
40+
import org.projectnessie.cel.common.types.pb.DefaultTypeAdapter;
3841
import org.projectnessie.cel.common.types.ref.TypeEnum;
3942
import org.projectnessie.cel.common.types.ref.Val;
4043
import org.projectnessie.cel.common.types.traits.Lister;
@@ -43,6 +46,7 @@
4346
/** Defines custom function overloads (the implementation). */
4447
final class CustomOverload {
4548

49+
private static final String OVERLOAD_GET_FIELD = "getField";
4650
private static final String OVERLOAD_FORMAT = "format";
4751
private static final String OVERLOAD_UNIQUE = "unique";
4852
private static final String OVERLOAD_STARTS_WITH = "startsWith";
@@ -65,6 +69,7 @@ final class CustomOverload {
6569
*/
6670
static Overload[] create() {
6771
return new Overload[] {
72+
getField(),
6873
format(),
6974
unique(),
7075
startsWith(),
@@ -82,6 +87,30 @@ static Overload[] create() {
8287
};
8388
}
8489

90+
/**
91+
* Creates a custom function overload for the "getField" operation.
92+
*
93+
* @return The {@link Overload} instance for the "getField" operation.
94+
*/
95+
private static Overload getField() {
96+
return Overload.binary(
97+
OVERLOAD_GET_FIELD,
98+
(msgarg, namearg) -> {
99+
if (msgarg.type().typeEnum() != TypeEnum.Object
100+
|| namearg.type().typeEnum() != TypeEnum.String) {
101+
return Err.newErr("no such overload");
102+
}
103+
Message message = msgarg.convertToNative(Message.class);
104+
String fieldName = namearg.convertToNative(String.class);
105+
Descriptors.FieldDescriptor field =
106+
message.getDescriptorForType().findFieldByName(fieldName);
107+
if (field == null) {
108+
return Err.newErr("no such field: " + fieldName);
109+
}
110+
return DefaultTypeAdapter.Instance.nativeToValue(message.getField(field));
111+
});
112+
}
113+
85114
/**
86115
* Creates a custom binary function overload for the "format" operation.
87116
*

0 commit comments

Comments
 (0)