#!/usr/bin/env python3

##===--- fix_includes.py - rewrite source files based on iwyu output ------===##
#
#                     The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##

from __future__ import print_function

"""Update files with the 'correct' #include and forward-declare lines.

Given the output of include_what_you_use on stdin -- when run at the
(default) --v=1 verbosity level or higher -- modify the files
mentioned in the output, removing their old #include lines and
replacing them with the lines given by the include_what_you_use
script.

This script runs in four stages.  In the first, it groups physical
lines together to form 'move spans'.  A 'move span' is the atomic unit
for moving or deleting code.  A move span is either a) an #include
line, along with any comment lines immediately preceding it; b) a
forward-declare line -- or more if it's a multi-line forward declare
-- along with preceding comments; c) any other single line.  Example:

   // I really am glad I'm forward-declaring this class!
   // If I didn't, I'd have to #include the entire world.
   template<typename A, typename B, typename C, typename D>
   class MyClass;

Then, it groups move spans together into 'reorder spans'.  These are
spans of code that consist entirely of #includes and forward-declares,
maybe separated by blank lines and comments.  We assume that we can
arbitrarily reorder #includes and forward-declares within a reorder
span, without affecting correctness.  Things like #ifdefs, #defines,
namespace declarations, static variable declarations, class
definitions, etc -- just about anything -- break up reorder spans.

In stage 3 it deletes all #include and forward-declare lines that iwyu
says to delete.  iwyu includes line numbers for deletion, making this
part easy.  If this step results in "empty" #ifdefs or namespaces
(#ifdefs or namespaces with no code inside them), we delete those as
well.  We recalculate the reorder spans, which may have gotten bigger
due to the deleted code.

In stage 4 it adds new iwyu-dictated #includes and forward-declares
after the last existing #includes and forward-declares.  Then it
reorders the #includes and forward-declares to match the order
specified by iwyu.  It follows iwyu's instructions as much as
possible, modulo the constraint that an #include or forward-declare
cannot leave its current reorder span.

All this moving messes up the blank lines, which we then need to fix
up.  Then we're done!
"""

__author__ = 'csilvers@google.com (Craig Silverstein)'

import difflib
import argparse
import os
import re
import sys
from collections import OrderedDict

_EPILOG = """\
Reads the output from include-what-you-use on stdin -- run with --v=1 (default)
verbosity level or above -- and, unless --sort_only or --dry_run is specified,
modifies the files mentioned in the output, removing their old #include lines
and replacing them with the lines given by include-what-you-use.  It also sorts
the #include and forward-declare lines.

All files mentioned in include-what-you-use output are modified, unless
filenames are specified on the commandline, in which case only those files are
modified.

The exit code is non-zero if a critical error occurs, otherwise zero.
"""

_COMMENT_RE = re.compile(r'\s*//.*')

# These are the types of lines a file can have.  These are matched
# using re.match(), so don't need a leading ^.
_C_COMMENT_START_RE = re.compile(r'\s*/\*')
_C_COMMENT_END_RE = re.compile(r'.*\*/\s*(.*)$')
_COMMENT_LINE_RE = re.compile(r'\s*//')
_PRAGMA_ONCE_LINE_RE = re.compile(r'\s*#\s*pragma\s+once')
_PRAGMA_PUSH_LINE_RE = re.compile(r'\s*#\s*pragma.*push.*')
_PRAGMA_POP_LINE_RE = re.compile(r'\s*#\s*pragma.*pop.*')
_BLANK_LINE_RE = re.compile(r'\s*$')
_IF_RE = re.compile(r'\s*#\s*if')               # compiles #if/ifdef/ifndef
_ELSE_RE = re.compile(r'\s*#\s*(else|elif)\b')  # compiles #else/elif
_ENDIF_RE = re.compile(r'\s*#\s*endif\b')
# This is used to delete 'empty' namespaces after fwd-decls are removed.
# Some third-party libraries use macros to start/end namespaces.
_NAMESPACE_START_RE = re.compile(r'\s*(namespace\b[^{]*{\s*)+(//.*)?$|'
                                 r'\s*(U_NAMESPACE_BEGIN)|'
                                 r'\s*(HASH_NAMESPACE_DECLARATION_START)')
# Also detect Allman and mixed style namespaces.  Use a continue regex for
# validation and to correctly set the line info.
_NAMESPACE_START_ALLMAN_RE = re.compile(r'\s*(namespace\b[^{=]*)+(//.*)?$')
_NAMESPACE_START_MIXED_RE = re.compile(
  r'\s*(namespace\b[^{]*{\s*)+(namespace\b[^{]*)+(//.*)?$')
_NAMESPACE_CONTINUE_ALLMAN_MIXED_RE = re.compile(r'\s*{\s*(//.*)?$')
_NAMESPACE_END_RE = re.compile(r'\s*(})|'
                               r'\s*(U_NAMESPACE_END)|'
                               r'\s*(HASH_NAMESPACE_DECLARATION_END)')
# The group (in parens) holds the unique 'key' identifying this #include.
_INCLUDE_RE = re.compile(r'\s*#\s*include\s+([<"][^">]+[>"])')
# We don't need this to actually match forward-declare lines (we get
# that information from the iwyu input), but we do need an RE here to
# serve as an index to _LINE_TYPES.  So we use an RE that never matches.
_FORWARD_DECLARE_RE = re.compile(r'$.FORWARD_DECLARE_RE')
# Likewise, used to mark an '#ifdef' line of a header guard, or other
# #ifdef that covers an entire file.
_HEADER_GUARD_RE = re.compile(r'$.HEADER_GUARD_RE')
# Marks the '#define' line that comes after a header guard.  Since we
# know the previous line was a header-guard line, we're not that picky
# about this one.
_HEADER_GUARD_DEFINE_RE = re.compile(r'\s*#\s*define\s+')
# Pragma to mark the associated header (for use when it cannot be deduced from
# the filename)
_IWYU_PRAGMA_ASSOCIATED_RE = re.compile(r'IWYU\s*pragma:\s*associated')

# We annotate every line in the source file by the re it matches, or None.
# Note that not all of the above RE's are represented here; for instance,
# we fold _C_COMMENT_START_RE and _C_COMMENT_END_RE into _COMMENT_LINE_RE.
# The _NAMESPACE_CONTINUE_ALLMAN_MIXED_RE is also set on lines when Allman
# and mixed namespaces are detected but the RE is too easy to match to add
# under normal circumstances (must always be preceded by Allman/mixed).
_LINE_TYPES = [_COMMENT_LINE_RE, _BLANK_LINE_RE,
               _NAMESPACE_START_RE, _NAMESPACE_START_ALLMAN_RE,
               _NAMESPACE_START_MIXED_RE, _NAMESPACE_END_RE,
               _IF_RE, _ELSE_RE, _ENDIF_RE,
               _INCLUDE_RE, _FORWARD_DECLARE_RE,
               _HEADER_GUARD_RE, _HEADER_GUARD_DEFINE_RE,
               _PRAGMA_ONCE_LINE_RE,
               _PRAGMA_PUSH_LINE_RE, _PRAGMA_POP_LINE_RE,
              ]

# A regexp matching #include lines that should be a barrier for
# sorting -- that is, we should never reorganize the code so an
# #include that used to come before this line now comes after, or vice
# versa.  This can be used for 'fragile' #includes that require other
# #includes to happen before them to function properly.
# (Note that the barrier has no effect on where new #includes are
# added; it just affects the reordering of existing #includes.)
_BARRIER_INCLUDES = re.compile(r'^\s*#\s*include\s+(<linux/)')

# A list of all known extensions for C++ source files, used to
# guess if a filename is a source file or a header.
# Please keep this in sync with source_extensions in iwyu_path_util.cc.
_SOURCE_EXTENSIONS = [".c", ".C", ".cc", ".CC", ".cxx", ".CXX",
                      ".cpp", ".CPP", ".c++", ".C++", ".cp"]


# Adapt Python 2 iterators to Python 3 syntax
if sys.version_info[0] < 3:
  def next(i):
    return i.next()


class OrderedSet(object):
  """ Sometimes sets affect order of outputs, which hinders testing. This
  (naive) set implementation preserves order to avoid that problem. """
  def __init__(self, iterable=None):
    iterable = iterable or []
    self.storage = OrderedDict((a, None) for a in iterable)

  def add(self, value):
    self.storage[value] = None

  def intersection_update(self, other):
    self.storage = OrderedDict(
        (k, None) for k in self.storage if k in other.storage)

  def update(self, other):
    self.storage.update(other.storage)

  def difference(self, other):
    diff_values = (v for v in self if v not in other)
    return OrderedSet(diff_values)

  def __iter__(self):
    return self.storage.keys().__iter__()

  def __contains__(self, value):
    return value in self.storage

  def __len__(self):
    return len(self.storage)


def _MayBeHeaderFile(filename):
  """Tries to figure out if filename is a C++ header file.  Defaults to yes."""
  # Header files have all sorts of extensions: .h, .hpp, .hxx, or no
  # extension at all.  So we say everything is a header file unless it
  # has a known extension that's not.
  extension = os.path.splitext(filename)[1]
  return extension not in _SOURCE_EXTENSIONS


class FixIncludesError(Exception):
  pass


class IWYUOutputRecord(object):
  """Information that the iwyu output file has about one source file."""

  def __init__(self, filename):
    self.filename = filename

    # A set of integers.
    self.lines_to_delete = set()

    # A set of integer line-numbers, for each #include iwyu saw that
    # is marked with a line number.  This is usually not an exhaustive
    # list of include-lines, but that's ok because we only use this
    # data structure for sanity checking: we double-check with our own
    # analysis that these lines are all # #include lines.  If not, we
    # know the iwyu data is likely out of date, and we complain.  So
    # more data here is always welcome, but not essential.
    self.some_include_lines = set()

    # A set of integer line-number spans [start_line, end_line), for
    # each forward-declare iwyu saw.  iwyu reports line numbers for
    # every forward-declare it sees in the source code.  (It won't
    # report, though, forward-declares inside '#if 0' or similar.)
    self.seen_forward_declare_lines = set()

    # Those spans which pertain to nested forward declarations (i.e. of nested
    # classes).  This set should be a subset of self.seen_forward_declare_lines.
    self.nested_forward_declare_lines = set()

    # A set of each line in the iwyu 'add' section.
    self.includes_and_forward_declares_to_add = OrderedSet()

    # A map from the include filename (including ""s or <>s) to the
    # full line as given by iwyu, which includes comments that iwyu
    # has put next to the #include.  This holds both 'to-add' and
    # 'to-keep' #includes.  If flags.comments is False, the comments
    # are removed before adding to this list.
    self.full_include_lines = OrderedDict()

  def Merge(self, other):
    """Merges other with this one.  They must share a filename.

    This function is intended to be used when we see two iwyu records
    in the input, both for the same file.  We can merge the two together.
    We are conservative: we union the lines to add, and intersect the
    lines to delete.

    Arguments:
      other: an IWYUOutputRecord to merge into this one.
        It must have the same value for filename that self does.
    """
    assert self.filename == other.filename, "Can't merge distinct files"
    self.lines_to_delete.intersection_update(other.lines_to_delete)
    self.some_include_lines.update(other.some_include_lines)
    self.seen_forward_declare_lines.update(other.seen_forward_declare_lines)
    self.nested_forward_declare_lines.update(other.nested_forward_declare_lines)
    self.includes_and_forward_declares_to_add.update(
        other.includes_and_forward_declares_to_add)
    self.full_include_lines.update(other.full_include_lines)

  def HasContentfulChanges(self):
    """Returns true iff this record has at least one add or delete."""
    return (self.includes_and_forward_declares_to_add or
            self.lines_to_delete)

  def __str__(self):
    return ('--- iwyu record ---\n  FILENAME: %s\n  LINES TO DELETE: %s\n'
            '  (SOME) INCLUDE LINES: %s\n  (SOME) FWD-DECL LINES: %s\n'
            '  TO ADD: %s\n  ALL INCLUDES: %s\n---\n'
            % (self.filename, self.lines_to_delete,
               self.some_include_lines, self.seen_forward_declare_lines,
               self.includes_and_forward_declares_to_add,
               self.full_include_lines))


