text: from empire import *
  
  import re
  
  from empire.strings.string_manipulation import StringManipulation
  
  
  class _ParameterDefinitionListExtractor:
      @staticmethod
      def extract(code: str) -> List[str]:
          parameter_definitions: List[str] = []
          if not code.startswith('('):
              code = StringManipulation.strip_chars_till_first_token_encountered(code, '(')
  
          code = CodeAnalysis.extract_surrounded(code)
  
          pos: int = 0
          current_token: str = ''
          block_depth: int = 0
          in_str: bool = False
          in_tqstr: bool = False
  
          while pos < len(code):
              if code[pos] in ['"', "'"]:
                  if StringManipulation.char_at(code, pos + 1) == code[pos] and StringManipulation.char_at(code, pos + 2) == code[pos]:
                      in_tqstr = ~in_tqstr
                      in_str = ~in_str
                      current_token += code[pos:pos + 2]
                      pos += 2
                  else:
                      in_str = ~in_str
                      current_token += code[pos]
              elif in_str or in_tqstr:
                  current_token += code[pos]
              elif code[pos] in ['(', '{', '[']:
                  block_depth += 1
                  current_token += code[pos]
              elif code[pos] in [')', '}', ']']:
                  block_depth -= 1
                  current_token += code[pos]
              elif block_depth == 0 and code[pos] == ',':
                  parameter_definitions.append(current_token)
                  current_token = ''
              else:
                  current_token += code[pos]
  
              pos += 1
  
          parameter_definitions.append(current_token)
          return parameter_definitions
  
  
  class CodeAnalysis:
      _FUNCTION_CALL_REGEX: Final[re.Pattern] = re.compile(r"[A-z0-9_]+\(.*\)")
  
      @staticmethod
      def extract_end_of_line_comment(code_line: str) -> Tuple[str, Union[str, None]]:
          """
          Takes a line of code as input, and checks if it ends with a comment.
          Returns a tuple where:
          - The first item is the line of code cleaned of comment
          - The second item, if there was a comment, the comment itself, else, None
          """
          if '#' not in code_line:
              return code_line, None
  
          in_str: bool = False
          pos: int = len(code_line) - 1
  
          for char in reversed(code_line):
              if char in ['"', "'"]:
                  in_str = ~in_str
              elif char == '#' and not in_str:
                  break
              else:
                  pos -= 1
  
          return code_line[0:pos].strip(), code_line[pos+1:len(code_line)].strip()
  
      @staticmethod
      def extract_function_parameters_definitions(code: str) -> List[str]:
          return _ParameterDefinitionListExtractor.extract(code)
  
      @staticmethod
      def extract_surrounded(string: str) -> Union[str, None]:
          try:
              return string[1:-1]
          except IndexError:
              return None
  
      @staticmethod
      def token_is_function_call(token: str) -> bool:
          return True if token.endswith(')') and CodeAnalysis._FUNCTION_CALL_REGEX.findall(token) else False
  
      @staticmethod
      def token_is_string(token: str) -> Union[str, None]:
          """
          If token is a strings (surrounded by ' or "), returns the strings delimeter char (' or "). If not returns None
          """
          if CodeAnalysis.token_is_surrounded_by_delimeter(token, "'"):
              return "'"
          elif CodeAnalysis.token_is_surrounded_by_delimeter(token, '"'):
              return '"'
          else:
              return None
  
      @staticmethod
      def token_is_surrounded_by_delimeter(token: str, delimeter: str) -> bool:
          return token.startswith(delimeter) and token.endswith(delimeter)
  
      @staticmethod
      def get_typing_as_string(value: Any) -> str:
          raw: str = str(type(value))
          if raw.startswith('<class'):
              return CodeAnalysis.extract_surrounded(raw.replace('<class ', '').replace('>', ''))
          else:
              return raw
  
  
  if __name__ == '__main__':
      print(CodeAnalysis.extract_function_parameters_definitions('AppendKnowledgeGraph._get_knowledge_graph_value_multi_lang(raw_sd,AppendKnowledgeGraph.KNOWLEDGE_GRAPH_WEBSITE_FIELD_NAMES,"patate",123,False,[\'address\',\'adresse\'])'))