/*
   * declaration
   *   : function
   *   : property
   *   : extension
   *   : class
   *   : typeAlias
   *   : object
   *   ;
   */
  private IElementType parseLocalDeclarationRest(boolean isEnum) {
    IElementType keywordToken = tt();
    IElementType declType = null;
    if (keywordToken == CLASS_KEYWORD || keywordToken == TRAIT_KEYWORD) {
      declType = myJetParsing.parseClass(isEnum);
    } else if (keywordToken == FUN_KEYWORD) {
      declType = myJetParsing.parseFunction();
    } else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
      declType = myJetParsing.parseProperty(true);
    } else if (keywordToken == TYPE_ALIAS_KEYWORD) {
      declType = myJetParsing.parseTypeAlias();
    } else if (keywordToken == OBJECT_KEYWORD) {
      // Object expression may appear at the statement position: should parse it
      // as expression instead of object declaration
      // sample:
      // {
      //   object : Thread() {
      //   }
      // }
      IElementType lookahead = lookahead(1);
      if (lookahead == COLON || lookahead == LBRACE) {
        return null;
      }

      myJetParsing.parseObject(NameParsingMode.REQUIRED, true);
      declType = OBJECT_DECLARATION;
    }
    return declType;
  }
  /*
   * when
   *   : "when" ("(" (modifiers "val" SimpleName "=")? element ")")? "{"
   *         whenEntry*
   *     "}"
   *   ;
   */
  private void parseWhen() {
    assert _at(WHEN_KEYWORD);

    PsiBuilder.Marker when = mark();

    advance(); // WHEN_KEYWORD

    // Parse condition
    myBuilder.disableNewlines();
    if (at(LPAR)) {
      advanceAt(LPAR);

      int valPos =
          matchTokenStreamPredicate(
              new FirstBefore(new At(VAL_KEYWORD), new AtSet(RPAR, LBRACE, RBRACE, SEMICOLON, EQ)));
      if (valPos >= 0) {
        PsiBuilder.Marker property = mark();
        myJetParsing.parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ALLOW_SHORTS);
        myJetParsing.parseProperty(true);
        property.done(PROPERTY);
      } else {
        parseExpression();
      }

      expect(RPAR, "Expecting ')'");
    }
    myBuilder.restoreNewlinesState();

    // Parse when block
    myBuilder.enableNewlines();
    if (expect(LBRACE, "Expecting '{'")) {
      while (!eof() && !at(RBRACE)) {
        parseWhenEntry();
      }

      expect(RBRACE, "Expecting '}'");
    }
    myBuilder.restoreNewlinesState();

    when.done(WHEN);
  }