// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import '../../scanner/token.dart' show Token;
import '../messages.dart' as fasta;
import 'formal_parameter_kind.dart' show FormalParameterKind;
import 'member_kind.dart' show MemberKind;
import 'parser.dart' show Parser;
import 'type_continuation.dart' show TypeContinuation;
import 'util.dart' show optional;

bool isModifier(Token token) {
  if (!token.isModifier) {
    return false;
  }
  if (token.type.isBuiltIn) {
    // A built-in identifier can only be a modifier as long as it is
    // followed by another modifier or an identifier. Otherwise, it is the
    // identifier.
    //
    // For example, `external` is a modifier in this declaration:
    //   external Foo foo();
    // but is the identifier in this declaration
    //   external() => true;
    if (!token.next.type.isKeyword && !token.next.isIdentifier) {
      return false;
    }
  }
  return true;
}

TypeContinuation typeContinuationAfterVar(TypeContinuation typeContinuation) {
  switch (typeContinuation) {
    case TypeContinuation.NormalFormalParameter:
      return TypeContinuation.NormalFormalParameterAfterVar;

    case TypeContinuation.OptionalPositionalFormalParameter:
      return TypeContinuation.OptionalPositionalFormalParameterAfterVar;

    case TypeContinuation.NamedFormalParameter:
      return TypeContinuation.NamedFormalParameterAfterVar;

    default:
      return TypeContinuation.OptionalAfterVar;
  }
}

TypeContinuation typeContinuationFromMemberKind(
        bool isVarAllowed, MemberKind memberKind) =>
    (isVarAllowed || memberKind == MemberKind.GeneralizedFunctionType)
        ? TypeContinuation.Required
        : TypeContinuation.Optional;

/// This class is used to parse modifiers in most locations where modifiers
/// can occur. However, it isn't used when parsing a class or when parsing
/// the modifiers of a member function (non-local),
/// but is used when parsing their formal parameters.
class ModifierContext {
  final Parser parser;
  MemberKind memberKind;

  /// When parsing the formal parameters of any function,
  /// [parameterKind] is non-null.
  final FormalParameterKind parameterKind;

  final bool isVarAllowed;
  TypeContinuation typeContinuation;
  int modifierCount = 0;
  Token varFinalOrConst;

  ModifierContext(this.parser, this.memberKind, this.parameterKind,
      this.isVarAllowed, this.typeContinuation);

  bool get isCovariantFinalAllowed =>
      memberKind != MemberKind.StaticField &&
      memberKind != MemberKind.NonStaticField;

  Token parseConst(Token token) {
    Token next = token.next;
    assert(optional('const', next));
    if (!isVarAllowed) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateExtraneousModifier);
      // TODO(danrubel): investigate why token must be included (fall through)
      // so that tests will pass. I think that it should not be included
      // because the 'const' is invalid in this situation.
      //
      // return token.next;
    }
    typeContinuation ??= TypeContinuation.Optional;
    varFinalOrConst ??= next;
    modifierCount++;
    return parser.parseModifier(token);
  }

  Token parseCovariantOpt(Token token) {
    Token next = token.next;
    assert(optional('covariant', next));
    // A built-in identifier can only be a modifier as long as it is
    // followed by another modifier or an identifier.
    // Otherwise, it is the identifier.
    if (!next.next.isKeywordOrIdentifier) {
      return token;
    }
    switch (memberKind) {
      case MemberKind.Local:
      case MemberKind.StaticField:
      case MemberKind.StaticMethod:
      case MemberKind.TopLevelField:
      case MemberKind.TopLevelMethod:
        parser.reportRecoverableErrorWithToken(
            next, fasta.templateExtraneousModifier);
        return next;

      default:
        modifierCount++;
        return parser.parseModifier(token);
    }
  }

  Token parseExternalOpt(Token token) {
    Token next = token.next;
    assert(optional('external', next));
    // A built-in identifier can only be a modifier as long as it is
    // followed by another modifier or an identifier.
    // Otherwise, it is the identifier.
    if (!next.next.isKeywordOrIdentifier) {
      return token;
    }
    switch (memberKind) {
      case MemberKind.Factory:
      case MemberKind.NonStaticMethod:
      case MemberKind.StaticMethod:
      case MemberKind.TopLevelMethod:
        modifierCount++;
        return parser.parseModifier(token);

      case MemberKind.StaticField:
      case MemberKind.NonStaticField:
        parser.reportRecoverableError(next, fasta.messageExternalField);
        return next;

      default:
        parser.reportRecoverableErrorWithToken(
            next, fasta.templateExtraneousModifier);
        return next;
    }
  }

  Token parseFinal(Token token) {
    Token next = token.next;
    assert(optional('final', next));
    if (!isVarAllowed && parameterKind == null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateExtraneousModifier);
      return next;
    }
    typeContinuation ??= TypeContinuation.Optional;
    varFinalOrConst ??= next;
    modifierCount++;
    return parser.parseModifier(token);
  }

  Token parseStaticOpt(Token token) {
    Token next = token.next;
    assert(optional('static', next));
    // A built-in identifier can only be a modifier as long as it is
    // followed by another modifier or an identifier.
    // Otherwise, it is the identifier.
    if (!next.next.isKeywordOrIdentifier) {
      return token;
    }
    if (parameterKind != null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateExtraneousModifier);
      return next;
    }
    switch (memberKind) {
      case MemberKind.NonStaticMethod:
        memberKind = MemberKind.StaticMethod;
        modifierCount++;
        return parser.parseModifier(token);
      case MemberKind.NonStaticField:
        memberKind = MemberKind.StaticField;
        modifierCount++;
        return parser.parseModifier(token);
      default:
        parser.reportRecoverableErrorWithToken(
            next, fasta.templateExtraneousModifier);
        return next;
    }
  }

  Token parseVar(Token token) {
    Token next = token.next;
    assert(optional('var', next));
    if (!isVarAllowed && parameterKind == null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateExtraneousModifier);
      return next;
    }
    typeContinuation = typeContinuationAfterVar(typeContinuation);
    varFinalOrConst ??= next;
    modifierCount++;
    return parser.parseModifier(token);
  }
}

/// This class parses modifiers in recovery situations,
/// but does not call handleModifier or handleModifiers.
class ModifierRecoveryContext2 {
  final Parser parser;
  TypeContinuation typeContinuation;
  int modifierCount = 0;
  Token abstractToken;
  Token constToken;
  Token covariantToken;
  Token externalToken;
  Token finalToken;
  Token staticToken;
  Token varFinalOrConst;
  Token varToken;

  // Set `true` when parsing modifiers after the `factory` token.
  bool afterFactory = false;

  // TODO(danrubel): Replace [ModifierRecoveryContext] and [ModifierContext]
  // with this class.

  ModifierRecoveryContext2(this.parser);

  /// Parse modifiers for class methods and fields.
  Token parseClassMemberModifiers(
      Token token, TypeContinuation typeContinuation,
      {Token externalToken,
      Token staticToken,
      Token covariantToken,
      Token varFinalOrConst}) {
    token = parseModifiers(token, typeContinuation,
        externalToken: externalToken,
        staticToken: staticToken,
        covariantToken: covariantToken,
        varFinalOrConst: varFinalOrConst);

    if (abstractToken != null) {
      parser.reportRecoverableError(
          abstractToken, fasta.messageAbstractClassMember);
    }
    return token;
  }

  /// Parse modifiers after the `factory` token.
  Token parseModifiersAfterFactory(Token token,
      {Token externalToken, Token staticOrCovariant, Token varFinalOrConst}) {
    afterFactory = true;
    token = parseModifiers(token, null,
        externalToken: externalToken,
        staticOrCovariant: staticOrCovariant,
        varFinalOrConst: varFinalOrConst);

    if (abstractToken != null) {
      parser.reportRecoverableError(
          abstractToken, fasta.messageAbstractClassMember);
    }
    return token;
  }

