code: def _parse_and_analyze(f, autobatch_functions):
      """Performs preliminary analyses and transformations.
  
      The goal is to massage the source program into a form on which
      the `_AutoBatchingTransformer` below will be successful.
  
      Args:
        f: Function to analyze
        autobatch_functions: List of Python `str` names of autobatched functions.
          Arguments to these functions will be canonicalized to variable references,
          but others will not.
  
      Returns:
        node: A Python AST node representing the function, suitable for
          passing to `_AutoBatchingTransformer.visit`
        entity_info: An AutoGraph `EntityInfo` object, with some information
          about `f`.  Required for initializing `_AutoBatchingTransformer`.
      """
      # TODO(mdan): Replace all this boilerplate with FunctionTranspiler.
      namespace = {}
  
      # Get the AST of the function
      future_features = inspect_utils.getfutureimports(f)
      node, _ = parser.parse_entity(f, future_features=future_features)
  
      # Boilerplate for AutoGraph transforms
      if hasattr(converter, "EntityContext"):
          # TF 2.2-
          entity_info = transformer.EntityInfo(
              source_code="",
              source_file=None,
              future_features=future_features,
              namespace=namespace,
          )
          program_ctx = converter.ProgramContext(
              options=converter.ConversionOptions(recursive=True),
              autograph_module=None,
          )
          ctx = converter.EntityContext(
              namer=naming.Namer(namespace),
              entity_info=entity_info,
              program_ctx=program_ctx,
          )
      else:
          # TF 2.3+
          entity_info = transformer.EntityInfo(
              name=f.__name__,
              source_code="",
              source_file=None,
              future_features=future_features,
              namespace=namespace,
          )
          program_ctx = converter.ProgramContext(
              options=converter.ConversionOptions(recursive=True),
              autograph_module=None,
          )
          ctx = transformer.Context(
              info=entity_info,
              namer=naming.Namer(namespace),
              user_context=program_ctx,
          )
  
      # Canonicalize away break statements
      node = converter.standard_analysis(node, ctx)
      node = break_statements.transform(node, ctx)
  
      # Canonicalize away continue statements
      node = converter.standard_analysis(node, ctx)
      node = continue_statements.transform(node, ctx)
  
      # Force single returns
      node = converter.standard_analysis(node, ctx)
      node = return_statements.transform(
          node, ctx, default_to_null_return=False
      )
  
      # Transform into ANF
      # Replacing if tests and autobatched function call arguments because
      # that's where divergence can happen.
      # Replacing all function calls because the downstream transformation
      # expects calls to lead directly to assignments.
      def maybe_replace_function_argument(parent, field_name, child):
          del field_name, child
          if not anno.hasanno(parent.func, anno.Basic.QN):
              return False
          func_name = anno.getanno(parent.func, anno.Basic.QN)
          if str(func_name) in autobatch_functions:
              return True
          return False
  
      anf_config = [
          (anf.ASTEdgePattern(gast.If, "test", anf.ANY), anf.REPLACE),
          (
              anf.ASTEdgePattern(anf.ANY, anf.ANY, gast.Call),
              anf.REPLACE,
          ),
          (
              anf.ASTEdgePattern(gast.Call, "args", anf.ANY),
              maybe_replace_function_argument,
          ),
      ]
      node = anf.transform(node, ctx, config=anf_config)
      node = qual_names.resolve(node)
      node = activity.resolve(node, ctx)
  
      return node, ctx
  
imports: import contextlib
  import functools
  import gast
  import six
  import tensorflow.compat.v2
  from tensorflow_probability.python.experimental.auto_batching import allocation_strategy
  from tensorflow_probability.python.experimental.auto_batching import dsl
  from tensorflow_probability.python.experimental.auto_batching import gast_util
  from tensorflow_probability.python.experimental.auto_batching import instructions
  from tensorflow_probability.python.experimental.auto_batching import lowering
  from tensorflow_probability.python.experimental.auto_batching import stack_optimization
  from tensorflow_probability.python.experimental.auto_batching import stackless
  from tensorflow_probability.python.experimental.auto_batching import tf_backend
  from tensorflow_probability.python.experimental.auto_batching import type_inference
  from tensorflow_probability.python.experimental.auto_batching import virtual_machine
  from tensorflow.python.autograph.converters import break_statements
  from tensorflow.python.autograph.converters import continue_statements
  from tensorflow.python.autograph.converters import return_statements
  from tensorflow.python.autograph.core import converter
  from tensorflow.python.autograph.pyct import anno
  from tensorflow.python.autograph.pyct import inspect_utils
  from tensorflow.python.autograph.pyct import parser
  from tensorflow.python.autograph.pyct import qual_names
  from tensorflow.python.autograph.pyct import templates
  from tensorflow.python.autograph.pyct import transformer
  from tensorflow.python.autograph.pyct.common_transformers import anf
  from tensorflow.python.autograph.pyct.static_analysis import activity
label_desc: Use image node_id 1 for calling a global function with example usage: _parse_and_analyze(f, autobatch_functions) and returns: node,  ctx, False, False, True