class IWYUOutputParser(object):
  """Parses the lines in iwyu output corresponding to one source file."""

  # iwyu adds this comment to some lines to map them to the source file.
  _LINE_NUMBERS_COMMENT_RE = re.compile(r'\s*// lines ([0-9]+)-([0-9]+)')

  # The output of include-what-you-use has sections that indicate what
  # #includes and forward-declares should be added to the output file,
  # what should be removed, and what the end result is.  The first line
  # of each section also has the filename.
  _ADD_SECTION_RE = re.compile(r'^(.*) should add these lines:$')
  _REMOVE_SECTION_RE = re.compile(r'^(.*) should remove these lines:$')
  _TOTAL_SECTION_RE = re.compile(r'^The full include-list for (.*):$')
  _SECTION_END_RE = re.compile(r'^---$')

  # Alternately, if a file does not need any iwyu modifications (though
  # it still may need its #includes sorted), iwyu will emit this:
  _NO_EDITS_RE = re.compile(r'^\((.*) has correct #includes/fwd-decls\)$')

  _RE_TO_NAME = {_ADD_SECTION_RE: 'add',
                 _REMOVE_SECTION_RE: 'remove',
                 _TOTAL_SECTION_RE: 'total',
                 _SECTION_END_RE: 'end',
                 _NO_EDITS_RE: 'no_edits',
                }
  # A small state-transition machine.  key==None indicates the start
  # state.  value==None means that the key is an end state (that is,
  # its presence indicates the record is finished).
  _EXPECTED_NEXT_RE = {
      None:               frozenset([_ADD_SECTION_RE, _NO_EDITS_RE]),
      _ADD_SECTION_RE:    frozenset([_REMOVE_SECTION_RE]),
      _REMOVE_SECTION_RE: frozenset([_TOTAL_SECTION_RE]),
      _TOTAL_SECTION_RE:  frozenset([_SECTION_END_RE]),
      _SECTION_END_RE:    None,
      _NO_EDITS_RE:       None,
  }

  def __init__(self):
    # This is set to one of the 'section' REs above.  None is the start-state.
    self.current_section = None
    self.filename = '<unknown file>'
    self.lines_by_section = {}     # key is an RE, value is a list of lines

  def _ProcessOneLine(self, line, basedir=None):
    """Reads one line of input, updates self, and returns False at EORecord.

    If the line matches one of the hard-coded section names, updates
    self.filename and self.current_section.  Otherwise, the line is
    taken to be a member of the currently active section, and is added
    to self.lines_by_section.

    Arguments:
      line: one line from the iwyu input file.

    Returns:
      False if the line is the end-of-section marker, True otherwise.

    Raises:
      FixIncludesError: if there is an out-of-order section or
      mismatched filename.
    """
    line = line.rstrip()     # don't worry about line endings
    if not line:             # just ignore blank lines
      return True

    for (section_re, section_name) in self._RE_TO_NAME.items():
      m = section_re.search(line)
      if m:
        # Check or set the filename (if the re has a group, it's for filename).
        if section_re.groups >= 1:
          this_filename = NormalizeFilePath(basedir, m.group(1))

          if (self.current_section is not None and
              this_filename != self.filename):
            raise FixIncludesError('"%s" section for %s comes after "%s" for %s'
                                   % (section_name, this_filename,
                                      self._RE_TO_NAME[self.current_section],
                                      self.filename))
          self.filename = this_filename

        # Check and set the new section we're entering.
        if section_re not in self._EXPECTED_NEXT_RE[self.current_section]:
          if self.current_section is None:
            raise FixIncludesError('%s: "%s" section unexpectedly comes first'
                                   % (self.filename, section_name))
          else:
            raise FixIncludesError('%s: "%s" section unexpectedly follows "%s"'
                                   % (self.filename, section_name,
                                      self._RE_TO_NAME[self.current_section]))
        self.current_section = section_re
        # We're done parsing this record if this section has nothing after it.
        return self._EXPECTED_NEXT_RE[self.current_section] is not None

    # We're not starting a new section, so just add to the current section.
    # We ignore lines before section-start, they're probably things like
    # compiler messages ("Compiling file foo").
    if self.current_section is not None:
      self.lines_by_section.setdefault(self.current_section, []).append(line)
    return True

  def ParseOneRecord(self, iwyu_output, flags):
    """Given a file object with output from an iwyu run, return per file info.

    For each source file that iwyu_output mentions (because iwyu was run on
    it), we return a structure holding the information in IWYUOutputRecord:
    1) What file these changes apply to
    2) What line numbers hold includes/fwd-declares to remove
    3) What includes/fwd-declares to add
    4) Ordering information for includes and fwd-declares

    Arguments:
      iwyu_output: a File object returning lines from an iwyu run
      flags: commandline flags, as parsed by argparse.  We use
         flags.comments, which controls whether we output comments
         generated by iwyu.
    Returns:
       An IWYUOutputRecord object, or None at EOF.

    Raises:
       FixIncludesError: for malformed-looking lines in the iwyu output.
    """
    for line in iwyu_output:
      if not self._ProcessOneLine(line, flags.basedir):
        # returns False at end-of-record
        break
    else:                                  # for/else
      return None                          # at EOF

    # Now set up all the fields in an IWYUOutputRecord.
    # IWYUOutputRecord.filename
    retval = IWYUOutputRecord(self.filename)

    # IWYUOutputRecord.lines_to_delete
    for line in self.lines_by_section.get(self._REMOVE_SECTION_RE, []):
      m = self._LINE_NUMBERS_COMMENT_RE.search(line)
      if not m:
        raise FixIncludesError('line "%s" (for %s) has no line number'
                               % (line, self.filename))
      # The RE is of the form [start_line, end_line], inclusive.
      for line_number in range(int(m.group(1)), int(m.group(2)) + 1):
        retval.lines_to_delete.add(line_number)

    # IWYUOutputRecord.some_include_lines
    for line in (self.lines_by_section.get(self._REMOVE_SECTION_RE, []) +
                 self.lines_by_section.get(self._TOTAL_SECTION_RE, [])):
      if not _INCLUDE_RE.match(line):
        continue
      m = self._LINE_NUMBERS_COMMENT_RE.search(line)
      if not m:
        continue   # not all #include lines have line numbers, but some do
      for line_number in range(int(m.group(1)), int(m.group(2)) + 1):
        retval.some_include_lines.add(line_number)

    # IWYUOutputRecord.seen_forward_declare_lines
    for line in (self.lines_by_section.get(self._REMOVE_SECTION_RE, []) +
                 self.lines_by_section.get(self._TOTAL_SECTION_RE, [])):
      # Everything that's not an #include is a forward-declare.
      if line.startswith('- '):    # the 'remove' lines all start with '- '.
        line = line[len('- '):]
      if _INCLUDE_RE.match(line):
        continue
      m = self._LINE_NUMBERS_COMMENT_RE.search(line)
      if m:
        line_range = (int(m.group(1)), int(m.group(2))+1)
        retval.seen_forward_declare_lines.add(line_range)
        if '::' in line:
            retval.nested_forward_declare_lines.add(line_range)

    # IWYUOutputRecord.includes_and_forward_declares_to_add
    for line in self.lines_by_section.get(self._ADD_SECTION_RE, []):
      line = _COMMENT_RE.sub('', line)
      retval.includes_and_forward_declares_to_add.add(line)

    # IWYUOutputRecord.full_include_lines
    for line in self.lines_by_section.get(self._TOTAL_SECTION_RE, []):
      m = _INCLUDE_RE.match(line)
      if m:
        if not flags.comments:
          line = _COMMENT_RE.sub('', line)  # pretend there were no comments
        else:
          # Just remove '// line XX': that's iwyu metadata, not a real comment
          line = self._LINE_NUMBERS_COMMENT_RE.sub('', line)
        retval.full_include_lines[m.group(1)] = line

    return retval


class LineInfo(object):
  """Information about a single line of a source file."""

  def __init__(self, line):
    """Initializes the content of the line, but no ancillary fields."""
    # The content of the line in the input file
    self.line = line

    # The 'type' of the line.  The 'type' is one of the regular
    # expression objects in _LINE_TYPES, or None for any line that
    # does not match any regular expression in _LINE_TYPES.
    self.type = None

    # True if no lines processed before this one have the same type
    # as this line.
    self.is_first_line_of_this_type = False

    # Set to true if we want to delete/ignore this line in the output
    # (for instance, because iwyu says to delete this line).  At the
    # start, the only line to delete is the 'dummy' line 0.
    self.deleted = self.line is None

    # If this line is an #include or a forward-declare, gives a
    # [begin,end) pair saying the 'span' this line is part of.  We do
    # this for two types of span: the move span (an #include or
    # forward declare, along with any preceding comments) and the
    # reorder span (a continguous block of move-spans, connected only
    # by blank lines and comments).  For lines that are not an
    # #include or forward-declare, these may have an arbitrary value.
    self.move_span = None
    self.reorder_span = None

    # If this line is an #include or a forward-declare, gives the
    # 'key' of the line.  For #includes it is the filename included,
    # including the ""s or <>s.  For a forward-declare it's the name
    # of the class/struct.  For other types of lines, this is None.
    self.key = None

    # If this is a forward-declaration of a nested class, then this will be
    # True.
    self.is_nested_forward_declaration = False

  def __str__(self):
    if self.deleted:
      line = 'XX-%s-XX' % self.line
    else:
      line = '>>>%s<<<' % self.line
    if self.type is None:
      type_id = None
    else:
      type_id = _LINE_TYPES.index(self.type)
    return ('%s\n  -- type: %s (key: %s).  move_span: %s.  reorder_span: %s'
            % (line, type_id, self.key, self.move_span, self.reorder_span))


class FileInfo(object):
  """ Details about a file's storage encoding  """
  DEFAULT_LINESEP = os.linesep
  DEFAULT_ENCODING = 'utf-8'

  def __init__(self, linesep, encoding):
    self.linesep = linesep
    self.encoding = encoding

  @staticmethod
  def parse(filename):
    """ Return a FileInfo object describing file encoding details. """
    with open(filename, 'rb') as f:
      content = f.read()

    linesep = FileInfo.guess_linesep(content)
    encoding = FileInfo.guess_encoding(content)
    return FileInfo(linesep, encoding)

  @staticmethod
  def guess_linesep(bytebuf):
    """ Return most frequent line separator of buffer. """
    win = bytebuf.count(b'\r\n')
    unix = bytebuf.count(b'\n') - win
    if win > unix:
      return '\r\n'
    elif unix > win:
      return '\n'

    return FileInfo.DEFAULT_LINESEP

  @staticmethod
  def guess_encoding(bytebuf):
    """ Return approximate encoding for buffer.

    This is heavily heuristic, and will return any supported encoding that can
    describe the file without losing information, not necessarily the *right*
    encoding. This is usually OK, because IWYU typically only adds ASCII content
    (or content pulled from the file itself).
    """
    def try_decode(buf, encoding):
      try:
        buf.decode(encoding, errors='strict')
      except UnicodeError:
        return False
      return True

    # Special-case UTF-8 BOM
    if bytebuf[0:3] == b'\xef\xbb\xbf':
      if try_decode(bytebuf, 'utf-8-sig'):
        return 'utf-8-sig'

    encodings = ['ascii', 'utf-8', 'windows-1250', 'windows-1252']
    for encoding in encodings:
      if try_decode(bytebuf, encoding):
        return encoding

    return FileInfo.DEFAULT_ENCODING


def _ReadFile(filename, fileinfo):
  """Read from filename and return a list of file lines."""
  try:
    with open(filename, 'rb') as f:
      content = f.read()
      # Call splitlines with True to keep the original line
      # endings.  Later in WriteFile, they will be used as-is.
      # This will reduce spurious changes to the original files.
      # The lines we add will have the linesep determined by
      # FileInfo.
      return content.decode(fileinfo.encoding).splitlines(True)
  except (IOError, OSError) as why:
    print("Skipping '%s': %s" % (filename, why))
  return None


def _WriteFile(filename, fileinfo, file_lines):
  """Write the given file-lines to the file."""
  try:
    with open(filename, 'wb') as f:
      # file_lines already have line endings, so join with ''.
      content = ''.join(file_lines)
      content = content.encode(fileinfo.encoding)
      f.write(content)
  except (IOError, OSError) as why:
    print("Error writing '%s': %s" % (filename, why))


def PrintFileDiff(old_file_contents, new_file_contents):
  """Print a unified diff between files, specified as lists of lines."""
  diff = difflib.unified_diff(old_file_contents, new_file_contents)
  # skip the '--- <filename>/+++ <filename>' lines at the start
  try:
    next(diff)
    next(diff)
    print('\n'.join(l.rstrip() for l in diff))
  except StopIteration:
    pass