  /// Parse modifiers for top level functions and fields.
  Token parseTopLevelModifiers(Token token, TypeContinuation typeContinuation,
      {Token externalToken, Token varFinalOrConst}) {
    token = parseModifiers(token, typeContinuation,
        externalToken: externalToken, varFinalOrConst: varFinalOrConst);

    if (abstractToken != null) {
      parser.reportRecoverableErrorWithToken(
          abstractToken, fasta.templateExtraneousModifier);
    }
    if (staticToken != null) {
      parser.reportRecoverableErrorWithToken(
          staticToken, fasta.templateExtraneousModifier);
      staticToken = null;
      --modifierCount;
    }
    if (covariantToken != null) {
      parser.reportRecoverableErrorWithToken(
          covariantToken, fasta.templateExtraneousModifier);
      covariantToken = null;
      --modifierCount;
    }
    return token;
  }

  /// Parse modifiers during recovery when modifiers are out of order
  /// or invalid. Typically clients call methods like
  /// [parseClassMemberModifiers] which in turn calls this method,
  /// rather than calling this method directly.
  ///
  /// The various modifier token parameters represent tokens of modifiers
  /// that have already been parsed prior to recovery. The [staticOrCovariant]
  /// parameter is for convenience if caller has a token that may be either
  /// `static` or `covariant`. The first non-null parameter of
  /// [staticOrCovariant], [staticToken], or [covariantToken] will be used,
  /// in that order, and the others ignored.
  Token parseModifiers(Token token, TypeContinuation typeContinuation,
      {Token externalToken,
      Token staticToken,
      Token staticOrCovariant,
      Token covariantToken,
      Token varFinalOrConst}) {
    this.typeContinuation = typeContinuation;
    if (externalToken != null) {
      this.externalToken = externalToken;
      ++modifierCount;
    }
    if (staticOrCovariant != null) {
      if (optional('static', staticOrCovariant)) {
        this.staticToken = staticOrCovariant;
        ++modifierCount;
      } else if (optional('covariant', staticOrCovariant)) {
        this.covariantToken = staticOrCovariant;
        ++modifierCount;
      } else {
        throw "Internal error: "
            "Unexpected staticOrCovariant '$staticOrCovariant'.";
      }
    } else if (staticToken != null) {
      this.staticToken = staticToken;
      ++modifierCount;
    } else if (covariantToken != null) {
      this.covariantToken = covariantToken;
      ++modifierCount;
    }
    if (varFinalOrConst != null) {
      this.varFinalOrConst = varFinalOrConst;
      ++modifierCount;
      if (optional('var', varFinalOrConst)) {
        varToken = varFinalOrConst;
      } else if (optional('final', varFinalOrConst)) {
        finalToken = varFinalOrConst;
      } else if (optional('const', varFinalOrConst)) {
        constToken = varFinalOrConst;
      } else {
        throw "Internal error: Unexpected varFinalOrConst '$varFinalOrConst'.";
      }
    }

    // Process invalid and out-of-order modifiers
    Token next = token.next;
    while (true) {
      final value = next.stringValue;
      if (isModifier(next)) {
        if (identical('abstract', value)) {
          token = parseAbstract(token);
        } else if (identical('const', value)) {
          token = parseConst(token);
        } else if (identical('covariant', value)) {
          token = parseCovariant(token);
        } else if (identical('external', value)) {
          token = parseExternal(token);
        } else if (identical('final', value)) {
          token = parseFinal(token);
        } else if (identical('static', value)) {
          token = parseStatic(token);
        } else if (identical('var', value)) {
          token = parseVar(token);
        } else {
          throw 'Internal Error: Unhandled modifier: $value';
        }
      } else if (afterFactory && identical('factory', value)) {
        parser.reportRecoverableErrorWithToken(
            next, fasta.templateDuplicatedModifier);
        token = next;
      } else {
        break;
      }
      next = token.next;
    }

    return token;
  }

