Skip to content

Commit

Permalink
CLI: Annotated callback types in pbjs-generated services, see #582
Browse files Browse the repository at this point in the history
  • Loading branch information
dcodeIO committed Dec 22, 2016
1 parent b1b6a81 commit c60cd39
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 13 deletions.
54 changes: 46 additions & 8 deletions cli/targets/static.js
Expand Up @@ -14,6 +14,7 @@ var Type = protobuf.Type,
var out = [];
var indent = 0;
var config = {};
var firstService = true;

static_target.description = "Static code without reflection";

Expand Down Expand Up @@ -47,13 +48,14 @@ function static_target(root, options, callback) {
push("});");
--indent;
push("});");
callback(null, out.join('\n'));
return callback(null, out.join("\n"));
} catch (err) {
callback(err);
return callback(err);
} finally {
out = [];
indent = 0;
config = {};
firstService = true;
}
}

Expand All @@ -63,12 +65,12 @@ function push(line) {
var ind = "";
for (var i = 0; i < indent; ++i)
ind += " ";
out.push(ind + line);
return out.push(ind + line);
}

function pushComment(lines) {
push("/**");
lines.forEach(function(line, i) {
lines.forEach(function(line) {
push(" * " + line);
});
push(" */");
Expand Down Expand Up @@ -133,7 +135,7 @@ function buildFunction(type, functionName, gen, scope) {
return field.resolve().resolvedType
? JSON.stringify(field.resolvedType.fullName.substring(1))
: "null";
}).join(',') + "]);");
}).join(",") + "]);");
push("return " + lines[0]);
lines.slice(1).forEach(function(line) {
var prev = indent;
Expand Down Expand Up @@ -366,21 +368,47 @@ function buildType(ref, type) {
function buildService(ref, service) {
var fullName = service.fullName.substring(1);

if (firstService) {
firstService = false;

push("");
pushComment([
"RPC implementation passed to services performing a service request on network level, i.e. by utilizing http requests or websockets.",
"@typedef RPCImpl",
"@type {function}",
"@param {Method} method Reflected method being called",
"@param {Uint8Array} requestData Request data",
"@param {RPCCallback} callback Callback function",
"@returns {undefined}"
]);

push("");
pushComment([
"Node-style callback as used by {@link RPCImpl}.",
"@typedef RPCCallback",
"@type {function}",
"@param {?Error} error Error, if any, otherwise `null`",
"@param {Uint8Array} [responseData] Response data or `null` to signal end of stream, if there hasn't been an error",
"@returns {undefined}"
]);
}

push("");
pushComment([
"Constructs a new " + service.name + ".",
"@exports " + fullName,
"@constructor",
"@param {function(function, Uint8Array, function)} rpc RPC implementation",
"@param {RPCImpl} rpc RPC implementation",
"@param {boolean} [requestDelimited=false] Whether requests are length-delimited",
"@param {boolean} [responseDelimited=false] Whether responses are length-delimited"
]);
push("function " + name(service.name) + "(rpc, requestDelimited, responseDelimited) {");
++indent;

push("");
pushComment([
"RPC implementation.",
"@type {function(function, Uint8Array, function)}"
"@type {RPCImpl}"
]);
push("this.rpc = rpc;");
push("");
Expand All @@ -397,14 +425,24 @@ function buildService(ref, service) {
push("this.responseDelimited = Boolean(responseDelimited);");
--indent;
push("};");

service.getMethodsArray().forEach(function(method) {
method.resolve();
var lcName = method.name.substring(0, 1).toLowerCase() + method.name.substring(1);
push("");
var cbName = name(service.name) + "_" + name(lcName) + "_Callback";
pushComment([
"Callback as used by {@link " + name(service.name) + "#" + name(lcName) + "}.",
"@typedef " + cbName,
"@type {function}",
"@param {?Error} error Error, if any",
"@param {" + method.resolvedResponseType.fullName.substring(1) + "} [response] " + method.resolvedResponseType.name
]);
push("");
pushComment([
"Calls " + method.name + ".",
"@param {" + method.resolvedRequestType.fullName.substring(1) + "|Object} request " + method.resolvedRequestType.name + " or plain object",
"@param {function(?Error, " + method.resolvedResponseType.fullName.substring(1) + "=)} callback Node-style callback called with the error, if any, and " + method.resolvedResponseType.name,
"@param {" + cbName + "} callback Node-style callback called with the error, if any, and " + method.resolvedResponseType.name,
"@returns {undefined}"
]);
push(name(service.name) + ".prototype[" + JSON.stringify(lcName) + "] = function " + name(lcName) + "(request, callback) {");
Expand Down
2 changes: 1 addition & 1 deletion tests/data/ambiguous-names.js
Expand Up @@ -188,7 +188,7 @@ $root.B = (function() {
return function encode(m, w) {
w||(w=Writer.create())
if(m["A"]!==undefined&&m["A"]!==null)
types[0].encode(m["A"],w.fork()).len&&w.ldelim(1)||w.reset()
types[0].encode(m["A"],w.uint32(10).fork()).ldelim()
return w
}
/* eslint-enable */
Expand Down
2 changes: 1 addition & 1 deletion tests/data/package.js
Expand Up @@ -173,7 +173,7 @@ $root.Package = (function() {
if(m["license"]!==undefined&&m["license"]!=="")
w.uint32(42).string(m["license"])
if(m["repository"]!==undefined&&m["repository"]!==null)
types[5].encode(m["repository"],w.fork()).len&&w.ldelim(6)||w.reset()
types[5].encode(m["repository"],w.uint32(50).fork()).ldelim()
if(m["bugs"]!==undefined&&m["bugs"]!=="")
w.uint32(58).string(m["bugs"])
if(m["homepage"]!==undefined&&m["homepage"]!=="")
Expand Down
33 changes: 30 additions & 3 deletions tests/data/rpc.js
Expand Up @@ -10,19 +10,38 @@ var $root = {};

$root.MyService = (function() {

/**
* RPC implementation passed to services performing a service request on network level, i.e. by utilizing http requests or websockets.
* @typedef RPCImpl
* @type {function}
* @param {Method} method Reflected method being called
* @param {Uint8Array} requestData Request data
* @param {RPCCallback} callback Callback function
* @returns {undefined}
*/

/**
* Node-style callback as used by {@link RPCImpl}.
* @typedef RPCCallback
* @type {function}
* @param {?Error} error Error, if any, otherwise `null`
* @param {Uint8Array} [responseData] Response data or `null` to signal end of stream, if there hasn't been an error
* @returns {undefined}
*/

/**
* Constructs a new MyService.
* @exports MyService
* @constructor
* @param {function(function, Uint8Array, function)} rpc RPC implementation
* @param {RPCImpl} rpc RPC implementation
* @param {boolean} [requestDelimited=false] Whether requests are length-delimited
* @param {boolean} [responseDelimited=false] Whether responses are length-delimited
*/
function MyService(rpc, requestDelimited, responseDelimited) {

/**
* RPC implementation.
* @type {function(function, Uint8Array, function)}
* @type {RPCImpl}
*/
this.rpc = rpc;

Expand All @@ -39,10 +58,18 @@ $root.MyService = (function() {
this.responseDelimited = Boolean(responseDelimited);
};

/**
* Callback as used by {@link MyService#myMethod}.
* @typedef MyService_myMethod_Callback
* @type {function}
* @param {?Error} error Error, if any
* @param {MyResponse} [response] MyResponse
*/

/**
* Calls MyMethod.
* @param {MyRequest|Object} request MyRequest or plain object
* @param {function(?Error, MyResponse=)} callback Node-style callback called with the error, if any, and MyResponse
* @param {MyService_myMethod_Callback} callback Node-style callback called with the error, if any, and MyResponse
* @returns {undefined}
*/
MyService.prototype["myMethod"] = function myMethod(request, callback) {
Expand Down

0 comments on commit c60cd39

Please sign in to comment.