#!/usr/bin/env python
# Copyright 2002 Google Inc. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Flagvalues module - Registry of 'Flag' objects.

Instead of importing this module directly, it's preferable to import the
flags package and use the aliases defined at the package level.
"""

import hashlib
import logging
import os
import struct
import sys
import traceback
import warnings
from xml.dom import minidom

import six

from gflags import _helpers
from gflags import exceptions
from gflags import flag as _flag

# Add flagvalues module to disclaimed module ids.
_helpers.disclaim_module_ids.add(id(sys.modules[__name__]))

# The MOE directives in this file cause the docstring indentation
# linter to go nuts.
# pylint: disable=g-doc-bad-indent

# Environment variable that controls whether to allow unparsed flag access.
# Do not rely on, it will be removed later.
_UNPARSED_FLAG_ACCESS_ENV_NAME = 'GFLAGS_ALLOW_UNPARSED_FLAG_ACCESS'

# Percentage of the flag names for which unparsed flag access will fail by
# default.
_UNPARSED_ACCESS_DISABLED_PERCENT = 0

# b/32278439 will change flag parsing to use GNU-style scanning by default.
# This environment variable allows users to force setting the default parsing
# style. Do NOT rely on it. It will be removed as part of b/32278439.
_USE_GNU_GET_OPT_ENV_NAME = 'GFLAGS_USE_GNU_GET_OPT'




class FlagValues(object):
  """Registry of 'Flag' objects.

  A 'FlagValues' can then scan command line arguments, passing flag
  arguments through to the 'Flag' objects that it owns.  It also
  provides easy access to the flag values.  Typically only one
  'FlagValues' object is needed by an application: gflags.FLAGS

  This class is heavily overloaded:

  'Flag' objects are registered via __setitem__:
       FLAGS['longname'] = x   # register a new flag

  The .value attribute of the registered 'Flag' objects can be accessed
  as attributes of this 'FlagValues' object, through __getattr__.  Both
  the long and short name of the original 'Flag' objects can be used to
  access its value:
       FLAGS.longname          # parsed flag value
       FLAGS.x                 # parsed flag value (short name)

  Command line arguments are scanned and passed to the registered 'Flag'
  objects through the __call__ method.  Unparsed arguments, including
  argv[0] (e.g. the program name) are returned.
       argv = FLAGS(sys.argv)  # scan command line arguments

  The original registered Flag objects can be retrieved through the use
  of the dictionary-like operator, __getitem__:
       x = FLAGS['longname']   # access the registered Flag object

  The str() operator of a 'FlagValues' object provides help for all of
  the registered 'Flag' objects.
  """

  def __init__(self):
    # Since everything in this class is so heavily overloaded, the only
    # way of defining and using fields is to access __dict__ directly.

    # Dictionary: flag name (string) -> Flag object.
    self.__dict__['__flags'] = {}

    # Set: name of hidden flag (string).
    # Holds flags that should not be directly accessible from Python.
    self.__dict__['__hiddenflags'] = set()

    # Dictionary: module name (string) -> list of Flag objects that are defined
    # by that module.
    self.__dict__['__flags_by_module'] = {}
    # Dictionary: module id (int) -> list of Flag objects that are defined by
    # that module.
    self.__dict__['__flags_by_module_id'] = {}
    # Dictionary: module name (string) -> list of Flag objects that are
    # key for that module.
    self.__dict__['__key_flags_by_module'] = {}

    # Bool: True if flags were parsed.
    self.__dict__['__flags_parsed'] = False

    # Bool: True if Reset() was called.
    self.__dict__['__reset_called'] = False

    # None or Method(name, value) to call from __setattr__ for an unknown flag.
    self.__dict__['__set_unknown'] = None

    if _USE_GNU_GET_OPT_ENV_NAME in os.environ:
      self.__dict__['__use_gnu_getopt'] = (
          os.environ[_USE_GNU_GET_OPT_ENV_NAME] == '1')
    else:
      # By default don't use the GNU-style scanning when parsing the args.
      self.__dict__['__use_gnu_getopt'] = False

  def UseGnuGetOpt(self, use_gnu_getopt=True):
    """Use GNU-style scanning. Allows mixing of flag and non-flag arguments.

    See http://docs.python.org/library/getopt.html#getopt.gnu_getopt

    Args:
      use_gnu_getopt: wether or not to use GNU style scanning.
    """
    self.__dict__['__use_gnu_getopt'] = use_gnu_getopt

  def IsGnuGetOpt(self):
    return self.__dict__['__use_gnu_getopt']

  def FlagDict(self):
    return self.__dict__['__flags']

  def FlagsByModuleDict(self):
    """Returns the dictionary of module_name -> list of defined flags.

    Returns:
      A dictionary.  Its keys are module names (strings).  Its values
      are lists of Flag objects.
    """
    return self.__dict__['__flags_by_module']

  def FlagsByModuleIdDict(self):
    """Returns the dictionary of module_id -> list of defined flags.

    Returns:
      A dictionary.  Its keys are module IDs (ints).  Its values
      are lists of Flag objects.
    """
    return self.__dict__['__flags_by_module_id']

  def KeyFlagsByModuleDict(self):
    """Returns the dictionary of module_name -> list of key flags.

    Returns:
      A dictionary.  Its keys are module names (strings).  Its values
      are lists of Flag objects.
    """
    return self.__dict__['__key_flags_by_module']

  def _RegisterFlagByModule(self, module_name, flag):
    """Records the module that defines a specific flag.

    We keep track of which flag is defined by which module so that we
    can later sort the flags by module.

    Args:
      module_name: A string, the name of a Python module.
      flag: A Flag object, a flag that is key to the module.
    """
    flags_by_module = self.FlagsByModuleDict()
    flags_by_module.setdefault(module_name, []).append(flag)

  def _RegisterFlagByModuleId(self, module_id, flag):
    """Records the module that defines a specific flag.

    Args:
      module_id: An int, the ID of the Python module.
      flag: A Flag object, a flag that is key to the module.
    """
    flags_by_module_id = self.FlagsByModuleIdDict()
    flags_by_module_id.setdefault(module_id, []).append(flag)

  def _RegisterKeyFlagForModule(self, module_name, flag):
    """Specifies that a flag is a key flag for a module.

    Args:
      module_name: A string, the name of a Python module.
      flag: A Flag object, a flag that is key to the module.
    """
    key_flags_by_module = self.KeyFlagsByModuleDict()
    # The list of key flags for the module named module_name.
    key_flags = key_flags_by_module.setdefault(module_name, [])
    # Add flag, but avoid duplicates.
    if flag not in key_flags:
      key_flags.append(flag)

  def _FlagIsRegistered(self, flag_obj):
    """Checks whether a Flag object is registered under long name or short name.

    Args:
      flag_obj: A Flag object.

    Returns:
      A boolean: True iff flag_obj is registered under long name or short name.
    """
    flag_dict = self.FlagDict()
    # Check whether flag_obj is registered under its long name.
    name = flag_obj.name
    if flag_dict.get(name, None) == flag_obj:
      return True
    # Check whether flag_obj is registered under its short name.
    short_name = flag_obj.short_name
    if (short_name is not None and
        flag_dict.get(short_name, None) == flag_obj):
      return True
    return False

  def _CleanupUnregisteredFlagFromModuleDicts(self, flag_obj):
    """Cleanup unregistered flags from all module -> [flags] dictionaries.

    If flag_obj is registered under either its long name or short name, it
    won't be removed from the dictionaries.

    Args:
      flag_obj: A flag object.
    """
    if self._FlagIsRegistered(flag_obj):
      return
    for flags_by_module_dict in (self.FlagsByModuleDict(),
                                 self.FlagsByModuleIdDict(),
                                 self.KeyFlagsByModuleDict()):
      for flags_in_module in six.itervalues(flags_by_module_dict):
        # While (as opposed to if) takes care of multiple occurrences of a
        # flag in the list for the same module.
        while flag_obj in flags_in_module:
          flags_in_module.remove(flag_obj)

  def _GetFlagsDefinedByModule(self, module):
    """Returns the list of flags defined by a module.

    Args:
      module: A module object or a module name (a string).

    Returns:
      A new list of Flag objects.  Caller may update this list as he
      wishes: none of those changes will affect the internals of this
      FlagValue object.
    """
    if not isinstance(module, str):
      module = module.__name__

    return list(self.FlagsByModuleDict().get(module, []))

  def _GetKeyFlagsForModule(self, module):
    """Returns the list of key flags for a module.

    Args:
      module: A module object or a module name (a string)

    Returns:
      A new list of Flag objects.  Caller may update this list as he
      wishes: none of those changes will affect the internals of this
      FlagValue object.
    """
    if not isinstance(module, str):
      module = module.__name__

    # Any flag is a key flag for the module that defined it.  NOTE:
    # key_flags is a fresh list: we can update it without affecting the
    # internals of this FlagValues object.
    key_flags = self._GetFlagsDefinedByModule(module)

    # Take into account flags explicitly declared as key for a module.
    for flag in self.KeyFlagsByModuleDict().get(module, []):
      if flag not in key_flags:
        key_flags.append(flag)
    return key_flags

  def FindModuleDefiningFlag(self, flagname, default=None):
    """Return the name of the module defining this flag, or default.

    Args:
      flagname: Name of the flag to lookup.
      default: Value to return if flagname is not defined. Defaults
          to None.

    Returns:
      The name of the module which registered the flag with this name.
      If no such module exists (i.e. no flag with this name exists),
      we return default.
    """
    registered_flag = self.FlagDict().get(flagname)
    if registered_flag is None:
      return default
    for module, flags in six.iteritems(self.FlagsByModuleDict()):
      for flag in flags:
        # It must compare the flag with the one in FlagDict. This is because a
        # flag might be overridden only for its long name (or short name),
        # and only its short name (or long name) is considered registered.
        if (flag.name == registered_flag.name and
            flag.short_name == registered_flag.short_name):
          return module
    return default

  def FindModuleIdDefiningFlag(self, flagname, default=None):
    """Return the ID of the module defining this flag, or default.

    Args:
      flagname: Name of the flag to lookup.
      default: Value to return if flagname is not defined. Defaults
          to None.

    Returns:
      The ID of the module which registered the flag with this name.
      If no such module exists (i.e. no flag with this name exists),
      we return default.
    """
    registered_flag = self.FlagDict().get(flagname)
    if registered_flag is None:
      return default
    for module_id, flags in six.iteritems(self.FlagsByModuleIdDict()):
      for flag in flags:
        # It must compare the flag with the one in FlagDict. This is because a
        # flag might be overridden only for its long name (or short name),
        # and only its short name (or long name) is considered registered.
        if (flag.name == registered_flag.name and
            flag.short_name == registered_flag.short_name):
          return module_id
    return default

  def _RegisterUnknownFlagSetter(self, setter):
    """Allow set default values for undefined flags.

    Args:
      setter: Method(name, value) to call to __setattr__ an unknown flag.
        Must raise NameError or ValueError for invalid name/value.
    """
    self.__dict__['__set_unknown'] = setter

  def _SetUnknownFlag(self, name, value):
    """Returns value if setting flag |name| to |value| returned True.

    Args:
      name: Name of the flag to set.
      value: Value to set.

    Returns:
      Flag value on successful call.

    Raises:
      UnrecognizedFlagError
      IllegalFlagValueError
    """
    setter = self.__dict__['__set_unknown']
    if setter:
      try:
        setter(name, value)
        return value
      except (TypeError, ValueError):  # Flag value is not valid.
        raise exceptions.IllegalFlagValueError('"{1}" is not valid for --{0}'
                                               .format(name, value))
      except NameError:  # Flag name is not valid.
        pass
    raise exceptions.UnrecognizedFlagError(name, value)

  def AppendFlagValues(self, flag_values):
    """Appends flags registered in another FlagValues instance.

    Args:
      flag_values: registry to copy from
    """
    for flag_name, flag in six.iteritems(flag_values.FlagDict()):
      # Each flags with shortname appears here twice (once under its
      # normal name, and again with its short name).  To prevent
      # problems (DuplicateFlagError) with double flag registration, we
      # perform a check to make sure that the entry we're looking at is
      # for its normal name.
      if flag_name == flag.name:
        try:
          self[flag_name] = flag
        except exceptions.DuplicateFlagError:
          raise exceptions.DuplicateFlagError.from_flag(
              flag_name, self, other_flag_values=flag_values)

  def RemoveFlagValues(self, flag_values):
    """Remove flags that were previously appended from another FlagValues.

    Args:
      flag_values: registry containing flags to remove.
    """
    for flag_name in flag_values.FlagDict():
      self.__delattr__(flag_name)

  def __setitem__(self, name, flag):
    """Registers a new flag variable."""
    fl = self.FlagDict()
    if not isinstance(flag, _flag.Flag):
      raise exceptions.IllegalFlagValueError(flag)
    if str is bytes and isinstance(name, unicode):
      # When using Python 2 with unicode_literals, allow it but encode it
      # into the bytes type we require.
      name = name.encode('utf-8')
    if not isinstance(name, type('')):
      raise exceptions.Error('Flag name must be a string')
    if not name:
      raise exceptions.Error('Flag name cannot be empty')
    if name in fl and not flag.allow_override and not fl[name].allow_override:
      module, module_name = _helpers.GetCallingModuleObjectAndName()
      if (self.FindModuleDefiningFlag(name) == module_name and
          id(module) != self.FindModuleIdDefiningFlag(name)):
        # If the flag has already been defined by a module with the same name,
        # but a different ID, we can stop here because it indicates that the
        # module is simply being imported a subsequent time.
        return
      raise exceptions.DuplicateFlagError.from_flag(name, self)
    short_name = flag.short_name
    # If a new flag overrides an old one, we need to cleanup the old flag's
    # modules if it's not registered.
    flags_to_cleanup = set()
    if short_name is not None:
      if (short_name in fl and not flag.allow_override and
          not fl[short_name].allow_override):
        raise exceptions.DuplicateFlagError.from_flag(short_name, self)
      if short_name in fl and fl[short_name] != flag:
        flags_to_cleanup.add(fl[short_name])
      fl[short_name] = flag
    if (name not in fl  # new flag
        or fl[name].using_default_value
        or not flag.using_default_value):
      if name in fl and fl[name] != flag:
        flags_to_cleanup.add(fl[name])
      fl[name] = flag
    for f in flags_to_cleanup:
      self._CleanupUnregisteredFlagFromModuleDicts(f)

  def __dir__(self):
    """Returns list of names of all defined flags.

    Useful for TAB-completion in ipython.

    Returns:
      list(str)
    """
    return sorted(self.__dict__['__flags'])

  # TODO(olexiy): Call GetFlag() to raise UnrecognizedFlagError if name is
  # unknown.
  def __getitem__(self, name):
    """Retrieves the Flag object for the flag --name."""
    return self.FlagDict()[name]

  def GetFlag(self, name):
    """Same as __getitem__, but raises a specific error."""
    res = self.FlagDict().get(name)
    if res is None:
      raise exceptions.UnrecognizedFlagError(name)
    return res

  def HideFlag(self, name):
    """Mark the flag --name as hidden."""
    self.__dict__['__hiddenflags'].add(name)

  def _IsUnparsedFlagAccessAllowed(self, name):
    """Determine whether to allow unparsed flag access or not."""
    if _UNPARSED_FLAG_ACCESS_ENV_NAME in os.environ:
      # We've been told explicitly what to do.
      allow_unparsed_flag_access = (
          os.getenv(_UNPARSED_FLAG_ACCESS_ENV_NAME) == '1')
    elif self.__dict__['__reset_called']:
      # Raise exception if .Reset() was called. This mostly happens in tests.
      allow_unparsed_flag_access = False
    elif _helpers.IsRunningTest():
      # Staged "rollout", based on name of the flag so that we don't break
      # everyone.  Hashing the flag is a way of choosing a random but
      # consistent subset of flags to lock down which we can make larger
      # over time.
      name_bytes = name.encode('utf8') if not isinstance(name, bytes) else name
      flag_percentile = (
          struct.unpack('<I', hashlib.md5(name_bytes).digest()[:4])[0] % 100)
      allow_unparsed_flag_access = (
          _UNPARSED_ACCESS_DISABLED_PERCENT <= flag_percentile)
    else:
      allow_unparsed_flag_access = True
    return allow_unparsed_flag_access

  def __getattr__(self, name):
    """Retrieves the 'value' attribute of the flag --name."""
    fl = self.FlagDict()
    if name not in fl:
      raise AttributeError(name)
    if name in self.__dict__['__hiddenflags']:
      raise AttributeError(name)

    if self.__dict__['__flags_parsed'] or fl[name].present:
      return fl[name].value
    else:
      error_message = (
          'Trying to access flag %s before flags were parsed.' % name)
      if self._IsUnparsedFlagAccessAllowed(name):
        # Print warning to stderr. Messages in logs are often ignored/unnoticed.
        warnings.warn(
            error_message + ' This will raise an exception in the future.',
            RuntimeWarning,
            stacklevel=2)
        # Force logging.exception() to behave realistically, but don't propagate
        # exception up. Allow flag value to be returned (for now).
        try:
          raise exceptions.UnparsedFlagAccessError(error_message)
        except exceptions.UnparsedFlagAccessError:
            logging.exception(error_message)
        return fl[name].value
      else:
        raise exceptions.UnparsedFlagAccessError(error_message)

  def __setattr__(self, name, value):
    """Sets the 'value' attribute of the flag --name."""
    fl = self.FlagDict()
    if name in self.__dict__['__hiddenflags']:
      raise AttributeError(name)
    if name not in fl:
      return self._SetUnknownFlag(name, value)
    fl[name].value = value
    self._AssertValidators(fl[name].validators)
    fl[name].using_default_value = False
    return value

  def _AssertAllValidators(self):
    all_validators = set()
    for flag in six.itervalues(self.FlagDict()):
      for validator in flag.validators:
        all_validators.add(validator)
    self._AssertValidators(all_validators)

  def _AssertValidators(self, validators):
    """Assert if all validators in the list are satisfied.

    Asserts validators in the order they were created.
    Args:
      validators: Iterable(validators.Validator), validators to be
        verified
    Raises:
      AttributeError: if validators work with a non-existing flag.
      IllegalFlagValueError: if validation fails for at least one validator
    """
    for validator in sorted(
        validators, key=lambda validator: validator.insertion_index):
      try:
        validator.verify(self)
      except exceptions.ValidationError as e:
        message = validator.print_flags_with_values(self)
        raise exceptions.IllegalFlagValueError('%s: %s' % (message, str(e)))

  def __delattr__(self, flag_name):
    """Deletes a previously-defined flag from a flag object.

    This method makes sure we can delete a flag by using

      del FLAGS.<flag_name>

    E.g.,

      gflags.DEFINE_integer('foo', 1, 'Integer flag.')
      del gflags.FLAGS.foo

    If a flag is also registered by its the other name (long name or short
    name), the other name won't be deleted.

    Args:
      flag_name: A string, the name of the flag to be deleted.

    Raises:
      AttributeError: When there is no registered flag named flag_name.
    """
    fl = self.FlagDict()
    if flag_name not in fl:
      raise AttributeError(flag_name)

    flag_obj = fl[flag_name]
    del fl[flag_name]

    self._CleanupUnregisteredFlagFromModuleDicts(flag_obj)

  def _RemoveAllFlagAppearances(self, name):
    """Removes flag with name for all appearances.

    A flag can be registered with its long name and an optional short name.
    This method removes both of them. This is different than __delattr__.

    Args:
      name: Either flag's long name or short name.

    Raises:
      UnrecognizedFlagError: When flag name is not found.
    """
    flag_dict = self.FlagDict()
    if name not in flag_dict:
      raise exceptions.UnrecognizedFlagError(name)
    flag = flag_dict[name]
    names_to_remove = {name}
    names_to_remove.add(flag.name)
    if flag.short_name:
      names_to_remove.add(flag.short_name)
    for n in names_to_remove:
      self.__delattr__(n)

  def SetDefault(self, name, value):
    """Changes the default value (and current value) of the named flag object.

    Call this method at the top level of a module to avoid overwriting the value
    passed at the command line.

    Args:
      name: A string, the name of the flag to modify.
      value: The new default value.

    Raises:
      UnrecognizedFlagError: When there is no registered flag named name.
      IllegalFlagValueError: When value is not valid.
    """
    fl = self.FlagDict()
    if name not in fl:
      self._SetUnknownFlag(name, value)
      return
    if self.IsParsed():
      logging.warn(
          'FLAGS.SetDefault called on flag "%s" after flag parsing. Call this '
          'method at the top level of a module to avoid overwriting the value '
          'passed at the command line.',
          name)
    fl[name]._set_default(value)  # pylint: disable=protected-access
    self._AssertValidators(fl[name].validators)

  def __contains__(self, name):
    """Returns True if name is a value (flag) in the dict."""
    return name in self.FlagDict()

  has_key = __contains__  # a synonym for __contains__()

  def __iter__(self):
    return iter(self.FlagDict())

  def __call__(self, argv, known_only=False):
    """Parses flags from argv; stores parsed flags into this FlagValues object.

    All unparsed arguments are returned.

    Args:
       argv: argument list. Can be of any type that may be converted to a list.
       known_only: parse and remove known flags, return rest untouched.

    Returns:
       The list of arguments not parsed as options, including argv[0].

    Raises:
       Error: on any parsing error.
       ValueError: on flag value parsing error.
    """
    if not argv:
      # Unfortunately, the old parser used to accept an empty argv, and some
      # users rely on that behaviour. Allow it as a special case for now.
      self.MarkAsParsed()
      self._AssertAllValidators()
      return []

    # This pre parses the argv list for --flagfile=<> options.
    program_name = argv[0]
    args = self.ReadFlagsFromFiles(argv[1:], force_gnu=False)

    # Parse the arguments.
    unknown_flags, unparsed_args, undefok = self._ParseArgs(args, known_only)

    # Handle unknown flags by raising UnrecognizedFlagError.
    # Note some users depend on us raising this particular error.
    for name, value in unknown_flags:
      if name in undefok:
        continue

      suggestions = _helpers.GetFlagSuggestions(
          name, self.RegisteredFlags())
      raise exceptions.UnrecognizedFlagError(
          name, value, suggestions=suggestions)

    self.MarkAsParsed()
    self._AssertAllValidators()
    return [program_name] + unparsed_args

  def _ParseArgs(self, args, known_only):
    """Helper function to do the main argument parsing.

    This function goes through args and does the bulk of the flag parsing.
    It will find the corresponding flag in our flag dictionary, and call its
    .parse() method on the flag value.

    Args:
      args: List of strings with the arguments to parse.
      known_only: parse and remove known flags, return rest in unparsed_args

    Returns:
      A tuple with the following:
        unknown_flags: List of (flag name, arg) for flags we don't know about.
        unparsed_args: List of arguments we did not parse.
        undefok: Set of flags that were given via --undefok.

    Raises:
       Error: on any parsing error.
       ValueError: on flag value parsing error.
    """
    unknown_flags, unparsed_args, undefok = [], [], set()

    flag_dict = self.FlagDict()
    args = iter(args)
    for arg in args:
      value = None

      def GetValue():
        # pylint: disable=cell-var-from-loop
        try:
          return next(args) if value is None else value
        except StopIteration:
          raise exceptions.Error('Missing value for flag ' + arg)

      if not arg.startswith('-'):
        # A non-argument: default is break, GNU is skip.
        unparsed_args.append(arg)
        if self.IsGnuGetOpt():
          continue
        else:
          break

      if arg == '--':
        if known_only:
          unparsed_args.append(arg)
        break

      if '=' in arg:
        name, value = arg.lstrip('-').split('=', 1)
      else:
        name, value = arg.lstrip('-'), None

      if not name:
        # The argument is all dashes (including one dash).
        unparsed_args.append(arg)
        if self.IsGnuGetOpt():
          continue
        else:
          break

      # --undefok is a special case.
      if name == 'undefok':
        if known_only:
          unparsed_args.append(arg)
        value = GetValue()
        undefok.update(v.strip() for v in value.split(','))
        undefok.update('no' + v.strip() for v in value.split(','))
        continue

      flag = flag_dict.get(name)
      if flag:
        value = (flag.boolean and value is None) or GetValue()
      elif name.startswith('no') and len(name) > 2:
        # Boolean flags can take the form of --noflag, with no value.
        noflag = flag_dict.get(name[2:])
        if noflag and noflag.boolean:
          if value is not None:
            raise ValueError(arg + ' does not take an argument')
          flag = noflag
          value = False


      if flag:
        flag.parse(value)
        flag.using_default_value = False
      elif known_only:
        unparsed_args.append(arg)
      else:
        unknown_flags.append((name, arg))

    unparsed_args.extend(args)
    return unknown_flags, unparsed_args, undefok

  def IsParsed(self):
    """Whether flags were parsed."""
    return self.__dict__['__flags_parsed']

  def MarkAsParsed(self):
    """Explicitly mark parsed.

    Use this when the caller knows that this FlagValues has been parsed as if
    a __call__() invocation has happened.  This is only a public method for
    use by things like appcommands which do additional command like parsing.
    """
    self.__dict__['__flags_parsed'] = True

  def Reset(self):
    """Resets the values to the point before FLAGS(argv) was called."""
    for f in self.FlagDict().values():
      f.unparse()
    # We log this message before marking flags as unparsed to avoid a
    # problem when the logging library causes flags access.
    logging.info('Reset() called; flags access will now raise errors.')
    self.__dict__['__flags_parsed'] = False
    self.__dict__['__reset_called'] = True

  def RegisteredFlags(self):
    """Returns: a list of the names and short names of all registered flags."""
    return list(self.FlagDict())

  def FlagValuesDict(self):
    """Returns: a dictionary that maps flag names to flag values."""
    flag_values = {}

    for flag_name in self.RegisteredFlags():
      flag = self.FlagDict()[flag_name]
      flag_values[flag_name] = flag.value

    return flag_values

  def __str__(self):
    """Generates a help string for all known flags."""
    return self.GetHelp()

  def GetHelp(self, prefix='', include_special_flags=True):
    """Generates a help string for all known flags.

    Args:
      prefix: str, per-line output prefix.
      include_special_flags: bool, whether to include description of
        _SPECIAL_FLAGS, i.e. --flagfile and --undefok.

    Returns:
      str, formatted help message.
    """
    # TODO(vrusinov): this function needs a test.
    helplist = []

    flags_by_module = self.FlagsByModuleDict()
    if flags_by_module:
      modules = sorted(flags_by_module)

      # Print the help for the main module first, if possible.
      main_module = sys.argv[0]
      if main_module in modules:
        modules.remove(main_module)
        modules = [main_module] + modules

      for module in modules:
        self.__RenderOurModuleFlags(module, helplist)
      if include_special_flags:
        self.__RenderModuleFlags('gflags',
                                 _helpers.SPECIAL_FLAGS.FlagDict().values(),
                                 helplist)
    else:
      # Just print one long list of flags.
      values = self.FlagDict().values()
      if include_special_flags:
        values.append(_helpers.SPECIAL_FLAGS.FlagDict().values())
      self.__RenderFlagList(values, helplist, prefix)

    return '\n'.join(helplist)

  def __RenderModuleFlags(self, module, flags, output_lines, prefix=''):
    """Generates a help string for a given module."""
    if not isinstance(module, str):
      module = module.__name__
    output_lines.append('\n%s%s:' % (prefix, module))
    self.__RenderFlagList(flags, output_lines, prefix + '  ')

  def __RenderOurModuleFlags(self, module, output_lines, prefix=''):
    """Generates a help string for a given module."""
    flags = self._GetFlagsDefinedByModule(module)
    if flags:
      self.__RenderModuleFlags(module, flags, output_lines, prefix)

  def __RenderOurModuleKeyFlags(self, module, output_lines, prefix=''):
    """Generates a help string for the key flags of a given module.

    Args:
      module: A module object or a module name (a string).
      output_lines: A list of strings.  The generated help message
        lines will be appended to this list.
      prefix: A string that is prepended to each generated help line.
    """
    key_flags = self._GetKeyFlagsForModule(module)
    if key_flags:
      self.__RenderModuleFlags(module, key_flags, output_lines, prefix)

  def ModuleHelp(self, module):
    """Describe the key flags of a module.

    Args:
      module: A module object or a module name (a string).

    Returns:
      string describing the key flags of a module.
    """
    helplist = []
    self.__RenderOurModuleKeyFlags(module, helplist)
    return '\n'.join(helplist)

  def MainModuleHelp(self):
    """Describe the key flags of the main module.

    Returns:
      string describing the key flags of a module.
    """
    return self.ModuleHelp(sys.argv[0])

  def __RenderFlagList(self, flaglist, output_lines, prefix='  '):
    fl = self.FlagDict()
    special_fl = _helpers.SPECIAL_FLAGS.FlagDict()
    flaglist = [(flag.name, flag) for flag in flaglist]
    flaglist.sort()
    flagset = {}
    for (name, flag) in flaglist:
      # It's possible this flag got deleted or overridden since being
      # registered in the per-module flaglist.  Check now against the
      # canonical source of current flag information, the FlagDict.
      if fl.get(name, None) != flag and special_fl.get(name, None) != flag:
        # a different flag is using this name now
        continue
      # only print help once
      if flag in flagset: continue
      flagset[flag] = 1
      flaghelp = ''
      if flag.short_name: flaghelp += '-%s,' % flag.short_name
      if flag.boolean:
        flaghelp += '--[no]%s:' % flag.name
      else:
        flaghelp += '--%s:' % flag.name
      flaghelp += ' '
      if flag.help:
        flaghelp += flag.help
      flaghelp = _helpers.TextWrap(
          flaghelp, indent=prefix+'  ', firstline_indent=prefix)
      if flag.default_as_str:
        flaghelp += '\n'
        flaghelp += _helpers.TextWrap(
            '(default: %s)' % flag.default_as_str, indent=prefix+'  ')
      if flag.parser.syntactic_help:
        flaghelp += '\n'
        flaghelp += _helpers.TextWrap(
            '(%s)' % flag.parser.syntactic_help, indent=prefix+'  ')
      output_lines.append(flaghelp)

  def get_flag_value(self, name, default):  # pylint: disable=invalid-name
    """Returns the value of a flag (if not None) or a default value.

    Args:
      name: A string, the name of a flag.
      default: Default value to use if the flag value is None.

    Returns:
      Requested flag value or default.
    """

    value = self.__getattr__(name)
    if value is not None:  # Can't do if not value, b/c value might be '0' or ""
      return value
    else:
      return default

  # TODO(b/32098517): Remove this.
  get = get_flag_value

  def __IsFlagFileDirective(self, flag_string):
    """Checks whether flag_string contain a --flagfile=<foo> directive."""
    if isinstance(flag_string, type('')):
      if flag_string.startswith('--flagfile='):
        return 1
      elif flag_string == '--flagfile':
        return 1
      elif flag_string.startswith('-flagfile='):
        return 1
      elif flag_string == '-flagfile':
        return 1
      else:
        return 0
    return 0

  def ExtractFilename(self, flagfile_str):
    """Returns filename from a flagfile_str of form -[-]flagfile=filename.

    The cases of --flagfile foo and -flagfile foo shouldn't be hitting
    this function, as they are dealt with in the level above this
    function.

    Args:
      flagfile_str: flagfile string.

    Returns:
      str filename from a flagfile_str of form -[-]flagfile=filename.

    Raises:
      Error: when illegal --flagfile provided.
    """
    if flagfile_str.startswith('--flagfile='):
      return os.path.expanduser((flagfile_str[(len('--flagfile=')):]).strip())
    elif flagfile_str.startswith('-flagfile='):
      return os.path.expanduser((flagfile_str[(len('-flagfile=')):]).strip())
    else:
      raise exceptions.Error(
          'Hit illegal --flagfile type: %s' % flagfile_str)

  def __GetFlagFileLines(self, filename, parsed_file_stack=None):
    """Returns the useful (!=comments, etc) lines from a file with flags.

    Args:
      filename: A string, the name of the flag file.
      parsed_file_stack: A list of the names of the files that we have
        recursively encountered at the current depth. MUTATED BY THIS FUNCTION
        (but the original value is preserved upon successfully returning from
        function call).

    Returns:
      List of strings. See the note below.

    NOTE(springer): This function checks for a nested --flagfile=<foo>
    tag and handles the lower file recursively. It returns a list of
    all the lines that _could_ contain command flags. This is
    EVERYTHING except whitespace lines and comments (lines starting
    with '#' or '//').
    """
    if parsed_file_stack is None:
      parsed_file_stack = []
    # We do a little safety check for reparsing a file we've already encountered
    # at a previous depth.
    if filename in parsed_file_stack:
      sys.stderr.write('Warning: Hit circular flagfile dependency. Ignoring'
                       ' flagfile: %s\n' % (filename,))
      return []
    else:
      parsed_file_stack.append(filename)

    line_list = []  # All line from flagfile.
    flag_line_list = []  # Subset of lines w/o comments, blanks, flagfile= tags.
    try:
      file_obj = open(filename, 'r')
    except IOError as e_msg:
      raise exceptions.CantOpenFlagFileError(
          'ERROR:: Unable to open flagfile: %s' % e_msg)

    with file_obj:
      line_list = file_obj.readlines()

    # This is where we check each line in the file we just read.
    for line in line_list:
      if line.isspace():
        pass
      # Checks for comment (a line that starts with '#').
      elif line.startswith('#') or line.startswith('//'):
        pass
      # Checks for a nested "--flagfile=<bar>" flag in the current file.
      # If we find one, recursively parse down into that file.
      elif self.__IsFlagFileDirective(line):
        sub_filename = self.ExtractFilename(line)
        included_flags = self.__GetFlagFileLines(
            sub_filename, parsed_file_stack=parsed_file_stack)
        flag_line_list.extend(included_flags)
      else:
        # Any line that's not a comment or a nested flagfile should get
        # copied into 2nd position.  This leaves earlier arguments
        # further back in the list, thus giving them higher priority.
        flag_line_list.append(line.strip())

    parsed_file_stack.pop()
    return flag_line_list

  def ReadFlagsFromFiles(self, argv, force_gnu=True):
    """Processes command line args, but also allow args to be read from file.

    Args:
      argv: A list of strings, usually sys.argv[1:], which may contain one or
        more flagfile directives of the form --flagfile="./filename".
        Note that the name of the program (sys.argv[0]) should be omitted.
      force_gnu: If False, --flagfile parsing obeys normal flag semantics.
        If True, --flagfile parsing instead follows gnu_getopt semantics.
        *** WARNING *** force_gnu=False may become the future default!

    Returns:
      A new list which has the original list combined with what we read
      from any flagfile(s).

    Raises:
      IllegalFlagValueError: when --flagfile provided with no argument.

    References: Global gflags.FLAG class instance.

    This function should be called before the normal FLAGS(argv) call.
    This function scans the input list for a flag that looks like:
    --flagfile=<somefile>. Then it opens <somefile>, reads all valid key
    and value pairs and inserts them into the input list in exactly the
    place where the --flagfile arg is found.

    Note that your application's flags are still defined the usual way
    using gflags DEFINE_flag() type functions.

    Notes (assuming we're getting a commandline of some sort as our input):
    --> For duplicate flags, the last one we hit should "win".
    --> Since flags that appear later win, a flagfile's settings can be "weak"
        if the --flagfile comes at the beginning of the argument sequence,
        and it can be "strong" if the --flagfile comes at the end.
    --> A further "--flagfile=<otherfile.cfg>" CAN be nested in a flagfile.
        It will be expanded in exactly the spot where it is found.
    --> In a flagfile, a line beginning with # or // is a comment.
    --> Entirely blank lines _should_ be ignored.
    """
    rest_of_args = argv
    new_argv = []
    while rest_of_args:
      current_arg = rest_of_args[0]
      rest_of_args = rest_of_args[1:]
      if self.__IsFlagFileDirective(current_arg):
        # This handles the case of -(-)flagfile foo.  In this case the
        # next arg really is part of this one.
        if current_arg == '--flagfile' or current_arg == '-flagfile':
          if not rest_of_args:
            raise exceptions.IllegalFlagValueError(
                '--flagfile with no argument')
          flag_filename = os.path.expanduser(rest_of_args[0])
          rest_of_args = rest_of_args[1:]
        else:
          # This handles the case of (-)-flagfile=foo.
          flag_filename = self.ExtractFilename(current_arg)
        new_argv.extend(self.__GetFlagFileLines(flag_filename))
      else:
        new_argv.append(current_arg)
        # Stop parsing after '--', like getopt and gnu_getopt.
        if current_arg == '--':
          break
        # Stop parsing after a non-flag, like getopt.
        if not current_arg.startswith('-'):
          if not force_gnu and not self.__dict__['__use_gnu_getopt']:
            break
        else:
          if ('=' not in current_arg and
              rest_of_args and not rest_of_args[0].startswith('-')):
            # If this is an occurence of a legitimate --x y, skip the value
            # so that it won't be mistaken for a standalone arg.
            fl = self.FlagDict()
            name = current_arg.lstrip('-')
            if name in fl and not fl[name].boolean:
              current_arg = rest_of_args[0]
              rest_of_args = rest_of_args[1:]
              new_argv.append(current_arg)

    if rest_of_args:
      new_argv.extend(rest_of_args)

    return new_argv

  def FlagsIntoString(self):
    """Returns a string with the flags assignments from this FlagValues object.

    This function ignores flags whose value is None.  Each flag
    assignment is separated by a newline.

    NOTE: MUST mirror the behavior of the C++ CommandlineFlagsIntoString
    from http://code.google.com/p/google-gflags

    Returns:
      string with the flags assignments from this FlagValues object.
    """
    s = ''
    for flag in self.FlagDict().values():
      if flag.value is not None:
        s += flag.serialize() + '\n'
    return s

  def AppendFlagsIntoFile(self, filename):
    """Appends all flags assignments from this FlagInfo object to a file.

    Output will be in the format of a flagfile.

    NOTE: MUST mirror the behavior of the C++ AppendFlagsIntoFile
    from http://code.google.com/p/google-gflags

    Args:
      filename: string, name of the file.
    """
    with open(filename, 'a') as out_file:
      out_file.write(self.FlagsIntoString())

  def WriteHelpInXMLFormat(self, outfile=None):
    """Outputs flag documentation in XML format.

    NOTE: We use element names that are consistent with those used by
    the C++ command-line flag library, from
    http://code.google.com/p/google-gflags
    We also use a few new elements (e.g., <key>), but we do not
    interfere / overlap with existing XML elements used by the C++
    library.  Please maintain this consistency.

    Args:
      outfile: File object we write to.  Default None means sys.stdout.
    """
    doc = minidom.Document()
    all_flag = doc.createElement('AllFlags')
    doc.appendChild(all_flag)

    all_flag.appendChild(_helpers.CreateXMLDOMElement(
        doc, 'program', os.path.basename(sys.argv[0])))

    usage_doc = sys.modules['__main__'].__doc__
    if not usage_doc:
      usage_doc = '\nUSAGE: %s [flags]\n' % sys.argv[0]
    else:
      usage_doc = usage_doc.replace('%s', sys.argv[0])
    all_flag.appendChild(_helpers.CreateXMLDOMElement(doc, 'usage', usage_doc))

    # Get list of key flags for the main module.
    key_flags = self._GetKeyFlagsForModule(sys.argv[0])

    # Sort flags by declaring module name and next by flag name.
    flags_by_module = self.FlagsByModuleDict()
    all_module_names = list(flags_by_module.keys())
    all_module_names.sort()
    for module_name in all_module_names:
      flag_list = [(f.name, f) for f in flags_by_module[module_name]]
      flag_list.sort()
      for unused_flag_name, flag in flag_list:
        is_key = flag in key_flags
        all_flag.appendChild(flag._create_xml_dom_element(  # pylint: disable=protected-access
            doc, module_name, is_key=is_key))

    outfile = outfile or sys.stdout
    if six.PY2:
      outfile.write(doc.toprettyxml(indent='  ', encoding='utf-8'))
    else:
      outfile.write(
          doc.toprettyxml(indent='  ', encoding='utf-8').decode('utf-8'))
    outfile.flush()

  # New PEP8 style functions.
  def set_gnu_getopt(self, gnu_getopt=True):
    self.UseGnuGetOpt(gnu_getopt)

  is_gnu_getopt = IsGnuGetOpt
  flags_by_module_dict = FlagsByModuleDict
  flags_by_module_id_dict = FlagsByModuleIdDict
  key_flags_by_module_dict = KeyFlagsByModuleDict
  register_key_flag_for_module = _RegisterKeyFlagForModule
  find_module_defining_flag = FindModuleDefiningFlag
  find_module_id_defining_flag = FindModuleIdDefiningFlag
  append_flag_values = AppendFlagValues
  remove_flag_values = RemoveFlagValues
  set_default = SetDefault
  is_parsed = IsParsed
  mark_as_parsed = MarkAsParsed
  flag_values_dict = FlagValuesDict
  module_help = ModuleHelp
  main_module_help = MainModuleHelp
  read_flags_from_files = ReadFlagsFromFiles
  flags_into_string = FlagsIntoString
  append_flags_into_file = AppendFlagsIntoFile
  write_help_in_xml_format = WriteHelpInXMLFormat
  get_key_flags_for_module = _GetKeyFlagsForModule
  unparse_flags = Reset


_helpers.SPECIAL_FLAGS = FlagValues()