  Token parseAbstract(Token token) {
    Token next = token.next;
    assert(optional('abstract', next));
    if (abstractToken == null) {
      abstractToken = next;
      ++modifierCount;
      return next;
    }

    // Recovery
    parser.reportRecoverableErrorWithToken(
        next, fasta.templateDuplicatedModifier);
    return next;
  }

  Token parseConst(Token token) {
    Token next = token.next;
    assert(optional('const', next));
    if (varFinalOrConst == null && covariantToken == null) {
      typeContinuation ??= TypeContinuation.Optional;
      varFinalOrConst = constToken = next;
      ++modifierCount;

      if (afterFactory) {
        parser.reportRecoverableError(next, fasta.messageConstAfterFactory);
      }
      return next;
    }

    // Recovery
    if (constToken != null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateDuplicatedModifier);
    } else if (covariantToken != null) {
      parser.reportRecoverableError(next, fasta.messageConstAndCovariant);
    } else if (finalToken != null) {
      parser.reportRecoverableError(next, fasta.messageConstAndFinal);
    } else if (varToken != null) {
      parser.reportRecoverableError(next, fasta.messageConstAndVar);
    } else {
      throw 'Internal Error: Unexpected varFinalOrConst: $varFinalOrConst';
    }
    return next;
  }

  Token parseCovariant(Token token) {
    Token next = token.next;
    assert(optional('covariant', next));
    if (constToken == null &&
        covariantToken == null &&
        staticToken == null &&
        !afterFactory) {
      covariantToken = next;
      ++modifierCount;

      if (varToken != null) {
        parser.reportRecoverableError(next, fasta.messageCovariantAfterVar);
      } else if (finalToken != null) {
        parser.reportRecoverableError(next, fasta.messageCovariantAfterFinal);
      }
      return next;
    }

    // Recovery
    if (covariantToken != null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateDuplicatedModifier);
    } else if (afterFactory) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateExtraneousModifier);
    } else if (constToken != null) {
      parser.reportRecoverableError(next, fasta.messageConstAndCovariant);
    } else if (staticToken != null) {
      parser.reportRecoverableError(next, fasta.messageCovariantAndStatic);
    } else {
      throw 'Internal Error: Unhandled recovery: $next';
    }
    return next;
  }

  Token parseExternal(Token token) {
    Token next = token.next;
    assert(optional('external', next));
    if (externalToken == null) {
      externalToken = next;
      ++modifierCount;

      if (afterFactory) {
        parser.reportRecoverableError(next, fasta.messageExternalAfterFactory);
      } else if (constToken != null) {
        parser.reportRecoverableError(next, fasta.messageExternalAfterConst);
      } else if (staticToken != null) {
        parser.reportRecoverableError(next, fasta.messageExternalAfterStatic);
      }
      return next;
    }

    // Recovery
    parser.reportRecoverableErrorWithToken(
        next, fasta.templateDuplicatedModifier);
    return next;
  }

  Token parseFinal(Token token) {
    Token next = token.next;
    assert(optional('final', next));
    if (varFinalOrConst == null && !afterFactory) {
      typeContinuation ??= TypeContinuation.Optional;
      varFinalOrConst = finalToken = next;
      ++modifierCount;
      return next;
    }

    // Recovery
    if (finalToken != null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateDuplicatedModifier);
    } else if (afterFactory) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateExtraneousModifier);
    } else if (constToken != null) {
      parser.reportRecoverableError(next, fasta.messageConstAndFinal);
    } else if (varToken != null) {
      parser.reportRecoverableError(next, fasta.messageFinalAndVar);
    } else {
      throw 'Internal Error: Unexpected varFinalOrConst: $varFinalOrConst';
    }
    return next;
  }

  Token parseStatic(Token token) {
    Token next = token.next;
    assert(optional('static', next));
    if (covariantToken == null && staticToken == null && !afterFactory) {
      staticToken = next;
      ++modifierCount;

      if (constToken != null) {
        parser.reportRecoverableError(next, fasta.messageStaticAfterConst);
      } else if (finalToken != null) {
        parser.reportRecoverableError(next, fasta.messageStaticAfterFinal);
      } else if (varToken != null) {
        parser.reportRecoverableError(next, fasta.messageStaticAfterVar);
      }
      return next;
    }

    // Recovery
    if (covariantToken != null) {
      parser.reportRecoverableError(next, fasta.messageCovariantAndStatic);
    } else if (staticToken != null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateDuplicatedModifier);
    } else if (afterFactory) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateExtraneousModifier);
    } else {
      throw 'Internal Error: Unhandled recovery: $next';
    }
    return next;
  }

  Token parseVar(Token token) {
    Token next = token.next;
    assert(optional('var', next));
    if (varFinalOrConst == null && !afterFactory) {
      typeContinuation = typeContinuationAfterVar(typeContinuation);
      varFinalOrConst = varToken = next;
      ++modifierCount;
      return next;
    }

    // Recovery
    if (varToken != null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateDuplicatedModifier);
    } else if (afterFactory) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateExtraneousModifier);
    } else if (constToken != null) {
      parser.reportRecoverableError(next, fasta.messageConstAndVar);
    } else if (finalToken != null) {
      parser.reportRecoverableError(next, fasta.messageFinalAndVar);
    } else {
      throw 'Internal Error: Unexpected varFinalOrConst: $varFinalOrConst';
    }
    return next;
  }
}

