diff --git a/scripts/msgpack-gen.lua b/scripts/msgpack-gen.lua index 946cff1d11..1516271973 100644 --- a/scripts/msgpack-gen.lua +++ b/scripts/msgpack-gen.lua @@ -123,6 +123,7 @@ end output:write([[ }; const unsigned int msgpack_metadata_size = sizeof(msgpack_metadata); +msgpack_unpacked msgpack_unpacked_metadata; ]]) @@ -237,6 +238,14 @@ static Map(String, rpc_method_handler_fn) *methods = NULL; void msgpack_rpc_init(void) { + msgpack_unpacked_init(&msgpack_unpacked_metadata); + if (msgpack_unpack_next(&msgpack_unpacked_metadata, + (const char *)msgpack_metadata, + msgpack_metadata_size, + NULL) != MSGPACK_UNPACK_SUCCESS) { + abort(); + } + methods = map_new(String, rpc_method_handler_fn)(); ]]) @@ -256,6 +265,12 @@ for i = 1, #api.functions do end end +local metadata_fn = 'get_api_metadata' +output:write(' map_put(String, rpc_method_handler_fn)(methods, '.. + '(String) {.data = "'..metadata_fn..'", '.. + '.size = sizeof("'..metadata_fn..'") - 1}, msgpack_rpc_handle_'.. + metadata_fn..');\n') + output:write('\n}\n\n') output:write([[ diff --git a/src/nvim/os/msgpack_rpc.c b/src/nvim/os/msgpack_rpc.c index 4a586e8e01..b06c8ee597 100644 --- a/src/nvim/os/msgpack_rpc.c +++ b/src/nvim/os/msgpack_rpc.c @@ -17,8 +17,7 @@ # include "os/msgpack_rpc.c.generated.h" #endif -extern const uint8_t msgpack_metadata[]; -extern const unsigned int msgpack_metadata_size; +extern msgpack_unpacked msgpack_unpacked_metadata; /// Validates the basic structure of the msgpack-rpc call and fills `res` /// with the basic response structure. @@ -39,11 +38,6 @@ WBuffer *msgpack_rpc_call(uint64_t channel_id, return serialize_response(response_id, err, NIL, sbuffer); } - if (req->via.array.ptr[2].type == MSGPACK_OBJECT_POSITIVE_INTEGER - && req->via.array.ptr[2].via.u64 == 0) { - return serialize_metadata(response_id, channel_id, sbuffer); - } - // dispatch the call Error error = { .set = false }; Object rv = msgpack_rpc_dispatch(channel_id, req, &error); @@ -125,6 +119,19 @@ Object msgpack_rpc_handle_missing_method(uint64_t channel_id, return NIL; } +/// Handler for retrieving API metadata through a msgpack-rpc call +Object msgpack_rpc_handle_get_api_metadata(uint64_t channel_id, + msgpack_object *req, + Error *error) +{ + Array rv = ARRAY_DICT_INIT; + Object metadata; + msgpack_rpc_to_object(&msgpack_unpacked_metadata.data, &metadata); + ADD(rv, INTEGER_OBJ((int64_t)channel_id)); + ADD(rv, metadata); + return ARRAY_OBJ(rv); +} + /// Serializes a msgpack-rpc request or notification(id == 0) WBuffer *serialize_request(uint64_t request_id, String method, @@ -190,31 +197,6 @@ WBuffer *serialize_response(uint64_t response_id, return rv; } -WBuffer *serialize_metadata(uint64_t id, - uint64_t channel_id, - msgpack_sbuffer *sbuffer) - FUNC_ATTR_NONNULL_ALL -{ - msgpack_packer pac; - msgpack_packer_init(&pac, sbuffer, msgpack_sbuffer_write); - msgpack_pack_array(&pac, 4); - msgpack_pack_int(&pac, 1); - msgpack_pack_uint64(&pac, id); - // Nil error - msgpack_pack_nil(&pac); - // The result is the [channel_id, metadata] array - msgpack_pack_array(&pac, 2); - msgpack_pack_uint64(&pac, channel_id); - msgpack_pack_bin(&pac, msgpack_metadata_size); - msgpack_pack_bin_body(&pac, msgpack_metadata, msgpack_metadata_size); - WBuffer *rv = wstream_new_buffer(xmemdup(sbuffer->data, sbuffer->size), - sbuffer->size, - 1, - free); - msgpack_sbuffer_clear(sbuffer); - return rv; -} - static char *msgpack_rpc_validate(uint64_t *response_id, msgpack_object *req) { // response id not known yet