def _MarkHeaderGuardIfPresent(file_lines):
  """If any line in file_lines is a header-guard, mark it in file_lines.

  We define a header-guard as follows: an #ifdef where there is
  nothing contentful before or after the #ifdef.  Also, the #ifdef
  should have no #elif in it (though we don't currently test that).
  This catches the common case of an 'ifdef guard' in .h file, such
  as '#ifndef FOO_H\n#define FOO_H\n...contents...\n#endif', but it
  can also catch other whole-program #ifdefs, such as
  '#ifdef __linux\n...\n#endif'.  The issue here is that if an #ifdef
  encloses the entire file, then we are willing to put new
  #includes/fwd-declares inside the #ifdef (which normally we
  wouldn't do).  So we want to mark such #ifdefs with a special label.

  If we find such an #ifdef line -- and a single file can have at most
  one -- we change its type to a special type for header guards.

  Arguments:
    file_lines: an array of LineInfo objects with .type filled in.
  """
  # Pass over blank lines, pragmas and comments at the top of the file.
  i = 0
  for i in range(len(file_lines)):
    if (not file_lines[i].deleted and
        file_lines[i].type not in [_COMMENT_LINE_RE, _BLANK_LINE_RE,
                                   _PRAGMA_ONCE_LINE_RE]):
      break
  else:     # for/else: got to EOF without finding any non-blank/comment lines
    return

  # This next line is the candidate header guard-line.
  ifdef_start = i
  if file_lines[ifdef_start].type != _IF_RE:
    # Not a header guard, just return without doing anything.
    return

  # Find the end of this ifdef, to see if it's really a header guard..
  ifdef_depth = 0
  for ifdef_end in range(ifdef_start, len(file_lines)):
    if file_lines[ifdef_end].deleted:
      continue
    if file_lines[ifdef_end].type == _IF_RE:
      ifdef_depth += 1
    elif file_lines[ifdef_end].type == _ENDIF_RE:
      ifdef_depth -= 1
      if ifdef_depth == 0:   # The end of our #ifdef!
        break
  else:                      # for/else
    return False             # Weird: never found a close to this #ifdef

  # Finally, all the lines after the end of the ifdef must be blank or comments.
  for i in range(ifdef_end + 1, len(file_lines)):
    if (not file_lines[i].deleted and
        file_lines[i].type not in [_COMMENT_LINE_RE, _BLANK_LINE_RE]):
      return

  # We passed the gauntlet!
  file_lines[ifdef_start].type = _HEADER_GUARD_RE

  # And the line after the header guard #ifdef is the '#define' (usually).
  if _HEADER_GUARD_DEFINE_RE.match(file_lines[ifdef_start + 1].line):
    file_lines[ifdef_start+1].type = _HEADER_GUARD_DEFINE_RE


def _CalculateLineTypesAndKeys(file_lines, iwyu_record):
  """Fills file_line's type and key fields, where the 'type' is a regexp object.

  We match each line (line_info.line) against every regexp in
  _LINE_TYPES, and assign the first that matches, or None if none
  does.  We also use iwyu_record's some_include_lines and
  seen_forward_declare_lines to identify those lines.  In fact,
  that's the only data source we use for forward-declare lines.

  Sets file_line.type and file_line.is_first_line_of_this_type for
  each file_line in file_lines.

  Arguments:
    file_lines: an array of LineInfo objects with .line fields filled in.
    iwyu_record: the IWYUOutputRecord struct for this source file.

  Raises:
    FixIncludesError: if iwyu_record's line-number information is
      is inconsistent with what we see in the file.  (For instance,
      it says line 12 is an #include, but we say it's a blank line,
      or the file only has 11 lines.)
  """
  seen_types = set()
  in_c_style_comment = False
  in_allman_or_mixed_namespace = False
  for line_info in file_lines:
    if line_info.line is None:
      line_info.type = None
    elif _C_COMMENT_START_RE.match(line_info.line):
      # Note: _C_COMMENT_START_RE only matches a comment at the start
      # of a line.  Comments in the middle of a line are ignored.
      # This can cause problems with multi-line comments that start
      # in the middle of the line, but that's hopefully quite rare.
      # TODO(csilvers): check for that case.
      m = _C_COMMENT_END_RE.match(line_info.line)
      if not m:             # comment continues onto future lines
        line_info.type = _COMMENT_LINE_RE
        in_c_style_comment = True
      elif not m.group(1):  # comment extends across entire line (only)
        line_info.type = _COMMENT_LINE_RE
      else:                 # comment takes only part of line, treat as content
        # TODO(csilvers): this mis-diagnoses lines like '/*comment*/class Foo;'
        line_info.type = None
    elif in_c_style_comment and _C_COMMENT_END_RE.match(line_info.line):
      line_info.type = _COMMENT_LINE_RE
      in_c_style_comment = False
    elif in_c_style_comment:
      line_info.type = _COMMENT_LINE_RE
    elif (in_allman_or_mixed_namespace and
          _NAMESPACE_CONTINUE_ALLMAN_MIXED_RE.match(line_info.line)):
      in_allman_or_mixed_namespace = False
      line_info.type = _NAMESPACE_CONTINUE_ALLMAN_MIXED_RE
    else:
      for type_re in _LINE_TYPES:
        # header-guard-define-re has a two-part decision criterion: it
        # matches the RE, *and* it comes after a header guard line.
        # That's too complex to figure out now, so we skip over it now
        # and fix it up later in _MarkHeaderGuardIfPresent().
        if type_re in (_HEADER_GUARD_DEFINE_RE,):
          continue
        m = type_re.match(line_info.line)
        if m:
          line_info.type = type_re
          if type_re == _INCLUDE_RE:
            line_info.key = m.group(1)   # get the 'key' for the #include.
          elif type_re in (_NAMESPACE_START_ALLMAN_RE,
                           _NAMESPACE_START_MIXED_RE):
            # set in_allman_or_mixed_namespace to true to find the next {
            in_allman_or_mixed_namespace = True
          break
      else:    # for/else
        line_info.type = None   # means we didn't match any re

    line_info.is_first_line_of_this_type = (line_info.type not in seen_types)
    seen_types.add(line_info.type)

  # Now double-check against iwyu that we got all the #include lines right.
  for line_number in iwyu_record.some_include_lines:
    if file_lines[line_number].type != _INCLUDE_RE:
      raise FixIncludesError('iwyu line number %s:%d (%s) is not an #include'
                             % (iwyu_record.filename, line_number,
                                file_lines[line_number].line))

  # We depend entirely on the iwyu_record for the forward-declare lines.
  for (start_line, end_line) in iwyu_record.seen_forward_declare_lines:
    for line_number in range(start_line, end_line):
      if line_number >= len(file_lines):
        raise FixIncludesError('iwyu line number %s:%d is past file-end'
                               % (iwyu_record.filename, line_number))
      file_lines[line_number].type = _FORWARD_DECLARE_RE

  for (start_line, end_line) in iwyu_record.nested_forward_declare_lines:
    for line_number in range(start_line, end_line):
      if line_number >= len(file_lines):
        raise FixIncludesError('iwyu line number %s:%d is past file-end'
                               % (iwyu_record.filename, line_number))
      file_lines[line_number].is_nested_forward_declaration = True

  # While we're at it, let's do a bit more sanity checking on iwyu_record.
  for line_number in iwyu_record.lines_to_delete:
    if line_number >= len(file_lines):
      raise FixIncludesError('iwyu line number %s:%d is past file-end'
                             % (iwyu_record.filename, line_number))
    elif file_lines[line_number].type not in (_INCLUDE_RE,
                                              _FORWARD_DECLARE_RE):
      raise FixIncludesError('iwyu line number %s:%d (%s) is not'
                             ' an #include or forward declare'
                             % (iwyu_record.filename, line_number,
                                file_lines[line_number].line))

  # Check if this file has a header guard, which for our purposes is
  # an #ifdef (or #if) that covers an entire source file.  Usually
  # this will be a standard .h header-guard, but it could be something
  # like '#if __linux/#endif'.  The point here is that if an #ifdef
  # encloses the entire file, then we are willing to put new
  # #includes/fwd-declares inside the #ifdef (which normally we
  # wouldn't do).  So we mark such #ifdefs with a special label.
  _MarkHeaderGuardIfPresent(file_lines)


def _PreviousNondeletedLine(file_lines, line_number):
  """Returns the line number of the previous not-deleted line, or None."""
  for line_number in range(line_number - 1, -1, -1):
    if not file_lines[line_number].deleted:
      return line_number
  return None


def _NextNondeletedLine(file_lines, line_number):
  """Returns the line number of the next not-deleted line, or None."""
  for line_number in range(line_number + 1, len(file_lines)):
    if not file_lines[line_number].deleted:
      return line_number
  return None


def _LineNumberStartingPrecedingComments(file_lines, line_number):
  """Returns the line-number for the comment-lines preceding the given linenum.

  Looking at file_lines, look at the lines immediately preceding the
  given line-number.  If they're comment lines, return the first line
  of the comment lines preceding the given line.  Otherwise, return
  the given line number.

  As a special case, if the comments go all the way up to the first
  line of the file (line 1), we assume they're comment lines, which
  are special -- they're not associated with any source code line --
  and we return line_number in that case.

  Arguments:
    file_lines: an array of LineInfo objects, with .type fields filled in.
    line_number: an index into file_lines.

  Returns:
    The first line number of the preceding comments, or line_number
      if there are no preceding comments or they appear to be a
      top-of-file copyright notice.
  """
  retval = line_number
  while retval > 0 and file_lines[retval - 1].type == _COMMENT_LINE_RE:
    retval -= 1
  if retval <= 1:          # top-of-line comments
    retval = line_number   # so ignore all the comment lines
  return retval


def _CalculateMoveSpans(file_lines, forward_declare_spans):
  """Fills each input_line's move_span field.

  A 'move span' is a range of lines (from file_lines) that includes
  an #include or forward-declare, and all the comments preceding it.
  It is the unit we would move if we decided to move (or delete) this
  #include or forward-declare.

  For lines of type _INCLUDE_RE or _FORWARD_DECLARE_RE, the move span
  is set to the tuple [start_of_span, end_of_span).  All other lines
  have the move span kept at None.

  Arguments:
    file_lines: an array of LineInfo objects, with .type fields filled in.
    forward_declare_spans: a set of line-number pairs
       [start_line, end_line), each representing a single namespace.
       In practice this comes from iwyu_record.seen_forward_declare_lines.
  """
  # First let's do #includes.
  for line_number in range(len(file_lines)):
    if file_lines[line_number].type == _INCLUDE_RE:
      span_begin = _LineNumberStartingPrecedingComments(file_lines, line_number)
      for i in range(span_begin, line_number + 1):
        file_lines[i].move_span = (span_begin, line_number + 1)

  # Now forward-declares.  These spans come as input to this function.
  for (span_begin, span_end) in forward_declare_spans:
    span_begin = _LineNumberStartingPrecedingComments(file_lines, span_begin)
    for i in range(span_begin, span_end):
      file_lines[i].move_span = (span_begin, span_end)


def _ContainsBarrierInclude(file_lines, line_range):
  """Returns true iff some line in [line_range[0], line_range[1]) is BARRIER."""
  for line_number in range(*line_range):
    if (not file_lines[line_number].deleted and
        _BARRIER_INCLUDES.search(file_lines[line_number].line)):
      return True
  return False


def _LinesAreAllBlank(file_lines, start_line, end_line):
  """Returns true iff all lines in [start_line, end_line) are blank/deleted."""
  for line_number in range(start_line, end_line):
    if (not file_lines[line_number].deleted and
        file_lines[line_number].type != _BLANK_LINE_RE):
      return False
  return True


