@Override
  public PreparedLayer call() throws IOException, CacheCorruptedException, RegistryException {
    EventHandlers eventHandlers = buildContext.getEventHandlers();
    DescriptorDigest layerDigest = layer.getBlobDescriptor().getDigest();
    try (ProgressEventDispatcher progressEventDispatcher =
            progressEventDispatcherFactory.create("checking base image layer " + layerDigest, 1);
        TimerEventDispatcher ignored =
            new TimerEventDispatcher(eventHandlers, String.format(DESCRIPTION, layerDigest))) {

      StateInTarget stateInTarget = blobExistenceChecker.check(layerDigest);
      if (stateInTarget == StateInTarget.EXISTING) {
        eventHandlers.dispatch(
            LogEvent.info(
                "Skipping pull; BLOB already exists on target registry : "
                    + layer.getBlobDescriptor()));
        return new PreparedLayer.Builder(layer).setStateInTarget(stateInTarget).build();
      }

      Cache cache = buildContext.getBaseImageLayersCache();

      // Checks if the layer already exists in the cache.
      Optional<CachedLayer> optionalCachedLayer = cache.retrieve(layerDigest);
      if (optionalCachedLayer.isPresent()) {
        CachedLayer cachedLayer = optionalCachedLayer.get();
        return new PreparedLayer.Builder(cachedLayer).setStateInTarget(stateInTarget).build();
      } else if (buildContext.isOffline()) {
        throw new IOException(
            "Cannot run Jib in offline mode; local Jib cache for base image is missing image layer "
                + layerDigest
                + ". Rerun Jib in online mode with \"-Djib.alwaysCacheBaseImage=true\" to "
                + "re-download the base image layers.");
      }

      try (ThrottledProgressEventDispatcherWrapper progressEventDispatcherWrapper =
          new ThrottledProgressEventDispatcherWrapper(
              progressEventDispatcher.newChildProducer(),
              "pulling base image layer " + layerDigest)) {
        CachedLayer cachedLayer =
            cache.writeCompressedLayer(
                Verify.verifyNotNull(registryClient)
                    .pullBlob(
                        layerDigest,
                        progressEventDispatcherWrapper::setProgressTarget,
                        progressEventDispatcherWrapper::dispatchProgress));
        return new PreparedLayer.Builder(cachedLayer).setStateInTarget(stateInTarget).build();
      }
    }
  }
Pulls and caches a single base image layer.
jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/ObtainBaseImageLayerStep.java