Skip to content

feat: accept a CancellationToken in EmptyStreamingMarkdownFile - #210

Merged
Ilia Permiashkin (p3rmiashkin) merged 1 commit into
JetBrains:masterfrom
rvandermeulen:streaming-cancellation-token
Aug 1, 2026
Merged

feat: accept a CancellationToken in EmptyStreamingMarkdownFile#210
Ilia Permiashkin (p3rmiashkin) merged 1 commit into
JetBrains:masterfrom
rvandermeulen:streaming-cancellation-token

Conversation

@rvandermeulen

Copy link
Copy Markdown
Contributor

Problem

EmptyStreamingMarkdownFile hardcodes MarkdownParser(flavour), so a streaming file always parses with CancellationToken.NonCancellable and an append cannot be aborted. It is the only remaining place in commonMain that constructs a MarkdownParser without a token: cancellation support (#141) and the streaming parser (#185) landed independently, and #203 threaded the token further into TopLevelBuilder.

This matters most when a block never closes. An unterminated fence keeps the whole document in unstableTail, so every append reparses all of it with no way to bail out. That is a common shape for LLM-generated markdown, which is the context this was found in: Firefox for Android renders streamed page summaries through this parser.

Approach

It was not clear what the project's policy on ABI compatibility is, beyond the // To keep the ABI compatibility. comments in MarkdownParser.kt, so the safer route was taken here.

Adding a second defaulted parameter to the existing function would drop the EmptyStreamingMarkdownFile$default(MarkdownFlavourDescriptor, int, Object) synthetic that no-argument Kotlin callers bind to, breaking anything compiled against 0.7.8. Instead the flavour-only function is unchanged and delegates to a new two-argument overload. Diffing compiled method sets against the published 0.7.8 jar confirms nothing removed and one method added.

The cost is an extra overload, plus the loss of EmptyStreamingMarkdownFile(cancellationToken = token), since the default flavour can no longer be combined with a token. Should an ABI break be acceptable, the single-function form seems preferable and can be substituted on request.

MarkdownParser, TreeBuilder, TopLevelBuilder and SequentialParserManager all deprecate their tokenless entry points. EmptyStreamingMarkdownFile(flavour) is left undeprecated here because the no-argument form is used throughout the existing test suite, but the deprecation can be added for consistency if preferred.

Tests

Added three new cases: cancellation propagating out of append, the token being consulted on successive appends while the unstable tail grows, and the flavour-only overload producing output identical to an explicit NonCancellable.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update CHANGELOG.md

Comment thread src/commonTest/kotlin/org/intellij/markdown/parser/StreamingMarkdownFileTest.kt Outdated
`EmptyStreamingMarkdownFile` hardcoded `MarkdownParser(flavour)`, so the streaming
parser always ran with `CancellationToken.NonCancellable` and callers had no way to
make an `append` abortable. This matters most when a block never closes: an
unterminated fence keeps the whole document in `unstableTail`, so every append
reparses all of it.

The existing flavour-only function is left as-is and delegates to a new two-argument
overload, so the change is additive at the ABI level.
@rvandermeulen

Ryan VanderMeulen (rvandermeulen) commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

Dropped flavourOnlyOverloadMatchesExplicitNonCancellable. The two remaining cases cover distinct behaviour: the token being consulted on successive appends while the unstable tail grows, and an exception from the token propagating out of append.

CHANGELOG.md was already updated in this PR: [#210] Accept a CancellationToken in EmptyStreamingMarkdownFile, at the top of ## [Unreleased]. Happy to reword or move it if something specific was intended there.

@p3rmiashkin
Ilia Permiashkin (p3rmiashkin) merged commit 14e35f1 into JetBrains:master Aug 1, 2026
3 checks passed
@rvandermeulen
Ryan VanderMeulen (rvandermeulen) deleted the streaming-cancellation-token branch August 2, 2026 03:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants