public Model build() {
        SmithyBuilder.requiredState("arguments", arguments);
        SmithyBuilder.requiredState("models", models);
        SmithyBuilder.requiredState("env", env);
        SmithyBuilder.requiredState("config", config);

        StandardOptions standardOptions = arguments.getReceiver(StandardOptions.class);
        BuildOptions buildOptions = arguments.getReceiver(BuildOptions.class);

        // Resolve validator options and severity.
        ValidatorOptions validatorOptions = arguments.hasReceiver(ValidatorOptions.class)
                ? arguments.getReceiver(ValidatorOptions.class)
                : new ValidatorOptions();
        resolveMinSeverity(standardOptions, validatorOptions);

        ClassLoader classLoader = env.classLoader();
        ColorFormatter colors = env.colors();
        CliPrinter stderr = env.stderr();

        if (validationPrinter == null) {
            validationPrinter = env.stderr();
        }

        if (validationMode == null) {
            validationMode = Validator.Mode.from(standardOptions);
        }

        if (validatedResult == null) {
            ModelAssembler assembler = createModelAssembler(classLoader);

            if (validationMode == Validator.Mode.QUIET_CORE_ONLY) {
                assembler.disableValidation();
            }

            // Emit status updates.
            AtomicInteger issueCount = new AtomicInteger();
            assembler.validationEventListener(createStatusUpdater(standardOptions, colors, stderr, issueCount));

            handleModelDiscovery(assembler, classLoader, config);
            handleUnknownTraitsOption(buildOptions, assembler);

            // Add imports and sources from the config by default, but this can be disabled (e.g., smithy diff).
            if (!disableConfigModels) {
                config.getSources().forEach(assembler::addImport);
                config.getImports().forEach(assembler::addImport);
            }

            models.forEach(assembler::addImport);
            validatedResult = assembler.assemble();
            clearStatusUpdateIfPresent(issueCount, stderr);
        }

        // Sort events by file so that we can efficiently read files for context sequentially.
        List<ValidationEvent> sortedEvents = new ArrayList<>(validatedResult.getValidationEvents());
        sortedEvents.sort(Comparator.comparing(ValidationEvent::getSourceLocation));

        SourceContextLoader sourceContextLoader = validatedResult.getResult()
                .map(model -> SourceContextLoader.createModelAwareLoader(model, DEFAULT_CODE_LINES))
                .orElseGet(() -> SourceContextLoader.createLineBasedLoader(DEFAULT_CODE_LINES));
        PrettyAnsiValidationFormatter formatter = PrettyAnsiValidationFormatter.builder()
                .sourceContextLoader(sourceContextLoader)
                .colors(colors)
                .titleLabel(titleLabel, titleLabelStyles)
                .build();

        if (!disableOutputFormatFraming) {
            validationOutputFormat.beginPrinting(validationPrinter);
        }

        for (ValidationEvent event : sortedEvents) {
            // Only log events that are >= --severity. Note that setting --quiet inherently
            // configures events to need to be >= DANGER. Also filter using --show-validators and --hide-validators.
            if (validatorOptions.isVisible(event)) {
                validationOutputFormat.print(validationPrinter, formatter, event);
            }
        }

        if (!disableOutputFormatFraming) {
            validationOutputFormat.endPrinting(validationPrinter);
        }

        env.flush();
        // Note: disabling validation will still show a summary of failures if the model can't be loaded.
        Validator.validate(validationMode != Validator.Mode.ENABLE, colors, stderr, validatedResult);
        env.flush();

        return validatedResult.getResult().orElseThrow(() -> new RuntimeException("Expected Validator to throw"));
    }
Loads, builds, and report validation issues with models.
smithy-cli/src/main/java/software/amazon/smithy/cli/commands/ModelBuilder.java