blob: ecc17145d4d77697e0890a1c0bb0d433e8713573 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/**
* @fileoverview A method to create an array of interface signatures for a
* service based on the descriptions passed in.
* @private
*/
module.exports = createSignature;
var stringify = require('./stringify');
var capitalize = require('./util').capitalize;
var Interface = require('./interface');
function sigsHaveMethod(sigs, method) {
return sigs.some(function(sig) {
return sig.methods.some(function(elem) {
return elem.name === method;
});
});
}
function createSignature(service, descs) {
if (!Array.isArray(descs)) {
if (typeof descs !== 'object') {
descs = [];
} else {
descs = [descs];
}
}
var sigs = descs.map(function(desc) {
return new Interface(service, desc);
});
// Find any methods that are in service that are not in any of the
// signatures generated and then generate a signature that contains
// those methods.
var leftOverSig = {
methods: []
};
for (var methodName in service) {
if (typeof service[methodName] === 'function') {
var name = capitalize(methodName);
if (!sigsHaveMethod(sigs, name)) {
leftOverSig.methods.push({ name: name });
}
}
}
// TODO(bjornick): How terrible is it to create this leftover signature if the
// user provided a description and thought (incorrectly) that it was complete?
if (leftOverSig.methods.length > 0) {
sigs.push(new Interface(service, leftOverSig));
}
checkForConflicts(sigs);
return sigs;
}
// Looks through all the Interface signatures and makes sure that any duplicate
// methods have the same signature. Throws if there are any conflicts.
function checkForConflicts(sigs) {
// Keep track of the methods sigs seen so far. The key is the method name.
// the value is the an object containing the interface name under the key
// 'interfaceName' and the method signature under the key 'sig'.
var methodsSeen = {};
sigs.forEach(function(sig) {
sig.methods.forEach(function(method) {
if (methodsSeen[method.name]) {
var seenMethod = methodsSeen[method.name].sig;
var iname = methodsSeen[method.name].interfaceName;
if (stringify(method) !== stringify(seenMethod)) {
throw new Error('Method ' + method.name + ' has conflicting ' +
'signatures in ' + iname + ' and ' + sig.name);
}
} else {
methodsSeen[method.name] = {
sig: method,
interfaceName: sig.name
};
}
});
});
}