@@ -112,7 +112,7 @@ public void registerStaticCapabilities(ServerCapabilities result) {
112112 /**
113113 * Update capabilities for language contributions.
114114 * @param contribs The contributions to represent.
115- * @return A void future that completes when all capabilities are updated .
115+ * @return A future that completes with a boolean that is false when any registration failed, and true otherwise .
116116 */
117117 public CompletableFuture <Boolean > updateCapabilities (Collection <ILanguageContributions > contribs ) {
118118 // Copy the contributions so we know we are looking at a stable set of elements.
@@ -125,6 +125,15 @@ public CompletableFuture<Boolean> updateCapabilities(Collection<ILanguageContrib
125125 return CompletableFutureUtils .reduce (registrations , CompletableFutureUtils .completedFuture (true , singleExec ), Boolean ::booleanValue , Boolean ::logicalAnd );
126126 }
127127
128+ /**
129+ * Update the registration of a capability.
130+ * - If the capability is not yet registered, register it.
131+ * - If the capability is already registered, and the options changed, update it (by unregistering and registering with new options).
132+ * - If the capability is already registered and the options did not change, do nothing.
133+ * @param cap The capability to update.
134+ * @param registration The computed registration to do, or `null` when this capability is absent.
135+ * @return A future completing with `true` when successful, or `false` otherwise.
136+ */
128137 private <T > CompletableFuture <Boolean > updateRegistration (AbstractDynamicCapability <T > cap , @ Nullable Registration registration ) {
129138 var method = cap .methodName ();
130139 var existingRegistration = currentRegistrations .get (method );
@@ -152,6 +161,12 @@ private <T> CompletableFuture<Boolean> updateRegistration(AbstractDynamicCapabil
152161 return register (registration );
153162 }
154163
164+ /**
165+ * Unregister this registration.
166+ * Aims to be atomic, i.e. keeps local administration of registered capabilities in sync with the client.
167+ * @param reg The registration to undo.
168+ * @return A future completing with `true` if successful, and `false` otherwise.
169+ */
155170 private CompletableFuture <Boolean > unregister (Registration reg ) {
156171 // If our administration contains exactly this registration, remove it and inform the client
157172 if (!currentRegistrations .remove (reg .getMethod (), reg )) {
@@ -170,6 +185,12 @@ private CompletableFuture<Boolean> unregister(Registration reg) {
170185 });
171186 }
172187
188+ /**
189+ * Register this registration.
190+ * Aims to be atomic, i.e. keeps local administration of registered capabilities in sync with the client.
191+ * @param reg The registration to do.
192+ * @return A future completing with `true` if successful, and `false` otherwise.
193+ */
173194 private CompletableFuture <Boolean > register (Registration reg ) {
174195 // If our administration contains no registration, inform the client
175196 if (currentRegistrations .putIfAbsent (reg .getMethod (), reg ) != null ) {
@@ -195,10 +216,21 @@ private void handleError(Throwable t, String task, String method) {
195216 logger .error ("Exception while {} capability {}" , task , method , t );
196217 }
197218
219+ /**
220+ * Update a registration.
221+ * Aims to be atomic, i.e. keeps local administration of registered capabilities in sync with the client.
222+ * @param newRegistration The registration with the updated options.
223+ * @param existingRegistration The registration that we expect to currently be in place.
224+ * @return A future completing with `true` if successful, or `false` otherwise.
225+ */
198226 private CompletableFuture <Boolean > changeOptions (Registration newRegistration , Registration existingRegistration ) {
199227 return unregister (existingRegistration )
200228 .thenCompose (b -> {
201229 if (!b .booleanValue ()) {
230+ /* If unregistration fails, this has one of multiple causes:
231+ 1. Someone raced us, won, and updated `currentRegistrations`. Our view of the current state is outdated, so we don't do anything and leave it to the winner.
232+ 2. The unregistration request failed. This happens when a capability is not supported by the client. Since we successfully registered, this should not happen.
233+ */
202234 return falsy ;
203235 }
204236 return register (newRegistration );
0 commit comments