/src/main/java/io/proleap/cobol/asg/metamodel/data/datadescription/impl/DataDescriptionEntryContainerImpl.java

https://github.com/uwol/proleap-cobol-parser · Java · 479 lines · 308 code · 95 blank · 76 comment · 71 complexity · e242731dad62de1106247bec969b5bc9 MD5 · raw file

  1. /*
  2. * Copyright (C) 2017, Ulrich Wolffgang <ulrich.wolffgang@proleap.io>
  3. * All rights reserved.
  4. *
  5. * This software may be modified and distributed under the terms
  6. * of the MIT license. See the LICENSE file for details.
  7. */
  8. package io.proleap.cobol.asg.metamodel.data.datadescription.impl;
  9. import java.util.ArrayList;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Map;
  13. import org.antlr.v4.runtime.ParserRuleContext;
  14. import org.slf4j.Logger;
  15. import org.slf4j.LoggerFactory;
  16. import io.proleap.cobol.CobolParser.DataAlignedClauseContext;
  17. import io.proleap.cobol.CobolParser.DataBlankWhenZeroClauseContext;
  18. import io.proleap.cobol.CobolParser.DataCommonOwnLocalClauseContext;
  19. import io.proleap.cobol.CobolParser.DataDescriptionEntryContext;
  20. import io.proleap.cobol.CobolParser.DataDescriptionEntryExecSqlContext;
  21. import io.proleap.cobol.CobolParser.DataDescriptionEntryFormat1Context;
  22. import io.proleap.cobol.CobolParser.DataDescriptionEntryFormat2Context;
  23. import io.proleap.cobol.CobolParser.DataDescriptionEntryFormat3Context;
  24. import io.proleap.cobol.CobolParser.DataExternalClauseContext;
  25. import io.proleap.cobol.CobolParser.DataGlobalClauseContext;
  26. import io.proleap.cobol.CobolParser.DataIntegerStringClauseContext;
  27. import io.proleap.cobol.CobolParser.DataJustifiedClauseContext;
  28. import io.proleap.cobol.CobolParser.DataOccursClauseContext;
  29. import io.proleap.cobol.CobolParser.DataPictureClauseContext;
  30. import io.proleap.cobol.CobolParser.DataReceivedByClauseContext;
  31. import io.proleap.cobol.CobolParser.DataRecordAreaClauseContext;
  32. import io.proleap.cobol.CobolParser.DataRedefinesClauseContext;
  33. import io.proleap.cobol.CobolParser.DataSignClauseContext;
  34. import io.proleap.cobol.CobolParser.DataSynchronizedClauseContext;
  35. import io.proleap.cobol.CobolParser.DataThreadLocalClauseContext;
  36. import io.proleap.cobol.CobolParser.DataTypeClauseContext;
  37. import io.proleap.cobol.CobolParser.DataTypeDefClauseContext;
  38. import io.proleap.cobol.CobolParser.DataUsageClauseContext;
  39. import io.proleap.cobol.CobolParser.DataUsingClauseContext;
  40. import io.proleap.cobol.CobolParser.DataValueClauseContext;
  41. import io.proleap.cobol.CobolParser.DataWithLowerBoundsClauseContext;
  42. import io.proleap.cobol.asg.metamodel.ProgramUnit;
  43. import io.proleap.cobol.asg.metamodel.data.datadescription.DataDescriptionEntriesSymbolTableEntry;
  44. import io.proleap.cobol.asg.metamodel.data.datadescription.DataDescriptionEntry;
  45. import io.proleap.cobol.asg.metamodel.data.datadescription.DataDescriptionEntryCondition;
  46. import io.proleap.cobol.asg.metamodel.data.datadescription.DataDescriptionEntryContainer;
  47. import io.proleap.cobol.asg.metamodel.data.datadescription.DataDescriptionEntryExecSql;
  48. import io.proleap.cobol.asg.metamodel.data.datadescription.DataDescriptionEntryGroup;
  49. import io.proleap.cobol.asg.metamodel.data.datadescription.DataDescriptionEntryRename;
  50. import io.proleap.cobol.asg.metamodel.impl.CobolDivisionElementImpl;
  51. import io.proleap.cobol.asg.util.AsgStringUtils;
  52. import io.proleap.cobol.asg.util.TagUtils;
  53. import io.proleap.cobol.preprocessor.CobolPreprocessor;
  54. public abstract class DataDescriptionEntryContainerImpl extends CobolDivisionElementImpl
  55. implements DataDescriptionEntryContainer {
  56. private final static Logger LOG = LoggerFactory.getLogger(DataDescriptionEntryContainerImpl.class);
  57. protected List<DataDescriptionEntry> dataDescriptionEntries = new ArrayList<DataDescriptionEntry>();
  58. protected Map<String, DataDescriptionEntriesSymbolTableEntry> dataDescriptionEntriesSymbolTable = new HashMap<String, DataDescriptionEntriesSymbolTableEntry>();
  59. public DataDescriptionEntryContainerImpl(final ProgramUnit programUnit, final ParserRuleContext ctx) {
  60. super(programUnit, ctx);
  61. }
  62. @Override
  63. public DataDescriptionEntryCondition addDataDescriptionEntryCondition(
  64. final DataDescriptionEntryFormat3Context ctx) {
  65. DataDescriptionEntryCondition result = (DataDescriptionEntryCondition) getASGElement(ctx);
  66. if (result == null) {
  67. final String name = determineName(ctx);
  68. result = new DataDescriptionEntryConditionImpl(name, this, programUnit, ctx);
  69. result.setLevelNumber(DataDescriptionEntry.LEVEL_NUMBER_CONDITION);
  70. result.addValueClause(ctx.dataValueClause());
  71. registerASGElement(result);
  72. dataDescriptionEntries.add(result);
  73. assureDataDescriptionEntriesSymbolTableEntry(name).addDataDescriptionEntry(result);
  74. }
  75. return result;
  76. }
  77. @Override
  78. public DataDescriptionEntryExecSql addDataDescriptionEntryExecSql(final DataDescriptionEntryExecSqlContext ctx) {
  79. DataDescriptionEntryExecSql result = (DataDescriptionEntryExecSql) getASGElement(ctx);
  80. if (result == null) {
  81. result = new DataDescriptionEntryExecSqlImpl(this, programUnit, ctx);
  82. final String execSqlText = TagUtils.getUntaggedText(ctx.EXECSQLLINE(), CobolPreprocessor.EXEC_SQL_TAG,
  83. CobolPreprocessor.EXEC_END_TAG);
  84. result.setExecSqlText(execSqlText);
  85. registerASGElement(result);
  86. dataDescriptionEntries.add(result);
  87. }
  88. return result;
  89. }
  90. @Override
  91. public DataDescriptionEntryGroup addDataDescriptionEntryGroup(final DataDescriptionEntryFormat1Context ctx) {
  92. DataDescriptionEntryGroup result = (DataDescriptionEntryGroup) getASGElement(ctx);
  93. if (result == null) {
  94. final String name = determineName(ctx);
  95. result = new DataDescriptionEntryGroupImpl(name, this, programUnit, ctx);
  96. /*
  97. * level number
  98. */
  99. final Integer levelNumber;
  100. if (ctx.LEVEL_NUMBER_77() != null) {
  101. levelNumber = DataDescriptionEntry.LEVEL_NUMBER_SCALAR;
  102. } else if (ctx.INTEGERLITERAL() != null) {
  103. levelNumber = AsgStringUtils.parseInteger(ctx.INTEGERLITERAL().getText());
  104. } else {
  105. levelNumber = null;
  106. }
  107. result.setLevelNumber(levelNumber);
  108. /*
  109. * filler
  110. */
  111. if (ctx.FILLER() != null) {
  112. result.setFiller(true);
  113. result.setFillerNumber(compilationUnit.incrementFillerCounter());
  114. }
  115. /*
  116. * aligned clause
  117. */
  118. final List<DataAlignedClauseContext> dataAlignedClauseContexts = ctx.dataAlignedClause();
  119. if (!dataAlignedClauseContexts.isEmpty()) {
  120. final DataAlignedClauseContext dataAlignedClauseContext = dataAlignedClauseContexts.get(0);
  121. result.addAlignedClause(dataAlignedClauseContext);
  122. }
  123. /*
  124. * blank when zero clause
  125. */
  126. final List<DataBlankWhenZeroClauseContext> dataBlankWhenZeroClauseContexts = ctx.dataBlankWhenZeroClause();
  127. if (!dataBlankWhenZeroClauseContexts.isEmpty()) {
  128. final DataBlankWhenZeroClauseContext dataBlankWhenZeroClauseContext = dataBlankWhenZeroClauseContexts
  129. .get(0);
  130. result.addBlankWhenZeroClause(dataBlankWhenZeroClauseContext);
  131. }
  132. /*
  133. * common own local clause
  134. */
  135. final List<DataCommonOwnLocalClauseContext> dataCommonOwnLocalClauseContexts = ctx
  136. .dataCommonOwnLocalClause();
  137. if (!dataCommonOwnLocalClauseContexts.isEmpty()) {
  138. final DataCommonOwnLocalClauseContext dataCommonOwnLocalClauseContext = dataCommonOwnLocalClauseContexts
  139. .get(0);
  140. result.addCommonOwnLocalClause(dataCommonOwnLocalClauseContext);
  141. }
  142. /*
  143. * external clause
  144. */
  145. final List<DataExternalClauseContext> dataExternalClauseContexts = ctx.dataExternalClause();
  146. if (!dataExternalClauseContexts.isEmpty()) {
  147. final DataExternalClauseContext dataExternalClauseContext = dataExternalClauseContexts.get(0);
  148. result.addExternalClause(dataExternalClauseContext);
  149. }
  150. /*
  151. * global clause
  152. */
  153. final List<DataGlobalClauseContext> dataGlobalClauseContexts = ctx.dataGlobalClause();
  154. if (!dataGlobalClauseContexts.isEmpty()) {
  155. final DataGlobalClauseContext dataGlobalClauseContext = dataGlobalClauseContexts.get(0);
  156. result.addGlobalClause(dataGlobalClauseContext);
  157. }
  158. /*
  159. * data integer string clause
  160. */
  161. final List<DataIntegerStringClauseContext> dataIntegerStringClauseContexts = ctx.dataIntegerStringClause();
  162. if (!dataIntegerStringClauseContexts.isEmpty()) {
  163. final DataIntegerStringClauseContext dataIntegerStringClauseContext = dataIntegerStringClauseContexts
  164. .get(0);
  165. result.addIntegerStringClause(dataIntegerStringClauseContext);
  166. }
  167. /*
  168. * justified clause
  169. */
  170. final List<DataJustifiedClauseContext> dataJustifiedClauseContexts = ctx.dataJustifiedClause();
  171. if (!dataJustifiedClauseContexts.isEmpty()) {
  172. final DataJustifiedClauseContext dataJustifiedClauseContext = dataJustifiedClauseContexts.get(0);
  173. result.addJustifiedClause(dataJustifiedClauseContext);
  174. }
  175. /*
  176. * occurs clause
  177. */
  178. final List<DataOccursClauseContext> dataOccursClauseContexts = ctx.dataOccursClause();
  179. for (final DataOccursClauseContext dataOccursClauseContext : dataOccursClauseContexts) {
  180. result.addOccursClause(dataOccursClauseContext);
  181. }
  182. /*
  183. * picture clause
  184. */
  185. final List<DataPictureClauseContext> dataPictureClauseContexts = ctx.dataPictureClause();
  186. if (!dataPictureClauseContexts.isEmpty()) {
  187. final DataPictureClauseContext dataPictureClauseContext = ctx.dataPictureClause().get(0);
  188. result.addPictureClause(dataPictureClauseContext);
  189. }
  190. /*
  191. * received by clause
  192. */
  193. final List<DataReceivedByClauseContext> dataReceivedByClauseContexts = ctx.dataReceivedByClause();
  194. if (!dataReceivedByClauseContexts.isEmpty()) {
  195. final DataReceivedByClauseContext dataReceivedByClauseContext = dataReceivedByClauseContexts.get(0);
  196. result.addReceivedByClause(dataReceivedByClauseContext);
  197. }
  198. /*
  199. * record area clause
  200. */
  201. final List<DataRecordAreaClauseContext> dataRecordAreaClauseContexts = ctx.dataRecordAreaClause();
  202. if (!dataRecordAreaClauseContexts.isEmpty()) {
  203. final DataRecordAreaClauseContext dataRecordAreaClauseContext = dataRecordAreaClauseContexts.get(0);
  204. result.addRecordAreaClause(dataRecordAreaClauseContext);
  205. }
  206. /*
  207. * redefines clause
  208. */
  209. final List<DataRedefinesClauseContext> dataRedefinesClauseContexts = ctx.dataRedefinesClause();
  210. if (!dataRedefinesClauseContexts.isEmpty()) {
  211. final DataRedefinesClauseContext dataRedefinesClauseContext = dataRedefinesClauseContexts.get(0);
  212. result.addRedefinesClause(dataRedefinesClauseContext);
  213. }
  214. /*
  215. * sign clause
  216. */
  217. final List<DataSignClauseContext> dataSignClauseContexts = ctx.dataSignClause();
  218. if (!dataSignClauseContexts.isEmpty()) {
  219. final DataSignClauseContext dataSignClauseContext = dataSignClauseContexts.get(0);
  220. result.addSignClause(dataSignClauseContext);
  221. }
  222. /*
  223. * synchronized
  224. */
  225. final List<DataSynchronizedClauseContext> dataSynchronizedClauseContexts = ctx.dataSynchronizedClause();
  226. if (!dataSynchronizedClauseContexts.isEmpty()) {
  227. final DataSynchronizedClauseContext dataSynchronizedClauseContext = dataSynchronizedClauseContexts
  228. .get(0);
  229. result.addSynchronizedClause(dataSynchronizedClauseContext);
  230. }
  231. /*
  232. * thread local
  233. */
  234. final List<DataThreadLocalClauseContext> dataThreadLocalClauseContexts = ctx.dataThreadLocalClause();
  235. if (!dataThreadLocalClauseContexts.isEmpty()) {
  236. final DataThreadLocalClauseContext dataThreadLocalClauseContext = dataThreadLocalClauseContexts.get(0);
  237. result.addThreadLocalClause(dataThreadLocalClauseContext);
  238. }
  239. /*
  240. * time type
  241. */
  242. final List<DataTypeClauseContext> dataTypeClauseContexts = ctx.dataTypeClause();
  243. if (!dataTypeClauseContexts.isEmpty()) {
  244. final DataTypeClauseContext dataTypeClauseContext = dataTypeClauseContexts.get(0);
  245. result.addTypeClause(dataTypeClauseContext);
  246. }
  247. /*
  248. * type def
  249. */
  250. final List<DataTypeDefClauseContext> dataTypeDefClauseContexts = ctx.dataTypeDefClause();
  251. if (!dataTypeDefClauseContexts.isEmpty()) {
  252. final DataTypeDefClauseContext dataTypeDefClauseContext = dataTypeDefClauseContexts.get(0);
  253. result.addTypeDefClause(dataTypeDefClauseContext);
  254. }
  255. /*
  256. * usage
  257. */
  258. final List<DataUsageClauseContext> dataUsageClauseContexts = ctx.dataUsageClause();
  259. if (!dataUsageClauseContexts.isEmpty()) {
  260. final DataUsageClauseContext dataUsageClauseContext = dataUsageClauseContexts.get(0);
  261. result.addUsageClause(dataUsageClauseContext);
  262. }
  263. /*
  264. * using
  265. */
  266. final List<DataUsingClauseContext> dataUsingClauseContexts = ctx.dataUsingClause();
  267. if (!dataUsingClauseContexts.isEmpty()) {
  268. final DataUsingClauseContext dataUsingClauseContext = dataUsingClauseContexts.get(0);
  269. result.addUsingClause(dataUsingClauseContext);
  270. }
  271. /*
  272. * value
  273. */
  274. final List<DataValueClauseContext> dataValueClauseContexts = ctx.dataValueClause();
  275. if (!dataValueClauseContexts.isEmpty()) {
  276. final DataValueClauseContext dataValueClauseContext = dataValueClauseContexts.get(0);
  277. result.addValueClause(dataValueClauseContext);
  278. }
  279. /*
  280. * with lower bounds
  281. */
  282. final List<DataWithLowerBoundsClauseContext> dataWithLowerBoundsClauseContexts = ctx
  283. .dataWithLowerBoundsClause();
  284. if (!dataWithLowerBoundsClauseContexts.isEmpty()) {
  285. final DataWithLowerBoundsClauseContext dataWithLowerBoundsClauseContext = dataWithLowerBoundsClauseContexts
  286. .get(0);
  287. result.addWithLowerBoundClause(dataWithLowerBoundsClauseContext);
  288. }
  289. registerASGElement(result);
  290. dataDescriptionEntries.add(result);
  291. assureDataDescriptionEntriesSymbolTableEntry(name).addDataDescriptionEntry(result);
  292. }
  293. return result;
  294. }
  295. @Override
  296. public DataDescriptionEntryRename addDataDescriptionEntryRename(final DataDescriptionEntryFormat2Context ctx) {
  297. DataDescriptionEntryRename result = (DataDescriptionEntryRename) getASGElement(ctx);
  298. if (result == null) {
  299. final String name = determineName(ctx);
  300. result = new DataDescriptionEntryRenameImpl(name, this, programUnit, ctx);
  301. result.setLevelNumber(DataDescriptionEntry.LEVEL_NUMBER_RENAME);
  302. result.addRenamesClause(ctx.dataRenamesClause());
  303. registerASGElement(result);
  304. dataDescriptionEntries.add(result);
  305. assureDataDescriptionEntriesSymbolTableEntry(name).addDataDescriptionEntry(result);
  306. }
  307. return result;
  308. }
  309. protected DataDescriptionEntriesSymbolTableEntry assureDataDescriptionEntriesSymbolTableEntry(final String name) {
  310. DataDescriptionEntriesSymbolTableEntry dataDescriptionEntriesSymbolTableEntry = dataDescriptionEntriesSymbolTable
  311. .get(getSymbol(name));
  312. if (dataDescriptionEntriesSymbolTableEntry == null) {
  313. dataDescriptionEntriesSymbolTableEntry = new DataDescriptionEntriesSymbolTableEntryImpl();
  314. dataDescriptionEntriesSymbolTable.put(getSymbol(name), dataDescriptionEntriesSymbolTableEntry);
  315. }
  316. return dataDescriptionEntriesSymbolTableEntry;
  317. }
  318. @Override
  319. public DataDescriptionEntry createDataDescriptionEntry(
  320. final DataDescriptionEntryGroup currentDataDescriptionEntryGroup, final DataDescriptionEntryContext ctx) {
  321. final DataDescriptionEntry result;
  322. if (ctx.dataDescriptionEntryFormat1() != null) {
  323. result = addDataDescriptionEntryGroup(ctx.dataDescriptionEntryFormat1());
  324. } else if (ctx.dataDescriptionEntryFormat2() != null) {
  325. result = addDataDescriptionEntryRename(ctx.dataDescriptionEntryFormat2());
  326. } else if (ctx.dataDescriptionEntryFormat3() != null) {
  327. result = addDataDescriptionEntryCondition(ctx.dataDescriptionEntryFormat3());
  328. } else if (ctx.dataDescriptionEntryExecSql() != null) {
  329. result = addDataDescriptionEntryExecSql(ctx.dataDescriptionEntryExecSql());
  330. } else {
  331. LOG.warn("unknown data description entry {}", ctx);
  332. result = null;
  333. }
  334. if (currentDataDescriptionEntryGroup != null && result != null) {
  335. groupDataDescriptionEntry(currentDataDescriptionEntryGroup, result);
  336. }
  337. return result;
  338. }
  339. @Override
  340. public List<DataDescriptionEntry> getDataDescriptionEntries() {
  341. return dataDescriptionEntries;
  342. }
  343. @Override
  344. public List<DataDescriptionEntry> getDataDescriptionEntries(final String name) {
  345. return dataDescriptionEntriesSymbolTable.get(getSymbol(name)) == null ? new ArrayList<>()
  346. : dataDescriptionEntriesSymbolTable.get(getSymbol(name)).getDataDescriptionEntries();
  347. }
  348. @Override
  349. public DataDescriptionEntry getDataDescriptionEntry(final String name) {
  350. return dataDescriptionEntriesSymbolTable.get(getSymbol(name)) == null ? null
  351. : dataDescriptionEntriesSymbolTable.get(getSymbol(name)).getDataDescriptionEntry();
  352. }
  353. @Override
  354. public List<DataDescriptionEntry> getRootDataDescriptionEntries() {
  355. final List<DataDescriptionEntry> result = new ArrayList<DataDescriptionEntry>();
  356. for (final DataDescriptionEntry dataDescriptionEntry : dataDescriptionEntries) {
  357. if (dataDescriptionEntry.getParentDataDescriptionEntryGroup() == null) {
  358. result.add(dataDescriptionEntry);
  359. }
  360. }
  361. return result;
  362. }
  363. protected void groupDataDescriptionEntry(final DataDescriptionEntryGroup currentDataDescriptionEntryGroup,
  364. final DataDescriptionEntry dataDescriptionEntry) {
  365. final Integer currentLevelNumber = currentDataDescriptionEntryGroup.getLevelNumber();
  366. final Integer levelNumber = dataDescriptionEntry.getLevelNumber();
  367. if (!isGroupableLevelNumber(levelNumber)) {
  368. } else if (levelNumber > currentLevelNumber) {
  369. currentDataDescriptionEntryGroup.addDataDescriptionEntry(dataDescriptionEntry);
  370. dataDescriptionEntry.setParentDataDescriptionEntryGroup(currentDataDescriptionEntryGroup);
  371. } else {
  372. final DataDescriptionEntryGroup currentParentDataDescriptionEntryGroup = currentDataDescriptionEntryGroup
  373. .getParentDataDescriptionEntryGroup();
  374. if (currentParentDataDescriptionEntryGroup != null) {
  375. groupDataDescriptionEntry(currentParentDataDescriptionEntryGroup, dataDescriptionEntry);
  376. }
  377. }
  378. }
  379. protected boolean isGroupableLevelNumber(final Integer levelNumber) {
  380. final boolean result = levelNumber != null && DataDescriptionEntry.LEVEL_NUMBER_SCALAR != levelNumber
  381. && DataDescriptionEntry.LEVEL_NUMBER_RENAME != levelNumber;
  382. return result;
  383. }
  384. }