# Source: core/serialization/alias.js

    /*global require, exports */

    var Montage = require("../core").Montage;

    /**
     * A component can expose internal components to external usage using aliases.
     * For example, a [Repetition]{@link Repetition} exposes
     * `@repetition:iteration` and a table might expose the current cell as
     * `@table:cell`, aliasing the internal `@cells:iteration`.
     *
     * An alias declaration in a component sheet (serialization) looks like:
     *
     *     {
     *         ":cell": {
     *             "alias": "repetition:iteration"
     *         }
     *     }
     *
     * An `Alias` is a representation of one of these declarations.
     * An alias can only point to another template property and can be optionally
     * followed by a path.
     *
     * @class Alias
     * @classdesc Models a label alias in a component sheet (serialization).
     * @extends Montage
     */
    exports.Alias = Montage.specialize({ /** @lends Alias# */

        _value: {
            value: null
        },

        _aliasRegExp: {
            // $1: component name
            // $2: property name
            // alias = @$1:$2
            value: /@([_a-zA-Z$][0-9_a-zA-Z$]*):([_a-zA-Z$][0-9_a-zA-Z$]*)$/
        },

        /**
         * The alias string as found in the serialization.
         *
         * @name Alias#value
         * @type {string}
         */
        value: {
            get: function () {
                return this._value;
            },

            set: function (value) {
                var split = this._aliasRegExp.exec(value);

                if (!split) {
                    throw new Error("Invalid alias syntax: " + value);
                }

                this._value = value;

                this._componentLabel = split[1];
                this._propertyName = split[2];
            }
        },

        _componentLabel: {
            value: null
        },

        /**
         * The component name part of the alias, this is the component where the
         * template property is located.
         * Derived from the alias.
         *
         * @name Alias#componentName
         * @type {string}
         * @readonly
         */
        componentLabel: {
            get: function () {
                return this._componentLabel;
            }
        },

        _propertyName: {
            value: null
        },

        /**
         * The property name of the template property. It's up to the component
         * template to define this property.
         * Derived from the alias.
         *
         * @name Alias#propertyName
         * @type {string}
         * @readonly
         */
        propertyName: {
            get: function () {
                return this._propertyName;
            }
        },

        init: {
            value: function (value) {
                this.value = value;

                return this;
            }
        }

    });