class ModifierRecoveryContext extends ModifierContext {
  Token constToken;
  Token covariantToken;
  Token externalToken;
  Token finalToken;
  Token staticToken;
  Token varToken;

  ModifierRecoveryContext(
      Parser parser,
      MemberKind memberKind,
      FormalParameterKind parameterKind,
      bool isVarAllowed,
      TypeContinuation typeContinuation)
      : super(
            parser, memberKind, parameterKind, isVarAllowed, typeContinuation);

  Token parseRecovery(Token token,
      {Token covariantToken, Token staticToken, Token varFinalOrConst}) {
    if (covariantToken != null) {
      this.covariantToken = covariantToken;
      ++modifierCount;
    }
    if (staticToken != null) {
      this.staticToken = staticToken;
      ++modifierCount;
    }
    if (varFinalOrConst != null) {
      this.varFinalOrConst = varFinalOrConst;
      ++modifierCount;
      if (optional('var', varFinalOrConst)) {
        varToken = varFinalOrConst;
      } else if (optional('final', varFinalOrConst)) {
        finalToken = varFinalOrConst;
      } else if (optional('const', varFinalOrConst)) {
        constToken = varFinalOrConst;
      } else {
        throw "Internal error: Unexpected varFinalOrConst '$varFinalOrConst'.";
      }
    }

    // Process invalid and out-of-order modifiers
    Token next = token.next;
    while (isModifier(next)) {
      final value = next.stringValue;
      if (identical('abstract', value)) {
        token = parseAbstract(token);
      } else if (identical('const', value)) {
        token = parseConst(token);
      } else if (identical('covariant', value)) {
        token = parseCovariantOpt(token);
      } else if (identical('external', value)) {
        token = parseExternalOpt(token);
      } else if (identical('final', value)) {
        token = parseFinal(token);
      } else if (identical('static', value)) {
        token = parseStaticOpt(token);
      } else if (identical('var', value)) {
        token = parseVar(token);
      } else {
        token = parseExtraneousModifier(token);
      }
      next = token.next;
    }

    return token;
  }

  Token parseAbstract(Token token) {
    assert(optional('abstract', token.next));
    if (memberKind == MemberKind.NonStaticField ||
        memberKind == MemberKind.NonStaticMethod ||
        memberKind == MemberKind.StaticField ||
        memberKind == MemberKind.StaticMethod) {
      parser.reportRecoverableError(
          token.next, fasta.messageAbstractClassMember);
      return token.next;
    }
    return parseExtraneousModifier(token);
  }

