code: func (c *PodAffinityChecker) podMatchesPodAffinityTerms(pod, targetPod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo, terms []v1.PodAffinityTerm) (bool, bool, error) {
  	if len(terms) == 0 {
  		return false, false, fmt.Errorf("terms array is empty")
  	}
  	props, err := getAffinityTermProperties(pod, terms)
  	if err != nil {
  		return false, false, err
  	}
  	if !podMatchesAllAffinityTermProperties(targetPod, props) {
  		return false, false, nil
  	}
  	// Namespace and selector of the terms have matched. Now we check topology of the terms.
  	targetPodNode, err := c.info.GetNodeInfo(targetPod.Spec.NodeName)
  	if err != nil {
  		return false, false, err
  	}
  	for _, term := range terms {
  		if len(term.TopologyKey) == 0 {
  			return false, false, fmt.Errorf("empty topologyKey is not allowed except for PreferredDuringScheduling pod anti-affinity")
  		}
  		if !priorityutil.NodesHaveSameTopologyKey(nodeInfo.Node(), targetPodNode, term.TopologyKey) {
  			return false, true, nil
  		}
  	}
  	return true, true, nil
  }
docs: // podMatchesPodAffinityTerms checks if the "targetPod" matches the given "terms"
  // of the "pod" on the given "nodeInfo".Node(). It returns three values: 1) whether
  // targetPod matches all the terms and their topologies, 2) whether targetPod
  // matches all the terms label selector and namespaces (AKA term properties),
  // 3) any error.