For Parsoid purposes, the interwiki mapping needs to be bidirectional -- that is, we need to be able not just to go from `enwiki:$1` to `//en.wikipedia.org/wiki/$1` but also given a URL `https://en.wkipedia.org/wiki/Foo` we need to lookup that this patches the `enwiki` prefix.
We are currently doing this by calling the InterwikiLookup::getAllPrefixes() method *but* this doesn't play nicely with the `InterwikiLoadPrefix` hook. That is, `InterwikiLoadPrefix` is demand-driven, but extensions can add new prefixes via `InterwikiLoadPrefix` (and `Extension:Interwiki` does so, as does the parser test infrastructure) without them showing up in `::getAllPrefixes()`. In fact, `Extension:Interwiki` explicitly requires that the new prefixes *not* show up in `::getAllPrefixes`, as its implementation of the `InterwikiLoadPrefix` hook recursively calls `::getAllPrefixes` to avoid delegating lookup of prefixes defined locally.
One solution is to add a "reverse mapping" API and hook to InterwikiLookup, say:
public function match( $url ): string {
if ( !$this->hookRunner->onInterwikiMatchPrefix( $url, $result ) ) {
return $result;
}
// else....
}
This would allow Parsoid to call *just* `InterwikiLookup::fetch` and `InterwikiLookup::match` and avoid calling the problematic `::getAllPrefixes` method (or indeed, avoid enumerating all prefixes at all).
The `Extension:Interwiki` could continue to recursively invoke `::getAllPrefixes` to determine what prefixes the base wiki supports. It would implement the new `InterwikiMatchPrefix` hook by enumerating the interwiki table from the central DB (caching would help here!) and then returning `true` to indicate that any matches from the local DB should take precedence.
But {T113034} proposes to overhaul and unify the interwiki map; it's possible that would lead to a better solution.