generateParsers.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Licensed to Cloudera, Inc. under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. Cloudera, Inc. licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. /* eslint-disable no-restricted-syntax */
  17. import { identifySqlParsers } from './parserDefinitions.js';
  18. import { deleteFile, readFile, writeFile } from './utils.js';
  19. import jisonCli from 'jison/lib/cli.js';
  20. const findParsersToGenerateFromArgs = parserDefinitions => {
  21. process.argv.shift(); // drop "node"
  22. process.argv.shift(); // drop "generateParsers.js"
  23. const foundDefinitions = new Set();
  24. const invalid = [];
  25. if (process.argv[0] === 'all') {
  26. Object.values(parserDefinitions).forEach(definition => foundDefinitions.add(definition));
  27. } else {
  28. process.argv.forEach(arg => {
  29. if (parserDefinitions[arg]) {
  30. foundDefinitions.add(parserDefinitions[arg]);
  31. } else {
  32. let found = false;
  33. Object.keys(parserDefinitions).forEach(key => {
  34. if (key.indexOf(arg) === 0) {
  35. found = true;
  36. foundDefinitions.add(parserDefinitions[key]);
  37. }
  38. });
  39. if (!found) {
  40. invalid.push(arg);
  41. }
  42. }
  43. });
  44. }
  45. if (invalid.length) {
  46. throw new Error(`Could not find parser definitions for '${invalid.join(", '")}'`);
  47. }
  48. return [...foundDefinitions];
  49. };
  50. const getConcatenatedContent = async sources => {
  51. const contents = [];
  52. for (const source of sources) {
  53. // We know the file exists, verified in parserDefinitions.js
  54. contents.push(await readFile(source));
  55. }
  56. return contents.join();
  57. };
  58. const generateParser = async parserDefinition => {
  59. const jisonContents = await getConcatenatedContent(parserDefinition.sources);
  60. await writeFile(parserDefinition.targetJison, jisonContents);
  61. const generatedParserFileName = `${parserDefinition.parserName}.js`;
  62. const options = {
  63. file: parserDefinition.targetJison,
  64. outfile: generatedParserFileName,
  65. 'module-type': 'js'
  66. };
  67. if (parserDefinition.lexer) {
  68. options.lexfile = parserDefinition.lexer;
  69. }
  70. try {
  71. jisonCli.main(options); // Writes the generated parser in the current folder
  72. } catch (err) {
  73. console.error('Failed calling jison cli');
  74. throw err;
  75. }
  76. // Remove the concatenated jison file
  77. deleteFile(parserDefinition.targetJison);
  78. const generatedFileContents = await readFile(generatedParserFileName);
  79. const modifiedContents = await parserDefinition.afterParse(generatedFileContents);
  80. // Write a modified version of the parser to the defined outputFolder
  81. await writeFile(`${parserDefinition.outputFolder}/${generatedParserFileName}`, modifiedContents);
  82. // Remove the generated parser
  83. deleteFile(generatedParserFileName);
  84. };
  85. try {
  86. console.log('Identifying parsers...');
  87. const parserDefinitions = await identifySqlParsers();
  88. const definitionsToGenerate = findParsersToGenerateFromArgs(parserDefinitions);
  89. const totalParserCount = definitionsToGenerate.length;
  90. if (totalParserCount > 1) {
  91. console.log(`Generating ${totalParserCount} parser(s)...`);
  92. }
  93. for (let i = 0; i < definitionsToGenerate.length; i++) {
  94. const parserDefinition = definitionsToGenerate[i];
  95. console.log(
  96. `Generating "${parserDefinition.parserName}"${
  97. definitionsToGenerate.length > 1 ? ` (${i + 1}/${totalParserCount})` : ''
  98. }...`
  99. );
  100. await generateParser(parserDefinition);
  101. }
  102. console.log('Done!');
  103. } catch (err) {
  104. console.log(err);
  105. }
  106. /* eslint-enable no-restricted-syntax */