defineBridgeLazy method

void defineBridgeLazy(
  1. String name,
  2. Type nativeType,
  3. BridgedClass thunk(), {
  4. String? sourceUri,
})

Registers a bridged class as a deferred thunk keyed by name, plus a parallel Type → thunk entry under nativeType for native-object resolution. The BridgedClass is built (and memoized) only when name or nativeType is first resolved — the substrate the generator's lazy emission plugs into (import-optimization plan step #17).

In the common no-collision case the thunk is stored without building. A genuine same-name collision (another bridge / enum / value already holds name) resolves the new thunk eagerly so the displaced bridge can be preserved for candidate enumeration and the shadow list shares the same instance the memo will serve. Collisions are rare, so this does not regress the common lazy path.

sourceUri is the URI of the library that declares the class (not the barrel it was imported through). It is what makes two same-named bridges distinguishable: when a second, different nativeType registers under an already-taken name, the name becomes ambiguous — see _markAmbiguousBridgeName.

Implementation

void defineBridgeLazy(
  String name,
  Type nativeType,
  BridgedClass Function() thunk, {
  String? sourceUri,
}) {
  final priorBridge = _bridgedClassesRaw?[name];
  final collides =
      _values.containsKey(name) ||
      priorBridge != null ||
      _bridgedEnums.containsKey(name);
  if (collides) {
    // CHECK: Also collides with bridged enums / values.
    Logger.warn(
      "Redefining bridged class or colliding with existing definition: $name",
    );
    // Preserve a displaced same-name bridge so every candidate stays
    // enumerable (two packages exporting an identically named class).
    final built = thunk();
    _recordShadowedBridge(name, priorBridge, built);
    thunk = () => built;
    // Two DIFFERENT native classes under one simple name is Dart's
    // ambiguous-import case: the bare name stops resolving and the script
    // must qualify. Same nativeType means the same class arriving through a
    // second barrel — a re-export, not an ambiguity.
    if (priorBridge != null && priorBridge.nativeType != nativeType) {
      if (_markAmbiguousBridgeName(name, priorBridge, built, sourceUri)) {
        // This registration is a `dart:*` declaration that the sitting
        // non-platform one shadows. It stays reachable by qualifier and by
        // native type, but must not take the bare name — nor overwrite the
        // recorded source URI, which still describes the winner.
        _bridgedClassesLookupByTypeOrNew.putThunk(nativeType, thunk);
        _invalidateResolutionCache();
        return;
      }
    }
  }
  if (sourceUri != null) _bridgeSourceUrisOrNew[name] = sourceUri;
  _bridgedClassesOrNew.putThunk(name, thunk);
  _bridgedClassesLookupByTypeOrNew.putThunk(nativeType, thunk);
  _invalidateResolutionCache();
  Logger.debugLazy(() => "[Environment] Defined bridge for class: $name");
}