private PsiBuilder.@NotNull Marker parseTypeOrRecordPattern(final PsiBuilder builder, boolean expectVar) {
    PsiBuilder.Marker pattern = builder.mark();
    PsiBuilder.Marker patternVariable = builder.mark();
    Boolean hasNoModifiers = myParser.getDeclarationParser().parseModifierList(builder, PATTERN_MODIFIERS).second;

    int flags = BasicReferenceParser.EAT_LAST_DOT | BasicReferenceParser.WILDCARD;
    if (expectVar) {
      flags |= BasicReferenceParser.VAR_TYPE;
    }
    PsiBuilder.Marker type = myParser.getReferenceParser().parseType(builder, flags);
    assert type != null; // guarded by isPattern
    boolean isRecord = false;
    if (builder.getTokenType() == JavaTokenType.LPARENTH && hasNoModifiers) {
      parseRecordStructurePattern(builder);
      isRecord = true;
    }

    final boolean hasIdentifier;
    if (builder.getTokenType() == JavaTokenType.IDENTIFIER &&
        (!PsiKeyword.WHEN.equals(builder.getTokenText()) || isWhenAsIdentifier(isRecord))) {
      // pattern variable after the record structure pattern
      if (isRecord) {
        PsiBuilder.Marker variable = builder.mark();
        builder.advanceLexer();
        variable.done(myJavaElementTypeContainer.DECONSTRUCTION_PATTERN_VARIABLE);
      }
      else {
        builder.advanceLexer();
      }
      hasIdentifier = true;
    }
    else {
      hasIdentifier = false;
    }

    if (isRecord) {
      patternVariable.drop();
      done(pattern, myJavaElementTypeContainer.DECONSTRUCTION_PATTERN, myWhiteSpaceAndCommentSetHolder);
    }
    else {
      if (hasIdentifier) {
        done(patternVariable, myJavaElementTypeContainer.PATTERN_VARIABLE, myWhiteSpaceAndCommentSetHolder);
      }
      else {
        patternVariable.drop();
      }
      done(pattern, myJavaElementTypeContainer.TYPE_TEST_PATTERN, myWhiteSpaceAndCommentSetHolder);
    }
    return pattern;
  }
private PsiBuilder.@NotNull Marker parseTypeOrRecordPattern(final PsiBuilder builder, boolean expectVar)