def _CalculateReorderSpans(file_lines):
  """Fills each input_line's reorder_span field.

  A 'reorder span' is a range of lines (from file_lines) that only has
  #includes and forward-declares in it (and maybe blank lines, and
  comments associated with #includes or forward-declares).  In
  particular, it does not include any "real code" besides #includes
  and forward-declares: no functions, no static variable assignment,
  no macro #defines, no nothing.  We are willing to reorder #includes
  and namespaces freely inside a reorder span.

  Calculating reorder_span is easy: they're just the union of
  contiguous move-spans (with perhaps blank lines and comments
  thrown in), because move-spans share the 'no actual code'
  requirement.

  There's one exception: if any move-span matches the
  _BARRIER_INCLUDES regexp, it means that we should consider that
  move-span to be a 'barrier': nothing should get reordered from one
  side of that move-span to the other.  (This is used for #includes
  that depend on other #includes being before them to function
  properly.)  We do that by putting them into their own reorder span.

  For lines of type _INCLUDE_RE or _FORWARD_DECLARE_RE, the reorder
  span is set to the tuple [start_of_span, end_of_span).  All other
  lines have an arbitrary value for the reorder span.

  Arguments:
    file_lines: an array of LineInfo objects with .type and .move_span
       fields filled in.
  """
  # Happily, move_spans are disjoint. Just make sure they're sorted and unique.
  move_spans = [s.move_span for s in file_lines if s.move_span is not None]
  sorted_move_spans = sorted(set(move_spans))

  i = 0
  while i < len(sorted_move_spans):
    reorder_span_start = sorted_move_spans[i][0]

    # If we're a 'nosort' include, we're always in a reorder span of
    # our own.  Otherwise, add in the next move span if we're
    # connected to it only by blank lines.
    if not _ContainsBarrierInclude(file_lines, sorted_move_spans[i]):
      while i < len(sorted_move_spans) - 1:
        move_span_end = sorted_move_spans[i][1]
        next_move_span_start = sorted_move_spans[i+1][0]
        if (_LinesAreAllBlank(file_lines, move_span_end, next_move_span_start)
            and not _ContainsBarrierInclude(file_lines, sorted_move_spans[i+1])):
          i += 1
        else:
          break
    reorder_span_end = sorted_move_spans[i][1]
    # We'll map every line in the span to the span-extent.
    for line_number in range(reorder_span_start, reorder_span_end):
      file_lines[line_number].reorder_span = (reorder_span_start,
                                              reorder_span_end)
    i += 1


def ParseOneFile(f, iwyu_record):
  """Given a file object, read and classify the lines of the file.

  For each file that iwyu_output mentions, we return a list of LineInfo
  objects, which is a parsed version of each line, including not only
  its content but its 'type', its 'key', etc.

  Arguments:
    f: an iterable object returning lines from a file.
    iwyu_record: the IWYUOutputRecord struct for this source file.

  Returns:
     An array of LineInfo objects.  The first element is always a dummy
     element, so the first line of the file is at retval[1], matching
     the way iwyu counts line numbers.
  """
  file_lines = [LineInfo(None)]
  for line in f:
    file_lines.append(LineInfo(line))
  _CalculateLineTypesAndKeys(file_lines, iwyu_record)
  _CalculateMoveSpans(file_lines, iwyu_record.seen_forward_declare_lines)
  _CalculateReorderSpans(file_lines)
  return file_lines


def _DeleteEmptyNamespaces(file_lines):
  """Delete namespaces with nothing in them.

  Empty namespaces could be caused by transformations that removed
  forward-declarations:
        namespace foo {
        class Myclass;
        }
     ->
        namespace foo {
        }
  We want to get rid of the 'empty' namespace in this case.

  This routine 'deletes' lines by setting their 'deleted' field to True.

  Arguments:
    file_lines: an array of LineInfo objects with .type fields filled in.

  Returns:
    The number of namespaces deleted.
  """
  num_namespaces_deleted = 0
  start_line = 0
  while start_line < len(file_lines):
    line_info = file_lines[start_line]
    if (line_info.deleted or
        (line_info.type != _NAMESPACE_START_RE and
         line_info.type != _NAMESPACE_START_ALLMAN_RE and
         line_info.type != _NAMESPACE_START_MIXED_RE)):
      start_line += 1
      continue
    if line_info.type in (_NAMESPACE_START_RE, _NAMESPACE_START_MIXED_RE):
      # Because multiple namespaces can be on one line
      # ("namespace foo { namespace bar { ..."), we need to count.
      # We use the max because line may have 0 '{'s if it's a macro.
      # TODO(csilvers): ignore { in comments.
      namespace_depth = max(line_info.line.count('{'), 1)
    elif line_info.type == _NAMESPACE_START_ALLMAN_RE:
      # For Allman namespaces, keep the start line and increment
      # the namespace depths when the actual brace is encountered.
      namespace_depth = 0
    else:
      # We should have handled all the namespace styles above!
      assert False, ('unknown namespace type',
                     _LINE_TYPES.index(line_info.type))
    end_line = start_line + 1
    while end_line < len(file_lines):
      line_info = file_lines[end_line]
      if line_info.deleted:
        end_line += 1
      elif line_info.type in (_COMMENT_LINE_RE, _BLANK_LINE_RE):
        end_line += 1                # ignore blank lines
      elif line_info.type == _NAMESPACE_CONTINUE_ALLMAN_MIXED_RE:
        namespace_depth += 1
        end_line += 1
      elif line_info.type in (_NAMESPACE_START_RE, _NAMESPACE_START_MIXED_RE):
        # nested namespace
        namespace_depth += max(line_info.line.count('{'), 1)
        end_line += 1
      elif line_info.type == _NAMESPACE_START_ALLMAN_RE:
        # nested Allman namespace
        end_line += 1
      elif line_info.type == _NAMESPACE_END_RE:
        namespace_depth -= max(line_info.line.count('}'), 1)
        end_line += 1
        if namespace_depth <= 0:
          # Delete any comments preceding this namespace as well.
          start_line = _LineNumberStartingPrecedingComments(file_lines,
                                                            start_line)
          # And also blank lines.
          while (start_line > 0 and
                 file_lines[start_line-1].type == _BLANK_LINE_RE):
            start_line -= 1
          for line_number in range(start_line, end_line):
            file_lines[line_number].deleted = True
          num_namespaces_deleted += 1
          break
      else:   # bail: we're at a line indicating this isn't an empty namespace
        end_line = start_line + 1  # rewind to try again with nested namespaces
        break
    start_line = end_line

  return num_namespaces_deleted


def _DeleteEmptyIfdefs(file_lines):
  """Deletes ifdefs with nothing in them.

  This could be caused by transformations that removed #includes:
        #ifdef OS_WINDOWS
        # include <windows.h>
        #endif
     ->
        #ifdef OS_WINDOWS
        #endif
  We want to get rid of the 'empty' #ifdef in this case.
  We also handle 'empty' #ifdefs with #else, if both sides of
  the #else are empty.  We also handle #ifndef and #if.

  This routine 'deletes' lines by replacing their content with None.

  Arguments:
    file_lines: an array of LineInfo objects with .type fields filled in.

  Returns:
    The number of ifdefs deleted.
  """
  num_ifdefs_deleted = 0
  start_line = 0
  while start_line < len(file_lines):
    if file_lines[start_line].type not in (_IF_RE, _HEADER_GUARD_RE):
      start_line += 1
      continue
    end_line = start_line + 1
    while end_line < len(file_lines):
      line_info = file_lines[end_line]
      if line_info.deleted:
        end_line += 1
      elif line_info.type in (_ELSE_RE, _COMMENT_LINE_RE, _BLANK_LINE_RE):
        end_line += 1                # ignore blank lines
      elif line_info.type == _ENDIF_RE:
        end_line += 1
        # Delete any comments preceding this #ifdef as well.
        start_line = _LineNumberStartingPrecedingComments(file_lines,
                                                          start_line)
        # And also blank lines.
        while (start_line > 0 and
               file_lines[start_line-1].type == _BLANK_LINE_RE):
          start_line -= 1
        for line_number in range(start_line, end_line):
          file_lines[line_number].deleted = True
        num_ifdefs_deleted += 1
        break
      else:   # bail: we're at a line indicating this isn't an empty ifdef
        end_line = start_line + 1  # rewind to try again with nested #ifdefs
        break
    start_line = end_line

  return num_ifdefs_deleted


def _DeleteDuplicateLines(file_lines, line_ranges):
  """Goes through all lines in line_ranges, and if any are dups, deletes them.

  For all lines in line_ranges, if any is the same as a previously
  seen line, set its deleted bit to True.  The purpose of line_ranges
  is to avoid lines in #ifdefs and namespaces, that may be identical
  syntactically but have different semantics.  Ideally, line_ranges
  should include only 'top-level' lines.

  We ignore lines that consist only of comments (or are blank).  We
  ignore end-of-line comments when comparing lines for equality.
  NOTE: Because our comment-finding RE is primitive, it's best if
  line_ranges covers only #include and forward-declare lines.  In
  particular, it should not cover lines that may have C literal
  strings in them.

  We only delete whole move_spans, not lines within them.

  Arguments:
    file_lines: an array of LineInfo objects.
    line_ranges: a list of [start_line, end_line) pairs.
  """
  seen_lines = set()
  for line_range in line_ranges:
    for line_number in range(*line_range):
      line_info = file_lines[line_number]
      if line_info.type in (_BLANK_LINE_RE, _COMMENT_LINE_RE):
        continue
      if line_number != line_info.move_span[0]:
        continue
      span_line_numbers = range(line_info.move_span[0], line_info.move_span[1])
      line_infos_in_span = [file_lines[i] for i in span_line_numbers]
      uncommented_lines = [
          _COMMENT_RE.sub('', inf.line.strip()) for inf in line_infos_in_span]
      uncommented_span = ' '.join(uncommented_lines)
      if uncommented_span in seen_lines:
        for info in line_infos_in_span:
          info.deleted = True
      elif not line_info.deleted:
        seen_lines.add(uncommented_span)


def _DeleteExtraneousBlankLines(file_lines, line_range):
  """Deletes extraneous blank lines caused by line deletion.

  Here's a example file:
     class Foo { ... };

     class Bar;

     class Baz { ... }

  If we delete the "class Bar;" line, we also want to delete one of
  the blank lines around it, otherwise we leave two blank lines
  between Foo and Baz which looks bad.  The idea is that if we have
  whitespace on both sides of a deleted span of code, the whitespace
  on one of the sides is 'extraneous'.  In this case, we should delete
  not only 'class Bar;' but also the whitespace line below it.  That
  leaves one blank line between Foo and Bar, like people would expect.

  We're careful to only delete the minimum of the number of blank
  lines that show up on either side.  If 'class Bar' had one blank
  line before it, and one hundred after it, we'd only delete one blank
  line when we delete 'class Bar'.  This matches user's expecatations.

  The situation can get tricky when two deleted spans touch (we might
  think it's safe to delete the whitespace between them when it's
  not).  To be safe, we only do this check when an entire reorder-span
  has been deleted.  So we check the given line_range, and only do
  blank-line deletion if every line in the range is deleted.

  Arguments:
    file_lines: an array of LineInfo objects, with .type filled in.
    line_range: a range [start_line, end_line).  It should correspond
       to a reorder-span.
  """
  # First make sure the entire span is deleted.
  for line_number in range(*line_range):
    if not file_lines[line_number].deleted:
      return

  before_line = _PreviousNondeletedLine(file_lines, line_range[0])
  after_line = _NextNondeletedLine(file_lines, line_range[1] - 1)
  while (before_line and file_lines[before_line].type == _BLANK_LINE_RE and
         after_line and file_lines[after_line].type == _BLANK_LINE_RE):
    # OK, we've got whitespace on both sides of a deleted span.  We
    # only want to keep whitespace on one side, so delete on the other.
    file_lines[after_line].deleted = True
    before_line = _PreviousNondeletedLine(file_lines, before_line)
    after_line = _NextNondeletedLine(file_lines, after_line)