  @override
  Token parseConst(Token token) {
    Token next = token.next;
    if (constToken != null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateDuplicatedModifier);
      return next;
    }
    constToken = next;
    if (covariantToken != null) {
      parser.reportRecoverableError(constToken, fasta.messageConstAndCovariant);
      return constToken;
    }
    if (finalToken != null) {
      parser.reportRecoverableError(constToken, fasta.messageConstAndFinal);
      return constToken;
    }
    if (varToken != null) {
      parser.reportRecoverableError(constToken, fasta.messageConstAndVar);
      return constToken;
    }
    return super.parseConst(token);
  }

  @override
  Token parseCovariantOpt(Token token) {
    Token next = token.next;
    if (covariantToken != null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateDuplicatedModifier);
      return next;
    }
    covariantToken = next;
    if (constToken != null) {
      parser.reportRecoverableError(
          covariantToken, fasta.messageConstAndCovariant);
      return covariantToken;
    }
    if (staticToken != null) {
      parser.reportRecoverableError(
          covariantToken, fasta.messageCovariantAndStatic);
      return covariantToken;
    }
    if (varToken != null) {
      parser.reportRecoverableError(
          covariantToken, fasta.messageCovariantAfterVar);
      // fall through to parse modifier
    } else if (finalToken != null) {
      if (!isCovariantFinalAllowed) {
        parser.reportRecoverableError(
            covariantToken, fasta.messageFinalAndCovariant);
        return covariantToken;
      }
      parser.reportRecoverableError(
          covariantToken, fasta.messageCovariantAfterFinal);
      // fall through to parse modifier
    }
    return super.parseCovariantOpt(token);
  }

  @override
  Token parseExternalOpt(Token token) {
    Token next = token.next;
    if (externalToken != null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateDuplicatedModifier);
      return next;
    }
    externalToken = token.next;
    return super.parseExternalOpt(token);
  }

  @override
  Token parseFinal(Token token) {
    Token next = token.next;
    if (finalToken != null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateDuplicatedModifier);
      return next;
    }
    finalToken = next;
    if (constToken != null) {
      parser.reportRecoverableError(finalToken, fasta.messageConstAndFinal);
      return finalToken;
    }
    if (covariantToken != null && !isCovariantFinalAllowed) {
      parser.reportRecoverableError(finalToken, fasta.messageFinalAndCovariant);
      return finalToken;
    }
    if (varToken != null) {
      parser.reportRecoverableError(finalToken, fasta.messageFinalAndVar);
      return finalToken;
    }
    return super.parseFinal(token);
  }

  Token parseExtraneousModifier(Token token) {
    Token next = token.next;
    if (next.isModifier) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateExtraneousModifier);
    } else {
      // TODO(danrubel): Provide more specific error messages.
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateUnexpectedToken);
    }
    return next;
  }

  @override
  Token parseStaticOpt(Token token) {
    Token next = token.next;
    if (staticToken != null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateDuplicatedModifier);
      return next;
    }
    staticToken = next;
    if (covariantToken != null) {
      parser.reportRecoverableError(
          staticToken, fasta.messageCovariantAndStatic);
      return staticToken;
    }
    if (constToken != null) {
      parser.reportRecoverableError(staticToken, fasta.messageStaticAfterConst);
      // fall through to parse modifier
    } else if (finalToken != null) {
      parser.reportRecoverableError(staticToken, fasta.messageStaticAfterFinal);
      // fall through to parse modifier
    } else if (varToken != null) {
      parser.reportRecoverableError(staticToken, fasta.messageStaticAfterVar);
      // fall through to parse modifier
    }
    return super.parseStaticOpt(token);
  }

  @override
  Token parseVar(Token token) {
    Token next = token.next;
    if (varToken != null) {
      parser.reportRecoverableErrorWithToken(
          next, fasta.templateDuplicatedModifier);
      return next;
    }
    varToken = next;
    if (constToken != null) {
      parser.reportRecoverableError(varToken, fasta.messageConstAndVar);
      return varToken;
    }
    if (finalToken != null) {
      parser.reportRecoverableError(varToken, fasta.messageFinalAndVar);
      return varToken;
    }
    return super.parseVar(token);
  }
}
