@malloydata/malloy 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +39 -0
  2. package/dist/connection_utils.d.ts +1 -0
  3. package/dist/connection_utils.js +56 -0
  4. package/dist/dialect/dialect-map.d.ts +3 -0
  5. package/dist/dialect/dialect-map.js +33 -0
  6. package/dist/dialect/dialect.d.ts +64 -0
  7. package/dist/dialect/dialect.js +64 -0
  8. package/dist/dialect/dialect_map.d.ts +3 -0
  9. package/dist/dialect/dialect_map.js +35 -0
  10. package/dist/dialect/duckdb.d.ts +49 -0
  11. package/dist/dialect/duckdb.js +349 -0
  12. package/dist/dialect/index.d.ts +6 -0
  13. package/dist/dialect/index.js +27 -0
  14. package/dist/dialect/postgres.d.ts +49 -0
  15. package/dist/dialect/postgres.js +308 -0
  16. package/dist/dialect/standardsql.d.ts +46 -0
  17. package/dist/dialect/standardsql.js +361 -0
  18. package/dist/index.d.ts +9 -0
  19. package/dist/index.js +47 -0
  20. package/dist/lang/ast/apply-expr.d.ts +16 -0
  21. package/dist/lang/ast/apply-expr.js +215 -0
  22. package/dist/lang/ast/ast-expr.d.ts +291 -0
  23. package/dist/lang/ast/ast-expr.js +1056 -0
  24. package/dist/lang/ast/ast-main.d.ts +480 -0
  25. package/dist/lang/ast/ast-main.js +2096 -0
  26. package/dist/lang/ast/ast-time-expr.d.ts +109 -0
  27. package/dist/lang/ast/ast-time-expr.js +550 -0
  28. package/dist/lang/ast/ast-types.d.ts +83 -0
  29. package/dist/lang/ast/ast-types.js +215 -0
  30. package/dist/lang/ast/index.d.ts +5 -0
  31. package/dist/lang/ast/index.js +34 -0
  32. package/dist/lang/ast/time-utils.d.ts +8 -0
  33. package/dist/lang/ast/time-utils.js +83 -0
  34. package/dist/lang/field-space.d.ts +157 -0
  35. package/dist/lang/field-space.js +651 -0
  36. package/dist/lang/field-utils.d.ts +5 -0
  37. package/dist/lang/field-utils.js +33 -0
  38. package/dist/lang/index.d.ts +9 -0
  39. package/dist/lang/index.js +22 -0
  40. package/dist/lang/lib/Malloy/MalloyLexer.d.ts +156 -0
  41. package/dist/lang/lib/Malloy/MalloyLexer.js +1163 -0
  42. package/dist/lang/lib/Malloy/MalloyListener.d.ts +2026 -0
  43. package/dist/lang/lib/Malloy/MalloyListener.js +4 -0
  44. package/dist/lang/lib/Malloy/MalloyParser.d.ts +1920 -0
  45. package/dist/lang/lib/Malloy/MalloyParser.js +11790 -0
  46. package/dist/lang/lib/Malloy/MalloyVisitor.d.ts +1276 -0
  47. package/dist/lang/lib/Malloy/MalloyVisitor.js +4 -0
  48. package/dist/lang/parse-log.d.ts +27 -0
  49. package/dist/lang/parse-log.js +41 -0
  50. package/dist/lang/parse-malloy.d.ts +245 -0
  51. package/dist/lang/parse-malloy.js +729 -0
  52. package/dist/lang/parse-to-ast.d.ts +156 -0
  53. package/dist/lang/parse-to-ast.js +945 -0
  54. package/dist/lang/parse-tree-walkers/document-completion-walker.d.ts +10 -0
  55. package/dist/lang/parse-tree-walkers/document-completion-walker.js +136 -0
  56. package/dist/lang/parse-tree-walkers/document-help-context-walker.d.ts +9 -0
  57. package/dist/lang/parse-tree-walkers/document-help-context-walker.js +97 -0
  58. package/dist/lang/parse-tree-walkers/document-highlight-walker.d.ts +83 -0
  59. package/dist/lang/parse-tree-walkers/document-highlight-walker.js +375 -0
  60. package/dist/lang/parse-tree-walkers/document-symbol-walker.d.ts +11 -0
  61. package/dist/lang/parse-tree-walkers/document-symbol-walker.js +172 -0
  62. package/dist/lang/parse-tree-walkers/explore-query-walker.d.ts +34 -0
  63. package/dist/lang/parse-tree-walkers/explore-query-walker.js +64 -0
  64. package/dist/lang/parse-tree-walkers/find-external-references.d.ts +11 -0
  65. package/dist/lang/parse-tree-walkers/find-external-references.js +51 -0
  66. package/dist/lang/reference-list.d.ts +10 -0
  67. package/dist/lang/reference-list.js +80 -0
  68. package/dist/lang/space-field.d.ts +119 -0
  69. package/dist/lang/space-field.js +339 -0
  70. package/dist/lang/test/document-help-context-walker.spec.d.ts +1 -0
  71. package/dist/lang/test/document-help-context-walker.spec.js +45 -0
  72. package/dist/lang/test/document-symbol-walker.spec.d.ts +1 -0
  73. package/dist/lang/test/document-symbol-walker.spec.js +100 -0
  74. package/dist/lang/test/field-symbols.spec.d.ts +1 -0
  75. package/dist/lang/test/field-symbols.spec.js +172 -0
  76. package/dist/lang/test/parse.spec.d.ts +12 -0
  77. package/dist/lang/test/parse.spec.js +1936 -0
  78. package/dist/lang/test/test-translator.d.ts +38 -0
  79. package/dist/lang/test/test-translator.js +334 -0
  80. package/dist/lang/zone.d.ts +57 -0
  81. package/dist/lang/zone.js +97 -0
  82. package/dist/malloy.d.ts +1134 -0
  83. package/dist/malloy.js +2354 -0
  84. package/dist/model/index.d.ts +2 -0
  85. package/dist/model/index.js +34 -0
  86. package/dist/model/malloy-query.d.ts +313 -0
  87. package/dist/model/malloy-query.js +2603 -0
  88. package/dist/model/malloy-types.d.ts +404 -0
  89. package/dist/model/malloy-types.js +242 -0
  90. package/dist/model/malloy_query.d.ts +353 -0
  91. package/dist/model/malloy_query.js +2990 -0
  92. package/dist/model/malloy_types.d.ts +502 -0
  93. package/dist/model/malloy_types.js +283 -0
  94. package/dist/model/sql-block.d.ts +11 -0
  95. package/dist/model/sql-block.js +38 -0
  96. package/dist/model/sql_block.d.ts +11 -0
  97. package/dist/model/sql_block.js +41 -0
  98. package/dist/model/utils.d.ts +21 -0
  99. package/dist/model/utils.js +84 -0
  100. package/dist/runtime-types.d.ts +116 -0
  101. package/dist/runtime-types.js +40 -0
  102. package/dist/runtime_types.d.ts +119 -0
  103. package/dist/runtime_types.js +15 -0
  104. package/package.json +36 -0
