diff --git a/lib/descriptors/ExtendDescriptor.js b/lib/descriptors/ExtendDescriptor.js index 25e8d40..94f6596 100644 --- a/lib/descriptors/ExtendDescriptor.js +++ b/lib/descriptors/ExtendDescriptor.js @@ -48,9 +48,14 @@ ExtendDescriptor.prototype.inspect = function () { /** @override */ ExtendDescriptor.prototype.toTemplateObject = function () { + var fields = null + var self = this return { name: this._name, - fields: helper.values(this._fields, helper.toTemplateObject) + get fields() { + if (fields) return fields + return ((fields = helper.values(self._fields, helper.toTemplateObject))) + } } } diff --git a/lib/descriptors/FieldDescriptor.js b/lib/descriptors/FieldDescriptor.js index 7fd6ed7..1c34ca1 100644 --- a/lib/descriptors/FieldDescriptor.js +++ b/lib/descriptors/FieldDescriptor.js @@ -33,6 +33,9 @@ module.exports = FieldDescriptor /** @override */ FieldDescriptor.prototype.toTemplateObject = function () { + var typeDescriptor = null + var self = this + return { name: this._name, camelName: this.getCamelName(), @@ -41,9 +44,11 @@ FieldDescriptor.prototype.toTemplateObject = function () { rawType: this._type, baseType: this.getBaseType(), type: this.getType(), - typeDescriptor: this._typeDescriptor ? - this._typeDescriptor.toTemplateObject(true /* skipFields to avoid infinite loops */) : - null, + get typeDescriptor() { + if (typeDescriptor) return typeDescriptor + if (!self._typeDescriptor) return null + return ((typeDescriptor = self._typeDescriptor.toTemplateObject())) + }, tag: this._tag, isOptional: this._isOptional, isRepeated: this._isRepeated, diff --git a/lib/descriptors/MessageDescriptor.js b/lib/descriptors/MessageDescriptor.js index 960ccc4..9df3a75 100644 --- a/lib/descriptors/MessageDescriptor.js +++ b/lib/descriptors/MessageDescriptor.js @@ -37,24 +37,35 @@ MessageDescriptor.prototype.inspect = function () { return util.inspect(this.toTemplateObject(), false, null) } +/** @override */ +MessageDescriptor.prototype.toTemplateObject = function () { + var fields = null + var oneofs = null + var messages = null + var enums = null + var self = this -/** - * @param {boolean=} opt_skipFields - * @override - */ -MessageDescriptor.prototype.toTemplateObject = function (opt_skipFields) { var obj = { name: this._name, fullName: helper.joinPackage(this._package, this._name), camelName: this.getCamelName(), - options: this._options - } - - if (!opt_skipFields) { - obj.fields = helper.values(this._fields, helper.toTemplateObject), - obj.oneofs = this._oneofs.map(helper.toTemplateObject), - obj.messages = helper.values(this._messages, helper.toTemplateObject), - obj.enums = helper.values(this._enums, helper.toTemplateObject) + options: this._options, + get fields() { + if (fields) return fields + return ((fields = helper.values(self._fields, helper.toTemplateObject))) + }, + get oneofs() { + if (oneofs) return oneofs + return ((oneofs = helper.values(self._oneofs, helper.toTemplateObject))) + }, + get messages() { + if (messages) return messages + return ((messages = helper.values(self._messages, helper.toTemplateObject))) + }, + get enums() { + if (enums) return enums + return ((enums = helper.values(self._enums, helper.toTemplateObject))) + } } return obj diff --git a/lib/descriptors/MethodDescriptor.js b/lib/descriptors/MethodDescriptor.js index a2bbfdb..32f367f 100644 --- a/lib/descriptors/MethodDescriptor.js +++ b/lib/descriptors/MethodDescriptor.js @@ -32,6 +32,10 @@ module.exports = MethodDescriptor /** @override */ MethodDescriptor.prototype.toTemplateObject = function () { + var inputTypeDescriptor = null + var outputTypeDescriptor = null + var self = this + return { name: this._name, camelName: this.getCamelName(), @@ -47,10 +51,17 @@ MethodDescriptor.prototype.toTemplateObject = function () { rawInputType: this._inputType, rawOutputType: this._outputType, - inputTypeDescriptor: this._inputTypeDescriptor ? - this._inputTypeDescriptor.toTemplateObject() : null, - outputTypeDescriptor: this._outputTypeDescriptor ? - this._outputTypeDescriptor.toTemplateObject() : null, + get inputTypeDescriptor() { + if (inputTypeDescriptor) return inputTypeDescriptor + if (!self._inputTypeDescriptor) return null + return ((inputTypeDescriptor = self._inputTypeDescriptor.toTemplateObject())) + }, + + get outputTypeDescriptor() { + if (outputTypeDescriptor) return outputTypeDescriptor + if (!self._outputTypeDescriptor) return null + return ((outputTypeDescriptor = self._outputTypeDescriptor.toTemplateObject())) + }, options: this._options } @@ -162,4 +173,3 @@ MethodDescriptor.prototype.addOption = function (name, value) { MethodDescriptor.prototype.getOption = function (name) { return this._options[name] } - diff --git a/lib/descriptors/ProtoDescriptor.js b/lib/descriptors/ProtoDescriptor.js index ce5fd81..2d8fbb8 100644 --- a/lib/descriptors/ProtoDescriptor.js +++ b/lib/descriptors/ProtoDescriptor.js @@ -25,8 +25,6 @@ function ProtoDescriptor(filePath) { this._services = {} this._enums = {} this._extends = {} - - this._recursing = false } util.inherits(ProtoDescriptor, Descriptor) module.exports = ProtoDescriptor @@ -50,23 +48,39 @@ ProtoDescriptor.prototype.inspect = function () { /** @override */ ProtoDescriptor.prototype.toTemplateObject = function () { - if (this._recursing) { - throw new Error('import loop detected: ' + this.getName()) - } - this._recursing = true + var messages = null + var services = null + var extendObjs = null + var enums = null + var imports = null + var self = this var result = { name: this.getName(), package: this._package, options: this._options, - messages: helper.values(this._messages, helper.toTemplateObject), - services: helper.values(this._services, helper.toTemplateObject), - extends: helper.values(this._messages, helper.toTemplateObject), - enums: helper.values(this._enums, helper.toTemplateObject), importNames: this._importNames, - imports: this._imports.map(helper.toTemplateObject) + get messages() { + if (messages) return messages + return ((messages = helper.values(self._messages, helper.toTemplateObject))) + }, + get services() { + if (services) return services + return ((services = helper.values(self._services, helper.toTemplateObject))) + }, + get extends() { + if (extendObjs) return extendObjs + return ((extendObjs = helper.values(self._extends, helper.toTemplateObject))) + }, + get enums() { + if (enums) return enums + return ((enums = helper.values(self._enums, helper.toTemplateObject))) + }, + get imports() { + if (imports) return imports + return ((imports = self._imports.map(helper.toTemplateObject))) + } } - this._recursing = false return result } diff --git a/lib/descriptors/ServiceDescriptor.js b/lib/descriptors/ServiceDescriptor.js index 680dbd3..1be7bf5 100644 --- a/lib/descriptors/ServiceDescriptor.js +++ b/lib/descriptors/ServiceDescriptor.js @@ -31,10 +31,15 @@ ServiceDescriptor.prototype.inspect = function () { /** @override */ ServiceDescriptor.prototype.toTemplateObject = function () { + var methods = null + var self = this return { name: this._name, fullName: helper.joinPackage(this._package, this._name), - methods: this._methodSequence.map(helper.toTemplateObject) + get methods() { + if (methods) return methods + return ((methods = self._methodSequence.map(helper.toTemplateObject))) + } } } diff --git a/tests/project_test.js b/tests/project_test.js index ace566d..4006277 100644 --- a/tests/project_test.js +++ b/tests/project_test.js @@ -194,7 +194,7 @@ builder.add(function testTypeResolutionLoop(test) { var dee = project.getProtos('protos/loop.proto')[0].getMessage('TweedleDee') var dum = dee.getField('dum') test.equal('TweedleDum', dum.toTemplateObject().typeDescriptor.name) - test.equal(null, dum.toTemplateObject().typeDescriptor.fields) + test.equal(1, dum.toTemplateObject().typeDescriptor.fields.length) test.done() })