Skip to content

Commit 114c432

Browse files
committed
Refadctor to remove cache complexity, add coverage
1 parent f2a1388 commit 114c432

5 files changed

Lines changed: 1159 additions & 815 deletions

File tree

codegen/src/main/java/software/amazon/awssdk/codegen/AddShapes.java

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,9 @@
2222
import static software.amazon.awssdk.codegen.internal.Utils.isScalar;
2323

2424
import java.util.Collections;
25-
import java.util.HashSet;
2625
import java.util.List;
2726
import java.util.Map;
2827
import java.util.Optional;
29-
import java.util.Set;
3028
import software.amazon.awssdk.codegen.internal.TypeUtils;
3129
import software.amazon.awssdk.codegen.model.config.customization.CustomizationConfig;
3230
import software.amazon.awssdk.codegen.model.intermediate.EnumModel;
@@ -38,7 +36,6 @@
3836
import software.amazon.awssdk.codegen.model.intermediate.ReturnTypeModel;
3937
import software.amazon.awssdk.codegen.model.intermediate.ShapeModel;
4038
import software.amazon.awssdk.codegen.model.intermediate.VariableModel;
41-
import software.amazon.awssdk.codegen.model.service.ErrorMap;
4239
import software.amazon.awssdk.codegen.model.service.Location;
4340
import software.amazon.awssdk.codegen.model.service.Member;
4441
import software.amazon.awssdk.codegen.model.service.Operation;
@@ -57,7 +54,6 @@ abstract class AddShapes {
5754

5855
private final IntermediateModelBuilder builder;
5956
private final NamingStrategy namingStrategy;
60-
private Set<Shape> directOperationShapes;
6157

6258
AddShapes(IntermediateModelBuilder builder) {
6359
this.builder = builder;
@@ -315,10 +311,9 @@ private ParameterHttpMapping generateParameterHttpMapping(Shape parentShape,
315311

316312
ParameterHttpMapping mapping = new ParameterHttpMapping();
317313

314+
// Per the Smithy spec, HTTP binding traits are only honored on specific shape types:
318315
// https://smithy.io/2.0/spec/http-bindings.html
319-
Location location = isDirectOperationShape(parentShape, allC2jShapes)
320-
? Location.forValue(member.getLocation())
321-
: null;
316+
Location location = resolveLocation(parentShape, member, allC2jShapes);
322317

323318
Shape memberShape = allC2jShapes.get(member.getShape());
324319
mapping.withLocation(location)
@@ -332,24 +327,43 @@ private ParameterHttpMapping generateParameterHttpMapping(Shape parentShape,
332327
return mapping;
333328
}
334329

335-
private boolean isDirectOperationShape(Shape parentShape, Map<String, Shape> allC2jShapes) {
336-
if (directOperationShapes == null) {
337-
directOperationShapes = new HashSet<>();
338-
for (Operation operation : builder.getService().getOperations().values()) {
339-
if (operation.getInput() != null) {
340-
directOperationShapes.add(allC2jShapes.get(operation.getInput().getShape()));
341-
}
342-
if (operation.getOutput() != null) {
343-
directOperationShapes.add(allC2jShapes.get(operation.getOutput().getShape()));
344-
}
345-
if (operation.getErrors() != null) {
346-
for (ErrorMap error : operation.getErrors()) {
347-
directOperationShapes.add(allC2jShapes.get(error.getShape()));
348-
}
349-
}
350-
}
330+
private Location resolveLocation(Shape parentShape, Member member, Map<String, Shape> allC2jShapes) {
331+
Location location = Location.forValue(member.getLocation());
332+
if (location == null) {
333+
return null;
334+
}
335+
switch (location) {
336+
case URI:
337+
case QUERY_STRING:
338+
return isDirectInputShape(parentShape, allC2jShapes) ? location : null;
339+
case HEADER:
340+
case HEADERS:
341+
return isDirectOperationShape(parentShape, allC2jShapes) ? location : null;
342+
case STATUS_CODE:
343+
return isDirectOutputShape(parentShape, allC2jShapes) ? location : null;
344+
default:
345+
return location;
351346
}
352-
return directOperationShapes.contains(parentShape);
347+
}
348+
349+
private boolean isDirectInputShape(Shape shape, Map<String, Shape> allC2jShapes) {
350+
return builder.getService().getOperations().values().stream()
351+
.filter(o -> o.getInput() != null)
352+
.anyMatch(o -> allC2jShapes.get(o.getInput().getShape()).equals(shape));
353+
}
354+
355+
private boolean isDirectOutputShape(Shape shape, Map<String, Shape> allC2jShapes) {
356+
return builder.getService().getOperations().values().stream()
357+
.filter(o -> o.getOutput() != null)
358+
.anyMatch(o -> allC2jShapes.get(o.getOutput().getShape()).equals(shape));
359+
}
360+
361+
private boolean isDirectOperationShape(Shape shape, Map<String, Shape> allC2jShapes) {
362+
return builder.getService().getOperations().values().stream()
363+
.anyMatch(o -> (o.getInput() != null && allC2jShapes.get(o.getInput().getShape()).equals(shape))
364+
|| (o.getOutput() != null && allC2jShapes.get(o.getOutput().getShape()).equals(shape))
365+
|| (o.getErrors() != null && o.getErrors().stream()
366+
.anyMatch(e -> allC2jShapes.get(e.getShape()).equals(shape))));
353367
}
354368

355369
private boolean isFlattened(Member member, Shape memberShape) {
@@ -407,8 +421,8 @@ private Optional<String> findRequestUri(Shape parentShape, Map<String, Shape> al
407421
.map(Map.Entry::getKey)
408422
.findFirst()
409423
.orElseThrow(() -> new IllegalStateException("Shape not found in model: " + parentShape));
410-
String detailMsg = "Could not find request URI for input shape '" + shapeName
411-
+ "'. No operation was found that references this shape as its input.";
424+
String detailMsg = "Operation referencing input shape '" + shapeName
425+
+ "' has no requestUri configured in its HTTP binding.";
412426
ValidationEntry entry =
413427
new ValidationEntry().withErrorId(ValidationErrorId.REQUEST_URI_NOT_FOUND)
414428
.withDetailMessage(detailMsg)

0 commit comments

Comments
 (0)