package org.implab.gradle.common.core.lang;

import java.util.Objects;
import java.util.function.Supplier;

public class LazyValue<T> implements Supplier<T> {
    private volatile T value;
    private volatile boolean initialized = false;

    private final Supplier<T> innerSupplier;

    public LazyValue(Supplier<T> supplier) {
        this.innerSupplier = supplier;
    }

    @Override
    public T get() {
        var v = value;
        if (initialized) {
            return v;
        }

        synchronized (this) {
            v = value;
            if (v == null) {
                v = Objects.requireNonNull(
                        innerSupplier.get(),
                        "LazyValue supplier returned null");
                value = v;
            }
            return v;
        }
    }

}