def _ShouldInsertBlankLine(decorated_move_span, next_decorated_move_span,
                           file_lines, flags):
  """Returns true iff we should insert a blank line between the two spans.

  Given two decorated move-spans, of the form
     (reorder_range, kind, noncomment_lines, all_lines)
  returns true if we should insert a blank line between them.  We
  always put a blank line when transitioning from an #include to a
  forward-declare and back.  When the appropriate commandline flag is
  set, we also put a blank line between the 'main' includes (foo.h)
  and the C/C++ system includes, and another between the system
  includes and the rest of the Google includes.

  If the two move spans are in different reorder_ranges, that means
  the first move_span is at the end of a reorder range.  In that case,
  a different rule for blank lines applies: if the next line is
  contentful (eg 'static int x = 5;'), or a namespace start, we want
  to insert a blank line to separate the move-span from the next
  block.  When figuring out if the next line is contentful, we skip
  over comments.

  Arguments:
    decorated_move_span: a decorated_move_span we may want to put a blank
       line after.
    next_decorated_move_span: the next decorated_move_span, which may
       be a sentinel decorated_move_span at end-of-file.
    file_lines: an array of LineInfo objects with .deleted filled in.
    flags: commandline flags, as parsed by argparse.  We use
       flags.blank_lines, which controls whether we put blank
       lines between different 'kinds' of #includes.

  Returns:
     true if we should insert a blank line after decorated_move_span.
  """
  # First handle the 'at the end of a reorder range' case.
  if decorated_move_span[0] != next_decorated_move_span[0]:
    next_line = _NextNondeletedLine(file_lines, decorated_move_span[0][1] - 1)
    # Skip over comments to figure out if the next line is contentful.
    while (next_line and next_line < len(file_lines) and
           file_lines[next_line].type == _COMMENT_LINE_RE):
      next_line += 1
    return (next_line and next_line < len(file_lines) and
            file_lines[next_line].type in (_NAMESPACE_START_RE,
                                           _NAMESPACE_START_ALLMAN_RE,
                                           _NAMESPACE_START_MIXED_RE,
                                           _PRAGMA_PUSH_LINE_RE,
                                           None))

  # We never insert a blank line between two spans of the same kind.
  # Nor do we ever insert a blank line at EOF.
  (this_kind, next_kind) = (decorated_move_span[1], next_decorated_move_span[1])
  if this_kind == next_kind or next_kind == _EOF_KIND:
    return False

  # We also never insert a blank line between C and C++-style #includes,
  # no matter what the flag value.
  if (this_kind in [_C_SYSTEM_INCLUDE_KIND, _CXX_SYSTEM_INCLUDE_KIND] and
      next_kind in [_C_SYSTEM_INCLUDE_KIND, _CXX_SYSTEM_INCLUDE_KIND]):
    return False

  # Handle the case we're going from an include to fwd declare or
  # back.  If we get here, we can't both be fwd-declares, so it
  # suffices to check if either of us is.
  if this_kind == _FORWARD_DECLARE_KIND or next_kind == _FORWARD_DECLARE_KIND:
    return True

  # Now, depending on the flag, we insert a blank line whenever the
  # kind changes (we handled the one case where a changing kind
  # doesn't introduce a blank line, above).
  if flags.blank_lines:
    return this_kind != next_kind

  return False


def _GetToplevelReorderSpans(file_lines):
  """Returns a sorted list of all reorder_spans not inside an
  #ifdef/namespace/class.

  This routine looks at all the reorder_spans in file_lines, ignores
  reorder spans inside #ifdefs and namespaces -- except for the 'header
  guard' ifdef that encapsulates an entire .h file -- and returns the
  rest in sorted order.

  Arguments:
    file_lines: an array of LineInfo objects with .type and
       .reorder_span filled in.

  Returns:
    A list of [start_line, end_line) reorder_spans.
  """
  in_ifdef = [False] * len(file_lines)   # lines inside an #if
  ifdef_depth = 0
  for line_number in range(len(file_lines)):
    line_info = file_lines[line_number]
    if line_info.deleted:
      continue
    if line_info.type == _IF_RE:  # does not cover the header-guard ifdef
      ifdef_depth += 1
    elif line_info.type == _ENDIF_RE:
      ifdef_depth -= 1
    if ifdef_depth > 0:
      in_ifdef[line_number] = True

  # Figuring out whether a } ends a namespace or some other languague
  # construct is hard, so as soon as we see any 'contentful' line
  # inside a namespace, we assume the entire rest of the file is in
  # the namespace.
  in_namespace = [False] * len(file_lines)
  namespace_depth = 0
  for line_number in range(len(file_lines)):
    line_info = file_lines[line_number]
    if line_info.deleted:
      continue
    if line_info.type in (_NAMESPACE_START_RE, _NAMESPACE_START_MIXED_RE):
      # The 'max' is because the namespace-re may be a macro.
      namespace_depth += max(line_info.line.count('{'), 1)
    elif line_info.type == _NAMESPACE_CONTINUE_ALLMAN_MIXED_RE:
      namespace_depth += 1
    elif line_info.type == _NAMESPACE_END_RE:
      namespace_depth -= max(line_info.line.count('}'), 1)
    if namespace_depth > 0:
      in_namespace[line_number] = True
      if line_info.type is None:
        for i in range(line_number, len(file_lines)):  # rest of file
          in_namespace[i] = True
        break

  reorder_spans = [fl.reorder_span for fl in file_lines if fl.reorder_span]
  reorder_spans = sorted(set(reorder_spans))
  good_reorder_spans = []
  for reorder_span in reorder_spans:
    for line_number in range(*reorder_span):
      if (in_ifdef[line_number] or in_namespace[line_number] or
          file_lines[line_number].is_nested_forward_declaration):
        break
    else:   # for/else
      good_reorder_spans.append(reorder_span)    # never in ifdef or namespace

  return good_reorder_spans


def _GetNamespaceLevelReorderSpans(file_lines):
  """Returns a list of reorder-spans inside namespaces, if it's easy to do.

  This routine is meant to handle the simple case where code consists
  of includes and forward-declares, and then a 'namespace
  my_namespace'.  We return the reorder spans of the inside-namespace
  forward-declares, which is a good place to insert new
  inside-namespace forward-declares (rather than putting these new
  forward-declares at the top level).

  So it goes through the top of the file, stopping at the first
  'contentful' line.  If that line has the form 'namespace <foo> {',
  it then continues until it finds a forward-declare line, or a
  non-namespace contentful line.  In the former case, it figures out
  the reorder-span this forward-declare line is part of, while in the
  latter case it creates a new reorder-span.  A list of these namespace
  reorder spans are returned so they can all be checked.  These elements
  are in the form (enclosing_namespace, reorder_span).

  Arguments:
    file_lines: an array of LineInfo objects with .type and
    .reorder_span filled in.

  Returns:
    [] if we could not find any namespace-level reorder-spans, or
    [(enclosing_namespace, reorder_span), ...], where enclosing_namespace
    is a string that looks like (for instance)
    'namespace ns1 { namespace ns2 {', and reorder-span is a
    [start_line, end_line) pair.
  """

  def _GetNamespaceNames(namespace_line):
    """Returns a list of namespace names given a namespace line.  Anonymous
    namespaces will return an empty string
    """
    namespace_re = re.compile(r'\s*namespace\b(.*)')
    namespaces = []
    namespace_line = namespace_line.split("/")[0] # remove C++ comments
    namespace_line = namespace_line.split("{") # extract all namespaces
    for namespace in namespace_line:
      m = namespace_re.match(namespace)
      if m:
        namespaces.append(m.group(1).strip())

    return namespaces

  namespace_reorder_spans = {}
  try:
    namespace_prefixes = []
    pending_namespace_prefix = ''
    ifdef_depth = 0

    for line_number, line_info in enumerate(file_lines):
      if line_info.deleted:
        continue

      # If we're an empty line, just ignore us.  Likewise with #include
      # lines, which aren't 'contentful' for our purposes, and the
      # header guard, which is (by definition) the only kind of #ifdef
      # that we can be inside and still considered at the "top level".
      if line_info.type in (_COMMENT_LINE_RE,
                            _BLANK_LINE_RE,
                            _INCLUDE_RE,
                            _HEADER_GUARD_RE,
                            _HEADER_GUARD_DEFINE_RE,
                            _PRAGMA_ONCE_LINE_RE):
        continue

      # If we're a 'contentful' line such as a (non-header-guard) #ifdef, add
      # to the ifdef depth.  If we encounter #endif, reduce the ifdef depth.
      # Only keep track of namespaces when ifdef depth is 0
      elif line_info.type == _IF_RE:
        ifdef_depth += 1

      elif line_info.type == _ELSE_RE:
        continue

      elif line_info.type == _ENDIF_RE:
        ifdef_depth -= 1

      elif ifdef_depth != 0:
        continue # skip lines until we're outside of an ifdef block

      # Build the simplified namespace dictionary.  When any new namespace is
      # encountered, add the namespace to the list using the next line to cover
      # namespaces without forward declarations.  When a forward declare is
      # found, update the dictionary using the existing namespace span that the
      # forward declare contains.  Once a contentful line (None) has been found
      # or any exception occurs, return the results that have been found.  Any
      # forward declare that wasn't able to have a proper namespace name found
      # will still propagate to the top of the file.
      elif line_info.type == _NAMESPACE_START_RE:
        for namespace in _GetNamespaceNames(line_info.line):
          if not namespace:
            namespace_prefixes.append('namespace {')
          else:
            namespace_prefixes.append('namespace %s {' % namespace)

        namespace_reorder_spans[' '.join(namespace_prefixes)] = (
          line_number+1, line_number+1)

      elif line_info.type == _NAMESPACE_START_ALLMAN_RE:
        pending_namespace_prefix = ''
        namespaces = _GetNamespaceNames(line_info.line)
        if len(namespaces) != 1:
          raise FixIncludesError('Allman namespace found containing multiple '
                                 'names: %s', line_info.line)
        for namespace in namespaces:
          if not namespace:
            pending_namespace_prefix += 'namespace'
          else:
            pending_namespace_prefix += 'namespace %s' % namespace

      elif line_info.type == _NAMESPACE_START_MIXED_RE:
        # For mixed namespace styles, we need to append normalized prefixes
        # using regular and Allman style.  Treat the first elements as
        # normal and only treat the final element as Allman.  By the
        # nature of mixed namespaces, there will always be more than
        # one namespace so it is okay to assume that _GetNamespaceNames
        # will always return multiple records.
        pending_namespace_prefix = ''
        namespaces = _GetNamespaceNames(line_info.line)
        for namespace in namespaces[:-1]:
          if not namespace:
            namespace_prefixes.append('namespace {')
          else:
            namespace_prefixes.append('namespace %s {' % namespace)

        if not namespaces[-1]:
          pending_namespace_prefix += 'namespace'
        else:
          pending_namespace_prefix += 'namespace %s' % namespaces[-1]

      elif line_info.type == _NAMESPACE_CONTINUE_ALLMAN_MIXED_RE:
        # Append to the simplified allman namespace.
        if pending_namespace_prefix == '':
          raise FixIncludesError('Namespace bracket found without an associated '
                                 'namespace name at line: %s', line_number)
        pending_namespace_prefix += ' {'
        namespace_prefixes.append(pending_namespace_prefix)
        namespace_reorder_spans[' '.join(namespace_prefixes)] = (
          line_number+1, line_number+1)

      elif line_info.type == _NAMESPACE_END_RE:
        # Remove C++ comments and count the ending brackets.
        namespace_end_count = line_info.line.split("/")[0].count("}")
        namespace_prefixes = namespace_prefixes[:-namespace_end_count]

      elif line_info.type == _FORWARD_DECLARE_RE:
        # If we're not in a namespace, keep going.  Otherwise, this is
        # just the situation we're looking for!  Update the dictionary
        # with the better reorder span
        if len(namespace_prefixes) > 0:
          namespace_reorder_spans[' '.join(namespace_prefixes)] = (
            line_info.reorder_span)

      elif line_info.type == None:
        break

      else:
        # We should have handled all the cases above!
        assert False, ('unknown line-info type',
                       _LINE_TYPES.index(line_info.type))
  except Exception as why:
    # Namespace detection could be tricky so take what we have and return.
    print('DEBUG: Namespace detection returned prematurely because of an '
          'exception: %s' % (why))
    pass

  # return a reverse sorted list so longest matches are checked first
  return sorted(namespace_reorder_spans.items(), reverse=True)


# These are potential 'kind' arguments to _FirstReorderSpanWith.
_MAIN_CU_INCLUDE_KIND = 1         # e.g. #include "foo.h" when editing foo.cc
_C_SYSTEM_INCLUDE_KIND = 2        # e.g. #include <stdio.h>
_CXX_SYSTEM_INCLUDE_KIND = 3      # e.g. #include <vector>
_NONSYSTEM_INCLUDE_KIND = 4       # e.g. #include "bar.h"
_PROJECT_INCLUDE_KIND = 5         # e.g. #include "myproject/quux.h"
_FORWARD_DECLARE_KIND = 6         # e.g. class Baz;
_EOF_KIND = 7                     # used at eof

# The span kinds are defined in default sort order, so generate a default
# identity mapping.
SORT_ORDER_DEFAULT = {
  kind: kind for kind in range(_MAIN_CU_INCLUDE_KIND, _EOF_KIND + 1)
}

# In quoted-first mode, we sort all quoted kinds before system kinds.
SORT_ORDER_QUOTED_FIRST = {
  _MAIN_CU_INCLUDE_KIND: 1,
  _NONSYSTEM_INCLUDE_KIND: 2,
  _PROJECT_INCLUDE_KIND: 3,
  _C_SYSTEM_INCLUDE_KIND: 4,
  _CXX_SYSTEM_INCLUDE_KIND: 5,
  _FORWARD_DECLARE_KIND: 6,
  _EOF_KIND: 7,
}

def _IsSystemInclude(line_info):
  """Given a line-info, return true iff the line is a <>-style #include."""
  # The key for #includes includes the <> or "", so this is easy. :-)
  return line_info.type == _INCLUDE_RE and line_info.key[0] == '<'


def _IsMainCUInclude(line_info, filename):
  """Given a line-info, return true iff the line is a 'main-CU' #include line.

  A 'main-CU' #include line is one that is related to the file being edited.
  For instance, if we are editing foo.cc, foo.h is a main-CU #include, as
  is foo-inl.h.  The same holds if we are editing foo_test.cc.

  The algorithm is like so: first, canonicalize the includee by removing the
  following suffixes:
     -inl.h  .h

  Then canonicalize the includer by removing file extension and then the
  following suffixes:
     _unittest  _regtest  _test

  Rule 1: If the canonical names (filenames after removal) match --
  including all directories -- the .h file is a main-cu #include.

  Rule 2: If the basenames of the canonnical names match -- that is,
  ignoring all directories -- the .h file is a main-cu #include *if*
  it is the first #include seen.

  Arguments:
    line_info: a LineInfo structure with .type,
       .is_first_line_of_this_type, and .key filled in.
    filename: the name of the file being edited.

  Returns:
    True if line_info is an #include of a main_CU file, False else.
  """
  if line_info.type != _INCLUDE_RE or _IsSystemInclude(line_info):
    return False
  if _IWYU_PRAGMA_ASSOCIATED_RE.search(line_info.line):
    return True
  # First, normalize the includee by getting rid of -inl.h and .h
  # suffixes (for the #include) and the "'s around the #include line.
  canonical_include = re.sub(r'(-inl\.h|\.h|\.hpp)$', '',
                             line_info.key.replace('"', ''), flags=re.I)
  # Then normalize includer by stripping extension and Google's test suffixes.
  canonical_file, _ = os.path.splitext(filename)
  canonical_file = re.sub(r'(_unittest|_regtest|_test)$', '', canonical_file)
  # .h files in /public/ match .cc files in /internal/.
  canonical_include2 = re.sub(r'/public/', '/internal/', canonical_include)

  # Rule 1:
  if canonical_file in (canonical_include, canonical_include2):
    return True
  # Rule 2:
  if (line_info.is_first_line_of_this_type and
      os.path.basename(canonical_file) == os.path.basename(canonical_include)):
    return True

  return False


def _GetPathRoot(path):
  """ Return the root of a path, i.e. the first path component.
  We allow / as an alternative path separator on Windows because it helps with
  testing and forward slashes are common even on Windows in portable codebases.
  """
  first_sep = path.find(os.path.sep)
  if os.path.sep != '/' and first_sep == -1:
    first_sep = path.find('/')

  if first_sep == -1:
    return None

  return path[0:first_sep]


def _IsSameProject(line_info, edited_file, project):
  """Return true if included file and edited file are in the same project.

  An included_file is in project 'project' if the project is a prefix of the
  included_file.  'project' should end with /.

  As a special case, if project is '<tld>', then the project is defined to
  be the top-level directory of edited_file.

  Arguments:
    line_info: a LineInfo structure with .key containing the file that is
      being included.
    edited_file: the name of the file being edited.
    project: if '<tld>', set the project path to be the top-level directory
      name of the file being edited.  If not '<tld>', this value is used to
      specify the project directory.

  Returns:
    True if line_info and filename belong in the same project, False otherwise.
  """
  included_file = line_info.key[1:]
  if project != '<tld>':
    return included_file.startswith(project)
  included_root = _GetPathRoot(included_file)
  edited_root = _GetPathRoot(edited_file)
  return (included_root and edited_root and included_root == edited_root)


def _GetLineKind(file_line, filename, separate_project_includes):
  """Given a file_line + file being edited, return best *_KIND value or None."""
  line_without_coments = _COMMENT_RE.sub('', file_line.line)
  if file_line.deleted:
    return None
  elif _IsMainCUInclude(file_line, filename):
    return _MAIN_CU_INCLUDE_KIND
  elif _IsSystemInclude(file_line) and '.' in line_without_coments:
    return _C_SYSTEM_INCLUDE_KIND
  elif _IsSystemInclude(file_line):
    return _CXX_SYSTEM_INCLUDE_KIND
  elif file_line.type == _INCLUDE_RE:
    if (separate_project_includes and
        _IsSameProject(file_line, filename, separate_project_includes)):
      return _PROJECT_INCLUDE_KIND
    return _NONSYSTEM_INCLUDE_KIND
  elif file_line.type == _FORWARD_DECLARE_RE:
    return _FORWARD_DECLARE_KIND
  else:
    return None


def _FirstReorderSpanWith(file_lines, good_reorder_spans, kind, filename,
                          flags):
  """Returns [start_line,end_line) of 1st reorder_span with a line of kind kind.

  This function iterates over all the reorder_spans in file_lines, and
  calculates the first one that has a line of the given kind in it.
  If no such reorder span is found, it takes the last span of 'lower'
  kinds (main-cu kind is lowest, forward-declare is highest).  If no
  such reorder span is found, it takes the first span of 'higher'
  kind, but not considering the forward-declare kind (we don't want to
  put an #include with the first forward-declare, because it may be
  inside a class or something weird).  If there's *still* no match, we
  return the first line past leading comments, whitespace, and #ifdef
  guard lines.  If there's *still* no match, we just insert at
  end-of-file.

  As a special case, we never return a span for forward-declares that is
  after 'contentful' code, even if other forward-declares are there.
  For instance:
     using Foo::Bar;
     class Bang;
  We want to make sure to put 'namespace Foo { class Bar; }'
  *before* the using line!

  kind is one of the following enums, with examples:
     _MAIN_CU_INCLUDE_KIND:    #include "foo.h" when editing foo.cc
     _C_SYSTEM_INCLUDE_KIND:   #include <stdio.h>
     _CXX_SYSTEM_INCLUDE_KIND: #include <vector>
     _NONSYSTEM_INCLUDE_KIND:  #include "bar.h"
     _PROJECT_INCLUDE_KIND:    #include "myproject/quux.h"
     _FORWARD_DECLARE_KIND:    class Baz;

  Arguments:
    file_lines: an array of LineInfo objects with .type and
       .reorder_span filled in.
    good_reorder_spans: a sorted list of reorder_spans to consider
       (should not include reorder_spans inside #ifdefs or
       namespaces).
    kind: one of *_KIND values.
    filename: the name of the file that file_lines comes from.
       This is passed to _GetLineKind (are we a main-CU #include?)
    flags: commandline flags, as parsed by argparse.  We use
       flags.separate_project_includes to sort the #includes for the
       current project separately from other #includes.

  Returns:
    A pair of line numbers, [start_line, end_line), that is the 'best'
    reorder_span in file_lines for the given kind.
  """
  assert kind in (_MAIN_CU_INCLUDE_KIND, _C_SYSTEM_INCLUDE_KIND,
                  _CXX_SYSTEM_INCLUDE_KIND, _NONSYSTEM_INCLUDE_KIND,
                  _PROJECT_INCLUDE_KIND, _FORWARD_DECLARE_KIND), kind
  # Figure out where the first 'contentful' line is (after the first
  # 'good' span, so we skip past header guards and the like).  Basically,
  # the first contentful line is a line not in any reorder span.
  for i in range(len(good_reorder_spans) - 1):
    if good_reorder_spans[i][1] != good_reorder_spans[i+1][0]:
      first_contentful_line = good_reorder_spans[i][1]
      break
  else:     # got to the end of the file without finding a break in the spans
    if good_reorder_spans:
      first_contentful_line = good_reorder_spans[-1][1]
    else:
      first_contentful_line = 0

  # Let's just find the first and last span for each kind.
  first_reorder_spans = {}
  last_reorder_spans = {}
  for reorder_span in good_reorder_spans:
    for line_number in range(*reorder_span):
      line_kind = _GetLineKind(file_lines[line_number], filename,
                               flags.separate_project_includes)
      # Ignore forward-declares that come after 'contentful' code; we
      # never want to insert new forward-declares there.
      if (line_kind == _FORWARD_DECLARE_KIND and
          line_number > first_contentful_line):
        continue
      if line_kind is not None:
        first_reorder_spans.setdefault(line_kind, reorder_span)
        last_reorder_spans[line_kind] = reorder_span

  # Find the first span of our kind.
  if kind in first_reorder_spans:
    return first_reorder_spans[kind]

  # Second choice: last span of the kinds above us:
  for backup_kind in range(kind - 1, _MAIN_CU_INCLUDE_KIND - 1, -1):
    if backup_kind in last_reorder_spans:
      return last_reorder_spans[backup_kind]

  # Third choice: first span of the kinds below us, but not counting
  # _FORWARD_DECLARE_KIND.
  for backup_kind in range(kind + 1, _FORWARD_DECLARE_KIND):
    if backup_kind in first_reorder_spans:
      return first_reorder_spans[backup_kind]

  # There are no reorder-spans at all, or they are only
  # _FORWARD_DECLARE spans.  Return the first line past the leading
  # comments, whitespace, and #ifdef guard lines, or the beginning
  # of the _FORWARD_DECLARE span, whichever is smaller.
  line_number = 0
  seen_header_guard = False
  while line_number < len(file_lines):
    if file_lines[line_number].deleted:
      line_number += 1
    elif file_lines[line_number].type == _HEADER_GUARD_RE:
      seen_header_guard = True
      line_number += 2    # skip over the header guard
    elif file_lines[line_number].type == _BLANK_LINE_RE:
      line_number += 1
    elif file_lines[line_number].type == _PRAGMA_ONCE_LINE_RE:
      seen_header_guard = True
      line_number += 1
    elif (file_lines[line_number].type == _COMMENT_LINE_RE
          and not seen_header_guard):
      # We put #includes after top-of-file comments.  But comments
      # inside the header guard are no longer top-of-file comments;
      # #includes go before them.
      line_number += 1
    else:
      # If the "first line" we would return is inside the forward-declare
      # reorder span, just return that span, rather than creating a new
      # span inside the existing one.
      if first_reorder_spans:
        assert list(first_reorder_spans.keys()) == [_FORWARD_DECLARE_KIND], \
            first_reorder_spans
        if line_number >= first_reorder_spans[_FORWARD_DECLARE_KIND][0]:
          return first_reorder_spans[_FORWARD_DECLARE_KIND]
      return (line_number, line_number)

  # OK, I guess just insert at the end of the file
  return (len(file_lines), len(file_lines))


def _RemoveNamespacePrefix(fwd_decl_iwyu_line, namespace_prefix):
  """Return a version of the input line with namespace_prefix removed, or None.

  If fwd_decl_iwyu_line is
     namespace ns1 { namespace ns2 { namespace ns3 { foo } } }
  and namespace_prefix = 'namespace ns1 { namespace ns2 {', then
  this function returns 'namespace ns3 { foo }'.  It removes the
  namespace_prefix, and any } }'s at the end of the line.  If line
  does not fit this form, then this function returns None.

  Arguments:
    line: a line from iwyu about a forward-declare line to add
    namespace_prefix: a non-empty string of the form
      namespace <ns1> { namespace <ns2> { [...]

  Returns:
    A version of the input line with the namespaces in namespace
    prefix removed, or None if this is not possible because the input
    line is not of the right form.
  """
  assert namespace_prefix, "_RemoveNamespaces requires a non-empty prefix"
  if not fwd_decl_iwyu_line.startswith(namespace_prefix):
    return None

  # Remove the prefix
  fwd_decl_iwyu_line = fwd_decl_iwyu_line[len(namespace_prefix):].lstrip()

  # Remove the matching trailing }'s, preserving comments.
  num_braces = namespace_prefix.count('{')
  ending_braces_re = re.compile(r'(\s*\}){%d}\s*$' % num_braces)
  m = ending_braces_re.search(fwd_decl_iwyu_line)
  if not m:
    return None
  fwd_decl_iwyu_line = fwd_decl_iwyu_line[:m.start(0)]

  return fwd_decl_iwyu_line


