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 {Fiber} from './ReactInternalTypes';
  import type {Lanes} from './ReactFiberLane.new';
  import type {UpdateQueue} from './ReactUpdateQueue.new';
  import type {Flags} from './ReactFiberFlags';
  
  import * as React from 'react';
  import {
    LayoutStatic,
    MountLayoutDev,
    Update,
    Snapshot,
  } from './ReactFiberFlags';
  import {
    debugRenderPhaseSideEffectsForStrictMode,
    disableLegacyContext,
    enableDebugTracing,
    enableSchedulingProfiler,
    warnAboutDeprecatedLifecycles,
    enableStrictEffects,
    enableLazyContextPropagation,
    enableSuspenseLayoutEffectSemantics,
  } from 'shared/ReactFeatureFlags';
  import ReactStrictModeWarnings from './ReactStrictModeWarnings.new';
  import {isMounted} from './ReactFiberTreeReflection';
  import {get as getInstance, set as setInstance} from 'shared/ReactInstanceMap';
  import shallowEqual from 'shared/shallowEqual';
  import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
  import getComponentNameFromType from 'shared/getComponentNameFromType';
  import invariant from 'shared/invariant';
  import isArray from 'shared/isArray';
  import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols';
  
  import {resolveDefaultProps} from './ReactFiberLazyComponent.new';
  import {
    DebugTracingMode,
    NoMode,
    StrictLegacyMode,
    StrictEffectsMode,
  } from './ReactTypeOfMode';
  
  import {
    enqueueUpdate,
    entangleTransitions,
    processUpdateQueue,
    checkHasForceUpdateAfterProcessing,
    resetHasForceUpdateBeforeProcessing,
    createUpdate,
    ReplaceState,
    ForceUpdate,
    initializeUpdateQueue,
    cloneUpdateQueue,
  } from './ReactUpdateQueue.new';
  import {NoLanes} from './ReactFiberLane.new';
  import {
    cacheContext,
    getMaskedContext,
    getUnmaskedContext,
    hasContextChanged,
    emptyContextObject,
  } from './ReactFiberContext.new';
  import {readContext, checkIfContextChanged} from './ReactFiberNewContext.new';
  import {
    requestEventTime,
    requestUpdateLane,
    scheduleUpdateOnFiber,
  } from './ReactFiberWorkLoop.new';
  import {logForceUpdateScheduled, logStateUpdateScheduled} from './DebugTracing';
  
  import {disableLogs, reenableLogs} from 'shared/ConsolePatchingDev';
  import {
    markForceUpdateScheduled,
    markStateUpdateScheduled,
  } from './SchedulingProfiler';
  
  const fakeInternalInstance = {};
  
  // React.Component uses a shared frozen object by default.
  // We'll use it to determine whether we need to initialize legacy refs.
  export const emptyRefsObject = new React.Component().refs;
  
  let didWarnAboutStateAssignmentForComponent;
  let didWarnAboutUninitializedState;
  let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
  let didWarnAboutLegacyLifecyclesAndDerivedState;
  let didWarnAboutUndefinedDerivedState;
  let warnOnUndefinedDerivedState;
  let warnOnInvalidCallback;
  let didWarnAboutDirectlyAssigningPropsToState;
  let didWarnAboutContextTypeAndContextTypes;
  let didWarnAboutInvalidateContextType;
  
  if (__DEV__) {
    didWarnAboutStateAssignmentForComponent = new Set();
    didWarnAboutUninitializedState = new Set();
    didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
    didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
    didWarnAboutDirectlyAssigningPropsToState = new Set();
    didWarnAboutUndefinedDerivedState = new Set();
    didWarnAboutContextTypeAndContextTypes = new Set();
    didWarnAboutInvalidateContextType = new Set();
  
    const didWarnOnInvalidCallback = new Set();
  
    warnOnInvalidCallback = function(callback: mixed, callerName: string) {
      if (callback === null || typeof callback === 'function') {
        return;
      }
      const key = callerName + '_' + (callback: any);
      if (!didWarnOnInvalidCallback.has(key)) {
        didWarnOnInvalidCallback.add(key);
        console.error(
          '%s(...): Expected the last optional `callback` argument to be a ' +
            'function. Instead received: %s.',
          callerName,
          callback,
        );
      }
    };
  
    warnOnUndefinedDerivedState = function(type, partialState) {
      if (partialState === undefined) {
        const componentName = getComponentNameFromType(type) || 'Component';
        if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
          didWarnAboutUndefinedDerivedState.add(componentName);
          console.error(
            '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' +
              'You have returned undefined.',
            componentName,
          );
        }
      }
    };
  
    // This is so gross but it's at least non-critical and can be removed if
    // it causes problems. This is meant to give a nicer error message for
    // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
    // ...)) which otherwise throws a "_processChildContext is not a function"
    // exception.
    Object.defineProperty(fakeInternalInstance, '_processChildContext', {
      enumerable: false,
      value: function() {
        invariant(
          false,
          '_processChildContext is not available in React 16+. This likely ' +
            'means you have multiple copies of React and are attempting to nest ' +
            'a React 15 tree inside a React 16 tree using ' +
            "unstable_renderSubtreeIntoContainer, which isn't supported. Try " +
            'to make sure you have only one copy of React (and ideally, switch ' +
            'to ReactDOM.createPortal).',
        );
      },
    });
    Object.freeze(fakeInternalInstance);
  }
  
  function applyDerivedStateFromProps(
    workInProgress: Fiber,
    ctor: any,
    getDerivedStateFromProps: (props: any, state: any) => any,
    nextProps: any,
  ) {
    const prevState = workInProgress.memoizedState;
  
    if (__DEV__) {
      if (
        debugRenderPhaseSideEffectsForStrictMode &&
        workInProgress.mode & StrictLegacyMode
      ) {
        disableLogs();
        try {
          // Invoke the function an extra time to help detect side-effects.
          getDerivedStateFromProps(nextProps, prevState);
        } finally {
          reenableLogs();
        }
      }
    }
  
    const partialState = getDerivedStateFromProps(nextProps, prevState);
  
    if (__DEV__) {
      warnOnUndefinedDerivedState(ctor, partialState);
    }
    // Merge the partial state and the previous state.
    const memoizedState =
      partialState === null || partialState === undefined
        ? prevState
        : Object.assign({}, prevState, partialState);
    workInProgress.memoizedState = memoizedState;
  
    // Once the update queue is empty, persist the derived state onto the
    // base state.
    if (workInProgress.lanes === NoLanes) {
      // Queue is always non-null for classes
      const updateQueue: UpdateQueue<any> = (workInProgress.updateQueue: any);
      updateQueue.baseState = memoizedState;
    }
  }
  
  const classComponentUpdater = {
    isMounted,
    enqueueSetState(inst, payload, callback) {
      const fiber = getInstance(inst);
      const eventTime = requestEventTime();
      const lane = requestUpdateLane(fiber);
  
      const update = createUpdate(eventTime, lane);
      update.payload = payload;
      if (callback !== undefined && callback !== null) {
        if (__DEV__) {
          warnOnInvalidCallback(callback, 'setState');
        }
        update.callback = callback;
      }
  
      enqueueUpdate(fiber, update, lane);
      const root = scheduleUpdateOnFiber(fiber, lane, eventTime);
      if (root !== null) {
        entangleTransitions(root, fiber, lane);
      }
  
      if (__DEV__) {
        if (enableDebugTracing) {
          if (fiber.mode & DebugTracingMode) {
            const name = getComponentNameFromFiber(fiber) || 'Unknown';
            logStateUpdateScheduled(name, lane, payload);
          }
        }
      }
  
      if (enableSchedulingProfiler) {
        markStateUpdateScheduled(fiber, lane);
      }
    },
    enqueueReplaceState(inst, payload, callback) {
      const fiber = getInstance(inst);
      const eventTime = requestEventTime();
      const lane = requestUpdateLane(fiber);
  
      const update = createUpdate(eventTime, lane);
      update.tag = ReplaceState;
      update.payload = payload;
  
      if (callback !== undefined && callback !== null) {
        if (__DEV__) {
          warnOnInvalidCallback(callback, 'replaceState');
        }
        update.callback = callback;
      }
  
      enqueueUpdate(fiber, update, lane);
      const root = scheduleUpdateOnFiber(fiber, lane, eventTime);
      if (root !== null) {
        entangleTransitions(root, fiber, lane);
      }
  
      if (__DEV__) {
        if (enableDebugTracing) {
          if (fiber.mode & DebugTracingMode) {
            const name = getComponentNameFromFiber(fiber) || 'Unknown';
            logStateUpdateScheduled(name, lane, payload);
          }
        }
      }
  
      if (enableSchedulingProfiler) {
        markStateUpdateScheduled(fiber, lane);
      }
    },
    enqueueForceUpdate(inst, callback) {
      const fiber = getInstance(inst);
      const eventTime = requestEventTime();
      const lane = requestUpdateLane(fiber);
  
      const update = createUpdate(eventTime, lane);
      update.tag = ForceUpdate;
  
      if (callback !== undefined && callback !== null) {
        if (__DEV__) {
          warnOnInvalidCallback(callback, 'forceUpdate');
        }
        update.callback = callback;
      }
  
      enqueueUpdate(fiber, update, lane);
      const root = scheduleUpdateOnFiber(fiber, lane, eventTime);
      if (root !== null) {
        entangleTransitions(root, fiber, lane);
      }
  
      if (__DEV__) {
        if (enableDebugTracing) {
          if (fiber.mode & DebugTracingMode) {
            const name = getComponentNameFromFiber(fiber) || 'Unknown';
            logForceUpdateScheduled(name, lane);
          }
        }
      }
  
      if (enableSchedulingProfiler) {
        markForceUpdateScheduled(fiber, lane);
      }
    },
  };
  
  function checkShouldComponentUpdate(
    workInProgress,
    ctor,
    oldProps,
    newProps,
    oldState,
    newState,
    nextContext,
  ) {
    const instance = workInProgress.stateNode;
    if (typeof instance.shouldComponentUpdate === 'function') {
      if (__DEV__) {
        if (
          debugRenderPhaseSideEffectsForStrictMode &&
          workInProgress.mode & StrictLegacyMode
        ) {
          disableLogs();
          try {
            // Invoke the function an extra time to help detect side-effects.
            instance.shouldComponentUpdate(newProps, newState, nextContext);
          } finally {
            reenableLogs();
          }
        }
      }
      const shouldUpdate = instance.shouldComponentUpdate(
        newProps,
        newState,
        nextContext,
      );
  
      if (__DEV__) {
        if (shouldUpdate === undefined) {
          console.error(
            '%s.shouldComponentUpdate(): Returned undefined instead of a ' +
              'boolean value. Make sure to return true or false.',
            getComponentNameFromType(ctor) || 'Component',
          );
        }
      }
  
      return shouldUpdate;
    }
  
    if (ctor.prototype && ctor.prototype.isPureReactComponent) {
      return (
        !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)
      );
    }
  
    return true;
  }
  
  function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) {
    const instance = workInProgress.stateNode;
    if (__DEV__) {
      const name = getComponentNameFromType(ctor) || 'Component';
      const renderPresent = instance.render;
  
      if (!renderPresent) {
        if (ctor.prototype && typeof ctor.prototype.render === 'function') {
          console.error(
            '%s(...): No `render` method found on the returned component ' +
              'instance: did you accidentally return an object from the constructor?',
            name,
          );
        } else {
          console.error(
            '%s(...): No `render` method found on the returned component ' +
              'instance: you may have forgotten to define `render`.',
            name,
          );
        }
      }
  
      if (
        instance.getInitialState &&
        !instance.getInitialState.isReactClassApproved &&
        !instance.state
      ) {
        console.error(
          'getInitialState was defined on %s, a plain JavaScript class. ' +
            'This is only supported for classes created using React.createClass. ' +
            'Did you mean to define a state property instead?',
          name,
        );
      }
      if (
        instance.getDefaultProps &&
        !instance.getDefaultProps.isReactClassApproved
      ) {
        console.error(
          'getDefaultProps was defined on %s, a plain JavaScript class. ' +
            'This is only supported for classes created using React.createClass. ' +
            'Use a static property to define defaultProps instead.',
          name,
        );
      }
      if (instance.propTypes) {
        console.error(
          'propTypes was defined as an instance property on %s. Use a static ' +
            'property to define propTypes instead.',
          name,
        );
      }
      if (instance.contextType) {
        console.error(
          'contextType was defined as an instance property on %s. Use a static ' +
            'property to define contextType instead.',
          name,
        );
      }
  
      if (disableLegacyContext) {
        if (ctor.childContextTypes) {
          console.error(
            '%s uses the legacy childContextTypes API which is no longer supported. ' +
              'Use React.createContext() instead.',
            name,
          );
        }
        if (ctor.contextTypes) {
          console.error(
            '%s uses the legacy contextTypes API which is no longer supported. ' +
              'Use React.createContext() with static contextType instead.',
            name,
          );
        }
      } else {
        if (instance.contextTypes) {
          console.error(
            'contextTypes was defined as an instance property on %s. Use a static ' +
              'property to define contextTypes instead.',
            name,
          );
        }
  
        if (
          ctor.contextType &&
          ctor.contextTypes &&
          !didWarnAboutContextTypeAndContextTypes.has(ctor)
        ) {
          didWarnAboutContextTypeAndContextTypes.add(ctor);
          console.error(
            '%s declares both contextTypes and contextType static properties. ' +
              'The legacy contextTypes property will be ignored.',
            name,
          );
        }
      }
  
      if (typeof instance.componentShouldUpdate === 'function') {
        console.error(
          '%s has a method called ' +
            'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
            'The name is phrased as a question because the function is ' +
            'expected to return a value.',
          name,
        );
      }
      if (
        ctor.prototype &&
        ctor.prototype.isPureReactComponent &&
        typeof instance.shouldComponentUpdate !== 'undefined'
      ) {
        console.error(
          '%s has a method called shouldComponentUpdate(). ' +
            'shouldComponentUpdate should not be used when extending React.PureComponent. ' +
            'Please extend React.Component if shouldComponentUpdate is used.',
          getComponentNameFromType(ctor) || 'A pure component',
        );
      }
      if (typeof instance.componentDidUnmount === 'function') {
        console.error(
          '%s has a method called ' +
            'componentDidUnmount(). But there is no such lifecycle method. ' +
            'Did you mean componentWillUnmount()?',
          name,
        );
      }
      if (typeof instance.componentDidReceiveProps === 'function') {
        console.error(
          '%s has a method called ' +
            'componentDidReceiveProps(). But there is no such lifecycle method. ' +
            'If you meant to update the state in response to changing props, ' +
            'use componentWillReceiveProps(). If you meant to fetch data or ' +
            'run side-effects or mutations after React has updated the UI, use componentDidUpdate().',
          name,
        );
      }
      if (typeof instance.componentWillRecieveProps === 'function') {
        console.error(
          '%s has a method called ' +
            'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
          name,
        );
      }
      if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
        console.error(
          '%s has a method called ' +
            'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?',
          name,
        );
      }
      const hasMutatedProps = instance.props !== newProps;
      if (instance.props !== undefined && hasMutatedProps) {
        console.error(
          '%s(...): When calling super() in `%s`, make sure to pass ' +
            "up the same props that your component's constructor was passed.",
          name,
          name,
        );
      }
      if (instance.defaultProps) {
        console.error(
          'Setting defaultProps as an instance property on %s is not supported and will be ignored.' +
            ' Instead, define defaultProps as a static property on %s.',
          name,
          name,
        );
      }
  
      if (
        typeof instance.getSnapshotBeforeUpdate === 'function' &&
        typeof instance.componentDidUpdate !== 'function' &&
        !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)
      ) {
        didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
        console.error(
          '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' +
            'This component defines getSnapshotBeforeUpdate() only.',
          getComponentNameFromType(ctor),
        );
      }
  
      if (typeof instance.getDerivedStateFromProps === 'function') {
        console.error(
          '%s: getDerivedStateFromProps() is defined as an instance method ' +
            'and will be ignored. Instead, declare it as a static method.',
          name,
        );
      }
      if (typeof instance.getDerivedStateFromError === 'function') {
        console.error(
          '%s: getDerivedStateFromError() is defined as an instance method ' +
            'and will be ignored. Instead, declare it as a static method.',
          name,
        );
      }
      if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
        console.error(
          '%s: getSnapshotBeforeUpdate() is defined as a static method ' +
            'and will be ignored. Instead, declare it as an instance method.',
          name,
        );
      }
      const state = instance.state;
      if (state && (typeof state !== 'object' || isArray(state))) {
        console.error('%s.state: must be set to an object or null', name);
      }
      if (
        typeof instance.getChildContext === 'function' &&
        typeof ctor.childContextTypes !== 'object'
      ) {
        console.error(
          '%s.getChildContext(): childContextTypes must be defined in order to ' +
            'use getChildContext().',
          name,
        );
      }
    }
  }
  
  function adoptClassInstance(workInProgress: Fiber, instance: any): void {
    instance.updater = classComponentUpdater;
    workInProgress.stateNode = instance;
    // The instance needs access to the fiber so that it can schedule updates
    setInstance(instance, workInProgress);
    if (__DEV__) {
      instance._reactInternalInstance = fakeInternalInstance;
    }
  }
  
  function constructClassInstance(
    workInProgress: Fiber,
    ctor: any,
    props: any,
  ): any {
    let isLegacyContextConsumer = false;
    let unmaskedContext = emptyContextObject;
    let context = emptyContextObject;
    const contextType = ctor.contextType;
  
    if (__DEV__) {
      if ('contextType' in ctor) {
        const isValid =
          // Allow null for conditional declaration
          contextType === null ||
          (contextType !== undefined &&
            contextType.$$typeof === REACT_CONTEXT_TYPE &&
            contextType._context === undefined); // Not a <Context.Consumer>
  
        if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
          didWarnAboutInvalidateContextType.add(ctor);
  
          let addendum = '';
          if (contextType === undefined) {
            addendum =
              ' However, it is set to undefined. ' +
              'This can be caused by a typo or by mixing up named and default imports. ' +
              'This can also happen due to a circular dependency, so ' +
              'try moving the createContext() call to a separate file.';
          } else if (typeof contextType !== 'object') {
            addendum = ' However, it is set to a ' + typeof contextType + '.';
          } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
            addendum = ' Did you accidentally pass the Context.Provider instead?';
          } else if (contextType._context !== undefined) {
            // <Context.Consumer>
            addendum = ' Did you accidentally pass the Context.Consumer instead?';
          } else {
            addendum =
              ' However, it is set to an object with keys {' +
              Object.keys(contextType).join(', ') +
              '}.';
          }
          console.error(
            '%s defines an invalid contextType. ' +
              'contextType should point to the Context object returned by React.createContext().%s',
            getComponentNameFromType(ctor) || 'Component',
            addendum,
          );
        }
      }
    }
  
    if (typeof contextType === 'object' && contextType !== null) {
      context = readContext((contextType: any));
    } else if (!disableLegacyContext) {
      unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
      const contextTypes = ctor.contextTypes;
      isLegacyContextConsumer =
        contextTypes !== null && contextTypes !== undefined;
      context = isLegacyContextConsumer
        ? getMaskedContext(workInProgress, unmaskedContext)
        : emptyContextObject;
    }
  
    // Instantiate twice to help detect side-effects.
    if (__DEV__) {
      if (
        debugRenderPhaseSideEffectsForStrictMode &&
        workInProgress.mode & StrictLegacyMode
      ) {
        disableLogs();
        try {
          new ctor(props, context); // eslint-disable-line no-new
        } finally {
          reenableLogs();
        }
      }
    }
  
    const instance = new ctor(props, context);
    const state = (workInProgress.memoizedState =
      instance.state !== null && instance.state !== undefined
        ? instance.state
        : null);
    adoptClassInstance(workInProgress, instance);
  
    if (__DEV__) {
      if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
        const componentName = getComponentNameFromType(ctor) || 'Component';
        if (!didWarnAboutUninitializedState.has(componentName)) {
          didWarnAboutUninitializedState.add(componentName);
          console.error(
            '`%s` uses `getDerivedStateFromProps` but its initial state is ' +
              '%s. This is not recommended. Instead, define the initial state by ' +
              'assigning an object to `this.state` in the constructor of `%s`. ' +
              'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
            componentName,
            instance.state === null ? 'null' : 'undefined',
            componentName,
          );
        }
      }
  
      // If new component APIs are defined, "unsafe" lifecycles won't be called.
      // Warn about these lifecycles if they are present.
      // Don't warn about react-lifecycles-compat polyfilled methods though.
      if (
        typeof ctor.getDerivedStateFromProps === 'function' ||
        typeof instance.getSnapshotBeforeUpdate === 'function'
      ) {
        let foundWillMountName = null;
        let foundWillReceivePropsName = null;
        let foundWillUpdateName = null;
        if (
          typeof instance.componentWillMount === 'function' &&
          instance.componentWillMount.__suppressDeprecationWarning !== true
        ) {
          foundWillMountName = 'componentWillMount';
        } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
          foundWillMountName = 'UNSAFE_componentWillMount';
        }
        if (
          typeof instance.componentWillReceiveProps === 'function' &&
          instance.componentWillReceiveProps.__suppressDeprecationWarning !== true
        ) {
          foundWillReceivePropsName = 'componentWillReceiveProps';
        } else if (
          typeof instance.UNSAFE_componentWillReceiveProps === 'function'
        ) {
          foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
        }
        if (
          typeof instance.componentWillUpdate === 'function' &&
          instance.componentWillUpdate.__suppressDeprecationWarning !== true
        ) {
          foundWillUpdateName = 'componentWillUpdate';
        } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
          foundWillUpdateName = 'UNSAFE_componentWillUpdate';
        }
        if (
          foundWillMountName !== null ||
          foundWillReceivePropsName !== null ||
          foundWillUpdateName !== null
        ) {
          const componentName = getComponentNameFromType(ctor) || 'Component';
          const newApiName =
            typeof ctor.getDerivedStateFromProps === 'function'
              ? 'getDerivedStateFromProps()'
              : 'getSnapshotBeforeUpdate()';
          if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(componentName)) {
            didWarnAboutLegacyLifecyclesAndDerivedState.add(componentName);
            console.error(
              'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
                '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' +
                'The above lifecycles should be removed. Learn more about this warning here:\n' +
                'https://reactjs.org/link/unsafe-component-lifecycles',
              componentName,
              newApiName,
              foundWillMountName !== null ? `\n  ${foundWillMountName}` : '',
              foundWillReceivePropsName !== null
                ? `\n  ${foundWillReceivePropsName}`
                : '',
              foundWillUpdateName !== null ? `\n  ${foundWillUpdateName}` : '',
            );
          }
        }
      }
    }
  
    // Cache unmasked context so we can avoid recreating masked context unless necessary.
    // ReactFiberContext usually updates this cache but can't for newly-created instances.
    if (isLegacyContextConsumer) {
      cacheContext(workInProgress, unmaskedContext, context);
    }
  
    return instance;
  }
  
  function callComponentWillMount(workInProgress, instance) {
    const oldState = instance.state;
  
    if (typeof instance.componentWillMount === 'function') {
      instance.componentWillMount();
    }
    if (typeof instance.UNSAFE_componentWillMount === 'function') {
      instance.UNSAFE_componentWillMount();
    }
  
    if (oldState !== instance.state) {
      if (__DEV__) {
        console.error(
          '%s.componentWillMount(): Assigning directly to this.state is ' +
            "deprecated (except inside a component's " +
            'constructor). Use setState instead.',
          getComponentNameFromFiber(workInProgress) || 'Component',
        );
      }
      classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
    }
  }
  
  function callComponentWillReceiveProps(
    workInProgress,
    instance,
    newProps,
    nextContext,
  ) {
    const oldState = instance.state;
    if (typeof instance.componentWillReceiveProps === 'function') {
      instance.componentWillReceiveProps(newProps, nextContext);
    }
    if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
      instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
    }
  
    if (instance.state !== oldState) {
      if (__DEV__) {
        const componentName =
          getComponentNameFromFiber(workInProgress) || 'Component';
        if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
          didWarnAboutStateAssignmentForComponent.add(componentName);
          console.error(
            '%s.componentWillReceiveProps(): Assigning directly to ' +
              "this.state is deprecated (except inside a component's " +
              'constructor). Use setState instead.',
            componentName,
          );
        }
      }
      classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
    }
  }
  
  // Invokes the mount life-cycles on a previously never rendered instance.
  function mountClassInstance(
    workInProgress: Fiber,
    ctor: any,
    newProps: any,
    renderLanes: Lanes,
  ): void {
    if (__DEV__) {
      checkClassInstance(workInProgress, ctor, newProps);
    }
  
    const instance = workInProgress.stateNode;
    instance.props = newProps;
    instance.state = workInProgress.memoizedState;
    instance.refs = emptyRefsObject;
  
    initializeUpdateQueue(workInProgress);
  
    const contextType = ctor.contextType;
    if (typeof contextType === 'object' && contextType !== null) {
      instance.context = readContext(contextType);
    } else if (disableLegacyContext) {
      instance.context = emptyContextObject;
    } else {
      const unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
      instance.context = getMaskedContext(workInProgress, unmaskedContext);
    }
  
    if (__DEV__) {
      if (instance.state === newProps) {
        const componentName = getComponentNameFromType(ctor) || 'Component';
        if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
          didWarnAboutDirectlyAssigningPropsToState.add(componentName);
          console.error(
            '%s: It is not recommended to assign props directly to state ' +
              "because updates to props won't be reflected in state. " +
              'In most cases, it is better to use props directly.',
            componentName,
          );
        }
      }
  
      if (workInProgress.mode & StrictLegacyMode) {
        ReactStrictModeWarnings.recordLegacyContextWarning(
          workInProgress,
          instance,
        );
      }
  
      if (warnAboutDeprecatedLifecycles) {
        ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(
          workInProgress,
          instance,
        );
      }
    }
  
    instance.state = workInProgress.memoizedState;
  
    const getDerivedStateFromProps = ctor.getDerivedStateFromProps;
    if (typeof getDerivedStateFromProps === 'function') {
      applyDerivedStateFromProps(
        workInProgress,
        ctor,
        getDerivedStateFromProps,
        newProps,
      );
      instance.state = workInProgress.memoizedState;
    }
  
    // In order to support react-lifecycles-compat polyfilled components,
    // Unsafe lifecycles should not be invoked for components using the new APIs.
    if (
      typeof ctor.getDerivedStateFromProps !== 'function' &&
      typeof instance.getSnapshotBeforeUpdate !== 'function' &&
      (typeof instance.UNSAFE_componentWillMount === 'function' ||
        typeof instance.componentWillMount === 'function')
    ) {
      callComponentWillMount(workInProgress, instance);
      // If we had additional state updates during this life-cycle, let's
      // process them now.
      processUpdateQueue(workInProgress, newProps, instance, renderLanes);
      instance.state = workInProgress.memoizedState;
    }
  
    if (typeof instance.componentDidMount === 'function') {
      let fiberFlags: Flags = Update;
      if (enableSuspenseLayoutEffectSemantics) {
        fiberFlags |= LayoutStatic;
      }
      if (
        __DEV__ &&
        enableStrictEffects &&
        (workInProgress.mode & StrictEffectsMode) !== NoMode
      ) {
        fiberFlags |= MountLayoutDev;
      }
      workInProgress.flags |= fiberFlags;
    }
  }
  
  function resumeMountClassInstance(
    workInProgress: Fiber,
    ctor: any,
    newProps: any,
    renderLanes: Lanes,
  ): boolean {
    const instance = workInProgress.stateNode;
  
    const oldProps = workInProgress.memoizedProps;
    instance.props = oldProps;
  
    const oldContext = instance.context;
    const contextType = ctor.contextType;
    let nextContext = emptyContextObject;
    if (typeof contextType === 'object' && contextType !== null) {
      nextContext = readContext(contextType);
    } else if (!disableLegacyContext) {
      const nextLegacyUnmaskedContext = getUnmaskedContext(
        workInProgress,
        ctor,
        true,
      );
      nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
    }
  
    const getDerivedStateFromProps = ctor.getDerivedStateFromProps;
    const hasNewLifecycles =
      typeof getDerivedStateFromProps === 'function' ||
      typeof instance.getSnapshotBeforeUpdate === 'function';
  
    // Note: During these life-cycles, instance.props/instance.state are what
    // ever the previously attempted to render - not the "current". However,
    // during componentDidUpdate we pass the "current" props.
  
    // In order to support react-lifecycles-compat polyfilled components,
    // Unsafe lifecycles should not be invoked for components using the new APIs.
    if (
      !hasNewLifecycles &&
      (typeof instance.UNSAFE_componentWillReceiveProps === 'function' ||
        typeof instance.componentWillReceiveProps === 'function')
    ) {
      if (oldProps !== newProps || oldContext !== nextContext) {
        callComponentWillReceiveProps(
          workInProgress,
          instance,
          newProps,
          nextContext,
        );
      }
    }
  
    resetHasForceUpdateBeforeProcessing();
  
    const oldState = workInProgress.memoizedState;
    let newState = (instance.state = oldState);
    processUpdateQueue(workInProgress, newProps, instance, renderLanes);
    newState = workInProgress.memoizedState;
    if (
      oldProps === newProps &&
      oldState === newState &&
      !hasContextChanged() &&
      !checkHasForceUpdateAfterProcessing()
    ) {
      // If an update was already in progress, we should schedule an Update
      // effect even though we're bailing out, so that cWU/cDU are called.
      if (typeof instance.componentDidMount === 'function') {
        let fiberFlags: Flags = Update;
        if (enableSuspenseLayoutEffectSemantics) {
          fiberFlags |= LayoutStatic;
        }
        if (
          __DEV__ &&
          enableStrictEffects &&
          (workInProgress.mode & StrictEffectsMode) !== NoMode
        ) {
          fiberFlags |= MountLayoutDev;
        }
        workInProgress.flags |= fiberFlags;
      }
      return false;
    }
  
    if (typeof getDerivedStateFromProps === 'function') {
      applyDerivedStateFromProps(
        workInProgress,
        ctor,
        getDerivedStateFromProps,
        newProps,
      );
      newState = workInProgress.memoizedState;
    }
  
    const shouldUpdate =
      checkHasForceUpdateAfterProcessing() ||
      checkShouldComponentUpdate(
        workInProgress,
        ctor,
        oldProps,
        newProps,
        oldState,
        newState,
        nextContext,
      );
  
    if (shouldUpdate) {
      // In order to support react-lifecycles-compat polyfilled components,
      // Unsafe lifecycles should not be invoked for components using the new APIs.
      if (
        !hasNewLifecycles &&
        (typeof instance.UNSAFE_componentWillMount === 'function' ||
          typeof instance.componentWillMount === 'function')
      ) {
        if (typeof instance.componentWillMount === 'function') {
          instance.componentWillMount();
        }
        if (typeof instance.UNSAFE_componentWillMount === 'function') {
          instance.UNSAFE_componentWillMount();
        }
      }
      if (typeof instance.componentDidMount === 'function') {
        let fiberFlags: Flags = Update;
        if (enableSuspenseLayoutEffectSemantics) {
          fiberFlags |= LayoutStatic;
        }
        if (
          __DEV__ &&
          enableStrictEffects &&
          (workInProgress.mode & StrictEffectsMode) !== NoMode
        ) {
          fiberFlags |= MountLayoutDev;
        }
        workInProgress.flags |= fiberFlags;
      }
    } else {
      // If an update was already in progress, we should schedule an Update
      // effect even though we're bailing out, so that cWU/cDU are called.
      if (typeof instance.componentDidMount === 'function') {
        let fiberFlags: Flags = Update;
        if (enableSuspenseLayoutEffectSemantics) {
          fiberFlags |= LayoutStatic;
        }
        if (
          __DEV__ &&
          enableStrictEffects &&
          (workInProgress.mode & StrictEffectsMode) !== NoMode
        ) {
          fiberFlags |= MountLayoutDev;
        }
        workInProgress.flags |= fiberFlags;
      }
  
      // If shouldComponentUpdate returned false, we should still update the
      // memoized state to indicate that this work can be reused.
      workInProgress.memoizedProps = newProps;
      workInProgress.memoizedState = newState;
    }
  
    // Update the existing instance's state, props, and context pointers even
    // if shouldComponentUpdate returns false.
    instance.props = newProps;
    instance.state = newState;
    instance.context = nextContext;
  
    return shouldUpdate;
  }
  
  // Invokes the update life-cycles and returns false if it shouldn't rerender.
  function updateClassInstance(
    current: Fiber,
    workInProgress: Fiber,
    ctor: any,
    newProps: any,
    renderLanes: Lanes,
  ): boolean {
    const instance = workInProgress.stateNode;
  
    cloneUpdateQueue(current, workInProgress);
  
    const unresolvedOldProps = workInProgress.memoizedProps;
    const oldProps =
      workInProgress.type === workInProgress.elementType
        ? unresolvedOldProps
        : resolveDefaultProps(workInProgress.type, unresolvedOldProps);
    instance.props = oldProps;
    const unresolvedNewProps = workInProgress.pendingProps;
  
    const oldContext = instance.context;
    const contextType = ctor.contextType;
    let nextContext = emptyContextObject;
    if (typeof contextType === 'object' && contextType !== null) {
      nextContext = readContext(contextType);
    } else if (!disableLegacyContext) {
      const nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
      nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
    }
  
    const getDerivedStateFromProps = ctor.getDerivedStateFromProps;
    const hasNewLifecycles =
      typeof getDerivedStateFromProps === 'function' ||
      typeof instance.getSnapshotBeforeUpdate === 'function';
  
    // Note: During these life-cycles, instance.props/instance.state are what
    // ever the previously attempted to render - not the "current". However,
    // during componentDidUpdate we pass the "current" props.
  
    // In order to support react-lifecycles-compat polyfilled components,
    // Unsafe lifecycles should not be invoked for components using the new APIs.
    if (
      !hasNewLifecycles &&
      (typeof instance.UNSAFE_componentWillReceiveProps === 'function' ||
        typeof instance.componentWillReceiveProps === 'function')
    ) {
      if (
        unresolvedOldProps !== unresolvedNewProps ||
        oldContext !== nextContext
      ) {
        callComponentWillReceiveProps(
          workInProgress,
          instance,
          newProps,
          nextContext,
        );
      }
    }
  
    resetHasForceUpdateBeforeProcessing();
  
    const oldState = workInProgress.memoizedState;
    let newState = (instance.state = oldState);
    processUpdateQueue(workInProgress, newProps, instance, renderLanes);
    newState = workInProgress.memoizedState;
  
    if (
      unresolvedOldProps === unresolvedNewProps &&
      oldState === newState &&
      !hasContextChanged() &&
      !checkHasForceUpdateAfterProcessing() &&
      !(
        enableLazyContextPropagation &&
        current !== null &&
        current.dependencies !== null &&
        checkIfContextChanged(current.dependencies)
      )
    ) {
      // If an update was already in progress, we should schedule an Update
      // effect even though we're bailing out, so that cWU/cDU are called.
      if (typeof instance.componentDidUpdate === 'function') {
        if (
          unresolvedOldProps !== current.memoizedProps ||
          oldState !== current.memoizedState
        ) {
          workInProgress.flags |= Update;
        }
      }
      if (typeof instance.getSnapshotBeforeUpdate === 'function') {
        if (
          unresolvedOldProps !== current.memoizedProps ||
          oldState !== current.memoizedState
        ) {
          workInProgress.flags |= Snapshot;
        }
      }
      return false;
    }
  
    if (typeof getDerivedStateFromProps === 'function') {
      applyDerivedStateFromProps(
        workInProgress,
        ctor,
        getDerivedStateFromProps,
        newProps,
      );
      newState = workInProgress.memoizedState;
    }
  
    const shouldUpdate =
      checkHasForceUpdateAfterProcessing() ||
      checkShouldComponentUpdate(
        workInProgress,
        ctor,
        oldProps,
        newProps,
        oldState,
        newState,
        nextContext,
      ) ||
      // TODO: In some cases, we'll end up checking if context has changed twice,
      // both before and after `shouldComponentUpdate` has been called. Not ideal,
      // but I'm loath to refactor this function. This only happens for memoized
      // components so it's not that common.
      (enableLazyContextPropagation &&
        current !== null &&
        current.dependencies !== null &&
        checkIfContextChanged(current.dependencies));
  
    if (shouldUpdate) {
      // In order to support react-lifecycles-compat polyfilled components,
      // Unsafe lifecycles should not be invoked for components using the new APIs.
      if (
        !hasNewLifecycles &&
        (typeof instance.UNSAFE_componentWillUpdate === 'function' ||
          typeof instance.componentWillUpdate === 'function')
      ) {
        if (typeof instance.componentWillUpdate === 'function') {
          instance.componentWillUpdate(newProps, newState, nextContext);
        }
        if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
          instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
        }
      }
      if (typeof instance.componentDidUpdate === 'function') {
        workInProgress.flags |= Update;
      }
      if (typeof instance.getSnapshotBeforeUpdate === 'function') {
        workInProgress.flags |= Snapshot;
      }
    } else {
      // If an update was already in progress, we should schedule an Update
      // effect even though we're bailing out, so that cWU/cDU are called.
      if (typeof instance.componentDidUpdate === 'function') {
        if (
          unresolvedOldProps !== current.memoizedProps ||
          oldState !== current.memoizedState
        ) {
          workInProgress.flags |= Update;
        }
      }
      if (typeof instance.getSnapshotBeforeUpdate === 'function') {
        if (
          unresolvedOldProps !== current.memoizedProps ||
          oldState !== current.memoizedState
        ) {
          workInProgress.flags |= Snapshot;
        }
      }
  
      // If shouldComponentUpdate returned false, we should still update the
      // memoized props/state to indicate that this work can be reused.
      workInProgress.memoizedProps = newProps;
      workInProgress.memoizedState = newState;
    }
  
    // Update the existing instance's state, props, and context pointers even
    // if shouldComponentUpdate returns false.
    instance.props = newProps;
    instance.state = newState;
    instance.context = nextContext;
  
    return shouldUpdate;
  }
  
  export {
    adoptClassInstance,
    constructClassInstance,
    mountClassInstance,
    resumeMountClassInstance,
    updateClassInstance,
  };
  