Skip to content

Instantly share code, notes, and snippets.

@mathjazz
Created March 15, 2017 20:19
Show Gist options
  • Select an option

  • Save mathjazz/d525c1fbe8a63a5e0cc684ec7939b490 to your computer and use it in GitHub Desktop.

Select an option

Save mathjazz/d525c1fbe8a63a5e0cc684ec7939b490 to your computer and use it in GitHub Desktop.
'use strict';
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
(function (global, factory) {
(typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define('fluent-syntax', ['exports'], factory) : factory(global.FluentSyntax = global.FluentSyntax || {});
})(undefined, function (exports) {
'use strict';
var Node = function Node() {
_classCallCheck(this, Node);
};
var Resource = function (_Node) {
_inherits(Resource, _Node);
function Resource() {
var body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var comment = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var source = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
_classCallCheck(this, Resource);
var _this = _possibleConstructorReturn(this, (Resource.__proto__ || Object.getPrototypeOf(Resource)).call(this));
_this.type = 'Resource';
_this.body = body;
_this.comment = comment;
_this.source = source;
return _this;
}
return Resource;
}(Node);
var Entry = function (_Node2) {
_inherits(Entry, _Node2);
function Entry() {
_classCallCheck(this, Entry);
var _this2 = _possibleConstructorReturn(this, (Entry.__proto__ || Object.getPrototypeOf(Entry)).call(this));
_this2.type = 'Entry';
_this2.annotations = [];
return _this2;
}
_createClass(Entry, [{
key: 'addSpan',
value: function addSpan(from, to) {
this.span = { from: from, to: to };
}
}, {
key: 'addAnnotation',
value: function addAnnotation(annot) {
this.annotations.push(annot);
}
}]);
return Entry;
}(Node);
var Message = function (_Entry) {
_inherits(Message, _Entry);
function Message(id) {
var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var attrs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var tags = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
var comment = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
_classCallCheck(this, Message);
var _this3 = _possibleConstructorReturn(this, (Message.__proto__ || Object.getPrototypeOf(Message)).call(this));
_this3.type = 'Message';
_this3.id = id;
_this3.value = value;
_this3.attributes = attrs;
_this3.tags = tags;
_this3.comment = comment;
return _this3;
}
return Message;
}(Entry);
var Pattern = function (_Node3) {
_inherits(Pattern, _Node3);
function Pattern(elements) {
_classCallCheck(this, Pattern);
var _this4 = _possibleConstructorReturn(this, (Pattern.__proto__ || Object.getPrototypeOf(Pattern)).call(this));
_this4.type = 'Pattern';
_this4.elements = elements;
return _this4;
}
return Pattern;
}(Node);
var TextElement = function (_Node4) {
_inherits(TextElement, _Node4);
function TextElement(value) {
_classCallCheck(this, TextElement);
var _this5 = _possibleConstructorReturn(this, (TextElement.__proto__ || Object.getPrototypeOf(TextElement)).call(this));
_this5.type = 'TextElement';
_this5.value = value;
return _this5;
}
return TextElement;
}(Node);
var Expression = function (_Node5) {
_inherits(Expression, _Node5);
function Expression() {
_classCallCheck(this, Expression);
var _this6 = _possibleConstructorReturn(this, (Expression.__proto__ || Object.getPrototypeOf(Expression)).call(this));
_this6.type = 'Expression';
return _this6;
}
return Expression;
}(Node);
var StringExpression = function (_Expression) {
_inherits(StringExpression, _Expression);
function StringExpression(value) {
_classCallCheck(this, StringExpression);
var _this7 = _possibleConstructorReturn(this, (StringExpression.__proto__ || Object.getPrototypeOf(StringExpression)).call(this));
_this7.type = 'StringExpression';
_this7.value = value;
return _this7;
}
return StringExpression;
}(Expression);
var NumberExpression = function (_Expression2) {
_inherits(NumberExpression, _Expression2);
function NumberExpression(value) {
_classCallCheck(this, NumberExpression);
var _this8 = _possibleConstructorReturn(this, (NumberExpression.__proto__ || Object.getPrototypeOf(NumberExpression)).call(this));
_this8.type = 'NumberExpression';
_this8.value = value;
return _this8;
}
return NumberExpression;
}(Expression);
var MessageReference = function (_Expression3) {
_inherits(MessageReference, _Expression3);
function MessageReference(id) {
_classCallCheck(this, MessageReference);
var _this9 = _possibleConstructorReturn(this, (MessageReference.__proto__ || Object.getPrototypeOf(MessageReference)).call(this));
_this9.type = 'MessageReference';
_this9.id = id;
return _this9;
}
return MessageReference;
}(Expression);
var ExternalArgument = function (_Expression4) {
_inherits(ExternalArgument, _Expression4);
function ExternalArgument(id) {
_classCallCheck(this, ExternalArgument);
var _this10 = _possibleConstructorReturn(this, (ExternalArgument.__proto__ || Object.getPrototypeOf(ExternalArgument)).call(this));
_this10.type = 'ExternalArgument';
_this10.id = id;
return _this10;
}
return ExternalArgument;
}(Expression);
var SelectExpression = function (_Expression5) {
_inherits(SelectExpression, _Expression5);
function SelectExpression(expression, variants) {
_classCallCheck(this, SelectExpression);
var _this11 = _possibleConstructorReturn(this, (SelectExpression.__proto__ || Object.getPrototypeOf(SelectExpression)).call(this));
_this11.type = 'SelectExpression';
_this11.expression = expression;
_this11.variants = variants;
return _this11;
}
return SelectExpression;
}(Expression);
var AttributeExpression = function (_Expression6) {
_inherits(AttributeExpression, _Expression6);
function AttributeExpression(id, name) {
_classCallCheck(this, AttributeExpression);
var _this12 = _possibleConstructorReturn(this, (AttributeExpression.__proto__ || Object.getPrototypeOf(AttributeExpression)).call(this));
_this12.type = 'AttributeExpression';
_this12.id = id;
_this12.name = name;
return _this12;
}
return AttributeExpression;
}(Expression);
var VariantExpression = function (_Expression7) {
_inherits(VariantExpression, _Expression7);
function VariantExpression(id, key) {
_classCallCheck(this, VariantExpression);
var _this13 = _possibleConstructorReturn(this, (VariantExpression.__proto__ || Object.getPrototypeOf(VariantExpression)).call(this));
_this13.type = 'VariantExpression';
_this13.id = id;
_this13.key = key;
return _this13;
}
return VariantExpression;
}(Expression);
var CallExpression = function (_Expression8) {
_inherits(CallExpression, _Expression8);
function CallExpression(callee, args) {
_classCallCheck(this, CallExpression);
var _this14 = _possibleConstructorReturn(this, (CallExpression.__proto__ || Object.getPrototypeOf(CallExpression)).call(this));
_this14.type = 'CallExpression';
_this14.callee = callee;
_this14.args = args;
return _this14;
}
return CallExpression;
}(Expression);
var Attribute = function (_Node6) {
_inherits(Attribute, _Node6);
function Attribute(id, value) {
_classCallCheck(this, Attribute);
var _this15 = _possibleConstructorReturn(this, (Attribute.__proto__ || Object.getPrototypeOf(Attribute)).call(this));
_this15.type = 'Attribute';
_this15.id = id;
_this15.value = value;
return _this15;
}
return Attribute;
}(Node);
var Tag = function (_Node7) {
_inherits(Tag, _Node7);
function Tag(name) {
_classCallCheck(this, Tag);
var _this16 = _possibleConstructorReturn(this, (Tag.__proto__ || Object.getPrototypeOf(Tag)).call(this));
_this16.type = 'Tag';
_this16.name = name;
return _this16;
}
return Tag;
}(Node);
var Variant = function (_Node8) {
_inherits(Variant, _Node8);
function Variant(key, value) {
var def = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
_classCallCheck(this, Variant);
var _this17 = _possibleConstructorReturn(this, (Variant.__proto__ || Object.getPrototypeOf(Variant)).call(this));
_this17.type = 'Variant';
_this17.key = key;
_this17.value = value;
_this17.default = def;
return _this17;
}
return Variant;
}(Node);
var NamedArgument = function (_Node9) {
_inherits(NamedArgument, _Node9);
function NamedArgument(name, val) {
_classCallCheck(this, NamedArgument);
var _this18 = _possibleConstructorReturn(this, (NamedArgument.__proto__ || Object.getPrototypeOf(NamedArgument)).call(this));
_this18.type = 'NamedArgument';
_this18.name = name;
_this18.val = val;
return _this18;
}
return NamedArgument;
}(Node);
var Identifier = function (_Node10) {
_inherits(Identifier, _Node10);
function Identifier(name) {
_classCallCheck(this, Identifier);
var _this19 = _possibleConstructorReturn(this, (Identifier.__proto__ || Object.getPrototypeOf(Identifier)).call(this));
_this19.type = 'Identifier';
_this19.name = name;
return _this19;
}
return Identifier;
}(Node);
var Symbol$1 = function (_Identifier) {
_inherits(Symbol$1, _Identifier);
function Symbol$1(name) {
_classCallCheck(this, Symbol$1);
var _this20 = _possibleConstructorReturn(this, (Symbol$1.__proto__ || Object.getPrototypeOf(Symbol$1)).call(this, name));
_this20.type = 'Symbol';
return _this20;
}
return Symbol$1;
}(Identifier);
var Comment = function (_Entry2) {
_inherits(Comment, _Entry2);
function Comment(content) {
_classCallCheck(this, Comment);
var _this21 = _possibleConstructorReturn(this, (Comment.__proto__ || Object.getPrototypeOf(Comment)).call(this));
_this21.type = 'Comment';
_this21.content = content;
return _this21;
}
return Comment;
}(Entry);
var Section = function (_Entry3) {
_inherits(Section, _Entry3);
function Section(name) {
var comment = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
_classCallCheck(this, Section);
var _this22 = _possibleConstructorReturn(this, (Section.__proto__ || Object.getPrototypeOf(Section)).call(this));
_this22.type = 'Section';
_this22.name = name;
_this22.comment = comment;
return _this22;
}
return Section;
}(Entry);
var Function = function (_Identifier2) {
_inherits(Function, _Identifier2);
function Function(name) {
_classCallCheck(this, Function);
var _this23 = _possibleConstructorReturn(this, (Function.__proto__ || Object.getPrototypeOf(Function)).call(this, name));
_this23.type = 'Function';
return _this23;
}
return Function;
}(Identifier);
var Junk = function (_Entry4) {
_inherits(Junk, _Entry4);
function Junk(content) {
_classCallCheck(this, Junk);
var _this24 = _possibleConstructorReturn(this, (Junk.__proto__ || Object.getPrototypeOf(Junk)).call(this));
_this24.type = 'Junk';
_this24.content = content;
return _this24;
}
return Junk;
}(Entry);
var ParserStream = function () {
function ParserStream(string) {
_classCallCheck(this, ParserStream);
this.string = string;
this.iter = string[Symbol.iterator]();
this.buf = [];
this.peekIndex = 0;
this.index = 0;
this.iterEnd = false;
this.peekEnd = false;
this.ch = this.iter.next().value;
}
_createClass(ParserStream, [{
key: 'next',
value: function next() {
if (this.iterEnd) {
return undefined;
}
if (this.buf.length === 0) {
this.ch = this.iter.next().value;
} else {
this.ch = this.buf.shift();
}
this.index++;
if (this.ch === undefined) {
this.iterEnd = true;
this.peekEnd = true;
}
this.peekIndex = this.index;
return this.ch;
}
}, {
key: 'current',
value: function current() {
return this.ch;
}
}, {
key: 'currentIs',
value: function currentIs(ch) {
return this.ch === ch;
}
}, {
key: 'currentPeek',
value: function currentPeek() {
if (this.peekEnd) {
return undefined;
}
var diff = this.peekIndex - this.index;
if (diff === 0) {
return this.ch;
}
return this.buf[diff - 1];
}
}, {
key: 'currentPeekIs',
value: function currentPeekIs(ch) {
return this.currentPeek() === ch;
}
}, {
key: 'peek',
value: function peek() {
if (this.peekEnd) {
return undefined;
}
this.peekIndex += 1;
var diff = this.peekIndex - this.index;
if (diff > this.buf.length) {
var ch = this.iter.next().value;
if (ch !== undefined) {
this.buf.push(ch);
} else {
this.peekEnd = true;
return undefined;
}
}
return this.buf[diff - 1];
}
}, {
key: 'getIndex',
value: function getIndex() {
return this.index;
}
}, {
key: 'getPeekIndex',
value: function getPeekIndex() {
return this.peekIndex;
}
}, {
key: 'peekCharIs',
value: function peekCharIs(ch) {
if (this.peekEnd) {
return false;
}
var ret = this.peek();
this.peekIndex -= 1;
return ret === ch;
}
}, {
key: 'resetPeek',
value: function resetPeek() {
this.peekIndex = this.index;
this.peekEnd = this.iterEnd;
}
}, {
key: 'skipToPeek',
value: function skipToPeek() {
var diff = this.peekIndex - this.index;
for (var i = 0; i < diff; i++) {
this.ch = this.buf.shift();
}
this.index = this.peekIndex;
}
}]);
return ParserStream;
}();
var Annotation = function Annotation(message) {
_classCallCheck(this, Annotation);
this.message = message;
};
var ParseError = function (_Annotation) {
_inherits(ParseError, _Annotation);
function ParseError(message) {
_classCallCheck(this, ParseError);
var _this25 = _possibleConstructorReturn(this, (ParseError.__proto__ || Object.getPrototypeOf(ParseError)).call(this, message));
_this25.name = 'ParseError';
return _this25;
}
return ParseError;
}(Annotation);
function error(ps, message) {
var err = new ParseError(message);
err.pos = ps.getIndex();
return err;
}
/* eslint no-magic-numbers: "off" */
var FTLParserStream = function (_ParserStream) {
_inherits(FTLParserStream, _ParserStream);
function FTLParserStream() {
_classCallCheck(this, FTLParserStream);
return _possibleConstructorReturn(this, (FTLParserStream.__proto__ || Object.getPrototypeOf(FTLParserStream)).apply(this, arguments));
}
_createClass(FTLParserStream, [{
key: 'peekLineWS',
value: function peekLineWS() {
var ch = this.currentPeek();
while (ch) {
if (ch !== ' ' && ch !== '\t') {
break;
}
ch = this.peek();
}
}
}, {
key: 'skipWSLines',
value: function skipWSLines() {
while (true) {
this.peekLineWS();
if (this.currentPeek() === '\n') {
this.skipToPeek();
this.next();
} else {
this.resetPeek();
break;
}
}
}
}, {
key: 'skipLineWS',
value: function skipLineWS() {
while (this.ch) {
if (this.ch !== ' ' && this.ch !== '\t') {
break;
}
this.next();
}
}
}, {
key: 'expectChar',
value: function expectChar(ch) {
if (this.ch === ch) {
this.next();
return true;
}
throw error(this, 'Expected token "' + ch + '"');
}
}, {
key: 'takeCharIf',
value: function takeCharIf(ch) {
if (this.ch === ch) {
this.next();
return true;
}
return false;
}
}, {
key: 'takeChar',
value: function takeChar(f) {
var ch = this.ch;
if (f(ch)) {
this.next();
return ch;
}
return undefined;
}
}, {
key: 'isIDStart',
value: function isIDStart() {
var cc = this.ch.charCodeAt(0);
return cc >= 97 && cc <= 122 || // a-z
cc >= 65 && cc <= 90 || // A-Z
cc === 95; // _
}
}, {
key: 'isNumberStart',
value: function isNumberStart() {
var cc = this.ch.charCodeAt(0);
return cc >= 48 && cc <= 57 || cc === 45; // 0-9
}
}, {
key: 'isPeekNextLineIndented',
value: function isPeekNextLineIndented() {
if (!this.currentPeekIs('\n')) {
return false;
}
this.peek();
if (this.currentPeekIs(' ')) {
this.resetPeek();
return true;
}
this.resetPeek();
return false;
}
}, {
key: 'isPeekNextLineVariantStart',
value: function isPeekNextLineVariantStart() {
if (!this.currentPeekIs('\n')) {
return false;
}
this.peek();
this.peekLineWS();
if (this.currentPeekIs('*')) {
this.peek();
}
if (this.currentPeekIs('[') && !this.peekCharIs('[')) {
this.resetPeek();
return true;
}
this.resetPeek();
return false;
}
}, {
key: 'isPeekNextLineAttributeStart',
value: function isPeekNextLineAttributeStart() {
if (!this.currentPeekIs('\n')) {
return false;
}
this.peek();
this.peekLineWS();
if (this.currentPeekIs('.')) {
this.resetPeek();
return true;
}
this.resetPeek();
return false;
}
}, {
key: 'isPeekNextLineTagStart',
value: function isPeekNextLineTagStart() {
if (!this.currentPeekIs('\n')) {
return false;
}
this.peek();
this.peekLineWS();
if (this.currentPeekIs('#')) {
this.resetPeek();
return true;
}
this.resetPeek();
return false;
}
}, {
key: 'skipToNextEntryStart',
value: function skipToNextEntryStart() {
while (this.next()) {
if (this.currentIs('\n') && !this.peekCharIs('\n')) {
this.next();
if (this.ch === undefined || this.isIDStart() || this.currentIs('/') && this.peekCharIs('/') || this.currentIs('[') && this.peekCharIs('[')) {
break;
}
}
}
}
}, {
key: 'takeIDStart',
value: function takeIDStart() {
if (this.isIDStart()) {
var ret = this.ch;
this.next();
return ret;
}
throw error(this, 'Expected char range');
}
}, {
key: 'takeIDChar',
value: function takeIDChar() {
var closure = function closure(ch) {
var cc = ch.charCodeAt(0);
return cc >= 97 && cc <= 122 || // a-z
cc >= 65 && cc <= 90 || // A-Z
cc >= 48 && cc <= 57 || // 0-9
cc === 95 || cc === 45; // _-
};
return this.takeChar(closure);
}
}, {
key: 'takeSymbChar',
value: function takeSymbChar() {
var closure = function closure(ch) {
if (ch === undefined) {
return false;
}
var cc = ch.charCodeAt(0);
return cc >= 97 && cc <= 122 || // a-z
cc >= 65 && cc <= 90 || // A-Z
cc >= 48 && cc <= 57 || // 0-9
cc === 95 || cc === 45 || cc === 32; // _-
};
return this.takeChar(closure);
}
}, {
key: 'takeDigit',
value: function takeDigit() {
var closure = function closure(ch) {
var cc = ch.charCodeAt(0);
return cc >= 48 && cc <= 57; // 0-9
};
return this.takeChar(closure);
}
}]);
return FTLParserStream;
}(ParserStream);
/* eslint no-magic-numbers: [0] */
function parse(source) {
var comment = null;
var ps = new FTLParserStream(source);
ps.skipWSLines();
var entries = [];
while (ps.current()) {
var entryStartPos = ps.getIndex();
try {
var entry = getEntry(ps);
if (entryStartPos === 0 && entry.type === 'Comment') {
comment = entry;
} else {
entry.addSpan(entryStartPos, ps.getIndex());
entries.push(entry);
}
} catch (err) {
if (!(err instanceof ParseError)) {
throw err;
}
ps.skipToNextEntryStart();
var nextEntryStart = ps.getIndex();
// Create a Junk instance
var slice = source.substring(entryStartPos, nextEntryStart);
var junk = new Junk(slice);
junk.addSpan(entryStartPos, nextEntryStart);
junk.addAnnotation(err);
entries.push(junk);
}
ps.skipWSLines();
}
return new Resource(entries, comment, source);
}
function getEntry(ps) {
var comment = void 0;
if (ps.currentIs('/')) {
comment = getComment(ps);
}
if (ps.currentIs('[')) {
return getSection(ps, comment);
}
if (ps.isIDStart()) {
return getMessage(ps, comment);
}
if (comment) {
return comment;
}
throw error(ps, 'Expected entry');
}
function getComment(ps) {
ps.expectChar('/');
ps.expectChar('/');
ps.takeCharIf(' ');
var content = '';
while (true) {
var ch = void 0;
while (ch = ps.takeChar(function (x) {
return x !== '\n';
})) {
content += ch;
}
ps.next();
if (ps.current() === '/') {
content += '\n';
ps.next();
ps.expectChar('/');
ps.takeCharIf(' ');
} else {
break;
}
}
return new Comment(content);
}
function getSection(ps, comment) {
ps.expectChar('[');
ps.expectChar('[');
ps.skipLineWS();
var symb = getSymbol(ps);
ps.skipLineWS();
ps.expectChar(']');
ps.expectChar(']');
ps.skipLineWS();
ps.expectChar('\n');
return new Section(symb, comment);
}
function getMessage(ps, comment) {
var id = getIdentifier(ps);
ps.skipLineWS();
var pattern = void 0;
var attrs = void 0;
var tags = void 0;
if (ps.currentIs('=')) {
ps.next();
ps.skipLineWS();
pattern = getPattern(ps);
}
if (ps.isPeekNextLineAttributeStart()) {
attrs = getAttributes(ps);
}
if (ps.isPeekNextLineTagStart()) {
if (attrs !== undefined) {
throw error(ps, 'Tags cannot be added to a message with attributes.');
}
tags = getTags(ps);
}
if (pattern === undefined && attrs === undefined && tags === undefined) {
throw error(ps, 'Missing field');
}
return new Message(id, pattern, attrs, tags, comment);
}
function getAttributes(ps) {
var attrs = [];
while (true) {
ps.expectChar('\n');
ps.skipLineWS();
ps.expectChar('.');
var key = getIdentifier(ps);
ps.skipLineWS();
ps.expectChar('=');
ps.skipLineWS();
var value = getPattern(ps);
if (value === undefined) {
throw error(ps, 'Expected field');
}
attrs.push(new Attribute(key, value));
if (!ps.isPeekNextLineAttributeStart()) {
break;
}
}
return attrs;
}
function getTags(ps) {
var tags = [];
while (true) {
ps.expectChar('\n');
ps.skipLineWS();
ps.expectChar('#');
var symbol = getSymbol(ps);
tags.push(new Tag(symbol));
if (!ps.isPeekNextLineTagStart()) {
break;
}
}
return tags;
}
function getIdentifier(ps) {
var name = '';
name += ps.takeIDStart();
var ch = void 0;
while (ch = ps.takeIDChar()) {
name += ch;
}
return new Identifier(name);
}
function getVariantKey(ps) {
var ch = ps.current();
if (!ch) {
throw error(ps, 'Expected VariantKey');
}
var cc = ch.charCodeAt(0);
if (cc >= 48 && cc <= 57 || cc === 45) {
// 0-9, -
return getNumber(ps);
}
return getSymbol(ps);
}
function getVariants(ps) {
var variants = [];
var hasDefault = false;
while (true) {
var defaultIndex = false;
ps.expectChar('\n');
ps.skipLineWS();
if (ps.currentIs('*')) {
ps.next();
defaultIndex = true;
hasDefault = true;
}
ps.expectChar('[');
var key = getVariantKey(ps);
ps.expectChar(']');
ps.skipLineWS();
var value = getPattern(ps);
if (!value) {
throw error(ps, 'Expected field');
}
variants.push(new Variant(key, value, defaultIndex));
if (!ps.isPeekNextLineVariantStart()) {
break;
}
}
if (!hasDefault) {
throw error(ps, 'Missing default variant');
}
return variants;
}
function getSymbol(ps) {
var name = '';
name += ps.takeIDStart();
while (true) {
var ch = ps.takeSymbChar();
if (ch) {
name += ch;
} else {
break;
}
}
return new Symbol$1(name.trimRight());
}
function getDigits(ps) {
var num = '';
var ch = void 0;
while (ch = ps.takeDigit()) {
num += ch;
}
if (num.length === 0) {
throw error(ps, 'Expected char range');
}
return num;
}
function getNumber(ps) {
var num = '';
if (ps.currentIs('-')) {
num += '-';
ps.next();
}
num = '' + num + getDigits(ps);
if (ps.currentIs('.')) {
num += '.';
ps.next();
num = '' + num + getDigits(ps);
}
return new NumberExpression(num);
}
function getPattern(ps) {
var buffer = '';
var elements = [];
var firstLine = true;
var ch = void 0;
while (ch = ps.current()) {
if (ch === '\n') {
if (firstLine && buffer.length !== 0) {
break;
}
ps.peek();
if (!ps.currentPeekIs(' ')) {
ps.resetPeek();
break;
}
ps.peekLineWS();
ps.skipToPeek();
firstLine = false;
if (buffer.length !== 0) {
buffer += ch;
}
continue;
} else if (ch === '\\') {
var ch2 = ps.peek();
if (ch2 === '{' || ch2 === '"') {
buffer += ch2;
} else {
buffer += ch + ch2;
}
ps.next();
} else if (ch === '{') {
ps.next();
ps.skipLineWS();
if (buffer.length !== 0) {
elements.push(new TextElement(buffer));
}
buffer = '';
elements.push(getExpression(ps));
ps.expectChar('}');
continue;
} else {
buffer += ps.ch;
}
ps.next();
}
if (buffer.length !== 0) {
elements.push(new TextElement(buffer));
}
return new Pattern(elements);
}
function getExpression(ps) {
if (ps.isPeekNextLineVariantStart()) {
var variants = getVariants(ps);
ps.expectChar('\n');
ps.expectChar(' ');
ps.skipLineWS();
return new SelectExpression(null, variants);
}
var selector = getSelectorExpression(ps);
ps.skipLineWS();
if (ps.currentIs('-')) {
ps.peek();
if (!ps.currentPeekIs('>')) {
ps.resetPeek();
} else {
ps.next();
ps.next();
ps.skipLineWS();
var _variants = getVariants(ps);
if (_variants.length === 0) {
throw error(ps, 'Missing variants');
}
ps.expectChar('\n');
ps.expectChar(' ');
ps.skipLineWS();
return new SelectExpression(selector, _variants);
}
}
return selector;
}
function getSelectorExpression(ps) {
var literal = getLiteral(ps);
if (literal.type !== 'MessageReference') {
return literal;
}
var ch = ps.current();
if (ch === '.') {
ps.next();
var attr = getIdentifier(ps);
return new AttributeExpression(literal.id, attr);
}
if (ch === '[') {
ps.next();
var key = getVariantKey(ps);
ps.expectChar(']');
return new VariantExpression(literal.id, key);
}
if (ch === '(') {
ps.next();
var args = getCallArgs(ps);
ps.expectChar(')');
return new CallExpression(literal.id, args);
}
return literal;
}
function getCallArgs(ps) {
var args = [];
ps.skipLineWS();
while (true) {
if (ps.current() === ')') {
break;
}
var exp = getSelectorExpression(ps);
ps.skipLineWS();
if (ps.current() === ':') {
if (exp.type !== 'MessageReference') {
throw error(ps, 'Forbidden key');
}
ps.next();
ps.skipLineWS();
var val = getArgVal(ps);
args.push(new NamedArgument(exp.id, val));
} else {
args.push(exp);
}
ps.skipLineWS();
if (ps.current() === ',') {
ps.next();
ps.skipLineWS();
continue;
} else {
break;
}
}
return args;
}
function getArgVal(ps) {
if (ps.isNumberStart()) {
return getNumber(ps);
} else if (ps.currentIs('"')) {
return getString(ps);
}
throw error(ps, 'Expected field');
}
function getString(ps) {
var val = '';
ps.expectChar('"');
var ch = void 0;
while (ch = ps.takeChar(function (x) {
return x !== '"';
})) {
val += ch;
}
ps.next();
return new StringExpression(val);
}
function getLiteral(ps) {
var ch = ps.current();
if (!ch) {
throw error(ps, 'Expected literal');
}
if (ps.isNumberStart()) {
return getNumber(ps);
} else if (ch === '"') {
return getString(ps);
} else if (ch === '$') {
ps.next();
var _name = getIdentifier(ps);
return new ExternalArgument(_name);
}
var name = getIdentifier(ps);
return new MessageReference(name);
}
function indent(content) {
return content.split('\n').join('\n ');
}
function containNewLine(elems) {
var withNewLine = elems.filter(function (elem) {
return elem.type === 'TextElement' && elem.value.includes('\n');
});
return !!withNewLine.length;
}
function serialize(resource) {
var withJunk = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var parts = [];
if (resource.comment) {
parts.push(serializeComment(resource.comment) + '\n\n');
}
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = resource.body[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var entry = _step.value;
switch (entry.type) {
case 'Junk':
if (withJunk) {
parts.push(serializeJunk(entry));
}
break;
case 'Section':
parts.push(serializeSection(entry));
break;
case 'Message':
parts.push(serializeMessage(entry));
break;
default:
throw new Error('Unknown entry type: ' + entry.type);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return parts.join('').trim();
}
function serializeComment(comment) {
return comment.content.split('\n').map(function (line) {
return '// ' + line;
}).join('\n');
}
function serializeSection(section) {
var name = serializeSymbol(section.name);
if (section.comment) {
var comment = serializeComment(section.comment);
return '\n\n' + comment + '\n[[ ' + name + ' ]]\n\n';
}
return '\n\n[[ ' + name + ' ]]\n\n';
}
function serializeJunk(junk) {
return junk.content;
}
function serializeMessage(message) {
var parts = [];
if (message.comment) {
parts.push(serializeComment(message.comment));
parts.push('\n');
}
parts.push(serializeIdentifier(message.id));
if (message.value) {
parts.push(' =');
parts.push(serializeValue(message.value));
}
if (message.tags) {
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = message.tags[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var tag = _step2.value;
parts.push(serializeTag(tag));
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
if (message.attributes) {
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = message.attributes[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var attribute = _step3.value;
parts.push(serializeAttribute(attribute));
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
}
parts.push('\n');
return parts.join('');
}
function serializeTag(tag) {
var name = serializeSymbol(tag.name);
return '\n #' + name;
}
function serializeAttribute(attribute) {
var id = serializeIdentifier(attribute.id);
var value = indent(serializeValue(attribute.value));
return '\n .' + id + ' =' + value;
}
function serializeValue(pattern) {
var content = indent(serializePattern(pattern));
var multi = containNewLine(pattern.elements);
if (multi) {
return '\n ' + content;
}
return ' ' + content;
}
function serializePattern(pattern) {
return pattern.elements.map(serializeElement).join('');
}
function serializeElement(element) {
switch (element.type) {
case 'TextElement':
return serializeTextElement(element);
case 'SelectExpression':
return '{' + serializeSelectExpression(element) + '}';
default:
return '{ ' + serializeExpression(element) + ' }';
}
}
function serializeTextElement(text) {
return text.value;
}
function serializeExpression(expr) {
switch (expr.type) {
case 'StringExpression':
return serializeStringExpression(expr);
case 'NumberExpression':
return serializeNumberExpression(expr);
case 'MessageReference':
return serializeMessageReference(expr);
case 'ExternalArgument':
return serializeExternalArgument(expr);
case 'AttributeExpression':
return serializeAttributeExpression(expr);
case 'VariantExpression':
return serializeVariantExpression(expr);
case 'CallExpression':
return serializeCallExpression(expr);
default:
throw new Error('Unknown expression type: ' + expr.type);
}
}
function serializeStringExpression(expr) {
return '"' + expr.value + '"';
}
function serializeNumberExpression(expr) {
return expr.value;
}
function serializeMessageReference(expr) {
return serializeIdentifier(expr.id);
}
function serializeExternalArgument(expr) {
return '$' + serializeIdentifier(expr.id);
}
function serializeSelectExpression(expr) {
var parts = [];
if (expr.expression) {
var selector = ' ' + serializeExpression(expr.expression) + ' ->';
parts.push(selector);
}
var _iteratorNormalCompletion4 = true;
var _didIteratorError4 = false;
var _iteratorError4 = undefined;
try {
for (var _iterator4 = expr.variants[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
var variant = _step4.value;
parts.push(serializeVariant(variant));
}
} catch (err) {
_didIteratorError4 = true;
_iteratorError4 = err;
} finally {
try {
if (!_iteratorNormalCompletion4 && _iterator4.return) {
_iterator4.return();
}
} finally {
if (_didIteratorError4) {
throw _iteratorError4;
}
}
}
parts.push('\n');
return parts.join('');
}
function serializeVariant(variant) {
var key = serializeVariantKey(variant.key);
var value = indent(serializeValue(variant.value));
if (variant.default) {
return '\n *[' + key + ']' + value;
}
return '\n [' + key + ']' + value;
}
function serializeAttributeExpression(expr) {
var id = serializeIdentifier(expr.id);
var name = serializeIdentifier(expr.name);
return id + '.' + name;
}
function serializeVariantExpression(expr) {
var id = serializeIdentifier(expr.id);
var key = serializeVariantKey(expr.key);
return id + '[' + key + ']';
}
function serializeCallExpression(expr) {
var fun = serializeFunction(expr.callee);
var args = expr.args.map(serializeCallArgument).join(', ');
return fun + '(' + args + ')';
}
function serializeCallArgument(arg) {
switch (arg.type) {
case 'NamedArgument':
return serializeNamedArgument(arg);
default:
return serializeExpression(arg);
}
}
function serializeNamedArgument(arg) {
var name = serializeIdentifier(arg.name);
var value = serializeArgumentValue(arg.val);
return name + ': ' + value;
}
function serializeArgumentValue(argval) {
switch (argval.type) {
case 'StringExpression':
return serializeStringExpression(argval);
case 'NumberExpression':
return serializeNumberExpression(argval);
default:
throw new Error('Unknown argument type: ' + argval.type);
}
}
function serializeIdentifier(identifier) {
return identifier.name;
}
function serializeSymbol(symbol) {
return symbol.name;
}
function serializeVariantKey(key) {
switch (key.type) {
case 'Symbol':
return serializeSymbol(key);
case 'NumberExpression':
return serializeNumberExpression(key);
default:
throw new Error('Unknown variant key type: ' + key.type);
}
}
function serializeFunction(fun) {
return fun.name;
}
function lineOffset(source, pos) {
// Substract 1 to get the offset.
return source.substring(0, pos).split('\n').length - 1;
}
function columnOffset(source, pos) {
var lastLineBreak = source.lastIndexOf('\n', pos);
return lastLineBreak === -1 ? pos
// Substracting two offsets gives length; substract 1 to get the offset.
: pos - lastLineBreak - 1;
}
exports.lineOffset = lineOffset;
exports.columnOffset = columnOffset;
exports.Resource = Resource;
exports.Entry = Entry;
exports.Message = Message;
exports.Pattern = Pattern;
exports.TextElement = TextElement;
exports.Expression = Expression;
exports.StringExpression = StringExpression;
exports.NumberExpression = NumberExpression;
exports.MessageReference = MessageReference;
exports.ExternalArgument = ExternalArgument;
exports.SelectExpression = SelectExpression;
exports.AttributeExpression = AttributeExpression;
exports.VariantExpression = VariantExpression;
exports.CallExpression = CallExpression;
exports.Attribute = Attribute;
exports.Tag = Tag;
exports.Variant = Variant;
exports.NamedArgument = NamedArgument;
exports.Identifier = Identifier;
exports.Symbol = Symbol$1;
exports.Comment = Comment;
exports.Section = Section;
exports.Function = Function;
exports.Junk = Junk;
exports.parse = parse;
exports.serialize = serialize;
Object.defineProperty(exports, '__esModule', { value: true });
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment