private ValidationEvent constructValidationEvent(
            TextInstance instance,
            List<String> replacements,
            String matchedText
    ) {
        String replacementAddendum = getReplacementAddendum(matchedText, replacements);
        switch (instance.getLocationType()) {
            case NAMESPACE:
                //Cannot use any warning() overloads because there is no shape associated with the event.
                return ValidationEvent.builder()
                        .severity(Severity.WARNING)
                        .sourceLocation(SourceLocation.none())
                        .id(getName() + "." + NAMESPACE + "." + instance.getText()
                                + "." + matchedText.toLowerCase(Locale.US))
                        .message(String.format("%s namespace uses a non-inclusive term `%s`.%s",
                                instance.getText(),
                                matchedText,
                                replacementAddendum))
                        .build();
            case APPLIED_TRAIT:
                ValidationEvent validationEvent =
                        warning(instance.getShape(), instance.getTrait().getSourceLocation(), "");
                String idiomaticTraitName = Trait.getIdiomaticTraitName(instance.getTrait());
                if (instance.getTraitPropertyPath().isEmpty()) {
                    return validationEvent.toBuilder()
                            .message(String.format("'%s' trait has a value that contains a non-inclusive term `%s`.%s",
                                    idiomaticTraitName,
                                    matchedText,
                                    replacementAddendum))
                            .id(getName() + "." + TRAIT + "."
                                    + matchedText.toLowerCase(Locale.US) + "." + idiomaticTraitName)
                            .build();
                } else {
                    String valuePropertyPathFormatted = formatPropertyPath(instance.getTraitPropertyPath());
                    return validationEvent.toBuilder()
                            .message(String.format(
                                    "'%s' trait value at path {%s} contains a non-inclusive term `%s`.%s",
                                    idiomaticTraitName,
                                    valuePropertyPathFormatted,
                                    matchedText,
                                    replacementAddendum))
                            .id(getName() + "." + TRAIT + "." + matchedText.toLowerCase(Locale.US)
                                    + "." + idiomaticTraitName + "." + valuePropertyPathFormatted)
                            .build();
                }
            case SHAPE:
            default:
                return warning(instance.getShape(),
                        instance.getShape().getSourceLocation(),
                        String.format("%s shape uses a non-inclusive term `%s`.%s",
                                StringUtils.capitalize(instance.getShape().getType().toString()),
                                matchedText,
                                replacementAddendum),
                        SHAPE,
                        matchedText.toLowerCase(Locale.US));
        }
    }
Generates zero or more @see ValidationEvents and returns them in a collection.

@param instance text occurrence found in the body of the model
smithy-linters/src/main/java/software/amazon/smithy/linters/NoninclusiveTermsValidator.java