private void writeWaiterComparator()

in codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/integration/Waiters.java [661:765]


    private void writeWaiterComparator(
            GoWriter writer,
            Acceptor acceptor,
            PathComparator comparator,
            Symbol targetSymbol,
            String actual,
            String expected
    ) {
        if (targetSymbol == null) {
            targetSymbol = SymbolUtils.createValueSymbolBuilder("string").build();
        }

        String valueAccessor = "string(value)";
        Optional<Boolean> isPointable = targetSymbol.getProperty(SymbolUtils.POINTABLE, Boolean.class);
        if (isPointable.isPresent() && isPointable.get().booleanValue()) {
            valueAccessor = "string(*value)";
        }

        switch (comparator) {
            case STRING_EQUALS:
                writer.write("value, ok := $L.($P)", actual, targetSymbol);
                writer.write("if !ok {");
                writer.write("return false, fmt.Errorf(\"waiter comparator expected $P value, got %T\", $L)}",
                        targetSymbol, actual);
                writer.write("");

                writer.openBlock("if $L == $L {", "}", valueAccessor, expected, () -> {
                    writeMatchedAcceptorReturn(writer, acceptor);
                });
                break;

            case BOOLEAN_EQUALS:
                writer.addUseImports(SmithyGoDependency.STRCONV);
                writer.write("bv, err := strconv.ParseBool($L)", expected);
                writer.write(
                        "if err != nil { return false, "
                                + "fmt.Errorf(\"error parsing boolean from string %w\", err)}");

                writer.write("value, ok := $L.(bool)", actual);
                writer.openBlock(" if !ok {", "}", () -> {
                    writer.write("return false, "
                            + "fmt.Errorf(\"waiter comparator expected bool value got %T\", $L)", actual);
                });
                writer.write("");

                writer.openBlock("if value == bv {", "}", () -> {
                    writeMatchedAcceptorReturn(writer, acceptor);
                });
                break;

            case ALL_STRING_EQUALS:
                writer.write("var match = true");
                writer.write("listOfValues, ok := $L.([]interface{})", actual);
                writer.openBlock(" if !ok {", "}", () -> {
                    writer.write("return false, "
                            + "fmt.Errorf(\"waiter comparator expected list got %T\", $L)", actual);
                });
                writer.write("");

                writer.write("if len(listOfValues) == 0 { match = false }");

                String allStringValueAccessor = valueAccessor;
                Symbol allStringTargetSymbol = targetSymbol;
                writer.openBlock("for _, v := range listOfValues {", "}", () -> {
                    writer.write("value, ok := v.($P)", allStringTargetSymbol);
                    writer.write("if !ok {");
                    writer.write("return false, fmt.Errorf(\"waiter comparator expected $P value, got %T\", $L)}",
                            allStringTargetSymbol, actual);
                    writer.write("");
                    writer.write("if $L != $L { match = false }", allStringValueAccessor, expected);
                });
                writer.write("");

                writer.openBlock("if match {", "}", () -> {
                    writeMatchedAcceptorReturn(writer, acceptor);
                });
                break;

            case ANY_STRING_EQUALS:
                writer.write("listOfValues, ok := $L.([]interface{})", actual);
                writer.openBlock(" if !ok {", "}", () -> {
                    writer.write("return false, "
                            + "fmt.Errorf(\"waiter comparator expected list got %T\", $L)", actual);
                });
                writer.write("");

                String anyStringValueAccessor = valueAccessor;
                Symbol anyStringTargetSymbol = targetSymbol;
                writer.openBlock("for _, v := range listOfValues {", "}", () -> {
                    writer.write("value, ok := v.($P)", anyStringTargetSymbol);
                    writer.write("if !ok {");
                    writer.write("return false, fmt.Errorf(\"waiter comparator expected $P value, got %T\", $L)}",
                            anyStringTargetSymbol, actual);
                    writer.write("");
                    writer.openBlock("if $L == $L {", "}", anyStringValueAccessor, expected, () -> {
                        writeMatchedAcceptorReturn(writer, acceptor);
                    });
                });
                break;

            default:
                throw new CodegenException(
                        String.format("Found unknown waiter path comparator, %s", comparator.toString()));
        }
    }