code: def collect_fields(
          self,
          runtime_type: GraphQLObjectType,
          selection_set: SelectionSetNode,
          fields: Dict[str, List[FieldNode]],
          visited_fragment_names: Set[str],
      ) -> Dict[str, List[FieldNode]]:
          
          for selection in selection_set.selections:
              if isinstance(selection, FieldNode):
                  if not self.should_include_node(selection):
                      continue
                  name = get_field_entry_key(selection)
                  fields.setdefault(name, []).append(selection)
              elif isinstance(selection, InlineFragmentNode):
                  if not self.should_include_node(
                      selection
                  ) or not self.does_fragment_condition_match(selection, runtime_type):
                      continue
                  self.collect_fields(
                      runtime_type,
                      selection.selection_set,
                      fields,
                      visited_fragment_names,
                  )
              elif isinstance(selection, FragmentSpreadNode):
                  frag_name = selection.name.value
                  if frag_name in visited_fragment_names or not self.should_include_node(
                      selection
                  ):
                      continue
                  visited_fragment_names.add(frag_name)
                  fragment = self.fragments.get(frag_name)
                  if not fragment or not self.does_fragment_condition_match(
                      fragment, runtime_type
                  ):
                      continue
                  self.collect_fields(
                      runtime_type, fragment.selection_set, fields, visited_fragment_names
                  )
          return fields
docs: Collect fields.
  
          Given a selection_set, adds all of the fields in that selection to the passed in
          map of fields, and returns it at the end.
  
          collect_fields requires the "runtime type" of an object. For a field which
          returns an Interface or Union type, the "runtime type" will be the actual
          Object type returned by that field.