//===--- ContinuationIndenter.h - Format C++ code ---------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements an indenter that manages the indentation of
/// continuations.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_LIB_FORMAT_CONTINUATIONINDENTER_H
#define LLVM_CLANG_LIB_FORMAT_CONTINUATIONINDENTER_H

#include "Encoding.h"
#include "FormatToken.h"
#include "clang/Format/Format.h"
#include "llvm/Support/Regex.h"
#include <map>
#include <tuple>

namespace clang {
class SourceManager;

namespace format {

class AnnotatedLine;
class BreakableToken;
struct FormatToken;
struct LineState;
struct ParenState;
struct RawStringFormatStyleManager;
class WhitespaceManager;

struct RawStringFormatStyleManager {
  llvm::StringMap<FormatStyle> DelimiterStyle;
  llvm::StringMap<FormatStyle> EnclosingFunctionStyle;

  RawStringFormatStyleManager(const FormatStyle &CodeStyle);

  llvm::Optional<FormatStyle> getDelimiterStyle(StringRef Delimiter) const;

  llvm::Optional<FormatStyle>
  getEnclosingFunctionStyle(StringRef EnclosingFunction) const;
};

class ContinuationIndenter {
public:
  /// Constructs a \c ContinuationIndenter to format \p Line starting in
  /// column \p FirstIndent.
  ContinuationIndenter(const FormatStyle &Style,
                       const AdditionalKeywords &Keywords,
                       const SourceManager &SourceMgr,
                       WhitespaceManager &Whitespaces,
                       encoding::Encoding Encoding,
                       bool BinPackInconclusiveFunctions);

  /// Get the initial state, i.e. the state after placing \p Line's
  /// first token at \p FirstIndent. When reformatting a fragment of code, as in
  /// the case of formatting inside raw string literals, \p FirstStartColumn is
  /// the column at which the state of the parent formatter is.
  LineState getInitialState(unsigned FirstIndent, unsigned FirstStartColumn,
                            const AnnotatedLine *Line, bool DryRun);

  // FIXME: canBreak and mustBreak aren't strictly indentation-related. Find a
  // better home.
  /// Returns \c true, if a line break after \p State is allowed.
  bool canBreak(const LineState &State);

  /// Returns \c true, if a line break after \p State is mandatory.
  bool mustBreak(const LineState &State);

  /// Appends the next token to \p State and updates information
  /// necessary for indentation.
  ///
  /// Puts the token on the current line if \p Newline is \c false and adds a
  /// line break and necessary indentation otherwise.
  ///
  /// If \p DryRun is \c false, also creates and stores the required
  /// \c Replacement.
  unsigned addTokenToState(LineState &State, bool Newline, bool DryRun,
                           unsigned ExtraSpaces = 0);

  /// Get the column limit for this line. This is the style's column
  /// limit, potentially reduced for preprocessor definitions.
  unsigned getColumnLimit(const LineState &State) const;

private:
  /// Mark the next token as consumed in \p State and modify its stacks
  /// accordingly.
  unsigned moveStateToNextToken(LineState &State, bool DryRun, bool Newline);

  /// Update 'State' according to the next token's fake left parentheses.
  void moveStatePastFakeLParens(LineState &State, bool Newline);
  /// Update 'State' according to the next token's fake r_parens.
  void moveStatePastFakeRParens(LineState &State);

  /// Update 'State' according to the next token being one of "(<{[".
  void moveStatePastScopeOpener(LineState &State, bool Newline);
  /// Update 'State' according to the next token being one of ")>}]".
  void moveStatePastScopeCloser(LineState &State);
  /// Update 'State' with the next token opening a nested block.
  void moveStateToNewBlock(LineState &State);

  /// Reformats a raw string literal.
  ///
  /// \returns An extra penalty induced by reformatting the token.
  unsigned reformatRawStringLiteral(const FormatToken &Current,
                                    LineState &State,
                                    const FormatStyle &RawStringStyle,
                                    bool DryRun, bool Newline);

  /// If the current token is at the end of the current line, handle
  /// the transition to the next line.
  unsigned handleEndOfLine(const FormatToken &Current, LineState &State,
                           bool DryRun, bool AllowBreak, bool Newline);

  /// If \p Current is a raw string that is configured to be reformatted,
  /// return the style to be used.
  llvm::Optional<FormatStyle> getRawStringStyle(const FormatToken &Current,
                                                const LineState &State);

