text: "use strict";
  var __importDefault = (this && this.__importDefault) || function (mod) {
      return (mod && mod.__esModule) ? mod : { "default": mod };
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  /*
   * Copyright (c) 2018, salesforce.com, inc.
   * All rights reserved.
   * SPDX-License-Identifier: MIT
   * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
   */
  const assert_1 = __importDefault(require("../../shared/assert"));
  const language_1 = require("../../shared/language");
  const wire_1 = __importDefault(require("./wire"));
  const track_1 = __importDefault(require("./track"));
  const api_1 = __importDefault(require("./api"));
  const utils_1 = require("../utils");
  const attributes_1 = require("../attributes");
  const decorate_1 = __importDefault(require("./decorate"));
  const signedDecoratorToMetaMap = new Map();
  function registerDecorators(Ctor, meta) {
      const decoratorMap = language_1.create(null);
      const props = getPublicPropertiesHash(Ctor, meta.publicProps);
      const methods = getPublicMethodsHash(Ctor, meta.publicMethods);
      const wire = getWireHash(Ctor, meta.wire);
      const track = getTrackHash(Ctor, meta.track);
      signedDecoratorToMetaMap.set(Ctor, {
          props,
          methods,
          wire,
          track,
      });
      for (const propName in props) {
          decoratorMap[propName] = api_1.default;
      }
      if (wire) {
          for (const propName in wire) {
              const wireDef = wire[propName];
              if (wireDef.method) {
                  // for decorated methods we need to do nothing
                  continue;
              }
              decoratorMap[propName] = wire_1.default(wireDef.adapter, wireDef.params);
          }
      }
      if (track) {
          for (const propName in track) {
              decoratorMap[propName] = track_1.default;
          }
      }
      decorate_1.default(Ctor, decoratorMap);
      return Ctor;
  }
  exports.registerDecorators = registerDecorators;
  function getDecoratorsRegisteredMeta(Ctor) {
      return signedDecoratorToMetaMap.get(Ctor);
  }
  exports.getDecoratorsRegisteredMeta = getDecoratorsRegisteredMeta;
  function getTrackHash(target, track) {
      if (language_1.isUndefined(track) || language_1.getOwnPropertyNames(track).length === 0) {
          return utils_1.EmptyObject;
      }
      // TODO: check that anything in `track` is correctly defined in the prototype
      return language_1.assign(language_1.create(null), track);
  }
  function getWireHash(target, wire) {
      if (language_1.isUndefined(wire) || language_1.getOwnPropertyNames(wire).length === 0) {
          return;
      }
      // TODO: check that anything in `wire` is correctly defined in the prototype
      return language_1.assign(language_1.create(null), wire);
  }
  function getPublicPropertiesHash(target, props) {
      if (language_1.isUndefined(props) || language_1.getOwnPropertyNames(props).length === 0) {
          return utils_1.EmptyObject;
      }
      return language_1.getOwnPropertyNames(props).reduce((propsHash, propName) => {
          const attrName = attributes_1.getAttrNameFromPropName(propName);
          if (process.env.NODE_ENV !== 'production') {
              const globalHTMLProperty = attributes_1.getGlobalHTMLPropertiesInfo()[propName];
              if (globalHTMLProperty &&
                  globalHTMLProperty.attribute &&
                  globalHTMLProperty.reflective === false) {
                  const { error, attribute, experimental } = globalHTMLProperty;
                  const msg = [];
                  if (error) {
                      msg.push(error);
                  }
                  else if (experimental) {
                      msg.push(`"${propName}" is an experimental property that is not standardized or supported by all browsers. You should not use "${propName}" and attribute "${attribute}" in your component.`);
                  }
                  else {
                      msg.push(`"${propName}" is a global HTML property. Instead access it via the reflective attribute "${attribute}" with one of these techniques:`);
                      msg.push(`  * Use \`this.getAttribute("${attribute}")\` to access the attribute value. This option is best suited for accessing the value in a getter during the rendering process.`);
                  }
                  assert_1.default.logError(msg.join('\n'));
              }
          }
          propsHash[propName] = language_1.assign({
              config: 0,
              type: 'any',
              attr: attrName,
          }, props[propName]);
          return propsHash;
      }, language_1.create(null));
  }
  function getPublicMethodsHash(target, publicMethods) {
      if (language_1.isUndefined(publicMethods) || publicMethods.length === 0) {
          return utils_1.EmptyObject;
      }
      return publicMethods.reduce((methodsHash, methodName) => {
          if (process.env.NODE_ENV !== 'production') {
              assert_1.default.isTrue(language_1.isFunction(target.prototype[methodName]), `Component "${target.name}" should have a method \`${methodName}\` instead of ${target.prototype[methodName]}.`);
          }
          methodsHash[methodName] = target.prototype[methodName];
          return methodsHash;
      }, language_1.create(null));
  }
  //# sourceMappingURL=register.js.map