Permalink
Browse files

Other: Added infrastructure for TypeScript support of extensions

  • Loading branch information...
dcodeIO committed Apr 12, 2017
1 parent 57d7d35 commit 708552bb84508364b6e6fdf73906aa69e83854e1
@@ -393,7 +393,6 @@ function notAModuleReference(ref) {
return ref.indexOf("module:") === -1;
}
// handles a class or class-like
function handleClass(element, parent) {
var is_interface = isInterface(element);
@@ -367,7 +367,7 @@ function buildType(ref, type) {
"@constructor",
"@param {" + fullName + "$Properties=} [" + (config.beautify ? "properties" : "p") + "] Properties to set"
]);
buildFunction(type, type.name, Class.generate(type));
buildFunction(type, type.name, Type.generateConstructor(type));
// default values
var firstField = true;
@@ -0,0 +1,21 @@
protobufjs/ext/descriptor
=========================
Experimental [protobuf.js](https://github.com/dcodeIO/protobuf.js) extension for interoperability with descriptor.proto types.
Usage
-----
```js
var protobuf = require("protobufjs"),
descriptor = require("protobufjs/ext/descriptor");
var descriptor = ...; // either a FieldDescriptorSet buffer or JSON object
var root = protobuf.Root.fromDescriptor(descriptor);
var rootDescriptor = root.toDescriptor("proto3");
```
API
---
The extension adds `.fromDescriptor(descriptor[, syntax])` and `#toDescriptor([syntax])` methods to reflection objects and exports the internally used `Root` instance that contains the types present in descriptor.proto.
@@ -0,0 +1,108 @@
import * as $protobuf from "../..";
declare const descriptor: $protobuf.Root;
interface IFileDescriptorSet {
file: IFileDescriptorProto[];
}
interface IFileDescriptorProto {
name?: string;
package?: string;
dependency?: any;
publicDependency?: any;
weakDependency?: any;
messageType?: IDescriptorProto[];
enumType?: IEnumDescriptorProto[];
service?: IServiceDescriptorProto[];
extension?: IFieldDescriptorProto[];
options?: any;
sourceCodeInfo?: any;
syntax?: string;
}
interface IDescriptorProto {
name?: string;
field?: IFieldDescriptorProto[];
extension?: IFieldDescriptorProto[];
nestedType?: IDescriptorProto[];
enumType?: IEnumDescriptorProto[];
extensionRange?: IExtensionRange[];
oneofDecl?: IOneofDescriptorProto[];
options?: IMessageOptions;
reservedRange?: IReservedRange[];
reservedName?: string[];
}
interface IMessageOptions {
mapEntry?: any;
}
interface IExtensionRange {
start?: number;
end?: number;
}
interface IReservedRange {
start?: number;
end?: number;
}
interface IFieldDescriptorProto {
name?: string;
number?: number;
label?: IFieldDescriptorProto_Label;
type?: IFieldDescriptorProto_Type;
typeName?: string;
extendee?: string;
defaultValue?: any;
oneofIndex?: number;
jsonName?: any;
options?: IFieldOptions;
}
type IFieldDescriptorProto_Label = number;
type IFieldDescriptorProto_Type = number;
interface IFieldOptions {
packed?: boolean;
}
interface IEnumDescriptorProto {
name?: string;
value?: IEnumValueDescriptorProto[];
options?: IEnumOptions;
}
interface IEnumValueDescriptorProto {
name?: string;
number?: number;
options?: any;
}
interface IEnumOptions {
allowAlias?: boolean;
}
interface IOneofDescriptorProto {
name?: string;
options?: any;
}
interface IServiceDescriptorProto {
name?: string;
method?: IMethodDescriptorProto[];
options?: any;
}
interface IMethodDescriptorProto {
name?: string;
inputType?: string;
outputType?: string;
options?: any;
clientStreaming?: boolean;
serverStreaming?: boolean;
}
export = descriptor;
@@ -1,35 +1,26 @@
// [WIP] Extension for reflection interoperability with descriptor.proto types
// var protobuf = require("protobufjs"),
// descriptor = require("protobufjs/ext/descriptor");
// ...
"use strict";
var protobuf = require("..");
var $protobuf = require("..");
/**
* Descriptor extension (ext/descriptor).
* @namespace
* @type {Root}
* @tstype $protobuf.Root
* @const
*/
var descriptor = module.exports = protobuf.Root.fromJSON(require("../google/protobuf/descriptor.json")).lookup(".google.protobuf");
var descriptor = module.exports = $protobuf.Root.fromJSON(require("../google/protobuf/descriptor.json")).lookup(".google.protobuf");
var google = descriptor,
Root = protobuf.Root,
Enum = protobuf.Enum,
Type = protobuf.Type,
Field = protobuf.Field,
OneOf = protobuf.OneOf,
Service = protobuf.Service,
Method = protobuf.Method;
Root = $protobuf.Root,
Enum = $protobuf.Enum,
Type = $protobuf.Type,
Field = $protobuf.Field,
OneOf = $protobuf.OneOf,
Service = $protobuf.Service,
Method = $protobuf.Method;
// --- Root ---
/**
* Reflected type describing a root.
* @name descriptor.FileDescriptorSet
* @type {Type}
*/
/**
* @interface IFileDescriptorSet
* @property {IFileDescriptorProto[]} file
@@ -118,12 +109,6 @@ Root.prototype.toDescriptor = function toDescriptor(syntax) {
// --- Type ---
/**
* Reflected type describing a type.
* @name descriptor.DescriptorProto
* @type {Type}
*/
/**
* @interface IDescriptorProto
* @property {string} [name]
@@ -175,15 +160,15 @@ Type.fromDescriptor = function fromDescriptor(descriptor, syntax) {
i;
/* Fields */ for (i = 0; i < descriptor.field.length; ++i)
type.add(protobuf.Field.fromDescriptor(descriptor.field[i], syntax));
type.add(Field.fromDescriptor(descriptor.field[i], syntax));
/* Extension fields */ for (i = 0; i < descriptor.extension.length; ++i)
type.add(protobuf.Field.fromDescriptor(descriptor.extension[i], syntax));
type.add(Field.fromDescriptor(descriptor.extension[i], syntax));
/* Oneofs */ for (i = 0; i < descriptor.oneofDecl.length; ++i)
type.add(protobuf.OneOf.fromDescriptor(descriptor.oneofDecl[i]));
type.add(OneOf.fromDescriptor(descriptor.oneofDecl[i]));
/* Nested types */ for (i = 0; i < descriptor.nestedType.length; ++i)
type.add(protobuf.Type.fromDescriptor(descriptor.nestedType[i], syntax));
type.add(Type.fromDescriptor(descriptor.nestedType[i], syntax));
/* Nested enums */ for (i = 0; i < descriptor.enumType.length; ++i)
type.add(protobuf.Enum.fromDescriptor(descriptor.enumType[i]));
type.add(Enum.fromDescriptor(descriptor.enumType[i]));
/* Extension ranges */ if (descriptor.extensionRange.length) {
type.extensions = [];
for (i = 0; i < descriptor.extensionRange.length; ++i)
@@ -236,18 +221,10 @@ Type.prototype.toDescriptor = function toDescriptor(syntax) {
// --- Field ---
/**
* Reflected type describing a field.
* @name descriptor.FieldDescriptorProto
* @type {Type}
* @property {Enum} Label Reflected descriptor describing a field label (rule)
* @property {Enum} Type Reflected descriptor describing a field type
*/
/**
* @interface IFieldDescriptorProto
* @property {string} [name]
* @property {number} [number}
* @property {number} [number]
* @property {IFieldDescriptorProto_Label} [label]
* @property {IFieldDescriptorProto_Type} [type]
* @property {string} [typeName]
@@ -424,24 +401,6 @@ Field.prototype.toDescriptor = function toDescriptor(syntax) {
// --- Enum ---
/**
* Reflected type describing an enum.
* @name descriptor.EnumDescriptorProto
* @type {Type}
*/
/**
* Reflected type describing an enum value.
* @name descriptor.EnumValueDescriptorProto
* @type {Type}
*/
/**
* Reflected type describing enum options.
* @name descriptor.EnumOptions
* @type {Type}
*/
/**
* @interface IEnumDescriptorProto
* @property {string} [name]
@@ -511,12 +470,6 @@ Enum.prototype.toDescriptor = function toDescriptor() {
// --- OneOf ---
/**
* Reflected type describing a oneof.
* @name descriptor.OneofDescriptorProto
* @type {Type}
*/
/**
* @interface IOneofDescriptorProto
* @property {string} [name]
@@ -556,12 +509,6 @@ OneOf.prototype.toDescriptor = function toDescriptor() {
// --- Service ---
/**
* Reflected type describing a service.
* @name descriptor.ServiceDescriptorProto
* @type {Type}
*/
/**
* @interface IServiceDescriptorProto
* @property {string} [name]
@@ -610,12 +557,6 @@ Service.prototype.toDescriptor = function toDescriptor() {
// --- Method ---
/**
* Reflected type describing a method.
* @name descriptor.MethodDescriptorProto
* @type {Type}
*/
/**
* @interface IMethodDescriptorProto
* @property {string} [name]
@@ -1719,6 +1719,13 @@ export class Type extends NamespaceBase {
*/
public ctor: Constructor<{}>;
/**
* Generates a constructor function for the specified type.
* @param {Type} type Type
* @returns {Codegen} Codegen instance
*/
public static generateConstructor(type: Type): Codegen;
/**
* Creates a message type from a message type descriptor.
* @param {string} name Message name
@@ -42,10 +42,11 @@ var fs = require("fs"),
});
[
"tests/data/rpc.js",
"tests/data/test.js",
{ file: "tests/data/rpc.js" },
{ file: "tests/data/test.js" },
{ file: "ext/descriptor/index.js", ext: true }
]
.forEach(function(file) {
.forEach(function({ file, ext }) {
var out = file.replace(/\.js$/, ".d.ts");
pbts.main([
"--no-comments",
@@ -54,7 +55,13 @@ var fs = require("fs"),
if (err)
throw err;
var pathToProtobufjs = path.relative(path.dirname(out), "").replace(/\\/g, "/");
fs.writeFileSync(out, output.replace(/"protobufjs"/g, JSON.stringify(pathToProtobufjs)));
output = output.replace(/"protobufjs"/g, JSON.stringify(pathToProtobufjs));
if (ext) {
var extName;
output = output.replace(/export (\w+) (\w+)/, function($0, $1, $2) { extName = $2; return "declare " + $1 + " " + extName; });
output += "\nexport = " + extName + ";\n";
}
fs.writeFileSync(out, output);
process.stdout.write("pbts: " + file + " -> " + out + "\n");
});
});
});
@@ -152,7 +152,7 @@ Object.defineProperties(Type.prototype, {
*/
ctor: {
get: function() {
return this._ctor || (this.ctor = generateConstructor(this).eof(this.name));
return this._ctor || (this.ctor = Type.generateConstructor(this).eof(this.name));
},
set: function(ctor) {
@@ -189,7 +189,12 @@ Object.defineProperties(Type.prototype, {
}
});
function generateConstructor(type) {
/**
* Generates a constructor function for the specified type.
* @param {Type} type Type
* @returns {Codegen} Codegen instance
*/
Type.generateConstructor = function generateConstructor(type) {
/* eslint-disable no-unexpected-multiline */
var gen = util.codegen("p");
// explicitly initialize mutable object/array fields so that these aren't just inherited from the prototype
@@ -202,7 +207,7 @@ function generateConstructor(type) {
("if(p)for(var ks=Object.keys(p),i=0;i<ks.length;++i)if(p[ks[i]]!=null)") // omit undefined or null
("this[ks[i]]=p[ks[i]]");
/* eslint-enable no-unexpected-multiline */
}
};
function clearCache(type) {
type._fieldsById = type._fieldsArray = type._oneofsArray = type._ctor = null;
Oops, something went wrong.

0 comments on commit 708552b

Please sign in to comment.