Skip to content

createStreamParser() and parse() disagree on redefined statement IDs #1127

Description

@seshuthota

parse() and createStreamParser() produce different final results for the same completed OpenUI Lang program when a statement ID is defined more than once.

The batch parser behaves as last definition wins, while the streaming parser behaves as first definition wins.

Minimal reproduction

const text = root = Stack([a]) a = Title("x") a = Title("y") ;

const batch = parse(text, schema);
// root -> Title("y")

const stream = createStreamParser(schema);
stream.push(text);
const streamed = stream.getResult();
// root -> Title("x")

Actual behavior

For the same completed input:

parse(text) -> Title("y")
createStreamParser().push() -> Title("x")

I also tested multiple delivery schedules:

the whole input in a single push()

line-by-line

character-by-character

multiple two-chunk splits

The streaming parser consistently returns "x" in all of these cases, while parse() consistently returns "y".

So this does not appear to be a chunk-boundary race. It looks like a systematic difference in duplicate/redefined statement semantics between the batch and streaming parsers.

Likely cause

The batch parser builds its statement map using normal Map.set() behavior, so a later statement with the same ID replaces the earlier one.

The streaming parser caches completed statements and skips a later completed statement when the ID is already present, effectively making that path first-definition-wins.

In particular, the completed-statement cache together with the existing guard around an already-present statement ID appears to preserve the first definition.

Expected behavior / question

I think parse() and createStreamParser() should have the same final semantics for the same completed input.

I'm not sure which duplicate-ID behavior is intended:

last definition wins

first definition wins

duplicate statement IDs are invalid and should produce a parser error

Happy to contribute the corresponding fix and regression coverage once the intended behavior is confirmed.

Additional context

I found this while building a streaming-invariance test harness for createStreamParser().

The harness currently checks valid OpenUI Lang programs across:

exhaustive single-cut partitions

exhaustive two-cut partitions

seeded multi-cut partitions

trailing-newline variants

no-prefix-crash behavior

error convergence

determinism

Those tests are currently green. Duplicate statement IDs were deliberately excluded because their intended semantics were unclear; testing that excluded case exposed this batch-vs-stream divergence.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions