public static <FnT extends DoFn<?, ?>> DoFnSignature getSignature(Class<FnT> fn) {
    return signatureCache.computeIfAbsent(fn, DoFnSignatures::parseSignature);
  }
@Test
  public void testWindowParamOnTimer() throws Exception {
    final String timerId = "some-timer-id";
    final String timerDeclarationId = TimerDeclaration.PREFIX + timerId;

    DoFnSignature sig =
        DoFnSignatures.getSignature(
            new DoFn<String, String>() {

              @TimerId(timerId)
              private final TimerSpec myfield1 = TimerSpecs.timer(TimeDomain.EVENT_TIME);

              @ProcessElement
              public void process(ProcessContext c) {}

              @OnTimer(timerId)
              public void onTimer(BoundedWindow w) {}
            }.getClass());

    assertThat(sig.onTimerMethods().get(timerDeclarationId).extraParameters().size(), equalTo(1));
    assertThat(
        sig.onTimerMethods().get(timerDeclarationId).extraParameters().get(0),
        instanceOf(WindowParameter.class));
  }