async parseManifest_(data, finalManifestUri, rootElement) {
    let manifestData = data;
    const manifestPreprocessor = this.config_.dash.manifestPreprocessor;
    const defaultManifestPreprocessor =
        shaka.util.PlayerConfiguration.defaultManifestPreprocessor;
    if (manifestPreprocessor != defaultManifestPreprocessor) {
      shaka.Deprecate.deprecateFeature(5,
          'manifest.dash.manifestPreprocessor configuration',
          'Please Use manifest.dash.manifestPreprocessorTXml instead.');
      const mpdElement =
          shaka.util.XmlUtils.parseXml(manifestData, rootElement);
      if (!mpdElement) {
        throw new shaka.util.Error(
            shaka.util.Error.Severity.CRITICAL,
            shaka.util.Error.Category.MANIFEST,
            shaka.util.Error.Code.DASH_INVALID_XML,
            finalManifestUri);
      }
      manifestPreprocessor(mpdElement);
      manifestData = shaka.util.XmlUtils.toArrayBuffer(mpdElement);
    }
    const mpd = shaka.util.TXml.parseXml(manifestData, rootElement);
    if (!mpd) {
      throw new shaka.util.Error(
          shaka.util.Error.Severity.CRITICAL,
          shaka.util.Error.Category.MANIFEST,
          shaka.util.Error.Code.DASH_INVALID_XML,
          finalManifestUri);
    }
    const manifestPreprocessorTXml =
        this.config_.dash.manifestPreprocessorTXml;
    const defaultManifestPreprocessorTXml =
        shaka.util.PlayerConfiguration.defaultManifestPreprocessorTXml;
    if (manifestPreprocessorTXml != defaultManifestPreprocessorTXml) {
      manifestPreprocessorTXml(mpd);
    }

    if (rootElement === 'Patch') {
      return this.processPatchManifest_(mpd);
    }

    const disableXlinkProcessing = this.config_.dash.disableXlinkProcessing;
    if (disableXlinkProcessing) {
      return this.processManifest_(mpd, finalManifestUri);
    }

    // Process the mpd to account for xlink connections.
    const failGracefully = this.config_.dash.xlinkFailGracefully;
    const xlinkOperation = shaka.dash.MpdUtils.processXlinks(
        mpd, this.config_.retryParameters, failGracefully, finalManifestUri,
        this.playerInterface_.networkingEngine);
    this.operationManager_.manage(xlinkOperation);
    const finalMpd = await xlinkOperation.promise;
    return this.processManifest_(finalMpd, finalManifestUri);
  }
Parses the manifest XML.  This also handles updates and will update the
stored manifest.

@param {BufferSource} data
@param {string} finalManifestUri The final manifest URI, which may
  differ from this.manifestUri_ if there has been a redirect.
@param {string} rootElement MPD or Patch, depending on context
@return {!Promise}
@private