e', '.exe');
    msg += `\n(Use \`${argv0} ${flag} ...\` to show where the warning ` +
           'was created)';
    traceWarningHelperShown = true;
  }
  const warningFile = lazyOption();
  if (warningFile) {
    return writeToFile(msg);
  }
  writeOut(msg);
}

// process.emitWarning(error)
// process.emitWarning(str[, type[, code]][, ctor])
// process.emitWarning(str[, options])
function emitWarning(warning, type, code, ctor) {
  let detail;
  if (type !== null && typeof type === 'object' && !ArrayIsArray(type)) {
    ctor = type.ctor;
    code = type.code;
    if (typeof type.detail === 'string')
      detail = type.detail;
    type = type.type || 'Warning';
  } else if (typeof type === 'function') {
    ctor = type;
    code = undefined;
    type = 'Warning';
  }
  if (type !== undefined)
    validateString(type, 'type');
  if (typeof code === 'function') {
    ctor = code;
    code = undefined;
  } else if (code !== undefined) {
    validateString(code, 'code');
  }
  if (typeof warning === 'string') {
    warning = createWarningObject(warning, type, code, ctor, detail);
  } else if (!(warning instanceof Error)) {
    throw new ERR_INVALID_ARG_TYPE('warning', ['Error', 'string'], warning);
  }
  if (warning.name === 'DeprecationWarning') {
    if (process.noDeprecation)
      return;
    if (process.throwDeprecation) {
      // Delay throwing the error to guarantee that all former warnings were
      // properly logged.
      return process.nextTick(() => {
        throw warning;
      });
    }
  }
  process.nextTick(doEmitWarning, warning);
}

function emitWarningSync(warning, type, code, ctor) {
  process.emit('warning', createWarningObject(warning, type, code, ctor));
}

function createWarningObject(warning, type, code, ctor, detail) {
  assert(typeof warning === 'string');
  // Improve error creation performance by skipping the error frames.
  // They are added in the `captureStackTrace()` function below.
  const tmpStackLimit = Error.stackTraceLimit;
  if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0;
  // eslint-disable-next-line no-restricted-syntax
  warning = new Error(warning);
  if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmpStackLimit;
  warning.name = String(type || 'Warning');
  if (code !== undefined) warning.code = code;
  if (detail !== undefined) warning.detail = detail;
  ErrorCaptureStackTrace(warning, ctor || process.emitWarning);
  return warning;
}

module.exports = {
  emitWarning,
  emitWarningSync,
  onWarning,
  resetForSerialization,
};
