content: #!/usr/bin/python
  
  # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
  #
  # This source code is licensed under the MIT license found in the
  # LICENSE file in the root directory of this source tree.
  
  # These set of commands provide a way to use counters in debug time. By using these counters,
  # you can track how many times your program takes a specific path.
  #
  # Sample Use Case:
  # Let's say you have a function that logs some messages from various parts of your code.
  # And you want to learn how many times logMessage is called on startup.
  #
  # 1. Add a breakpoint to the entry point of your program (e.g. main).
  #   a. Add `zzz 10 printcounter` as an action.
  #   b. Check "Automatically continue after evaluating actions"
  # 2. Add a breakpoint to the logMessage function.
  #   a. Add `incrementcounter log` as an action.
  #   b. Add `incrementcounter log_{} message` as an action.
  #   c. Check "Automatically continue after evaluating actions"
  # 3. Run the program
  #
  # Format String:
  # It uses Python's string.Formatter to format strings. You can use placeholders here as you can in Python:
  # https://docs.python.org/3.4/library/string.html#string.Formatter.format
  #
  # Sample key_format_string:
  # "key_{}" (int)5 -> Will build the key string as "key_5"
  
  # Can be removed when Python 2 support is removed.
  from __future__ import print_function
  
  import fbchisellldbbase as fb
  
  
  counters = {}
  
  
  def lldbcommands():
      return [
          FBIncrementCounterCommand(),
          FBPrintCounterCommand(),
          FBPrintCountersCommand(),
          FBResetCounterCommand(),
          FBResetCountersCommand(),
      ]
  
  
  def generateKey(arguments):
      keyFormatString = arguments[1]
      keyArgs = []
  
      for argument in arguments[2:]:
          if argument.startswith("("):
              value = fb.evaluateExpression(argument)
          else:
              value = fb.evaluateExpressionValue(argument).GetObjectDescription()
  
              if not value:
                  value = fb.evaluateExpression(argument)
  
          keyArgs.append(value)
  
      return keyFormatString.format(*keyArgs).strip()
  
  
  # Increments the counter for the key.
  # (lldb) incrementcounter key_format_string key_args
  class FBIncrementCounterCommand(fb.FBCommand):
      def name(self):
          return "incrementcounter"
  
      def description(self):
          return "Increments the counter for the key."
  
      def run(self, arguments, options):
          key = generateKey(arguments)
          counters[key] = counters.get(key, 0) + 1
  
  
  # Prints the counter for the key.
  # (lldb) printcounter key_format_string key_args
  # 0
  class FBPrintCounterCommand(fb.FBCommand):
      def name(self):
          return "printcounter"
  
      def description(self):
          return "Prints the counter for the key."
  
      def run(self, arguments, options):
          key = generateKey(arguments)
          print(str(counters[key]))
  
  
  # Prints all the counters sorted by the keys.
  # (lldb) printcounters
  # key_1: 0
  class FBPrintCountersCommand(fb.FBCommand):
      def name(self):
          return "printcounters"
  
      def description(self):
          return "Prints all the counters sorted by the keys."
  
      def run(self, arguments, options):
          keys = sorted(counters.keys())
          for key in keys:
              print(key + ": " + str(counters[key]))
  
  
  # Resets the counter for the key.
  # (lldb) resetcounter key_format_string key_args
  class FBResetCounterCommand(fb.FBCommand):
      def name(self):
          return "resetcounter"
  
      def description(self):
          return "Resets the counter for the key."
  
      def run(self, arguments, options):
          key = generateKey(arguments)
          counters[key] = 0
  
  
  # Resets all the counters.
  # (lldb) resetcounters
  class FBResetCountersCommand(fb.FBCommand):
      def name(self):
          return "resetcounters"
  
      def description(self):
          return "Resets all the counters."
  
      def run(self, arguments, options):
          counters.clear()
  