  /// If the current token sticks out over the end of the line, break
  /// it if possible.
  ///
  /// \returns A pair (penalty, exceeded), where penalty is the extra penalty
  /// when tokens are broken or lines exceed the column limit, and exceeded
  /// indicates whether the algorithm purposefully left lines exceeding the
  /// column limit.
  ///
  /// The returned penalty will cover the cost of the additional line breaks
  /// and column limit violation in all lines except for the last one. The
  /// penalty for the column limit violation in the last line (and in single
  /// line tokens) is handled in \c addNextStateToQueue.
  ///
  /// \p Strict indicates whether reflowing is allowed to leave characters
  /// protruding the column limit; if true, lines will be split strictly within
  /// the column limit where possible; if false, words are allowed to protrude
  /// over the column limit as long as the penalty is less than the penalty
  /// of a break.
  std::pair<unsigned, bool> breakProtrudingToken(const FormatToken &Current,
                                                 LineState &State,
                                                 bool AllowBreak, bool DryRun,
                                                 bool Strict);

  /// Returns the \c BreakableToken starting at \p Current, or nullptr
  /// if the current token cannot be broken.
  std::unique_ptr<BreakableToken>
  createBreakableToken(const FormatToken &Current, LineState &State,
                       bool AllowBreak);

  /// Appends the next token to \p State and updates information
  /// necessary for indentation.
  ///
  /// Puts the token on the current line.
  ///
  /// If \p DryRun is \c false, also creates and stores the required
  /// \c Replacement.
  void addTokenOnCurrentLine(LineState &State, bool DryRun,
                             unsigned ExtraSpaces);

  /// Appends the next token to \p State and updates information
  /// necessary for indentation.
  ///
  /// Adds a line break and necessary indentation.
  ///
  /// If \p DryRun is \c false, also creates and stores the required
  /// \c Replacement.
  unsigned addTokenOnNewLine(LineState &State, bool DryRun);

  /// Calculate the new column for a line wrap before the next token.
  unsigned getNewLineColumn(const LineState &State);

  /// Adds a multiline token to the \p State.
  ///
  /// \returns Extra penalty for the first line of the literal: last line is
  /// handled in \c addNextStateToQueue, and the penalty for other lines doesn't
  /// matter, as we don't change them.
  unsigned addMultilineToken(const FormatToken &Current, LineState &State);

  /// Returns \c true if the next token starts a multiline string
  /// literal.
  ///
  /// This includes implicitly concatenated strings, strings that will be broken
  /// by clang-format and string literals with escaped newlines.
  bool nextIsMultilineString(const LineState &State);

  FormatStyle Style;
  const AdditionalKeywords &Keywords;
  const SourceManager &SourceMgr;
  WhitespaceManager &Whitespaces;
  encoding::Encoding Encoding;
  bool BinPackInconclusiveFunctions;
  llvm::Regex CommentPragmasRegex;
  const RawStringFormatStyleManager RawStringFormats;
};

struct ParenState {
  ParenState(const FormatToken *Tok, unsigned Indent, unsigned LastSpace,
             bool AvoidBinPacking, bool NoLineBreak)
      : Tok(Tok), Indent(Indent), LastSpace(LastSpace),
        NestedBlockIndent(Indent), IsAligned(false),
        BreakBeforeClosingBrace(false), AvoidBinPacking(AvoidBinPacking),
        BreakBeforeParameter(false), NoLineBreak(NoLineBreak),
        NoLineBreakInOperand(false), LastOperatorWrapped(true),
        ContainsLineBreak(false), ContainsUnwrappedBuilder(false),
        AlignColons(true), ObjCSelectorNameFound(false),
        HasMultipleNestedBlocks(false), NestedBlockInlined(false),
        IsInsideObjCArrayLiteral(false), IsCSharpGenericTypeConstraint(false),
        IsChainedConditional(false), IsWrappedConditional(false),
        UnindentOperator(false) {}

  /// \brief The token opening this parenthesis level, or nullptr if this level
  /// is opened by fake parenthesis.
  ///
  /// Not considered for memoization as it will always have the same value at
  /// the same token.
  const FormatToken *Tok;

  /// The position to which a specific parenthesis level needs to be
  /// indented.
  unsigned Indent;

  /// The position of the last space on each level.
  ///
  /// Used e.g. to break like:
  /// functionCall(Parameter, otherCall(
  ///                             OtherParameter));
  unsigned LastSpace;

  /// If a block relative to this parenthesis level gets wrapped, indent
  /// it this much.
  unsigned NestedBlockIndent;

  /// The position the first "<<" operator encountered on each level.
  ///
  /// Used to align "<<" operators. 0 if no such operator has been encountered
  /// on a level.
  unsigned FirstLessLess = 0;

