@backbencher/brain 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/CHANGELOG.md +298 -0
  2. package/EMBEDDINGS.md +355 -0
  3. package/LICENSE +21 -0
  4. package/README.md +415 -2
  5. package/bin/bb +13 -0
  6. package/dist/analysis-exclusions-7ZJDXOVZ.js +35 -0
  7. package/dist/brain-index-health-Q5APTJQL.js +17 -0
  8. package/dist/brain-relationship-enrichment-MYR2AM4F.js +558 -0
  9. package/dist/brain.sql-EIM4WS4D.js +29 -0
  10. package/dist/chunk-22V37YTK.js +1758 -0
  11. package/dist/chunk-2BSKD7O3.js +40 -0
  12. package/dist/chunk-2DE27DVC.js +1314 -0
  13. package/dist/chunk-2RRBMNBQ.js +322 -0
  14. package/dist/chunk-2WXYNLBA.js +29 -0
  15. package/dist/chunk-3CTFIJJB.js +17 -0
  16. package/dist/chunk-3ZTOHHSW.js +2104 -0
  17. package/dist/chunk-4H22TLOT.js +543 -0
  18. package/dist/chunk-5BVAH26D.js +340 -0
  19. package/dist/chunk-62DHLYW6.js +3427 -0
  20. package/dist/chunk-7AN7U5IZ.js +371 -0
  21. package/dist/chunk-7DRPNVIN.js +782 -0
  22. package/dist/chunk-7MBYT777.js +174 -0
  23. package/dist/chunk-AHDWGM7Q.js +236 -0
  24. package/dist/chunk-B5GEAAYF.js +818 -0
  25. package/dist/chunk-BEIZZ73B.js +1479 -0
  26. package/dist/chunk-BQ3OVQ3P.js +125 -0
  27. package/dist/chunk-D2Q4Y47A.js +53 -0
  28. package/dist/chunk-DIYAGQJL.js +34 -0
  29. package/dist/chunk-DWKXZ6IF.js +336 -0
  30. package/dist/chunk-DYM4FQEE.js +90 -0
  31. package/dist/chunk-ENW4BTBA.js +930 -0
  32. package/dist/chunk-EWMWK7WN.js +75 -0
  33. package/dist/chunk-EY5ZZUUA.js +626 -0
  34. package/dist/chunk-GBI7V7KY.js +69 -0
  35. package/dist/chunk-GEFFO6O2.js +152 -0
  36. package/dist/chunk-HJEWO5EV.js +247 -0
  37. package/dist/chunk-HQSPJDHI.js +613 -0
  38. package/dist/chunk-KAET47ZL.js +125 -0
  39. package/dist/chunk-KCDECRJY.js +440 -0
  40. package/dist/chunk-L5TDYKYK.js +76 -0
  41. package/dist/chunk-MLKGABMK.js +9 -0
  42. package/dist/chunk-NO3U3FJQ.js +201 -0
  43. package/dist/chunk-OWISBAOF.js +61 -0
  44. package/dist/chunk-QKTRECYS.js +1119 -0
  45. package/dist/chunk-QLK6ED4Q.js +235 -0
  46. package/dist/chunk-R2GW4F6R.js +19 -0
  47. package/dist/chunk-RCMTFSEF.js +87 -0
  48. package/dist/chunk-RM3PY6TG.js +376 -0
  49. package/dist/chunk-ROMM6KMC.js +433 -0
  50. package/dist/chunk-SGGCSHAX.js +12050 -0
  51. package/dist/chunk-SK6YVHFZ.js +211 -0
  52. package/dist/chunk-SM7RFQRO.js +214 -0
  53. package/dist/chunk-UGR4QIGS.js +67 -0
  54. package/dist/chunk-UQNQZXHY.js +711 -0
  55. package/dist/chunk-UUNHHX4M.js +13 -0
  56. package/dist/chunk-VL52PL2T.js +71 -0
  57. package/dist/chunk-WIG36E67.js +196 -0
  58. package/dist/chunk-XHK3WWGB.js +7436 -0
  59. package/dist/chunk-XTQM2IP3.js +2863 -0
  60. package/dist/chunk-ZE2LG76D.js +1296 -0
  61. package/dist/chunk-ZETTGPAW.js +6950 -0
  62. package/dist/cli/index.js +37 -0
  63. package/dist/config-HZAAYDP3.js +10 -0
  64. package/dist/content-search-7XIP555Q.js +593 -0
  65. package/dist/database-76RP44JG.js +9 -0
  66. package/dist/doctor-ANGETYMN.js +395 -0
  67. package/dist/edit-engine-CG72LDZD.js +51 -0
  68. package/dist/engine-BKEOGN7N.js +11 -0
  69. package/dist/engine-VIW6NSKO.js +18 -0
  70. package/dist/fingerprint-OBLIMZLP.js +33 -0
  71. package/dist/framework-intelligence-3LORTPOX.js +860 -0
  72. package/dist/freshness-3K6VU5OT.js +174 -0
  73. package/dist/graph-engine-HBSQNPTB.js +21 -0
  74. package/dist/graph_request-Q6NKB6N2.js +350 -0
  75. package/dist/impact_request-LYP672WE.js +68 -0
  76. package/dist/index-space-IUUN5WYV.js +15 -0
  77. package/dist/index-status-7OVGYSGW.js +34 -0
  78. package/dist/index.js +159 -0
  79. package/dist/instance-FO6QZRLH.js +19 -0
  80. package/dist/language-detection-DFCAU5DZ.js +11 -0
  81. package/dist/lsp/server.js +4301 -0
  82. package/dist/mcp/server.js +132 -0
  83. package/dist/onboard-DIQZV2NW.js +161 -0
  84. package/dist/override-companion-pass-XR7MHTP7.js +117 -0
  85. package/dist/parallel-indexer-FK2XKZXY.js +88 -0
  86. package/dist/pool-worker.js +1153 -0
  87. package/dist/project-health-6XPENVAA.js +94 -0
  88. package/dist/project-index-5SDPHITE.js +57 -0
  89. package/dist/project-registry-ZJ3DVUGO.js +355 -0
  90. package/dist/real-bash-analyzer-EJAU5LW5.js +2201 -0
  91. package/dist/real-c-analyzer-HBD3FNNH.js +5942 -0
  92. package/dist/real-clean-analyzer-4EEZLPV5.js +3470 -0
  93. package/dist/real-clojure-analyzer-Q55EBOO2.js +2818 -0
  94. package/dist/real-cpp-analyzer-IVVOD25R.js +4101 -0
  95. package/dist/real-csharp-analyzer-ZBNLNJZJ.js +3298 -0
  96. package/dist/real-css-analyzer-6XRQLUN7.js +15 -0
  97. package/dist/real-dart-analyzer-OLR72EFW.js +3944 -0
  98. package/dist/real-elixir-analyzer-MQWGAH2I.js +2192 -0
  99. package/dist/real-erlang-analyzer-7BVPQEHO.js +1731 -0
  100. package/dist/real-fsharp-analyzer-C2UPFNOA.js +2390 -0
  101. package/dist/real-go-analyzer-UKGI43YS.js +4126 -0
  102. package/dist/real-graphql-analyzer-VE2EEFII.js +1442 -0
  103. package/dist/real-groovy-analyzer-W26VACFW.js +2285 -0
  104. package/dist/real-haskell-analyzer-5CVVAJRX.js +2533 -0
  105. package/dist/real-hcl-analyzer-5ZT4U43N.js +725 -0
  106. package/dist/real-html-analyzer-JWNX3C6I.js +1759 -0
  107. package/dist/real-java-analyzer-GU42VBGQ.js +4677 -0
  108. package/dist/real-javascript-analyzer-QA4QOJ6W.js +14 -0
  109. package/dist/real-json-analyzer-MPA6PRXL.js +1640 -0
  110. package/dist/real-julia-analyzer-22CWYQMN.js +2085 -0
  111. package/dist/real-kotlin-analyzer-QDZJLXXU.js +3956 -0
  112. package/dist/real-lua-analyzer-G7NHLYKS.js +1957 -0
  113. package/dist/real-makefile-analyzer-OCY3GT5N.js +920 -0
  114. package/dist/real-markdown-analyzer-TEJK2JXJ.js +1215 -0
  115. package/dist/real-matlab-analyzer-Q5SWLN7Z.js +480 -0
  116. package/dist/real-nim-analyzer-YLXSK563.js +3603 -0
  117. package/dist/real-objective-c-analyzer-D23ACC2R.js +1518 -0
  118. package/dist/real-perl-analyzer-WWTRHYDT.js +1865 -0
  119. package/dist/real-php-analyzer-JNKJHTCL.js +9368 -0
  120. package/dist/real-powershell-analyzer-XRSNQERV.js +2915 -0
  121. package/dist/real-protobuf-analyzer-3OKUCZ7T.js +867 -0
  122. package/dist/real-python-analyzer-VXAFWI72.js +4880 -0
  123. package/dist/real-r-analyzer-ZGAIDVI4.js +2596 -0
  124. package/dist/real-ruby-analyzer-X2KTLVBH.js +2429 -0
  125. package/dist/real-rust-analyzer-OFFHPL2A.js +3359 -0
  126. package/dist/real-scala-analyzer-TSTW27J6.js +3293 -0
  127. package/dist/real-scss-analyzer-AVWYPSOQ.js +1515 -0
  128. package/dist/real-solidity-analyzer-UCI2KWUB.js +2608 -0
  129. package/dist/real-sql-analyzer-F77ZMQXR.js +3840 -0
  130. package/dist/real-svelte-analyzer-SF7NRUO5.js +2532 -0
  131. package/dist/real-swift-analyzer-MN5QT3QN.js +2311 -0
  132. package/dist/real-toml-analyzer-66L7BDCQ.js +929 -0
  133. package/dist/real-typescript-analyzer-6KEMVDWQ.js +14 -0
  134. package/dist/real-vb-analyzer-VICVPOP7.js +3145 -0
  135. package/dist/real-vba-analyzer-HXLTTHKM.js +466 -0
  136. package/dist/real-vue-analyzer-QXR56CFV.js +2680 -0
  137. package/dist/real-xml-analyzer-YL465ZJW.js +2405 -0
  138. package/dist/real-yaml-analyzer-SUBCBNSI.js +3528 -0
  139. package/dist/real-zig-analyzer-HIQLZMGY.js +2430 -0
  140. package/dist/regex-search-NJKHMZNO.js +239 -0
  141. package/dist/rules-ACHPB7QU.js +152 -0
  142. package/dist/scoped-path-MJYWJZQX.js +11 -0
  143. package/dist/setup-show-NT5ZHYNE.js +15 -0
  144. package/dist/setup-wizard-G5YYR5T6.js +24 -0
  145. package/dist/symbol-search-GZJIM2J2.js +16 -0
  146. package/dist/taint-KXUHHPIE.js +202 -0
  147. package/dist/taint-analyzer-N7YLZU3N.js +163 -0
  148. package/dist/tool-handlers-OJDC35DI.js +72 -0
  149. package/dist/tool-registry-BPEJNSZG.js +17 -0
  150. package/dist/tool-validation-Q57YMMBX.js +32 -0
  151. package/dist/type-inference-QMT2RMLV.js +13 -0
  152. package/dist/vector-binary-LMY4QGAN.js +19 -0
  153. package/dist/version-ABP2TUL2.js +9 -0
  154. package/dist/wasm-NMWO3WXY.js +16 -0
  155. package/docs/EMBEDDINGS.md +132 -0
  156. package/docs/README.md +178 -0
  157. package/docs/data/m10-baseline.json +602 -0
  158. package/docs/data/m10-benchmark-baseline.json +57 -0
  159. package/docs/data/m10-benchmark-last-run.json +127 -0
  160. package/docs/data/m10-final-audit.json +215 -0
  161. package/docs/data/m12-final-audit.json +138 -0
  162. package/docs/data/m12-surface-matrix.json +50 -0
  163. package/docs/data/public-tools.json +1902 -0
  164. package/docs/indexing/DEAD-ASSETS.md +88 -0
  165. package/docs/indexing/INDEXER-REVIEW.md +634 -0
  166. package/docs/indexing/PERFORMANCE-FINDINGS.md +106 -0
  167. package/docs/indexing/README.md +427 -0
  168. package/docs/indexing/discovery-matrix.md +41 -0
  169. package/docs/indexing/embeddings.md +325 -0
  170. package/docs/indexing/environment-variables.md +77 -0
  171. package/docs/indexing/performance.md +323 -0
  172. package/docs/indexing/resume.md +345 -0
  173. package/docs/indexing/troubleshooting.md +391 -0
  174. package/docs/man/bb.1 +190 -0
  175. package/docs/tools/bb_analyze.md +147 -0
  176. package/docs/tools/bb_annotate.md +110 -0
  177. package/docs/tools/bb_annotations.md +106 -0
  178. package/docs/tools/bb_ask.md +101 -0
  179. package/docs/tools/bb_cross_language.md +103 -0
  180. package/docs/tools/bb_doc.md +169 -0
  181. package/docs/tools/bb_edit.md +185 -0
  182. package/docs/tools/bb_graph.md +169 -0
  183. package/docs/tools/bb_health.md +156 -0
  184. package/docs/tools/bb_impact.md +117 -0
  185. package/docs/tools/bb_index.md +108 -0
  186. package/docs/tools/bb_migrate.md +135 -0
  187. package/docs/tools/bb_patterns.md +140 -0
  188. package/docs/tools/bb_search.md +150 -0
  189. package/docs/tools/bb_security.md +100 -0
  190. package/docs/tools/bb_visualize.md +184 -0
  191. package/grammars/README.md +57 -0
  192. package/grammars/THIRD-PARTY-NOTICES.md +50 -0
  193. package/grammars/tree-sitter-c/LICENSE +21 -0
  194. package/grammars/tree-sitter-clojure/LICENSE.md +21 -0
  195. package/grammars/tree-sitter-cpp/LICENSE +21 -0
  196. package/grammars/tree-sitter-csharp/LICENSE +21 -0
  197. package/grammars/tree-sitter-css/LICENSE +21 -0
  198. package/grammars/tree-sitter-css/README.md +21 -0
  199. package/grammars/tree-sitter-dart/LICENSE +20 -0
  200. package/grammars/tree-sitter-dart-upstream/LICENSE +20 -0
  201. package/grammars/tree-sitter-dart-upstream/README.md +18 -0
  202. package/grammars/tree-sitter-elixir/LICENSE +176 -0
  203. package/grammars/tree-sitter-elixir/README.md +11 -0
  204. package/grammars/tree-sitter-fsharp/LICENSE +21 -0
  205. package/grammars/tree-sitter-fsharp/README.md +45 -0
  206. package/grammars/tree-sitter-graphql/LICENSE +21 -0
  207. package/grammars/tree-sitter-graphql/README.md +106 -0
  208. package/grammars/tree-sitter-groovy/LICENSE +21 -0
  209. package/grammars/tree-sitter-groovy/README.md +4 -0
  210. package/grammars/tree-sitter-haskell/LICENSE +21 -0
  211. package/grammars/tree-sitter-haskell/README.md +394 -0
  212. package/grammars/tree-sitter-hcl/CHANGELOG.md +102 -0
  213. package/grammars/tree-sitter-hcl/LICENSE +201 -0
  214. package/grammars/tree-sitter-hcl/README.md +39 -0
  215. package/grammars/tree-sitter-html/LICENSE +21 -0
  216. package/grammars/tree-sitter-html/README.md +21 -0
  217. package/grammars/tree-sitter-julia/LICENSE +21 -0
  218. package/grammars/tree-sitter-julia/README.md +24 -0
  219. package/grammars/tree-sitter-kotlin/LICENSE +9 -0
  220. package/grammars/tree-sitter-lua/LICENSE.md +21 -0
  221. package/grammars/tree-sitter-lua/README.md +29 -0
  222. package/grammars/tree-sitter-make/LICENSE +21 -0
  223. package/grammars/tree-sitter-matlab/LICENSE +19 -0
  224. package/grammars/tree-sitter-matlab/README.md +99 -0
  225. package/grammars/tree-sitter-nim/LICENSE +373 -0
  226. package/grammars/tree-sitter-nim/README.md +46 -0
  227. package/grammars/tree-sitter-objc/LICENSE +21 -0
  228. package/grammars/tree-sitter-objc/README.md +20 -0
  229. package/grammars/tree-sitter-perl/LICENSE +7 -0
  230. package/grammars/tree-sitter-perl/README.md +100 -0
  231. package/grammars/tree-sitter-powershell/LICENSE +21 -0
  232. package/grammars/tree-sitter-powershell/README.md +7 -0
  233. package/grammars/tree-sitter-proto/LICENSE +21 -0
  234. package/grammars/tree-sitter-proto/README.md +105 -0
  235. package/grammars/tree-sitter-r/LICENSE +9 -0
  236. package/grammars/tree-sitter-r/README.md +66 -0
  237. package/grammars/tree-sitter-ruby/LICENSE +22 -0
  238. package/grammars/tree-sitter-scss/LICENSE +21 -0
  239. package/grammars/tree-sitter-scss/README.md +17 -0
  240. package/grammars/tree-sitter-solidity/LICENSE +7 -0
  241. package/grammars/tree-sitter-sql/LICENSE +21 -0
  242. package/grammars/tree-sitter-typescript/LICENSE +21 -0
  243. package/grammars/tree-sitter-vba/LICENSE +21 -0
  244. package/grammars/tree-sitter-vba/README.md +738 -0
  245. package/grammars/tree-sitter-vbnet/LICENSE +21 -0
  246. package/grammars/tree-sitter-vbnet/README.md +322 -0
  247. package/grammars/tree-sitter-xml/LICENSE +19 -0
  248. package/grammars/tree-sitter-yaml/LICENSE +20 -0
  249. package/grammars/tree-sitter-yaml/README.md +21 -0
  250. package/package.json +184 -4
  251. package/wasm/dart.wasm +0 -0
  252. package/wasm/tree-sitter-bash.wasm +0 -0
  253. package/wasm/tree-sitter-c.wasm +0 -0
  254. package/wasm/tree-sitter-c_sharp.wasm +0 -0
  255. package/wasm/tree-sitter-clean.wasm +0 -0
  256. package/wasm/tree-sitter-clojure.wasm +0 -0
  257. package/wasm/tree-sitter-core_schema.wasm +0 -0
  258. package/wasm/tree-sitter-cpp.wasm +0 -0
  259. package/wasm/tree-sitter-css.wasm +0 -0
  260. package/wasm/tree-sitter-dart.wasm +0 -0
  261. package/wasm/tree-sitter-elisp.wasm +0 -0
  262. package/wasm/tree-sitter-elixir.wasm +0 -0
  263. package/wasm/tree-sitter-elm.wasm +0 -0
  264. package/wasm/tree-sitter-embedded_template.wasm +0 -0
  265. package/wasm/tree-sitter-erlang.wasm +0 -0
  266. package/wasm/tree-sitter-fsharp.wasm +0 -0
  267. package/wasm/tree-sitter-fsharp_signature.wasm +0 -0
  268. package/wasm/tree-sitter-go.wasm +0 -0
  269. package/wasm/tree-sitter-graphql.wasm +0 -0
  270. package/wasm/tree-sitter-groovy.wasm +0 -0
  271. package/wasm/tree-sitter-haskell.wasm +0 -0
  272. package/wasm/tree-sitter-hcl.wasm +0 -0
  273. package/wasm/tree-sitter-html.wasm +0 -0
  274. package/wasm/tree-sitter-java.wasm +0 -0
  275. package/wasm/tree-sitter-javascript.wasm +0 -0
  276. package/wasm/tree-sitter-json.wasm +0 -0
  277. package/wasm/tree-sitter-json_schema.wasm +0 -0
  278. package/wasm/tree-sitter-julia.wasm +0 -0
  279. package/wasm/tree-sitter-kotlin.wasm +0 -0
  280. package/wasm/tree-sitter-lua.wasm +0 -0
  281. package/wasm/tree-sitter-make.wasm +0 -0
  282. package/wasm/tree-sitter-markdown.wasm +0 -0
  283. package/wasm/tree-sitter-markdown_inline.wasm +0 -0
  284. package/wasm/tree-sitter-matlab.wasm +0 -0
  285. package/wasm/tree-sitter-nim.wasm +0 -0
  286. package/wasm/tree-sitter-objc.wasm +0 -0
  287. package/wasm/tree-sitter-ocaml.wasm +0 -0
  288. package/wasm/tree-sitter-perl.wasm +0 -0
  289. package/wasm/tree-sitter-php.wasm +0 -0
  290. package/wasm/tree-sitter-php_only.wasm +0 -0
  291. package/wasm/tree-sitter-powershell.wasm +0 -0
  292. package/wasm/tree-sitter-protobuf.wasm +0 -0
  293. package/wasm/tree-sitter-python.wasm +0 -0
  294. package/wasm/tree-sitter-ql.wasm +0 -0
  295. package/wasm/tree-sitter-r.wasm +0 -0
  296. package/wasm/tree-sitter-rescript.wasm +0 -0
  297. package/wasm/tree-sitter-ruby.wasm +0 -0
  298. package/wasm/tree-sitter-rust.wasm +0 -0
  299. package/wasm/tree-sitter-scala.wasm +0 -0
  300. package/wasm/tree-sitter-scss.wasm +0 -0
  301. package/wasm/tree-sitter-solidity.wasm +0 -0
  302. package/wasm/tree-sitter-sql.wasm +0 -0
  303. package/wasm/tree-sitter-svelte.wasm +0 -0
  304. package/wasm/tree-sitter-swift.wasm +0 -0
  305. package/wasm/tree-sitter-systemrdl.wasm +0 -0
  306. package/wasm/tree-sitter-terraform.wasm +0 -0
  307. package/wasm/tree-sitter-tlaplus.wasm +0 -0
  308. package/wasm/tree-sitter-toml.wasm +0 -0
  309. package/wasm/tree-sitter-tsx.wasm +0 -0
  310. package/wasm/tree-sitter-typescript.wasm +0 -0
  311. package/wasm/tree-sitter-vba.wasm +0 -0
  312. package/wasm/tree-sitter-vbnet.wasm +0 -0
  313. package/wasm/tree-sitter-vue.wasm +0 -0
  314. package/wasm/tree-sitter-xml.wasm +0 -0
  315. package/wasm/tree-sitter-yaml.wasm +0 -0
  316. package/wasm/tree-sitter-zig.wasm +0 -0
  317. package/wasm/tree-sitter.wasm +0 -0
  318. package/wasm/tsx.wasm +0 -0
  319. package/wasm/typescript.wasm +0 -0
