UNPKG

7.23 kBJavaScriptView Raw
1/*
2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15'use strict';
16
17var {
18 Factory,
19 Serializer,
20 DateTimeUtil
21} = require('@accordproject/concerto-core');
22var ParsingTable = require('./parsingtable');
23var draftVisitNodes = require('./ToCiceroMarkVisitor').visitNodes;
24var ToParserVisitor = require('./ToParserVisitor');
25var FormulaVisitor = require('./FormulaVisitor');
26var {
27 templateMarkManager,
28 templateToTokens,
29 tokensToUntypedTemplateMark,
30 templateMarkTyping
31} = require('./templatemarkutil');
32
33/**
34 * Hooks
35 */
36
37var defaultFormulaEval = name => {
38 return (code, data, currentTime, utcOffset) => {
39 var variables = Object.keys(data).filter(x => !(x === '$class' || x === 'clauseId' || x === 'contractId'));
40 return " calculate(".concat(code, ")(").concat(variables, ") @ ").concat(currentTime.format(), " ");
41 };
42};
43
44/**
45 * Generates and manages a template parser/drafter
46 * @class
47 */
48class ParserManager {
49 /**
50 * Create the ParserManager.
51 * @param {object} modelManager - the model manager
52 * @param {object} parsingTable - parsing table extension
53 * @param {string} templateKind - either 'clause' or 'contract'
54 * @param {*} formulaEval - function from formula code to JavaScript evaluation function
55 */
56 constructor(modelManager, parsingTable, templateKind, formulaEval) {
57 this.modelManager = modelManager;
58 this.factory = new Factory(this.modelManager);
59 this.serializer = new Serializer(this.factory, this.modelManager);
60 this.template = null;
61 this.templateMark = null;
62 this.parser = null;
63 this.templateKind = templateKind ? templateKind : 'clause';
64 // Default setting to now
65 var {
66 currentTime,
67 utcOffset
68 } = DateTimeUtil.setCurrentTime();
69 this.currentTime = currentTime;
70 this.utcOffset = utcOffset;
71 this.userParsingTable = parsingTable;
72 this.formulaEval = formulaEval ? formulaEval : defaultFormulaEval;
73
74 // Initialize parsing table
75 this.initParsingTable();
76 }
77
78 /**
79 * Initialize parsing table
80 */
81 initParsingTable() {
82 // Mapping from types to parsers/drafters
83 this.parserVisitor = new ToParserVisitor();
84 var parserHook = function parserHook(ast, parameters) {
85 return ToParserVisitor.toParserWithParameters(new ToParserVisitor(), ast, parameters);
86 };
87 this.parsingTable = new ParsingTable(this.modelManager, parserHook, draftVisitNodes);
88 if (this.userParsingTable) {
89 this.parsingTable.addParsingTable(this.userParsingTable);
90 }
91 }
92
93 /**
94 * Gets the model manager for this parser
95 * @return {object} the model manager
96 */
97 getModelManager() {
98 return this.modelManager;
99 }
100
101 /**
102 * Gets the factory for this parser
103 * @return {object} the factory
104 */
105 getFactory() {
106 return this.factory;
107 }
108
109 /**
110 * Gets the serializer for this parser
111 * @return {object} the serializer
112 */
113 getSerializer() {
114 return this.serializer;
115 }
116
117 /**
118 * Gets the template text
119 * @return {string} the template
120 */
121 getTemplate() {
122 return this.template;
123 }
124
125 /**
126 * Sets the template
127 * @param {string} template - the template text
128 */
129 setTemplate(template) {
130 this.template = template;
131 }
132
133 /**
134 * Gets the TemplateMark AST
135 * @return {object} templateMark - the TemplateMark AST
136 */
137 getTemplateMark() {
138 if (!this.templateMark) {
139 throw new Error('Must call buildParser before calling getTemplateMark');
140 }
141 return this.templateMark;
142 }
143
144 /**
145 * Sets the TemplateMark AST
146 * @param {object} templateMark - the TemplateMark AST
147 */
148 setTemplateMark(templateMark) {
149 this.templateMark = templateMark;
150 }
151
152 /**
153 * Gets a parser object for this template
154 * @return {object} the parser for this template
155 */
156 getParser() {
157 if (!this.parser) {
158 throw new Error('Must call buildParser before calling getParser');
159 }
160 return this.parser;
161 }
162
163 /**
164 * Gets parsing table for variables
165 * @return {object} the parsing table
166 */
167 getParsingTable() {
168 return this.parsingTable;
169 }
170
171 /**
172 * Sets parsing table extension
173 * @param {object} table the parsing table
174 */
175 setParsingTable(table) {
176 this.userParsingTable = table;
177 }
178
179 /**
180 * Initialize the parser
181 */
182 initParser() {
183 if (!this.templateMark) {
184 var tokenStream = templateToTokens(this.template);
185 var template = tokensToUntypedTemplateMark(tokenStream, this.templateKind);
186 this.templateMark = templateMarkTyping(template, this.modelManager, this.templateKind);
187 }
188 this.parser = this.parserVisitor.toParser(this, this.templateMark, this.parsingTable);
189 }
190
191 /**
192 * Build the parser
193 */
194 buildParser() {
195 if (this.parser) {
196 this.rebuildParser();
197 } else {
198 this.initParser();
199 }
200 }
201
202 /**
203 * Rebuild the parser
204 */
205 rebuildParser() {
206 // Clear the parser
207 this.parser = null;
208 // Reinitialize the parsing table
209 this.initParsingTable();
210 // Clear templateMark if a template grammar exists
211 if (this.template && this.templateMark) {
212 this.templateMark = null;
213 }
214 this.initParser();
215 }
216
217 /**
218 * Get the execute function for a given formula
219 * @param {string} name - the name of that formula
220 * @return {string} a function taking the contract data and returning the corresponding formula result
221 */
222 getFormulaEval(name) {
223 return this.formulaEval(name);
224 }
225
226 /**
227 * Set a new execute function for formulas
228 * @param {*} evalFun - the eval function
229 */
230 setFormulaEval(evalFun) {
231 this.formulaEval = evalFun;
232 }
233
234 /**
235 * Get the formulas for this templatemark
236 * @return {*} the formulas
237 */
238 getFormulas() {
239 var visitor = new FormulaVisitor();
240 return visitor.processFormulas(templateMarkManager.modelManager.serializer, this.getTemplateMark());
241 }
242
243 /**
244 * Sets the template kind
245 * @param {string} templateKind - either 'clause' or 'contract'
246 */
247 setTemplateKind(templateKind) {
248 this.templateKind = templateKind;
249 }
250
251 /**
252 * Sets the current time
253 * @param {string} [currentTime] - the definition of 'now'
254 * @param {number} [utcOffset] - UTC Offset for this execution
255 */
256 setCurrentTime(currentTime, utcOffset) {
257 var {
258 currentTime: setCurrentTime,
259 utcOffset: setUtcOffset
260 } = DateTimeUtil.setCurrentTime(currentTime, utcOffset);
261 this.currentTime = setCurrentTime;
262 this.utcOffset = setUtcOffset;
263 }
264
265 /**
266 * Returns the current time
267 * @return {string} the current time
268 */
269 getCurrentTime() {
270 return this.currentTime;
271 }
272
273 /**
274 * Returns the UTC offset
275 * @return {number} the UTC offset
276 */
277 getUtcOffset() {
278 return this.utcOffset;
279 }
280}
281module.exports = ParserManager;
\No newline at end of file