  /// The column of a \c ? in a conditional expression;
  unsigned QuestionColumn = 0;

  /// The position of the colon in an ObjC method declaration/call.
  unsigned ColonPos = 0;

  /// The start of the most recent function in a builder-type call.
  unsigned StartOfFunctionCall = 0;

  /// Contains the start of array subscript expressions, so that they
  /// can be aligned.
  unsigned StartOfArraySubscripts = 0;

  /// If a nested name specifier was broken over multiple lines, this
  /// contains the start column of the second line. Otherwise 0.
  unsigned NestedNameSpecifierContinuation = 0;

  /// If a call expression was broken over multiple lines, this
  /// contains the start column of the second line. Otherwise 0.
  unsigned CallContinuation = 0;

  /// The column of the first variable name in a variable declaration.
  ///
  /// Used to align further variables if necessary.
  unsigned VariablePos = 0;

  /// Whether this block's indentation is used for alignment.
  bool IsAligned : 1;

  /// Whether a newline needs to be inserted before the block's closing
  /// brace.
  ///
  /// We only want to insert a newline before the closing brace if there also
  /// was a newline after the beginning left brace.
  bool BreakBeforeClosingBrace : 1;

  /// Avoid bin packing, i.e. multiple parameters/elements on multiple
  /// lines, in this context.
  bool AvoidBinPacking : 1;

  /// Break after the next comma (or all the commas in this context if
  /// \c AvoidBinPacking is \c true).
  bool BreakBeforeParameter : 1;

  /// Line breaking in this context would break a formatting rule.
  bool NoLineBreak : 1;

  /// Same as \c NoLineBreak, but is restricted until the end of the
  /// operand (including the next ",").
  bool NoLineBreakInOperand : 1;

  /// True if the last binary operator on this level was wrapped to the
  /// next line.
  bool LastOperatorWrapped : 1;

  /// \c true if this \c ParenState already contains a line-break.
  ///
  /// The first line break in a certain \c ParenState causes extra penalty so
  /// that clang-format prefers similar breaks, i.e. breaks in the same
  /// parenthesis.
  bool ContainsLineBreak : 1;

  /// \c true if this \c ParenState contains multiple segments of a
  /// builder-type call on one line.
  bool ContainsUnwrappedBuilder : 1;

  /// \c true if the colons of the curren ObjC method expression should
  /// be aligned.
  ///
  /// Not considered for memoization as it will always have the same value at
  /// the same token.
  bool AlignColons : 1;

  /// \c true if at least one selector name was found in the current
  /// ObjC method expression.
  ///
  /// Not considered for memoization as it will always have the same value at
  /// the same token.
  bool ObjCSelectorNameFound : 1;

  /// \c true if there are multiple nested blocks inside these parens.
  ///
  /// Not considered for memoization as it will always have the same value at
  /// the same token.
  bool HasMultipleNestedBlocks : 1;

  /// The start of a nested block (e.g. lambda introducer in C++ or
  /// "function" in JavaScript) is not wrapped to a new line.
  bool NestedBlockInlined : 1;

  /// \c true if the current \c ParenState represents an Objective-C
  /// array literal.
  bool IsInsideObjCArrayLiteral : 1;

  bool IsCSharpGenericTypeConstraint : 1;

  /// \brief true if the current \c ParenState represents the false branch of
  /// a chained conditional expression (e.g. else-if)
  bool IsChainedConditional : 1;

  /// \brief true if there conditionnal was wrapped on the first operator (the
  /// question mark)
  bool IsWrappedConditional : 1;

  /// \brief Indicates the indent should be reduced by the length of the
  /// operator.
  bool UnindentOperator : 1;

