static void format(final JavaInput javaInput, JavaOutput javaOutput, JavaFormatterOptions options)
      throws FormatterException {
    Context context = new Context();
    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
    context.put(DiagnosticListener.class, diagnostics);
    Options.instance(context).put("allowStringFolding", "false");
    Options.instance(context).put("--enable-preview", "true");
    JCCompilationUnit unit;
    JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8);
    try {
      fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, ImmutableList.of());
    } catch (IOException e) {
      // impossible
      throw new IOError(e);
    }
    SimpleJavaFileObject source =
        new SimpleJavaFileObject(URI.create("source"), JavaFileObject.Kind.SOURCE) {
          @Override
          public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
            return javaInput.getText();
          }
        };
    Log.instance(context).useSource(source);
    ParserFactory parserFactory = ParserFactory.instance(context);
    JavacParser parser =
        parserFactory.newParser(
            javaInput.getText(),
            /* keepDocComments= */ true,
            /* keepEndPos= */ true,
            /* keepLineMap= */ true);
    unit = parser.parseCompilationUnit();
    unit.sourcefile = source;

    javaInput.setCompilationUnit(unit);
    Iterable<Diagnostic<? extends JavaFileObject>> errorDiagnostics =
        Iterables.filter(diagnostics.getDiagnostics(), Formatter::errorDiagnostic);
    if (!Iterables.isEmpty(errorDiagnostics)) {
      throw FormatterException.fromJavacDiagnostics(errorDiagnostics);
    }
    OpsBuilder builder = new OpsBuilder(javaInput, javaOutput);
    // Output the compilation unit.
    JavaInputAstVisitor visitor;
    if (Runtime.version().feature() >= 21) {
      visitor =
          createVisitor(
              "com.google.googlejavaformat.java.java21.Java21InputAstVisitor", builder, options);
    } else if (Runtime.version().feature() >= 17) {
      visitor =
          createVisitor(
              "com.google.googlejavaformat.java.java17.Java17InputAstVisitor", builder, options);
    } else {
      visitor = new JavaInputAstVisitor(builder, options.indentationMultiplier());
    }
    visitor.scan(unit, null);
    builder.sync(javaInput.getText().length());
    builder.drain();
    Doc doc = new DocBuilder().withOps(builder.build()).build();
    doc.computeBreaks(javaOutput.getCommentsHelper(), MAX_LINE_LENGTH, new Doc.State(+0, 0));
    doc.write(javaOutput);
    javaOutput.flush();
  }
@Test
  public void testFormatStdinStdoutWithDashFlag() throws Exception {
    String input = "class Foo{\n" + "void f\n" + "() {\n" + "}\n" + "}\n";
    String expectedOutput = "class Foo {\n" + "  void f() {}\n" + "}\n";

    InputStream in = new ByteArrayInputStream(input.getBytes(UTF_8));
    StringWriter out = new StringWriter();
    StringWriter err = new StringWriter();

    InputStream oldIn = System.in;
    System.setIn(in);

    Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in);
    assertThat(main.format("-")).isEqualTo(0);
    assertThat(out.toString()).isEqualTo(expectedOutput);

    System.setIn(oldIn);
  }