def collect_fields(
        self,
        runtime_type: GraphQLObjectType,
        selection_set: SelectionSetNode,
        fields: Dict[str, List[FieldNode]],
        visited_fragment_names: Set[str],
    ) -> Dict[str, List[FieldNode]]:
        """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.
        """
        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
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.