// Copyright 2018 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.skyframe;

import com.google.common.base.Preconditions;
import com.google.common.collect.Iterators;
import java.math.BigInteger;
import java.util.Iterator;
import javax.annotation.Nullable;

/** List of fingerprints, each of which is a nullable {@link BigInteger}. Ordered and immutable. */
public class DepFingerprintList implements Iterable<BigInteger> {
  /**
   * Marker object indicating that dep fingerprints are not being tracked, and so there should be no
   * attempts to use this dep fingerprints object. Clients can compare their {@code
   * DepFingerprintList} object to this one using reference equality to see if they are tracking dep
   * fingerprints. This object should never be passed in as a valid {@code DepFingerprintList}
   * object.
   */
  public static final DepFingerprintList NOT_TRACKING_MARKER = new NoDepGroupsFingerprintMarker();

  private static final DepFingerprintList EMPTY_DEP_GROUPS_FINGERPRINT =
      new DepFingerprintList(new BigInteger[0]);

  private final BigInteger[] fingerprints;

  private DepFingerprintList(BigInteger[] fingerprints) {
    this.fingerprints = fingerprints;
  }

  /**
   * Returns the {@link BigInteger} for the dep group at {@code index}. A null value indicates that
   * a fingerprint could not be computed for this group, so that equality-by-dep-group checking
   * cannot be performed for this group.
   */
  @Nullable
  public BigInteger get(int index) {
    return fingerprints[index];
  }

  @Override
  public Iterator<BigInteger> iterator() {
    return Iterators.forArray(fingerprints);
  }

  private static class NoDepGroupsFingerprintMarker extends DepFingerprintList {
    private NoDepGroupsFingerprintMarker() {
      super(null);
    }

    @Override
    public BigInteger get(int index) {
      throw new UnsupportedOperationException("No dep groups fingerprint (" + index + ")");
    }

    @Override
    public Iterator<BigInteger> iterator() {
      throw new UnsupportedOperationException("No dep groups fingerprint");
    }
  }

  /** Builder for {@code DepFingerprintList}. */
  public static class Builder {
    private int curIndex = 0;
    private final BigInteger[] fingerprints;

    public Builder(int size) {
      fingerprints = new BigInteger[size];
    }

    public void add(BigInteger fingerprint) {
      fingerprints[curIndex++] = fingerprint;
    }

    public DepFingerprintList build() {
      Preconditions.checkState(
          curIndex == fingerprints.length, "%s %s", curIndex, fingerprints.length);
      if (fingerprints.length == 0) {
        return EMPTY_DEP_GROUPS_FINGERPRINT;
      }
      return new DepFingerprintList(fingerprints);
    }
  }
}

@@ -772,16 +772,41 @@
 nteger;%0A
+import java.util.Arrays;%0A
 import j
@@ -2239,16 +2239,134 @@
 );%0A  %7D%0A%0A
+  @Override%0A  public String toString() %7B%0A    return %22DepFingerprintList%7B%22 + Arrays.toString(fingerprints) + %22%7D%22;%0A  %7D%0A%0A
   privat
@@ -2797,24 +2797,121 @@
 int%22);%0A    %7D
+%0A%0A    @Override%0A    public String toString() %7B%0A      return %22NoDepGroupsFingerprintMarker%22;%0A    %7D
 %0A  %7D%0A%0A  /** 

Add #toString to DepFingerprintList.