def _DecoratedMoveSpanLines(iwyu_record, file_lines, move_span_lines, flags):
  """Given a span of lines from file_lines, returns a "decorated" result.

  First, we construct the actual contents of the move-span, as a list
  of strings (one per line).  If we see an #include in the move_span,
  we replace its comments with the ones in iwyu_record, if present
  (iwyu_record will never have any comments if flags.comments is
  False).

  Second, we construct a string, of the 'contentful' part of the
  move_span -- that is, without the leading comments -- with
  whitespace removed, and a few other changes made.  This is used for
  sorting (we remove whitespace so '# include <foo>' compares properly
  against '#include <bar>').

  Third, we figure out the 'kind' of this span: system include,
  main-cu include, etc.

  We return all of these together in a tuple, along with the
  reorder-span this move span is inside.  We pick the best
  reorder-span if one isn't already present (because it's an
  #include we're adding in, for instance.)  This allows us to sort
  all the moveable content.

  Arguments:
    iwyu_record: the IWYUOutputRecord struct for this source file.
    file_lines: a list of LineInfo objects holding the parsed output of
      the file in iwyu_record.filename
    move_span_lines: A list of LineInfo objects.  For #includes and
      forward-declares already in the file, this will be a sub-list
      of file_lines.  For #includes and forward-declares we're adding
      in, it will be a newly created list.
    flags: commandline flags, as parsed by argparse.  We use
      flags.separate_project_includes to sort the #includes for the
      current project separately from other #includes.

  Returns:
    A tuple (reorder_span, kind, sort_key, all_lines_as_list)
    sort_key is the 'contentful' part of the move_span, which whitespace
      removed, and -inl.h changed to _inl.h (so it sorts later).
    all_lines_as_list is a list of strings, not of LineInfo objects.
    Returns None if the move-span has been deleted, or for some other
      reason lacks an #include or forward-declare line.
  """
  # Get to the first contentful line.
  for i in range(len(move_span_lines)):
    if (not move_span_lines[i].deleted and
        move_span_lines[i].type in (_INCLUDE_RE, _FORWARD_DECLARE_RE)):
      first_contentful_line = i
      break
  else:       # for/else
    # No include or forward-declare line seen, must be a deleted span.
    return None

  firstline = move_span_lines[first_contentful_line]
  m = _INCLUDE_RE.match(firstline.line)
  if m:
    # If we're an #include, the contentful lines are easy.  But we have
    # to do the comment-replacing first.
    sort_key = firstline.line
    iwyu_version = iwyu_record.full_include_lines.get(m.group(1), '')
    if _COMMENT_LINE_RE.search(iwyu_version):  # the iwyu version has comments
      sort_key = iwyu_version                  # replace the comments
    all_lines = ([li.line for li in move_span_lines[:-1] if not li.deleted] +
                 [sort_key])
  else:
    # We're a forward-declare.  Also easy.
    contentful_list = [li.line for li in move_span_lines[first_contentful_line:]
                       if not li.deleted]
    sort_key = ''.join(contentful_list)
    all_lines = [li.line for li in move_span_lines if not li.deleted]

  # Get rid of whitespace in the contentful_lines
  sort_key = re.sub(r'\s+', '', sort_key)
  # Replace -inl.h with _inl.h so foo-inl.h sorts after foo.h in #includes.
  sort_key = sort_key.replace('-inl.h', '_inl.h')

  # Next figure out the kind.
  kind = _GetLineKind(firstline, iwyu_record.filename,
                      flags.separate_project_includes)

  # All we're left to do is the reorder-span we're in.  Hopefully it's easy.
  reorder_span = firstline.reorder_span
  if reorder_span is None:     # must be a new #include we're adding
    # If we're a forward-declare inside a namespace, see if there's a
    # reorder span inside the same namespace we can fit into.
    if kind == _FORWARD_DECLARE_KIND:
      namespace_reorder_spans = _GetNamespaceLevelReorderSpans(file_lines)
      for namespace_prefix, possible_reorder_span in namespace_reorder_spans:
        if (namespace_prefix and possible_reorder_span and
            firstline.line.startswith(namespace_prefix)):
          # Great, we can go into this reorder_span.  We also need to
          # modify all-lines because this line doesn't need the
          # namespace prefix anymore.  Make sure we can do that before
          # succeeding.
          new_firstline = _RemoveNamespacePrefix(firstline.line, namespace_prefix)
          if new_firstline:
            assert all_lines[first_contentful_line] == firstline.line
            all_lines[first_contentful_line] = new_firstline
            sort_key = re.sub(r'\s+', '', new_firstline)
            reorder_span = possible_reorder_span
            break

    # If that didn't work out, find a top-level reorder span to go into.
    if reorder_span is None:
      # TODO(csilvers): could make this more efficient by storing, per-kind.
      toplevel_reorder_spans = _GetToplevelReorderSpans(file_lines)
      reorder_span = _FirstReorderSpanWith(file_lines, toplevel_reorder_spans,
                                           kind, iwyu_record.filename, flags)

  return (reorder_span, kind, sort_key, all_lines)


def _CommonPrefixLength(a, b):
  """Given two lists, returns the index of 1st element not common to both."""
  end = min(len(a), len(b))
  for i in range(end):
    if a[i] != b[i]:
      return i
  return end


def _NormalizeNamespaceForwardDeclareLines(lines):
  """'Normalize' namespace lines in a list of output lines and return new list.

  When suggesting new forward-declares to insert, iwyu uses the following
  format, putting each class on its own line with all namespaces:
     namespace foo { namespace bar { class A; } }
     namespace foo { namespace bar { class B; } }
     namespace foo { namespace bang { class C; } }
  We convert this to 'normalized' form, which puts namespaces on their
  own line and collects classes together:
     namespace foo {
     namespace bar {
     class A;
     class B;
     }  // namespace bar
     namespace bang {
     class C;
     }  // namespace bang
     }  // namespace foo

  Non-namespace lines are left alone.  Only adjacent namespace lines
  from the input are merged.

  Arguments:
    lines: a list of output-lines -- that is, lines that are ready to
       be emitted as-is to the output file.

  Returns:
    A new version of lines, with namespace lines normalized as above.
  """
  # iwyu input is very regular, which is nice.
  iwyu_namespace_re = re.compile(r'namespace ([^{]*) { ')
  iwyu_classname_re = re.compile(r'{ ([^{}]*) }')

  retval = []
  current_namespaces = []
  # We append a blank line so the final namespace-closing happens "organically".
  for line in lines + ['']:
    namespaces_in_line = iwyu_namespace_re.findall(line)
    differ_pos = _CommonPrefixLength(namespaces_in_line, current_namespaces)
    namespaces_to_close = reversed(current_namespaces[differ_pos:])
    namespaces_to_open = namespaces_in_line[differ_pos:]
    retval.extend('}  // namespace %s' % ns for ns in namespaces_to_close)
    retval.extend('namespace %s {' % ns for ns in namespaces_to_open)
    current_namespaces = namespaces_in_line
    # Now add the current line.  If we were a namespace line, it's the
    # 'class' part of the line (everything but the 'namespace {'s).
    if namespaces_in_line:
      m = iwyu_classname_re.search(line)
      if not m:
        raise FixIncludesError('Malformed namespace line from iwyu: %s', line)
      retval.append(m.group(1))
    else:
      retval.append(line)

  assert retval and retval[-1] == '', 'What happened to our sentinel line?'
  return retval[:-1]


def _DeleteLinesAccordingToIwyu(iwyu_record, file_lines):
  """Deletes all lines that iwyu_record tells us to, and cleans up after."""
  for line_number in iwyu_record.lines_to_delete:
    # Delete the entire move-span (us and our preceding comments).
    for i in range(*file_lines[line_number].move_span):
      file_lines[i].deleted = True

  while True:
    num_deletes = _DeleteEmptyNamespaces(file_lines)
    num_deletes += _DeleteEmptyIfdefs(file_lines)
    if num_deletes == 0:
      break

  # Also delete any duplicate lines in the input.  To avoid trouble
  # (accidentally deleting inside an #ifdef, for instance), we only
  # check 'top-level' #includes and forward-declares.
  toplevel_reorder_spans = _GetToplevelReorderSpans(file_lines)
  _DeleteDuplicateLines(file_lines, toplevel_reorder_spans)

  # If a whole reorder span was deleted, check if it has extra
  # whitespace on both sides that we could trim.  We've already
  # deleted extra blank lines inside #ifdefs and namespaces,
  # so looking at toplevel spans is enough.
  for reorder_span in toplevel_reorder_spans:
    _DeleteExtraneousBlankLines(file_lines, reorder_span)


def _GetSymbolNameFromForwardDeclareLine(line):
  """Given a forward declare line to add from iwyu output, get symbol.

  Two possibilities: In or not in namespace(s).
  If in namespaces, then return foo::bar::sym.
  Else just sym.
  """
  iwyu_namespace_re = re.compile(r'namespace ([^{]*) { ')
  symbolname_re = re.compile(r'([A-Za-z0-9_]+)')
  # Turn anonymous namespaces into their proper symbol representation.
  namespaces_in_line = iwyu_namespace_re.findall(line.replace(
    "namespace {", "namespace (anonymous namespace) {"))
  symbols_in_line = symbolname_re.findall(line)
  symbol_name = symbols_in_line[-1]
  if (namespaces_in_line):
    symbol_name = '::'.join(namespaces_in_line) + '::' + symbol_name
  return symbol_name


def GetLineSortOrdinal(kind, quoted_includes_first):
  if quoted_includes_first:
    return SORT_ORDER_QUOTED_FIRST[kind]
  else:
    return SORT_ORDER_DEFAULT[kind]


def FixFileLines(iwyu_record, file_lines, flags, fileinfo):
  """Applies one block of lines from the iwyu output script.

  Called once we have read all the lines from the iwyu output script
  pertaining to a single source file, and parsed them into an
  iwyu_record.  At that point we edit the source file, remove the old
  #includes and forward-declares, insert the #includes and
  forward-declares, and reorder the lot, all as specified by the iwyu
  output script.  The resulting source code lines are returned.

  Arguments:
    iwyu_record: an IWYUOutputRecord object holding the parsed output
      of the include-what-you-use script (run at verbose level 1 or
      higher) pertaining to a single source file.
    file_lines: a list of LineInfo objects holding the parsed output of
      the file in iwyu_record.filename
    flags: commandline flags, as parsed by argparse.  We use
       flags.safe_headers to turn off deleting lines, and use the
       other flags indirectly (via calls to other routines).
    fileinfo: FileInfo for the current file.

  Returns:
    An array of 'fixed' source code lines, after modifications as
    specified by iwyu.
  """
  # First delete the includes and forward-declares that we should delete.
  # This is easy since iwyu tells us the line numbers.
  if not (flags.safe_headers and _MayBeHeaderFile(iwyu_record.filename)):
    _DeleteLinesAccordingToIwyu(iwyu_record, file_lines)

  # With these deletions, we may be able to merge together some
  # reorder-spans.  Recalculate them to see.
  _CalculateReorderSpans(file_lines)

  # For every move-span in our file -- that's every #include and
  # forward-declare we saw -- 'decorate' the move-range to allow us
  # to sort them.
  move_spans = OrderedSet([fl.move_span for fl in file_lines if fl.move_span])
  decorated_move_spans = []
  for (start_line, end_line) in move_spans:
    decorated_span = _DecoratedMoveSpanLines(iwyu_record, file_lines,
                                             file_lines[start_line:end_line],
                                             flags)
    if decorated_span:
      decorated_move_spans.append(decorated_span)

  # Now let's add in a decorated move-span for all the new #includes
  # and forward-declares.
  symbol_names_seen = set()
  for line in iwyu_record.includes_and_forward_declares_to_add:
    line_info = LineInfo(line)
    m = _INCLUDE_RE.match(line)
    if m:
      line_info.type = _INCLUDE_RE
      line_info.key = m.group(1)
    else:
      # Avoid duplicates that can arise if different template args
      # were suggested by different iwyu analyses for this file.
      symbol_name = _GetSymbolNameFromForwardDeclareLine(line)
      if symbol_name in symbol_names_seen:
        continue
      symbol_names_seen.add(symbol_name)
      line_info.type = _FORWARD_DECLARE_RE
    decorated_span = _DecoratedMoveSpanLines(iwyu_record, file_lines,
                                             [line_info], flags)
    assert decorated_span, 'line to add is not an #include or fwd-decl?'
    decorated_move_spans.append(decorated_span)

  # Add a sentinel decorated move-span, to make life easy, and sort.
  decorated_move_spans.append(((len(file_lines), len(file_lines)),
                               _EOF_KIND, '', []))

  def key(decorated_span):
    reorder_span, kind, sort_key, all_lines = decorated_span
    kind_key = GetLineSortOrdinal(kind, flags.quoted_includes_first)
    if flags.reorder:
      return reorder_span, kind_key, sort_key, all_lines
    else:
      return reorder_span, kind_key

  decorated_move_spans.sort(key=key)

  # Now go through all the lines of the input file and construct the
  # output file.  Before we get to the next reorder-span, we just
  # copy lines over verbatim (ignoring deleted lines, of course).
  # In a reorder-span, we just print the sorted content, introducing
  # blank lines when appropriate.
  output_lines = []
  line_number = 0
  while line_number < len(file_lines):
    current_reorder_span = decorated_move_spans[0][0]

    # Just copy over all the lines until the next reorder span.
    while line_number < current_reorder_span[0]:
      if not file_lines[line_number].deleted:
        output_lines.append(file_lines[line_number].line)
      line_number += 1

    # Now fill in the contents of the reorder-span from decorated_move_spans
    new_lines = []
    while (decorated_move_spans and
           decorated_move_spans[0][0] == current_reorder_span):
      new_lines.extend(decorated_move_spans[0][3])   # the full content
      if (len(decorated_move_spans) > 1 and
          _ShouldInsertBlankLine(decorated_move_spans[0],
                                 decorated_move_spans[1], file_lines, flags)):
        new_lines.append('')
      decorated_move_spans = decorated_move_spans[1:]   # pop

    if not flags.keep_iwyu_namespace_format:
      # Now do the munging to convert namespace lines from the iwyu input
      # format to the 'official style' format:
      #    'namespace foo { class Bar; }\n' -> 'namespace foo {\nclass Bar;\n}'
      # along with collecting multiple classes in the same namespace.
      new_lines = _NormalizeNamespaceForwardDeclareLines(new_lines)

    # Add line separators to the new lines.
    new_lines = [nl.rstrip() + fileinfo.linesep for nl in new_lines]

    output_lines.extend(new_lines)
    line_number = current_reorder_span[1]               # go to end of span

  return [line for line in output_lines if line is not None]


