4040import dev .cel .common .types .ListType ;
4141import dev .cel .common .types .MapType ;
4242import dev .cel .common .types .NullableType ;
43+ import dev .cel .common .types .OptionalType ;
4344import dev .cel .common .types .SimpleType ;
4445import dev .cel .common .types .StructType ;
4546import dev .cel .common .types .StructTypeReference ;
@@ -287,9 +288,13 @@ private TranslatedValue translateList(CelExpr celExpr, CelAbstractSyntaxTree ast
287288 for (int i = 0 ; i < elements .size (); i ++) {
288289 CelExpr element = elements .get (i );
289290 TranslatedValue elem = translateExpr (element , ast );
290- elementsTv .add (elem );
291291
292292 if (optionalIndices .contains (i )) {
293+ Expr <?> checkedValue =
294+ typeSystem .withRuntimeError (
295+ elem .z3Expr (), ctx .mkNot (typeSystem .isOptional (elem .z3Expr ())));
296+ elem = TranslatedValue .create (checkedValue , element , typeSystem , elem .isApproximate ());
297+
293298 Expr <?> optRef = typeSystem .getOptionalRef (elem .z3Expr ());
294299 seq =
295300 (SeqExpr )
@@ -300,6 +305,7 @@ private TranslatedValue translateList(CelExpr celExpr, CelAbstractSyntaxTree ast
300305 } else {
301306 seq = typeSystem .mkConcatSafe (seq , ctx .mkUnit (elem .z3Expr ()));
302307 }
308+ elementsTv .add (elem );
303309 }
304310 listRef = typeSystem .mkListRefConst (LIST_REF_PREFIX );
305311 typeConstraints .add (ctx .mkEq (typeSystem .getSeq (listRef ), seq ));
@@ -327,15 +333,20 @@ private TranslatedValue translateMap(CelExpr celExpr, CelAbstractSyntaxTree ast)
327333 elementsTv .add (keyTv );
328334 TranslatedValue valueTv = translateExpr (entryAst .value (), ast );
329335 Expr <?> value = valueTv .z3Expr ();
330- elementsTv .add (valueTv );
331336
332337 Expr <?> finalValue = value ;
333338 BoolExpr finalPresence = ctx .mkTrue ();
334339 if (entryAst .optionalEntry ()) {
335- Expr <?> optRef = typeSystem .getOptionalRef (value );
340+ Expr <?> checkedValue =
341+ typeSystem .withRuntimeError (value , ctx .mkNot (typeSystem .isOptional (value )));
342+ valueTv =
343+ TranslatedValue .create (
344+ checkedValue , entryAst .value (), typeSystem , valueTv .isApproximate ());
345+ Expr <?> optRef = typeSystem .getOptionalRef (checkedValue );
336346 finalPresence = typeSystem .optHasValue (optRef );
337347 finalValue = typeSystem .getOptionalValue (optRef );
338348 }
349+ elementsTv .add (valueTv );
339350
340351 BoolExpr keyAlreadyPresent = (BoolExpr ) ctx .mkSelect (mapPresence , key );
341352 BoolExpr shouldInsertKey = ctx .mkAnd (ctx .mkNot (keyAlreadyPresent ), finalPresence );
@@ -382,7 +393,6 @@ private TranslatedValue translateStruct(CelExpr celExpr, CelAbstractSyntaxTree a
382393 Expr <?> key = ctx .mkString (entryAst .fieldKey ());
383394 TranslatedValue valueTv = translateExpr (entryAst .value (), ast );
384395 Expr <?> value = valueTv .z3Expr ();
385- elementsTv .add (valueTv );
386396
387397 CelType fieldType =
388398 typeProvider
@@ -397,10 +407,16 @@ private TranslatedValue translateStruct(CelExpr celExpr, CelAbstractSyntaxTree a
397407 Expr <?> finalValue = value ;
398408 BoolExpr optionalHasValue = ctx .mkTrue ();
399409 if (entryAst .optionalEntry ()) {
400- Expr <?> optRef = typeSystem .getOptionalRef (value );
410+ Expr <?> checkedValue =
411+ typeSystem .withRuntimeError (value , ctx .mkNot (typeSystem .isOptional (value )));
412+ valueTv =
413+ TranslatedValue .create (
414+ checkedValue , entryAst .value (), typeSystem , valueTv .isApproximate ());
415+ Expr <?> optRef = typeSystem .getOptionalRef (checkedValue );
401416 optionalHasValue = typeSystem .optHasValue (optRef );
402417 finalValue = typeSystem .getOptionalValue (optRef );
403418 }
419+ elementsTv .add (valueTv );
404420
405421 // Canonicalization Trick:
406422 //
@@ -436,6 +452,9 @@ private Expr<?> getDefaultValueForType(CelType type) {
436452 if (type instanceof NullableType ) {
437453 return typeSystem .mkNull ();
438454 }
455+ if (type instanceof OptionalType ) {
456+ return typeSystem .mkOptionalNone ();
457+ }
439458 if (type .equals (SimpleType .INT )) {
440459 return typeSystem .mkInt (0 );
441460 }
@@ -1147,6 +1166,23 @@ private BoolExpr createTypeConstraint(Expr<?> val, long exprId, CelAbstractSynta
11471166 }
11481167
11491168 private BoolExpr createTypeConstraintForType (Expr <?> val , CelType type ) {
1169+ if (type instanceof NullableType ) {
1170+ NullableType nullableType = (NullableType ) type ;
1171+ return ctx .mkOr (
1172+ typeSystem .isNull (val ), createTypeConstraintForType (val , nullableType .targetType ()));
1173+ }
1174+ if (type instanceof OptionalType ) {
1175+ BoolExpr isOpt = typeSystem .isOptional (val );
1176+ CelType paramType = type .parameters ().get (0 );
1177+ if (paramType .kind ().isDyn () || paramType .kind ().isTypeParam ()) {
1178+ return isOpt ;
1179+ }
1180+ Expr <?> optRef = typeSystem .getOptionalRef (val );
1181+ BoolExpr hasValue = typeSystem .optHasValue (optRef );
1182+ BoolExpr valConstraint =
1183+ createTypeConstraintForType (typeSystem .getOptionalValue (optRef ), paramType );
1184+ return ctx .mkAnd (isOpt , ctx .mkImplies (hasValue , valConstraint ));
1185+ }
11501186 if (type .equals (SimpleType .BOOL )) {
11511187 return (BoolExpr ) ctx .mkApp (typeSystem .boolCons ().getTesterDecl (), val );
11521188 }
0 commit comments