var Module;
(function(Module2) {
  Module2.merge = (m1, m2) => _merge(_merge({}, m1), m2);
})(Module || (Module = {}));
function inject(module1, module2, module3, module4, module5, module6, module7, module8, module9) {
  const module = [module1, module2, module3, module4, module5, module6, module7, module8, module9].reduce(_merge, {});
  return _inject(module);
}
const isProxy = Symbol("isProxy");
function _inject(module, injector) {
  const proxy = new Proxy({}, {
    deleteProperty: () => false,
    set: () => {
      throw new Error("Cannot set property on injected service container");
    },
    get: (obj, prop) => {
      if (prop === isProxy) {
        return true;
      } else {
        return _resolve(obj, prop, module, injector || proxy);
      }
    },
    getOwnPropertyDescriptor: (obj, prop) => (_resolve(obj, prop, module, injector || proxy), Object.getOwnPropertyDescriptor(obj, prop)),
    // used by for..in
    has: (_, prop) => prop in module,
    // used by ..in..
    ownKeys: () => [...Object.getOwnPropertyNames(module)]
    // used by for..in
  });
  return proxy;
}
const __requested__ = Symbol();
function _resolve(obj, prop, module, injector) {
  if (prop in obj) {
    if (obj[prop] instanceof Error) {
      throw new Error("Construction failure. Please make sure that your dependencies are constructable.", { cause: obj[prop] });
    }
    if (obj[prop] === __requested__) {
      throw new Error('Cycle detected. Please make "' + String(prop) + '" lazy. Visit https://langium.org/docs/reference/configuration-services/#resolving-cyclic-dependencies');
    }
    return obj[prop];
  } else if (prop in module) {
    const value = module[prop];
    obj[prop] = __requested__;
    try {
      obj[prop] = typeof value === "function" ? value(injector) : _inject(value, injector);
    } catch (error) {
      obj[prop] = error instanceof Error ? error : void 0;
      throw error;
    }
    return obj[prop];
  } else {
    return void 0;
  }
}
function _merge(target, source) {
  if (source) {
    for (const [key, value2] of Object.entries(source)) {
      if (value2 !== void 0) {
        const value1 = target[key];
        if (value1 !== null && value2 !== null && typeof value1 === "object" && typeof value2 === "object") {
          target[key] = _merge(value1, value2);
        } else {
          target[key] = value2;
        }
      }
    }
  }
  return target;
}
export {
  Module,
  inject
};
//# sourceMappingURL=lib-dependency-injection.js.map
