public static <FnT extends DoFn<?, ?>> DoFnSignature getSignature(Class<FnT> fn) {
    return signatureCache.computeIfAbsent(fn, DoFnSignatures::parseSignature);
  }
@Test
  public void testStartBundleWithAllParameters() throws Exception {
    DoFnSignature sig =
        DoFnSignatures.getSignature(
            new DoFn<String, String>() {
              @ProcessElement
              public void processElement() {}

              @StartBundle
              public void startBundle(
                  StartBundleContext context,
                  BundleFinalizer bundleFinalizer,
                  PipelineOptions options) {}
            }.getClass());
    assertThat(sig.startBundle().extraParameters().size(), equalTo(3));
    assertThat(
        sig.startBundle().extraParameters().get(0), instanceOf(StartBundleContextParameter.class));
    assertThat(
        sig.startBundle().extraParameters().get(1), instanceOf(BundleFinalizerParameter.class));
    assertThat(
        sig.startBundle().extraParameters().get(2), instanceOf(PipelineOptionsParameter.class));
  }