  bool operator<(const ParenState &Other) const {
    if (Indent != Other.Indent)
      return Indent < Other.Indent;
    if (LastSpace != Other.LastSpace)
      return LastSpace < Other.LastSpace;
    if (NestedBlockIndent != Other.NestedBlockIndent)
      return NestedBlockIndent < Other.NestedBlockIndent;
    if (FirstLessLess != Other.FirstLessLess)
      return FirstLessLess < Other.FirstLessLess;
    if (IsAligned != Other.IsAligned)
      return IsAligned;
    if (BreakBeforeClosingBrace != Other.BreakBeforeClosingBrace)
      return BreakBeforeClosingBrace;
    if (QuestionColumn != Other.QuestionColumn)
      return QuestionColumn < Other.QuestionColumn;
    if (AvoidBinPacking != Other.AvoidBinPacking)
      return AvoidBinPacking;
    if (BreakBeforeParameter != Other.BreakBeforeParameter)
      return BreakBeforeParameter;
    if (NoLineBreak != Other.NoLineBreak)
      return NoLineBreak;
    if (LastOperatorWrapped != Other.LastOperatorWrapped)
      return LastOperatorWrapped;
    if (ColonPos != Other.ColonPos)
      return ColonPos < Other.ColonPos;
    if (StartOfFunctionCall != Other.StartOfFunctionCall)
      return StartOfFunctionCall < Other.StartOfFunctionCall;
    if (StartOfArraySubscripts != Other.StartOfArraySubscripts)
      return StartOfArraySubscripts < Other.StartOfArraySubscripts;
    if (CallContinuation != Other.CallContinuation)
      return CallContinuation < Other.CallContinuation;
    if (VariablePos != Other.VariablePos)
      return VariablePos < Other.VariablePos;
    if (ContainsLineBreak != Other.ContainsLineBreak)
      return ContainsLineBreak;
    if (ContainsUnwrappedBuilder != Other.ContainsUnwrappedBuilder)
      return ContainsUnwrappedBuilder;
    if (NestedBlockInlined != Other.NestedBlockInlined)
      return NestedBlockInlined;
    if (IsCSharpGenericTypeConstraint != Other.IsCSharpGenericTypeConstraint)
      return IsCSharpGenericTypeConstraint;
    if (IsChainedConditional != Other.IsChainedConditional)
      return IsChainedConditional;
    if (IsWrappedConditional != Other.IsWrappedConditional)
      return IsWrappedConditional;
    if (UnindentOperator != Other.UnindentOperator)
      return UnindentOperator;
    return false;
  }
};

/// The current state when indenting a unwrapped line.
///
/// As the indenting tries different combinations this is copied by value.
struct LineState {
  /// The number of used columns in the current line.
  unsigned Column;

  /// The token that needs to be next formatted.
  FormatToken *NextToken;

  /// \c true if this line contains a continued for-loop section.
  bool LineContainsContinuedForLoopSection;

  /// \c true if \p NextToken should not continue this line.
  bool NoContinuation;

  /// The \c NestingLevel at the start of this line.
  unsigned StartOfLineLevel;

  /// The lowest \c NestingLevel on the current line.
  unsigned LowestLevelOnLine;

  /// The start column of the string literal, if we're in a string
  /// literal sequence, 0 otherwise.
  unsigned StartOfStringLiteral;

  /// A stack keeping track of properties applying to parenthesis
  /// levels.
  std::vector<ParenState> Stack;

  /// Ignore the stack of \c ParenStates for state comparison.
  ///
  /// In long and deeply nested unwrapped lines, the current algorithm can
  /// be insufficient for finding the best formatting with a reasonable amount
  /// of time and memory. Setting this flag will effectively lead to the
  /// algorithm not analyzing some combinations. However, these combinations
  /// rarely contain the optimal solution: In short, accepting a higher
  /// penalty early would need to lead to different values in the \c
  /// ParenState stack (in an otherwise identical state) and these different
  /// values would need to lead to a significant amount of avoided penalty
  /// later.
  ///
  /// FIXME: Come up with a better algorithm instead.
  bool IgnoreStackForComparison;

  /// The indent of the first token.
  unsigned FirstIndent;

  /// The line that is being formatted.
  ///
  /// Does not need to be considered for memoization because it doesn't change.
  const AnnotatedLine *Line;

  /// Comparison operator to be able to used \c LineState in \c map.
  bool operator<(const LineState &Other) const {
    if (NextToken != Other.NextToken)
      return NextToken < Other.NextToken;
    if (Column != Other.Column)
      return Column < Other.Column;
    if (LineContainsContinuedForLoopSection !=
        Other.LineContainsContinuedForLoopSection)
      return LineContainsContinuedForLoopSection;
    if (NoContinuation != Other.NoContinuation)
      return NoContinuation;
    if (StartOfLineLevel != Other.StartOfLineLevel)
      return StartOfLineLevel < Other.StartOfLineLevel;
    if (LowestLevelOnLine != Other.LowestLevelOnLine)
      return LowestLevelOnLine < Other.LowestLevelOnLine;
    if (StartOfStringLiteral != Other.StartOfStringLiteral)
      return StartOfStringLiteral < Other.StartOfStringLiteral;
    if (IgnoreStackForComparison || Other.IgnoreStackForComparison)
      return false;
    return Stack < Other.Stack;
  }
};

} // end namespace format
} // end namespace clang

#endif
