/*
* Copyright 2025 the original author or authors.
*
* Licensed under the Moderne Source Available License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://docs.moderne.io/licensing/moderne-source-available-license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Checksum, FileAttributes, TreeKind} from "../tree";
import {RpcCodecs, RpcReceiveQueue, RpcSendQueue} from "./queue";
import {
Markers,
MarkersKind,
MarkupDebug,
MarkupError,
MarkupInfo,
MarkupWarn,
RecipeThatMadeChanges,
RecipesThatMadeChanges,
SearchResult
} from "../markers";
import {asRef} from "../reference";
import {updateIfChanged} from "../util";
export * from "./queue";
export * from "../reference";
export {RewriteRpc} from "./rewrite-rpc";
export {RpcRecipe, RpcVisitor} from "./recipe";
export {prepareJavaRecipe} from "./java-recipe";
export {registerVisitor} from "./request/visitor-registry";
RpcCodecs.registerCodec(TreeKind.Checksum, {
async rpcReceive(before: Checksum, q: RpcReceiveQueue): Promise {
return updateIfChanged(before, {
algorithm: await q.receive(before.algorithm),
value: await q.receive(before.value),
});
},
async rpcSend(after: Checksum, q: RpcSendQueue): Promise {
await q.getAndSend(after, c => c.algorithm);
await q.getAndSend(after, c => c.value);
}
});
RpcCodecs.registerCodec(TreeKind.FileAttributes, {
async rpcReceive(before: FileAttributes, q: RpcReceiveQueue): Promise {
return updateIfChanged(before, {
creationDate: await q.receive(before.creationDate),
lastModifiedTime: await q.receive(before.lastModifiedTime),
lastAccessTime: await q.receive(before.lastAccessTime),
isReadable: await q.receive(before.isReadable),
isWritable: await q.receive(before.isWritable),
isExecutable: await q.receive(before.isExecutable),
size: await q.receive(before.size),
});
},
async rpcSend(after: FileAttributes, q: RpcSendQueue): Promise {
await q.getAndSend(after, a => a.creationDate);
await q.getAndSend(after, a => a.lastModifiedTime);
await q.getAndSend(after, a => a.lastAccessTime);
await q.getAndSend(after, a => a.isReadable);
await q.getAndSend(after, a => a.isWritable);
await q.getAndSend(after, a => a.isExecutable);
await q.getAndSend(after, a => a.size);
}
});
RpcCodecs.registerCodec(MarkersKind.Markers, {
async rpcReceive(before: Markers, q: RpcReceiveQueue): Promise {
return updateIfChanged(before, {
id: await q.receive(before.id),
markers: (await q.receiveList(before.markers))!,
});
},
async rpcSend(after: Markers, q: RpcSendQueue): Promise {
await q.getAndSend(after, m => m.id);
await q.getAndSendList(after, m => m.markers.map(marker => asRef(marker)), m => m.id);
}
});
// Register codecs for all Java markers with additional properties
RpcCodecs.registerCodec(MarkersKind.SearchResult, {
async rpcReceive(before: SearchResult, q: RpcReceiveQueue): Promise {
return updateIfChanged(before, {
id: await q.receive(before.id),
description: await q.receive(before.description),
});
},
async rpcSend(after: SearchResult, q: RpcSendQueue): Promise {
await q.getAndSend(after, a => a.id);
await q.getAndSend(after, a => a.description);
}
});
// Field order mirrors Java's RecipeThatMadeChanges codec.
RpcCodecs.registerCodec(MarkersKind.RecipeThatMadeChanges, {
async rpcReceive(before: RecipeThatMadeChanges, q: RpcReceiveQueue): Promise {
return updateIfChanged(before, {
name: await q.receive(before.name),
displayName: await q.receive(before.displayName),
instanceName: await q.receive(before.instanceName),
options: await q.receive(before.options),
estimatedEffortPerOccurrenceMillis: await q.receive(before.estimatedEffortPerOccurrenceMillis),
});
},
async rpcSend(after: RecipeThatMadeChanges, q: RpcSendQueue): Promise {
await q.getAndSend(after, a => a.name);
await q.getAndSend(after, a => a.displayName);
await q.getAndSend(after, a => a.instanceName);
await q.getAndSend(after, a => a.options);
await q.getAndSend(after, a => a.estimatedEffortPerOccurrenceMillis);
}
});
RpcCodecs.registerCodec(MarkersKind.RecipesThatMadeChanges, {
async rpcReceive(before: RecipesThatMadeChanges, q: RpcReceiveQueue): Promise {
return updateIfChanged(before, {
id: await q.receive(before.id),
recipes: (await q.receiveList(before.recipes,
async stack => (await q.receiveList(stack))!))!,
});
},
async rpcSend(after: RecipesThatMadeChanges, q: RpcSendQueue): Promise {
await q.getAndSend(after, m => m.id);
// The stack key never travels; it only has to identify a stack within this process.
await q.getAndSendList(after, m => m.recipes, stack => stack.map(r => r.name).join("\0"),
async stack => q.getAndSendList(stack, s => s, r => r.name));
}
});
RpcCodecs.registerCodec(MarkersKind.MarkupError, {
async rpcReceive(before: MarkupError, q: RpcReceiveQueue): Promise {
return updateIfChanged(before, {
id: await q.receive(before.id),
message: await q.receive(before.message),
detail: await q.receive(before.detail),
});
},
async rpcSend(after: MarkupError, q: RpcSendQueue): Promise {
await q.getAndSend(after, a => a.id);
await q.getAndSend(after, a => a.message);
await q.getAndSend(after, a => a.detail);
}
});
RpcCodecs.registerCodec(MarkersKind.MarkupWarn, {
async rpcReceive(before: MarkupWarn, q: RpcReceiveQueue): Promise {
return updateIfChanged(before, {
id: await q.receive(before.id),
message: await q.receive(before.message),
detail: await q.receive(before.detail),
});
},
async rpcSend(after: MarkupWarn, q: RpcSendQueue): Promise {
await q.getAndSend(after, a => a.id);
await q.getAndSend(after, a => a.message);
await q.getAndSend(after, a => a.detail);
}
});
RpcCodecs.registerCodec(MarkersKind.MarkupInfo, {
async rpcReceive(before: MarkupInfo, q: RpcReceiveQueue): Promise {
return updateIfChanged(before, {
id: await q.receive(before.id),
message: await q.receive(before.message),
detail: await q.receive(before.detail),
});
},
async rpcSend(after: MarkupInfo, q: RpcSendQueue): Promise {
await q.getAndSend(after, a => a.id);
await q.getAndSend(after, a => a.message);
await q.getAndSend(after, a => a.detail);
}
});
RpcCodecs.registerCodec(MarkersKind.MarkupDebug, {
async rpcReceive(before: MarkupDebug, q: RpcReceiveQueue): Promise {
return updateIfChanged(before, {
id: await q.receive(before.id),
message: await q.receive(before.message),
detail: await q.receive(before.detail),
});
},
async rpcSend(after: MarkupDebug, q: RpcSendQueue): Promise {
await q.getAndSend(after, a => a.id);
await q.getAndSend(after, a => a.message);
await q.getAndSend(after, a => a.detail);
}
});