aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar murgatroid99 <mlumish@google.com>2016-02-17 12:59:26 -0800
committerGravatar murgatroid99 <mlumish@google.com>2016-02-17 12:59:26 -0800
commitc02910b07ae492098d7d0c1bca747fbcad742393 (patch)
tree4913561a1ea4a9193ea957089c2e66e98a5d7662 /src
parent7da3297be7068a5a167991efafb2ec4eba2b2779 (diff)
Node: add options to modify ProtoBuf behavior
Diffstat (limited to 'src')
-rw-r--r--src/node/index.js40
-rw-r--r--src/node/src/client.js6
-rw-r--r--src/node/src/common.js29
-rw-r--r--src/node/src/server.js7
4 files changed, 59 insertions, 23 deletions
diff --git a/src/node/index.js b/src/node/index.js
index 7eacdc67b1..4e4d12d9e4 100644
--- a/src/node/index.js
+++ b/src/node/index.js
@@ -56,17 +56,18 @@ var grpc = require('./src/grpc_extension');
/**
* Load a gRPC object from an existing ProtoBuf.Reflect object.
* @param {ProtoBuf.Reflect.Namespace} value The ProtoBuf object to load.
+ * @param {Object=} options Options to apply to the loaded object
* @return {Object<string, *>} The resulting gRPC object
*/
-exports.loadObject = function loadObject(value) {
+exports.loadObject = function loadObject(value, options) {
var result = {};
if (value.className === 'Namespace') {
_.each(value.children, function(child) {
- result[child.name] = loadObject(child);
+ result[child.name] = loadObject(child, options);
});
return result;
} else if (value.className === 'Service') {
- return client.makeProtobufClientConstructor(value);
+ return client.makeProtobufClientConstructor(value, options);
} else if (value.className === 'Message' || value.className === 'Enum') {
return value.build();
} else {
@@ -78,27 +79,36 @@ var loadObject = exports.loadObject;
/**
* Load a gRPC object from a .proto file.
- * @param {string} filename The file to load
+ * @param {string|{root: string, file: string}} filename The file to load
* @param {string=} format The file format to expect. Must be either 'proto' or
* 'json'. Defaults to 'proto'
+ * @param {Object=} options Options to apply to the loaded file
* @return {Object<string, *>} The resulting gRPC object
*/
-exports.load = function load(filename, format) {
+exports.load = function load(filename, format, options) {
if (!format) {
format = 'proto';
}
+ var convertFieldsToCamelCaseOriginal = ProtoBuf.convertFieldsToCamelCase;
+ if(options && options.hasOwnProperty('convertFieldsToCamelCase')) {
+ ProtoBuf.convertFieldsToCamelCase = options.convertFieldsToCamelCase;
+ }
var builder;
- switch(format) {
- case 'proto':
- builder = ProtoBuf.loadProtoFile(filename);
- break;
- case 'json':
- builder = ProtoBuf.loadJsonFile(filename);
- break;
- default:
- throw new Error('Unrecognized format "' + format + '"');
+ try {
+ switch(format) {
+ case 'proto':
+ builder = ProtoBuf.loadProtoFile(filename);
+ break;
+ case 'json':
+ builder = ProtoBuf.loadJsonFile(filename);
+ break;
+ default:
+ throw new Error('Unrecognized format "' + format + '"');
+ }
+ } finally {
+ ProtoBuf.convertFieldsToCamelCase = convertFieldsToCamelCaseOriginal;
}
- return loadObject(builder.ns);
+ return loadObject(builder.ns, options);
};
/**
diff --git a/src/node/src/client.js b/src/node/src/client.js
index b5247a69ee..5523d6b9a4 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -698,13 +698,15 @@ exports.waitForClientReady = function(client, deadline, callback) {
* Creates a constructor for clients for the given service
* @param {ProtoBuf.Reflect.Service} service The service to generate a client
* for
+ * @param {Object=} options Options to apply to the client
* @return {function(string, Object)} New client constructor
*/
-exports.makeProtobufClientConstructor = function(service) {
- var method_attrs = common.getProtobufServiceAttrs(service, service.name);
+exports.makeProtobufClientConstructor = function(service, options) {
+ var method_attrs = common.getProtobufServiceAttrs(service, service.name, options);
var Client = exports.makeClientConstructor(
method_attrs, common.fullyQualifiedName(service));
Client.service = service;
+ Client.service.grpc_options = options;
return Client;
};
diff --git a/src/node/src/common.js b/src/node/src/common.js
index 2e6c01c4d7..3e6609ab10 100644
--- a/src/node/src/common.js
+++ b/src/node/src/common.js
@@ -44,9 +44,20 @@ var _ = require('lodash');
/**
* Get a function that deserializes a specific type of protobuf.
* @param {function()} cls The constructor of the message type to deserialize
+ * @param {bool=} binaryAsBase64 Deserialize bytes fields as base64 instead of binary.
+ * Defaults to false
+ * @param {bool=} longsAsStrings Deserialize long values as strings instead of doubles.
+ * Defaults to true
* @return {function(Buffer):cls} The deserialization function
*/
-exports.deserializeCls = function deserializeCls(cls) {
+exports.deserializeCls = function deserializeCls(cls, binaryAsBase64,
+ longsAsStrings) {
+ if (binaryAsBase64 === undefined || binaryAsBase64 === null) {
+ binaryAsBase64 = false;
+ }
+ if (longsAsStrings === undefined || longsAsStrings === null) {
+ longsAsStrings = true;
+ }
/**
* Deserialize a buffer to a message object
* @param {Buffer} arg_buf The buffer to deserialize
@@ -55,7 +66,7 @@ exports.deserializeCls = function deserializeCls(cls) {
return function deserialize(arg_buf) {
// Convert to a native object with binary fields as Buffers (first argument)
// and longs as strings (second argument)
- return cls.decode(arg_buf).toRaw(false, true);
+ return cls.decode(arg_buf).toRaw(binaryAsBase64, longsAsStrings);
};
};
@@ -119,19 +130,27 @@ exports.wrapIgnoreNull = function wrapIgnoreNull(func) {
/**
* Return a map from method names to method attributes for the service.
* @param {ProtoBuf.Reflect.Service} service The service to get attributes for
+ * @param {Object=} options Options to apply to these attributes
* @return {Object} The attributes map
*/
-exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service) {
+exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service, options) {
var prefix = '/' + fullyQualifiedName(service) + '/';
+ var binaryAsBase64, longsAsStrings;
+ if (options) {
+ binaryAsBase64 = options.binaryAsBase64;
+ longsAsStrings = options.longsAsStrings;
+ }
return _.object(_.map(service.children, function(method) {
return [_.camelCase(method.name), {
path: prefix + method.name,
requestStream: method.requestStream,
responseStream: method.responseStream,
requestSerialize: serializeCls(method.resolvedRequestType.build()),
- requestDeserialize: deserializeCls(method.resolvedRequestType.build()),
+ requestDeserialize: deserializeCls(method.resolvedRequestType.build(),
+ binaryAsBase64, longsAsStrings),
responseSerialize: serializeCls(method.resolvedResponseType.build()),
- responseDeserialize: deserializeCls(method.resolvedResponseType.build())
+ responseDeserialize: deserializeCls(method.resolvedResponseType.build(),
+ binaryAsBase64, longsAsStrings)
}];
}));
};
diff --git a/src/node/src/server.js b/src/node/src/server.js
index e5aadcd565..0cf7ba3424 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -737,7 +737,12 @@ Server.prototype.addService = function(service, implementation) {
* method implementation for the provided service.
*/
Server.prototype.addProtoService = function(service, implementation) {
- this.addService(common.getProtobufServiceAttrs(service), implementation);
+ var options;
+ if (service.grpc_options) {
+ options = service.grpc_options;
+ }
+ this.addService(common.getProtobufServiceAttrs(service, options),
+ implementation);
};
/**