@@ -0,0 +1,945 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright 2021 Google LLC
4
+ *
5
+ * This program is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU General Public License
7
+ * version 2 as published by the Free Software Foundation.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ */
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.MalloyToAST = void 0;
39
+ const AbstractParseTreeVisitor_1 = require("antlr4ts/tree/AbstractParseTreeVisitor");
40
+ const ast = __importStar(require("./ast"));
41
+ const Interval_1 = require("antlr4ts/misc/Interval");
42
+ /**
43
+ * ANTLR visitor pattern parse tree traversal. Generates a Malloy
44
+ * AST from an ANTLR parse tree.
45
+ */
46
+ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
47
+ constructor(parse, msgLog) {
48
+ super();
49
+ this.parse = parse;
50
+ this.msgLog = msgLog;
51
+ }
52
+ /**
53
+ * Mostly used to flag a case where the grammar and the type system are
54
+ * no longer in sync. A visitor was written based on a grammar which
55
+ * apparently has changed and now an unexpected element type has appeared.
56
+ * This is a non recoverable error, since the parser and the grammar
57
+ * are not compatible.
58
+ * @returns an error object to throw.
59
+ */
60
+ internalError(cx, msg) {
61
+ const tmsg = `Internal Translator Error: ${msg}`;
62
+ this.contextError(cx, tmsg);
63
+ return new Error(tmsg);
64
+ }
65
+ /**
66
+ * Log an error message relative to an AST node
67
+ */
68
+ astError(el, str, sev = "error") {
69
+ this.msgLog.log({ message: str, at: el.location, severity: sev });
70
+ }
71
+ /**
72
+ * Log an error message relative to a parse node
73
+ */
74
+ contextError(cx, msg, sev = "error") {
75
+ this.msgLog.log({
76
+ message: msg,
77
+ at: {
78
+ url: this.parse.subTranslator.sourceURL,
79
+ range: this.parse.subTranslator.rangeFromContext(cx),
80
+ },
81
+ severity: sev,
82
+ });
83
+ }
84
+ onlyExploreProperties(els) {
85
+ const eps = [];
86
+ for (const el of els) {
87
+ if (ast.isExploreProperty(el)) {
88
+ eps.push(el);
89
+ }
90
+ else {
91
+ this.astError(el, `Expected explore property, not '${el.elementType}'`);
92
+ }
93
+ }
94
+ return eps;
95
+ }
96
+ onlyJoins(els) {
97
+ const eps = [];
98
+ for (const el of els) {
99
+ if (el instanceof ast.Join) {
100
+ eps.push(el);
101
+ }
102
+ else {
103
+ this.astError(el, `Expected explore property, not '${el.elementType}'`);
104
+ }
105
+ }
106
+ return eps;
107
+ }
108
+ onlyDocStatements(els) {
109
+ const eps = [];
110
+ for (const el of els) {
111
+ if (ast.isDocStatement(el)) {
112
+ eps.push(el);
113
+ }
114
+ else {
115
+ this.astError(el, `Expected statement, not '${el.elementType}'`);
116
+ }
117
+ }
118
+ return eps;
119
+ }
120
+ onlyNestedQueries(els) {
121
+ const eps = [];
122
+ for (const el of els) {
123
+ if (ast.isNestedQuery(el)) {
124
+ eps.push(el);
125
+ }
126
+ else {
127
+ this.astError(el, `Expected query, not '${el.elementType}'`);
128
+ }
129
+ }
130
+ return eps;
131
+ }
132
+ onlyQueryRefs(els) {
133
+ const eps = [];
134
+ for (const el of els) {
135
+ if (el instanceof ast.FieldReference ||
136
+ el instanceof ast.FieldDeclaration) {
137
+ eps.push(el);
138
+ }
139
+ else {
140
+ const reported = el instanceof ast.Unimplemented && el.reported;
141
+ if (!reported) {
142
+ this.astError(el, `Expected query field, not '${el.elementType}'`);
143
+ }
144
+ }
145
+ }
146
+ return eps;
147
+ }
148
+ getNumber(term) {
149
+ return Number.parseInt(term.text);
150
+ }
151
+ getIdText(fromTerm) {
152
+ return this.stripQuotes(fromTerm.text);
153
+ }
154
+ getFieldName(cx) {
155
+ return this.astAt(new ast.FieldName(this.getIdText(cx)), cx);
156
+ }
157
+ getModelEntryName(cx) {
158
+ return this.astAt(new ast.ModelEntryReference(this.getIdText(cx)), cx);
159
+ }
160
+ stripQuotes(s) {
161
+ if (s[0] === "`" || s[0] === "'" || s[0] === '"') {
162
+ if (s[0] === s[s.length - 1]) {
163
+ return s.slice(1, -1);
164
+ }
165
+ }
166
+ return s;
167
+ }
168
+ optionalText(idCx) {
169
+ if (idCx) {
170
+ return this.getIdText(idCx);
171
+ }
172
+ return undefined;
173
+ }
174
+ defaultResult() {
175
+ return new ast.Unimplemented();
176
+ }
177
+ astAt(el, cx) {
178
+ el.location = {
179
+ url: this.parse.subTranslator.sourceURL,
180
+ range: this.parse.subTranslator.rangeFromContext(cx),
181
+ };
182
+ return el;
183
+ }
184
+ getSourceCode(cx) {
185
+ const from = cx.start.startIndex;
186
+ const lastToken = cx.stop || cx.start;
187
+ const sourceRange = new Interval_1.Interval(from, lastToken.stopIndex);
188
+ return this.parse.sourceStream.getText(sourceRange);
189
+ }
190
+ getFilterElement(cx) {
191
+ const expr = this.getFieldExpr(cx);
192
+ const fel = new ast.FilterElement(expr, this.getSourceCode(cx));
193
+ return this.astAt(fel, cx);
194
+ }
195
+ getFieldDefs(cxList, isAgg) {
196
+ const visited = [];
197
+ for (const cx of cxList) {
198
+ const v = this.visit(cx);
199
+ if (v instanceof ast.FieldDeclaration) {
200
+ this.astAt(v, cx);
201
+ visited.push(v);
202
+ if (isAgg !== undefined) {
203
+ v.isMeasure = isAgg;
204
+ }
205
+ }
206
+ else {
207
+ this.contextError(cx, "Expected field definition");
208
+ }
209
+ }
210
+ return visited;
211
+ }
212
+ getFieldExpr(cx) {
213
+ const element = this.visit(cx);
214
+ if (element instanceof ast.ExpressionDef) {
215
+ return this.astAt(element, cx);
216
+ }
217
+ throw this.internalError(cx, `expression node unknown type '${element.elementType}'`);
218
+ }
219
+ getSegments(segments) {
220
+ return segments.map((cx) => this.visitQueryProperties(cx.queryProperties()));
221
+ }
222
+ getFilterShortcut(cx) {
223
+ const el = this.getFilterElement(cx.fieldExpr());
224
+ return new ast.Filter([el]);
225
+ }
226
+ getExploreSource(pcx) {
227
+ const element = this.visit(pcx);
228
+ if (element instanceof ast.Mallobj) {
229
+ return element;
230
+ }
231
+ throw this.internalError(pcx, `'${element.elementType}': illegal explore source`);
232
+ }
233
+ visitMalloyDocument(pcx) {
234
+ const stmts = this.onlyDocStatements(pcx.malloyStatement().map((scx) => this.visit(scx)));
235
+ return new ast.Document(stmts);
236
+ }
237
+ visitDefineExploreStatement(pcx) {
238
+ const defsCx = pcx.exploreDefinitionList().exploreDefinition();
239
+ const defs = defsCx.map((dcx) => this.visitExploreDefinition(dcx));
240
+ if (defs.length == 1) {
241
+ return defs[0];
242
+ }
243
+ return new ast.DefineSourceList(defs);
244
+ }
245
+ visitExploreDefinition(pcx) {
246
+ const exploreDef = new ast.DefineExplore(this.getIdText(pcx.exploreNameDef()), this.visitExplore(pcx.explore()), true, []);
247
+ return this.astAt(exploreDef, pcx);
248
+ }
249
+ visitExplore(pcx) {
250
+ const source = this.getExploreSource(pcx.exploreSource());
251
+ const refineCx = pcx.exploreProperties();
252
+ if (refineCx) {
253
+ return this.astAt(new ast.RefinedExplore(source, this.visitExploreProperties(refineCx)), pcx);
254
+ }
255
+ return source;
256
+ }
257
+ visitExploreProperties(pcx) {
258
+ const filterCx = pcx.filterShortcut();
259
+ const visited = pcx.exploreStatement().map((ecx) => this.visit(ecx));
260
+ const propList = new ast.ExploreDesc(this.onlyExploreProperties(visited));
261
+ if (filterCx) {
262
+ propList.push(this.getFilterShortcut(filterCx));
263
+ }
264
+ return propList;
265
+ }
266
+ visitExploreTable(pcx) {
267
+ const tableName = this.stripQuotes(pcx.tableName().text);
268
+ return this.astAt(new ast.TableSource(tableName), pcx);
269
+ }
270
+ visitTableSource(pcx) {
271
+ return this.visitExploreTable(pcx.exploreTable());
272
+ }
273
+ visitSQLSource(pcx) {
274
+ const name = this.getModelEntryName(pcx.sqlExploreNameRef());
275
+ return this.astAt(new ast.SQLSource(name), pcx);
276
+ }
277
+ visitQuerySource(pcx) {
278
+ const query = this.visit(pcx.query());
279
+ if (ast.isQueryElement(query)) {
280
+ return this.astAt(new ast.QuerySource(query), pcx);
281
+ }
282
+ throw this.internalError(pcx, `Expect query definition, got a '${query.elementType}'`);
283
+ }
284
+ visitDefJoinMany(pcx) {
285
+ const joinList = this.getJoinList(pcx.joinList());
286
+ const joins = [];
287
+ for (const join of joinList) {
288
+ if (join instanceof ast.Join) {
289
+ joins.push(join);
290
+ if (join instanceof ast.ExpressionJoin) {
291
+ join.joinType = "many";
292
+ if (join.joinOn == undefined) {
293
+ join.log("join_many: requires ON expression");
294
+ }
295
+ }
296
+ else if (join instanceof ast.KeyJoin) {
297
+ join.log("Foreign key join not legal in join_many:");
298
+ }
299
+ }
300
+ }
301
+ return new ast.Joins(joins);
302
+ }
303
+ visitDefJoinOne(pcx) {
304
+ const joinList = this.getJoinList(pcx.joinList());
305
+ const joins = [];
306
+ for (const join of joinList) {
307
+ if (join instanceof ast.Join) {
308
+ joins.push(join);
309
+ if (join instanceof ast.ExpressionJoin) {
310
+ join.joinType = "one";
311
+ }
312
+ }
313
+ }
314
+ return new ast.Joins(joins);
315
+ }
316
+ visitDefJoinCross(pcx) {
317
+ const joinList = this.getJoinList(pcx.joinList());
318
+ const joins = [];
319
+ for (const join of joinList) {
320
+ if (join instanceof ast.Join) {
321
+ joins.push(join);
322
+ if (join instanceof ast.ExpressionJoin) {
323
+ join.joinType = "cross";
324
+ }
325
+ else {
326
+ join.log("Foreign key join not legal in join_cross:");
327
+ }
328
+ }
329
+ }
330
+ return new ast.Joins(joins);
331
+ }
332
+ getJoinList(pcx) {
333
+ return pcx.joinDef().map((jcx) => this.visit(jcx));
334
+ }
335
+ getJoinSource(name, ecx) {
336
+ if (ecx) {
337
+ return this.visitExplore(ecx);
338
+ }
339
+ return new ast.NamedSource(name);
340
+ }
341
+ visitJoinOn(pcx) {
342
+ const joinAs = this.getModelEntryName(pcx.joinNameDef());
343
+ const joinFrom = this.getJoinSource(joinAs, pcx.explore());
344
+ const join = new ast.ExpressionJoin(joinAs, joinFrom);
345
+ const onCx = pcx.joinExpression();
346
+ if (onCx) {
347
+ join.joinOn = this.getFieldExpr(onCx);
348
+ }
349
+ return this.astAt(join, pcx);
350
+ }
351
+ visitJoinWith(pcx) {
352
+ const joinAs = this.getModelEntryName(pcx.joinNameDef());
353
+ const joinFrom = this.getJoinSource(joinAs, pcx.explore());
354
+ const joinOn = this.getFieldExpr(pcx.fieldExpr());
355
+ const join = new ast.KeyJoin(joinAs, joinFrom, joinOn);
356
+ return this.astAt(join, pcx);
357
+ }
358
+ visitFieldDef(pcx) {
359
+ const defCx = pcx.fieldExpr();
360
+ const fieldName = this.getIdText(pcx.fieldNameDef());
361
+ const valExpr = this.getFieldExpr(defCx);
362
+ const def = new ast.FieldDeclaration(valExpr, fieldName, this.getSourceCode(defCx));
363
+ return this.astAt(def, pcx);
364
+ }
365
+ visitDefExploreDimension(pcx) {
366
+ const defs = this.getFieldDefs(pcx.dimensionDefList().dimensionDef(), false);
367
+ const stmt = new ast.Dimensions(defs);
368
+ return this.astAt(stmt, pcx);
369
+ }
370
+ visitDefExploreMeasure(pcx) {
371
+ const defs = this.getFieldDefs(pcx.measureDefList().measureDef(), true);
372
+ const stmt = new ast.Measures(defs);
373
+ return this.astAt(stmt, pcx);
374
+ }
375
+ visitDeclareStatement(pcx) {
376
+ const defs = this.getFieldDefs(pcx.fieldDef(), true);
377
+ const stmt = new ast.DeclareFields(defs);
378
+ return this.astAt(stmt, pcx);
379
+ }
380
+ visitExploreRenameDef(pcx) {
381
+ const newName = pcx.fieldName(0).id();
382
+ const oldName = pcx.fieldName(1).id();
383
+ const rename = new ast.RenameField(this.getIdText(newName), this.getFieldName(oldName));
384
+ return this.astAt(rename, pcx);
385
+ }
386
+ visitDefExploreRename(pcx) {
387
+ const rcxs = pcx.renameList().exploreRenameDef();
388
+ const renames = rcxs.map((rcx) => this.visitExploreRenameDef(rcx));
389
+ const stmt = new ast.Renames(renames);
390
+ return this.astAt(stmt, pcx);
391
+ }
392
+ visitFilterClauseList(pcx) {
393
+ return new ast.Filter(pcx.fieldExpr().map((f) => this.getFilterElement(f)));
394
+ }
395
+ visitFilterByShortcut(pcx) {
396
+ const el = this.getFilterElement(pcx.fieldExpr());
397
+ return this.astAt(new ast.Filter([el]), pcx);
398
+ }
399
+ visitWhereStatement(pcx) {
400
+ const where = this.visitFilterClauseList(pcx.filterClauseList());
401
+ where.having = false;
402
+ return this.astAt(where, pcx);
403
+ }
404
+ visitHavingStatement(pcx) {
405
+ const having = this.visitFilterClauseList(pcx.filterClauseList());
406
+ having.having = true;
407
+ return this.astAt(having, pcx);
408
+ }
409
+ visitSubQueryDefList(pcx) {
410
+ const babyTurtles = pcx
411
+ .exploreQueryDef()
412
+ .map((cx) => this.visitExploreQueryDef(cx));
413
+ return new ast.Turtles(babyTurtles);
414
+ }
415
+ visitDefExplorePrimaryKey(pcx) {
416
+ const node = new ast.PrimaryKey(this.getFieldName(pcx.fieldName()));
417
+ return this.astAt(node, pcx);
418
+ }
419
+ visitFieldNameList(pcx) {
420
+ const members = pcx
421
+ .fieldName()
422
+ .map((cx) => new ast.FieldReference([this.getFieldName(cx)]));
423
+ return new ast.FieldReferences(members);
424
+ }
425
+ visitDefExploreEditField(pcx) {
426
+ const action = pcx.ACCEPT() ? "accept" : "except";
427
+ return new ast.FieldListEdit(action, this.visitFieldNameList(pcx.fieldNameList()));
428
+ }
429
+ visitQueryProperties(pcx) {
430
+ const qProps = pcx
431
+ .queryStatement()
432
+ .map((qcx) => this.astAt(this.visit(qcx), qcx))
433
+ .filter(function (p) {
434
+ if (ast.isQueryProperty(p)) {
435
+ return true;
436
+ }
437
+ p.log(`Unexpected statement type '${p.elementType}' in query`);
438
+ return false;
439
+ });
440
+ const fcx = pcx.filterShortcut();
441
+ if (fcx) {
442
+ qProps.push(this.getFilterShortcut(fcx));
443
+ }
444
+ return new ast.QOPDesc(qProps);
445
+ }
446
+ visitFieldPath(pcx) {
447
+ const names = pcx.fieldName().map((nameCx) => this.getFieldName(nameCx));
448
+ return this.astAt(new ast.FieldReference(names), pcx);
449
+ }
450
+ visitQueryFieldDef(pcx) {
451
+ const defCx = pcx.dimensionDef().fieldDef();
452
+ const dim = this.visitFieldDef(defCx);
453
+ return this.astAt(dim, defCx);
454
+ }
455
+ visitQueryFieldRef(pcx) {
456
+ return this.visitFieldPath(pcx.fieldPath());
457
+ }
458
+ // visitQueryFieldNameless(
459
+ // pcx: parse.QueryFieldNamelessContext
460
+ // ): ast.MalloyElement {
461
+ // this.contextError(pcx, `Expressions in queries must have names`);
462
+ // const noItem = new ast.Unimplemented();
463
+ // noItem.reported = true;
464
+ // return noItem;
465
+ // }
466
+ getQueryItems(pcx) {
467
+ const itemList = pcx.queryFieldEntry().map((e) => this.visit(e));
468
+ return this.onlyQueryRefs(itemList);
469
+ }
470
+ visitAggregateStatement(pcx) {
471
+ return new ast.Aggregate(this.getQueryItems(pcx.queryFieldList()));
472
+ }
473
+ visitGroupByStatement(pcx) {
474
+ return new ast.GroupBy(this.getQueryItems(pcx.queryFieldList()));
475
+ }
476
+ visitFieldCollection(pcx) {
477
+ const fields = [];
478
+ for (const elCx of pcx.collectionMember()) {
479
+ const el = this.visit(elCx);
480
+ if (ast.isFieldCollectionMember(el)) {
481
+ fields.push(el);
482
+ }
483
+ else {
484
+ throw this.internalError(elCx, `${el.elementType} is not a query field`);
485
+ }
486
+ }
487
+ return this.astAt(new ast.ProjectStatement(fields), pcx);
488
+ }
489
+ visitWildMember(pcx) {
490
+ const nameCx = pcx.fieldPath();
491
+ const stars = pcx.STAR() ? "*" : "**";
492
+ const join = nameCx ? this.visitFieldPath(nameCx) : undefined;
493
+ return new ast.WildcardFieldReference(join, stars);
494
+ }
495
+ visitIndexFields(pcx) {
496
+ const refList = pcx.indexElement().map((el) => {
497
+ const hasStar = el.STAR() != undefined;
498
+ const pathCx = el.fieldPath();
499
+ if (!pathCx) {
500
+ return new ast.WildcardFieldReference(undefined, "*");
501
+ }
502
+ const path = this.visitFieldPath(pathCx);
503
+ if (!hasStar) {
504
+ return this.astAt(path, pcx);
505
+ }
506
+ return this.astAt(new ast.WildcardFieldReference(path, "*"), pcx);
507
+ });
508
+ return new ast.FieldReferences(refList);
509
+ }
510
+ visitIndexStatement(pcx) {
511
+ const fields = this.visitIndexFields(pcx.indexFields());
512
+ const indexStmt = new ast.Index(fields);
513
+ const weightCx = pcx.fieldName();
514
+ if (weightCx) {
515
+ indexStmt.useWeight(this.getFieldName(weightCx));
516
+ }
517
+ return this.astAt(indexStmt, pcx);
518
+ }
519
+ visitLimitStatement(pcx) {
520
+ return new ast.Limit(this.getNumber(pcx.INTEGER_LITERAL()));
521
+ }
522
+ visitOrderBySpec(pcx) {
523
+ const dir = pcx.ASC() ? "asc" : pcx.DESC() ? "desc" : undefined;
524
+ const ncx = pcx.INTEGER_LITERAL();
525
+ if (ncx) {
526
+ return new ast.OrderBy(this.getNumber(ncx), dir);
527
+ }
528
+ const fieldCx = pcx.fieldName();
529
+ if (fieldCx) {
530
+ return new ast.OrderBy(this.getFieldName(fieldCx), dir);
531
+ }
532
+ throw this.internalError(pcx, "can't parse order_by specification");
533
+ }
534
+ visitOrdering(pcx) {
535
+ const orderList = pcx.orderBySpec().map((o) => this.visitOrderBySpec(o));
536
+ return this.astAt(new ast.Ordering(orderList), pcx);
537
+ }
538
+ visitTopStatement(pcx) {
539
+ const byCx = pcx.bySpec();
540
+ const topN = this.getNumber(pcx.INTEGER_LITERAL());
541
+ let top;
542
+ if (byCx) {
543
+ const nameCx = byCx.fieldName();
544
+ if (nameCx) {
545
+ const name = this.getFieldName(nameCx);
546
+ top = new ast.Top(topN, name);
547
+ }
548
+ const exprCx = byCx.fieldExpr();
549
+ if (exprCx) {
550
+ top = new ast.Top(topN, this.getFieldExpr(exprCx));
551
+ }
552
+ }
553
+ if (!top) {
554
+ top = new ast.Top(topN, undefined);
555
+ }
556
+ return this.astAt(top, pcx);
557
+ }
558
+ visitExploreName(pcx) {
559
+ const name = this.getModelEntryName(pcx.id());
560
+ return this.astAt(new ast.NamedSource(name), pcx);
561
+ }
562
+ buildPipelineFromName(pipe, pipeCx) {
563
+ const firstCx = pipeCx.firstSegment();
564
+ const nameCx = firstCx.exploreQueryName();
565
+ if (nameCx) {
566
+ pipe.turtleName = this.getFieldName(nameCx);
567
+ }
568
+ const propsCx = firstCx.queryProperties();
569
+ if (propsCx) {
570
+ const queryDesc = this.visitQueryProperties(propsCx);
571
+ if (nameCx) {
572
+ pipe.refineHead(queryDesc);
573
+ }
574
+ else {
575
+ pipe.addSegments(queryDesc);
576
+ }
577
+ }
578
+ const tail = this.getSegments(pipeCx.pipeElement());
579
+ pipe.addSegments(...tail);
580
+ }
581
+ visitExploreArrowQuery(pcx) {
582
+ const root = this.visitExplore(pcx.explore());
583
+ const query = new ast.FullQuery(root);
584
+ this.buildPipelineFromName(query, pcx.pipelineFromName());
585
+ return this.astAt(query, pcx);
586
+ }
587
+ visitArrowQuery(pcx) {
588
+ const query = new ast.ExistingQuery();
589
+ query.head = this.getModelEntryName(pcx.queryName());
590
+ const refCx = pcx.queryProperties();
591
+ if (refCx) {
592
+ query.refineHead(this.visitQueryProperties(refCx));
593
+ }
594
+ query.addSegments(...this.getSegments(pcx.pipeElement()));
595
+ return this.astAt(query, pcx);
596
+ }
597
+ visitTopLevelQueryDefs(pcx) {
598
+ const stmts = pcx
599
+ .topLevelQueryDef()
600
+ .map((cx) => this.visitTopLevelQueryDef(cx));
601
+ if (stmts.length === 1) {
602
+ return stmts[0];
603
+ }
604
+ return new ast.DefineQueryList(stmts);
605
+ }
606
+ visitTopLevelQueryDef(pcx) {
607
+ const queryName = this.getIdText(pcx.queryName());
608
+ const queryDef = this.visit(pcx.query());
609
+ if (ast.isQueryElement(queryDef)) {
610
+ return this.astAt(new ast.DefineQuery(queryName, queryDef), pcx);
611
+ }
612
+ throw this.internalError(pcx, `Expect query definition, got a '${queryDef.elementType}'`);
613
+ }
614
+ visitAnonymousQuery(pcx) {
615
+ const query = this.visit(pcx.topLevelAnonQueryDef().query());
616
+ if (ast.isQueryElement(query)) {
617
+ return new ast.AnonymousQuery(query);
618
+ }
619
+ throw this.internalError(pcx, `Anonymous query matched, but ${query.elementType} found`);
620
+ }
621
+ visitNestedQueryList(pcx) {
622
+ const nestedList = pcx.nestEntry().map((cx) => this.visit(cx));
623
+ if (nestedList.length == 1) {
624
+ return nestedList[0];
625
+ }
626
+ return new ast.Nests(this.onlyNestedQueries(nestedList));
627
+ }
628
+ visitNestExisting(pcx) {
629
+ const name = this.getFieldName(pcx.queryName());
630
+ const propsCx = pcx.queryProperties();
631
+ if (propsCx) {
632
+ const nestRefine = new ast.NestRefinement(name);
633
+ const queryDesc = this.visitQueryProperties(propsCx);
634
+ nestRefine.refineHead(queryDesc);
635
+ return this.astAt(nestRefine, pcx);
636
+ }
637
+ return this.astAt(new ast.NestReference(name), pcx);
638
+ }
639
+ visitNestDef(pcx) {
640
+ const name = this.getIdText(pcx.queryName());
641
+ const nestDef = new ast.NestDefinition(name);
642
+ this.buildPipelineFromName(nestDef, pcx.pipelineFromName());
643
+ return this.astAt(nestDef, pcx);
644
+ }
645
+ visitExploreQueryDef(pcx) {
646
+ const name = this.getIdText(pcx.exploreQueryNameDef());
647
+ const queryDef = new ast.TurtleDecl(name);
648
+ this.buildPipelineFromName(queryDef, pcx.pipelineFromName());
649
+ return this.astAt(queryDef, pcx);
650
+ }
651
+ visitExprNot(pcx) {
652
+ return new ast.ExprNot(this.getFieldExpr(pcx.fieldExpr()));
653
+ }
654
+ visitExprBool(pcx) {
655
+ return new ast.Boolean(pcx.TRUE() ? "true" : "false");
656
+ }
657
+ allFieldExpressions(exprList) {
658
+ return exprList.map((ecx) => this.getFieldExpr(ecx));
659
+ }
660
+ visitExprLogical(pcx) {
661
+ const left = this.getFieldExpr(pcx.fieldExpr(0));
662
+ const right = this.getFieldExpr(pcx.fieldExpr(1));
663
+ return new ast.ExprLogicalOp(left, pcx.AND() ? "and" : "or", right);
664
+ }
665
+ visitExprLogicalTree(pcx) {
666
+ const left = this.getFieldExpr(pcx.fieldExpr());
667
+ const right = this.getFieldExpr(pcx.partialAllowedFieldExpr());
668
+ return new ast.ExprAlternationTree(left, pcx.AMPER() ? "&" : "|", right);
669
+ }
670
+ visitExprNotPartial(pcx) {
671
+ return this.getFieldExpr(pcx.fieldExpr());
672
+ }
673
+ visitExprPartialCompare(pcx) {
674
+ const op = pcx.compareOp().text;
675
+ if (ast.isComparison(op)) {
676
+ return new ast.PartialCompare(op, this.getFieldExpr(pcx.fieldExpr()));
677
+ }
678
+ throw this.internalError(pcx, `partial comparison '${op}' not recognized`);
679
+ }
680
+ visitExprString(pcx) {
681
+ return new ast.ExprString(pcx.STRING_LITERAL().text);
682
+ }
683
+ visitExprRegex(pcx) {
684
+ const malloyRegex = pcx.HACKY_REGEX().text;
685
+ return new ast.ExprRegEx(this.stripQuotes(malloyRegex.slice(1)));
686
+ }
687
+ visitExprNow(_pcx) {
688
+ return new ast.ExprNow();
689
+ }
690
+ visitExprNumber(pcx) {
691
+ var _a, _b;
692
+ const number = ((_a = pcx.INTEGER_LITERAL()) === null || _a === void 0 ? void 0 : _a.text) || ((_b = pcx.NUMERIC_LITERAL()) === null || _b === void 0 ? void 0 : _b.text);
693
+ /*
694
+ * I "know" one of these is true because grammar, but Typescript
695
+ * rightly points out that grammvisitExprFieldPathar can change in unexpected ways
696
+ */
697
+ if (number) {
698
+ return new ast.ExprNumber(number);
699
+ }
700
+ else {
701
+ this.contextError(pcx, `'${pcx.text}' is not a number`);
702
+ return new ast.ExprNumber("42");
703
+ }
704
+ }
705
+ visitExprFieldPath(pcx) {
706
+ const idRef = new ast.ExprIdReference(this.visitFieldPath(pcx.fieldPath()));
707
+ return this.astAt(idRef, pcx);
708
+ }
709
+ visitExprNULL(_pcx) {
710
+ return new ast.ExprNULL();
711
+ }
712
+ visitExprExpr(pcx) {
713
+ return new ast.ExprParens(this.getFieldExpr(pcx.partialAllowedFieldExpr()));
714
+ }
715
+ visitExprMinus(pcx) {
716
+ return new ast.ExprMinus(this.getFieldExpr(pcx.fieldExpr()));
717
+ }
718
+ visitExprAddSub(pcx) {
719
+ const lhs = this.getFieldExpr(pcx.fieldExpr(0));
720
+ const rhs = this.getFieldExpr(pcx.fieldExpr(1));
721
+ const op = pcx.PLUS() ? "+" : "-";
722
+ return new ast.ExprAddSub(lhs, op, rhs);
723
+ }
724
+ visitExprMulDiv(pcx) {
725
+ return new ast.ExprMulDiv(this.getFieldExpr(pcx.fieldExpr(0)), pcx.STAR() ? "*" : "/", this.getFieldExpr(pcx.fieldExpr(1)));
726
+ }
727
+ visitExprCompare(pcx) {
728
+ const op = pcx.compareOp().text;
729
+ if (ast.isComparison(op)) {
730
+ return new ast.ExprCompare(this.getFieldExpr(pcx.fieldExpr(0)), op, this.getFieldExpr(pcx.fieldExpr(1)));
731
+ }
732
+ throw this.internalError(pcx, `untranslatable comparison operator '${op}'`);
733
+ }
734
+ visitExprCountDisinct(pcx) {
735
+ return this.astAt(new ast.ExprCountDistinct(this.getFieldExpr(pcx.fieldExpr())), pcx);
736
+ }
737
+ visitExprUngroup(pcx) {
738
+ const flist = pcx.fieldName().map((fcx) => this.getFieldName(fcx));
739
+ const kw = this.getIdText(pcx.ungroup()).toLocaleLowerCase();
740
+ return this.astAt(new ast.ExprUngroup(kw == "all" ? kw : "exclude", this.getFieldExpr(pcx.fieldExpr()), flist), pcx);
741
+ }
742
+ visitExprAggregate(pcx) {
743
+ const pathCx = pcx.fieldPath();
744
+ const path = pathCx ? this.visitFieldPath(pathCx) : undefined;
745
+ const source = pathCx && path ? this.astAt(path, pathCx) : undefined;
746
+ const exprDef = pcx.fieldExpr();
747
+ if (pcx.aggregate().COUNT()) {
748
+ if (exprDef) {
749
+ this.contextError(exprDef, "Ignored expression inside COUNT()");
750
+ }
751
+ return new ast.ExprCount(source);
752
+ }
753
+ // * was ok in count, not ok now ... this should be in grammer but at
754
+ // the moment while things are still changing its right to be caught here
755
+ const star = pcx.STAR();
756
+ if (star) {
757
+ this.contextError(pcx, "'*' is not a valid expression");
758
+ }
759
+ const expr = exprDef ? this.getFieldExpr(exprDef) : undefined;
760
+ if (pcx.aggregate().MIN()) {
761
+ if (path) {
762
+ this.contextError(pcx, `Path not legal for min()`);
763
+ }
764
+ else if (expr) {
765
+ return new ast.ExprMin(expr);
766
+ }
767
+ else {
768
+ this.contextError(pcx, "Missing expression for min");
769
+ }
770
+ }
771
+ else if (pcx.aggregate().MAX()) {
772
+ if (path) {
773
+ this.contextError(pcx, `Path not legal for max()`);
774
+ }
775
+ else if (expr) {
776
+ return new ast.ExprMax(expr);
777
+ }
778
+ else {
779
+ this.contextError(pcx, "Missing expression for max");
780
+ }
781
+ }
782
+ else if (pcx.aggregate().AVG()) {
783
+ return new ast.ExprAvg(expr, source);
784
+ }
785
+ else if (pcx.aggregate().SUM()) {
786
+ return new ast.ExprSum(expr, source);
787
+ }
788
+ return new ast.ExprNULL();
789
+ }
790
+ visitExprApply(pcx) {
791
+ if (pcx.COLON()) {
792
+ this.contextError(pcx, "':' for apply is deprecated, use '?'", "warn");
793
+ }
794
+ return new ast.Apply(this.getFieldExpr(pcx.fieldExpr()), this.getFieldExpr(pcx.partialAllowedFieldExpr()));
795
+ }
796
+ visitExprRange(pcx) {
797
+ return new ast.Range(this.getFieldExpr(pcx.fieldExpr(0)), this.getFieldExpr(pcx.fieldExpr(1)));
798
+ }
799
+ visitExprCast(pcx) {
800
+ const type = pcx.malloyType().text;
801
+ if (ast.isCastType(type)) {
802
+ return new ast.ExprCast(this.getFieldExpr(pcx.fieldExpr()), type);
803
+ }
804
+ this.contextError(pcx, `CAST to unknown type '${type}'`);
805
+ return new ast.ExprNULL();
806
+ }
807
+ visitExprSafeCast(pcx) {
808
+ const type = pcx.malloyType().text;
809
+ if (ast.isCastType(type)) {
810
+ return new ast.ExprCast(this.getFieldExpr(pcx.fieldExpr()), type, true);
811
+ }
812
+ this.contextError(pcx, `'::' cast to unknown type '${type}'`);
813
+ return new ast.ExprNULL();
814
+ }
815
+ visitExprTimeTrunc(pcx) {
816
+ return new ast.ExprGranularTime(this.getFieldExpr(pcx.fieldExpr()), this.visitTimeframe(pcx.timeframe()).text, true);
817
+ }
818
+ visitTimeframe(pcx) {
819
+ return new ast.Timeframe(pcx.text);
820
+ }
821
+ visitExprForRange(pcx) {
822
+ const begin = this.getFieldExpr(pcx._startAt);
823
+ const duration = this.getFieldExpr(pcx._duration);
824
+ const units = this.visitTimeframe(pcx.timeframe());
825
+ return new ast.ForRange(begin, duration, units);
826
+ }
827
+ visitExprFunc(pcx) {
828
+ const argsCx = pcx.argumentList();
829
+ const args = argsCx ? this.allFieldExpressions(argsCx.fieldExpr()) : [];
830
+ const idCx = pcx.id();
831
+ const dCx = pcx.timeframe();
832
+ let fn;
833
+ if (idCx) {
834
+ fn = this.getIdText(idCx);
835
+ }
836
+ else if (dCx) {
837
+ fn = dCx.text;
838
+ }
839
+ else {
840
+ this.contextError(pcx, "Funciton name error");
841
+ fn = "FUNCTION_NAME_ERROR";
842
+ }
843
+ if (ast.ExprTimeExtract.extractor(fn)) {
844
+ return this.astAt(new ast.ExprTimeExtract(fn, args), pcx);
845
+ }
846
+ return this.astAt(new ast.ExprFunc(fn, args), pcx);
847
+ }
848
+ visitExprDuration(pcx) {
849
+ return new ast.ExprDuration(this.getFieldExpr(pcx.fieldExpr()), this.visitTimeframe(pcx.timeframe()).text);
850
+ }
851
+ visitPickStatement(pcx) {
852
+ const picks = pcx.pick().map((pwCx) => {
853
+ let pickExpr;
854
+ if (pwCx._pickValue) {
855
+ pickExpr = this.getFieldExpr(pwCx._pickValue);
856
+ }
857
+ return new ast.PickWhen(pickExpr, this.getFieldExpr(pwCx._pickWhen));
858
+ });
859
+ if (pcx.ELSE()) {
860
+ return new ast.Pick(picks, this.getFieldExpr(pcx._pickElse));
861
+ }
862
+ return new ast.Pick(picks);
863
+ }
864
+ visitNamedSource(pcx) {
865
+ const name = this.getModelEntryName(pcx.exploreName());
866
+ // Parameters ... coming ...
867
+ // const paramListCx = pcx.isParam();
868
+ // if (paramListCx) {
869
+ // const paramInit: Record<string, ast.ConstantSubExpression> = {};
870
+ // for (const cx of paramListCx) {
871
+ // const pName = this.identifer(cx.id());
872
+ // const pVal = this.getFieldExpr(cx.isExpr().partialAllowedFieldExpr());
873
+ // paramInit[pName] = new ast.ConstantSubExpression(pVal);
874
+ // }
875
+ // return this.astAt(new ast.NamedSource(name, paramInit), pcx);
876
+ // }
877
+ return this.astAt(new ast.NamedSource(name), pcx);
878
+ }
879
+ visitExprFilter(pcx) {
880
+ const filters = this.visit(pcx.filteredBy());
881
+ return new ast.ExprFilter(this.getFieldExpr(pcx.fieldExpr()), filters);
882
+ }
883
+ getLiteralTime(cx) {
884
+ const parsed = ast.GranularLiteral.parse(cx.text);
885
+ if (parsed === undefined) {
886
+ this.contextError(cx, `${cx.text} is not a legal day specification`);
887
+ return new ast.ExprNow();
888
+ }
889
+ return parsed;
890
+ }
891
+ visitLiteralTimestamp(pcx) {
892
+ return this.getLiteralTime(pcx);
893
+ }
894
+ visitLiteralDay(pcx) {
895
+ return this.getLiteralTime(pcx);
896
+ }
897
+ visitLiteralWeek(pcx) {
898
+ return this.getLiteralTime(pcx);
899
+ }
900
+ visitLiteralMonth(pcx) {
901
+ return this.getLiteralTime(pcx);
902
+ }
903
+ visitLiteralQuarter(pcx) {
904
+ return this.getLiteralTime(pcx);
905
+ }
906
+ visitLiteralYear(pcx) {
907
+ return this.getLiteralTime(pcx);
908
+ }
909
+ visitImportStatement(pcx) {
910
+ const url = this.stripQuotes(pcx.importURL().text);
911
+ return this.astAt(new ast.ImportStatement(url, this.parse.subTranslator.sourceURL), pcx);
912
+ }
913
+ visitJustExpr(pcx) {
914
+ return this.getFieldExpr(pcx.fieldExpr());
915
+ }
916
+ visitDefineSQLStatement(pcx) {
917
+ return this.visitSQLStatementDef(pcx.sqlStatementDef());
918
+ }
919
+ visitSQLStatementDef(pcx) {
920
+ const commands = pcx.sqlBlock().text;
921
+ const sqlStmt = new ast.SQLStatement({
922
+ select: commands.slice(2, commands.length - 2),
923
+ connection: this.optionalText(pcx.connectionName()),
924
+ });
925
+ const nameCx = pcx.sqlCommandNameDef();
926
+ if (nameCx) {
927
+ sqlStmt.is = this.getIdText(nameCx);
928
+ }
929
+ return this.astAt(sqlStmt, pcx);
930
+ }
931
+ visitSampleStatement(pcx) {
932
+ const rowCx = pcx.sampleSpec().INTEGER_LITERAL();
933
+ if (rowCx) {
934
+ return new ast.SampleProperty({ rows: this.getNumber(rowCx) });
935
+ }
936
+ const limitCx = pcx.sampleSpec().PERCENT_LITERAL();
937
+ if (limitCx) {
938
+ return new ast.SampleProperty({ percent: this.getNumber(limitCx) });
939
+ }
940
+ const enabled = pcx.sampleSpec().TRUE() != undefined;
941
+ return new ast.SampleProperty({ enable: enabled });
942
+ }
943
+ }
944
+ exports.MalloyToAST = MalloyToAST;
945
+ //# sourceMappingURL=parse-to-ast.js.map