diff --git a/cli/targets/static.js b/cli/targets/static.js index c589a67cd..deee1a52e 100644 --- a/cli/targets/static.js +++ b/cli/targets/static.js @@ -12,7 +12,6 @@ var Type = protobuf.Type, Service = protobuf.Service, Enum = protobuf.Enum, Namespace = protobuf.Namespace, - Class = protobuf.Class, util = protobuf.util; var out = []; diff --git a/config/tslint.json b/config/tslint.json index bf49d5d4a..6005e6f92 100644 --- a/config/tslint.json +++ b/config/tslint.json @@ -3,7 +3,7 @@ "rules": { "array-type": [ true, "array" ], "no-namespace": false, - "interface-name": [ true, "never-prefix" ], + "interface-name": [ false ], "interface-over-type-literal": false, "max-line-length": [ false ], "trailing-comma": [ true, "never" ], diff --git a/ext/descriptor/index.js b/ext/descriptor/index.js index f07243c50..e3f493874 100644 --- a/ext/descriptor/index.js +++ b/ext/descriptor/index.js @@ -12,11 +12,12 @@ var $protobuf = require(".."); */ var descriptor = module.exports = $protobuf.Root.fromJSON(require("../google/protobuf/descriptor.json")).lookup(".google.protobuf"); -var google = descriptor, // aliased used where `descriptor` is a local var +var google = descriptor, // alias used where `descriptor` is a local var Root = $protobuf.Root, Enum = $protobuf.Enum, Type = $protobuf.Type, Field = $protobuf.Field, + MapField = $protobuf.MapField, OneOf = $protobuf.OneOf, Service = $protobuf.Service, Method = $protobuf.Method; @@ -24,24 +25,28 @@ var google = descriptor, // aliased used where `descriptor` is a local var // --- Root --- /** + * Properties of a FileDescriptorSet message. * @interface IFileDescriptorSet - * @property {IFileDescriptorProto[]} file + * @property {IFileDescriptorProto[]} file Files + * @see Part of the {@link descriptor} extension (ext/descriptor) */ /** + * Properties of a FileDescriptorProto message. * @interface IFileDescriptorProto - * @property {string} [name] - * @property {string} [package] - * @property {*} [dependency] - * @property {*} [publicDependency] - * @property {*} [weakDependency] - * @property {IDescriptorProto[]} [messageType] - * @property {IEnumDescriptorProto[]} [enumType] - * @property {IServiceDescriptorProto[]} [service] - * @property {IFieldDescriptorProto[]} [extension] - * @property {*} [options] - * @property {*} [sourceCodeInfo] - * @property {string} [syntax="proto2"] + * @property {string} [name] File name + * @property {string} [package] Package + * @property {*} [dependency] Not supported + * @property {*} [publicDependency] Not supported + * @property {*} [weakDependency] Not supported + * @property {IDescriptorProto[]} [messageType] Nested message types + * @property {IEnumDescriptorProto[]} [enumType] Nested enums + * @property {IServiceDescriptorProto[]} [service] Nested services + * @property {IFieldDescriptorProto[]} [extension] Nested extension fields + * @property {*} [options] Not supported + * @property {*} [sourceCodeInfo] Not supported + * @property {string} [syntax="proto2"] Syntax + * @see Part of the {@link descriptor} extension (ext/descriptor) */ /** @@ -62,12 +67,11 @@ Root.fromDescriptor = function fromDescriptor(descriptor) { var fileDescriptor, filePackage; for (var j = 0, i; j < descriptor.file.length; ++j) { - fileDescriptor = descriptor.file[j]; filePackage = root; - if (fileDescriptor.name && fileDescriptor.name.length) - root.files.push(fileDescriptor.name); - if (fileDescriptor["package"] && fileDescriptor["package"].length) + if ((fileDescriptor = descriptor.file[j])["package"] && fileDescriptor["package"].length) filePackage = root.define(fileDescriptor["package"]); + if (fileDescriptor.name && fileDescriptor.name.length) + root.files.push(filePackage.filename = fileDescriptor.name); if (fileDescriptor.messageType) for (i = 0; i < fileDescriptor.messageType.length; ++i) filePackage.add(Type.fromDescriptor(fileDescriptor.messageType[i], fileDescriptor.syntax)); @@ -112,34 +116,42 @@ Root.prototype.toDescriptor = function toDescriptor(syntax) { // --- Type --- /** + * Properties of a DescriptorProto message. * @interface IDescriptorProto - * @property {string} [name] - * @property {IFieldDescriptorProto[]} [field] - * @property {IFieldDescriptorProto[]} [extension] - * @property {IDescriptorProto[]} [nestedType] - * @property {IEnumDescriptorProto[]} [enumType] - * @property {IExtensionRange[]} [extensionRange] - * @property {IOneofDescriptorProto[]} [oneofDecl] - * @property {IMessageOptions} [options] - * @property {IReservedRange[]} [reservedRange] - * @property {string[]} [reservedName] + * @property {string} [name] Message type name + * @property {IFieldDescriptorProto[]} [field] Fields + * @property {IFieldDescriptorProto[]} [extension] Extension fields + * @property {IDescriptorProto[]} [nestedType] Nested message types + * @property {IEnumDescriptorProto[]} [enumType] Nested enums + * @property {IExtensionRange[]} [extensionRange] Extension ranges + * @property {IOneofDescriptorProto[]} [oneofDecl] Oneofs + * @property {IMessageOptions} [options] Not supported + * @property {IReservedRange[]} [reservedRange] Reserved ranges + * @property {string[]} [reservedName] Reserved names + * @see Part of the {@link descriptor} extension (ext/descriptor) */ /** + * Properties of a MessageOptions message. * @interface IMessageOptions - * @property {*} [mapEntry] + * @property {boolean} [mapEntry=false] Whether this message is a map entry + * @see Part of the {@link descriptor} extension (ext/descriptor) */ /** + * Properties of an ExtensionRange message. * @interface IExtensionRange - * @property {number} [start] - * @property {number} [end] + * @property {number} [start] Start field id + * @property {number} [end] End field id + * @see Part of the {@link descriptor} extension (ext/descriptor) */ /** + * Properties of a ReservedRange message. * @interface IReservedRange - * @property {number} [start] - * @property {number} [end] + * @property {number} [start] Start field id + * @property {number} [end] End field id + * @see Part of the {@link descriptor} extension (ext/descriptor) */ var unnamedMessageIndex = 0; @@ -161,27 +173,37 @@ Type.fromDescriptor = function fromDescriptor(descriptor, syntax) { var type = new Type(descriptor.name.length ? descriptor.name : "Type" + unnamedMessageIndex++), i; - /* Fields */ for (i = 0; i < descriptor.field.length; ++i) - type.add(Field.fromDescriptor(descriptor.field[i], syntax)); - /* Extension fields */ for (i = 0; i < descriptor.extension.length; ++i) - type.add(Field.fromDescriptor(descriptor.extension[i], syntax)); - /* Oneofs */ for (i = 0; i < descriptor.oneofDecl.length; ++i) - type.add(OneOf.fromDescriptor(descriptor.oneofDecl[i])); - /* Nested types */ for (i = 0; i < descriptor.nestedType.length; ++i) - type.add(Type.fromDescriptor(descriptor.nestedType[i], syntax)); - /* Nested enums */ for (i = 0; i < descriptor.enumType.length; ++i) - type.add(Enum.fromDescriptor(descriptor.enumType[i])); - /* Extension ranges */ if (descriptor.extensionRange.length) { + /* Fields */ if (descriptor.field) + for (i = 0; i < descriptor.field.length; ++i) + type.add(Field.fromDescriptor(descriptor.field[i], syntax)); + /* Extension fields */ if (descriptor.extension) + for (i = 0; i < descriptor.extension.length; ++i) + type.add(Field.fromDescriptor(descriptor.extension[i], syntax)); + /* Oneofs */ if (descriptor.oneofDecl) + for (i = 0; i < descriptor.oneofDecl.length; ++i) + type.add(OneOf.fromDescriptor(descriptor.oneofDecl[i])); + /* Nested types */ if (descriptor.nestedType) + for (i = 0; i < descriptor.nestedType.length; ++i) { + type.add(Type.fromDescriptor(descriptor.nestedType[i], syntax)); + if (descriptor.nestedType[i].options && descriptor.nestedType[i].options.mapEntry) + type.setOption("map_entry", true); + } + /* Nested enums */ if (descriptor.enumType) + for (i = 0; i < descriptor.enumType.length; ++i) + type.add(Enum.fromDescriptor(descriptor.enumType[i])); + /* Extension ranges */ if (descriptor.extensionRange && descriptor.extensionRange.length) { type.extensions = []; for (i = 0; i < descriptor.extensionRange.length; ++i) type.extensions.push([ descriptor.extensionRange[i].start, descriptor.extensionRange[i].end ]); } - /* Reserved ranges and names */ if (descriptor.reservedRange.length || descriptor.reservedName.length) { + /* Reserved... */ if (descriptor.reservedRange && descriptor.reservedRange.length || descriptor.reservedName && descriptor.reservedName.length) { type.reserved = []; - for (i = 0; i < descriptor.reservedRange.length; ++i) - type.reserved.push([ descriptor.reservedRange[i].start, descriptor.reservedRange[i].end ]); - for (i = 0; i < descriptor.reservedName.length; ++i) - type.reserved.push(descriptor.reservedName[i]); + /* Ranges */ if (descriptor.reservedRange) + for (i = 0; i < descriptor.reservedRange.length; ++i) + type.reserved.push([ descriptor.reservedRange[i].start, descriptor.reservedRange[i].end ]); + /* Names */ if (descriptor.reservedName) + for (i = 0; i < descriptor.reservedName.length; ++i) + type.reserved.push(descriptor.reservedName[i]); } return type; @@ -197,8 +219,24 @@ Type.prototype.toDescriptor = function toDescriptor(syntax) { var descriptor = google.DescriptorProto.create({ name: this.name }), i; - /* Fields */ for (i = 0; i < this.fieldsArray.length; ++i) + /* Fields */ for (i = 0; i < this.fieldsArray.length; ++i) { descriptor.field.push(this._fieldsArray[i].toDescriptor(syntax)); + if (this._fieldsArray[i] instanceof MapField) { // map fields are repeated FieldNameEntry + var keyType = toDescriptorType(this._fieldsArray[i].keyType, this._fieldsArray[i].resolvedKeyType), + valueType = toDescriptorType(this._fieldsArray[i].type, this._fieldsArray[i].resolvedType), + valueTypeName = valueType === 11 || valueType === 14 + ? this._fieldsArray[i].resolvedType && this._fieldsArray[i].resolvedType.fullName || this._fieldsArray[i].type + : undefined; + descriptor.nestedType.push(google.DescriptorProto.create({ + name: descriptor.field[descriptor.field.length - 1].type_name, + field: [ + google.FieldDescriptorProto.create({ name: "key", number: 1, label: 1, type: keyType }), // can't be message + google.FieldDescriptorProto.create({ name: "value", number: 2, label: 1, type: valueType, typeName: valueTypeName }) + ], + options: google.MessageOptions({ mapEntry: true }) + })); + } + } /* Nested... */ for (i = 0; i < this.nestedArray.length; ++i) { /* Extension fields */ if (this._nestedArray[i] instanceof Field) descriptor.field.push(this._nestedArray[i].toDescriptor(syntax)); @@ -208,15 +246,20 @@ Type.prototype.toDescriptor = function toDescriptor(syntax) { descriptor.nestedType.push(this._nestedArray[i].toDescriptor(syntax)); /* Enums */ else if (this._nestedArray[i] instanceof Enum) descriptor.enumType.push(this._nestedArray[i].toDescriptor()); - // descriptor doesn't use / support plain nested namespaces + // plain nested namespaces become packages instead in Root#toDescriptor } - /* Extension ranges */ if (this.extensions) for (i = 0; i < this.extensions.length; ++i) - descriptor.extensionRange.push(google.DescriptorProto.ExtensionRange.create({ start: this.extensions[i][0], end: this.extensions[i][1] })); - /* Reserved ranges and names */ if (this.reserved) for (i = 0; i < this.reserved.length; ++i) - if (typeof this.reserved[i] === "string") - descriptor.reservedName.push(this.reserved[i]); - else - descriptor.reservedRange.push(google.DescriptorProto.ReservedRange.create({ start: this.reserved[i][0], end: this.reserved[i][1] })); + /* Extension ranges */ if (this.extensions) + for (i = 0; i < this.extensions.length; ++i) + descriptor.extensionRange.push(google.DescriptorProto.ExtensionRange.create({ start: this.extensions[i][0], end: this.extensions[i][1] })); + /* Reserved... */ if (this.reserved) + for (i = 0; i < this.reserved.length; ++i) + /* Names */ if (typeof this.reserved[i] === "string") + descriptor.reservedName.push(this.reserved[i]); + /* Ranges */ else + descriptor.reservedRange.push(google.DescriptorProto.ReservedRange.create({ start: this.reserved[i][0], end: this.reserved[i][1] })); + + if (this.options && this.options.map_entry) + descriptor.options = google.MessageOptions.create({ map_entry: true }); return descriptor; }; @@ -224,28 +267,33 @@ Type.prototype.toDescriptor = function toDescriptor(syntax) { // --- Field --- /** + * Properties of a FieldDescriptorProto message. * @interface IFieldDescriptorProto - * @property {string} [name] - * @property {number} [number] - * @property {IFieldDescriptorProto_Label} [label] - * @property {IFieldDescriptorProto_Type} [type] - * @property {string} [typeName] - * @property {string} [extendee] - * @property {*} [defaultValue] - * @property {number} [oneofIndex] - * @property {*} [jsonName] - * @property {IFieldOptions} [options] + * @property {string} [name] Field name + * @property {number} [number] Field id + * @property {IFieldDescriptorProto_Label} [label] Field rule + * @property {IFieldDescriptorProto_Type} [type] Field basic type + * @property {string} [typeName] Field type name + * @property {string} [extendee] Extended type name + * @property {*} [defaultValue] Not supported + * @property {number} [oneofIndex] Oneof index if part of a oneof + * @property {*} [jsonName] Not supported + * @property {IFieldOptions} [options] Field options + * @see Part of the {@link descriptor} extension (ext/descriptor) */ /** + * Values of the FieldDescriptorProto.Label enum. * @typedef IFieldDescriptorProto_Label * @type {number} * @property {number} LABEL_OPTIONAL=1 * @property {number} LABEL_REQUIRED=2 * @property {number} LABEL_REPEATED=3 + * @see Part of the {@link descriptor} extension (ext/descriptor) */ /** + * Values of the FieldDescriptorProto.Type enum. * @typedef IFieldDescriptorProto_Type * @type {number} * @property {number} TYPE_DOUBLE=1 @@ -266,13 +314,39 @@ Type.prototype.toDescriptor = function toDescriptor(syntax) { * @property {number} TYPE_SFIXED64=16 * @property {number} TYPE_SINT32=17 * @property {number} TYPE_SINT64=18 + * @see Part of the {@link descriptor} extension (ext/descriptor) */ /** + * Properties of a FieldOptions message. * @interface IFieldOptions - * @property {boolean} [packed] + * @property {boolean} [packed] Whether packed or not (defaults to `false` for proto2 and `true` for proto3) + * @see Part of the {@link descriptor} extension (ext/descriptor) */ +// Converts a descriptor type to a protobuf.js basic type +function fromDescriptorType(type) { + switch (type) { + // 0 is reserved for errors + case 1: return "double"; + case 2: return "float"; + case 3: return "int64"; + case 4: return "uint64"; + case 5: return "int32"; + case 6: return "fixed64"; + case 7: return "fixed32"; + case 8: return "bool"; + case 9: return "string"; + case 12: return "bytes"; + case 13: return "uint32"; + case 15: return "sfixed32"; + case 16: return "sfixed64"; + case 17: return "sint32"; + case 18: return "sint64"; + } + throw Error("illegal type: " + descriptor.type); +} + /** * Creates a field from a descriptor. * @param {IFieldDescriptorProto|Reader|Uint8Array} descriptor Descriptor @@ -286,32 +360,15 @@ Field.fromDescriptor = function fromDescriptor(descriptor, syntax) { if (typeof descriptor.length === "number") descriptor = google.DescriptorProto.decode(descriptor); + if (typeof descriptor.number !== "number") + throw Error("missing field id"); + // Rewire field type var fieldType; - if (descriptor.typeName.length) + if (descriptor.typeName && descriptor.typeName.length) fieldType = descriptor.typeName; - else switch (descriptor.type) { - // 0 is reserved for errors - case 1: fieldType = "double"; break; - case 2: fieldType = "float"; break; - case 3: fieldType = "int64"; break; - case 4: fieldType = "uint64"; break; - case 5: fieldType = "int32"; break; - case 6: fieldType = "fixed64"; break; - case 7: fieldType = "fixed32"; break; - case 8: fieldType = "bool"; break; - case 9: fieldType = "string"; break; - case 10: throw Error("unnamed group"); - case 11: throw Error("unnamed message"); - case 12: fieldType = "bytes"; break; - case 13: fieldType = "uint32"; break; - case 14: throw Error("unnamed enum"); - case 15: fieldType = "sfixed32"; break; - case 16: fieldType = "sfixed64"; break; - case 17: fieldType = "sint32"; break; - case 18: fieldType = "sint64"; break; - default: throw Error("illegal type: " + descriptor.type); - } + else + fieldType = fromDescriptorType(descriptor.type); // Rewire field rule var fieldRule; @@ -331,15 +388,42 @@ Field.fromDescriptor = function fromDescriptor(descriptor, syntax) { descriptor.extendee.length ? descriptor.extendee : undefined ); - if (syntax === "proto3") { + if (syntax === "proto3") { // defaults to packed=true (internal preset is packed=true) if (descriptor.options && !descriptor.options.packed) field.setOption("packed", false); - } else if (!(descriptor.options && descriptor.options.packed)) + } else if (!(descriptor.options && descriptor.options.packed)) // defaults to packed=false field.setOption("packed", false); return field; }; +// Converts a protobuf.js basic type to a descriptor type +function toDescriptorType(type, resolvedType) { + switch (type) { + // 0 is reserved for errors + case "double": return 1; + case "float": return 2; + case "int64": return 3; + case "uint64": return 4; + case "int32": return 5; + case "fixed64": return 6; + case "fixed32": return 7; + case "bool": return 8; + case "string": return 9; + case "bytes": return 12; + case "uint32": return 13; + case "sfixed32": return 15; + case "sfixed64": return 16; + case "sint32": return 17; + case "sint64": return 18; + } + if (resolvedType instanceof Enum) + return 14; + if (resolvedType instanceof Type) + return resolvedType.group ? 10 : 11; + throw Error("illegal type: " + type); +} + /** * Converts a field to a descriptor. * @returns {Message} Descriptor @@ -349,39 +433,30 @@ Field.fromDescriptor = function fromDescriptor(descriptor, syntax) { Field.prototype.toDescriptor = function toDescriptor(syntax) { var descriptor = google.FieldDescriptorProto.create({ name: this.name, number: this.id }); - // Rewire field type - switch (this.type) { - case "double": descriptor.type = 1; break; - case "float": descriptor.type = 2; break; - case "int64": descriptor.type = 3; break; - case "uint64": descriptor.type = 4; break; - case "int32": descriptor.type = 5; break; - case "fixed64": descriptor.type = 6; break; - case "fixed32": descriptor.type = 7; break; - case "bool": descriptor.type = 8; break; - case "string": descriptor.type = 9; break; - case "bytes": descriptor.type = 12; break; - case "uint32": descriptor.type = 13; break; - case "sfixed32": descriptor.type = 15; break; - case "sfixed64": descriptor.type = 16; break; - case "sint32": descriptor.type = 17; break; - case "sint64": descriptor.type = 18; break; - default: - descriptor.type_name = this.resolvedType ? this.resolvedType.fullName : this.type; - if (this.resolvedType instanceof Enum) - descriptor.type = 14; - else if (this.resolvedType instanceof Type) - descriptor.type = this.resolvedType.group ? 10 : 11; - else - throw Error("illegal type: " + this.type); - break; - } + if (this.map) { + + descriptor.type = 11; // message + descriptor.type_name = $protobuf.util.ucFirst(this.name); // fieldName -> FieldNameEntry (built in Type#toDescriptor) + descriptor.label = 3; // repeated + + } else { + + // Rewire field type + switch (descriptor.type = toDescriptorType(this.type, this.resolve().resolvedType)) { + case 10: // group + case 11: // type + case 14: // enum + descriptor.type_name = this.resolvedType ? this.resolvedType.fullName : this.type; + break; + } + + // Rewire field rule + switch (this.rule) { + case "repeated": descriptor.label = 3; break; + case "required": descriptor.label = 2; break; + default: descriptor.label = 1; break; + } - // Rewire field rule - switch (this.rule) { - case "repeated": descriptor.label = 3; break; - case "required": descriptor.label = 2; break; - default: descriptor.label = 1; break; } // Handle extension field @@ -392,10 +467,10 @@ Field.prototype.toDescriptor = function toDescriptor(syntax) { if ((descriptor.oneofIndex = this.parent.oneofsArray.indexOf(this.partOf)) < 0) throw Error("missing oneof"); - if (syntax === "proto3") { + if (syntax === "proto3") { // defaults to packed=true if (!this.packed) descriptor.options = google.FieldOptions.create({ packed: false }); - } else if (this.packed) + } else if (this.packed) // defaults to packed=false descriptor.options = google.FieldOptions.create({ packed: true }); return descriptor; @@ -404,22 +479,28 @@ Field.prototype.toDescriptor = function toDescriptor(syntax) { // --- Enum --- /** + * Properties of an EnumDescriptorProto message. * @interface IEnumDescriptorProto - * @property {string} [name] - * @property {IEnumValueDescriptorProto[]} [value] - * @property {IEnumOptions} [options] + * @property {string} [name] Enum name + * @property {IEnumValueDescriptorProto[]} [value] Enum values + * @property {IEnumOptions} [options] Enum options + * @see Part of the {@link descriptor} extension (ext/descriptor) */ /** + * Properties of an EnumValueDescriptorProto message. * @interface IEnumValueDescriptorProto - * @property {string} [name] - * @property {number} [number] - * @property {*} [options] + * @property {string} [name] Name + * @property {number} [number] Value + * @property {*} [options] Not supported + * @see Part of the {@link descriptor} extension (ext/descriptor) */ /** + * Properties of an EnumOptions message. * @interface IEnumOptions - * @property {boolean} [allowAlias] + * @property {boolean} [allowAlias] Whether aliases are allowed + * @see Part of the {@link descriptor} extension (ext/descriptor) */ var unnamedEnumIndex = 0; @@ -436,7 +517,7 @@ Enum.fromDescriptor = function fromDescriptor(descriptor) { if (typeof descriptor.length === "number") descriptor = google.EnumDescriptorProto.decode(descriptor); - // Values object + // Construct values object var values = {}; if (descriptor.value) for (var i = 0; i < descriptor.value.length; ++i) { @@ -461,7 +542,7 @@ Enum.prototype.toDescriptor = function toDescriptor() { for (var i = 0, ks = Object.keys(this.values), valueDescriptor; i < ks.length; ++i) { values.push(valueDescriptor = google.EnumValueDescriptorProto.create({ name: ks[i] })); - if (this.values[ks[i]]) + if (this.values[ks[i]]) // is 0 actually omitted? valueDescriptor.value = this.values[ks[i]]; } return google.EnumDescriptorProto.create({ @@ -473,12 +554,14 @@ Enum.prototype.toDescriptor = function toDescriptor() { // --- OneOf --- /** + * Properties of a OneofDescriptorProto message. * @interface IOneofDescriptorProto - * @property {string} [name] - * @property {*} [options] + * @property {string} [name] Oneof name + * @property {*} [options] Not supported + * @see Part of the {@link descriptor} extension (ext/descriptor) */ -var unnamedOneOfIndex = 0; +var unnamedOneofIndex = 0; /** * Creates a oneof from a descriptor. @@ -494,7 +577,7 @@ OneOf.fromDescriptor = function fromDescriptor(descriptor) { return new OneOf( // unnamedOneOfIndex is global, not per type, because we have no ref to a type here - descriptor.name && descriptor.name.length ? descriptor.name : "oneof" + unnamedOneOfIndex++ + descriptor.name && descriptor.name.length ? descriptor.name : "oneof" + unnamedOneofIndex++ ); }; @@ -512,10 +595,12 @@ OneOf.prototype.toDescriptor = function toDescriptor() { // --- Service --- /** + * Properties of a ServiceDescriptorProto message. * @interface IServiceDescriptorProto - * @property {string} [name] - * @property {IMethodDescriptorProto[]} [method] - * @property {*} [options] + * @property {string} [name] Service name + * @property {IMethodDescriptorProto[]} [method] Methods + * @property {*} [options] Not supported + * @see Part of the {@link descriptor} extension (ext/descriptor) */ var unnamedServiceIndex = 0; @@ -546,8 +631,9 @@ Service.fromDescriptor = function fromDescriptor(descriptor) { * @see Part of the {@link descriptor} extension (ext/descriptor) */ Service.prototype.toDescriptor = function toDescriptor() { - var methods = []; + // Methods + var methods = []; for (var i = 0; i < this.methodsArray; ++i) methods.push(this._methodsArray[i].toDescriptor()); @@ -560,13 +646,15 @@ Service.prototype.toDescriptor = function toDescriptor() { // --- Method --- /** + * Properties of a MethodDescriptorProto message. * @interface IMethodDescriptorProto - * @property {string} [name] - * @property {string} [inputType] - * @property {string} [outputType] - * @property {*} [options] - * @property {boolean} [clientStreaming] - * @property {boolean} [serverStreaming] + * @property {string} [name] Method name + * @property {string} [inputType] Request type name + * @property {string} [outputType] Response type name + * @property {*} [options] Not supported + * @property {boolean} [clientStreaming=false] Whether requests are streamed + * @property {boolean} [serverStreaming=false] Whether responses are streamed + * @see Part of the {@link descriptor} extension (ext/descriptor) */ var unnamedMethodIndex = 0;