// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gn/command_format.h"

#include <stddef.h>

#include <sstream>

#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "gn/commands.h"
#include "gn/filesystem_utils.h"
#include "gn/input_file.h"
#include "gn/parser.h"
#include "gn/scheduler.h"
#include "gn/setup.h"
#include "gn/source_file.h"
#include "gn/string_utils.h"
#include "gn/switches.h"
#include "gn/tokenizer.h"
#include "util/build_config.h"

#if defined(OS_WIN)
#include <fcntl.h>
#include <io.h>
#endif

namespace commands {

const char kSwitchDryRun[] = "dry-run";
const char kSwitchDumpTree[] = "dump-tree";
const char kSwitchReadTree[] = "read-tree";
const char kSwitchStdin[] = "stdin";
const char kSwitchTreeTypeJSON[] = "json";
const char kSwitchTreeTypeText[] = "text";

const char kFormat[] = "format";
const char kFormat_HelpShort[] = "format: Format .gn files.";
const char kFormat_Help[] =
    R"(gn format [--dump-tree] (--stdin | <list of build_files...>)

  Formats .gn file to a standard format.

  The contents of some lists ('sources', 'deps', etc.) will be sorted to a
  canonical order. To suppress this, you can add a comment of the form "#
  NOSORT" immediately preceding the assignment. e.g.

  # NOSORT
  sources = [
    "z.cc",
    "a.cc",
  ]

Arguments

  --dry-run
      Prints the list of files that would be reformatted but does not write
      anything to disk. This is useful for presubmit/lint-type checks.
      - Exit code 0: successful format, matches on disk.
      - Exit code 1: general failure (parse error, etc.)
      - Exit code 2: successful format, but differs from on disk.

  --dump-tree[=( text | json )]
      Dumps the parse tree to stdout and does not update the file or print
      formatted output. If no format is specified, text format will be used.

  --stdin
      Read input from stdin and write to stdout rather than update a file
      in-place.

  --read-tree=json
      Reads an AST from stdin in the format output by --dump-tree=json and
      uses that as the parse tree. (The only read-tree format currently
      supported is json.) The given .gn file will be overwritten. This can be
      used to programmatically transform .gn files.

Examples
  gn format //some/BUILD.gn //some/other/BUILD.gn //and/another/BUILD.gn
  gn format some\\BUILD.gn
  gn format /abspath/some/BUILD.gn
  gn format --stdin
  gn format --read-tree=json //rewritten/BUILD.gn
)";

namespace {

const int kIndentSize = 2;
const int kMaximumWidth = 80;

const int kPenaltyLineBreak = 500;
const int kPenaltyHorizontalSeparation = 100;
const int kPenaltyExcess = 10000;
const int kPenaltyBrokenLineOnOneLiner = 5000;

enum Precedence {
  kPrecedenceLowest,
  kPrecedenceAssign,
  kPrecedenceOr,
  kPrecedenceAnd,
  kPrecedenceCompare,
  kPrecedenceAdd,
  kPrecedenceUnary,
  kPrecedenceSuffix,
};

int CountLines(const std::string& str) {
  return static_cast<int>(base::SplitStringPiece(str, "\n",
                                                 base::KEEP_WHITESPACE,
                                                 base::SPLIT_WANT_ALL)
                              .size());
}

class Printer {
 public:
  Printer();
  ~Printer();

  void Block(const ParseNode* file);

  std::string String() const { return output_; }

 private:
  // Format a list of values using the given style.
  enum SequenceStyle {
    kSequenceStyleList,
    kSequenceStyleBracedBlock,
    kSequenceStyleBracedBlockAlreadyOpen,
  };

  struct Metrics {
    Metrics() : first_length(-1), longest_length(-1), multiline(false) {}
    int first_length;
    int longest_length;
    bool multiline;
  };

  // Add to output.
  void Print(std::string_view str);

  // Add the current margin (as spaces) to the output.
  void PrintMargin();

  void TrimAndPrintToken(const Token& token);

  void PrintTrailingCommentsWrapped(const std::vector<Token>& comments);

  void FlushComments();

  void PrintSuffixComments(const ParseNode* node);

  // End the current line, flushing end of line comments.
  void Newline();

  // Remove trailing spaces from the current line.
  void Trim();

  // Whether there's a blank separator line at the current position.
  bool HaveBlankLine();

  // Sort a list on the RHS if the LHS is one of the following:
  // 'sources': sorted alphabetically.
  // 'deps' or ends in 'deps': sorted such that relative targets are first,
  //   followed by global targets, each internally sorted alphabetically.
  // 'visibility': same as 'deps'.
  void SortIfApplicable(const BinaryOpNode* binop);

  // Traverse a binary op node tree and apply a callback to each leaf node.
  void TraverseBinaryOpNode(const ParseNode* node,
                            std::function<void(const ParseNode*)> callback);

  // Sort contiguous import() function calls in the given ordered list of
  // statements (the body of a block or scope).
  template <class PARSENODE>
  void SortImports(std::vector<std::unique_ptr<PARSENODE>>& statements);

  // Heuristics to decide if there should be a blank line added between two
  // items. For various "small" items, it doesn't look nice if there's too much
  // vertical whitespace added.
  bool ShouldAddBlankLineInBetween(const ParseNode* a, const ParseNode* b);

  // Get the 0-based x position on the current line.
  int CurrentColumn() const;

  // Get the current line in the output;
  int CurrentLine() const;

  // Adds an opening ( if prec is less than the outers (to maintain evalution
  // order for a subexpression). If an opening paren is emitted, *parenthesized
  // will be set so it can be closed at the end of the expression.
  void AddParen(int prec, int outer_prec, bool* parenthesized);

  // Print the expression given by |root| to the output buffer and appends
  // |suffix| to that output. Returns a penalty that represents the cost of
  // adding that output to the buffer (where higher is worse). The value of
  // outer_prec gives the precedence of the operator outside this Expr. If that
  // operator binds tighter than root's, Expr() must introduce parentheses.
  int Expr(const ParseNode* root, int outer_prec, const std::string& suffix);

  // Generic penalties for exceeding maximum width, adding more lines, etc.
  int AssessPenalty(const std::string& output);

  // Tests if any lines exceed the maximum width.
  bool ExceedsMaximumWidth(const std::string& output);

