@hydranium/core 1.0.0-next.10

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 (868) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +100 -0
  3. package/lib/documents/ast-document-manager.d.ts +243 -0
  4. package/lib/documents/ast-document-manager.d.ts.map +1 -0
  5. package/lib/documents/ast-document-manager.js +302 -0
  6. package/lib/documents/ast-document-manager.js.map +1 -0
  7. package/lib/documents/client-ids.d.ts +30 -0
  8. package/lib/documents/client-ids.d.ts.map +1 -0
  9. package/lib/documents/client-ids.js +30 -0
  10. package/lib/documents/client-ids.js.map +1 -0
  11. package/lib/documents/hydranium-text-documents.d.ts +490 -0
  12. package/lib/documents/hydranium-text-documents.d.ts.map +1 -0
  13. package/lib/documents/hydranium-text-documents.js +893 -0
  14. package/lib/documents/hydranium-text-documents.js.map +1 -0
  15. package/lib/documents/index.d.ts +14 -0
  16. package/lib/documents/index.d.ts.map +1 -0
  17. package/lib/documents/index.js +14 -0
  18. package/lib/documents/index.js.map +1 -0
  19. package/lib/documents/language-client-text-shadow.d.ts +101 -0
  20. package/lib/documents/language-client-text-shadow.d.ts.map +1 -0
  21. package/lib/documents/language-client-text-shadow.js +156 -0
  22. package/lib/documents/language-client-text-shadow.js.map +1 -0
  23. package/lib/documents/self-save-registry.d.ts +55 -0
  24. package/lib/documents/self-save-registry.d.ts.map +1 -0
  25. package/lib/documents/self-save-registry.js +68 -0
  26. package/lib/documents/self-save-registry.js.map +1 -0
  27. package/lib/index.d.ts +38 -0
  28. package/lib/index.d.ts.map +1 -0
  29. package/lib/index.js +39 -0
  30. package/lib/index.js.map +1 -0
  31. package/lib/langium/ast-extension/ast-extension-contribution.d.ts +33 -0
  32. package/lib/langium/ast-extension/ast-extension-contribution.d.ts.map +1 -0
  33. package/lib/langium/ast-extension/ast-extension-contribution.js +10 -0
  34. package/lib/langium/ast-extension/ast-extension-contribution.js.map +1 -0
  35. package/lib/langium/ast-extension/ast-extension-service.d.ts +212 -0
  36. package/lib/langium/ast-extension/ast-extension-service.d.ts.map +1 -0
  37. package/lib/langium/ast-extension/ast-extension-service.js +181 -0
  38. package/lib/langium/ast-extension/ast-extension-service.js.map +1 -0
  39. package/lib/langium/ast-extension/ast-node-builder.d.ts +90 -0
  40. package/lib/langium/ast-extension/ast-node-builder.d.ts.map +1 -0
  41. package/lib/langium/ast-extension/ast-node-builder.js +61 -0
  42. package/lib/langium/ast-extension/ast-node-builder.js.map +1 -0
  43. package/lib/langium/ast-extension/index.d.ts +12 -0
  44. package/lib/langium/ast-extension/index.d.ts.map +1 -0
  45. package/lib/langium/ast-extension/index.js +12 -0
  46. package/lib/langium/ast-extension/index.js.map +1 -0
  47. package/lib/langium/bootstrap.d.ts +224 -0
  48. package/lib/langium/bootstrap.d.ts.map +1 -0
  49. package/lib/langium/bootstrap.js +512 -0
  50. package/lib/langium/bootstrap.js.map +1 -0
  51. package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts +77 -0
  52. package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts.map +1 -0
  53. package/lib/langium/build-phase-pass/build-phase-pass-service.js +102 -0
  54. package/lib/langium/build-phase-pass/build-phase-pass-service.js.map +1 -0
  55. package/lib/langium/build-phase-pass/build-phase-pass.d.ts +106 -0
  56. package/lib/langium/build-phase-pass/build-phase-pass.d.ts.map +1 -0
  57. package/lib/langium/build-phase-pass/build-phase-pass.js +43 -0
  58. package/lib/langium/build-phase-pass/build-phase-pass.js.map +1 -0
  59. package/lib/langium/build-phase-pass/index.d.ts +11 -0
  60. package/lib/langium/build-phase-pass/index.d.ts.map +1 -0
  61. package/lib/langium/build-phase-pass/index.js +11 -0
  62. package/lib/langium/build-phase-pass/index.js.map +1 -0
  63. package/lib/langium/config/index.d.ts +10 -0
  64. package/lib/langium/config/index.d.ts.map +1 -0
  65. package/lib/langium/config/index.js +10 -0
  66. package/lib/langium/config/index.js.map +1 -0
  67. package/lib/langium/config/settings.d.ts +173 -0
  68. package/lib/langium/config/settings.d.ts.map +1 -0
  69. package/lib/langium/config/settings.js +196 -0
  70. package/lib/langium/config/settings.js.map +1 -0
  71. package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts +109 -0
  72. package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts.map +1 -0
  73. package/lib/langium/diagnostics/hydranium-langium-profiler.js +153 -0
  74. package/lib/langium/diagnostics/hydranium-langium-profiler.js.map +1 -0
  75. package/lib/langium/diagnostics/index.d.ts +14 -0
  76. package/lib/langium/diagnostics/index.d.ts.map +1 -0
  77. package/lib/langium/diagnostics/index.js +19 -0
  78. package/lib/langium/diagnostics/index.js.map +1 -0
  79. package/lib/langium/diagnostics/log-file-token.d.ts +16 -0
  80. package/lib/langium/diagnostics/log-file-token.d.ts.map +1 -0
  81. package/lib/langium/diagnostics/log-file-token.js +25 -0
  82. package/lib/langium/diagnostics/log-file-token.js.map +1 -0
  83. package/lib/langium/diagnostics/log-preamble.d.ts +42 -0
  84. package/lib/langium/diagnostics/log-preamble.d.ts.map +1 -0
  85. package/lib/langium/diagnostics/log-preamble.js +57 -0
  86. package/lib/langium/diagnostics/log-preamble.js.map +1 -0
  87. package/lib/langium/diagnostics/logger.d.ts +104 -0
  88. package/lib/langium/diagnostics/logger.d.ts.map +1 -0
  89. package/lib/langium/diagnostics/logger.js +178 -0
  90. package/lib/langium/diagnostics/logger.js.map +1 -0
  91. package/lib/langium/diagnostics/lsp-logger.d.ts +76 -0
  92. package/lib/langium/diagnostics/lsp-logger.d.ts.map +1 -0
  93. package/lib/langium/diagnostics/lsp-logger.js +223 -0
  94. package/lib/langium/diagnostics/lsp-logger.js.map +1 -0
  95. package/lib/langium/diagnostics/server-tracer.d.ts +27 -0
  96. package/lib/langium/diagnostics/server-tracer.d.ts.map +1 -0
  97. package/lib/langium/diagnostics/server-tracer.js +66 -0
  98. package/lib/langium/diagnostics/server-tracer.js.map +1 -0
  99. package/lib/langium/document-builder/build-pipeline-integration.d.ts +88 -0
  100. package/lib/langium/document-builder/build-pipeline-integration.d.ts.map +1 -0
  101. package/lib/langium/document-builder/build-pipeline-integration.js +151 -0
  102. package/lib/langium/document-builder/build-pipeline-integration.js.map +1 -0
  103. package/lib/langium/document-builder/document-builder.d.ts +405 -0
  104. package/lib/langium/document-builder/document-builder.d.ts.map +1 -0
  105. package/lib/langium/document-builder/document-builder.js +729 -0
  106. package/lib/langium/document-builder/document-builder.js.map +1 -0
  107. package/lib/langium/document-builder/index.d.ts +12 -0
  108. package/lib/langium/document-builder/index.d.ts.map +1 -0
  109. package/lib/langium/document-builder/index.js +12 -0
  110. package/lib/langium/document-builder/index.js.map +1 -0
  111. package/lib/langium/document-builder/labeled-phase-listener.d.ts +21 -0
  112. package/lib/langium/document-builder/labeled-phase-listener.d.ts.map +1 -0
  113. package/lib/langium/document-builder/labeled-phase-listener.js +15 -0
  114. package/lib/langium/document-builder/labeled-phase-listener.js.map +1 -0
  115. package/lib/langium/documentation/comment-provider.d.ts +31 -0
  116. package/lib/langium/documentation/comment-provider.d.ts.map +1 -0
  117. package/lib/langium/documentation/comment-provider.js +36 -0
  118. package/lib/langium/documentation/comment-provider.js.map +1 -0
  119. package/lib/langium/documentation/index.d.ts +10 -0
  120. package/lib/langium/documentation/index.d.ts.map +1 -0
  121. package/lib/langium/documentation/index.js +10 -0
  122. package/lib/langium/documentation/index.js.map +1 -0
  123. package/lib/langium/integration-services.d.ts +200 -0
  124. package/lib/langium/integration-services.d.ts.map +1 -0
  125. package/lib/langium/integration-services.js +65 -0
  126. package/lib/langium/integration-services.js.map +1 -0
  127. package/lib/langium/integrity/index.d.ts +12 -0
  128. package/lib/langium/integrity/index.d.ts.map +1 -0
  129. package/lib/langium/integrity/index.js +12 -0
  130. package/lib/langium/integrity/index.js.map +1 -0
  131. package/lib/langium/integrity/integrity-contribution.d.ts +42 -0
  132. package/lib/langium/integrity/integrity-contribution.d.ts.map +1 -0
  133. package/lib/langium/integrity/integrity-contribution.js +10 -0
  134. package/lib/langium/integrity/integrity-contribution.js.map +1 -0
  135. package/lib/langium/integrity/integrity-rule.d.ts +82 -0
  136. package/lib/langium/integrity/integrity-rule.d.ts.map +1 -0
  137. package/lib/langium/integrity/integrity-rule.js +52 -0
  138. package/lib/langium/integrity/integrity-rule.js.map +1 -0
  139. package/lib/langium/integrity/integrity-service.d.ts +221 -0
  140. package/lib/langium/integrity/integrity-service.d.ts.map +1 -0
  141. package/lib/langium/integrity/integrity-service.js +328 -0
  142. package/lib/langium/integrity/integrity-service.js.map +1 -0
  143. package/lib/langium/keys/default-element-key-provider.d.ts +19 -0
  144. package/lib/langium/keys/default-element-key-provider.d.ts.map +1 -0
  145. package/lib/langium/keys/default-element-key-provider.js +18 -0
  146. package/lib/langium/keys/default-element-key-provider.js.map +1 -0
  147. package/lib/langium/keys/element-key-provider.d.ts +106 -0
  148. package/lib/langium/keys/element-key-provider.d.ts.map +1 -0
  149. package/lib/langium/keys/element-key-provider.js +25 -0
  150. package/lib/langium/keys/element-key-provider.js.map +1 -0
  151. package/lib/langium/keys/index.d.ts +13 -0
  152. package/lib/langium/keys/index.d.ts.map +1 -0
  153. package/lib/langium/keys/index.js +13 -0
  154. package/lib/langium/keys/index.js.map +1 -0
  155. package/lib/langium/keys/name-based-key-provider.d.ts +99 -0
  156. package/lib/langium/keys/name-based-key-provider.d.ts.map +1 -0
  157. package/lib/langium/keys/name-based-key-provider.js +134 -0
  158. package/lib/langium/keys/name-based-key-provider.js.map +1 -0
  159. package/lib/langium/keys/positional-key-provider.d.ts +41 -0
  160. package/lib/langium/keys/positional-key-provider.d.ts.map +1 -0
  161. package/lib/langium/keys/positional-key-provider.js +48 -0
  162. package/lib/langium/keys/positional-key-provider.js.map +1 -0
  163. package/lib/langium/labeling/index.d.ts +10 -0
  164. package/lib/langium/labeling/index.d.ts.map +1 -0
  165. package/lib/langium/labeling/index.js +10 -0
  166. package/lib/langium/labeling/index.js.map +1 -0
  167. package/lib/langium/labeling/label-provider.d.ts +79 -0
  168. package/lib/langium/labeling/label-provider.d.ts.map +1 -0
  169. package/lib/langium/labeling/label-provider.js +44 -0
  170. package/lib/langium/labeling/label-provider.js.map +1 -0
  171. package/lib/langium/language-module.d.ts +281 -0
  172. package/lib/langium/language-module.d.ts.map +1 -0
  173. package/lib/langium/language-module.js +103 -0
  174. package/lib/langium/language-module.js.map +1 -0
  175. package/lib/langium/language-types.d.ts +85 -0
  176. package/lib/langium/language-types.d.ts.map +1 -0
  177. package/lib/langium/language-types.js +173 -0
  178. package/lib/langium/language-types.js.map +1 -0
  179. package/lib/langium/model-service/index.d.ts +10 -0
  180. package/lib/langium/model-service/index.d.ts.map +1 -0
  181. package/lib/langium/model-service/index.js +10 -0
  182. package/lib/langium/model-service/index.js.map +1 -0
  183. package/lib/langium/model-service/model-service.d.ts +598 -0
  184. package/lib/langium/model-service/model-service.d.ts.map +1 -0
  185. package/lib/langium/model-service/model-service.js +889 -0
  186. package/lib/langium/model-service/model-service.js.map +1 -0
  187. package/lib/langium/module.d.ts +308 -0
  188. package/lib/langium/module.d.ts.map +1 -0
  189. package/lib/langium/module.js +165 -0
  190. package/lib/langium/module.js.map +1 -0
  191. package/lib/langium/naming/index.d.ts +11 -0
  192. package/lib/langium/naming/index.d.ts.map +1 -0
  193. package/lib/langium/naming/index.js +11 -0
  194. package/lib/langium/naming/index.js.map +1 -0
  195. package/lib/langium/naming/name-provider.d.ts +360 -0
  196. package/lib/langium/naming/name-provider.d.ts.map +1 -0
  197. package/lib/langium/naming/name-provider.js +240 -0
  198. package/lib/langium/naming/name-provider.js.map +1 -0
  199. package/lib/langium/naming/name-separator-validation.d.ts +47 -0
  200. package/lib/langium/naming/name-separator-validation.d.ts.map +1 -0
  201. package/lib/langium/naming/name-separator-validation.js +61 -0
  202. package/lib/langium/naming/name-separator-validation.js.map +1 -0
  203. package/lib/langium/project/abstract-project-manager.d.ts +242 -0
  204. package/lib/langium/project/abstract-project-manager.d.ts.map +1 -0
  205. package/lib/langium/project/abstract-project-manager.js +545 -0
  206. package/lib/langium/project/abstract-project-manager.js.map +1 -0
  207. package/lib/langium/project/index.d.ts +13 -0
  208. package/lib/langium/project/index.d.ts.map +1 -0
  209. package/lib/langium/project/index.js +13 -0
  210. package/lib/langium/project/index.js.map +1 -0
  211. package/lib/langium/project/project-change-event.d.ts +64 -0
  212. package/lib/langium/project/project-change-event.d.ts.map +1 -0
  213. package/lib/langium/project/project-change-event.js +10 -0
  214. package/lib/langium/project/project-change-event.js.map +1 -0
  215. package/lib/langium/project/project-manager.d.ts +196 -0
  216. package/lib/langium/project/project-manager.d.ts.map +1 -0
  217. package/lib/langium/project/project-manager.js +10 -0
  218. package/lib/langium/project/project-manager.js.map +1 -0
  219. package/lib/langium/project/single-project-manager.d.ts +69 -0
  220. package/lib/langium/project/single-project-manager.d.ts.map +1 -0
  221. package/lib/langium/project/single-project-manager.js +104 -0
  222. package/lib/langium/project/single-project-manager.js.map +1 -0
  223. package/lib/langium/residency/cst-residency-service.d.ts +214 -0
  224. package/lib/langium/residency/cst-residency-service.d.ts.map +1 -0
  225. package/lib/langium/residency/cst-residency-service.js +349 -0
  226. package/lib/langium/residency/cst-residency-service.js.map +1 -0
  227. package/lib/langium/residency/index.d.ts +10 -0
  228. package/lib/langium/residency/index.d.ts.map +1 -0
  229. package/lib/langium/residency/index.js +10 -0
  230. package/lib/langium/residency/index.js.map +1 -0
  231. package/lib/langium/scope/ast-node-description-provider.d.ts +122 -0
  232. package/lib/langium/scope/ast-node-description-provider.d.ts.map +1 -0
  233. package/lib/langium/scope/ast-node-description-provider.js +115 -0
  234. package/lib/langium/scope/ast-node-description-provider.js.map +1 -0
  235. package/lib/langium/scope/hydranium-scope-computation.d.ts +163 -0
  236. package/lib/langium/scope/hydranium-scope-computation.d.ts.map +1 -0
  237. package/lib/langium/scope/hydranium-scope-computation.js +220 -0
  238. package/lib/langium/scope/hydranium-scope-computation.js.map +1 -0
  239. package/lib/langium/scope/hydranium-scope-provider.d.ts +411 -0
  240. package/lib/langium/scope/hydranium-scope-provider.d.ts.map +1 -0
  241. package/lib/langium/scope/hydranium-scope-provider.js +543 -0
  242. package/lib/langium/scope/hydranium-scope-provider.js.map +1 -0
  243. package/lib/langium/scope/index.d.ts +18 -0
  244. package/lib/langium/scope/index.d.ts.map +1 -0
  245. package/lib/langium/scope/index.js +18 -0
  246. package/lib/langium/scope/index.js.map +1 -0
  247. package/lib/langium/scope/reference-builder.d.ts +125 -0
  248. package/lib/langium/scope/reference-builder.d.ts.map +1 -0
  249. package/lib/langium/scope/reference-builder.js +115 -0
  250. package/lib/langium/scope/reference-builder.js.map +1 -0
  251. package/lib/langium/scope/reference-candidate-provider.d.ts +228 -0
  252. package/lib/langium/scope/reference-candidate-provider.d.ts.map +1 -0
  253. package/lib/langium/scope/reference-candidate-provider.js +185 -0
  254. package/lib/langium/scope/reference-candidate-provider.js.map +1 -0
  255. package/lib/langium/scope/scope-extension-contribution.d.ts +32 -0
  256. package/lib/langium/scope/scope-extension-contribution.d.ts.map +1 -0
  257. package/lib/langium/scope/scope-extension-contribution.js +10 -0
  258. package/lib/langium/scope/scope-extension-contribution.js.map +1 -0
  259. package/lib/langium/scope/scope-extension-service.d.ts +149 -0
  260. package/lib/langium/scope/scope-extension-service.d.ts.map +1 -0
  261. package/lib/langium/scope/scope-extension-service.js +94 -0
  262. package/lib/langium/scope/scope-extension-service.js.map +1 -0
  263. package/lib/langium/scope/scoped-ast-node-description.d.ts +160 -0
  264. package/lib/langium/scope/scoped-ast-node-description.d.ts.map +1 -0
  265. package/lib/langium/scope/scoped-ast-node-description.js +98 -0
  266. package/lib/langium/scope/scoped-ast-node-description.js.map +1 -0
  267. package/lib/langium/scope/tier-specificity.d.ts +47 -0
  268. package/lib/langium/scope/tier-specificity.d.ts.map +1 -0
  269. package/lib/langium/scope/tier-specificity.js +83 -0
  270. package/lib/langium/scope/tier-specificity.js.map +1 -0
  271. package/lib/langium/serialization/abstract-serializer.d.ts +316 -0
  272. package/lib/langium/serialization/abstract-serializer.d.ts.map +1 -0
  273. package/lib/langium/serialization/abstract-serializer.js +351 -0
  274. package/lib/langium/serialization/abstract-serializer.js.map +1 -0
  275. package/lib/langium/serialization/index.d.ts +14 -0
  276. package/lib/langium/serialization/index.d.ts.map +1 -0
  277. package/lib/langium/serialization/index.js +14 -0
  278. package/lib/langium/serialization/index.js.map +1 -0
  279. package/lib/langium/serialization/json-serializer.d.ts +106 -0
  280. package/lib/langium/serialization/json-serializer.d.ts.map +1 -0
  281. package/lib/langium/serialization/json-serializer.js +198 -0
  282. package/lib/langium/serialization/json-serializer.js.map +1 -0
  283. package/lib/langium/serialization/serialization-util.d.ts +29 -0
  284. package/lib/langium/serialization/serialization-util.d.ts.map +1 -0
  285. package/lib/langium/serialization/serialization-util.js +37 -0
  286. package/lib/langium/serialization/serialization-util.js.map +1 -0
  287. package/lib/langium/serialization/serializer.d.ts +66 -0
  288. package/lib/langium/serialization/serializer.d.ts.map +1 -0
  289. package/lib/langium/serialization/serializer.js +10 -0
  290. package/lib/langium/serialization/serializer.js.map +1 -0
  291. package/lib/langium/serialization/yaml-serializer.d.ts +166 -0
  292. package/lib/langium/serialization/yaml-serializer.d.ts.map +1 -0
  293. package/lib/langium/serialization/yaml-serializer.js +228 -0
  294. package/lib/langium/serialization/yaml-serializer.js.map +1 -0
  295. package/lib/langium/service-registry.d.ts +220 -0
  296. package/lib/langium/service-registry.d.ts.map +1 -0
  297. package/lib/langium/service-registry.js +258 -0
  298. package/lib/langium/service-registry.js.map +1 -0
  299. package/lib/langium/shared-services.d.ts +98 -0
  300. package/lib/langium/shared-services.d.ts.map +1 -0
  301. package/lib/langium/shared-services.js +30 -0
  302. package/lib/langium/shared-services.js.map +1 -0
  303. package/lib/langium/transfer/index.d.ts +10 -0
  304. package/lib/langium/transfer/index.d.ts.map +1 -0
  305. package/lib/langium/transfer/index.js +10 -0
  306. package/lib/langium/transfer/index.js.map +1 -0
  307. package/lib/langium/transfer/transfer-encoder.d.ts +294 -0
  308. package/lib/langium/transfer/transfer-encoder.d.ts.map +1 -0
  309. package/lib/langium/transfer/transfer-encoder.js +328 -0
  310. package/lib/langium/transfer/transfer-encoder.js.map +1 -0
  311. package/lib/langium/update-rewrite/index.d.ts +14 -0
  312. package/lib/langium/update-rewrite/index.d.ts.map +1 -0
  313. package/lib/langium/update-rewrite/index.js +14 -0
  314. package/lib/langium/update-rewrite/index.js.map +1 -0
  315. package/lib/langium/update-rewrite/normalize-empty-strings.d.ts +52 -0
  316. package/lib/langium/update-rewrite/normalize-empty-strings.d.ts.map +1 -0
  317. package/lib/langium/update-rewrite/normalize-empty-strings.js +83 -0
  318. package/lib/langium/update-rewrite/normalize-empty-strings.js.map +1 -0
  319. package/lib/langium/update-rewrite/semantic-root-rewrite.d.ts +37 -0
  320. package/lib/langium/update-rewrite/semantic-root-rewrite.d.ts.map +1 -0
  321. package/lib/langium/update-rewrite/semantic-root-rewrite.js +51 -0
  322. package/lib/langium/update-rewrite/semantic-root-rewrite.js.map +1 -0
  323. package/lib/langium/update-rewrite/update-rewrite-contribution.d.ts +42 -0
  324. package/lib/langium/update-rewrite/update-rewrite-contribution.d.ts.map +1 -0
  325. package/lib/langium/update-rewrite/update-rewrite-contribution.js +10 -0
  326. package/lib/langium/update-rewrite/update-rewrite-contribution.js.map +1 -0
  327. package/lib/langium/update-rewrite/update-rewrite-service.d.ts +89 -0
  328. package/lib/langium/update-rewrite/update-rewrite-service.d.ts.map +1 -0
  329. package/lib/langium/update-rewrite/update-rewrite-service.js +75 -0
  330. package/lib/langium/update-rewrite/update-rewrite-service.js.map +1 -0
  331. package/lib/langium/update-rewrite/update-rewrite.d.ts +59 -0
  332. package/lib/langium/update-rewrite/update-rewrite.d.ts.map +1 -0
  333. package/lib/langium/update-rewrite/update-rewrite.js +10 -0
  334. package/lib/langium/update-rewrite/update-rewrite.js.map +1 -0
  335. package/lib/langium/validation/document-validator.d.ts +106 -0
  336. package/lib/langium/validation/document-validator.d.ts.map +1 -0
  337. package/lib/langium/validation/document-validator.js +118 -0
  338. package/lib/langium/validation/document-validator.js.map +1 -0
  339. package/lib/langium/validation/index.d.ts +12 -0
  340. package/lib/langium/validation/index.d.ts.map +1 -0
  341. package/lib/langium/validation/index.js +12 -0
  342. package/lib/langium/validation/index.js.map +1 -0
  343. package/lib/langium/validation/validation-contribution-collector.d.ts +34 -0
  344. package/lib/langium/validation/validation-contribution-collector.d.ts.map +1 -0
  345. package/lib/langium/validation/validation-contribution-collector.js +51 -0
  346. package/lib/langium/validation/validation-contribution-collector.js.map +1 -0
  347. package/lib/langium/validation/validation-contribution.d.ts +36 -0
  348. package/lib/langium/validation/validation-contribution.d.ts.map +1 -0
  349. package/lib/langium/validation/validation-contribution.js +10 -0
  350. package/lib/langium/validation/validation-contribution.js.map +1 -0
  351. package/lib/langium/workspace/additional-document-contribution.d.ts +68 -0
  352. package/lib/langium/workspace/additional-document-contribution.d.ts.map +1 -0
  353. package/lib/langium/workspace/additional-document-contribution.js +23 -0
  354. package/lib/langium/workspace/additional-document-contribution.js.map +1 -0
  355. package/lib/langium/workspace/document-uri-policy.d.ts +151 -0
  356. package/lib/langium/workspace/document-uri-policy.d.ts.map +1 -0
  357. package/lib/langium/workspace/document-uri-policy.js +121 -0
  358. package/lib/langium/workspace/document-uri-policy.js.map +1 -0
  359. package/lib/langium/workspace/file-system-provider.d.ts +30 -0
  360. package/lib/langium/workspace/file-system-provider.d.ts.map +1 -0
  361. package/lib/langium/workspace/file-system-provider.js +41 -0
  362. package/lib/langium/workspace/file-system-provider.js.map +1 -0
  363. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts +45 -0
  364. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts.map +1 -0
  365. package/lib/langium/workspace/hydranium-langium-document-factory.js +64 -0
  366. package/lib/langium/workspace/hydranium-langium-document-factory.js.map +1 -0
  367. package/lib/langium/workspace/hydranium-workspace-lock.d.ts +31 -0
  368. package/lib/langium/workspace/hydranium-workspace-lock.d.ts.map +1 -0
  369. package/lib/langium/workspace/hydranium-workspace-lock.js +33 -0
  370. package/lib/langium/workspace/hydranium-workspace-lock.js.map +1 -0
  371. package/lib/langium/workspace/hydranium-workspace-manager.d.ts +232 -0
  372. package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -0
  373. package/lib/langium/workspace/hydranium-workspace-manager.js +368 -0
  374. package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -0
  375. package/lib/langium/workspace/in-memory-file-system-provider.d.ts +127 -0
  376. package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -0
  377. package/lib/langium/workspace/in-memory-file-system-provider.js +195 -0
  378. package/lib/langium/workspace/in-memory-file-system-provider.js.map +1 -0
  379. package/lib/langium/workspace/index-manager.d.ts +142 -0
  380. package/lib/langium/workspace/index-manager.d.ts.map +1 -0
  381. package/lib/langium/workspace/index-manager.js +245 -0
  382. package/lib/langium/workspace/index-manager.js.map +1 -0
  383. package/lib/langium/workspace/index.d.ts +23 -0
  384. package/lib/langium/workspace/index.d.ts.map +1 -0
  385. package/lib/langium/workspace/index.js +23 -0
  386. package/lib/langium/workspace/index.js.map +1 -0
  387. package/lib/langium/workspace/initialize-workspace.d.ts +63 -0
  388. package/lib/langium/workspace/initialize-workspace.d.ts.map +1 -0
  389. package/lib/langium/workspace/initialize-workspace.js +88 -0
  390. package/lib/langium/workspace/initialize-workspace.js.map +1 -0
  391. package/lib/langium/workspace/langium-documents.d.ts +47 -0
  392. package/lib/langium/workspace/langium-documents.d.ts.map +1 -0
  393. package/lib/langium/workspace/langium-documents.js +85 -0
  394. package/lib/langium/workspace/langium-documents.js.map +1 -0
  395. package/lib/langium/workspace/persistent-file-system-provider.d.ts +207 -0
  396. package/lib/langium/workspace/persistent-file-system-provider.d.ts.map +1 -0
  397. package/lib/langium/workspace/persistent-file-system-provider.js +208 -0
  398. package/lib/langium/workspace/persistent-file-system-provider.js.map +1 -0
  399. package/lib/langium/workspace/synthetic.d.ts +38 -0
  400. package/lib/langium/workspace/synthetic.d.ts.map +1 -0
  401. package/lib/langium/workspace/synthetic.js +58 -0
  402. package/lib/langium/workspace/synthetic.js.map +1 -0
  403. package/lib/langium/workspace/virtual-document.d.ts +78 -0
  404. package/lib/langium/workspace/virtual-document.d.ts.map +1 -0
  405. package/lib/langium/workspace/virtual-document.js +89 -0
  406. package/lib/langium/workspace/virtual-document.js.map +1 -0
  407. package/lib/langium/workspace/write-lock-scope.d.ts +69 -0
  408. package/lib/langium/workspace/write-lock-scope.d.ts.map +1 -0
  409. package/lib/langium/workspace/write-lock-scope.js +54 -0
  410. package/lib/langium/workspace/write-lock-scope.js.map +1 -0
  411. package/lib/launcher/index.d.ts +10 -0
  412. package/lib/launcher/index.d.ts.map +1 -0
  413. package/lib/launcher/index.js +12 -0
  414. package/lib/launcher/index.js.map +1 -0
  415. package/lib/launcher/integrated-server.d.ts +28 -0
  416. package/lib/launcher/integrated-server.d.ts.map +1 -0
  417. package/lib/launcher/integrated-server.js +10 -0
  418. package/lib/launcher/integrated-server.js.map +1 -0
  419. package/lib/lsp/completion/hydranium-completion-provider.d.ts +89 -0
  420. package/lib/lsp/completion/hydranium-completion-provider.d.ts.map +1 -0
  421. package/lib/lsp/completion/hydranium-completion-provider.js +123 -0
  422. package/lib/lsp/completion/hydranium-completion-provider.js.map +1 -0
  423. package/lib/lsp/hydranium-document-update-handler.d.ts +204 -0
  424. package/lib/lsp/hydranium-document-update-handler.d.ts.map +1 -0
  425. package/lib/lsp/hydranium-document-update-handler.js +288 -0
  426. package/lib/lsp/hydranium-document-update-handler.js.map +1 -0
  427. package/lib/lsp/index.d.ts +23 -0
  428. package/lib/lsp/index.d.ts.map +1 -0
  429. package/lib/lsp/index.js +23 -0
  430. package/lib/lsp/index.js.map +1 -0
  431. package/lib/lsp/instrument-connection.d.ts +36 -0
  432. package/lib/lsp/instrument-connection.d.ts.map +1 -0
  433. package/lib/lsp/instrument-connection.js +62 -0
  434. package/lib/lsp/instrument-connection.js.map +1 -0
  435. package/lib/lsp/language-module.d.ts +53 -0
  436. package/lib/lsp/language-module.d.ts.map +1 -0
  437. package/lib/lsp/language-module.js +28 -0
  438. package/lib/lsp/language-module.js.map +1 -0
  439. package/lib/lsp/semantic-token-provider.d.ts +131 -0
  440. package/lib/lsp/semantic-token-provider.d.ts.map +1 -0
  441. package/lib/lsp/semantic-token-provider.js +148 -0
  442. package/lib/lsp/semantic-token-provider.js.map +1 -0
  443. package/lib/lsp/shared-module.d.ts +76 -0
  444. package/lib/lsp/shared-module.d.ts.map +1 -0
  445. package/lib/lsp/shared-module.js +33 -0
  446. package/lib/lsp/shared-module.js.map +1 -0
  447. package/lib/lsp/start-language-server.d.ts +43 -0
  448. package/lib/lsp/start-language-server.d.ts.map +1 -0
  449. package/lib/lsp/start-language-server.js +60 -0
  450. package/lib/lsp/start-language-server.js.map +1 -0
  451. package/lib/node/ast-ground-truth.d.ts +57 -0
  452. package/lib/node/ast-ground-truth.d.ts.map +1 -0
  453. package/lib/node/ast-ground-truth.js +46 -0
  454. package/lib/node/ast-ground-truth.js.map +1 -0
  455. package/lib/node/event-loop-monitor.d.ts +40 -0
  456. package/lib/node/event-loop-monitor.d.ts.map +1 -0
  457. package/lib/node/event-loop-monitor.js +62 -0
  458. package/lib/node/event-loop-monitor.js.map +1 -0
  459. package/lib/node/index.d.ts +29 -0
  460. package/lib/node/index.d.ts.map +1 -0
  461. package/lib/node/index.js +50 -0
  462. package/lib/node/index.js.map +1 -0
  463. package/lib/node/latency-from-env.d.ts +32 -0
  464. package/lib/node/latency-from-env.d.ts.map +1 -0
  465. package/lib/node/latency-from-env.js +36 -0
  466. package/lib/node/latency-from-env.js.map +1 -0
  467. package/lib/node/lint-grammar.d.ts +87 -0
  468. package/lib/node/lint-grammar.d.ts.map +1 -0
  469. package/lib/node/lint-grammar.js +124 -0
  470. package/lib/node/lint-grammar.js.map +1 -0
  471. package/lib/node/log-file-sink.d.ts +22 -0
  472. package/lib/node/log-file-sink.d.ts.map +1 -0
  473. package/lib/node/log-file-sink.js +43 -0
  474. package/lib/node/log-file-sink.js.map +1 -0
  475. package/lib/node/log-preamble-node.d.ts +28 -0
  476. package/lib/node/log-preamble-node.d.ts.map +1 -0
  477. package/lib/node/log-preamble-node.js +55 -0
  478. package/lib/node/log-preamble-node.js.map +1 -0
  479. package/lib/node/measure-memory.d.ts +86 -0
  480. package/lib/node/measure-memory.d.ts.map +1 -0
  481. package/lib/node/measure-memory.js +128 -0
  482. package/lib/node/measure-memory.js.map +1 -0
  483. package/lib/node/memory-monitor.d.ts +42 -0
  484. package/lib/node/memory-monitor.d.ts.map +1 -0
  485. package/lib/node/memory-monitor.js +83 -0
  486. package/lib/node/memory-monitor.js.map +1 -0
  487. package/lib/node/node-file-system-provider.d.ts +112 -0
  488. package/lib/node/node-file-system-provider.d.ts.map +1 -0
  489. package/lib/node/node-file-system-provider.js +230 -0
  490. package/lib/node/node-file-system-provider.js.map +1 -0
  491. package/lib/node/process-memory.d.ts +66 -0
  492. package/lib/node/process-memory.d.ts.map +1 -0
  493. package/lib/node/process-memory.js +252 -0
  494. package/lib/node/process-memory.js.map +1 -0
  495. package/lib/node/profile-capture.d.ts +118 -0
  496. package/lib/node/profile-capture.d.ts.map +1 -0
  497. package/lib/node/profile-capture.js +315 -0
  498. package/lib/node/profile-capture.js.map +1 -0
  499. package/lib/node/profile-digest.d.ts +49 -0
  500. package/lib/node/profile-digest.d.ts.map +1 -0
  501. package/lib/node/profile-digest.js +74 -0
  502. package/lib/node/profile-digest.js.map +1 -0
  503. package/lib/node/profiling-run.d.ts +80 -0
  504. package/lib/node/profiling-run.d.ts.map +1 -0
  505. package/lib/node/profiling-run.js +183 -0
  506. package/lib/node/profiling-run.js.map +1 -0
  507. package/lib/node/reflect-grammar.d.ts +109 -0
  508. package/lib/node/reflect-grammar.d.ts.map +1 -0
  509. package/lib/node/reflect-grammar.js +96 -0
  510. package/lib/node/reflect-grammar.js.map +1 -0
  511. package/lib/node/server-diagnostics.d.ts +43 -0
  512. package/lib/node/server-diagnostics.d.ts.map +1 -0
  513. package/lib/node/server-diagnostics.js +46 -0
  514. package/lib/node/server-diagnostics.js.map +1 -0
  515. package/lib/node/server-state-snapshot.d.ts +48 -0
  516. package/lib/node/server-state-snapshot.d.ts.map +1 -0
  517. package/lib/node/server-state-snapshot.js +139 -0
  518. package/lib/node/server-state-snapshot.js.map +1 -0
  519. package/lib/node/socket-launcher.d.ts +106 -0
  520. package/lib/node/socket-launcher.d.ts.map +1 -0
  521. package/lib/node/socket-launcher.js +138 -0
  522. package/lib/node/socket-launcher.js.map +1 -0
  523. package/lib/node/stdio-launcher.d.ts +88 -0
  524. package/lib/node/stdio-launcher.d.ts.map +1 -0
  525. package/lib/node/stdio-launcher.js +83 -0
  526. package/lib/node/stdio-launcher.js.map +1 -0
  527. package/lib/node/validate-workspace.d.ts +80 -0
  528. package/lib/node/validate-workspace.d.ts.map +1 -0
  529. package/lib/node/validate-workspace.js +72 -0
  530. package/lib/node/validate-workspace.js.map +1 -0
  531. package/lib/node/write-lock-scope-node.d.ts +27 -0
  532. package/lib/node/write-lock-scope-node.d.ts.map +1 -0
  533. package/lib/node/write-lock-scope-node.js +38 -0
  534. package/lib/node/write-lock-scope-node.js.map +1 -0
  535. package/lib/testing/ast-snapshot.d.ts +38 -0
  536. package/lib/testing/ast-snapshot.d.ts.map +1 -0
  537. package/lib/testing/ast-snapshot.js +78 -0
  538. package/lib/testing/ast-snapshot.js.map +1 -0
  539. package/lib/testing/document-uri-policy-conformance.d.ts +65 -0
  540. package/lib/testing/document-uri-policy-conformance.d.ts.map +1 -0
  541. package/lib/testing/document-uri-policy-conformance.js +69 -0
  542. package/lib/testing/document-uri-policy-conformance.js.map +1 -0
  543. package/lib/testing/fake-description.d.ts +35 -0
  544. package/lib/testing/fake-description.d.ts.map +1 -0
  545. package/lib/testing/fake-description.js +38 -0
  546. package/lib/testing/fake-description.js.map +1 -0
  547. package/lib/testing/fake-document.d.ts +71 -0
  548. package/lib/testing/fake-document.d.ts.map +1 -0
  549. package/lib/testing/fake-document.js +85 -0
  550. package/lib/testing/fake-document.js.map +1 -0
  551. package/lib/testing/fake-reflection.d.ts +29 -0
  552. package/lib/testing/fake-reflection.d.ts.map +1 -0
  553. package/lib/testing/fake-reflection.js +30 -0
  554. package/lib/testing/fake-reflection.js.map +1 -0
  555. package/lib/testing/index.d.ts +44 -0
  556. package/lib/testing/index.d.ts.map +1 -0
  557. package/lib/testing/index.js +44 -0
  558. package/lib/testing/index.js.map +1 -0
  559. package/lib/testing/langium-test-helpers.d.ts +26 -0
  560. package/lib/testing/langium-test-helpers.d.ts.map +1 -0
  561. package/lib/testing/langium-test-helpers.js +26 -0
  562. package/lib/testing/langium-test-helpers.js.map +1 -0
  563. package/lib/testing/make-noop-language-services.d.ts +39 -0
  564. package/lib/testing/make-noop-language-services.d.ts.map +1 -0
  565. package/lib/testing/make-noop-language-services.js +30 -0
  566. package/lib/testing/make-noop-language-services.js.map +1 -0
  567. package/lib/testing/make-noop-shared-services.d.ts +61 -0
  568. package/lib/testing/make-noop-shared-services.d.ts.map +1 -0
  569. package/lib/testing/make-noop-shared-services.js +49 -0
  570. package/lib/testing/make-noop-shared-services.js.map +1 -0
  571. package/lib/testing/make-test-services.d.ts +217 -0
  572. package/lib/testing/make-test-services.d.ts.map +1 -0
  573. package/lib/testing/make-test-services.js +128 -0
  574. package/lib/testing/make-test-services.js.map +1 -0
  575. package/lib/testing/make-test-tracer.d.ts +67 -0
  576. package/lib/testing/make-test-tracer.d.ts.map +1 -0
  577. package/lib/testing/make-test-tracer.js +68 -0
  578. package/lib/testing/make-test-tracer.js.map +1 -0
  579. package/lib/testing/node/generated-workspace.d.ts +95 -0
  580. package/lib/testing/node/generated-workspace.d.ts.map +1 -0
  581. package/lib/testing/node/generated-workspace.js +134 -0
  582. package/lib/testing/node/generated-workspace.js.map +1 -0
  583. package/lib/testing/node/golden-corpus.d.ts +50 -0
  584. package/lib/testing/node/golden-corpus.d.ts.map +1 -0
  585. package/lib/testing/node/golden-corpus.js +80 -0
  586. package/lib/testing/node/golden-corpus.js.map +1 -0
  587. package/lib/testing/node/index.d.ts +28 -0
  588. package/lib/testing/node/index.d.ts.map +1 -0
  589. package/lib/testing/node/index.js +28 -0
  590. package/lib/testing/node/index.js.map +1 -0
  591. package/lib/testing/node/lsp-harness.d.ts +139 -0
  592. package/lib/testing/node/lsp-harness.d.ts.map +1 -0
  593. package/lib/testing/node/lsp-harness.js +119 -0
  594. package/lib/testing/node/lsp-harness.js.map +1 -0
  595. package/lib/testing/node/lsp-server-connection.d.ts +232 -0
  596. package/lib/testing/node/lsp-server-connection.d.ts.map +1 -0
  597. package/lib/testing/node/lsp-server-connection.js +304 -0
  598. package/lib/testing/node/lsp-server-connection.js.map +1 -0
  599. package/lib/testing/node/scratch-workspace.d.ts +60 -0
  600. package/lib/testing/node/scratch-workspace.d.ts.map +1 -0
  601. package/lib/testing/node/scratch-workspace.js +87 -0
  602. package/lib/testing/node/scratch-workspace.js.map +1 -0
  603. package/lib/testing/node/spawned-server.d.ts +170 -0
  604. package/lib/testing/node/spawned-server.d.ts.map +1 -0
  605. package/lib/testing/node/spawned-server.js +265 -0
  606. package/lib/testing/node/spawned-server.js.map +1 -0
  607. package/lib/testing/parse-semantic-root.d.ts +83 -0
  608. package/lib/testing/parse-semantic-root.d.ts.map +1 -0
  609. package/lib/testing/parse-semantic-root.js +119 -0
  610. package/lib/testing/parse-semantic-root.js.map +1 -0
  611. package/lib/testing/playwright/browser-capture-bridge.d.ts +80 -0
  612. package/lib/testing/playwright/browser-capture-bridge.d.ts.map +1 -0
  613. package/lib/testing/playwright/browser-capture-bridge.js +161 -0
  614. package/lib/testing/playwright/browser-capture-bridge.js.map +1 -0
  615. package/lib/testing/playwright/e2e-profiling.d.ts +132 -0
  616. package/lib/testing/playwright/e2e-profiling.d.ts.map +1 -0
  617. package/lib/testing/playwright/e2e-profiling.js +270 -0
  618. package/lib/testing/playwright/e2e-profiling.js.map +1 -0
  619. package/lib/testing/playwright/index.d.ts +13 -0
  620. package/lib/testing/playwright/index.d.ts.map +1 -0
  621. package/lib/testing/playwright/index.js +16 -0
  622. package/lib/testing/playwright/index.js.map +1 -0
  623. package/lib/testing/playwright/server-log-capture.d.ts +230 -0
  624. package/lib/testing/playwright/server-log-capture.d.ts.map +1 -0
  625. package/lib/testing/playwright/server-log-capture.js +336 -0
  626. package/lib/testing/playwright/server-log-capture.js.map +1 -0
  627. package/lib/testing/playwright/server-log-fixture.d.ts +36 -0
  628. package/lib/testing/playwright/server-log-fixture.d.ts.map +1 -0
  629. package/lib/testing/playwright/server-log-fixture.js +38 -0
  630. package/lib/testing/playwright/server-log-fixture.js.map +1 -0
  631. package/lib/testing/playwright/server-log-rename-reporter.d.ts +22 -0
  632. package/lib/testing/playwright/server-log-rename-reporter.d.ts.map +1 -0
  633. package/lib/testing/playwright/server-log-rename-reporter.js +26 -0
  634. package/lib/testing/playwright/server-log-rename-reporter.js.map +1 -0
  635. package/lib/testing/run-update-pipeline.d.ts +99 -0
  636. package/lib/testing/run-update-pipeline.d.ts.map +1 -0
  637. package/lib/testing/run-update-pipeline.js +24 -0
  638. package/lib/testing/run-update-pipeline.js.map +1 -0
  639. package/lib/testing/stub-ast-document-manager.d.ts +82 -0
  640. package/lib/testing/stub-ast-document-manager.d.ts.map +1 -0
  641. package/lib/testing/stub-ast-document-manager.js +125 -0
  642. package/lib/testing/stub-ast-document-manager.js.map +1 -0
  643. package/lib/testing/stub-document-builder.d.ts +99 -0
  644. package/lib/testing/stub-document-builder.d.ts.map +1 -0
  645. package/lib/testing/stub-document-builder.js +142 -0
  646. package/lib/testing/stub-document-builder.js.map +1 -0
  647. package/lib/testing/stub-hydranium-text-documents.d.ts +125 -0
  648. package/lib/testing/stub-hydranium-text-documents.d.ts.map +1 -0
  649. package/lib/testing/stub-hydranium-text-documents.js +164 -0
  650. package/lib/testing/stub-hydranium-text-documents.js.map +1 -0
  651. package/lib/testing/stub-index-manager.d.ts +40 -0
  652. package/lib/testing/stub-index-manager.d.ts.map +1 -0
  653. package/lib/testing/stub-index-manager.js +38 -0
  654. package/lib/testing/stub-index-manager.js.map +1 -0
  655. package/lib/testing/stub-langium-documents.d.ts +53 -0
  656. package/lib/testing/stub-langium-documents.d.ts.map +1 -0
  657. package/lib/testing/stub-langium-documents.js +62 -0
  658. package/lib/testing/stub-langium-documents.js.map +1 -0
  659. package/lib/testing/stub-model-service.d.ts +31 -0
  660. package/lib/testing/stub-model-service.d.ts.map +1 -0
  661. package/lib/testing/stub-model-service.js +45 -0
  662. package/lib/testing/stub-model-service.js.map +1 -0
  663. package/lib/testing/stub-project-manager.d.ts +43 -0
  664. package/lib/testing/stub-project-manager.d.ts.map +1 -0
  665. package/lib/testing/stub-project-manager.js +125 -0
  666. package/lib/testing/stub-project-manager.js.map +1 -0
  667. package/lib/testing/stub-self-save-registry.d.ts +31 -0
  668. package/lib/testing/stub-self-save-registry.d.ts.map +1 -0
  669. package/lib/testing/stub-self-save-registry.js +23 -0
  670. package/lib/testing/stub-self-save-registry.js.map +1 -0
  671. package/lib/testing/stub-service-registry.d.ts +95 -0
  672. package/lib/testing/stub-service-registry.d.ts.map +1 -0
  673. package/lib/testing/stub-service-registry.js +108 -0
  674. package/lib/testing/stub-service-registry.js.map +1 -0
  675. package/lib/testing/stub-writable-file-system.d.ts +42 -0
  676. package/lib/testing/stub-writable-file-system.d.ts.map +1 -0
  677. package/lib/testing/stub-writable-file-system.js +26 -0
  678. package/lib/testing/stub-writable-file-system.js.map +1 -0
  679. package/lib/util/connection-liveness.d.ts +25 -0
  680. package/lib/util/connection-liveness.d.ts.map +1 -0
  681. package/lib/util/connection-liveness.js +46 -0
  682. package/lib/util/connection-liveness.js.map +1 -0
  683. package/lib/util/environment.d.ts +53 -0
  684. package/lib/util/environment.d.ts.map +1 -0
  685. package/lib/util/environment.js +78 -0
  686. package/lib/util/environment.js.map +1 -0
  687. package/lib/util/index.d.ts +13 -0
  688. package/lib/util/index.d.ts.map +1 -0
  689. package/lib/util/index.js +18 -0
  690. package/lib/util/index.js.map +1 -0
  691. package/lib/util/registry.d.ts +88 -0
  692. package/lib/util/registry.d.ts.map +1 -0
  693. package/lib/util/registry.js +105 -0
  694. package/lib/util/registry.js.map +1 -0
  695. package/package.json +134 -0
  696. package/src/documents/ast-document-manager.ts +455 -0
  697. package/src/documents/client-ids.ts +33 -0
  698. package/src/documents/hydranium-text-documents.ts +1142 -0
  699. package/src/documents/index.ts +14 -0
  700. package/src/documents/language-client-text-shadow.ts +175 -0
  701. package/src/documents/self-save-registry.ts +81 -0
  702. package/src/index.ts +39 -0
  703. package/src/langium/ast-extension/ast-extension-contribution.ts +35 -0
  704. package/src/langium/ast-extension/ast-extension-service.ts +311 -0
  705. package/src/langium/ast-extension/ast-node-builder.ts +125 -0
  706. package/src/langium/ast-extension/index.ts +12 -0
  707. package/src/langium/bootstrap.ts +600 -0
  708. package/src/langium/build-phase-pass/build-phase-pass-service.ts +141 -0
  709. package/src/langium/build-phase-pass/build-phase-pass.ts +123 -0
  710. package/src/langium/build-phase-pass/index.ts +11 -0
  711. package/src/langium/config/index.ts +10 -0
  712. package/src/langium/config/settings.ts +353 -0
  713. package/src/langium/diagnostics/hydranium-langium-profiler.ts +187 -0
  714. package/src/langium/diagnostics/index.ts +19 -0
  715. package/src/langium/diagnostics/log-file-token.ts +26 -0
  716. package/src/langium/diagnostics/log-preamble.ts +87 -0
  717. package/src/langium/diagnostics/logger.ts +246 -0
  718. package/src/langium/diagnostics/lsp-logger.ts +277 -0
  719. package/src/langium/diagnostics/server-tracer.ts +73 -0
  720. package/src/langium/document-builder/build-pipeline-integration.ts +193 -0
  721. package/src/langium/document-builder/document-builder.ts +839 -0
  722. package/src/langium/document-builder/index.ts +12 -0
  723. package/src/langium/document-builder/labeled-phase-listener.ts +26 -0
  724. package/src/langium/documentation/comment-provider.ts +37 -0
  725. package/src/langium/documentation/index.ts +10 -0
  726. package/src/langium/integration-services.ts +281 -0
  727. package/src/langium/integrity/index.ts +12 -0
  728. package/src/langium/integrity/integrity-contribution.ts +44 -0
  729. package/src/langium/integrity/integrity-rule.ts +100 -0
  730. package/src/langium/integrity/integrity-service.ts +423 -0
  731. package/src/langium/keys/default-element-key-provider.ts +20 -0
  732. package/src/langium/keys/element-key-provider.ts +114 -0
  733. package/src/langium/keys/index.ts +13 -0
  734. package/src/langium/keys/name-based-key-provider.ts +146 -0
  735. package/src/langium/keys/positional-key-provider.ts +57 -0
  736. package/src/langium/labeling/index.ts +10 -0
  737. package/src/langium/labeling/label-provider.ts +110 -0
  738. package/src/langium/language-module.ts +367 -0
  739. package/src/langium/language-types.ts +214 -0
  740. package/src/langium/model-service/index.ts +10 -0
  741. package/src/langium/model-service/model-service.ts +1051 -0
  742. package/src/langium/module.ts +446 -0
  743. package/src/langium/naming/index.ts +11 -0
  744. package/src/langium/naming/name-provider.ts +533 -0
  745. package/src/langium/naming/name-separator-validation.ts +73 -0
  746. package/src/langium/project/abstract-project-manager.ts +630 -0
  747. package/src/langium/project/index.ts +13 -0
  748. package/src/langium/project/project-change-event.ts +66 -0
  749. package/src/langium/project/project-manager.ts +221 -0
  750. package/src/langium/project/single-project-manager.ts +126 -0
  751. package/src/langium/residency/cst-residency-service.ts +412 -0
  752. package/src/langium/residency/index.ts +10 -0
  753. package/src/langium/scope/ast-node-description-provider.ts +141 -0
  754. package/src/langium/scope/hydranium-scope-computation.ts +246 -0
  755. package/src/langium/scope/hydranium-scope-provider.ts +659 -0
  756. package/src/langium/scope/index.ts +18 -0
  757. package/src/langium/scope/reference-builder.ts +194 -0
  758. package/src/langium/scope/reference-candidate-provider.ts +314 -0
  759. package/src/langium/scope/scope-extension-contribution.ts +34 -0
  760. package/src/langium/scope/scope-extension-service.ts +207 -0
  761. package/src/langium/scope/scoped-ast-node-description.ts +174 -0
  762. package/src/langium/scope/tier-specificity.ts +89 -0
  763. package/src/langium/serialization/abstract-serializer.ts +474 -0
  764. package/src/langium/serialization/index.ts +14 -0
  765. package/src/langium/serialization/json-serializer.ts +264 -0
  766. package/src/langium/serialization/serialization-util.ts +40 -0
  767. package/src/langium/serialization/serializer.ts +68 -0
  768. package/src/langium/serialization/yaml-serializer.ts +348 -0
  769. package/src/langium/service-registry.ts +323 -0
  770. package/src/langium/shared-services.ts +107 -0
  771. package/src/langium/transfer/index.ts +10 -0
  772. package/src/langium/transfer/transfer-encoder.ts +434 -0
  773. package/src/langium/update-rewrite/index.ts +14 -0
  774. package/src/langium/update-rewrite/normalize-empty-strings.ts +86 -0
  775. package/src/langium/update-rewrite/semantic-root-rewrite.ts +57 -0
  776. package/src/langium/update-rewrite/update-rewrite-contribution.ts +44 -0
  777. package/src/langium/update-rewrite/update-rewrite-service.ts +129 -0
  778. package/src/langium/update-rewrite/update-rewrite.ts +60 -0
  779. package/src/langium/validation/document-validator.ts +188 -0
  780. package/src/langium/validation/index.ts +12 -0
  781. package/src/langium/validation/validation-contribution-collector.ts +61 -0
  782. package/src/langium/validation/validation-contribution.ts +38 -0
  783. package/src/langium/workspace/additional-document-contribution.ts +80 -0
  784. package/src/langium/workspace/document-uri-policy.ts +187 -0
  785. package/src/langium/workspace/file-system-provider.ts +52 -0
  786. package/src/langium/workspace/hydranium-langium-document-factory.ts +78 -0
  787. package/src/langium/workspace/hydranium-workspace-lock.ts +35 -0
  788. package/src/langium/workspace/hydranium-workspace-manager.ts +412 -0
  789. package/src/langium/workspace/in-memory-file-system-provider.ts +241 -0
  790. package/src/langium/workspace/index-manager.ts +266 -0
  791. package/src/langium/workspace/index.ts +23 -0
  792. package/src/langium/workspace/initialize-workspace.ts +102 -0
  793. package/src/langium/workspace/langium-documents.ts +94 -0
  794. package/src/langium/workspace/persistent-file-system-provider.ts +287 -0
  795. package/src/langium/workspace/synthetic.ts +63 -0
  796. package/src/langium/workspace/virtual-document.ts +94 -0
  797. package/src/langium/workspace/write-lock-scope.ts +88 -0
  798. package/src/launcher/index.ts +12 -0
  799. package/src/launcher/integrated-server.ts +28 -0
  800. package/src/lsp/completion/hydranium-completion-provider.ts +132 -0
  801. package/src/lsp/hydranium-document-update-handler.ts +345 -0
  802. package/src/lsp/index.ts +24 -0
  803. package/src/lsp/instrument-connection.ts +66 -0
  804. package/src/lsp/language-module.ts +64 -0
  805. package/src/lsp/semantic-token-provider.ts +215 -0
  806. package/src/lsp/shared-module.ts +88 -0
  807. package/src/lsp/start-language-server.ts +68 -0
  808. package/src/node/ast-ground-truth.ts +76 -0
  809. package/src/node/event-loop-monitor.ts +89 -0
  810. package/src/node/index.ts +53 -0
  811. package/src/node/latency-from-env.ts +39 -0
  812. package/src/node/lint-grammar.ts +189 -0
  813. package/src/node/log-file-sink.ts +43 -0
  814. package/src/node/log-preamble-node.ts +63 -0
  815. package/src/node/measure-memory.ts +196 -0
  816. package/src/node/memory-monitor.ts +103 -0
  817. package/src/node/node-file-system-provider.ts +252 -0
  818. package/src/node/process-memory.ts +299 -0
  819. package/src/node/profile-capture.ts +377 -0
  820. package/src/node/profile-digest.ts +112 -0
  821. package/src/node/profiling-run.ts +236 -0
  822. package/src/node/reflect-grammar.ts +182 -0
  823. package/src/node/server-diagnostics.ts +63 -0
  824. package/src/node/server-state-snapshot.ts +192 -0
  825. package/src/node/socket-launcher.ts +210 -0
  826. package/src/node/stdio-launcher.ts +150 -0
  827. package/src/node/validate-workspace.ts +133 -0
  828. package/src/node/write-lock-scope-node.ts +41 -0
  829. package/src/testing/ast-snapshot.ts +88 -0
  830. package/src/testing/document-uri-policy-conformance.ts +104 -0
  831. package/src/testing/fake-description.ts +52 -0
  832. package/src/testing/fake-document.ts +120 -0
  833. package/src/testing/fake-reflection.ts +39 -0
  834. package/src/testing/index.ts +45 -0
  835. package/src/testing/langium-test-helpers.ts +26 -0
  836. package/src/testing/make-noop-language-services.ts +47 -0
  837. package/src/testing/make-noop-shared-services.ts +78 -0
  838. package/src/testing/make-test-services.ts +356 -0
  839. package/src/testing/make-test-tracer.ts +92 -0
  840. package/src/testing/node/generated-workspace.ts +222 -0
  841. package/src/testing/node/golden-corpus.ts +114 -0
  842. package/src/testing/node/index.ts +29 -0
  843. package/src/testing/node/lsp-harness.ts +230 -0
  844. package/src/testing/node/lsp-server-connection.ts +575 -0
  845. package/src/testing/node/scratch-workspace.ts +137 -0
  846. package/src/testing/node/spawned-server.ts +447 -0
  847. package/src/testing/parse-semantic-root.ts +150 -0
  848. package/src/testing/playwright/browser-capture-bridge.ts +258 -0
  849. package/src/testing/playwright/e2e-profiling.ts +362 -0
  850. package/src/testing/playwright/index.ts +16 -0
  851. package/src/testing/playwright/server-log-capture.ts +433 -0
  852. package/src/testing/playwright/server-log-fixture.ts +57 -0
  853. package/src/testing/playwright/server-log-rename-reporter.ts +29 -0
  854. package/src/testing/run-update-pipeline.ts +113 -0
  855. package/src/testing/stub-ast-document-manager.ts +224 -0
  856. package/src/testing/stub-document-builder.ts +242 -0
  857. package/src/testing/stub-hydranium-text-documents.ts +270 -0
  858. package/src/testing/stub-index-manager.ts +79 -0
  859. package/src/testing/stub-langium-documents.ts +104 -0
  860. package/src/testing/stub-model-service.ts +72 -0
  861. package/src/testing/stub-project-manager.ts +161 -0
  862. package/src/testing/stub-self-save-registry.ts +43 -0
  863. package/src/testing/stub-service-registry.ts +192 -0
  864. package/src/testing/stub-writable-file-system.ts +58 -0
  865. package/src/util/connection-liveness.ts +47 -0
  866. package/src/util/environment.ts +88 -0
  867. package/src/util/index.ts +18 -0
  868. package/src/util/registry.ts +129 -0
