private void doSetBreakpointsForIsolate()

in flutter-idea/src/io/flutter/vmService/VmServiceWrapper.java [353:463]


  private void doSetBreakpointsForIsolate(@NotNull final Set<XLineBreakpoint<XBreakpointProperties>> xBreakpoints,
                                          @NotNull final String isolateId,
                                          @Nullable final Runnable onFinished) {
    if (xBreakpoints.isEmpty()) {
      if (onFinished != null) {
        onFinished.run();
      }
      return;
    }

    final AtomicInteger counter = new AtomicInteger(xBreakpoints.size());

    for (final XLineBreakpoint<XBreakpointProperties> xBreakpoint : xBreakpoints) {
      addBreakpoint(isolateId, xBreakpoint.getSourcePosition(), new VmServiceConsumers.BreakpointsConsumer() {
        @Override
        void sourcePositionNotApplicable() {
          myBreakpointHandler.breakpointFailed(xBreakpoint);

          checkDone();
        }

        @Override
        void received(List<Breakpoint> breakpointResponses, List<RPCError> errorResponses) {
          if (breakpointResponses.size() > 0) {
            for (Breakpoint breakpoint : breakpointResponses) {
              myBreakpointHandler.vmBreakpointAdded(xBreakpoint, isolateId, breakpoint);
            }
          }
          else if (errorResponses.size() > 0) {
            myBreakpointHandler.breakpointFailed(xBreakpoint);
          }

          checkDone();
        }

        private void checkDone() {
          if (counter.decrementAndGet() == 0 && onFinished != null) {
            onFinished.run();

            myVmService.getIsolate(isolateId, new GetIsolateConsumer() {
              @Override
              public void received(Isolate response) {
                final Set<String> libraryUris = new HashSet<>();
                final Set<String> fileNames = new HashSet<>();
                for (LibraryRef library : response.getLibraries()) {
                  final String uri = library.getUri();
                  libraryUris.add(uri);
                  final String[] split = uri.split("/");
                  fileNames.add(split[split.length - 1]);
                }

                final ElementList<Breakpoint> breakpoints = response.getBreakpoints();
                if (breakpoints.isEmpty()) {
                  return;
                }

                final Set<CanonicalBreakpoint> mappedCanonicalBreakpoints = new HashSet<>();
                for (Breakpoint breakpoint : breakpoints) {
                  Object location = breakpoint.getLocation();
                  // In JIT mode, locations will be unresolved at this time since files aren't compiled until they are used.
                  if (location instanceof UnresolvedSourceLocation) {
                    final ScriptRef script = ((UnresolvedSourceLocation)location).getScript();
                    if (script != null && libraryUris.contains(script.getUri())) {
                      mappedCanonicalBreakpoints.add(breakpointNumbersToCanonicalMap.get(breakpoint.getBreakpointNumber()));
                    }
                  }
                }

                final Analytics analytics = FlutterInitializer.getAnalytics();
                final String category = "breakpoint";

                final Sets.SetView<CanonicalBreakpoint> initialDifference =
                  Sets.difference(canonicalBreakpoints, mappedCanonicalBreakpoints);
                final Set<CanonicalBreakpoint> finalDifference = new HashSet<>();

                for (CanonicalBreakpoint missingBreakpoint : initialDifference) {
                  // If the file name doesn't exist in loaded library files, then most likely it's not part of the dependencies of what was
                  // built. So it's okay to ignore these breakpoints in our count.
                  if (fileNames.contains(missingBreakpoint.fileName)) {
                    finalDifference.add(missingBreakpoint);
                  }
                }

                analytics.sendEventMetric(category, "unmapped-count", finalDifference.size());

                // For internal bazel projects, report files where mapping failed.
                if (WorkspaceCache.getInstance(myDebugProcess.getSession().getProject()).isBazel()) {
                  for (CanonicalBreakpoint canonicalBreakpoint : finalDifference) {
                    if (canonicalBreakpoint.path.contains("google3")) {
                      analytics.sendEvent(category,
                                          String.format("unmapped-file|%s|%s", response.getRootLib().getUri(), canonicalBreakpoint.path));
                    }
                  }
                }
              }

              @Override
              public void received(Sentinel response) {

              }

              @Override
              public void onError(RPCError error) {

              }
            });
          }
        }
      });
    }
  }