@@ -0,0 +1,867 @@
1
+ import {
2
+ dirOf,
3
+ fileClaimForTarget
4
+ } from "./chunk-EWMWK7WN.js";
5
+ import {
6
+ ASTEngine
7
+ } from "./chunk-3ZTOHHSW.js";
8
+ import "./chunk-BQ3OVQ3P.js";
9
+ import "./chunk-SK6YVHFZ.js";
10
+ import "./chunk-2BSKD7O3.js";
11
+ import "./chunk-KAET47ZL.js";
12
+ import "./chunk-KCDECRJY.js";
13
+ import "./chunk-MLKGABMK.js";
14
+
15
+ // src/ast/real-protobuf-analyzer.ts
16
+ import * as path from "path";
17
+ var hasJsWhitespace = (c) => c === 9 || c === 10 || c === 11 || c === 12 || c === 13 || c === 32 || c === 160 || c === 5760 || c >= 8192 && c <= 8202 || c === 8232 || c === 8233 || c === 8239 || c === 8287 || c === 12288 || c === 65279;
18
+ var stripPackagePrefix = (s) => {
19
+ let i = 0;
20
+ while (i < s.length && hasJsWhitespace(s.charCodeAt(i))) i++;
21
+ if (!s.startsWith("package", i)) return s;
22
+ i += 7;
23
+ if (i >= s.length || !hasJsWhitespace(s.charCodeAt(i))) return s;
24
+ while (i < s.length && hasJsWhitespace(s.charCodeAt(i))) i++;
25
+ return s.slice(i);
26
+ };
27
+ var stripTrailingSemicolon = (s) => {
28
+ let e = s.length;
29
+ while (e > 0 && hasJsWhitespace(s.charCodeAt(e - 1))) e--;
30
+ if (e > 0 && s.charCodeAt(e - 1) === 59) e--;
31
+ return s.slice(0, e);
32
+ };
33
+ var stripOneTrailingSlash = (s) => s.endsWith("/") ? s.slice(0, -1) : s;
34
+ var hasPathSeparator = (s) => s.includes("/") || s.includes("\\");
35
+ var hasUriSchemePrefix = (s) => {
36
+ const isLetter = (c) => c >= 65 && c <= 90 || c >= 97 && c <= 122;
37
+ if (s.length === 0 || !isLetter(s.charCodeAt(0))) return false;
38
+ for (let i = 1; i < s.length; i++) {
39
+ const c = s.charCodeAt(i);
40
+ if (c === 58) return true;
41
+ if (!isLetter(c) && !(c >= 48 && c <= 57) && c !== 43 && c !== 46 && c !== 45) return false;
42
+ }
43
+ return false;
44
+ };
45
+ var PROTOBUF_DECLARATION_SPEC = {
46
+ typeNodes: { message: "class", enum: "enum", service: "interface" },
47
+ memberNodes: [],
48
+ baseNodes: [],
49
+ nameResolver: (n) => {
50
+ const children = (n.namedChildren ?? []).filter((c) => c !== null && c !== void 0);
51
+ const own = children.find((c) => String(c.type).endsWith("_name"))?.text ?? n.childForFieldName("name")?.text ?? "";
52
+ if (own.length === 0) return "";
53
+ let root = n;
54
+ while (root.parent !== null && root.parent !== void 0) root = root.parent;
55
+ const rootChildren = (root.namedChildren ?? []).filter((c) => c !== null && c !== void 0);
56
+ const packages = [];
57
+ for (const c of rootChildren) {
58
+ if (String(c.type) !== "package") continue;
59
+ const text = stripTrailingSemicolon(stripPackagePrefix(String(c.text ?? ""))).trim();
60
+ if (text.length > 0) packages.push(text);
61
+ }
62
+ return packages.length > 0 ? `${packages.join(".")}.${own}` : own;
63
+ }
64
+ };
65
+ var PROTOBUF_EXTERNAL_NAMESPACES = [
66
+ "google.protobuf",
67
+ "google.api",
68
+ // `google.rpc` is the Google API's error-code/status surface (`google.rpc.Status`,
69
+ // `google.rpc.Code`, `google/rpc/error_details.proto`), and it was missing from a list whose
70
+ // job is exactly the runtime namespaces no admitted file declares FOR THE PROJECT THAT READS
71
+ // THEM. MEASURED whole population before adding it
72
+ // (validation/m14/fixtures/protobuf/measurements/claim-pricing.mts §A): the entry attaches to
73
+ // 30 `uses` edges — 17 read in projects that do NOT ship `google/rpc` (docker 6,
74
+ // waypoint 10, kubernetes 1) and are `unresolved` today, 13 read in `pb-googleapis`, which
75
+ // DOES ship `google/rpc/status.proto` and where the edges resolve today. The 13 are the
76
+ // `resolved -> extOK` shape §8.2 of `FOUR-CLAUSE-protobuf.md` already pre-authorized for
77
+ // `google.protobuf` (415 such moves): a per-file analyzer cannot know which project it is in,
78
+ // so a namespace claim is a statement about the LIST and the arbiter checks it against the
79
+ // list — never the symbol table. Widening an array is a visible, reviewable act, which is
80
+ // what makes the 13 acceptable in exchange for closing 17.
81
+ "google.rpc",
82
+ "gogoproto",
83
+ "protoc-gen-openapiv2"
84
+ ];
85
+ function protobufExternalNamespaceOf(target) {
86
+ if (target.length === 0) return null;
87
+ const segs = target.split(".");
88
+ for (let n = segs.length; n >= 1; n--) {
89
+ const cand = segs.slice(0, n).join(".");
90
+ if (PROTOBUF_EXTERNAL_NAMESPACES.includes(cand)) return cand;
91
+ }
92
+ return null;
93
+ }
94
+ var RealProtobufAnalyzer = class {
95
+ analyze(rootNode, content, filePath, context) {
96
+ const symbols = [];
97
+ const relationships = [];
98
+ const imports = [];
99
+ const typeCache = /* @__PURE__ */ new Map();
100
+ const idOf = (n) => n.id ?? -1;
101
+ const typeOf = (n) => {
102
+ const id = idOf(n);
103
+ const hit = typeCache.get(id);
104
+ if (hit !== void 0) return hit;
105
+ const t = n.type;
106
+ typeCache.set(id, t);
107
+ return t;
108
+ };
109
+ const kids = (n) => {
110
+ const out = [];
111
+ for (const c of n.children) if (c && c.isNamed) out.push(c);
112
+ return out;
113
+ };
114
+ const firstOfType = (n, t) => {
115
+ for (const c of kids(n)) if (typeOf(c) === t) return c;
116
+ return null;
117
+ };
118
+ const lineOf = (n) => n ? n.startPosition.row + 1 : 0;
119
+ const lineOfOf = (startIndex) => {
120
+ let row = 1;
121
+ for (let i = 0; i < startIndex && i < content.length; i++) if (content.charCodeAt(i) === 10) row++;
122
+ return row;
123
+ };
124
+ const unquote = (s) => {
125
+ if (!s || s.length < 2) return s ?? "";
126
+ const a = s[0];
127
+ const b = s[s.length - 1];
128
+ if ((a === '"' || a === "'") && a === b) return s.slice(1, -1);
129
+ return s;
130
+ };
131
+ const prevSiblingOf = (parent, child) => {
132
+ const all = parent.children;
133
+ for (let i = 0; i < all.length; i++) {
134
+ const c = all[i];
135
+ if (c && c.startIndex === child.startIndex && c.endIndex === child.endIndex) {
136
+ return i > 0 ? all[i - 1] : null;
137
+ }
138
+ }
139
+ return null;
140
+ };
141
+ const docComments = /* @__PURE__ */ new Map();
142
+ {
143
+ const lineStarts = [0];
144
+ for (let i = 0; i < content.length; i++) {
145
+ if (content.charCodeAt(i) === 10) lineStarts.push(i + 1);
146
+ }
147
+ const onOwnLine = (n) => {
148
+ const s = lineStarts[n.startPosition.row];
149
+ if (s === void 0 || s > n.startIndex) return true;
150
+ for (let i = s; i < n.startIndex; i++) {
151
+ const c = content.charCodeAt(i);
152
+ if (c !== 32 && c !== 9 && c !== 13) return false;
153
+ }
154
+ return true;
155
+ };
156
+ const stack2 = [rootNode];
157
+ while (stack2.length) {
158
+ const n = stack2.pop();
159
+ let pending = [];
160
+ for (const c of n.children) {
161
+ if (!c) continue;
162
+ if (typeOf(c) === "comment") {
163
+ if (onOwnLine(c)) pending.push(c.text.trim());
164
+ continue;
165
+ }
166
+ if (pending.length && c.isNamed) {
167
+ docComments.set(idOf(c), pending);
168
+ pending = [];
169
+ }
170
+ stack2.push(c);
171
+ }
172
+ }
173
+ }
174
+ const nodeToRange = (node) => {
175
+ let anchor = node;
176
+ for (const c of node.children) {
177
+ if (!c) continue;
178
+ if (typeOf(c) === "comment") continue;
179
+ anchor = c;
180
+ break;
181
+ }
182
+ return {
183
+ startLine: anchor.startPosition.row + 1,
184
+ startColumn: anchor.startPosition.column + 1,
185
+ endLine: node.endPosition.row + 1,
186
+ endColumn: node.endPosition.column + 1,
187
+ startIndex: anchor.startIndex,
188
+ endIndex: node.endIndex
189
+ };
190
+ };
191
+ const fileDecls = kids(rootNode);
192
+ let pkg = "";
193
+ let syntax = null;
194
+ let edition = null;
195
+ const fileOptions = [];
196
+ const importDirs = /* @__PURE__ */ new Set();
197
+ for (const d of fileDecls) {
198
+ if (typeOf(d) !== "import") continue;
199
+ const mod = unquote(String(d.childForFieldName("path")?.text ?? ""));
200
+ if (mod.length === 0) continue;
201
+ const cut = mod.lastIndexOf("/");
202
+ importDirs.add(cut > 0 ? mod.slice(0, cut) : "");
203
+ }
204
+ const projectNames = context?.projectIndex?.symbolNames instanceof Set ? context.projectIndex.symbolNames : void 0;
205
+ for (const d of fileDecls) {
206
+ const t = typeOf(d);
207
+ if (t === "package") pkg = firstOfType(d, "full_ident")?.text ?? "";
208
+ else if (t === "syntax") {
209
+ const all = d.children;
210
+ let value = null;
211
+ for (let i = 0; i < all.length; i++) {
212
+ const c = all[i];
213
+ if (c && !c.isNamed && c.text === "=") {
214
+ const nxt = all[i + 1];
215
+ if (nxt) value = unquote(nxt.text);
216
+ break;
217
+ }
218
+ }
219
+ syntax = value;
220
+ } else if (t === "edition") {
221
+ edition = unquote(d.childForFieldName("value")?.text) || unquote(firstOfType(d, "string")?.text) || null;
222
+ } else if (t === "option") {
223
+ const k = kids(d);
224
+ fileOptions.push({
225
+ name: k[0]?.text ?? "",
226
+ value: k[1]?.text ?? "",
227
+ line: lineOf(d)
228
+ });
229
+ }
230
+ }
231
+ const SymbolKind = ASTEngine.SymbolKind;
232
+ const qualify = (owner, name) => owner ? `${owner}.${name}` : name;
233
+ const declaredIds = /* @__PURE__ */ new Set();
234
+ const usedIds = /* @__PURE__ */ new Set();
235
+ const metaOf = /* @__PURE__ */ new Map();
236
+ const uniqueId = (base, kind) => {
237
+ if (!usedIds.has(base)) return base;
238
+ let n = 0;
239
+ let cand = `${base}#${kind}`;
240
+ while (usedIds.has(cand)) {
241
+ n++;
242
+ cand = `${base}#${kind}${n}`;
243
+ }
244
+ return cand;
245
+ };
246
+ const declaredTypeIds = /* @__PURE__ */ new Set();
247
+ const slotClaims = /* @__PURE__ */ new Map();
248
+ const isTypeDeclaring = (kind) => kind === ASTEngine.SymbolKind.Class || kind === ASTEngine.SymbolKind.Enum;
249
+ const addSymbol = (id, s) => {
250
+ const real = uniqueId(id, String(s.kind));
251
+ const fieldNumber = s.metadata && s.metadata.fieldNumber !== void 0 ? s.metadata.fieldNumber : null;
252
+ if (s.kind === ASTEngine.SymbolKind.Property && fieldNumber !== null) {
253
+ const slotKey = `${String(s.ownerName ?? "")}\0${fieldNumber}`;
254
+ const prev = slotClaims.get(slotKey);
255
+ if (prev) {
256
+ const later = (s.range.startIndex ?? 0) > prev.startIndex;
257
+ const srcStart = later ? s.range.startIndex ?? 0 : prev.startIndex;
258
+ if (!collectOnly) {
259
+ addRel(
260
+ later ? real : prev.id,
261
+ later ? prev.id : real,
262
+ RelationshipTypeOverrides,
263
+ lineOfOf(srcStart),
264
+ { role: "fieldSlot", fieldNumber }
265
+ );
266
+ }
267
+ }
268
+ slotClaims.set(slotKey, { id: real, startIndex: s.range.startIndex ?? 0, name: String(s.name) });
269
+ }
270
+ usedIds.add(real);
271
+ declaredIds.add(real);
272
+ if (isTypeDeclaring(s.kind)) declaredTypeIds.add(real);
273
+ if (collectOnly) return real;
274
+ s.metadata = { ...s.metadata, id: real, qualifiedName: real };
275
+ s.qualifiedName = real;
276
+ metaOf.set(real, s.metadata);
277
+ symbols.push(s);
278
+ return real;
279
+ };
280
+ const ownerMeta = (id, fn) => {
281
+ const m = metaOf.get(id);
282
+ if (m) fn(m);
283
+ };
284
+ const fileRanges = [];
285
+ let collectOnly = false;
286
+ const evidenceClassFor = (type) => {
287
+ if (type === ASTEngine.RelationshipType.Imports) return "import_based";
288
+ if (type === ASTEngine.RelationshipType.Exports) return "structural";
289
+ return "structural";
290
+ };
291
+ const addRel = (source, target, type, line, metadata = {}) => {
292
+ if (collectOnly) return;
293
+ relationships.push({
294
+ source,
295
+ target,
296
+ type,
297
+ relationshipType: type,
298
+ line_number: line,
299
+ confidence: 1,
300
+ metadata: {
301
+ evidenceClass: evidenceClassFor(type),
302
+ // THE NAMESPACE CLAIM (task-19). Attached ONLY where this edge is a TYPE REFERENCE that
303
+ // this file does not declare AND whose namespace is one of the declared runtime
304
+ // namespaces above — i.e. exactly the class that used to read `unresolved` with no claim
305
+ // at all. The `declaredTypeIds` guard is what keeps the lane from certifying a reference
306
+ // its own file already answers; it is also why this adoption moves no `resolved` edge.
307
+ ...type === ASTEngine.RelationshipType.References && !declaredTypeIds.has(target) && protobufExternalNamespaceOf(target) !== null ? { languageNamespace: [...PROTOBUF_EXTERNAL_NAMESPACES] } : {},
308
+ ...metadata
309
+ }
310
+ });
311
+ };
312
+ const resolveRef = (text, scope) => {
313
+ if (text.startsWith(".")) return text.slice(1);
314
+ const chain = [];
315
+ if (scope) {
316
+ const segs = scope.split(".");
317
+ for (let i = segs.length; i > 0; i--) {
318
+ const cand = segs.slice(0, i).join(".");
319
+ if (!pkg || cand === pkg || cand.startsWith(pkg + ".")) chain.push(cand);
320
+ }
321
+ }
322
+ if (pkg) chain.push(pkg);
323
+ chain.push(null);
324
+ for (const base of chain) {
325
+ const cand = base ? `${base}.${text}` : text;
326
+ if (declaredTypeIds.has(cand)) return cand;
327
+ }
328
+ if (text.includes(".")) {
329
+ const hit = resolveViaImports(text, scope);
330
+ if (hit !== null) return hit;
331
+ return text;
332
+ }
333
+ const bare = resolveBareViaImports(text, scope);
334
+ if (bare !== null) return bare;
335
+ return qualify(pkg || null, text);
336
+ };
337
+ const resolveBareViaImports = (text, scope) => {
338
+ if (importDirs.size === 0) return null;
339
+ const chain = specScopeChain(scope);
340
+ for (const base of chain) {
341
+ if (base.length === 0) continue;
342
+ const dir = base.split(".").join("/");
343
+ if (!importDirs.has(dir)) continue;
344
+ for (const other of chain) {
345
+ if (other.length === 0) continue;
346
+ const otherDir = other.split(".").join("/");
347
+ if (otherDir !== dir && otherDir.endsWith(dir)) return null;
348
+ }
349
+ return `${base}.${text}`;
350
+ }
351
+ return null;
352
+ };
353
+ const specScopeChain = (scope) => {
354
+ const chain = [];
355
+ const push = (v) => {
356
+ if (!chain.includes(v)) chain.push(v);
357
+ };
358
+ if (scope) {
359
+ const segs = scope.split(".");
360
+ for (let i = segs.length; i > 0; i--) push(segs.slice(0, i).join("."));
361
+ }
362
+ if (pkg) {
363
+ const segs = pkg.split(".");
364
+ for (let i = segs.length; i > 0; i--) push(segs.slice(0, i).join("."));
365
+ }
366
+ push("");
367
+ return chain;
368
+ };
369
+ const resolveViaImports = (text, scope) => {
370
+ if (importDirs.size === 0) return null;
371
+ const lastDot = text.lastIndexOf(".");
372
+ if (lastDot <= 0) return null;
373
+ const rootedAt = text.slice(0, lastDot);
374
+ const typeName = text.slice(lastDot + 1);
375
+ const chain = specScopeChain(scope);
376
+ for (const base of chain) {
377
+ const packageOf = base.length > 0 ? `${base}.${rootedAt}` : rootedAt;
378
+ const dir = packageOf.split(".").join("/");
379
+ if (!importDirs.has(dir)) {
380
+ const candidate = `${packageOf}.${typeName}`;
381
+ if (projectNames !== void 0 && projectNames.has(candidate)) return candidate;
382
+ continue;
383
+ }
384
+ for (const other of chain) {
385
+ const otherPackage = other.length > 0 ? `${other}.${rootedAt}` : rootedAt;
386
+ const otherDir = otherPackage.split(".").join("/");
387
+ if (otherDir !== dir && otherDir.endsWith(dir)) return null;
388
+ }
389
+ return `${packageOf}.${typeName}`;
390
+ }
391
+ return null;
392
+ };
393
+ const refTypeOf = (typeNode) => {
394
+ if (!typeNode) return null;
395
+ const inner = firstOfType(typeNode, "message_or_enum_type");
396
+ return inner ? inner.text : null;
397
+ };
398
+ const idOwner = (ctx) => ctx.viaExtension ? ctx.scope : ctx.owner;
399
+ const addFieldLike = (node, nameNode, ctx, extra) => {
400
+ const name = nameNode.text;
401
+ if (!name) return null;
402
+ const meta = { ...extra };
403
+ if (ctx.oneof) meta.oneof = ctx.oneof;
404
+ if (ctx.viaExtension) meta.viaExtension = true;
405
+ const id = addSymbol(qualify(idOwner(ctx), name), {
406
+ name,
407
+ kind: SymbolKind.Property,
408
+ range: nodeToRange(node),
409
+ ownerName: ctx.owner ?? void 0,
410
+ ownerKind: ctx.ownerKind ?? void 0,
411
+ metadata: meta
412
+ });
413
+ if (ctx.owner) {
414
+ addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), {
415
+ member: "field",
416
+ // `viaExtension` on the EDGE as well as on the symbol. It was on the
417
+ // symbol only, so a consumer reading `google.protobuf.MessageOptions
418
+ // -contains-> audit_ticket` could not tell an extension field added in
419
+ // another file from a field declared in the message's own body — and the
420
+ // header's claim that the edge carries it was false. Measured over the
421
+ // corpus before this change: 0 of the extension-derived `contains` edges
422
+ // carried `viaExtension`, because `addFieldLike` set it on the symbol's
423
+ // metadata object and the `addRel` call passed only `member`.
424
+ ...ctx.viaExtension ? { viaExtension: true } : {}
425
+ });
426
+ }
427
+ return id;
428
+ };
429
+ const RelationshipTypeContains = ASTEngine.RelationshipType.Contains;
430
+ const RelationshipTypeReferences = ASTEngine.RelationshipType.References;
431
+ const RelationshipTypeImports = ASTEngine.RelationshipType.Imports;
432
+ const RelationshipTypeExports = ASTEngine.RelationshipType.Exports;
433
+ const RelationshipTypeOverrides = ASTEngine.RelationshipType.Overrides;
434
+ const emitField = (node, ctx) => {
435
+ const typeNode = firstOfType(node, "type");
436
+ const body = firstOfType(node, "message_body");
437
+ const numNode = firstOfType(node, "field_number");
438
+ const label = (node.children ?? []).filter((c) => c && !c.isNamed).map((c) => c.text).find((t) => t === "optional" || t === "required" || t === "repeated");
439
+ if (!typeNode && body) {
440
+ const gname = node.childForFieldName("name")?.text ?? firstOfType(node, "identifier")?.text;
441
+ if (gname) {
442
+ const typeOwner = idOwner(ctx);
443
+ const typeId = addSymbol(qualify(typeOwner, gname), {
444
+ name: gname,
445
+ kind: SymbolKind.Class,
446
+ range: nodeToRange(node),
447
+ ownerName: typeOwner ?? void 0,
448
+ // Inside an `extend`, `ctx.ownerKind` is the EXTENDEE's kind, which is
449
+ // not the kind of the scope the type is being declared in, so it is
450
+ // omitted rather than asserted. Outside an `extend` the two agree and it
451
+ // is carried through unchanged.
452
+ ...ctx.viaExtension ? {} : { ownerKind: ctx.ownerKind ?? void 0 },
453
+ // `isGroupType` and nothing else: a type declared at the block's own
454
+ // scope is not an extension member, so it does not carry `viaExtension`.
455
+ // The group's FIELD below still does.
456
+ metadata: { isGroupType: true }
457
+ });
458
+ if (typeOwner) addRel(typeOwner, typeId, RelationshipTypeContains, lineOf(node), { member: "groupType" });
459
+ const fieldId2 = addSymbol(qualify(idOwner(ctx), gname), {
460
+ name: gname,
461
+ kind: SymbolKind.Property,
462
+ range: nodeToRange(node),
463
+ ownerName: ctx.owner ?? void 0,
464
+ ownerKind: ctx.ownerKind ?? void 0,
465
+ metadata: {
466
+ type: gname,
467
+ isGroup: true,
468
+ fieldNumber: numNode?.text ?? null,
469
+ ...label ? { label } : {},
470
+ ...ctx.viaExtension ? { viaExtension: true } : {}
471
+ }
472
+ });
473
+ if (ctx.owner) addRel(ctx.owner, fieldId2, RelationshipTypeContains, lineOf(node), { member: "field", ...ctx.viaExtension ? { viaExtension: true } : {} });
474
+ addRel(fieldId2, typeId, RelationshipTypeReferences, lineOf(node), { role: "groupType" });
475
+ const inner = {
476
+ ...ctx,
477
+ owner: typeId,
478
+ scope: typeId,
479
+ ownerKind: SymbolKind.Class,
480
+ oneof: null,
481
+ viaExtension: false
482
+ };
483
+ pushAll(kids(body), inner);
484
+ return;
485
+ }
486
+ }
487
+ const nameNode = firstOfType(node, "identifier");
488
+ if (!nameNode) return;
489
+ const ref = refTypeOf(typeNode);
490
+ const fieldId = addFieldLike(node, nameNode, ctx, {
491
+ type: ref ?? typeNode?.text ?? null,
492
+ ...ref ? {} : { scalar: true },
493
+ fieldNumber: numNode?.text ?? null,
494
+ ...label ? { label } : {}
495
+ });
496
+ if (fieldId && ref) {
497
+ addRel(fieldId, resolveRef(ref, ctx.scope), RelationshipTypeReferences, lineOf(node), { role: "fieldType" });
498
+ }
499
+ };
500
+ const emitMapField = (node, ctx) => {
501
+ const nameNode = firstOfType(node, "identifier");
502
+ if (!nameNode) return;
503
+ const keyNode = firstOfType(node, "key_type");
504
+ const valType = firstOfType(node, "type");
505
+ const valRef = refTypeOf(valType);
506
+ const numNode = firstOfType(node, "field_number");
507
+ const fieldId = addFieldLike(node, nameNode, ctx, {
508
+ isMap: true,
509
+ mapKey: keyNode?.text ?? null,
510
+ mapValue: valRef ?? valType?.text ?? null,
511
+ ...valRef ? {} : { valueIsScalar: true },
512
+ fieldNumber: numNode?.text ?? null
513
+ });
514
+ if (fieldId && valRef) {
515
+ addRel(fieldId, resolveRef(valRef, ctx.scope), RelationshipTypeReferences, lineOf(node), {
516
+ role: "mapValueType"
517
+ });
518
+ }
519
+ };
520
+ const emitOneofField = (node, ctx) => {
521
+ const nameNode = firstOfType(node, "identifier");
522
+ if (!nameNode) return;
523
+ const typeNode = firstOfType(node, "type");
524
+ const ref = refTypeOf(typeNode);
525
+ const fieldId = addFieldLike(node, nameNode, ctx, {
526
+ type: ref ?? typeNode?.text ?? null,
527
+ ...ref ? {} : { scalar: true },
528
+ fieldNumber: firstOfType(node, "field_number")?.text ?? null
529
+ });
530
+ if (fieldId && ref) {
531
+ addRel(fieldId, resolveRef(ref, ctx.scope), RelationshipTypeReferences, lineOf(node), { role: "oneofFieldType" });
532
+ }
533
+ };
534
+ const emitEnumField = (node, ctx) => {
535
+ const nameNode = firstOfType(node, "identifier");
536
+ if (!nameNode) return;
537
+ const name = nameNode.text;
538
+ const id = addSymbol(qualify(idOwner(ctx), name), {
539
+ name,
540
+ kind: SymbolKind.EnumMember,
541
+ range: nodeToRange(node),
542
+ ownerName: ctx.owner ?? void 0,
543
+ ownerKind: SymbolKind.Enum,
544
+ metadata: {
545
+ value: firstOfType(node, "int_lit")?.text ?? null,
546
+ ...ctx.viaExtension ? { viaExtension: true } : {}
547
+ }
548
+ });
549
+ if (ctx.owner) addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), { member: "enumValue", ...ctx.viaExtension ? { viaExtension: true } : {} });
550
+ };
551
+ const emitRpc = (node, ctx) => {
552
+ const nameNode = firstOfType(node, "rpc_name");
553
+ if (!nameNode) return;
554
+ const name = nameNode.text;
555
+ const types = kids(node).filter((c) => typeOf(c) === "message_or_enum_type");
556
+ const request = types[0]?.text ?? null;
557
+ const response = types[1]?.text ?? null;
558
+ const isStreaming = (t) => {
559
+ if (!t) return false;
560
+ const p = prevSiblingOf(node, t);
561
+ return !!p && !p.isNamed && p.text === "stream";
562
+ };
563
+ const clientStreaming = isStreaming(types[0]);
564
+ const serverStreaming = isStreaming(types[1]);
565
+ const id = addSymbol(qualify(ctx.owner, name), {
566
+ name,
567
+ kind: SymbolKind.Method,
568
+ range: nodeToRange(node),
569
+ ownerName: ctx.owner ?? void 0,
570
+ ownerKind: SymbolKind.Interface,
571
+ ...request ? { parameters: [{ name: "request", type: request }] } : {},
572
+ ...response ? { returnType: response } : {},
573
+ metadata: {
574
+ ...request ? { requestType: request } : {},
575
+ ...response ? { responseType: response } : {},
576
+ clientStreaming,
577
+ serverStreaming
578
+ }
579
+ });
580
+ if (ctx.owner) addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), { member: "rpc", ...ctx.viaExtension ? { viaExtension: true } : {} });
581
+ if (request) addRel(id, resolveRef(request, ctx.scope), RelationshipTypeReferences, lineOf(node), { role: "rpcRequest" });
582
+ if (response) addRel(id, resolveRef(response, ctx.scope), RelationshipTypeReferences, lineOf(node), { role: "rpcResponse" });
583
+ };
584
+ const stack = [];
585
+ const pushAll = (children, ctx) => {
586
+ for (const c of children) stack.push({ node: c, ctx });
587
+ };
588
+ const visit = (node, ctx) => {
589
+ switch (typeOf(node)) {
590
+ case "message": {
591
+ const nameNode = firstOfType(node, "message_name");
592
+ if (!nameNode) return;
593
+ const name = nameNode.text;
594
+ const id = addSymbol(qualify(ctx.owner, name), {
595
+ name,
596
+ kind: SymbolKind.Class,
597
+ range: nodeToRange(node),
598
+ ...docComments.has(idOf(node)) ? { comments: docComments.get(idOf(node)) } : {},
599
+ ownerName: ctx.owner ?? void 0,
600
+ ownerKind: ctx.ownerKind ?? void 0,
601
+ metadata: { isMessage: true, ...ctx.viaExtension ? { viaExtension: true } : {} }
602
+ });
603
+ if (ctx.owner) addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), { member: "nestedType", ...ctx.viaExtension ? { viaExtension: true } : {} });
604
+ const body = firstOfType(node, "message_body");
605
+ if (body) {
606
+ const inner = { ...ctx, owner: id, scope: id, ownerKind: SymbolKind.Class, oneof: null };
607
+ pushAll(kids(body), inner);
608
+ }
609
+ return;
610
+ }
611
+ case "enum": {
612
+ const nameNode = firstOfType(node, "enum_name");
613
+ if (!nameNode) return;
614
+ const name = nameNode.text;
615
+ const id = addSymbol(qualify(ctx.owner, name), {
616
+ name,
617
+ kind: SymbolKind.Enum,
618
+ range: nodeToRange(node),
619
+ ...docComments.has(idOf(node)) ? { comments: docComments.get(idOf(node)) } : {},
620
+ ownerName: ctx.owner ?? void 0,
621
+ ownerKind: ctx.ownerKind ?? void 0,
622
+ metadata: { isEnum: true, ...ctx.viaExtension ? { viaExtension: true } : {} }
623
+ });
624
+ if (ctx.owner) addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), { member: "nestedType", ...ctx.viaExtension ? { viaExtension: true } : {} });
625
+ const body = firstOfType(node, "enum_body");
626
+ if (body) {
627
+ const inner = { ...ctx, owner: id, scope: id, ownerKind: SymbolKind.Enum, oneof: null };
628
+ pushAll(kids(body), inner);
629
+ }
630
+ return;
631
+ }
632
+ case "service": {
633
+ const nameNode = firstOfType(node, "service_name");
634
+ if (!nameNode) return;
635
+ const name = nameNode.text;
636
+ const id = addSymbol(qualify(ctx.owner, name), {
637
+ name,
638
+ kind: SymbolKind.Interface,
639
+ range: nodeToRange(node),
640
+ ...docComments.has(idOf(node)) ? { comments: docComments.get(idOf(node)) } : {},
641
+ ownerName: ctx.owner ?? void 0,
642
+ ownerKind: ctx.ownerKind ?? void 0,
643
+ metadata: { isService: true, ...ctx.viaExtension ? { viaExtension: true } : {} }
644
+ });
645
+ if (ctx.owner) addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), { member: "nestedType", ...ctx.viaExtension ? { viaExtension: true } : {} });
646
+ const inner = { ...ctx, owner: id, scope: id, ownerKind: SymbolKind.Interface, oneof: null };
647
+ pushAll(
648
+ kids(node).filter((c) => typeOf(c) !== "service_name"),
649
+ inner
650
+ );
651
+ return;
652
+ }
653
+ case "extend": {
654
+ const target = firstOfType(node, "full_ident")?.text ?? firstOfType(node, "message_or_enum_type")?.text;
655
+ const body = firstOfType(node, "message_body");
656
+ if (!target || !body) return;
657
+ const resolved = resolveRef(target, ctx.scope);
658
+ const inner = {
659
+ ...ctx,
660
+ owner: resolved,
661
+ // `scope` is DELIBERATELY NOT `resolved`. The block's members belong
662
+ // to the extended type, but a type written inside the block is
663
+ // looked up from where the block is WRITTEN, because `extend` does
664
+ // not open a scope. Inheriting `ctx.scope` unchanged is what makes a
665
+ // nested `extend` resolve against the enclosing messages; setting it
666
+ // to `resolved` would resolve against a type the language never made
667
+ // a scope of, and the walk would find nothing.
668
+ scope: ctx.scope,
669
+ ownerKind: SymbolKind.Class,
670
+ oneof: null,
671
+ viaExtension: true
672
+ };
673
+ pushAll(kids(body), inner);
674
+ return;
675
+ }
676
+ case "oneof": {
677
+ const kn = kids(node);
678
+ const nameNode = kn.find((c) => typeOf(c) === "identifier");
679
+ if (!nameNode) return;
680
+ const name = nameNode.text;
681
+ const id = addSymbol(qualify(ctx.owner, name), {
682
+ name,
683
+ kind: SymbolKind.Union,
684
+ range: nodeToRange(node),
685
+ ...docComments.has(idOf(node)) ? { comments: docComments.get(idOf(node)) } : {},
686
+ ownerName: ctx.owner ?? void 0,
687
+ ownerKind: ctx.ownerKind ?? void 0,
688
+ metadata: { isOneof: true }
689
+ });
690
+ if (ctx.owner) addRel(ctx.owner, id, RelationshipTypeContains, lineOf(node), { member: "oneof", ...ctx.viaExtension ? { viaExtension: true } : {} });
691
+ const inner = { ...ctx, oneof: id };
692
+ pushAll(kids(node), inner);
693
+ return;
694
+ }
695
+ case "reserved":
696
+ case "extensions": {
697
+ const what = typeOf(node) === "reserved" ? "reserved" : "extensions";
698
+ const ranges = kids(node).filter((c) => typeOf(c) === "ranges").flatMap((r) => kids(r).filter((c) => typeOf(c) === "range").map((c) => c.text));
699
+ const names = kids(node).filter((c) => typeOf(c) === "field_names").flatMap((f) => kids(f).map((c) => unquote(c.text)));
700
+ if (ctx.owner) ownerMeta(ctx.owner, (m) => {
701
+ const list = m[what] ?? [];
702
+ list.push(...ranges.length ? ranges.map((t) => ({ range: t })) : names.map((t) => ({ name: t })));
703
+ m[what] = list;
704
+ });
705
+ else
706
+ fileRanges.push(
707
+ ...ranges.length ? ranges.map((t) => ({ kind: what, range: t })) : names.map((t) => ({ kind: what, name: t }))
708
+ );
709
+ return;
710
+ }
711
+ case "field":
712
+ emitField(node, ctx);
713
+ return;
714
+ case "map_field":
715
+ emitMapField(node, ctx);
716
+ return;
717
+ case "oneof_field":
718
+ emitOneofField(node, ctx);
719
+ return;
720
+ case "enum_field":
721
+ emitEnumField(node, ctx);
722
+ return;
723
+ case "rpc":
724
+ emitRpc(node, ctx);
725
+ return;
726
+ default:
727
+ return;
728
+ }
729
+ };
730
+ const root = { pkg, owner: pkg || null, scope: pkg || null, ownerKind: null, oneof: null, viaExtension: false };
731
+ const drain = () => {
732
+ while (stack.length) {
733
+ const item = stack.pop();
734
+ const d = item.node;
735
+ const t = typeOf(d);
736
+ if (t === "import") {
737
+ const raw = d.childForFieldName("path")?.text ?? firstOfType(d, "string")?.text ?? "";
738
+ const path2 = unquote(raw);
739
+ let modifier = null;
740
+ for (const c of d.children) {
741
+ if (!c || c.isNamed) continue;
742
+ if (c.text === "public" || c.text === "weak" || c.text === "option") {
743
+ modifier = c.text;
744
+ break;
745
+ }
746
+ }
747
+ if (!collectOnly) {
748
+ imports.push({
749
+ module: path2,
750
+ path: path2,
751
+ items: [],
752
+ isDefaultImport: false,
753
+ isNamespaceImport: false,
754
+ range: nodeToRange(d),
755
+ metadata: { ...modifier ? { modifier } : {} }
756
+ });
757
+ if (path2) {
758
+ const selfMod = pkg.length > 0 ? pkg : filePath.split("/").pop() || filePath;
759
+ const moduleMeta = { modulePath: path2, filePath, ...pkg.length > 0 ? { moduleOwner: "package" } : { moduleOwner: "basename" } };
760
+ if (modifier === "public") {
761
+ addRel(selfMod, path2, RelationshipTypeExports, lineOf(d), {
762
+ ...moduleMeta,
763
+ viaPublicImport: true
764
+ });
765
+ addRel(selfMod, path2, RelationshipTypeImports, lineOf(d), {
766
+ ...moduleMeta,
767
+ ...modifier ? { modifier } : {},
768
+ viaPublicImport: true
769
+ });
770
+ } else {
771
+ addRel(selfMod, path2, RelationshipTypeImports, lineOf(d), {
772
+ ...moduleMeta,
773
+ ...modifier ? { modifier } : {},
774
+ // The editions FEATURE import resolves an option's definition
775
+ // rather than a message, which is why it is not a re-export even
776
+ // though it names a file this one depends on.
777
+ ...modifier === "option" ? { isFeatureImport: true } : {}
778
+ });
779
+ }
780
+ }
781
+ }
782
+ continue;
783
+ }
784
+ if (t === "package") {
785
+ addSymbol(pkg, {
786
+ name: pkg,
787
+ kind: SymbolKind.Namespace,
788
+ range: nodeToRange(d),
789
+ metadata: { isProtoPackage: true }
790
+ });
791
+ continue;
792
+ }
793
+ visit(d, item.ctx);
794
+ }
795
+ };
796
+ collectOnly = true;
797
+ pushAll(fileDecls, root);
798
+ drain();
799
+ collectOnly = false;
800
+ usedIds.clear();
801
+ metaOf.clear();
802
+ slotClaims.clear();
803
+ fileRanges.length = 0;
804
+ stack.length = 0;
805
+ pushAll(fileDecls, root);
806
+ drain();
807
+ const claimRoot = typeof context?.projectRoot === "string" && context.projectRoot.length > 0 ? context.projectRoot : null;
808
+ if (claimRoot !== null) {
809
+ for (const r of relationships) {
810
+ if (r.type !== ASTEngine.RelationshipType.Imports && r.type !== ASTEngine.RelationshipType.Exports) continue;
811
+ const md = r.metadata;
812
+ if (!md || typeof md.importProjectFile === "string") continue;
813
+ const written = String(r.target ?? "");
814
+ const extraCandidates = [];
815
+ const target = written.trim();
816
+ if (target.length > 0 && !target.includes("://") && !target.startsWith("/")) {
817
+ const fileRel = path.relative(path.resolve(claimRoot), filePath).split(path.sep).join("/");
818
+ let rel = stripOneTrailingSlash(dirOf(fileRel));
819
+ while (rel.length > 0) {
820
+ extraCandidates.push(`${rel}/${target}`);
821
+ rel = stripOneTrailingSlash(dirOf(rel));
822
+ }
823
+ }
824
+ const claim = fileClaimForTarget({
825
+ projectRoot: claimRoot,
826
+ filePath,
827
+ written,
828
+ admittedExtensions: ["proto"],
829
+ extraCandidates
830
+ });
831
+ if (claim === null) {
832
+ const src = String(r.target ?? "");
833
+ if (hasPathSeparator(src) || hasUriSchemePrefix(src)) md.sourcePathClaim = [src];
834
+ continue;
835
+ }
836
+ md.importProjectFile = claim;
837
+ }
838
+ }
839
+ return {
840
+ symbols,
841
+ relationships,
842
+ imports,
843
+ metadata: {
844
+ ...syntax ? { syntax } : {},
845
+ ...edition ? { edition } : {},
846
+ ...pkg ? { protoPackage: pkg } : {},
847
+ ...fileOptions.length ? { fileOptions } : {},
848
+ ...fileRanges.length ? { fileRanges } : {},
849
+ // A COUNTED work measure, not a duration. `typeCache.size` is the number
850
+ // of distinct nodes the walk actually read, which is what a linearity
851
+ // claim needs: it is deterministic and load-independent, where a wall
852
+ // clock on a shared machine moved this lane's own ratio between 0.94 and
853
+ // 2.05 across runs of identical code, and exceeded its bound only when
854
+ // other lanes were running. A gate whose verdict depends on what else the
855
+ // machine is doing is not a gate.
856
+ visitedNodes: typeCache.size,
857
+ filePath,
858
+ symbolCount: symbols.length,
859
+ relationshipCount: relationships.length
860
+ }
861
+ };
862
+ }
863
+ };
864
+ export {
865
+ PROTOBUF_DECLARATION_SPEC,
866
+ RealProtobufAnalyzer
867
+ };