  // Format a list of values using the given style.
  // |end| holds any trailing comments to be printed just before the closing
  // bracket.
  template <class PARSENODE>  // Just for const covariance.
  void Sequence(SequenceStyle style,
                const std::vector<std::unique_ptr<PARSENODE>>& list,
                const ParseNode* end,
                bool force_multiline);

  // Returns the penalty.
  int FunctionCall(const FunctionCallNode* func_call,
                   const std::string& suffix);

  // Create a clone of this Printer in a similar state (other than the output,
  // but including margins, etc.) to be used for dry run measurements.
  void InitializeSub(Printer* sub);

  template <class PARSENODE>
  bool ListWillBeMultiline(const std::vector<std::unique_ptr<PARSENODE>>& list,
                           const ParseNode* end);

  std::string output_;           // Output buffer.
  std::vector<Token> comments_;  // Pending end-of-line comments.
  int margin() const { return stack_.back().margin; }

  int penalty_depth_;
  int GetPenaltyForLineBreak() const {
    return penalty_depth_ * kPenaltyLineBreak;
  }

  struct IndentState {
    IndentState()
        : margin(0),
          continuation_requires_indent(false),
          parent_is_boolean_or(false) {}
    IndentState(int margin,
                bool continuation_requires_indent,
                bool parent_is_boolean_or)
        : margin(margin),
          continuation_requires_indent(continuation_requires_indent),
          parent_is_boolean_or(parent_is_boolean_or) {}

    // The left margin (number of spaces).
    int margin;

    bool continuation_requires_indent;

    bool parent_is_boolean_or;
  };
  // Stack used to track
  std::vector<IndentState> stack_;

  // Gives the precedence for operators in a BinaryOpNode.
  std::map<std::string_view, Precedence> precedence_;

