--- /dev/null
+/*?\r
+ // --- Scope ------------------\r
+ // T : Reflect.Service instance\r
+ */\r
+/**\r
+ * Constructs a new runtime Service.\r
+ * @name ProtoBuf.Builder.Service\r
+ * @param {function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))=} rpcImpl RPC implementation receiving the method name and the message\r
+ * @class Barebone of all runtime services.\r
+ * @constructor\r
+ * @throws {Error} If the service cannot be created\r
+ */\r
+var Service = function(rpcImpl) {\r
+ ProtoBuf.Builder.Service.call(this);\r
+\r
+ /**\r
+ * Service implementation.\r
+ * @name ProtoBuf.Builder.Service#rpcImpl\r
+ * @type {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))}\r
+ * @expose\r
+ */\r
+ this.rpcImpl = rpcImpl || function(name, msg, callback) {\r
+ // This is what a user has to implement: A function receiving the method name, the actual message to\r
+ // send (type checked) and the callback that's either provided with the error as its first\r
+ // argument or null and the actual response message.\r
+ setTimeout(callback.bind(this, Error("Not implemented, see: https://github.com/dcodeIO/ProtoBuf.js/wiki/Services")), 0); // Must be async!\r
+ };\r
+};\r
+\r
+/**\r
+ * @alias ProtoBuf.Builder.Service.prototype\r
+ * @inner\r
+ */\r
+var ServicePrototype = Service.prototype = Object.create(ProtoBuf.Builder.Service.prototype);\r
+\r
+/**\r
+ * Asynchronously performs an RPC call using the given RPC implementation.\r
+ * @name ProtoBuf.Builder.Service.[Method]\r
+ * @function\r
+ * @param {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))} rpcImpl RPC implementation\r
+ * @param {ProtoBuf.Builder.Message} req Request\r
+ * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving\r
+ * the error if any and the response either as a pre-parsed message or as its raw bytes\r
+ * @abstract\r
+ */\r
+\r
+/**\r
+ * Asynchronously performs an RPC call using the instance's RPC implementation.\r
+ * @name ProtoBuf.Builder.Service#[Method]\r
+ * @function\r
+ * @param {ProtoBuf.Builder.Message} req Request\r
+ * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving\r
+ * the error if any and the response either as a pre-parsed message or as its raw bytes\r
+ * @abstract\r
+ */\r
+\r
+var rpc = T.getChildren(ProtoBuf.Reflect.Service.RPCMethod);\r
+for (var i=0; i<rpc.length; i++) {\r
+ (function(method) {\r
+\r
+ // service#Method(message, callback)\r
+ ServicePrototype[method.name] = function(req, callback) {\r
+ try {\r
+ try {\r
+ // If given as a buffer, decode the request. Will throw a TypeError if not a valid buffer.\r
+ req = method.resolvedRequestType.clazz.decode(ByteBuffer.wrap(req));\r
+ } catch (err) {\r
+ if (!(err instanceof TypeError))\r
+ throw err;\r
+ }\r
+ if (req === null || typeof req !== 'object')\r
+ throw Error("Illegal arguments");\r
+ if (!(req instanceof method.resolvedRequestType.clazz))\r
+ req = new method.resolvedRequestType.clazz(req);\r
+ this.rpcImpl(method.fqn(), req, function(err, res) { // Assumes that this is properly async\r
+ if (err) {\r
+ callback(err);\r
+ return;\r
+ }\r
+ // Coalesce to empty string when service response has empty content\r
+ if (res === null)\r
+ res = ''\r
+ try { res = method.resolvedResponseType.clazz.decode(res); } catch (notABuffer) {}\r
+ if (!res || !(res instanceof method.resolvedResponseType.clazz)) {\r
+ callback(Error("Illegal response type received in service method "+ T.name+"#"+method.name));\r
+ return;\r
+ }\r
+ callback(null, res);\r
+ });\r
+ } catch (err) {\r
+ setTimeout(callback.bind(this, err), 0);\r
+ }\r
+ };\r
+\r
+ // Service.Method(rpcImpl, message, callback)\r
+ Service[method.name] = function(rpcImpl, req, callback) {\r
+ new Service(rpcImpl)[method.name](req, callback);\r
+ };\r
+\r
+ if (Object.defineProperty)\r
+ Object.defineProperty(Service[method.name], "$options", { "value": method.buildOpt() }),\r
+ Object.defineProperty(ServicePrototype[method.name], "$options", { "value": Service[method.name]["$options"] });\r
+ })(rpc[i]);\r
+}\r
+\r
+// Properties\r
+\r
+/**\r
+ * Service options.\r
+ * @name ProtoBuf.Builder.Service.$options\r
+ * @type {Object.<string,*>}\r
+ * @expose\r
+ */\r
+var $optionsS; // cc needs this\r
+\r
+/**\r
+ * Service options.\r
+ * @name ProtoBuf.Builder.Service#$options\r
+ * @type {Object.<string,*>}\r
+ * @expose\r
+ */\r
+var $options;\r
+\r
+/**\r
+ * Reflection type.\r
+ * @name ProtoBuf.Builder.Service.$type\r
+ * @type {!ProtoBuf.Reflect.Service}\r
+ * @expose\r
+ */\r
+var $typeS;\r
+\r
+/**\r
+ * Reflection type.\r
+ * @name ProtoBuf.Builder.Service#$type\r
+ * @type {!ProtoBuf.Reflect.Service}\r
+ * @expose\r
+ */\r
+var $type;\r
+\r
+if (Object.defineProperty)\r
+ Object.defineProperty(Service, "$options", { "value": T.buildOpt() }),\r
+ Object.defineProperty(ServicePrototype, "$options", { "value": Service["$options"] }),\r
+ Object.defineProperty(Service, "$type", { "value": T }),\r
+ Object.defineProperty(ServicePrototype, "$type", { "value": T });\r