33import static io .quarkus .qute .debug .agent .RemoteStackFrame .EMPTY_STACK_FRAMES ;
44import static io .quarkus .qute .debug .agent .scopes .RemoteScope .EMPTY_SCOPES ;
55
6+ import java .net .URI ;
67import java .util .ArrayList ;
78import java .util .Collection ;
8- import java .util .HashMap ;
99import java .util .HashSet ;
1010import java .util .Map ;
1111import java .util .Set ;
2121import org .eclipse .lsp4j .debug .Scope ;
2222import org .eclipse .lsp4j .debug .Source ;
2323import org .eclipse .lsp4j .debug .SourceBreakpoint ;
24+ import org .eclipse .lsp4j .debug .SourceResponse ;
2425import org .eclipse .lsp4j .debug .StackTraceResponse ;
2526import org .eclipse .lsp4j .debug .Thread ;
2627import org .eclipse .lsp4j .debug .Variable ;
3233import io .quarkus .qute .debug .StoppedEvent ;
3334import io .quarkus .qute .debug .ThreadEvent ;
3435import io .quarkus .qute .debug .ThreadEvent .ThreadStatus ;
36+ import io .quarkus .qute .debug .agent .breakpoints .BreakpointsRegistry ;
37+ import io .quarkus .qute .debug .agent .breakpoints .RemoteBreakpoint ;
3538import io .quarkus .qute .debug .agent .completions .CompletionSupport ;
3639import io .quarkus .qute .debug .agent .evaluations .EvaluationSupport ;
40+ import io .quarkus .qute .debug .agent .source .SourceReferenceRegistry ;
41+ import io .quarkus .qute .debug .agent .source .SourceTemplateRegistry ;
3742import io .quarkus .qute .debug .agent .variables .VariablesRegistry ;
3843import io .quarkus .qute .trace .ResolveEvent ;
3944import io .quarkus .qute .trace .TemplateEvent ;
@@ -59,8 +64,8 @@ public class DebuggeeAgent implements Debugger {
5964 */
6065 private final DebuggerTraceListener debugListener ;
6166
62- /** Breakpoints mapped by template ID and line number. */
63- private final Map < String , Map < Integer , RemoteBreakpoint >> breakpoints ;
67+ /** Breakpoints registry */
68+ private final BreakpointsRegistry breakpointsRegistry ;
6469
6570 /** Currently active debuggee threads mapped by thread ID. */
6671 private final Map <Integer , RemoteThread > debuggees ;
@@ -78,7 +83,10 @@ public class DebuggeeAgent implements Debugger {
7883 private final VariablesRegistry variablesRegistry ;
7984
8085 /** Registry mapping Qute templates to DAP {@link Source} objects. */
81- private final SourceTemplateRegistry sourceTemplateRegistry ;
86+ private final Map <Engine , SourceTemplateRegistry > sourceTemplateRegistry ;
87+
88+ /** Source reference registry (used to retrieve template content from JAR) */
89+ private final SourceReferenceRegistry sourceReferenceRegistry ;
8290
8391 /** The set of Qute engines being tracked for debugging. */
8492 private final Set <Engine > trackedEngine ;
@@ -99,11 +107,12 @@ public class DebuggeeAgent implements Debugger {
99107 */
100108 public DebuggeeAgent () {
101109 this .debugListener = new DebuggerTraceListener (this );
102- this .breakpoints = new ConcurrentHashMap <>();
103110 this .debuggees = new ConcurrentHashMap <>();
104111 this .listeners = new ArrayList <>();
105112 this .variablesRegistry = new VariablesRegistry ();
106- this .sourceTemplateRegistry = new SourceTemplateRegistry ();
113+ this .breakpointsRegistry = new BreakpointsRegistry ();
114+ this .sourceTemplateRegistry = new ConcurrentHashMap <>();
115+ this .sourceReferenceRegistry = new SourceReferenceRegistry ();
107116 this .trackedEngine = new HashSet <>();
108117 this .enginesWithDebugListener = new HashSet <>();
109118 this .evaluationSupport = new EvaluationSupport (this );
@@ -221,30 +230,7 @@ private RemoteThread getRemoteThread(int threadId) {
221230
222231 @ Override
223232 public Breakpoint [] setBreakpoints (SourceBreakpoint [] sourceBreakpoints , Source source ) {
224- sourceTemplateRegistry .registerSource (source );
225- String templateId = sourceTemplateRegistry .getTemplateId (source );
226- Map <Integer , RemoteBreakpoint > templateBreakpoints = templateId != null
227- ? this .breakpoints .computeIfAbsent (templateId , k -> new HashMap <>())
228- : null ;
229- if (templateBreakpoints != null ) {
230- templateBreakpoints .clear ();
231- }
232-
233- Breakpoint [] result = new Breakpoint [sourceBreakpoints .length ];
234- for (int i = 0 ; i < sourceBreakpoints .length ; i ++) {
235- SourceBreakpoint sourceBreakpoint = sourceBreakpoints [i ];
236- int line = sourceBreakpoint .getLine ();
237- String condition = sourceBreakpoint .getCondition ();
238- RemoteBreakpoint breakpoint = new RemoteBreakpoint (source , line , condition );
239- if (templateBreakpoints != null ) {
240- templateBreakpoints .put (line , breakpoint );
241- breakpoint .setVerified (true );
242- } else {
243- breakpoint .setVerified (false );
244- }
245- result [i ] = breakpoint ;
246- }
247- return result ;
233+ return breakpointsRegistry .setBreakpoints (sourceBreakpoints , source );
248234 }
249235
250236 @ Override
@@ -260,21 +246,15 @@ public Thread[] getThreads() {
260246 /**
261247 * Retrieves a breakpoint for the given template and line number.
262248 *
249+ * @param sourceUri
250+ *
263251 * @param templateId the template identifier.
264252 * @param line the line number.
253+ * @param engine
265254 * @return the matching breakpoint, or {@code null} if none exists.
266255 */
267- RemoteBreakpoint getBreakpoint (String templateId , int line ) {
268- Map <Integer , RemoteBreakpoint > templateBreakpoints = this .breakpoints .get (templateId );
269- if (templateBreakpoints == null ) {
270- for (var fileExtension : sourceTemplateRegistry .getFileExtensions ()) {
271- templateBreakpoints = this .breakpoints .get (templateId + fileExtension );
272- if (templateBreakpoints != null ) {
273- break ;
274- }
275- }
276- }
277- return templateBreakpoints != null ? templateBreakpoints .get (line ) : null ;
256+ RemoteBreakpoint getBreakpoint (URI sourceUri , String templateId , int line , Engine engine ) {
257+ return breakpointsRegistry .resolveBreakpoint (sourceUri , templateId , line , getSourceTemplateRegistry (engine ));
278258 }
279259
280260 @ Override
@@ -368,7 +348,9 @@ public void unlockAllDebuggeeThreads() {
368348 public void terminate () {
369349 try {
370350 unlockAllDebuggeeThreads ();
371- this .breakpoints .clear ();
351+ this .sourceTemplateRegistry .clear ();
352+ this .sourceReferenceRegistry .reset ();
353+ this .breakpointsRegistry .reset ();
372354 } finally {
373355 fireTerminateEvent ();
374356 }
@@ -411,6 +393,11 @@ public CompletableFuture<CompletionsResponse> completions(CompletionsArguments a
411393 return completionSupport .completions (args );
412394 }
413395
396+ @ Override
397+ public SourceResponse getSourceReference (int sourceReference ) {
398+ return sourceReferenceRegistry .getSourceReference (sourceReference );
399+ }
400+
414401 @ Override
415402 public StackTraceResponse getStackFrames (int threadId , Integer startFrame , Integer levels ) {
416403 StackTraceResponse response = new StackTraceResponse ();
@@ -474,8 +461,9 @@ public VariablesRegistry getVariablesRegistry() {
474461 return variablesRegistry ;
475462 }
476463
477- public SourceTemplateRegistry getSourceTemplateRegistry () {
478- return sourceTemplateRegistry ;
464+ public SourceTemplateRegistry getSourceTemplateRegistry (Engine engine ) {
465+ return this .sourceTemplateRegistry .computeIfAbsent (engine ,
466+ k -> new SourceTemplateRegistry (breakpointsRegistry , sourceReferenceRegistry , engine ));
479467 }
480468
481469 @ Override
@@ -516,5 +504,7 @@ public boolean isEnabled() {
516504 */
517505 public void reset () {
518506 unlockAllDebuggeeThreads ();
507+ this .sourceTemplateRegistry .clear ();
508+ this .sourceReferenceRegistry .reset ();
519509 }
520510}
0 commit comments