text: /**
   * Copyright (c) Facebook, Inc. and its affiliates.
   *
   * This source code is licensed under the MIT license found in the
   * LICENSE file in the root directory of this source tree.
   *
   * @flow
   */
  
  import type {FiberRoot, SuspenseHydrationCallbacks} from './ReactInternalTypes';
  import type {RootTag} from './ReactRootTags';
  
  import {noTimeout, supportsHydration} from './ReactFiberHostConfig';
  import {createHostRootFiber} from './ReactFiber.old';
  import {
    NoLane,
    NoLanes,
    NoTimestamp,
    TotalLanes,
    createLaneMap,
  } from './ReactFiberLane.old';
  import {
    enableSuspenseCallback,
    enableCache,
    enableProfilerCommitHooks,
    enableProfilerTimer,
    enableUpdaterTracking,
  } from 'shared/ReactFeatureFlags';
  import {initializeUpdateQueue} from './ReactUpdateQueue.old';
  import {LegacyRoot, ConcurrentRoot} from './ReactRootTags';
  import {createCache, retainCache} from './ReactFiberCacheComponent.old';
  
  function FiberRootNode(containerInfo, tag, hydrate, identifierPrefix) {
    this.tag = tag;
    this.containerInfo = containerInfo;
    this.pendingChildren = null;
    this.current = null;
    this.pingCache = null;
    this.finishedWork = null;
    this.timeoutHandle = noTimeout;
    this.context = null;
    this.pendingContext = null;
    this.isDehydrated = hydrate;
    this.callbackNode = null;
    this.callbackPriority = NoLane;
    this.eventTimes = createLaneMap(NoLanes);
    this.expirationTimes = createLaneMap(NoTimestamp);
  
    this.pendingLanes = NoLanes;
    this.suspendedLanes = NoLanes;
    this.pingedLanes = NoLanes;
    this.expiredLanes = NoLanes;
    this.mutableReadLanes = NoLanes;
    this.finishedLanes = NoLanes;
  
    this.entangledLanes = NoLanes;
    this.entanglements = createLaneMap(NoLanes);
  
    this.identifierPrefix = identifierPrefix;
  
    if (enableCache) {
      this.pooledCache = null;
      this.pooledCacheLanes = NoLanes;
    }
  
    if (supportsHydration) {
      this.mutableSourceEagerHydrationData = null;
    }
  
    if (enableSuspenseCallback) {
      this.hydrationCallbacks = null;
    }
  
    if (enableProfilerTimer && enableProfilerCommitHooks) {
      this.effectDuration = 0;
      this.passiveEffectDuration = 0;
    }
  
    if (enableUpdaterTracking) {
      this.memoizedUpdaters = new Set();
      const pendingUpdatersLaneMap = (this.pendingUpdatersLaneMap = []);
      for (let i = 0; i < TotalLanes; i++) {
        pendingUpdatersLaneMap.push(new Set());
      }
    }
  
    if (__DEV__) {
      switch (tag) {
        case ConcurrentRoot:
          this._debugRootType = hydrate ? 'hydrateRoot()' : 'createRoot()';
          break;
        case LegacyRoot:
          this._debugRootType = hydrate ? 'hydrate()' : 'render()';
          break;
      }
    }
  }
  
  export function createFiberRoot(
    containerInfo: any,
    tag: RootTag,
    hydrate: boolean,
    hydrationCallbacks: null | SuspenseHydrationCallbacks,
    isStrictMode: boolean,
    concurrentUpdatesByDefaultOverride: null | boolean,
    identifierPrefix: string,
  ): FiberRoot {
    const root: FiberRoot = (new FiberRootNode(
      containerInfo,
      tag,
      hydrate,
      identifierPrefix,
    ): any);
    if (enableSuspenseCallback) {
      root.hydrationCallbacks = hydrationCallbacks;
    }
  
    // Cyclic construction. This cheats the type system right now because
    // stateNode is any.
    const uninitializedFiber = createHostRootFiber(
      tag, //legacyRoot 0
      isStrictMode,
      concurrentUpdatesByDefaultOverride,
    );
    // FiberRoot current point to rootFiber
    root.current = uninitializedFiber;
    uninitializedFiber.stateNode = root;
  
    if (enableCache) {
      const initialCache = createCache();
      retainCache(initialCache);
  
      // The pooledCache is a fresh cache instance that is used temporarily
      // for newly mounted boundaries during a render. In general, the
      // pooledCache is always cleared from the root at the end of a render:
      // it is either released when render commits, or moved to an Offscreen
      // component if rendering suspends. Because the lifetime of the pooled
      // cache is distinct from the main memoizedState.cache, it must be
      // retained separately.
      root.pooledCache = initialCache;
      retainCache(initialCache);
      const initialState = {
        element: null,
        cache: initialCache,
      };
      uninitializedFiber.memoizedState = initialState;
    } else {
      const initialState = {
        element: null,
      };
      uninitializedFiber.memoizedState = initialState;
    }
  
    initializeUpdateQueue(uninitializedFiber);
  
    return root;
  }
  