'use strict'; 
 | 
  
 | 
const Hoek = require('@hapi/hoek'); 
 | 
  
 | 
const Any = require('../any'); 
 | 
  
 | 
  
 | 
const internals = {}; 
 | 
  
 | 
  
 | 
internals.Lazy = class extends Any { 
 | 
  
 | 
    constructor() { 
 | 
  
 | 
        super(); 
 | 
        this._type = 'lazy'; 
 | 
        this._flags.once = true; 
 | 
        this._cache = null; 
 | 
    } 
 | 
  
 | 
    _init(fn, options) { 
 | 
  
 | 
        return this.set(fn, options); 
 | 
    } 
 | 
  
 | 
    _base(value, state, options) { 
 | 
  
 | 
        let schema; 
 | 
        if (this._cache) { 
 | 
            schema = this._cache; 
 | 
        } 
 | 
        else { 
 | 
            const result = { value }; 
 | 
            const lazy = this._flags.lazy; 
 | 
  
 | 
            if (!lazy) { 
 | 
                result.errors = this.createError('lazy.base', null, state, options); 
 | 
                return result; 
 | 
            } 
 | 
  
 | 
            schema = lazy(); 
 | 
  
 | 
            if (!(schema instanceof Any)) { 
 | 
                result.errors = this.createError('lazy.schema', { schema }, state, options); 
 | 
                return result; 
 | 
            } 
 | 
  
 | 
            if (this._flags.once) { 
 | 
                this._cache = schema; 
 | 
            } 
 | 
        } 
 | 
  
 | 
        return schema._validate(value, state, options); 
 | 
    } 
 | 
  
 | 
    set(fn, options) { 
 | 
  
 | 
        Hoek.assert(typeof fn === 'function', 'You must provide a function as first argument'); 
 | 
        Hoek.assert(options === undefined || (options && typeof options === 'object' && !Array.isArray(options)), `Options must be an object`); 
 | 
  
 | 
        if (options) { 
 | 
            const unknownOptions = Object.keys(options).filter((key) => !['once'].includes(key)); 
 | 
            Hoek.assert(unknownOptions.length === 0, `Options contain unknown keys: ${unknownOptions}`); 
 | 
            Hoek.assert(options.once === undefined || typeof options.once === 'boolean', 'Option "once" must be a boolean'); 
 | 
        } 
 | 
  
 | 
        const obj = this.clone(); 
 | 
        obj._flags.lazy = fn; 
 | 
  
 | 
        if (options && options.once !== obj._flags.once) { 
 | 
            obj._flags.once = options.once; 
 | 
        } 
 | 
  
 | 
        return obj; 
 | 
    } 
 | 
  
 | 
}; 
 | 
  
 | 
module.exports = new internals.Lazy(); 
 |