  Printer(const Printer&) = delete;
  Printer& operator=(const Printer&) = delete;
};

Printer::Printer() : penalty_depth_(0) {
  output_.reserve(100 << 10);
  precedence_["="] = kPrecedenceAssign;
  precedence_["+="] = kPrecedenceAssign;
  precedence_["-="] = kPrecedenceAssign;
  precedence_["||"] = kPrecedenceOr;
  precedence_["&&"] = kPrecedenceAnd;
  precedence_["<"] = kPrecedenceCompare;
  precedence_[">"] = kPrecedenceCompare;
  precedence_["=="] = kPrecedenceCompare;
  precedence_["!="] = kPrecedenceCompare;
  precedence_["<="] = kPrecedenceCompare;
  precedence_[">="] = kPrecedenceCompare;
  precedence_["+"] = kPrecedenceAdd;
  precedence_["-"] = kPrecedenceAdd;
  precedence_["!"] = kPrecedenceUnary;
  stack_.push_back(IndentState());
}

Printer::~Printer() = default;

void Printer::Print(std::string_view str) {
  output_.append(str);
}

void Printer::PrintMargin() {
  output_ += std::string(margin(), ' ');
}

void Printer::TrimAndPrintToken(const Token& token) {
  std::string trimmed;
  TrimWhitespaceASCII(std::string(token.value()), base::TRIM_ALL, &trimmed);
  Print(trimmed);
}

// Assumes that the margin is set to the indent level where the comments should
// be aligned. This doesn't de-wrap, it only wraps. So if a suffix comment
// causes the line to exceed 80 col it will be wrapped, but the subsequent line
// would fit on the then-broken line it will not be merged with it. This is
// partly because it's difficult to implement at this level, but also because
// it can break hand-authored line breaks where they're starting a new paragraph
// or statement.
void Printer::PrintTrailingCommentsWrapped(const std::vector<Token>& comments) {
  bool have_empty_line = true;
  auto start_next_line = [this, &have_empty_line]() {
    Trim();
    Print("\n");
    PrintMargin();
    have_empty_line = true;
  };
  for (const auto& c : comments) {
    if (!have_empty_line) {
      start_next_line();
    }

    std::string trimmed;
    TrimWhitespaceASCII(std::string(c.value()), base::TRIM_ALL, &trimmed);

    if (margin() + trimmed.size() <= kMaximumWidth) {
      Print(trimmed);
      have_empty_line = false;
    } else {
      bool continuation = false;
      std::vector<std::string> split_on_spaces = base::SplitString(
          c.value(), " ", base::WhitespaceHandling::TRIM_WHITESPACE,
          base::SplitResult::SPLIT_WANT_NONEMPTY);
      for (size_t j = 0; j < split_on_spaces.size(); ++j) {
        if (have_empty_line && continuation) {
          Print("# ");
        }
        Print(split_on_spaces[j]);
        Print(" ");
        if (split_on_spaces[j] != "#") {
          have_empty_line = false;
        }
        if (!have_empty_line &&
            (j < split_on_spaces.size() - 1 &&
             CurrentColumn() + split_on_spaces[j + 1].size() > kMaximumWidth)) {
          start_next_line();
          continuation = true;
        }
      }
    }
  }
}

// Used during penalty evaluation, similar to Newline().
void Printer::PrintSuffixComments(const ParseNode* node) {
  if (node->comments() && !node->comments()->suffix().empty()) {
    Print("  ");
    stack_.push_back(IndentState(CurrentColumn(), false, false));
    PrintTrailingCommentsWrapped(node->comments()->suffix());
    stack_.pop_back();
  }
}

void Printer::FlushComments() {
  if (!comments_.empty()) {
    Print("  ");
    // Save the margin, and temporarily set it to where the first comment
    // starts so that multiple suffix comments are vertically aligned.
    stack_.push_back(IndentState(CurrentColumn(), false, false));
    PrintTrailingCommentsWrapped(comments_);
    stack_.pop_back();
    comments_.clear();
  }
}

void Printer::Newline() {
  FlushComments();
  Trim();
  Print("\n");
  PrintMargin();
}

void Printer::Trim() {
  size_t n = output_.size();
  while (n > 0 && output_[n - 1] == ' ')
    --n;
  output_.resize(n);
}

bool Printer::HaveBlankLine() {
  size_t n = output_.size();
  while (n > 0 && output_[n - 1] == ' ')
    --n;
  return n > 2 && output_[n - 1] == '\n' && output_[n - 2] == '\n';
}

void Printer::SortIfApplicable(const BinaryOpNode* binop) {
  if (const Comments* comments = binop->comments()) {
    const std::vector<Token>& before = comments->before();
    if (!before.empty() && (before.front().value() == "# NOSORT" ||
                            before.back().value() == "# NOSORT")) {
      // Allow disabling of sort for specific actions that might be
      // order-sensitive.
      return;
    }
  }
  const IdentifierNode* ident = binop->left()->AsIdentifier();
  if ((binop->op().value() == "=" || binop->op().value() == "+=" ||
       binop->op().value() == "-=") &&
      ident) {
    const std::string_view lhs = ident->value().value();
    if (base::EndsWith(lhs, "sources", base::CompareCase::SENSITIVE) ||
        lhs == "public") {
      TraverseBinaryOpNode(binop->right(), [](const ParseNode* node) {
        const ListNode* list = node->AsList();
        if (list)
          const_cast<ListNode*>(list)->SortAsStringsList();
      });
    } else if (base::EndsWith(lhs, "deps", base::CompareCase::SENSITIVE) ||
               lhs == "visibility") {
      TraverseBinaryOpNode(binop->right(), [](const ParseNode* node) {
        const ListNode* list = node->AsList();
        if (list)
          const_cast<ListNode*>(list)->SortAsTargetsList();
      });
    }
  }
}

void Printer::TraverseBinaryOpNode(
    const ParseNode* node,
    std::function<void(const ParseNode*)> callback) {
  const BinaryOpNode* binop = node->AsBinaryOp();
  if (binop) {
    TraverseBinaryOpNode(binop->left(), callback);
    TraverseBinaryOpNode(binop->right(), callback);
  } else {
    callback(node);
  }
}

template <class PARSENODE>
void Printer::SortImports(std::vector<std::unique_ptr<PARSENODE>>& statements) {
  // Build a set of ranges by indices of FunctionCallNode's that are imports.

  std::vector<std::vector<size_t>> import_statements;

  auto is_import = [](const PARSENODE* p) {
    const FunctionCallNode* func_call = p->AsFunctionCall();
    return func_call && func_call->function().value() == "import";
  };

  std::vector<size_t> current_group;
  for (size_t i = 0; i < statements.size(); ++i) {
    if (is_import(statements[i].get())) {
      if (i > 0 && (!is_import(statements[i - 1].get()) ||
                    ShouldAddBlankLineInBetween(statements[i - 1].get(),
                                                statements[i].get()))) {
        if (!current_group.empty()) {
          import_statements.push_back(current_group);
          current_group.clear();
        }
      }
      current_group.push_back(i);
    }
  }

  if (!current_group.empty())
    import_statements.push_back(current_group);

  struct CompareByImportFile {
    bool operator()(const std::unique_ptr<PARSENODE>& a,
                    const std::unique_ptr<PARSENODE>& b) const {
      const auto& a_args = a->AsFunctionCall()->args()->contents();
      const auto& b_args = b->AsFunctionCall()->args()->contents();
      std::string_view a_name;
      std::string_view b_name;

      // Non-literal imports are treated as empty names, and order is
      // maintained. Arbitrarily complex expressions in import() are
      // rare, and it probably doesn't make sense to sort non-string
      // literals anyway, see format_test_data/083.gn.
      if (!a_args.empty() && a_args[0]->AsLiteral())
        a_name = a_args[0]->AsLiteral()->value().value();
      if (!b_args.empty() && b_args[0]->AsLiteral())
        b_name = b_args[0]->AsLiteral()->value().value();

      auto is_absolute = [](std::string_view import) {
        return import.size() >= 3 && import[0] == '"' && import[1] == '/' &&
               import[2] == '/';
      };
      int a_is_rel = !is_absolute(a_name);
      int b_is_rel = !is_absolute(b_name);

      return std::tie(a_is_rel, a_name) < std::tie(b_is_rel, b_name);
    }
  };

  int line_after_previous = -1;

  for (const auto& group : import_statements) {
    size_t begin = group[0];
    size_t end = group.back() + 1;

    // Save the original line number so that ranges can be re-assigned. They're
    // contiguous because of the partitioning code above. Later formatting
    // relies on correct line number to know whether to insert blank lines,
    // which is why these need to be fixed up. Additionally, to handle multiple
    // imports on one line, they're assigned sequential line numbers, and
    // subsequent blocks will be gapped from them.
    int start_line =
        std::max(statements[begin]->GetRange().begin().line_number(),
                 line_after_previous + 1);

    std::sort(statements.begin() + begin, statements.begin() + end,
              CompareByImportFile());

    const PARSENODE* prev = nullptr;
    for (size_t i = begin; i < end; ++i) {
      const PARSENODE* node = statements[i].get();
      int line_number =
          prev ? prev->GetRange().end().line_number() + 1 : start_line;
      if (node->comments() && !node->comments()->before().empty())
        line_number++;
      const_cast<FunctionCallNode*>(node->AsFunctionCall())
          ->SetNewLocation(line_number);
      prev = node;
      line_after_previous = line_number + 1;
    }
  }
}

namespace {

int SuffixCommentTreeWalk(const ParseNode* node) {
  // Check all the children for suffix comments. This is conceptually simple,
  // but ugly as there's not a generic parse tree walker. This walker goes
  // lowest child first so that if it's valid that's returned.
  if (!node)
    return -1;

#define RETURN_IF_SET(x)             \
  if (int result = (x); result >= 0) \
    return result

  if (const AccessorNode* accessor = node->AsAccessor()) {
    RETURN_IF_SET(SuffixCommentTreeWalk(accessor->subscript()));
    RETURN_IF_SET(SuffixCommentTreeWalk(accessor->member()));
  } else if (const BinaryOpNode* binop = node->AsBinaryOp()) {
    RETURN_IF_SET(SuffixCommentTreeWalk(binop->right()));
  } else if (const BlockNode* block = node->AsBlock()) {
    RETURN_IF_SET(SuffixCommentTreeWalk(block->End()));
  } else if (const ConditionNode* condition = node->AsCondition()) {
    RETURN_IF_SET(SuffixCommentTreeWalk(condition->if_false()));
    RETURN_IF_SET(SuffixCommentTreeWalk(condition->if_true()));
    RETURN_IF_SET(SuffixCommentTreeWalk(condition->condition()));
  } else if (const FunctionCallNode* func_call = node->AsFunctionCall()) {
    RETURN_IF_SET(SuffixCommentTreeWalk(func_call->block()));
    RETURN_IF_SET(SuffixCommentTreeWalk(func_call->args()));
  } else if (node->AsIdentifier()) {
    // Nothing.
  } else if (const ListNode* list = node->AsList()) {
    RETURN_IF_SET(SuffixCommentTreeWalk(list->End()));
  } else if (node->AsLiteral()) {
    // Nothing.
  } else if (const UnaryOpNode* unaryop = node->AsUnaryOp()) {
    RETURN_IF_SET(SuffixCommentTreeWalk(unaryop->operand()));
  } else if (node->AsBlockComment()) {
    // Nothing.
  } else if (node->AsEnd()) {
    // Nothing.
  } else {
    CHECK(false) << "Unhandled case in SuffixCommentTreeWalk.";
  }

#undef RETURN_IF_SET

  // Check this node if there are no child comments.
  if (node->comments() && !node->comments()->suffix().empty()) {
    return node->comments()->suffix().back().location().line_number();
  }

  return -1;
}

// If there are suffix comments on the first node or its children, they might
// carry down multiple lines. Otherwise, use the node's normal end range. This
// function is needed because the parse tree doesn't include comments in the
// location ranges, and it's not a straightforword change to add them. So this
// is effectively finding the "real" range for |root| including suffix comments.
// Note that it's not enough to simply look at |root|'s suffix comments because
// in the case of:
//
//   a =
//       b + c  # something
//              # or other
//   x = y
//
// the comments are attached to a BinOp+ which is a child of BinOp=, not
// directly to the BinOp= which will be what's being used to determine if there
// should be a blank line inserted before the |x| line.
int FindLowestSuffixComment(const ParseNode* root) {
  LocationRange range = root->GetRange();
  int end = range.end().line_number();
  int result = SuffixCommentTreeWalk(root);
  return (result == -1 || result < end) ? end : result;
}

}  // namespace

bool Printer::ShouldAddBlankLineInBetween(const ParseNode* a,
                                          const ParseNode* b) {
  LocationRange b_range = b->GetRange();
  int a_end = FindLowestSuffixComment(a);

  // If they're already separated by 1 or more lines, then we want to keep a
  // blank line.
  return (b_range.begin().line_number() > a_end + 1) ||
         // Always put a blank line before a block comment.
         b->AsBlockComment();
}

int Printer::CurrentColumn() const {
  int n = 0;
  while (n < static_cast<int>(output_.size()) &&
         output_[output_.size() - 1 - n] != '\n') {
    ++n;
  }
  return n;
}

int Printer::CurrentLine() const {
  int count = 1;
  for (const char* p = output_.c_str(); (p = strchr(p, '\n')) != nullptr;) {
    ++count;
    ++p;
  }
  return count;
}

void Printer::Block(const ParseNode* root) {
  const BlockNode* block = root->AsBlock();

  if (block->comments()) {
    for (const auto& c : block->comments()->before()) {
      TrimAndPrintToken(c);
      Newline();
    }
  }

  SortImports(const_cast<std::vector<std::unique_ptr<ParseNode>>&>(
      block->statements()));

  size_t i = 0;
  for (const auto& stmt : block->statements()) {
    Expr(stmt.get(), kPrecedenceLowest, std::string());
    Newline();
    if (stmt->comments()) {
      // Why are before() not printed here too? before() are handled inside
      // Expr(), as are suffix() which are queued to the next Newline().
      // However, because it's a general expression handler, it doesn't insert
      // the newline itself, which only happens between block statements. So,
      // the after are handled explicitly here.
      for (const auto& c : stmt->comments()->after()) {
        TrimAndPrintToken(c);
        Newline();
      }
    }
    if (i < block->statements().size() - 1 &&
        (ShouldAddBlankLineInBetween(block->statements()[i].get(),
                                     block->statements()[i + 1].get()))) {
      Newline();
    }
    ++i;
  }

  if (block->comments()) {
    if (!block->statements().empty() &&
        block->statements().back()->AsBlockComment()) {
      // If the block ends in a comment, and there's a comment following it,
      // then the two comments were originally separate, so keep them that way.
      Newline();
    }
    for (const auto& c : block->comments()->after()) {
      TrimAndPrintToken(c);
      Newline();
    }
  }
}

int Printer::AssessPenalty(const std::string& output) {
  int penalty = 0;
  std::vector<std::string> lines = base::SplitString(
      output, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  penalty += static_cast<int>(lines.size() - 1) * GetPenaltyForLineBreak();
  for (const auto& line : lines) {
    if (line.size() > kMaximumWidth)
      penalty += static_cast<int>(line.size() - kMaximumWidth) * kPenaltyExcess;
  }
  return penalty;
}

bool Printer::ExceedsMaximumWidth(const std::string& output) {
  for (const auto& line : base::SplitString(output, "\n", base::KEEP_WHITESPACE,
                                            base::SPLIT_WANT_ALL)) {
    std::string_view trimmed =
        TrimString(line, " ", base::TrimPositions::TRIM_TRAILING);
    if (trimmed.size() > kMaximumWidth) {
      return true;
    }
  }
  return false;
}

void Printer::AddParen(int prec, int outer_prec, bool* parenthesized) {
  if (prec < outer_prec) {
    Print("(");
    *parenthesized = true;
  }
}

int Printer::Expr(const ParseNode* root,
                  int outer_prec,
                  const std::string& suffix) {
  std::string at_end = suffix;
  int penalty = 0;
  penalty_depth_++;

  if (root->comments()) {
    if (!root->comments()->before().empty()) {
      Trim();
      // If there's already other text on the line, start a new line.
      if (CurrentColumn() > 0)
        Print("\n");
      // We're printing a line comment, so we need to be at the current margin.
      PrintMargin();
      for (const auto& c : root->comments()->before()) {
        TrimAndPrintToken(c);
        Newline();
      }
    }
  }

  bool parenthesized = false;

  if (const AccessorNode* accessor = root->AsAccessor()) {
    AddParen(kPrecedenceSuffix, outer_prec, &parenthesized);
    Print(accessor->base().value());
    if (accessor->member()) {
      Print(".");
      Expr(accessor->member(), kPrecedenceLowest, std::string());
    } else {
      CHECK(accessor->subscript());
      Print("[");
      Expr(accessor->subscript(), kPrecedenceLowest, "]");
    }
  } else if (const BinaryOpNode* binop = root->AsBinaryOp()) {
    CHECK(precedence_.find(binop->op().value()) != precedence_.end());

    SortIfApplicable(binop);

    Precedence prec = precedence_[binop->op().value()];

    // Since binary operators format left-to-right, it is ok for the left side
    // use the same operator without parentheses, so the left uses prec. For the
    // same reason, the right side cannot reuse the same operator, or else "x +
    // (y + z)" would format as "x + y + z" which means "(x + y) + z". So, treat
    // the right expression as appearing one precedence level higher.
    // However, because the source parens are not in the parse tree, as a
    // special case for && and || we insert strictly-redundant-but-helpful-for-
    // human-readers parentheses.
    int prec_left = prec;
    int prec_right = prec + 1;
    if (binop->op().value() == "&&" && stack_.back().parent_is_boolean_or) {
      Print("(");
      parenthesized = true;
    } else {
      AddParen(prec_left, outer_prec, &parenthesized);
    }

    if (parenthesized)
      at_end = ")" + at_end;

    int start_line = CurrentLine();
    int start_column = CurrentColumn();
    bool is_assignment = binop->op().value() == "=" ||
                         binop->op().value() == "+=" ||
                         binop->op().value() == "-=";

    int indent_column = start_column;
    if (is_assignment) {
      // Default to a double-indent for wrapped assignments.
      indent_column = margin() + kIndentSize * 2;

      // A special case for the long lists and scope assignments that are
      // common in .gn files, don't indent them + 4, even though they're just
      // continuations when they're simple lists like "x = [ a, b, c, ... ]" or
      // scopes like "x = { a = 1 b = 2 }". Put back to "normal" indenting.
      if (const ListNode* right_as_list = binop->right()->AsList()) {
        if (ListWillBeMultiline(right_as_list->contents(),
                                right_as_list->End()))
          indent_column = start_column;
      } else {
        if (binop->right()->AsBlock())
          indent_column = start_column;
      }
    }
    if (stack_.back().continuation_requires_indent)
      indent_column += kIndentSize * 2;

    stack_.push_back(IndentState(indent_column,
                                 stack_.back().continuation_requires_indent,
                                 binop->op().value() == "||"));
    Printer sub_left;
    InitializeSub(&sub_left);
    sub_left.Expr(binop->left(), prec_left,
                  std::string(" ") + std::string(binop->op().value()));
    bool left_is_multiline = CountLines(sub_left.String()) > 1;
    // Avoid walking the whole left redundantly times (see timing of Format.046)
    // so pull the output and comments from subprinter.
    Print(sub_left.String().substr(start_column));
    std::copy(sub_left.comments_.begin(), sub_left.comments_.end(),
              std::back_inserter(comments_));

    // Single line.
    Printer sub1;
    InitializeSub(&sub1);
    sub1.Print(" ");
    int penalty_current_line = sub1.Expr(binop->right(), prec_right, at_end);
    sub1.PrintSuffixComments(root);
    sub1.FlushComments();
    penalty_current_line += AssessPenalty(sub1.String());
    if (!is_assignment && left_is_multiline) {
      // In e.g. xxx + yyy, if xxx is already multiline, then we want a penalty
      // for trying to continue as if this were one line.
      penalty_current_line +=
          (CountLines(sub1.String()) - 1) * kPenaltyBrokenLineOnOneLiner;
    }

    // Break after operator.
    Printer sub2;
    InitializeSub(&sub2);
    sub2.Newline();
    int penalty_next_line = sub2.Expr(binop->right(), prec_right, at_end);
    sub2.PrintSuffixComments(root);
    sub2.FlushComments();
    penalty_next_line += AssessPenalty(sub2.String());

    // Force a list on the RHS that would normally be a single line into
    // multiline.
    bool tried_rhs_multiline = false;
    Printer sub3;
    InitializeSub(&sub3);
    int penalty_multiline_rhs_list = std::numeric_limits<int>::max();
    const ListNode* rhs_list = binop->right()->AsList();
    if (is_assignment && rhs_list &&
        !ListWillBeMultiline(rhs_list->contents(), rhs_list->End())) {
      sub3.Print(" ");
      sub3.stack_.push_back(IndentState(start_column, false, false));
      sub3.Sequence(kSequenceStyleList, rhs_list->contents(), rhs_list->End(),
                    true);
      sub3.PrintSuffixComments(root);
      sub3.FlushComments();
      sub3.stack_.pop_back();
      penalty_multiline_rhs_list = AssessPenalty(sub3.String());
      tried_rhs_multiline = true;
    }

    // If in all cases it was forced past 80col, then we don't break to avoid
    // breaking after '=' in the case of:
    //   variable = "... very long string ..."
    // as breaking and indenting doesn't make things much more readable, even
    // though there's fewer characters past the maximum width.
    bool exceeds_maximum_all_ways =
        ExceedsMaximumWidth(sub1.String()) &&
        ExceedsMaximumWidth(sub2.String()) &&
        (!tried_rhs_multiline || ExceedsMaximumWidth(sub3.String()));

    if (penalty_current_line < penalty_next_line || exceeds_maximum_all_ways) {
      Print(" ");
      Expr(binop->right(), prec_right, at_end);
      at_end = "";
    } else if (tried_rhs_multiline &&
               penalty_multiline_rhs_list < penalty_next_line) {
      // Force a multiline list on the right.
      Print(" ");
      stack_.push_back(IndentState(start_column, false, false));
      Sequence(kSequenceStyleList, rhs_list->contents(), rhs_list->End(), true);
      stack_.pop_back();
    } else {
      // Otherwise, put first argument and op, and indent next.
      Newline();
      penalty += std::abs(CurrentColumn() - start_column) *
                 kPenaltyHorizontalSeparation;
      Expr(binop->right(), prec_right, at_end);
      at_end = "";
    }
    stack_.pop_back();
    penalty += (CurrentLine() - start_line) * GetPenaltyForLineBreak();
  } else if (const BlockNode* block = root->AsBlock()) {
    Sequence(kSequenceStyleBracedBlock, block->statements(), block->End(),
             false);
  } else if (const ConditionNode* condition = root->AsCondition()) {
    Print("if (");
    CHECK(at_end.empty());
    Expr(condition->condition(), kPrecedenceLowest, ") {");
    Sequence(kSequenceStyleBracedBlockAlreadyOpen,
             condition->if_true()->statements(), condition->if_true()->End(),
             false);
    if (condition->if_false()) {
      Print(" else ");
      // If it's a block it's a bare 'else', otherwise it's an 'else if'. See
      // ConditionNode::Execute.
      bool is_else_if = condition->if_false()->AsBlock() == nullptr;
      if (is_else_if) {
        Expr(condition->if_false(), kPrecedenceLowest, std::string());
      } else {
        Sequence(kSequenceStyleBracedBlock,
                 condition->if_false()->AsBlock()->statements(),
                 condition->if_false()->AsBlock()->End(), false);
      }
    }
  } else if (const FunctionCallNode* func_call = root->AsFunctionCall()) {
    penalty += FunctionCall(func_call, at_end);
    at_end = "";
  } else if (const IdentifierNode* identifier = root->AsIdentifier()) {
    Print(identifier->value().value());
  } else if (const ListNode* list = root->AsList()) {
    Sequence(kSequenceStyleList, list->contents(), list->End(),
             /*force_multiline=*/false);
  } else if (const LiteralNode* literal = root->AsLiteral()) {
    Print(literal->value().value());
  } else if (const UnaryOpNode* unaryop = root->AsUnaryOp()) {
    Print(unaryop->op().value());
    Expr(unaryop->operand(), kPrecedenceUnary, std::string());
  } else if (const BlockCommentNode* block_comment = root->AsBlockComment()) {
    Print(block_comment->comment().value());
  } else if (const EndNode* end = root->AsEnd()) {
    Print(end->value().value());
  } else {
    CHECK(false) << "Unhandled case in Expr.";
  }

  // Defer any end of line comment until we reach the newline.
  if (root->comments() && !root->comments()->suffix().empty()) {
    std::copy(root->comments()->suffix().begin(),
              root->comments()->suffix().end(), std::back_inserter(comments_));
  }

  Print(at_end);

  penalty_depth_--;
  return penalty;
}

template <class PARSENODE>
void Printer::Sequence(SequenceStyle style,
                       const std::vector<std::unique_ptr<PARSENODE>>& list,
                       const ParseNode* end,
                       bool force_multiline) {
  if (style == kSequenceStyleList) {
    Print("[");
  } else if (style == kSequenceStyleBracedBlock) {
    Print("{");
  } else if (style == kSequenceStyleBracedBlockAlreadyOpen) {
    style = kSequenceStyleBracedBlock;
  }

  if (style == kSequenceStyleBracedBlock) {
    force_multiline = true;
    SortImports(const_cast<std::vector<std::unique_ptr<PARSENODE>>&>(list));
  }

  force_multiline |= ListWillBeMultiline(list, end);

  if (list.size() == 0 && !force_multiline) {
    // No elements, and not forcing newlines, print nothing.
  } else if (list.size() == 1 && !force_multiline) {
    Print(" ");
    Expr(list[0].get(), kPrecedenceLowest, std::string());
    CHECK(!list[0]->comments() || list[0]->comments()->after().empty());
    Print(" ");
  } else {
    stack_.push_back(IndentState(margin() + kIndentSize,
                                 style == kSequenceStyleList, false));
    size_t i = 0;
    for (const auto& x : list) {
      Newline();
      // If:
      // - we're going to output some comments, and;
      // - we haven't just started this multiline list, and;
      // - there isn't already a blank line here;
      // Then: insert one.
      if (i != 0 && x->comments() && !x->comments()->before().empty() &&
          !HaveBlankLine()) {
        Newline();
      }
      bool body_of_list = i < list.size() - 1 || style == kSequenceStyleList;
      bool want_comma =
          body_of_list && (style == kSequenceStyleList && !x->AsBlockComment());
      Expr(x.get(), kPrecedenceLowest, want_comma ? "," : std::string());
      CHECK(!x->comments() || x->comments()->after().empty());
      if (body_of_list) {
        if (i < list.size() - 1 &&
            ShouldAddBlankLineInBetween(list[i].get(), list[i + 1].get()))
          Newline();
      }
      ++i;
    }

    // Trailing comments.
    if (end->comments() && !end->comments()->before().empty()) {
      if (list.size() >= 2)
        Newline();
      for (const auto& c : end->comments()->before()) {
        Newline();
        TrimAndPrintToken(c);
      }
    }

    stack_.pop_back();
    Newline();
  }

  // Defer any end of line comment until we reach the newline.
  if (end->comments() && !end->comments()->suffix().empty()) {
    std::copy(end->comments()->suffix().begin(),
              end->comments()->suffix().end(), std::back_inserter(comments_));
  }

  if (style == kSequenceStyleList)
    Print("]");
  else if (style == kSequenceStyleBracedBlock)
    Print("}");
}

int Printer::FunctionCall(const FunctionCallNode* func_call,
                          const std::string& suffix) {
  int start_line = CurrentLine();
  int start_column = CurrentColumn();
  Print(func_call->function().value());
  Print("(");

  bool have_block = func_call->block() != nullptr;
  bool force_multiline = false;

  const auto& list = func_call->args()->contents();
  const ParseNode* end = func_call->args()->End();

  if (end->comments() && !end->comments()->before().empty())
    force_multiline = true;

  // If there's before line comments, make sure we have a place to put them.
  for (const auto& i : list) {
    if (i->comments() && !i->comments()->before().empty())
      force_multiline = true;
  }

  // Calculate the penalties for 3 possible layouts:
  // 1. all on same line;
  // 2. starting on same line, broken at each comma but paren aligned;
  // 3. broken to next line + 4, broken at each comma.
  std::string terminator = ")";
  if (have_block)
    terminator += " {";
  terminator += suffix;

  // Special case to make function calls of one arg taking a long list of
  // boolean operators not indent.
  bool continuation_requires_indent =
      list.size() != 1 || !list[0]->AsBinaryOp();

  // 1: Same line.
  Printer sub1;
  InitializeSub(&sub1);
  sub1.stack_.push_back(
      IndentState(CurrentColumn(), continuation_requires_indent, false));
  int penalty_one_line = 0;
  for (size_t i = 0; i < list.size(); ++i) {
    penalty_one_line += sub1.Expr(list[i].get(), kPrecedenceLowest,
                                  i < list.size() - 1 ? ", " : std::string());
  }
  sub1.Print(terminator);
  penalty_one_line += AssessPenalty(sub1.String());
  // This extra penalty prevents a short second argument from being squeezed in
  // after a first argument that went multiline (and instead preferring a
  // variant below).
  penalty_one_line +=
      (CountLines(sub1.String()) - 1) * kPenaltyBrokenLineOnOneLiner;

  // 2: Starting on same line, broken at commas.
  Printer sub2;
  InitializeSub(&sub2);
  sub2.stack_.push_back(
      IndentState(CurrentColumn(), continuation_requires_indent, false));
  int penalty_multiline_start_same_line = 0;
  for (size_t i = 0; i < list.size(); ++i) {
    penalty_multiline_start_same_line +=
        sub2.Expr(list[i].get(), kPrecedenceLowest,
                  i < list.size() - 1 ? "," : std::string());
    if (i < list.size() - 1) {
      sub2.Newline();
    }
  }
  sub2.Print(terminator);
  penalty_multiline_start_same_line += AssessPenalty(sub2.String());

  // 3: Starting on next line, broken at commas.
  Printer sub3;
  InitializeSub(&sub3);
  sub3.stack_.push_back(IndentState(margin() + kIndentSize * 2,
                                    continuation_requires_indent, false));
  sub3.Newline();
  int penalty_multiline_start_next_line = 0;
  for (size_t i = 0; i < list.size(); ++i) {
    if (i == 0) {
      penalty_multiline_start_next_line +=
          std::abs(sub3.CurrentColumn() - start_column) *
          kPenaltyHorizontalSeparation;
    }
    penalty_multiline_start_next_line +=
        sub3.Expr(list[i].get(), kPrecedenceLowest,
                  i < list.size() - 1 ? "," : std::string());
    if (i < list.size() - 1) {
      sub3.Newline();
    }
  }
  sub3.Print(terminator);
  penalty_multiline_start_next_line += AssessPenalty(sub3.String());

  int penalty = penalty_multiline_start_next_line;
  bool fits_on_current_line = false;
  if (penalty_one_line < penalty_multiline_start_next_line ||
      penalty_multiline_start_same_line < penalty_multiline_start_next_line) {
    fits_on_current_line = true;
    penalty = penalty_one_line;
    if (penalty_multiline_start_same_line < penalty_one_line) {
      penalty = penalty_multiline_start_same_line;
      force_multiline = true;
    }
  } else {
    force_multiline = true;
  }

  if (list.size() == 0 && !force_multiline) {
    // No elements, and not forcing newlines, print nothing.
  } else {
    if (penalty_multiline_start_next_line < penalty_multiline_start_same_line) {
      stack_.push_back(IndentState(margin() + kIndentSize * 2,
                                   continuation_requires_indent, false));
      Newline();
    } else {
      stack_.push_back(
          IndentState(CurrentColumn(), continuation_requires_indent, false));
    }

    for (size_t i = 0; i < list.size(); ++i) {
      const auto& x = list[i];
      if (i > 0) {
        if (fits_on_current_line && !force_multiline)
          Print(" ");
        else
          Newline();
      }
      bool want_comma = i < list.size() - 1 && !x->AsBlockComment();
      Expr(x.get(), kPrecedenceLowest, want_comma ? "," : std::string());
      CHECK(!x->comments() || x->comments()->after().empty());
      if (i < list.size() - 1) {
        if (!want_comma)
          Newline();
      }
    }

    // Trailing comments.
    if (end->comments() && !end->comments()->before().empty()) {
      if (!list.empty())
        Newline();
      for (const auto& c : end->comments()->before()) {
        Newline();
        TrimAndPrintToken(c);
      }
      Newline();
    }
    stack_.pop_back();
  }

  // Defer any end of line comment until we reach the newline.
  if (end->comments() && !end->comments()->suffix().empty()) {
    std::copy(end->comments()->suffix().begin(),
              end->comments()->suffix().end(), std::back_inserter(comments_));
  }

  Print(")");
  Print(suffix);

  if (have_block) {
    Print(" ");
    Sequence(kSequenceStyleBracedBlock, func_call->block()->statements(),
             func_call->block()->End(), false);
  }
  return penalty + (CurrentLine() - start_line) * GetPenaltyForLineBreak();
}

void Printer::InitializeSub(Printer* sub) {
  sub->stack_ = stack_;
  sub->comments_ = comments_;
  sub->penalty_depth_ = penalty_depth_;
  sub->Print(std::string(CurrentColumn(), 'x'));
}

template <class PARSENODE>
bool Printer::ListWillBeMultiline(
    const std::vector<std::unique_ptr<PARSENODE>>& list,
    const ParseNode* end) {
  if (list.size() > 1)
    return true;

  if (end && end->comments() && !end->comments()->before().empty())
    return true;

  // If there's before or suffix line comments, make sure we have a place to put
  // them.
  for (const auto& i : list) {
    if (i->comments() && (!i->comments()->before().empty() ||
                          !i->comments()->suffix().empty())) {
      return true;
    }
  }

  // When a scope is used as a list entry, it's too complicated to go one a
  // single line (the block will always be formatted multiline itself).
  if (list.size() >= 1 && list[0]->AsBlock())
    return true;

  return false;
}

void DoFormat(const ParseNode* root,
              TreeDumpMode dump_tree,
              std::string* output,
              std::string* dump_output) {
  if (dump_tree == TreeDumpMode::kPlainText) {
    std::ostringstream os;
    RenderToText(root->GetJSONNode(), 0, os);
    *dump_output = os.str();
  } else if (dump_tree == TreeDumpMode::kJSON) {
    std::string os;
    base::JSONWriter::WriteWithOptions(
        root->GetJSONNode(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &os);
    *dump_output = os;
  }

  Printer pr;
  pr.Block(root);
  *output = pr.String();
}

}  // namespace

bool FormatJsonToString(const std::string& json, std::string* output) {
  base::JSONReader reader;
  std::unique_ptr<base::Value> json_root = reader.Read(json);
  std::unique_ptr<ParseNode> root = ParseNode::BuildFromJSON(*json_root);
  DoFormat(root.get(), TreeDumpMode::kInactive, output, nullptr);
  return true;
}

bool FormatStringToString(const std::string& input,
                          TreeDumpMode dump_tree,
                          std::string* output,
                          std::string* dump_output) {
  SourceFile source_file;
  InputFile file(source_file);
  file.SetContents(input);
  Err err;
  // Tokenize.
  std::vector<Token> tokens =
      Tokenizer::Tokenize(&file, &err, WhitespaceTransform::kInvalidToSpace);
  if (err.has_error()) {
    err.PrintToStdout();
    return false;
  }

  // Parse.
  std::unique_ptr<ParseNode> parse_node = Parser::Parse(tokens, &err);
  if (err.has_error()) {
    err.PrintToStdout();
    return false;
  }

  DoFormat(parse_node.get(), dump_tree, output, dump_output);
  return true;
}

int RunFormat(const std::vector<std::string>& args) {
#if defined(OS_WIN)
  // Set to binary mode to prevent converting newlines to \r\n.
  _setmode(_fileno(stdout), _O_BINARY);
  _setmode(_fileno(stderr), _O_BINARY);
#endif

  bool dry_run =
      base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDryRun);
  TreeDumpMode dump_tree = TreeDumpMode::kInactive;
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchDumpTree)) {
    std::string tree_type =
        base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            kSwitchDumpTree);
    if (tree_type == kSwitchTreeTypeJSON) {
      dump_tree = TreeDumpMode::kJSON;
    } else if (tree_type.empty() || tree_type == kSwitchTreeTypeText) {
      dump_tree = TreeDumpMode::kPlainText;
    } else {
      Err(Location(), tree_type +
                          " is an invalid value for --dump-tree. Specify "
                          "\"" +
                          kSwitchTreeTypeText + "\" or \"" +
                          kSwitchTreeTypeJSON + "\".\n")
          .PrintToStdout();
      return 1;
    }
  }
  bool from_stdin =
      base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchStdin);

  if (dry_run) {
    // --dry-run only works with an actual file to compare to.
    from_stdin = false;
  }

  bool quiet =
      base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kQuiet);

  if (from_stdin) {
    if (args.size() != 0) {
      Err(Location(), "Expecting no arguments when reading from stdin.\n")
          .PrintToStdout();
      return 1;
    }
    std::string input = ReadStdin();
    std::string output;
    std::string dump_output;
    if (!FormatStringToString(input, dump_tree, &output, &dump_output))
      return 1;
    printf("%s", dump_output.c_str());
    printf("%s", output.c_str());
    return 0;
  }

  if (args.size() == 0) {
    Err(Location(), "Expecting one or more arguments, see `gn help format`.\n")
        .PrintToStdout();
    return 1;
  }

  Setup setup;
  SourceDir source_dir =
      SourceDirForCurrentDirectory(setup.build_settings().root_path());

  if (base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchReadTree)) {
    std::string tree_type =
        base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            kSwitchReadTree);
    if (tree_type != kSwitchTreeTypeJSON) {
      Err(Location(), "Only json supported for read-tree.\n").PrintToStdout();
      return 1;
    }

    if (args.size() != 1) {
      Err(Location(),
          "Expect exactly one .gn when reading tree from json on stdin.\n")
          .PrintToStdout();
      return 1;
    }
    Err err;
    SourceFile file =
        source_dir.ResolveRelativeFile(Value(nullptr, args[0]), &err);
    if (err.has_error()) {
      err.PrintToStdout();
      return 1;
    }
    base::FilePath to_format = setup.build_settings().GetFullPath(file);
    std::string output;
    FormatJsonToString(ReadStdin(), &output);
    if (base::WriteFile(to_format, output.data(),
                        static_cast<int>(output.size())) == -1) {
      Err(Location(), std::string("Failed to write output to \"") +
                          FilePathToUTF8(to_format) + std::string("\"."))
          .PrintToStdout();
      return 1;
    }
    if (!quiet) {
      printf("Wrote rebuilt from json to '%s'.\n",
             FilePathToUTF8(to_format).c_str());
    }
    return 0;
  }

  // TODO(scottmg): Eventually, this list of files should be processed in
  // parallel.
  int exit_code = 0;
  for (const auto& arg : args) {
    Err err;
    SourceFile file = source_dir.ResolveRelativeFile(Value(nullptr, arg), &err);
    if (err.has_error()) {
      err.PrintToStdout();
      exit_code = 1;
      continue;
    }

    base::FilePath to_format = setup.build_settings().GetFullPath(file);
    std::string original_contents;
    if (!base::ReadFileToString(to_format, &original_contents)) {
      Err(Location(),
          std::string("Couldn't read \"") + FilePathToUTF8(to_format))
          .PrintToStdout();
      exit_code = 1;
      continue;
    }

    std::string output_string;
    std::string dump_output_string;
    if (!FormatStringToString(original_contents, dump_tree, &output_string,
                              &dump_output_string)) {
      exit_code = 1;
      continue;
    }
    printf("%s", dump_output_string.c_str());
    if (dump_tree == TreeDumpMode::kInactive) {
      if (dry_run) {
        if (original_contents != output_string) {
          printf("%s\n", arg.c_str());
          exit_code = 2;
        }
        continue;
      }
      // Update the file in-place.
      if (original_contents != output_string) {
        if (base::WriteFile(to_format, output_string.data(),
                            static_cast<int>(output_string.size())) == -1) {
          Err(Location(),
              std::string("Failed to write formatted output back to \"") +
                  FilePathToUTF8(to_format) + std::string("\"."))
              .PrintToStdout();
          exit_code = 1;
          continue;
        }
        if (!quiet) {
          printf("Wrote formatted to '%s'.\n",
                 FilePathToUTF8(to_format).c_str());
        }
      }
    }
  }

  return exit_code;
}

}  // namespace commands
