in codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/knowledge/GoValidationIndex.java [61:113]
public GoValidationIndex(Model model) {
TopDownIndex topDownIndex = model.getKnowledge(TopDownIndex.class);
Walker walker = new Walker(model);
model.shapes(ServiceShape.class).forEach(serviceShape -> {
// Go uses unique input shapes per operation so we can index using the input shape as our key
Map<Shape, OperationShape> inputShapeToOperation = new HashMap<>();
Set<ShapeId> requireValidationHelpers = new TreeSet<>();
// First pass is to collect member containers that contain members requiring validation
Set<OperationShape> operations = topDownIndex.getContainedOperations(serviceShape);
operations.forEach(operationShape -> {
Shape inputShape = model.expectShape(operationShape.getInput().get());
GoValidationIndex.walkValidationTree(walker, inputShape, shape -> {
if (shape.isMemberShape()) {
Shape container = model.expectShape(((MemberShape) shape).getContainer());
if (isRequiredParameter(model, (MemberShape) shape, inputShape.equals(container))) {
inputShapeToOperation.put(inputShape, operationShape);
requireValidationHelpers.add(container.toShapeId());
}
}
});
});
// 2nd step is final all containers that reference the initial containers which require validation until
// we've discovered all intermediate containing types
inputShapeToOperation.keySet().forEach(input -> {
Set<ShapeId> helpers = new TreeSet<>();
do {
GoValidationIndex.walkValidationTree(walker, input, shape -> {
if (shape.isMemberShape()) {
MemberShape memberShape = shape.asMemberShape().get();
Shape container = model.expectShape(memberShape.getContainer());
Shape target = model.expectShape(memberShape.getTarget());
if (requireValidationHelpers.contains(target.toShapeId())
&& !requireValidationHelpers.contains(container.toShapeId())) {
helpers.add(container.toShapeId());
}
}
});
if (helpers.isEmpty()) {
break;
}
requireValidationHelpers.addAll(helpers);
helpers.clear();
} while (true);
});
serviceToOperationMap.put(serviceShape.toShapeId(), new TreeSet<>(inputShapeToOperation.values().stream()
.map(OperationShape::toShapeId).collect(Collectors.toSet())));
serviceValidationHelpers.put(serviceShape.toShapeId(), requireValidationHelpers);
});
}