Code review comment: I think we should not call advanceProgress here, because it may be possible that advanceProgress would generate outputs, which is not allowed in open. maybe just add an initialProgess paramter in the constructor?

Code under review:
public void open() throws Exception {
        super.open();

        lastTriggeredProcessingTime = Long.MIN_VALUE;
        collector = new TimestampedCollector<>(output);
        collector.eraseTimestamp();

        internalTimerService =
                getInternalTimerService(
                        "window-timers", windowProcessor.createWindowSerializer(), this);

        windowProcessor.open(
                new WindowProcessorContext<>(
                        getContainingTask(),
                        getContainingTask().getEnvironment().getMemoryManager(),
                        computeMemorySize(),
                        internalTimerService,
                        getKeyedStateBackend(),
                        collector,
                        getRuntimeContext()));
        
        windowProcessor.advanceProgress(currentWatermark);

        
        this.numLateRecordsDropped = metrics.counter(LATE_ELEMENTS_DROPPED_METRIC_NAME);
        this.lateRecordsDroppedRate =
                metrics.meter(
                        LATE_ELEMENTS_DROPPED_RATE_METRIC_NAME,
                        new MeterView(numLateRecordsDropped));
        this.watermarkLatency =
                metrics.gauge(
                        WATERMARK_LATENCY_METRIC_NAME,
                        () -> {
                            long watermark = internalTimerService.currentWatermark();
                            if (watermark < 0) {
                                return 0L;
                            } else {
                                return internalTimerService.currentProcessingTime() - watermark;
                            }
                        });
    }

Line commented on: windowProcessor.advanceProgress(currentWatermark);

Revised code:
public void open() throws Exception {
        super.open();

        lastTriggeredProcessingTime = Long.MIN_VALUE;
        collector = new TimestampedCollector<>(output);
        collector.eraseTimestamp();

        internalTimerService =
                getInternalTimerService(
                        "window-timers", windowProcessor.createWindowSerializer(), this);

        windowProcessor.open(
                new WindowProcessorContext<>(
                        getContainingTask(),
                        getContainingTask().getEnvironment().getMemoryManager(),
                        computeMemorySize(),
                        internalTimerService,
                        getKeyedStateBackend(),
                        collector,
                        getRuntimeContext()));
        
        windowProcessor.initializeWatermark(currentWatermark);

        
        this.numLateRecordsDropped = metrics.counter(LATE_ELEMENTS_DROPPED_METRIC_NAME);
        this.lateRecordsDroppedRate =
                metrics.meter(
                        LATE_ELEMENTS_DROPPED_RATE_METRIC_NAME,
                        new MeterView(numLateRecordsDropped));
        this.watermarkLatency =
                metrics.gauge(
                        WATERMARK_LATENCY_METRIC_NAME,
                        () -> {
                            long watermark = internalTimerService.currentWatermark();
                            if (watermark < 0) {
                                return 0L;
                            } else {
                                return internalTimerService.currentProcessingTime() - watermark;
                            }
                        });
    }