public static @Nullable String toTableSpec(TableReference tableReference) {
    if (tableReference.getDatasetId() == null || tableReference.getTableId() == null) {
      throw new IllegalArgumentException(
          String.format(
              "Table reference [%s] must include at least a dataset and a table.", tableReference));
    }
    String tableSpec =
        String.format("%s.%s", tableReference.getDatasetId(), tableReference.getTableId());
    if (!Strings.isNullOrEmpty(tableReference.getProjectId())) {
      tableSpec = String.format("%s.%s", tableReference.getProjectId(), tableSpec);
    }
    return tableSpec;
  }
@Test
  public void testToTableSpec() {
    TableReference withProject =
        new TableReference().setProjectId("project").setDatasetId("dataset").setTableId("table");
    TableReference withoutProject =
        new TableReference().setDatasetId("dataset").setTableId("table");
    TableReference withDatasetOnly = new TableReference().setDatasetId("dataset");
    TableReference withTableOnly = new TableReference().setTableId("table");

    assertEquals("project.dataset.table", toTableSpec(withProject));
    assertEquals("dataset.table", toTableSpec(withoutProject));
    assertThrows(
        "must include at least a dataset and a table",
        IllegalArgumentException.class,
        () -> toTableSpec(withDatasetOnly));
    assertThrows(
        "must include at least a dataset and a table",
        IllegalArgumentException.class,
        () -> toTableSpec(withTableOnly));
  }