Skip to content

WProto: cross-assembly subtype dispatch, currently refused with WPROTO040 #603

Description

What

#601 asked for zero-touch subtypes and named two asks. The tag manifest shipped and answers the first: an author writes [WProtoSubtype(typeof(Base))], never picks a number, never edits the base, never reads a sibling, and add / remove / re-add preserves the wire.

The second ask is unanswered, and no tag scheme can answer it:

Let a client slap this attribute on a type in their assembly.

A subtype in a consumer's assembly deriving from a base in this package. A per-assembly generator provably cannot see it: the base's dispatch chain was emitted when the base's assembly compiled. It is refused today with WPROTO040, and #601's research recorded why the manifest deliberately does not extend to it.

Why it is a different mechanism, not a bigger manifest

A manifest cannot coordinate across repositories that never see each other. This needs a runtime registry, and its hazards are the durable-wire kind:

  • Unity's registrars run unordered. A serialize that happens before every registrar has run writes under the wrong tag, or none. The registry needs freeze semantics that refuse late registration after first use.
  • Two unrelated packages picking the same tag on a shared base is undetectable at build time and silently type-confusing at read time. Arbitration has to be a runtime error at registration.
  • Dispatch is currently branch-only static code. A registry lookup has to stay IL2CPP-safe — no MakeGenericType — and stripping has to be told to keep formatters that nothing statically references.

Each of those failure modes is silent data corruption rather than a build error, which is why #601 refused to fold this in.

Acceptance criteria

  • A consumer assembly can declare a subtype of a package base and have it round-trip, or the refusal stays and WPROTO040's message explains the permanent reason rather than implying a future.
  • Registration after first use is refused loudly, not honoured.
  • Two registrations claiming one tag on one base fail at registration with both type names.
  • The dispatch path is IL2CPP-safe and survives managed stripping, proven on a standalone player.
  • Round-trip against protobuf-net 2.4.9 and 3.2.56 is preserved in both directions, since that is the package's central promise.

Notes

WPROTO040 currently refuses this and should keep refusing it until the above holds — a build error is strictly better than a player that writes an unreadable save.

Split from #601, which shipped the same-assembly half.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions