The way we see this working is:
- Every options argument to ParserOutput::getText() becomes a ParserOption. NOTE not all of these options will necessarily split the parser cache; only the ones which have been "applied" split the cache.
- Methods which call $parserOutput->getText() will have the ParserOption corresponding to that $parserOutput handy -- it is used in the cache lookup, so it *should* always be available, but sometimes methods don't pass it along appropriately. We will incrementally fix these APIs to ensure the ParserOptions follow the ParserOutput.
- (Eventually) the ParserOutput will track which parser options have already been applied to it as post-cache transformations, allowing the parser output transformation pipeline to (a) be idempotent, and (b) be cacheable at any point. So if you decide you don't want to split the parser cache for anything, you can cache the initial parser results, and handle all the rest of the parser options as post-cache transforms. If later you decide to cache the result of a particular costly intermediate transformation, or even the final transformation output streamed to the user, those will also be stored alongside the record of the transformations already done on them, so a future pass through the pipeline will perform only the "work remaining" from the set of input ParserOptions.
This ought to also avoid the need to mutate the $options array during the post cache transformation pipeline, as both WikidataPageBanner and Translate are currently doing.
See also T303615: There's no reason to split the ParserCache on wrapclass which initially proposed the opposite direction (moving a parser option into a ::getText() parameter) but that's because the parser option was splitting the cache. Step #1 above entails *not* splitting the cache for these options until/unless they are applied to the ParserOutput.