class DnsNameResolver extends NameResolver {

  @VisibleForTesting
  static ResolutionResults resolveAll(
      AddressResolver addressResolver,
      @Nullable ResourceResolver resourceResolver,
      boolean requestSrvRecords,
      boolean requestTxtRecords,
      String name) {
    List<? extends InetAddress> addresses = Collections.emptyList();
    Exception addressesException = null;
    List<EquivalentAddressGroup> balancerAddresses = Collections.emptyList();
    Exception balancerAddressesException = null;
    List<String> txtRecords = Collections.emptyList();
    Exception txtRecordsException = null;

    try {
      addresses = addressResolver.resolveAddress(name);
    } catch (Exception e) {
      addressesException = e;
    }
    if (resourceResolver != null) {
      if (requestSrvRecords) {
        try {
          balancerAddresses =
              resourceResolver.resolveSrv(addressResolver, GRPCLB_NAME_PREFIX + name);
        } catch (Exception e) {
          balancerAddressesException = e;
        }
      }
      if (requestTxtRecords) {
        boolean balancerLookupFailedOrNotAttempted =
            !requestSrvRecords || balancerAddressesException != null;
        boolean dontResolveTxt =
            (addressesException != null) && balancerLookupFailedOrNotAttempted;
        // Only do the TXT record lookup if one of the above address resolutions succeeded.
        if (!dontResolveTxt) {
          try {
            txtRecords = resourceResolver.resolveTxt(SERVICE_CONFIG_NAME_PREFIX + name);
          } catch (Exception e) {
            txtRecordsException = e;
          }
        }
      }
    }
    try {
      if (addressesException != null
          && (balancerAddressesException != null || balancerAddresses.isEmpty())) {
        Throwables.throwIfUnchecked(addressesException);
        throw new RuntimeException(addressesException);
      }
    } finally {
      if (addressesException != null) {
        logger.log(Level.FINE, "Address resolution failure", addressesException);
      }
      if (balancerAddressesException != null) {
        logger.log(Level.FINE, "Balancer resolution failure", balancerAddressesException);
      }
      if (txtRecordsException != null) {
        logger.log(Level.FINE, "ServiceConfig resolution failure", txtRecordsException);
      }
    }
    return new ResolutionResults(addresses, txtRecords, balancerAddresses);
  }

    DnsNameResolver(@Nullable String nsAuthority, String name, Attributes params,
      Resource<Executor> executorResource, ProxyDetector proxyDetector,
      Stopwatch stopwatch, boolean isAndroid);

}