@@ -0,0 +1,839 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+
10
+ import { type Clock, type LogThreshold, type MaybeObservableValue, ObservableValue, type Tracer } from '@hydranium/protocol';
11
+ import {
12
+ type BuildOptions,
13
+ DefaultDocumentBuilder,
14
+ type DocumentPhaseListener,
15
+ DocumentState,
16
+ type LangiumDocument,
17
+ OperationCancelled,
18
+ type URI,
19
+ UriUtils,
20
+ interruptAndCheck,
21
+ isOperationCancelled
22
+ } from '@hydranium/langium';
23
+ import { CancellationToken, type Diagnostic } from 'vscode-languageserver-protocol';
24
+ import { type LogNameOptions } from '../diagnostics/logger.js';
25
+ import { CST_REHYDRATION_RESET_STATE, isCstShed } from '../residency/cst-residency-service.js';
26
+ import { type ExtendedServiceRegistry } from '../service-registry.js';
27
+ import { type ServerSharedServicesMinimal } from '../shared-services.js';
28
+ import { type DocumentUriPolicy } from '../workspace/document-uri-policy.js';
29
+ import { type LabeledPhaseListener, labelPhaseListener } from './labeled-phase-listener.js';
30
+
31
+ /** Document states a phase-reached line is emitted for by default — every built phase. */
32
+ export const DEFAULT_LOGGED_PHASES: DocumentState[] = [
33
+ DocumentState.Parsed,
34
+ DocumentState.IndexedContent,
35
+ DocumentState.ComputedScopes,
36
+ DocumentState.Linked,
37
+ DocumentState.IndexedReferences,
38
+ DocumentState.Validated
39
+ ];
40
+
41
+ /**
42
+ * Consecutive re-queued builds that leave a waited-on document at the same state
43
+ * before {@link HydraniumDocumentBuilder.awaitDocumentState} stops re-queuing it.
44
+ * A backstop against spinning builds for a document the builder will never carry
45
+ * to the requested state, not a tuning knob — the first re-queue resolves the
46
+ * case this exists for.
47
+ */
48
+ const MAX_STALLED_REQUEUES = 3;
49
+
50
+ /** Constructor options for {@link HydraniumDocumentBuilder}. */
51
+ export interface DocumentBuilderOptions extends LogNameOptions {
52
+ /**
53
+ * Level at which framework-side log lines are emitted, or `'off'` to
54
+ * suppress every framework log line entirely. Default: `'debug'`. Read once
55
+ * at construction to gate phase-listener registration, so it is a plain
56
+ * value — a live change could not register or dispose listeners.
57
+ */
58
+ readonly logLevel?: LogThreshold;
59
+ /**
60
+ * Document states for which a phase-reached line is emitted. Default: every
61
+ * built phase. Read once at construction (it drives listener registration),
62
+ * so it is a plain value.
63
+ */
64
+ readonly loggedPhases?: DocumentState[];
65
+ /**
66
+ * `notifyDocumentPhase` total ms at or above which a per-listener breakdown
67
+ * is logged. Default: `25`. Read per phase, so it accepts a
68
+ * {@link MaybeObservableValue} — pass a constant or bind it to a user setting.
69
+ */
70
+ readonly slowPhaseMs?: MaybeObservableValue<number>;
71
+ /**
72
+ * Per-listener ms at or above which a listener appears in the breakdown.
73
+ * Default: `5`. Read per phase; accepts a {@link MaybeObservableValue}.
74
+ */
75
+ readonly slowListenerMs?: MaybeObservableValue<number>;
76
+ /**
77
+ * `notifyBuildPhase` total ms at or above which the listener-count line is
78
+ * logged. Default: `25`. Read per phase; accepts a {@link MaybeObservableValue}.
79
+ */
80
+ readonly slowBuildMs?: MaybeObservableValue<number>;
81
+ /**
82
+ * Refresh cross-document `ComputedScopes` derivations when a referencing
83
+ * document is cascade-rebuilt (see
84
+ * {@link HydraniumDocumentBuilder.resetToState}). An `AstExtension` at
85
+ * `ComputedScopes` that reads a cross-document reference and caches a
86
+ * projection of the target keeps a STALE projection otherwise. Default
87
+ * `false` (Langium's standard reset — no extra work). Adopters whose
88
+ * `ComputedScopes` extensions derive from other documents set `true`, at the
89
+ * cost of one extra `collectLocalSymbols` per cascade-affected document.
90
+ */
91
+ readonly refreshCrossDocumentComputedScopes?: boolean;
92
+ }
93
+
94
+ /**
95
+ * Extends Langium's {@link DefaultDocumentBuilder} with:
96
+ *
97
+ * - **Bug-fixes** (always on): an {@link awaitDocumentState} that waits where
98
+ * the default rejects, a {@link prepareBuild} that keeps a cancelled
99
+ * non-validating build from suppressing validation, and a
100
+ * {@link shouldRelink} that never judges a document unaffected on an index
101
+ * that does not describe it.
102
+ * - **URI handling** (always on): directory-aware flattening and cascade
103
+ * deletes in {@link update}, plus the CST-rehydration and cross-document
104
+ * refresh resets in {@link resetToState}.
105
+ * - **In-place rebuild helpers** — {@link reparse} and
106
+ * {@link reparseAndRelink} — for a build-phase listener that mutated a
107
+ * document's AST and must reconcile it within the same build.
108
+ * - **Diagnostic dedupe** at `Validated` ({@link dedupeDiagnostics}).
109
+ * - **Logging instrumentation** (default on, opt-out via `logLevel: 'off'`):
110
+ * phase-reached lines, slow-listener breakdowns on `notifyDocumentPhase`,
111
+ * and slow-build-phase totals on `notifyBuildPhase`.
112
+ *
113
+ * Adopters extend this class — the configuration knobs cover what most
114
+ * adopters need; the `format*Line` methods, `formatUri`, and
115
+ * `collectDeletedURIs` are protected so subclasses can customise wording or
116
+ * domain-aware cascades without re-implementing surrounding logic.
117
+ */
118
+ export class HydraniumDocumentBuilder extends DefaultDocumentBuilder {
119
+ protected readonly tracer: Tracer;
120
+ /** Plain — read once at construction to gate phase-listener registration. */
121
+ protected readonly logLevel: LogThreshold;
122
+ /** Plain — read once at construction; drives which phases get a listener. */
123
+ protected readonly loggedPhases: DocumentState[];
124
+ /** Live slow-phase-total threshold; read `.value` per phase. */
125
+ protected readonly slowPhaseMs: ObservableValue<number>;
126
+ /** Live per-listener threshold; read `.value` per phase. */
127
+ protected readonly slowListenerMs: ObservableValue<number>;
128
+ /** Live slow-build-phase-total threshold; read `.value` per phase. */
129
+ protected readonly slowBuildMs: ObservableValue<number>;
130
+ protected readonly uriPolicy: DocumentUriPolicy;
131
+ protected readonly clock: Clock;
132
+ /** Narrower handle on the same registry as the inherited `serviceRegistry`, for {@link ExtendedServiceRegistry.registrations}. */
133
+ protected readonly languageRegistry: ExtendedServiceRegistry;
134
+ protected languageFileExtensions: string[] = [];
135
+ /** {@link ExtendedServiceRegistry.registrations} {@link languageFileExtensions} was built at; `-1` until first built. */
136
+ protected cachedRegistrations = -1;
137
+ protected lastPhaseMs = 0;
138
+ /** Resolved from {@link DocumentBuilderOptions.refreshCrossDocumentComputedScopes}. */
139
+ protected readonly refreshCrossDocumentComputedScopes: boolean;
140
+ /** LSP event name (e.g. `'didChangeWatchedFiles'`) staged for the next `update()` call. */
141
+ protected pendingUpdateReason?: string;
142
+
143
+ constructor(services: ServerSharedServicesMinimal, options: DocumentBuilderOptions = {}) {
144
+ super(services);
145
+ this.languageRegistry = services.ServiceRegistry;
146
+ this.uriPolicy = services.workspace.DocumentUriPolicy;
147
+ this.clock = services.Clock;
148
+ this.tracer = services.Tracer.for(options.logName ?? 'DocumentBuilder').trace('instantiated');
149
+ this.logLevel = options.logLevel ?? 'debug';
150
+ this.loggedPhases = options.loggedPhases ?? DEFAULT_LOGGED_PHASES;
151
+ this.slowPhaseMs = ObservableValue.from(options.slowPhaseMs ?? 25);
152
+ this.slowListenerMs = ObservableValue.from(options.slowListenerMs ?? 5);
153
+ this.slowBuildMs = ObservableValue.from(options.slowBuildMs ?? 25);
154
+ this.refreshCrossDocumentComputedScopes = options.refreshCrossDocumentComputedScopes ?? false;
155
+ if (this.logLevel !== 'off') {
156
+ this.registerPhaseListeners();
157
+ }
158
+ }
159
+
160
+ // ============================================================
161
+ // Public API — observability primitives
162
+ // ============================================================
163
+
164
+ /**
165
+ * Stage an LSP event name for the next `update()` call. Adopters call before
166
+ * the update fires; `HydraniumDocumentUpdateHandler` does it for the
167
+ * four LSP events.
168
+ *
169
+ * The framework stages the value and never reads it back. The consumer is a
170
+ * subclass overriding the build logging, which takes
171
+ * {@link pendingUpdateReason}, clears it, and tags its build line with the
172
+ * event that caused the build. So a grep of this repo alone shows a write
173
+ * with no read — that is the seam working, not a dead field.
174
+ */
175
+ markNextReason(reason: string | undefined): void {
176
+ this.pendingUpdateReason = reason;
177
+ }
178
+
179
+ /**
180
+ * Diagnostic snapshot for use in timeout/error messages around document
181
+ * state.
182
+ *
183
+ * Public rather than `protected`, against the default for a `format*`
184
+ * helper: the GLSP head reads it off the shared services tree to build its
185
+ * own diagnostics, and a cross-package caller cannot reach a `protected`
186
+ * member. Narrowing it would move that formatting into the caller and
187
+ * duplicate what this already knows.
188
+ */
189
+ formatBuildStatus(uri: URI): string {
190
+ // Canonicalize at the door (like every other document-lookup): a caller may
191
+ // hold a divergent spelling (e.g. a GLSP state's symlink `_sourceUri`) while
192
+ // the document is keyed by its real path.
193
+ const doc = this.langiumDocuments.getDocument(UriUtils.toUri(this.uriPolicy.canonicalUri(uri)));
194
+ const docState = doc ? DocumentState[doc.state] : 'unknown (document not loaded)';
195
+ const lastPhase = this.lastPhaseMs > 0 ? `${Math.round(performance.now() - this.lastPhaseMs)}ms ago` : 'no phase observed';
196
+ return `current state: '${docState}', last phase: ${lastPhase}`;
197
+ }
198
+
199
+ // ============================================================
200
+ // Bug-fixes (always on)
201
+ // ============================================================
202
+
203
+ /**
204
+ * Two edge cases the default Langium implementation rejects on:
205
+ * - Document below target state with no build active (newly-created file):
206
+ * wait for the next build instead of rejecting with "workspace state
207
+ * already Validated".
208
+ * - Document at target state but build active and state may regress: wait
209
+ * for phase notification instead of resolving immediately on stale state.
210
+ *
211
+ * When the document is already at target state and no regression is in
212
+ * progress, resolves immediately — avoids deadlocks where callers inside
213
+ * `onDocumentPhase` callbacks would block the active build otherwise.
214
+ *
215
+ * Replacing Langium's rejection with a wait makes the wait's liveness this
216
+ * class's responsibility: a listener can only fire if some build is still
217
+ * going to reach `state`. Both re-queue sites below exist for that, and they
218
+ * differ only in when the orphaning is observed — {@link isOrphaned} at
219
+ * registration time, the `onBuildPhase` branch for a build cancelled after
220
+ * the wait was already armed. Re-queuing stops after
221
+ * {@link MAX_STALLED_REQUEUES} builds that fail to advance the document, so a
222
+ * document the builder will never carry to `state` degrades to a pending wait
223
+ * plus a warning rather than an endless build loop.
224
+ */
225
+ protected override awaitDocumentState(state: DocumentState, uri: URI, cancelToken: CancellationToken): Promise<URI> {
226
+ const document = this.langiumDocuments.getDocument(uri);
227
+ if (!document) {
228
+ return super.awaitDocumentState(state, uri, cancelToken);
229
+ }
230
+ if (document.state >= state) {
231
+ return Promise.resolve(uri);
232
+ }
233
+ return new Promise<URI>((resolve, reject) => {
234
+ // Re-queues since the document last advanced. A re-queue is only ever
235
+ // worth repeating if the previous one made progress: repeating it for a
236
+ // document the builder will never carry to `state` — an adopter
237
+ // narrowing `shouldValidate`, say — would spin builds forever, since
238
+ // each build's own completion is what re-triggers the branch below.
239
+ // Bounded rather than one-shot because a re-queue legitimately fails to
240
+ // land while a busy workspace keeps cancelling builds.
241
+ let stalledRequeues = 0;
242
+ let lastRequeueState: DocumentState | undefined;
243
+ const requeue = (reason: string): void => {
244
+ if (document.state === lastRequeueState) {
245
+ if (++stalledRequeues > MAX_STALLED_REQUEUES) {
246
+ this.tracer
247
+ .withUri(uri.toString())
248
+ .warn(
249
+ `Giving up re-queuing ${this.formatUri(uri)}: stuck at '${DocumentState[document.state]}', needs ` +
250
+ `'${DocumentState[state]}' after ${stalledRequeues} builds that did not advance it. ` +
251
+ 'The wait now depends on its cancellation token.'
252
+ );
253
+ return;
254
+ }
255
+ } else {
256
+ stalledRequeues = 0;
257
+ lastRequeueState = document.state;
258
+ }
259
+ this.requeueOrphaned(document, state, reason);
260
+ };
261
+ const phaseDisposable = this.onDocumentPhase(
262
+ state,
263
+ labelPhaseListener((doc: LangiumDocument): void => {
264
+ if (UriUtils.equals(doc.uri, uri)) {
265
+ cleanup();
266
+ resolve(doc.uri);
267
+ }
268
+ }, 'awaitDocumentState')
269
+ );
270
+ const buildDisposable = this.onBuildPhase(DocumentState.Validated, () => {
271
+ if (document.state >= state) {
272
+ cleanup();
273
+ resolve(uri);
274
+ } else {
275
+ // Orphaned by a cancelled build — re-queue so the next build catches it up.
276
+ requeue('cancelled build');
277
+ }
278
+ });
279
+ const cancelDisposable = cancelToken.onCancellationRequested(() => {
280
+ cleanup();
281
+ reject(OperationCancelled);
282
+ });
283
+ const cleanup = (): void => {
284
+ phaseDisposable.dispose();
285
+ buildDisposable.dispose();
286
+ cancelDisposable.dispose();
287
+ };
288
+ // Orphaned BEFORE the wait was armed: the build that would have
289
+ // advanced this document has already finished, so neither listener
290
+ // above can ever fire. Re-queue now — the listeners are registered, so
291
+ // the resulting build resolves this wait.
292
+ if (this.isOrphaned(document, state)) {
293
+ requeue('quiescent builder');
294
+ }
295
+ });
296
+ }
297
+
298
+ /**
299
+ * Whether no build will advance `document` to `state`, so a wait on it can
300
+ * only be resolved by starting one.
301
+ *
302
+ * `currentState` is the target phase the builder last *completed*, and both
303
+ * `build` and `update` reset it to `Changed` before stepping the phases — so
304
+ * `currentState >= state` means the workspace has already passed `state`
305
+ * without carrying this document along, rather than being on its way there.
306
+ * That is precisely the condition Langium's `awaitDocumentState` rejects on;
307
+ * this class waits instead, and therefore has to schedule the build itself.
308
+ *
309
+ * The common cause is benign: workspace initialization builds with Langium's
310
+ * default `initialBuildOptions`, whose `validation` is unset, which
311
+ * leaves every document at `IndexedReferences` while the builder's own
312
+ * `currentState` still advances to `Validated` (the validation phase runs
313
+ * over an empty document list). Any first read that wants diagnostics — a
314
+ * one-shot data-head read, a CLI query, `ModelService.validated` — lands
315
+ * here.
316
+ */
317
+ protected isOrphaned(document: LangiumDocument, state: DocumentState): boolean {
318
+ return document.state < state && this.currentState >= state;
319
+ }
320
+
321
+ /**
322
+ * Schedule a build for a document no in-flight build will advance. Deliberately
323
+ * fire-and-forget: the caller is a waiter that resolves off the resulting phase
324
+ * notification, so awaiting here would invert the dependency. A rejection is
325
+ * logged rather than swallowed — it leaves the waiter pending until its own
326
+ * cancellation token fires, which is worth a line in the log.
327
+ */
328
+ protected requeueOrphaned(document: LangiumDocument, state: DocumentState, reason: string): void {
329
+ const tracer = this.tracer.withUri(document.uri.toString());
330
+ tracer.info(`Re-queuing orphaned document (at '${DocumentState[document.state]}', needs '${DocumentState[state]}'): ${reason}`);
331
+ this.update([document.uri], []).catch((err: unknown) => {
332
+ if (!isOperationCancelled(err)) {
333
+ tracer.error(`Re-queue build failed: ${err instanceof Error ? err.message : String(err)}`);
334
+ }
335
+ });
336
+ }
337
+
338
+ /**
339
+ * Don't let a cancelled non-validating build suppress validation forever.
340
+ *
341
+ * Langium's `prepareBuild` deliberately RETAINS the previous build options
342
+ * for a document whose previous build did not complete, so a cancelled
343
+ * build resumes with the options it started under. That is right in
344
+ * general and wrong for exactly one case: the initial workspace build runs
345
+ * with `initialBuildOptions` (`{}` — validation OFF), so if it is cancelled
346
+ * partway, every document it had not yet finished keeps `validation: false`.
347
+ * The next build inherits that, `shouldValidate` returns false, and
348
+ * `buildDocuments` marks those documents COMPLETED without ever validating
349
+ * them — no diagnostics computed, none published, and nothing in the log.
350
+ *
351
+ * A write arriving during workspace startup is enough to trigger it, since
352
+ * `WorkspaceLock.write` cancels the in-flight initial build. Measured: the
353
+ * cross-grammar dependents of an edited document silently never publish.
354
+ *
355
+ * So when the incoming build asks for validation and a retained, incomplete
356
+ * state does not, upgrade that state's validation option. Resuming
357
+ * behaviour is otherwise untouched — the retained state, its phase and its
358
+ * prior result all still stand.
359
+ */
360
+ protected override prepareBuild(documents: LangiumDocument[], options: BuildOptions): void {
361
+ super.prepareBuild(documents, options);
362
+ if (!options.validation) {
363
+ return;
364
+ }
365
+ for (const document of documents) {
366
+ const key = document.uri.toString();
367
+ const state = this.buildState.get(key);
368
+ if (state && !state.completed && !state.options.validation) {
369
+ this.buildState.set(key, { ...state, options: { ...state.options, validation: options.validation } });
370
+ this.tracer.withUri(key).debug('Upgraded a retained incomplete build state to validate (was carrying validation:false)');
371
+ }
372
+ }
373
+ }
374
+
375
+ /**
376
+ * Never judge a document unaffected on an index that does not describe it.
377
+ *
378
+ * Langium's `shouldRelink` asks `IndexManager.isAffected`, which reads the
379
+ * REFERENCE index — populated at `DocumentState.IndexedReferences`. A
380
+ * document that has not reached that phase has no entries there, so
381
+ * `isAffected` returns false for every change: not "unaffected", merely
382
+ * unknown. It is then left at `Linked`, and because `runCancelable` only
383
+ * processes documents whose state is BELOW its target, the next build does
384
+ * not re-link it either — it advances to `Validated` carrying links resolved
385
+ * against the OLD content, and validates clean.
386
+ *
387
+ * An interrupted initial build is enough to produce that state: the workspace
388
+ * build is a `WorkspaceLock.write` action, so any write arriving during
389
+ * startup cancels it, typically between `Linked` and `IndexedReferences`.
390
+ * Measured: the edited document's cross-grammar dependents keep stale,
391
+ * successfully-resolved references and report no diagnostics at all.
392
+ *
393
+ * Treating an un-indexed document as affected is the conservative reading and
394
+ * costs nothing in steady state — documents sit at `Validated` there, so this
395
+ * branch is only taken for documents an interrupted build left behind.
396
+ */
397
+ protected override shouldRelink(document: LangiumDocument, changedUris: Set<string>): boolean {
398
+ if (document.state < DocumentState.IndexedReferences) {
399
+ return true;
400
+ }
401
+ return super.shouldRelink(document, changedUris);
402
+ }
403
+
404
+ // ============================================================
405
+ // URI handling — directory flattening + cascade deletes (always on)
406
+ // ============================================================
407
+
408
+ override update(changed: URI[], deleted: URI[], cancelToken?: CancellationToken): Promise<void> {
409
+ this.ensureLanguageFileExtensions();
410
+ const changedURIs = changed.flatMap(uri => this.flattenAndAdaptURI(uri));
411
+ const deletedURIs = deleted.flatMap(uri => this.collectDeletedURIs(uri));
412
+ return super.update(changedURIs, deletedURIs, cancelToken);
413
+ }
414
+
415
+ /**
416
+ * Refresh cross-document `ComputedScopes` derivations on cascade, when
417
+ * {@link refreshCrossDocumentComputedScopes} is set (default off).
418
+ *
419
+ * An `AstExtension` registered at `ComputedScopes` whose `compute` resolves
420
+ * a cross-document reference and reads the target's data depends on another
421
+ * document's content. Langium resets a
422
+ * cascade-affected (referencing) document TO `ComputedScopes` and rebuilds it
423
+ * from `Linked` — so the `ComputedScopes` phase is never re-emitted for it and
424
+ * those derivations keep a stale projection of the referenced document. The
425
+ * symptom: a document whose computed projection of the referenced document
426
+ * — the projection that feeds its scope during `Linked` — does not pick up a
427
+ * member added there until the referencing document is re-parsed.
428
+ *
429
+ * When enabled, reset such documents one phase lower, to `IndexedContent`, so `ComputedScopes`
430
+ * (and its AST-extension pass) re-executes before the document's own link.
431
+ * `IndexedContent` — not `Parsed` — is the minimal reset: the document is left
432
+ * AT `IndexedContent`, so the build's `IndexedContent` pass skips it (no
433
+ * redundant own-symbol re-index) while the `ComputedScopes` pass re-runs
434
+ * `collectLocalSymbols` + the extension refresh. `ComputedScopes` is passed here
435
+ * only for the relink set (changed documents reset to `Changed`,
436
+ * supersession resets to `IndexedReferences`), so this is scoped to exactly the
437
+ * cascade-affected documents. Cost: one extra `collectLocalSymbols` per affected
438
+ * document per cascade.
439
+ */
440
+ override resetToState(document: LangiumDocument, state: DocumentState): void {
441
+ // Rehydrate-on-re-entry after CST shedding. A document whose CST was shed to
442
+ // reclaim memory (its `parseResult.value.$cstNode` nulled while the AST stays
443
+ // resident) cannot be relinked or re-indexed in place: Langium's
444
+ // `DefaultReferenceDescriptionProvider` derives the reference index — and thus
445
+ // `IndexManager.isAffected`, plus the `segment` used by rename / find-references —
446
+ // from each `reference.$refNode`. Re-running `IndexedReferences` with a shed CST
447
+ // drops the document's cross-references from the index (the provider skips any
448
+ // reference whose `$refNode` is missing), so its dependents silently stop being
449
+ // relinked when a referenced document changes, and they keep stale `.ref`s.
450
+ //
451
+ // So any re-entry into the build for a shed document must start from a full
452
+ // re-parse, which rebuilds the CST (and every `$refNode`). The residency
453
+ // feature owns both the "is shed" predicate and the recovery reset state
454
+ // (`CST_REHYDRATION_RESET_STATE`, necessarily `Changed`); this
455
+ // supersedes the `IndexedContent` cascade reset below — a re-parse re-runs
456
+ // every phase regardless.
457
+ if (isCstShed(document)) {
458
+ this.tracer.debug(`rehydrating CST of ${this.formatUri(document.uri)} (re-entered build while shed)`);
459
+ super.resetToState(document, CST_REHYDRATION_RESET_STATE);
460
+ return;
461
+ }
462
+ const targetState =
463
+ this.refreshCrossDocumentComputedScopes && state === DocumentState.ComputedScopes ? DocumentState.IndexedContent : state;
464
+ super.resetToState(document, targetState);
465
+ }
466
+
467
+ /**
468
+ * Re-parse a single document in place from its *current text* (the synced
469
+ * store, else disk), advancing it to `Parsed`. A thin wrapper over Langium's
470
+ * document factory so a caller already holding the write lock — e.g. the
471
+ * integrity service, which updated the document text after mutating its AST —
472
+ * can re-derive a fresh, consistent CST/AST without a full `update()` cycle.
473
+ *
474
+ * Reads the canonical source the build itself parses (not a passed-in
475
+ * string), so the CST cannot drift from the synced text; callers must update
476
+ * the text before calling.
477
+ */
478
+ async reparse(document: LangiumDocument, cancelToken: CancellationToken = CancellationToken.None): Promise<void> {
479
+ await this.langiumDocumentFactory.update(document, cancelToken);
480
+ }
481
+
482
+ /**
483
+ * Re-run the parse → index-content → local-scopes → link phases (0–3) for a
484
+ * single already-built document, in place — re-firing the per-document phase
485
+ * notifications (`onDocumentPhase`, e.g. AST-extension refresh) but NOT the
486
+ * batch `onBuildPhase` notifications.
487
+ *
488
+ * For a build-phase listener (e.g. the integrity service) that mutated a
489
+ * document's AST *after* it was linked — and updated its text to match — and
490
+ * must reconcile the document within the SAME build. A bare AST mutation
491
+ * leaves the CST stale, which makes Langium's re-parse gate
492
+ * (`DefaultLangiumDocumentFactory.update`, keyed on the CST's `fullText`)
493
+ * skip the re-parse on a later build and strand the mutated AST (a corrected
494
+ * edge never returns on reopen). Re-running the document through
495
+ * {@link buildDocuments} would re-fire `onBuildPhase` and re-enter the
496
+ * listener (recursion), so this mirrors {@link runCancelable}'s per-document
497
+ * progression (op → set state → `notifyDocumentPhase`) for phases 0–3 while
498
+ * deliberately omitting `notifyBuildPhase`.
499
+ *
500
+ * Re-firing `onDocumentPhase` matters: per-document derivations such as
501
+ * AST-extension computed properties are wired there, and the freshly
502
+ * re-parsed AST would otherwise lack them. The caller
503
+ * runs inside the `Linked` build phase; the build carries the document
504
+ * through IndexedReferences + Validation (and their `onDocumentPhase`) next.
505
+ */
506
+ async reparseAndRelink(document: LangiumDocument, cancelToken: CancellationToken = CancellationToken.None): Promise<void> {
507
+ const languageServices = this.serviceRegistry.getServices(document.uri);
508
+ // Phase 0 — Parse (the factory sets state to `Parsed` itself).
509
+ await this.reparse(document, cancelToken);
510
+ await this.notifyDocumentPhase(document, DocumentState.Parsed, cancelToken);
511
+ // Phase 1 — Index content.
512
+ await this.indexManager.updateContent(document, cancelToken);
513
+ document.state = DocumentState.IndexedContent;
514
+ await this.notifyDocumentPhase(document, DocumentState.IndexedContent, cancelToken);
515
+ // Phase 2 — Local scopes.
516
+ document.localSymbols = await languageServices.references.ScopeComputation.collectLocalSymbols(document, cancelToken);
517
+ document.state = DocumentState.ComputedScopes;
518
+ await this.notifyDocumentPhase(document, DocumentState.ComputedScopes, cancelToken);
519
+ // Phase 3 — Linking.
520
+ await languageServices.references.Linker.link(document, cancelToken);
521
+ document.state = DocumentState.Linked;
522
+ await this.notifyDocumentPhase(document, DocumentState.Linked, cancelToken);
523
+ }
524
+
525
+ /**
526
+ * Cached on first access — language registration completes after
527
+ * construction — and refreshed on every registration since.
528
+ *
529
+ * The refresh matters because the cache is otherwise held for the process
530
+ * lifetime: a language registered after the first directory expansion would
531
+ * be silently excluded from it, so files of that language would never build
532
+ * on a watched-directory change.
533
+ *
534
+ * Keyed on the registry's monotonic `registrations` counter, not on
535
+ * `all.length`: `register` writes into a map keyed by language id, so
536
+ * REPLACING a registered id leaves the length unchanged and a
537
+ * count-keyed cache would keep the replaced language's extensions. One
538
+ * integer comparison per call, and the "registration must be finished
539
+ * before the first expansion" precondition is gone rather than narrowed.
540
+ */
541
+ protected ensureLanguageFileExtensions(): void {
542
+ const registrations = this.languageRegistry.registrations;
543
+ if (this.cachedRegistrations !== registrations) {
544
+ this.languageFileExtensions = this.languageRegistry.all.flatMap(service => service.LanguageMetaData.fileExtensions);
545
+ this.cachedRegistrations = registrations;
546
+ }
547
+ }
548
+
549
+ /**
550
+ * Expand a changed URI to the registered-language files it covers, keyed
551
+ * canonically. A file resolves to itself (when its extension is registered);
552
+ * a directory expands to every registered language file beneath it.
553
+ *
554
+ * The expansion goes through the `FileSystemProvider` so it is
555
+ * platform-agnostic and discovers on-disk files that are *not yet loaded as
556
+ * documents*: the Node provider walks the real filesystem (a freshly added
557
+ * directory or never-opened file still builds), while a browser / empty
558
+ * provider yields nothing. `uriPolicy.loadUri` first maps the URI to its
559
+ * load identity — `undefined` (no on-disk content) short-circuits to `[]`
560
+ * rather than a doomed read, and a symlink resolves to its real path so the
561
+ * built documents key the same way every other layer does.
562
+ */
563
+ protected flattenAndAdaptURI(uri: URI): URI[] {
564
+ const resolved = this.uriPolicy.loadUri(uri);
565
+ return resolved ? this.collectLanguageFiles(resolved) : [];
566
+ }
567
+
568
+ /** Recurse `uri` through the `FileSystemProvider`, gathering registered
569
+ * language files. A directory's entries carry their own `isDirectory`, so
570
+ * the walk stats each node once (via `readDirectorySync`). */
571
+ protected collectLanguageFiles(uri: URI): URI[] {
572
+ if (!this.isDirectory(uri)) {
573
+ return this.isLanguageFile(uri) ? [uri] : [];
574
+ }
575
+ return this.fileSystemProvider.readDirectorySync(uri).flatMap(entry => {
576
+ if (entry.isDirectory) {
577
+ return this.collectLanguageFiles(entry.uri);
578
+ }
579
+ return this.isLanguageFile(entry.uri) ? [entry.uri] : [];
580
+ });
581
+ }
582
+
583
+ /** A path the provider cannot stat as a directory (missing / unreadable / a
584
+ * plain file) is treated as a non-directory; `collectLanguageFiles` then
585
+ * filters it by extension. */
586
+ protected isDirectory(uri: URI): boolean {
587
+ try {
588
+ return this.fileSystemProvider.statSync(uri).isDirectory;
589
+ } catch {
590
+ return false;
591
+ }
592
+ }
593
+
594
+ /** True when `uri`'s extension matches one of the registered language extensions. */
595
+ protected isLanguageFile(uri: URI): boolean {
596
+ return this.languageFileExtensions.includes(UriUtils.extname(uri));
597
+ }
598
+
599
+ /**
600
+ * Collect URIs to delete when `uri` is deleted. Default: if `uri` is a
601
+ * file, return `[uri]`; if it's a directory, return all documents under
602
+ * that path. Override for domain-aware cascades (e.g. when deleting a
603
+ * project descriptor should cascade to all its members).
604
+ */
605
+ protected collectDeletedURIs(uri: URI): URI[] {
606
+ if (UriUtils.extname(uri)) {
607
+ return [uri];
608
+ }
609
+ return [
610
+ ...this.langiumDocuments.all
611
+ .filter(doc => UriUtils.contains(uri, doc.uri))
612
+ .map(doc => doc.uri)
613
+ .toArray(),
614
+ uri
615
+ ];
616
+ }
617
+
618
+ // ============================================================
619
+ // Logging — phase-reached listeners
620
+ // ============================================================
621
+
622
+ protected registerPhaseListeners(): void {
623
+ for (const state of this.loggedPhases) {
624
+ this.onBuildPhase(state, documents => this.onPhaseReached(state, documents));
625
+ }
626
+ }
627
+
628
+ /** Called once per phase-reached event. Override to add custom side-effects beyond logging. */
629
+ protected onPhaseReached(state: DocumentState, documents: LangiumDocument[]): void {
630
+ const now = performance.now();
631
+ const elapsedMs = Math.round(now - this.lastPhaseMs);
632
+ this.lastPhaseMs = now;
633
+ this.log(this.phaseReachedLine(state, documents, elapsedMs));
634
+ }
635
+
636
+ /** Format the phase-reached log line. Override to customise wording. */
637
+ protected phaseReachedLine(state: DocumentState, documents: LangiumDocument[], elapsedMs: number): string {
638
+ const docInfo = documents.length === 1 ? this.formatUri(documents[0].uri) : `${documents.length} docs`;
639
+ return `Reached phase '${DocumentState[state]}' [${docInfo}, ${elapsedMs}ms since previous phase]`;
640
+ }
641
+
642
+ // ============================================================
643
+ // Logging — slow-listener breakdown on notifyDocumentPhase
644
+ // ============================================================
645
+
646
+ override async notifyDocumentPhase(document: LangiumDocument, state: DocumentState, cancelToken: CancellationToken): Promise<void> {
647
+ // Before the listeners, one of which is Langium's diagnostics publisher.
648
+ // Running first is NOT the same as running atomically with them: the loop
649
+ // below awaits, Langium's validate PUSHES onto the live array rather than
650
+ // replacing it, and the publisher reads that array when it is invoked. A
651
+ // build settling inside that window therefore appends after this call has
652
+ // already deduped, and the appended duplicate is published by the listener
653
+ // of the build that deduped. Only `serializeBuilds` closes the window.
654
+ if (state === DocumentState.Validated) {
655
+ this.dedupeDiagnostics(document);
656
+ }
657
+ if (this.logLevel === 'off') {
658
+ return super.notifyDocumentPhase(document, state, cancelToken);
659
+ }
660
+ const listeners = this.documentPhaseListeners.get(state).slice();
661
+ if (listeners.length === 0) {
662
+ return;
663
+ }
664
+ const perListenerMs: number[] = [];
665
+ let cancelledListeners = 0;
666
+ const { elapsedMs: totalMs } = await this.clock.measure(async () => {
667
+ for (const listener of listeners) {
668
+ const { elapsedMs } = await this.clock.measure(async () => {
669
+ try {
670
+ await interruptAndCheck(cancelToken);
671
+ await listener(document, cancelToken);
672
+ } catch (err) {
673
+ if (!isOperationCancelled(err)) {
674
+ throw err;
675
+ }
676
+ cancelledListeners++;
677
+ }
678
+ });
679
+ perListenerMs.push(elapsedMs);
680
+ }
681
+ });
682
+ if (cancelledListeners > 0) {
683
+ this.tracer
684
+ .withUri(document.uri.toString())
685
+ .info(this.cancelledDocumentPhaseLine(document, state, cancelledListeners, listeners.length));
686
+ }
687
+ if (totalMs >= this.slowPhaseMs.value) {
688
+ this.log(this.slowDocumentPhaseLine(document, state, listeners, perListenerMs, totalMs));
689
+ }
690
+ }
691
+
692
+ /**
693
+ * Format the skipped-listener line.
694
+ *
695
+ * Worth `info` rather than `debug` because of what the skip costs: Langium's
696
+ * `runCancelable` assigns `document.state = targetState` BEFORE calling
697
+ * `notifyDocumentPhase`, so a token that cancels here leaves the document AT
698
+ * the phase with its listeners never run — and the next build's
699
+ * `document.state < targetState` guard then skips it, so nothing re-notifies.
700
+ * At `DocumentState.Validated` the skipped listener is Langium's diagnostics
701
+ * publisher, so the client silently never receives those diagnostics.
702
+ */
703
+ protected cancelledDocumentPhaseLine(document: LangiumDocument, state: DocumentState, cancelled: number, total: number): string {
704
+ return (
705
+ `notifyDocumentPhase '${DocumentState[state]}' [${this.formatUri(document.uri)}]: ` +
706
+ `${cancelled} of ${total} listeners skipped by cancellation — the document is AT this phase but they did not run`
707
+ );
708
+ }
709
+
710
+ /** Format the slow-listener breakdown line. Override to customise wording. */
711
+ protected slowDocumentPhaseLine(
712
+ document: LangiumDocument,
713
+ state: DocumentState,
714
+ listeners: DocumentPhaseListener[],
715
+ perListenerMs: number[],
716
+ totalMs: number
717
+ ): string {
718
+ const slow = perListenerMs
719
+ .map((ms, i) => ({ ms, i }))
720
+ .filter(x => x.ms >= this.slowListenerMs.value)
721
+ .sort((a, b) => b.ms - a.ms)
722
+ .map(x => `${this.formatListener(listeners[x.i], x.i)}:${x.ms.toFixed(0)}ms`);
723
+ const breakdown = slow.length > 0 ? ` — slow listeners: [${slow.join(', ')}]` : '';
724
+ return `notifyDocumentPhase '${DocumentState[state]}' [${this.formatUri(document.uri)}]: ${listeners.length} listeners in ${totalMs.toFixed(0)}ms${breakdown}`;
725
+ }
726
+
727
+ // ============================================================
728
+ // Logging — slow build-phase total on notifyBuildPhase
729
+ // ============================================================
730
+
731
+ override async notifyBuildPhase(documents: LangiumDocument[], state: DocumentState, cancelToken: CancellationToken): Promise<void> {
732
+ if (this.logLevel === 'off') {
733
+ return super.notifyBuildPhase(documents, state, cancelToken);
734
+ }
735
+ const listeners = this.buildPhaseListeners.get(state);
736
+ if (documents.length === 0 || listeners.length === 0) {
737
+ return super.notifyBuildPhase(documents, state, cancelToken);
738
+ }
739
+ const { elapsedMs: totalMs } = await this.clock.measure(() => super.notifyBuildPhase(documents, state, cancelToken));
740
+ if (totalMs >= this.slowBuildMs.value) {
741
+ this.log(this.slowBuildPhaseLine(state, listeners.length, documents, totalMs));
742
+ }
743
+ }
744
+
745
+ /** Format the slow build-phase line. Override to customise wording. */
746
+ protected slowBuildPhaseLine(state: DocumentState, listenerCount: number, documents: LangiumDocument[], totalMs: number): string {
747
+ return `notifyBuildPhase '${DocumentState[state]}': ${listenerCount} listeners, ${documents.length} docs in ${totalMs.toFixed(0)}ms`;
748
+ }
749
+
750
+ // ============================================================
751
+ // Shared formatting hooks
752
+ // ============================================================
753
+
754
+ /** Format a URI for inclusion in log lines. Default: `uri.toString()`. Override for workspace-relative paths. */
755
+ protected formatUri(uri: URI): string {
756
+ return uri.toString();
757
+ }
758
+
759
+ /** Get a human-readable identifier for a phase listener. Falls back to `function.name` or `#index`. */
760
+ protected formatListener(listener: DocumentPhaseListener, index: number): string {
761
+ const labeled = listener as DocumentPhaseListener & LabeledPhaseListener;
762
+ return labeled.displayName ?? (listener.name && listener.name !== 'anonymous' ? listener.name : `#${index}`);
763
+ }
764
+
765
+ /**
766
+ * Collapse byte-identical duplicate diagnostics on `document`, in place.
767
+ *
768
+ * Two unserialised validation passes over one document report everything
769
+ * twice: Langium's validate appends to `document.diagnostics` when they are
770
+ * already set — deliberately, so a category-partitioned pass keeps the earlier
771
+ * category's findings — and a repeated FULL pass therefore doubles the list.
772
+ * `ModelServiceOptions.serializeBuilds` prevents that at the source; this is
773
+ * the net for configurations that allow concurrent builds anyway.
774
+ *
775
+ * Clearing the list before a pass is NOT an alternative: the append happens at
776
+ * pass completion, so two interleaved passes both clear, both finish, and the
777
+ * second still appends onto the first.
778
+ *
779
+ * **Equality is structural over the WHOLE diagnostic**, not a chosen subset of
780
+ * fields. That matters: `Diagnostic` carries `data` (which drives quick fixes),
781
+ * `relatedInformation`, `tags` and `source` besides the obvious range/message,
782
+ * so keying on a subset could collapse two findings that differ only in a
783
+ * code action. Duplicates produced by re-running the same checks over the same
784
+ * AST are identical in every field, so full structural equality removes
785
+ * exactly those. The one behavioural difference from a single pass: if a
786
+ * single pass ever emitted two byte-identical diagnostics, the count drops to
787
+ * one — indistinguishable to any consumer, since nothing can tell the two
788
+ * apart.
789
+ *
790
+ * Cost is kept off the common path. Each diagnostic contributes one short
791
+ * range key; a diagnostic is serialised ONLY when something else already
792
+ * occupies its range, so a document whose diagnostics are all at distinct
793
+ * ranges — every document, whenever builds are serialised — is walked without
794
+ * serialising anything.
795
+ */
796
+ protected dedupeDiagnostics(document: LangiumDocument): void {
797
+ const diagnostics = document.diagnostics;
798
+ if (!diagnostics || diagnostics.length < 2) {
799
+ return;
800
+ }
801
+ const byRange = new Map<string, Diagnostic[]>();
802
+ const unique: Diagnostic[] = [];
803
+ for (const diagnostic of diagnostics) {
804
+ const { start, end } = diagnostic.range;
805
+ const range = `${start.line}:${start.character}-${end.line}:${end.character}`;
806
+ const bucket = byRange.get(range);
807
+ if (!bucket) {
808
+ // First at this range: no candidate to compare against, so no
809
+ // serialisation. This is the whole list when nothing is duplicated,
810
+ // which is the default configuration's every call.
811
+ byRange.set(range, [diagnostic]);
812
+ unique.push(diagnostic);
813
+ continue;
814
+ }
815
+ // Same range as something already kept — now it is worth comparing, and
816
+ // the comparison is over the WHOLE diagnostic so two findings differing
817
+ // only in `data` (a quick-fix payload) or `relatedInformation` survive.
818
+ const serialised = JSON.stringify(diagnostic);
819
+ if (bucket.some(kept => JSON.stringify(kept) === serialised)) {
820
+ continue;
821
+ }
822
+ bucket.push(diagnostic);
823
+ unique.push(diagnostic);
824
+ }
825
+ if (unique.length !== diagnostics.length) {
826
+ this.tracer.debug(`collapsed ${diagnostics.length - unique.length} duplicate diagnostic(s) on ${this.formatUri(document.uri)}`);
827
+ document.diagnostics = unique;
828
+ }
829
+ }
830
+
831
+ // ============================================================
832
+ // Internal helpers
833
+ // ============================================================
834
+
835
+ /** Dispatch a log line at the configured log level; a no-op when `logLevel === 'off'`. */
836
+ protected log(message: string): void {
837
+ this.tracer.logAt(this.logLevel, message);
838
+ }
839
+ }