lCredentials(options);
}

struct HostConfig {
  util::Path certificate_path;
  std::string target_name;
  bool use_insecure_channel = false;
};

using ConfigByHost = std::unordered_map<std::string, HostConfig>;

ConfigByHost& Config() {
  static ConfigByHost config_by_host_;
  return config_by_host_;
}

bool HasSpecialConfig(const std::string& host) {
  return Config().find(host) != Config().end();
}

}  // namespace

GrpcConnection::GrpcConnection(const DatabaseInfo& database_info,
                               util::AsyncQueue* worker_queue,
                               grpc::CompletionQueue* grpc_queue,
                               ConnectivityMonitor* connectivity_monitor)
    : database_info_{&database_info},
      worker_queue_{NOT_NULL(worker_queue)},
      grpc_queue_{NOT_NULL(grpc_queue)},
      connectivity_monitor_{NOT_NULL(connectivity_monitor)} {
  RegisterConnectivityMonitor();
}

void GrpcConnection::Shutdown() {
  // Fast finish any pending calls. This will not trigger the observers.
  // Calls may unregister themselves on finish, so make a protective copy.
  auto active_calls = active_calls_;
  for (GrpcCall* call : active_calls) {
    call->FinishImmediately();
  }
}

std::unique_ptr<grpc::ClientContext> GrpcConnection::CreateContext(
    const Token& credential) const {
  absl::string_view token = credential.user().is_authenticated()
                                ? credential.token()
                                : absl::string_view{};

  auto context = absl::make_unique<grpc::ClientContext>();
  if (token.data()) {
    context->set_credentials(grpc::AccessTokenCredentials(MakeString(token)));
  }

  // TODO(dimond): This should ideally also include the gRPC version, however,
  // gRPC defines the version as a macro, so it would be hardcoded based on
  // version we have at compile time of the Firestore library, rather than the
  // version available at runtime/at compile time by the user of the library.
  //
  // TODO(varconst): this should be configurable (e.g., "gl-cpp" or similar f