diff --git a/conformance/expected-failures.yaml b/conformance/expected-failures.yaml index 17daf1bf..e69de29b 100644 --- a/conformance/expected-failures.yaml +++ b/conformance/expected-failures.yaml @@ -1,17 +0,0 @@ -custom_rules: - - field_expression/map/enum/invalid - - field_expression/map/enum/valid - - field_expression/map/message/invalid - - field_expression/map/message/valid - - field_expression/map/bool/valid - - field_expression/map/bool/invalid - - field_expression/map/string/valid - - field_expression/map/string/invalid - - field_expression/map/int32/valid - - field_expression/map/int32/invalid - - field_expression/map/uint32/valid - - field_expression/map/uint32/invalid - - field_expression/map/int64/valid - - field_expression/map/int64/invalid - - field_expression/map/uint64/valid - - field_expression/map/uint64/invalid diff --git a/src/main/java/build/buf/protovalidate/ObjectValue.java b/src/main/java/build/buf/protovalidate/ObjectValue.java index dcd2fa9b..af37251f 100644 --- a/src/main/java/build/buf/protovalidate/ObjectValue.java +++ b/src/main/java/build/buf/protovalidate/ObjectValue.java @@ -64,6 +64,9 @@ public Message messageValue() { @Override public T value(Class clazz) { Descriptors.FieldDescriptor.Type type = fieldDescriptor.getType(); + if (fieldDescriptor.isMapField()) { + return clazz.cast(mapValueAsObject()); + } if (!fieldDescriptor.isRepeated() && (type == Descriptors.FieldDescriptor.Type.UINT32 || type == Descriptors.FieldDescriptor.Type.UINT64 @@ -93,6 +96,38 @@ public List repeatedValue() { return out; } + // TODO - This should be refactored at some point. + // + // This is essentially the same functionality as `mapValue` except that it + // returns a Map of Objects rather than a Map of protovalidate-java Values. + // It is used for binding to a CEL variable (i.e. `this`). + // Trying to bind a Map of Values to a CEL variable does not work because + // CEL-Java doesn't know how to interpret that proprietary Value object. + // + // Ideally, we should be using CEL-Java's org.projectnessie.cel.common.types.ref.Val + // type instead of our own custom Value abstraction. However, since we are evaluating + // Java CEL implementations, we should probably wait until that decision is made before + // making such a large refactor. This should suffice as a stopgap until then. + private Map mapValueAsObject() { + List input = + value instanceof List + ? (List) value + : Collections.singletonList((AbstractMessage) value); + + Descriptors.FieldDescriptor keyDesc = fieldDescriptor.getMessageType().findFieldByNumber(1); + Descriptors.FieldDescriptor valDesc = fieldDescriptor.getMessageType().findFieldByNumber(2); + Map out = new HashMap<>(input.size()); + + for (AbstractMessage entry : input) { + Object keyValue = entry.getField(keyDesc); + Object valValue = entry.getField(valDesc); + + out.put(keyValue, valValue); + } + + return out; + } + @Override public Map mapValue() { List input =