private LocateXmlTokenResult doLocateTokenInsideXml()

in scala/scala-impl/src/org/jetbrains/plugins/scala/lang/lexer/ScalaLexer.java [175:331]


  private LocateXmlTokenResult doLocateTokenInsideXml(
      final int start,
      @Nullable final IElementType type,
      @NotNull final CharSequence tokenText
  ) {
    --xmlSteps;

    if (type == ScalaTokenTypesEx.SCALA_XML_CONTENT_START) {
      final XmlTagValidator xmlTagValidator = new XmlTagValidator(myCurrentLexer);
      if (!xmlTagValidator.validate()) {
        xmlSteps = xmlTagValidator.step;
      }

      myCurrentLexer = myXmlLexer;
      myXmlState = 0;
      myCurrentLexer.start(getBufferSequence(), start, myBufferEnd, 0);
      myLayeredTagStack.push(new Stack<>());
      myLayeredTagStack.peek().push(new MyOpenXmlTag());
      myTokenType = myCurrentLexer.getTokenType();
      locateTextRange();
    }
    else if ((/*type == XML_ATTRIBUTE_VALUE_TOKEN || */
        type == ScalaXmlTokenTypes.XML_DATA_CHARACTERS()) && //todo: Dafuq???
        // in xmlLexer injection start `{` is represented by XML_DATA_CHARACTERS
        // (<ul>{ {<li></li>} }</ul>).toString == <ul><li></li></ul>
        // (<ul>{{<li></li>}}</ul>).toString == <ul>{<li></li>}</ul>
        startsWith(tokenText, "{") &&
        !startsWith(tokenText, "{{") &&
        !inCdata
    ) {
      myXmlState = myCurrentLexer.getState();
      myCurrentLexer = myScalaPlainLexer;
      myCurrentLexer.start(getBufferSequence(), start, myBufferEnd, 0);
      locateTextRange();
      myBraceStack.push(1);
      myTokenType = ScalaTokenTypesEx.SCALA_IN_XML_INJECTION_START;
    }
    else if (type == ScalaTokenTypes.tRBRACE) {
      int currentLayer = myBraceStack.popInt();
      if (currentLayer == 1) {
        locateTextRange();
        myCurrentLexer = myXmlLexer;
        myXmlLexer.start(getBufferSequence(), start + 1, myBufferEnd, myXmlState);
        myTokenType = ScalaTokenTypesEx.SCALA_IN_XML_INJECTION_END;
      } else {
        myBraceStack.push(--currentLayer);
      }
    }
    else if (type == ScalaTokenTypes.tLBRACE) {
      int currentLayer = myBraceStack.popInt();
      myBraceStack.push(++currentLayer);
    }
    else if ((ScalaXmlTokenTypes.XML_START_TAG_START() == type ||
        ScalaXmlTokenTypes.XML_COMMENT_START() == type ||
        ScalaXmlTokenTypes.XML_CDATA_START() == type ||
        ScalaXmlTokenTypes.XML_PI_START() == type) &&
        !myLayeredTagStack.isEmpty()
    ) {
      if (type == ScalaXmlTokenTypes.XML_CDATA_START()) {
        inCdata = true;
      }
      myLayeredTagStack.peek().push(new MyOpenXmlTag());
    }
    else if (ScalaXmlTokenTypes.XML_EMPTY_ELEMENT_END() == type &&
        !myLayeredTagStack.isEmpty() &&
        !myLayeredTagStack.peek().isEmpty() &&
        myLayeredTagStack.peek().peek().state == TAG_STATE.UNDEFINED) {

      myLayeredTagStack.peek().pop();
      if (myLayeredTagStack.peek().isEmpty() && checkNotNextXmlBegin(myCurrentLexer)) {
        myLayeredTagStack.pop();
        locateTextRange();
        myTokenType = ScalaXmlTokenTypes.XML_EMPTY_ELEMENT_END();
        startScalaPlainLexer(start + 2);
        return LocateXmlTokenResult.STARTED_SCALA_PLAIN_LEXER;
      }
    }
    else if (ScalaXmlTokenTypes.XML_TAG_END() == type &&
        !myLayeredTagStack.isEmpty() &&
        !myLayeredTagStack.peek().isEmpty()
    ) {
      MyOpenXmlTag tag = myLayeredTagStack.peek().peek();
      if (tag.state == TAG_STATE.UNDEFINED) {
        tag.state = TAG_STATE.NONEMPTY;
      }
      else if (tag.state == TAG_STATE.NONEMPTY) {
        myLayeredTagStack.peek().pop();
      }
      if (myLayeredTagStack.peek().isEmpty() && checkNotNextXmlBegin(myCurrentLexer)) {
        myLayeredTagStack.pop();
        locateTextRange();
        myTokenType = ScalaXmlTokenTypes.XML_TAG_END();
        startScalaPlainLexer(start + 1);
        return LocateXmlTokenResult.STARTED_SCALA_PLAIN_LEXER;
      }
    }
    else if (ScalaXmlTokenTypes.XML_PI_END() == type &&
        !myLayeredTagStack.isEmpty() &&
        !myLayeredTagStack.peek().isEmpty() &&
        myLayeredTagStack.peek().peek().state == TAG_STATE.UNDEFINED
    ) {

      myLayeredTagStack.peek().pop();
      if (myLayeredTagStack.peek().isEmpty() && checkNotNextXmlBegin(myCurrentLexer)) {
        myLayeredTagStack.pop();
        locateTextRange();
        myTokenType = ScalaXmlTokenTypes.XML_PI_END();
        startScalaPlainLexer(start + 2);
        return LocateXmlTokenResult.STARTED_SCALA_PLAIN_LEXER;
      }
    }
    else if (ScalaXmlTokenTypes.XML_COMMENT_END() == type &&
        !myLayeredTagStack.isEmpty() &&
        !myLayeredTagStack.peek().isEmpty() &&
        myLayeredTagStack.peek().peek().state == TAG_STATE.UNDEFINED
    ) {

      myLayeredTagStack.peek().pop();
      if (myLayeredTagStack.peek().isEmpty() && checkNotNextXmlBegin(myCurrentLexer)) {
        myLayeredTagStack.pop();
        locateTextRange();
        myTokenType = ScalaXmlTokenTypes.XML_COMMENT_END();
        startScalaPlainLexer(start + 3);
        return LocateXmlTokenResult.STARTED_SCALA_PLAIN_LEXER;
      }
    }
    else if (ScalaXmlTokenTypes.XML_CDATA_END() == type &&
        !myLayeredTagStack.isEmpty() &&
        !myLayeredTagStack.peek().isEmpty() &&
        myLayeredTagStack.peek().peek().state == TAG_STATE.UNDEFINED
    ) {
      inCdata = false;
      myLayeredTagStack.peek().pop();
      if (myLayeredTagStack.peek().isEmpty() && checkNotNextXmlBegin(myCurrentLexer)) {
        myLayeredTagStack.pop();
        locateTextRange();
        myTokenType = ScalaXmlTokenTypes.XML_CDATA_END();
        startScalaPlainLexer(start + 3);
        return LocateXmlTokenResult.STARTED_SCALA_PLAIN_LEXER;
      }
    }
    else if (type == ScalaXmlTokenTypes.XML_DATA_CHARACTERS() &&
        CharArrayUtil.indexOf(tokenText, "{", 0) != -1 && !inCdata
    ) {
      int scalaToken = CharArrayUtil.indexOf(tokenText, "{", 0);
      while (scalaToken != -1 && scalaToken + 1 < tokenText.length() && tokenText.charAt(scalaToken + 1) == '{')
        scalaToken = CharArrayUtil.indexOf(tokenText, "{", scalaToken + 2);
      if (scalaToken != -1) {
        myTokenType = ScalaXmlTokenTypes.XML_DATA_CHARACTERS();
        myTokenStart = myCurrentLexer.getTokenStart();
        myTokenEnd = myTokenStart + scalaToken;
        myCurrentLexer.start(getBufferSequence(), myTokenEnd, myBufferEnd, myCurrentLexer.getState());
      }
    }

    return LocateXmlTokenResult.ADVANCE;
  }