code: public ApiFuture<String> publish(PubsubMessage message) {
      if (shutdown.get()) {
        throw new IllegalStateException("Cannot publish on a shut-down publisher.");
      }
  
      final OutstandingPublish outstandingPublish =
          new OutstandingPublish(messageTransform.apply(message));
      List<OutstandingBatch> batchesToSend;
      messagesBatchLock.lock();
      try {
        batchesToSend = messagesBatch.add(outstandingPublish);
        // Setup the next duration based delivery alarm if there are messages batched.
        setupAlarm();
      } finally {
        messagesBatchLock.unlock();
      }
  
      messagesWaiter.incrementPendingMessages(1);
  
      if (!batchesToSend.isEmpty()) {
        for (final OutstandingBatch batch : batchesToSend) {
          logger.log(Level.FINER, "Scheduling a batch for immediate sending.");
          executor.execute(
              new Runnable() {
                @Override
                public void run() {
                  publishOutstandingBatch(batch);
                }
              });
        }
      }
  
      return outstandingPublish.publishResult;
    }
docs: Schedules the publishing of a message. The publishing of the message may occur immediately or
  be delayed based on the publisher batching options.
  
  <p>Example of publishing a message.
  
  <pre>{@code
  String message = "my_message";
  ByteString data = ByteString.copyFromUtf8(message);
  PubsubMessage pubsubMessage = PubsubMessage.newBuilder().setData(data).build();
  ApiFuture<String> messageIdFuture = publisher.publish(pubsubMessage);
  ApiFutures.addCallback(messageIdFuture, new ApiFutureCallback<String>() {
  public void onSuccess(String messageId) {
  System.out.println("published with message id: " + messageId);
  }
  
  public void onFailure(Throwable t) {
  System.out.println("failed to publish: " + t);
  }
  });
  }</pre>
  
  @param message the message to publish.
  @return the message ID wrapped in a future.