|
21 | 21 | import static software.amazon.smithy.go.codegen.util.ShapeUtil.BOOL_SHAPE;
|
22 | 22 | import static software.amazon.smithy.go.codegen.util.ShapeUtil.INT_SHAPE;
|
23 | 23 | import static software.amazon.smithy.go.codegen.util.ShapeUtil.STRING_SHAPE;
|
24 |
| -import static software.amazon.smithy.go.codegen.util.ShapeUtil.listOf; |
25 | 24 | import static software.amazon.smithy.utils.StringUtils.capitalize;
|
26 | 25 |
|
| 26 | +import java.util.HashMap; |
27 | 27 | import java.util.List;
|
28 | 28 | import java.util.Map;
|
29 | 29 | import software.amazon.smithy.codegen.core.CodegenException;
|
@@ -64,6 +64,12 @@ public class GoJmespathExpressionGenerator {
|
64 | 64 |
|
65 | 65 | private int idIndex = 0;
|
66 | 66 |
|
| 67 | + // as we traverse an expression, we may produce intermediate "synthetic" lists - e.g. list of string, list of list |
| 68 | + // of string, etc. |
| 69 | + // we may need to pull the member shapes back out later, but they're not guaranteed to be in the model - so keep a |
| 70 | + // shadow map of synthetic -> member to short-circuit the model lookup |
| 71 | + private final Map<Shape, Shape> synthetics = new HashMap<>(); |
| 72 | + |
67 | 73 | public GoJmespathExpressionGenerator(GoCodegenContext ctx, GoWriter writer) {
|
68 | 74 | this.ctx = ctx;
|
69 | 75 | this.writer = writer;
|
@@ -121,8 +127,17 @@ private Variable visitMultiSelectList(MultiSelectListExpression expr, Variable c
|
121 | 127 | var first = items.get(0);
|
122 | 128 |
|
123 | 129 | var ident = nextIdent();
|
124 |
| - writer.write("$L := []$P{$L}", ident, first.type, |
125 |
| - String.join(",", items.stream().map(it -> it.ident).toList())); |
| 130 | + writer.write("$L := []$T{}", ident, first.type); |
| 131 | + for (var item : items) { |
| 132 | + if (isPointable(item.type)) { |
| 133 | + writer.write(""" |
| 134 | + if $2L != nil { |
| 135 | + $1L = append($1L, *$2L) |
| 136 | + }""", ident, item.ident); |
| 137 | + } else { |
| 138 | + writer.write("$1L = append($1L, $2L)", ident, item.ident); |
| 139 | + } |
| 140 | + } |
126 | 141 |
|
127 | 142 | return new Variable(listOf(first.shape), ident, sliceOf(first.type));
|
128 | 143 | }
|
@@ -247,11 +262,13 @@ private Variable visitProjection(ProjectionExpression expr, Variable current) {
|
247 | 262 | writer.indent();
|
248 | 263 | // projected.shape is the _member_ of the resulting list
|
249 | 264 | var projected = visit(expr.getRight(), new Variable(leftMember, "v", leftSymbol));
|
250 |
| - if (isPointable(lookahead.type)) { // projections implicitly filter out nil evaluations of RHS |
| 265 | + if (isPointable(lookahead.type)) { // projections implicitly filter out nil evaluations of RHS... |
| 266 | + var deref = lookahead.shape instanceof CollectionShape || lookahead.shape instanceof MapShape |
| 267 | + ? "" : "*"; // ...but slices/maps do not get dereferenced |
251 | 268 | writer.write("""
|
252 |
| - if $2L != nil { |
253 |
| - $1L = append($1L, *$2L) |
254 |
| - }""", ident, projected.ident); |
| 269 | + if $1L != nil { |
| 270 | + $2L = append($2L, $3L$1L) |
| 271 | + }""", projected.ident, ident, deref); |
255 | 272 | } else {
|
256 | 273 | writer.write("$1L = append($1L, $2L)", ident, projected.ident);
|
257 | 274 | }
|
@@ -348,22 +365,22 @@ private String nextIdent() {
|
348 | 365 | return "v" + idIndex;
|
349 | 366 | }
|
350 | 367 |
|
| 368 | + private Shape listOf(Shape shape) { |
| 369 | + var list = ShapeUtil.listOf(shape); |
| 370 | + synthetics.putIfAbsent(list, shape); |
| 371 | + return list; |
| 372 | + } |
| 373 | + |
351 | 374 | private Shape expectMember(CollectionShape shape) {
|
352 |
| - return switch (shape.getMember().getTarget().toString()) { |
353 |
| - case "smithy.go.synthetic#StringList" -> listOf(STRING_SHAPE); |
354 |
| - case "smithy.go.synthetic#IntegerList" -> listOf(INT_SHAPE); |
355 |
| - case "smithy.go.synthetic#BooleanList" -> listOf(BOOL_SHAPE); |
356 |
| - default -> ShapeUtil.expectMember(ctx.model(), shape); |
357 |
| - }; |
| 375 | + return synthetics.containsKey(shape) |
| 376 | + ? synthetics.get(shape) |
| 377 | + : ShapeUtil.expectMember(ctx.model(), shape); |
358 | 378 | }
|
359 | 379 |
|
360 | 380 | private Shape expectMember(MapShape shape) {
|
361 |
| - return switch (shape.getValue().getTarget().toString()) { |
362 |
| - case "smithy.go.synthetic#StringList" -> listOf(STRING_SHAPE); |
363 |
| - case "smithy.go.synthetic#IntegerList" -> listOf(INT_SHAPE); |
364 |
| - case "smithy.go.synthetic#BooleanList" -> listOf(BOOL_SHAPE); |
365 |
| - default -> ShapeUtil.expectMember(ctx.model(), shape); |
366 |
| - }; |
| 381 | + return synthetics.containsKey(shape) |
| 382 | + ? synthetics.get(shape) |
| 383 | + : ShapeUtil.expectMember(ctx.model(), shape); |
367 | 384 | }
|
368 | 385 |
|
369 | 386 | // helper to generate comparisons from two results, automatically handling any dereferencing in the process
|
|
0 commit comments