private static CompletableFuture<List<Pair<RegionInfo, ServerName>>> getTableRegionsAndLocations(
    final AsyncTable<AdvancedScanResultConsumer> metaTable, final TableName tableName,
    final boolean excludeOfflinedSplitParents) {
    CompletableFuture<List<Pair<RegionInfo, ServerName>>> future = new CompletableFuture<>();
    if (TableName.META_TABLE_NAME.equals(tableName)) {
      future.completeExceptionally(new IOException(
        "This method can't be used to locate meta regions;" + " use MetaTableLocator instead"));
    }

    // Make a version of CollectingVisitor that collects RegionInfo and ServerAddress
    CollectRegionLocationsVisitor visitor =
      new CollectRegionLocationsVisitor(excludeOfflinedSplitParents);

    addListener(scanMeta(metaTable, tableName, QueryType.REGION, visitor), (v, error) -> {
      if (error != null) {
        future.completeExceptionally(error);
        return;
      }
      future.complete(visitor.getResults());
    });
    return future;
  }
Used to get table regions' info and server.
@param metaTable                   scanner over meta table
@param tableName                   table we're looking for, can be null for getting all regions
@param excludeOfflinedSplitParents don't return split parents
@return the list of regioninfos and server. The return value will be wrapped by a
        {@link CompletableFuture}.
hbase-client/src/main/java/org/apache/hadoop/hbase/ClientMetaTableAccessor.java