def FixOneFile(iwyu_record, file_contents, flags, fileinfo):
  """Parse a file guided by an iwyu_record and flags and apply IWYU fixes.
  Returns two lists of lines (old, fixed).
  """
  file_lines = ParseOneFile(file_contents, iwyu_record)
  old_lines = [fl.line for fl in file_lines
               if fl is not None and fl.line is not None]
  fixed_lines = FixFileLines(iwyu_record, file_lines, flags, fileinfo)
  return old_lines, fixed_lines


def FixManyFiles(iwyu_records, flags):
  """Given a list of iwyu_records, fix each file listed in the record.

  For each iwyu record in the input, which lists the #includes and
  forward-declares to add, remove, and re-sort, loads the file, makes
  the fixes, and writes the fixed file to disk.  The flags affect the
  details of the fixing.

  Arguments:
    iwyu_records: a collection of IWYUOutputRecord objects holding
      the parsed output of the include-what-you-use script (run at
      verbose level 1 or higher) pertaining to a single source file.
      iwyu_record.filename indicates what file to edit.
    flags: commandline flags, as parsed by argparse..

  Returns:
    The number of files fixed (as opposed to ones that needed no fixing).
  """
  files_fixed = 0
  for iwyu_record in iwyu_records:
    try:
      fileinfo = FileInfo.parse(iwyu_record.filename)

      file_contents = _ReadFile(iwyu_record.filename, fileinfo)
      if not file_contents:
        continue

      print(">>> Fixing #includes in '%s'" % iwyu_record.filename)
      old_lines, fixed_lines = FixOneFile(iwyu_record, file_contents, flags, fileinfo)
      if old_lines == fixed_lines:
        print("No changes in file %s" % iwyu_record.filename)
        continue

      if flags.dry_run:
        PrintFileDiff(old_lines, fixed_lines)
      else:
        _WriteFile(iwyu_record.filename, fileinfo, fixed_lines)

      files_fixed += 1
    except FixIncludesError as why:
      print('ERROR: %s - skipping file %s' % (why, iwyu_record.filename))

  print('IWYU edited %d files on your behalf.\n' % files_fixed)
  return files_fixed


def ProcessIWYUOutput(f, files_to_process, flags, cwd):
  """Fix the #include and forward-declare lines as directed by f.

  Given a file object that has the output of the include_what_you_use
  script, see every file to be edited and edit it, if appropriate.

  Arguments:
    f: an iterable object that is the output of include_what_you_use.
    files_to_process: A set of filenames, or None.  If not None, we
       ignore files mentioned in f that are not in files_to_process.
    flags: commandline flags, as parsed by argparse.  The only flag
       we use directly is flags.ignore_re, to indicate files not to
       process; we also pass the flags to other routines.
    cwd: the current working directory, externalized for testing.

  Returns:
    The number of files that had to be modified (because they weren't
    already all correct).  In dry_run mode, returns the number of
    files that would have been modified.
  """
  if files_to_process is not None:
    files_to_process = [NormalizeFilePath(cwd, fname)
                        for fname in files_to_process]

  # First collect all the iwyu data from stdin.

  # Maintain sort order by using OrderedDict instead of dict
  iwyu_output_records = OrderedDict()  # IWYUOutputRecords keyed by filename
  while True:
    iwyu_output_parser = IWYUOutputParser()
    try:
      iwyu_record = iwyu_output_parser.ParseOneRecord(f, flags)
      if not iwyu_record:
        break
    except FixIncludesError as why:
      print('ERROR: %s' % why)
      continue
    filename = NormalizeFilePath(flags.basedir, iwyu_record.filename)
    if files_to_process is not None and filename not in files_to_process:
      print('(skipping %s: not listed on commandline)' % filename)
      continue
    if flags.ignore_re and re.search(flags.ignore_re, filename):
      print('(skipping %s: it matches --ignore_re, which is %s)' % (
          filename, flags.ignore_re))
      continue
    if flags.only_re and not re.search(flags.only_re, filename):
      print('(skipping %s: it does not match --only_re, which is %s)' % (
          filename, flags.only_re))
      continue

    if filename in iwyu_output_records:
      iwyu_output_records[filename].Merge(iwyu_record)
    else:
      iwyu_output_records[filename] = iwyu_record

  # Now ignore all the files that never had any contentful changes
  # seen for them.  (We have to wait until we're all done, since a .h
  # file may have a contentful change when #included from one .cc
  # file, but not another, and we need to have merged them above.)
  if not flags.update_comments:
    for filename in iwyu_output_records:
      if not iwyu_output_records[filename].HasContentfulChanges():
        print('(skipping %s: iwyu reports no contentful changes)' % filename)
        # Mark that we're skipping this file by setting the record to None
        iwyu_output_records[filename] = None

  # Now do all the fixing, and return the number of files modified
  contentful_records = [ior for ior in iwyu_output_records.values() if ior]
  return FixManyFiles(contentful_records, flags)


def NormalizeFilePath(basedir, filename):
  """ Normalize filename to be comparable.

  If basedir has a value and filename is not already absolute, make filename
  absolute. Otherwise return filename as-is.
  """
  if basedir and not os.path.isabs(filename):
    return os.path.normpath(os.path.join(basedir, filename))
  return filename


def SortIncludesInFiles(files_to_process, flags):
  """For each file in files_to_process, sort its #includes.

  This reads each input file, sorts the #include lines, and replaces
  the input file with the result. SortIncludesInFiles does not add
  or remove any #includes.  It also ignores forward-declares.

  Arguments:
    files_to_process: a list (or set) of filenames.
    flags: commandline flags, as parsed by argparse.  We do not use
       any flags directly, but pass them to other routines.

  Returns:
    The number of files that had to be modified (because they weren't
    already all correct, that is, already in sorted order).
  """
  sort_only_iwyu_records = []
  for filename in files_to_process:
    filename = NormalizeFilePath(flags.basedir, filename)
    # An empty iwyu record has no adds or deletes, so its only effect
    # is to cause us to sort the #include lines.  (Since fix_includes
    # gets all its knowledge of where forward-declare lines are from
    # the iwyu input, with an empty iwyu record it just ignores all
    # the forward-declare lines entirely.)
    sort_only_iwyu_records.append(IWYUOutputRecord(filename))
  return FixManyFiles(sort_only_iwyu_records, flags)


def main(argv):
  # Parse the command line.
  parser = argparse.ArgumentParser(
    formatter_class=argparse.RawDescriptionHelpFormatter,
    description='Update files based on include-what-you-use output',
    epilog=_EPILOG)
  parser.add_argument('-b', '--blank_lines', action='store_true', default=True,
                      help=('Put a blank line between primary header file and'
                            ' C/C++ system #includes, and another blank line'
                            ' between system #includes and google #includes'
                            ' [default]'))
  parser.add_argument('--noblank_lines', action='store_false',
                      dest='blank_lines')

  parser.add_argument('--comments', action='store_true', default=False,
                      help='Put comments after the #include lines')
  parser.add_argument('--nocomments', action='store_false', dest='comments')

  parser.add_argument('--update_comments', action='store_true', default=False,
                      help=('Replace \'why\' comments with the ones provided by'
                            ' IWYU'))
  parser.add_argument('--noupdate_comments', action='store_false',
                      dest='update_comments')

  parser.add_argument('--safe_headers', action='store_true', default=True,
                      help=('Do not remove unused #includes/fwd-declares from'
                            ' header files; just add new ones [default]'))
  parser.add_argument('--nosafe_headers', action='store_false',
                      dest='safe_headers')

  parser.add_argument('--reorder', action='store_true', default=False,
                      help=('Re-order lines relative to other similar lines '
                            '(e.g. headers relative to other headers)'))
  parser.add_argument('--noreorder', action='store_false', dest='reorder',
                      help=('Do not re-order lines relative to other similar '
                            'lines.'))

  parser.add_argument('-s', '--sort_only', action='store_true',
                      help=('Just sort #includes of files listed on cmdline;'
                            ' do not add or remove any #includes'))

  parser.add_argument('-n', '--dry_run', action='store_true', default=False,
                      help=('Do not actually edit any files; just print diffs.'
                            ' Return code is 0 if no changes are needed,'
                            ' else min(the number of files that would be'
                            ' modified, 100)'))

  parser.add_argument('--ignore_re', default=None,
                      help=('%(prog)s will skip editing any file whose name'
                            ' matches this regular expression.'))

  parser.add_argument('--only_re', default=None,
                      help=('%(prog)s will skip editing any file whose name'
                            ' does not match this regular expression.'))

  parser.add_argument('--separate_project_includes', default=None,
                      help=('Sort #includes for current project separately'
                            ' from all other #includes.  This flag specifies'
                            ' the root directory of the current project.'
                            ' If the value is "<tld>", #includes that share the'
                            ' same top-level directory are assumed to be in the'
                            ' same project. If not specified, project #includes'
                            ' will be sorted with other non-system #includes.'))

  parser.add_argument('-m', '--keep_iwyu_namespace_format', action='store_true',
                      default=False,
                      help=('Keep forward-declaration namespaces in IWYU format'
                            ', eg. namespace n1 { namespace n2 { class c1; } }.'
                            ' Do not convert to "normalized" Google format: '
                            'namespace n1 {\\nnamespace n2 {\\n class c1;'
                            '\\n}\\n}.'))
  parser.add_argument('--nokeep_iwyu_namespace_format', action='store_false',
                      dest='keep_iwyu_namespace_format')

  parser.add_argument('--basedir', '-p', default=None,
                      help=('Specify the base directory. fix_includes will '
                            'interpret non-absolute filenames relative to this '
                            'path.'))
  parser.add_argument('--quoted_includes_first', action='store_true',
                      default=False,
                      help='When sorting includes, place quoted ones first')

  parser.add_argument('files', nargs='*', metavar='FILES')

  flags = parser.parse_args(argv[1:])
  if flags.files:
    files_to_modify = set(flags.files)
  else:
    files_to_modify = None

  if (flags.separate_project_includes and
      not flags.separate_project_includes.startswith('<') and  # 'special' vals
      not flags.separate_project_includes.endswith(os.path.sep) and
      not flags.separate_project_includes.endswith('/')):
    flags.separate_project_includes += os.path.sep

  if flags.update_comments:
    flags.comments = True

  if flags.sort_only:
    if not files_to_modify:
      sys.exit('FATAL ERROR: -s flag requires a list of filenames')
    SortIncludesInFiles(files_to_modify, flags)
  else:
    ProcessIWYUOutput(sys.stdin, files_to_modify, flags, cwd=os.getcwd())

  return 0


if __name__ == '__main__':
  sys.exit(main(sys.argv))
