text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  var TransformOperationExecutor_1 = require("../TransformOperationExecutor");
  /**
   * Storage all library metadata.
   */
  var MetadataStorage = /** @class */ (function () {
      function MetadataStorage() {
          // -------------------------------------------------------------------------
          // Properties
          // -------------------------------------------------------------------------
          this._typeMetadatas = new Map();
          this._transformMetadatas = new Map();
          this._exposeMetadatas = new Map();
          this._excludeMetadatas = new Map();
          this._ancestorsMap = new Map();
      }
      // -------------------------------------------------------------------------
      // Adder Methods
      // -------------------------------------------------------------------------
      MetadataStorage.prototype.addTypeMetadata = function (metadata) {
          if (!this._typeMetadatas.has(metadata.target)) {
              this._typeMetadatas.set(metadata.target, new Map());
          }
          this._typeMetadatas.get(metadata.target).set(metadata.propertyName, metadata);
      };
      MetadataStorage.prototype.addTransformMetadata = function (metadata) {
          if (!this._transformMetadatas.has(metadata.target)) {
              this._transformMetadatas.set(metadata.target, new Map());
          }
          if (!this._transformMetadatas.get(metadata.target).has(metadata.propertyName)) {
              this._transformMetadatas.get(metadata.target).set(metadata.propertyName, []);
          }
          this._transformMetadatas.get(metadata.target).get(metadata.propertyName).push(metadata);
      };
      MetadataStorage.prototype.addExposeMetadata = function (metadata) {
          if (!this._exposeMetadatas.has(metadata.target)) {
              this._exposeMetadatas.set(metadata.target, new Map());
          }
          this._exposeMetadatas.get(metadata.target).set(metadata.propertyName, metadata);
      };
      MetadataStorage.prototype.addExcludeMetadata = function (metadata) {
          if (!this._excludeMetadatas.has(metadata.target)) {
              this._excludeMetadatas.set(metadata.target, new Map());
          }
          this._excludeMetadatas.get(metadata.target).set(metadata.propertyName, metadata);
      };
      // -------------------------------------------------------------------------
      // Public Methods
      // -------------------------------------------------------------------------
      MetadataStorage.prototype.findTransformMetadatas = function (target, propertyName, transformationType) {
          return this.findMetadatas(this._transformMetadatas, target, propertyName)
              .filter(function (metadata) {
              if (!metadata.options)
                  return true;
              if (metadata.options.toClassOnly === true && metadata.options.toPlainOnly === true)
                  return true;
              if (metadata.options.toClassOnly === true) {
                  return transformationType === TransformOperationExecutor_1.TransformationType.CLASS_TO_CLASS || transformationType === TransformOperationExecutor_1.TransformationType.PLAIN_TO_CLASS;
              }
              if (metadata.options.toPlainOnly === true) {
                  return transformationType === TransformOperationExecutor_1.TransformationType.CLASS_TO_PLAIN;
              }
              return true;
          });
      };
      MetadataStorage.prototype.findExcludeMetadata = function (target, propertyName) {
          return this.findMetadata(this._excludeMetadatas, target, propertyName);
      };
      MetadataStorage.prototype.findExposeMetadata = function (target, propertyName) {
          return this.findMetadata(this._exposeMetadatas, target, propertyName);
      };
      MetadataStorage.prototype.findExposeMetadataByCustomName = function (target, name) {
          return this.getExposedMetadatas(target).find(function (metadata) {
              return metadata.options && metadata.options.name === name;
          });
      };
      MetadataStorage.prototype.findTypeMetadata = function (target, propertyName) {
          return this.findMetadata(this._typeMetadatas, target, propertyName);
      };
      MetadataStorage.prototype.getStrategy = function (target) {
          var excludeMap = this._excludeMetadatas.get(target);
          var exclude = excludeMap && excludeMap.get(undefined);
          var exposeMap = this._exposeMetadatas.get(target);
          var expose = exposeMap && exposeMap.get(undefined);
          if ((exclude && expose) || (!exclude && !expose))
              return "none";
          return exclude ? "excludeAll" : "exposeAll";
      };
      MetadataStorage.prototype.getExposedMetadatas = function (target) {
          return this.getMetadata(this._exposeMetadatas, target);
      };
      MetadataStorage.prototype.getExcludedMetadatas = function (target) {
          return this.getMetadata(this._excludeMetadatas, target);
      };
      MetadataStorage.prototype.getExposedProperties = function (target, transformationType) {
          return this.getExposedMetadatas(target)
              .filter(function (metadata) {
              if (!metadata.options)
                  return true;
              if (metadata.options.toClassOnly === true && metadata.options.toPlainOnly === true)
                  return true;
              if (metadata.options.toClassOnly === true) {
                  return transformationType === TransformOperationExecutor_1.TransformationType.CLASS_TO_CLASS || transformationType === TransformOperationExecutor_1.TransformationType.PLAIN_TO_CLASS;
              }
              if (metadata.options.toPlainOnly === true) {
                  return transformationType === TransformOperationExecutor_1.TransformationType.CLASS_TO_PLAIN;
              }
              return true;
          })
              .map(function (metadata) { return metadata.propertyName; });
      };
      MetadataStorage.prototype.getExcludedProperties = function (target, transformationType) {
          return this.getExcludedMetadatas(target)
              .filter(function (metadata) {
              if (!metadata.options)
                  return true;
              if (metadata.options.toClassOnly === true && metadata.options.toPlainOnly === true)
                  return true;
              if (metadata.options.toClassOnly === true) {
                  return transformationType === TransformOperationExecutor_1.TransformationType.CLASS_TO_CLASS || transformationType === TransformOperationExecutor_1.TransformationType.PLAIN_TO_CLASS;
              }
              if (metadata.options.toPlainOnly === true) {
                  return transformationType === TransformOperationExecutor_1.TransformationType.CLASS_TO_PLAIN;
              }
              return true;
          })
              .map(function (metadata) { return metadata.propertyName; });
      };
      MetadataStorage.prototype.clear = function () {
          this._typeMetadatas.clear();
          this._exposeMetadatas.clear();
          this._excludeMetadatas.clear();
          this._ancestorsMap.clear();
      };
      // -------------------------------------------------------------------------
      // Private Methods
      // -------------------------------------------------------------------------
      MetadataStorage.prototype.getMetadata = function (metadatas, target) {
          var metadataFromTargetMap = metadatas.get(target);
          var metadataFromTarget;
          if (metadataFromTargetMap) {
              metadataFromTarget = Array.from(metadataFromTargetMap.values()).filter(function (meta) { return meta.propertyName !== undefined; });
          }
          var metadataFromAncestors = [];
          for (var _i = 0, _a = this.getAncestors(target); _i < _a.length; _i++) {
              var ancestor = _a[_i];
              var ancestorMetadataMap = metadatas.get(ancestor);
              if (ancestorMetadataMap) {
                  var metadataFromAncestor = Array.from(ancestorMetadataMap.values()).filter(function (meta) { return meta.propertyName !== undefined; });
                  metadataFromAncestors.push.apply(metadataFromAncestors, metadataFromAncestor);
              }
          }
          return metadataFromAncestors.concat(metadataFromTarget || []);
      };
      MetadataStorage.prototype.findMetadata = function (metadatas, target, propertyName) {
          var metadataFromTargetMap = metadatas.get(target);
          if (metadataFromTargetMap) {
              var metadataFromTarget = metadataFromTargetMap.get(propertyName);
              if (metadataFromTarget) {
                  return metadataFromTarget;
              }
          }
          for (var _i = 0, _a = this.getAncestors(target); _i < _a.length; _i++) {
              var ancestor = _a[_i];
              var ancestorMetadataMap = metadatas.get(ancestor);
              if (ancestorMetadataMap) {
                  var ancestorResult = ancestorMetadataMap.get(propertyName);
                  if (ancestorResult) {
                      return ancestorResult;
                  }
              }
          }
          return undefined;
      };
      MetadataStorage.prototype.findMetadatas = function (metadatas, target, propertyName) {
          var metadataFromTargetMap = metadatas.get(target);
          var metadataFromTarget;
          if (metadataFromTargetMap) {
              metadataFromTarget = metadataFromTargetMap.get(propertyName);
          }
          var metadataFromAncestorsTarget = [];
          for (var _i = 0, _a = this.getAncestors(target); _i < _a.length; _i++) {
              var ancestor = _a[_i];
              var ancestorMetadataMap = metadatas.get(ancestor);
              if (ancestorMetadataMap) {
                  if (ancestorMetadataMap.has(propertyName)) {
                      metadataFromAncestorsTarget.push.apply(metadataFromAncestorsTarget, ancestorMetadataMap.get(propertyName));
                  }
              }
          }
          return (metadataFromAncestorsTarget).reverse().concat((metadataFromTarget || []).reverse());
      };
      MetadataStorage.prototype.getAncestors = function (target) {
          if (!target)
              return [];
          if (!this._ancestorsMap.has(target)) {
              var ancestors = [];
              for (var baseClass = Object.getPrototypeOf(target.prototype.constructor); typeof baseClass.prototype !== "undefined"; baseClass = Object.getPrototypeOf(baseClass.prototype.constructor)) {
                  ancestors.push(baseClass);
              }
              this._ancestorsMap.set(target, ancestors);
          }
          return this._ancestorsMap.get(target);
      };
      return MetadataStorage;
  }());
  exports.MetadataStorage = MetadataStorage;
  
  //# sourceMappingURL=MetadataStorage.js.map
  