Bump artifact dependencies if CODEQL_ACTION_ARTIFACT_V2_UPGRADE enabled (#2482)

Co-authored-by: Andrew Eisenberg <aeisenberg@github.com>
Co-authored-by: Henry Mercer <henrymercer@github.com>
This commit is contained in:
Angela P Wen 2024-10-01 09:59:05 -07:00 committed by GitHub
parent cf5b0a9041
commit a196a714b8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5388 changed files with 2176737 additions and 71701 deletions

View file

@ -0,0 +1,48 @@
import * as ts from "typescript";
import { AnyDescriptorProto, DescriptorRegistry } from "@protobuf-ts/plugin-framework";
export declare class CommentGenerator {
private readonly registry;
constructor(registry: DescriptorRegistry);
/**
* Adds comments from the .proto as a JSDoc block.
*
* Looks up comments for the given descriptor in
* the source code info.
*
* Adds `@deprecated` tag if the element is
* marked deprecated. Also adds @deprecated if
* the descriptor is a type (enum, message) and
* the entire .proto file is marked deprecated.
*
* Adds `@generated` tag with source code
* information.
*
* Leading detached comments are added as line
* comments in front of the JSDoc block.
*
* Trailing comments are a bit weird. For .proto
* enums and messages, they sit between open
* bracket and first member. A message seems to
* only ever have a trailing comment if it is
* empty. For a simple solution, trailing
* comments on enums and messages should simply
* be appended to the leading block so that the
* information is not discarded.
*/
addCommentsForDescriptor(node: ts.Node, descriptor: AnyDescriptorProto, trailingCommentsMode: 'appendToLeadingBlock' | 'trailingLines'): void;
/**
* Returns a block of source comments (no leading detached!),
* with @generated tags and @deprecated tag (if applicable).
*/
getCommentBlock(descriptor: AnyDescriptorProto, appendTrailingComments?: boolean): string;
/**
* Returns "@deprecated\n" if explicitly deprecated.
* For top level types, also returns "@deprecated\n" if entire file is deprecated.
* Otherwise, returns "".
*/
makeDeprecatedTag(descriptor: AnyDescriptorProto): "" | "@deprecated\n";
/**
* Creates string like "@generated from protobuf field: string foo = 1;"
*/
makeGeneratedTag(descriptor: AnyDescriptorProto): string;
}

View file

@ -0,0 +1,117 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CommentGenerator = void 0;
const ts = require("typescript");
const plugin_framework_1 = require("@protobuf-ts/plugin-framework");
class CommentGenerator {
constructor(registry) {
this.registry = registry;
}
/**
* Adds comments from the .proto as a JSDoc block.
*
* Looks up comments for the given descriptor in
* the source code info.
*
* Adds `@deprecated` tag if the element is
* marked deprecated. Also adds @deprecated if
* the descriptor is a type (enum, message) and
* the entire .proto file is marked deprecated.
*
* Adds `@generated` tag with source code
* information.
*
* Leading detached comments are added as line
* comments in front of the JSDoc block.
*
* Trailing comments are a bit weird. For .proto
* enums and messages, they sit between open
* bracket and first member. A message seems to
* only ever have a trailing comment if it is
* empty. For a simple solution, trailing
* comments on enums and messages should simply
* be appended to the leading block so that the
* information is not discarded.
*/
addCommentsForDescriptor(node, descriptor, trailingCommentsMode) {
const source = this.registry.sourceCodeComments(descriptor);
// add leading detached comments as line comments
plugin_framework_1.addCommentBlocksAsLeadingDetachedLines(node, ...source.leadingDetached);
// start with leading block
let leading = this.getCommentBlock(descriptor, trailingCommentsMode === "appendToLeadingBlock");
// add leading block as jsdoc comment block
plugin_framework_1.addCommentBlockAsJsDoc(node, leading);
// add trailing comments as trailing line comments
if (source.trailing && trailingCommentsMode === 'trailingLines') {
let lines = source.trailing.split('\n').map(l => l[0] !== ' ' ? ` ${l}` : l);
for (let line of lines) {
ts.addSyntheticTrailingComment(node, ts.SyntaxKind.SingleLineCommentTrivia, line, true);
}
}
}
/**
* Returns a block of source comments (no leading detached!),
* with @generated tags and @deprecated tag (if applicable).
*/
getCommentBlock(descriptor, appendTrailingComments = false) {
var _a;
const source = this.registry.sourceCodeComments(descriptor);
// start with leading block
let commentBlock = (_a = source.leading) !== null && _a !== void 0 ? _a : '';
// add trailing comments to the leading block
if (source.trailing && appendTrailingComments) {
if (commentBlock.length > 0) {
commentBlock += '\n\n';
}
commentBlock += source.trailing;
}
// if there were any leading comments, we need some space
if (commentBlock.length > 0) {
commentBlock += '\n\n';
}
// add deprecated information to the leading block
commentBlock += this.makeDeprecatedTag(descriptor);
// add source info to the leading block
commentBlock += this.makeGeneratedTag(descriptor);
return commentBlock;
}
/**
* Returns "@deprecated\n" if explicitly deprecated.
* For top level types, also returns "@deprecated\n" if entire file is deprecated.
* Otherwise, returns "".
*/
makeDeprecatedTag(descriptor) {
let deprecated = this.registry.isExplicitlyDeclaredDeprecated(descriptor);
if (!deprecated && plugin_framework_1.isAnyTypeDescriptorProto(descriptor)) {
// an entire .proto file can be marked deprecated.
// this means all types within are deprecated.
// we mark them as deprecated, but dont touch members.
deprecated = this.registry.isExplicitlyDeclaredDeprecated(this.registry.fileOf(descriptor));
}
if (deprecated) {
return '@deprecated\n';
}
return '';
}
/**
* Creates string like "@generated from protobuf field: string foo = 1;"
*/
makeGeneratedTag(descriptor) {
if (plugin_framework_1.OneofDescriptorProto.is(descriptor)) {
return `@generated from protobuf oneof: ${descriptor.name}`;
}
else if (plugin_framework_1.EnumValueDescriptorProto.is(descriptor)) {
return `@generated from protobuf enum value: ${this.registry.formatEnumValueDeclaration(descriptor)}`;
}
else if (plugin_framework_1.FieldDescriptorProto.is(descriptor)) {
return `@generated from protobuf field: ${this.registry.formatFieldDeclaration(descriptor)}`;
}
else if (plugin_framework_1.MethodDescriptorProto.is(descriptor)) {
return `@generated from protobuf rpc: ${this.registry.formatRpcDeclaration(descriptor)}`;
}
else {
return `@generated from protobuf ${this.registry.formatQualifiedName(descriptor)}`;
}
}
}
exports.CommentGenerator = CommentGenerator;

View file

@ -0,0 +1,50 @@
import * as ts from "typescript";
import { DescriptorRegistry, EnumDescriptorProto, SymbolTable, TypescriptFile, TypeScriptImports } from "@protobuf-ts/plugin-framework";
import { CommentGenerator } from "./comment-generator";
import { Interpreter } from "../interpreter";
import { GeneratorBase } from "./generator-base";
export declare class EnumGenerator extends GeneratorBase {
private readonly options;
constructor(symbols: SymbolTable, registry: DescriptorRegistry, imports: TypeScriptImports, comments: CommentGenerator, interpreter: Interpreter, options: {});
/**
* For the following .proto:
*
* ```proto
* enum MyEnum {
* ANY = 0;
* YES = 1;
* NO = 2;
* }
* ```
*
* We generate the following enum:
*
* ```typescript
* enum MyEnum {
* ANY = 0,
* YES = 1,
* NO = 2
* }
* ```
*
* We drop a shared prefix, for example:
*
* ```proto
* enum MyEnum {
* MY_ENUM_FOO = 0;
* MY_ENUM_BAR = 1;
* }
* ```
*
* Becomes:
*
* ```typescript
* enum MyEnum {
* FOO = 0,
* BAR = 1,
* }
* ```
*
*/
generateEnum(source: TypescriptFile, descriptor: EnumDescriptorProto): ts.EnumDeclaration;
}

View file

@ -0,0 +1,69 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EnumGenerator = void 0;
const ts = require("typescript");
const rt = require("@protobuf-ts/runtime");
const plugin_framework_1 = require("@protobuf-ts/plugin-framework");
const generator_base_1 = require("./generator-base");
class EnumGenerator extends generator_base_1.GeneratorBase {
constructor(symbols, registry, imports, comments, interpreter, options) {
super(symbols, registry, imports, comments, interpreter);
this.options = options;
}
/**
* For the following .proto:
*
* ```proto
* enum MyEnum {
* ANY = 0;
* YES = 1;
* NO = 2;
* }
* ```
*
* We generate the following enum:
*
* ```typescript
* enum MyEnum {
* ANY = 0,
* YES = 1,
* NO = 2
* }
* ```
*
* We drop a shared prefix, for example:
*
* ```proto
* enum MyEnum {
* MY_ENUM_FOO = 0;
* MY_ENUM_BAR = 1;
* }
* ```
*
* Becomes:
*
* ```typescript
* enum MyEnum {
* FOO = 0,
* BAR = 1,
* }
* ```
*
*/
generateEnum(source, descriptor) {
let enumObject = this.interpreter.getEnumInfo(descriptor)[1], builder = new plugin_framework_1.TypescriptEnumBuilder();
for (let ev of rt.listEnumValues(enumObject)) {
let evDescriptor = descriptor.value.find(v => v.number === ev.number);
let comments = evDescriptor
? this.comments.getCommentBlock(evDescriptor, true)
: "@generated synthetic value - protobuf-ts requires all enums to have a 0 value";
builder.add(ev.name, ev.number, comments);
}
let statement = builder.build(this.imports.type(source, descriptor), [ts.createModifier(ts.SyntaxKind.ExportKeyword)]);
// add to our file
source.addStatement(statement);
this.comments.addCommentsForDescriptor(statement, descriptor, 'appendToLeadingBlock');
return statement;
}
}
exports.EnumGenerator = EnumGenerator;

View file

@ -0,0 +1,32 @@
import * as rt from "@protobuf-ts/runtime";
import * as ts from "typescript";
import { DescriptorRegistry, TypescriptFile, TypeScriptImports } from "@protobuf-ts/plugin-framework";
/**
* Generates TypeScript code for runtime field information,
* from runtime field information.
*/
export declare class FieldInfoGenerator {
private readonly registry;
private readonly imports;
private readonly options;
constructor(registry: DescriptorRegistry, imports: TypeScriptImports, options: {});
createFieldInfoLiterals(source: TypescriptFile, fieldInfos: readonly rt.PartialFieldInfo[]): ts.ArrayLiteralExpression;
createFieldInfoLiteral(source: TypescriptFile, fieldInfo: rt.PartialFieldInfo): ts.ObjectLiteralExpression;
/**
* Creates the interface field / oneof name based on original proto field name and naming options.
*/
static createTypescriptLocalName(name: string, options: {
useProtoFieldName: boolean;
}): string;
/**
* Turn normalized field info returned by normalizeFieldInfo() back into
* the minimized form.
*/
private static denormalizeFieldInfo;
private createMessageT;
private createEnumT;
private createRepeatType;
private createScalarType;
private createLongType;
private createMapV;
}

View file

@ -0,0 +1,159 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FieldInfoGenerator = void 0;
const rt = require("@protobuf-ts/runtime");
const ts = require("typescript");
const plugin_framework_1 = require("@protobuf-ts/plugin-framework");
/**
* Generates TypeScript code for runtime field information,
* from runtime field information.
*/
class FieldInfoGenerator {
constructor(registry, imports, options) {
this.registry = registry;
this.imports = imports;
this.options = options;
}
createFieldInfoLiterals(source, fieldInfos) {
fieldInfos = fieldInfos.map(fi => FieldInfoGenerator.denormalizeFieldInfo(fi));
return ts.createArrayLiteral(fieldInfos.map(fi => this.createFieldInfoLiteral(source, fi)), true);
}
createFieldInfoLiteral(source, fieldInfo) {
fieldInfo = FieldInfoGenerator.denormalizeFieldInfo(fieldInfo);
let properties = [];
// no: The field number of the .proto field.
// name: The original name of the .proto field.
// kind: discriminator
// localName: The name of the field in the runtime.
// jsonName: The name of the field in JSON.
// oneof: The name of the `oneof` group, if this field belongs to one.
for (let key of ["no", "name", "kind", "localName", "jsonName", "oneof"]) {
if (fieldInfo[key] !== undefined) {
properties.push(ts.createPropertyAssignment(key, plugin_framework_1.typescriptLiteralFromValue(fieldInfo[key])));
}
}
// repeat: Is the field repeated?
if (fieldInfo.repeat !== undefined) {
properties.push(ts.createPropertyAssignment("repeat", this.createRepeatType(fieldInfo.repeat)));
}
// opt: Is the field optional?
if (fieldInfo.opt !== undefined) {
properties.push(ts.createPropertyAssignment("opt", plugin_framework_1.typescriptLiteralFromValue(fieldInfo.opt)));
}
switch (fieldInfo.kind) {
case "scalar":
// T: Scalar field type.
properties.push(ts.createPropertyAssignment("T", this.createScalarType(fieldInfo.T)));
// L?: JavaScript long type
if (fieldInfo.L !== undefined) {
properties.push(ts.createPropertyAssignment("L", this.createLongType(fieldInfo.L)));
}
break;
case "enum":
// T: Return enum field type info.
properties.push(ts.createPropertyAssignment(ts.createIdentifier('T'), this.createEnumT(source, fieldInfo.T())));
break;
case "message":
// T: Return message field type handler.
properties.push(ts.createPropertyAssignment(ts.createIdentifier('T'), this.createMessageT(source, fieldInfo.T())));
break;
case "map":
// K: Map field key type.
properties.push(ts.createPropertyAssignment("K", this.createScalarType(fieldInfo.K)));
// V: Map field value type.
properties.push(ts.createPropertyAssignment("V", this.createMapV(source, fieldInfo.V)));
break;
}
// options:
if (fieldInfo.options) {
properties.push(ts.createPropertyAssignment(ts.createIdentifier('options'), plugin_framework_1.typescriptLiteralFromValue(fieldInfo.options)));
}
return ts.createObjectLiteral(properties, false);
}
/**
* Creates the interface field / oneof name based on original proto field name and naming options.
*/
static createTypescriptLocalName(name, options) {
return options.useProtoFieldName ? name : rt.lowerCamelCase(name);
}
/**
* Turn normalized field info returned by normalizeFieldInfo() back into
* the minimized form.
*/
static denormalizeFieldInfo(info) {
let partial = Object.assign({}, info);
if (info.jsonName === rt.lowerCamelCase(info.name)) {
delete partial.jsonName;
}
if (info.localName === rt.lowerCamelCase(info.name)) {
delete partial.localName;
}
if (info.repeat === rt.RepeatType.NO) {
delete partial.repeat;
}
if (info.opt === false) {
delete partial.opt;
}
else if (info.opt === true && info.kind == "message") {
delete partial.opt;
}
return partial;
}
createMessageT(source, type) {
let descriptor = this.registry.resolveTypeName(type.typeName);
let generatedMessage = this.imports.type(source, descriptor);
return ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createIdentifier(generatedMessage));
}
createEnumT(source, ei) {
let [pbTypeName, , sharedPrefix] = ei, descriptor = this.registry.resolveTypeName(pbTypeName), generatedEnum = this.imports.type(source, descriptor), enumInfoLiteral = [
ts.createStringLiteral(pbTypeName),
ts.createIdentifier(generatedEnum),
];
if (sharedPrefix) {
enumInfoLiteral.push(ts.createStringLiteral(sharedPrefix));
}
return ts.createArrowFunction(undefined, undefined, [], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createArrayLiteral(enumInfoLiteral, false));
}
createRepeatType(type) {
const expr = ts.createNumericLiteral(type.toString());
ts.addSyntheticTrailingComment(expr, ts.SyntaxKind.MultiLineCommentTrivia, `RepeatType.${rt.RepeatType[type]}`);
return expr;
}
createScalarType(type) {
const expr = ts.createNumericLiteral(type.toString());
ts.addSyntheticTrailingComment(expr, ts.SyntaxKind.MultiLineCommentTrivia, `ScalarType.${rt.ScalarType[type]}`);
return expr;
}
createLongType(type) {
const expr = ts.createNumericLiteral(type.toString());
ts.addSyntheticTrailingComment(expr, ts.SyntaxKind.MultiLineCommentTrivia, `LongType.${rt.LongType[type]}`);
return expr;
}
// V: Map field value type.
createMapV(source, mapV) {
let T;
let L = undefined;
switch (mapV.kind) {
case "message":
T = this.createMessageT(source, mapV.T());
break;
case "enum":
T = this.createEnumT(source, mapV.T());
break;
case "scalar":
T = this.createScalarType(mapV.T);
if (mapV.L !== undefined)
L = this.createLongType(mapV.L);
break;
}
const properties = [
ts.createPropertyAssignment(ts.createIdentifier('kind'), ts.createStringLiteral(mapV.kind)),
ts.createPropertyAssignment(ts.createIdentifier('T'), T)
];
if (L) {
properties.push(ts.createPropertyAssignment(ts.createIdentifier('L'), L));
}
return ts.createObjectLiteral(properties);
}
}
exports.FieldInfoGenerator = FieldInfoGenerator;

View file

@ -0,0 +1,11 @@
import { CommentGenerator } from "./comment-generator";
import { DescriptorRegistry, SymbolTable, TypeScriptImports } from "@protobuf-ts/plugin-framework";
import { Interpreter } from "../interpreter";
export declare abstract class GeneratorBase {
protected readonly symbols: SymbolTable;
protected readonly registry: DescriptorRegistry;
protected readonly imports: TypeScriptImports;
protected readonly comments: CommentGenerator;
protected readonly interpreter: Interpreter;
protected constructor(symbols: SymbolTable, registry: DescriptorRegistry, imports: TypeScriptImports, comments: CommentGenerator, interpreter: Interpreter);
}

View file

@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GeneratorBase = void 0;
class GeneratorBase {
constructor(symbols, registry, imports, comments, interpreter) {
this.symbols = symbols;
this.registry = registry;
this.imports = imports;
this.comments = comments;
this.interpreter = interpreter;
}
}
exports.GeneratorBase = GeneratorBase;

View file

@ -0,0 +1,10 @@
import { AnyTypeDescriptorProto, IDescriptorTree } from "@protobuf-ts/plugin-framework";
/**
* Create a name for an enum, message or service.
* - ignores package
* - nested types get the names merged with '_'
* - reserved words are escaped by adding '$' at the end
* - does *not* prevent clashes, for example clash
* of merged nested name with other message name
*/
export declare function createLocalTypeName(descriptor: AnyTypeDescriptorProto, treeLookup: IDescriptorTree): string;

View file

@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createLocalTypeName = void 0;
const plugin_framework_1 = require("@protobuf-ts/plugin-framework");
const runtime_1 = require("@protobuf-ts/runtime");
// TODO in generated code, use globalThis for all types in global scope
// rationale: keywords are much less likely to change than objects in the global scope
// TODO move all code creating names into one place (see interpreter.ts for more code)
const reservedKeywords = 'break,case,catch,class,const,continue,debugger,default,delete,do,else,enum,export,extends,false,finally,for,function,if,import,in,instanceof,new,null,return,super,switch,this,throw,true,try,typeof,var,void,while,with,as,implements,interface,let,package,private,protected,public,static,yield,any,boolean,constructor,declare,get,module,require,number,set,string,symbol,type,from,of'.split(',');
const reservedTypeNames = 'object,Uint8Array,array,Array,string,String,number,Number,boolean,Boolean,bigint,BigInt'.split(',');
const escapeCharacter = '$';
/**
* Create a name for an enum, message or service.
* - ignores package
* - nested types get the names merged with '_'
* - reserved words are escaped by adding '$' at the end
* - does *not* prevent clashes, for example clash
* of merged nested name with other message name
*/
function createLocalTypeName(descriptor, treeLookup) {
// build name components for parent types
const components = [];
for (const ancestor of treeLookup.ancestorsOf(descriptor)) {
if (plugin_framework_1.FileDescriptorProto.is(ancestor)) {
continue;
}
const name = ancestor.name;
runtime_1.assert(name !== undefined);
components.push(name);
}
// add name for actual descriptor
const name = descriptor.name;
runtime_1.assert(name !== undefined);
components.push(name);
// join all components with underscore
let fullName = components.join('_');
// escape if reserved
if (reservedKeywords.includes(fullName)) {
fullName = fullName + escapeCharacter;
}
if (reservedTypeNames.includes(fullName)) {
fullName = fullName + escapeCharacter;
}
return fullName;
}
exports.createLocalTypeName = createLocalTypeName;

View file

@ -0,0 +1,65 @@
import * as ts from "typescript";
import * as rt from "@protobuf-ts/runtime";
import { DescriptorProto, DescriptorRegistry, FieldDescriptorProto, OneofDescriptorProto, SymbolTable, TypescriptFile, TypeScriptImports } from "@protobuf-ts/plugin-framework";
import { CommentGenerator } from "./comment-generator";
import { Interpreter } from "../interpreter";
import { GeneratorBase } from "./generator-base";
export declare class MessageInterfaceGenerator extends GeneratorBase {
private readonly options;
constructor(symbols: SymbolTable, registry: DescriptorRegistry, imports: TypeScriptImports, comments: CommentGenerator, interpreter: Interpreter, options: {
oneofKindDiscriminator: string;
normalLongType: rt.LongType;
});
registerSymbols(source: TypescriptFile, descriptor: DescriptorProto): void;
/**
* `message` as an interface.
*
* For the following .proto:
*
* message MyMessage {
* string str_field = 1;
* }
*
* We generate the following interface:
*
* interface MyMessage {
* strField: string;
* }
*
*/
generateMessageInterface(source: TypescriptFile, descriptor: DescriptorProto): ts.InterfaceDeclaration;
/**
* Create property signature for a protobuf field. Example:
*
* fieldName: number
*
*/
protected createFieldPropertySignature(source: TypescriptFile, fieldDescriptor: FieldDescriptorProto, fieldInfo: rt.FieldInfo): ts.PropertySignature;
/**
* `oneof` as an algebraic data type.
*
* For the following .proto:
*
* oneof result {
* int32 value = 1;
* string error = 2;
* }
*
* We generate the following property signature:
*
* result: { oneofKind: "value"; value: number; }
* | { oneofKind: "error"; error: string; }
* | { oneofKind: undefined; };
*/
protected createOneofADTPropertySignature(source: TypescriptFile, oneofDescriptor: OneofDescriptorProto): ts.PropertySignature;
/**
* Helper to find for a OneofDescriptorProto:
* [0] the message descriptor
* [1] a corresponding message type generated by the interpreter
* [2] the runtime local name of the oneof
*/
private oneofInfo;
private createScalarTypeNode;
private createMessageTypeNode;
private createEnumTypeNode;
}

View file

@ -0,0 +1,221 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageInterfaceGenerator = void 0;
const ts = require("typescript");
const rt = require("@protobuf-ts/runtime");
const runtime_1 = require("@protobuf-ts/runtime");
const plugin_framework_1 = require("@protobuf-ts/plugin-framework");
const generator_base_1 = require("./generator-base");
const local_type_name_1 = require("./local-type-name");
class MessageInterfaceGenerator extends generator_base_1.GeneratorBase {
constructor(symbols, registry, imports, comments, interpreter, options) {
super(symbols, registry, imports, comments, interpreter);
this.options = options;
}
registerSymbols(source, descriptor) {
const name = local_type_name_1.createLocalTypeName(descriptor, this.registry);
this.symbols.register(name, descriptor, source);
}
/**
* `message` as an interface.
*
* For the following .proto:
*
* message MyMessage {
* string str_field = 1;
* }
*
* We generate the following interface:
*
* interface MyMessage {
* strField: string;
* }
*
*/
generateMessageInterface(source, descriptor) {
const interpreterType = this.interpreter.getMessageType(descriptor), processedOneofs = [], // oneof groups already processed
members = []; // the interface members
for (let fieldInfo of interpreterType.fields) {
let fieldDescriptor = descriptor.field.find(fd => fd.number === fieldInfo.no);
runtime_1.assert(fieldDescriptor !== undefined);
if (fieldInfo.oneof) {
if (processedOneofs.includes(fieldInfo.oneof)) {
continue;
}
// create single property for entire oneof group
runtime_1.assert(fieldDescriptor.oneofIndex !== undefined);
let oneofDescriptor = descriptor.oneofDecl[fieldDescriptor.oneofIndex];
runtime_1.assert(oneofDescriptor !== undefined);
members.push(this.createOneofADTPropertySignature(source, oneofDescriptor));
processedOneofs.push(fieldInfo.oneof);
}
else {
// create regular properties
members.push(this.createFieldPropertySignature(source, fieldDescriptor, fieldInfo));
}
}
// export interface MyMessage { ...
const statement = ts.createInterfaceDeclaration(undefined, [ts.createModifier(ts.SyntaxKind.ExportKeyword)], this.imports.type(source, descriptor), undefined, undefined, members);
// add to our file
source.addStatement(statement);
this.comments.addCommentsForDescriptor(statement, descriptor, 'appendToLeadingBlock');
return statement;
}
/**
* Create property signature for a protobuf field. Example:
*
* fieldName: number
*
*/
createFieldPropertySignature(source, fieldDescriptor, fieldInfo) {
let type; // the property type, may be made optional or wrapped into array at the end
switch (fieldInfo.kind) {
case "scalar":
type = this.createScalarTypeNode(fieldInfo.T, fieldInfo.L);
break;
case "enum":
type = this.createEnumTypeNode(source, fieldInfo.T());
break;
case "message":
type = this.createMessageTypeNode(source, fieldInfo.T());
break;
case "map":
let keyType = fieldInfo.K === rt.ScalarType.BOOL
? ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
: this.createScalarTypeNode(fieldInfo.K, rt.LongType.STRING);
let valueType;
switch (fieldInfo.V.kind) {
case "scalar":
valueType = this.createScalarTypeNode(fieldInfo.V.T, fieldInfo.V.L);
break;
case "enum":
valueType = this.createEnumTypeNode(source, fieldInfo.V.T());
break;
case "message":
valueType = this.createMessageTypeNode(source, fieldInfo.V.T());
break;
}
type = ts.createTypeLiteralNode([
ts.createIndexSignature(undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier('key'), undefined, keyType, undefined)
], valueType)
]);
break;
default:
throw new Error("unkown kind " + fieldDescriptor.name);
}
// if repeated, wrap type into array type
if (fieldInfo.repeat) {
type = ts.createArrayTypeNode(type);
}
// if optional, add question mark
let questionToken = fieldInfo.opt ? ts.createToken(ts.SyntaxKind.QuestionToken) : undefined;
// create property
const property = ts.createPropertySignature(undefined, ts.createIdentifier(fieldInfo.localName), questionToken, type, undefined);
this.comments.addCommentsForDescriptor(property, fieldDescriptor, 'trailingLines');
return property;
}
/**
* `oneof` as an algebraic data type.
*
* For the following .proto:
*
* oneof result {
* int32 value = 1;
* string error = 2;
* }
*
* We generate the following property signature:
*
* result: { oneofKind: "value"; value: number; }
* | { oneofKind: "error"; error: string; }
* | { oneofKind: undefined; };
*/
createOneofADTPropertySignature(source, oneofDescriptor) {
const oneofCases = [], [messageDescriptor, interpreterType, oneofLocalName] = this.oneofInfo(oneofDescriptor), memberFieldInfos = interpreterType.fields.filter(fi => fi.oneof === oneofLocalName);
runtime_1.assert(oneofDescriptor !== undefined);
// create a type for each selection case
for (let fieldInfo of memberFieldInfos) {
// { oneofKind: 'fieldName' ... } part
const kindProperty = ts.createPropertySignature(undefined, ts.createIdentifier(this.options.oneofKindDiscriminator), undefined, ts.createLiteralTypeNode(ts.createStringLiteral(fieldInfo.localName)), undefined);
// { ..., fieldName: type } part
let fieldDescriptor = messageDescriptor.field.find(fd => fd.number === fieldInfo.no);
runtime_1.assert(fieldDescriptor !== undefined);
let valueProperty = this.createFieldPropertySignature(source, fieldDescriptor, fieldInfo);
// add this case
oneofCases.push(ts.createTypeLiteralNode([kindProperty, valueProperty]));
}
// case for no selection: { oneofKind: undefined; }
oneofCases.push(ts.createTypeLiteralNode([
ts.createPropertySignature(undefined, ts.createIdentifier(this.options.oneofKindDiscriminator), undefined, ts.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword), undefined)
]));
// final property signature for the oneof group, with a union type for all oneof cases
const property = ts.createPropertySignature(undefined, ts.createIdentifier(oneofLocalName), undefined, ts.createUnionTypeNode(oneofCases), undefined);
// add comments
this.comments.addCommentsForDescriptor(property, oneofDescriptor, 'appendToLeadingBlock');
return property;
}
/**
* Helper to find for a OneofDescriptorProto:
* [0] the message descriptor
* [1] a corresponding message type generated by the interpreter
* [2] the runtime local name of the oneof
*/
oneofInfo(oneofDescriptor) {
const messageDescriptor = this.registry.parentOf(oneofDescriptor);
runtime_1.assert(plugin_framework_1.DescriptorProto.is(messageDescriptor));
const interpreterType = this.interpreter.getMessageType(messageDescriptor);
const oneofIndex = messageDescriptor.oneofDecl.indexOf(oneofDescriptor);
runtime_1.assert(oneofIndex !== undefined);
const sampleFieldDescriptor = messageDescriptor.field.find(fd => fd.oneofIndex === oneofIndex);
runtime_1.assert(sampleFieldDescriptor !== undefined);
const sampleFieldInfo = interpreterType.fields.find(fi => fi.no === sampleFieldDescriptor.number);
runtime_1.assert(sampleFieldInfo !== undefined);
const oneofName = sampleFieldInfo.oneof;
runtime_1.assert(oneofName !== undefined);
return [messageDescriptor, interpreterType, oneofName];
}
createScalarTypeNode(scalarType, longType) {
switch (scalarType) {
case rt.ScalarType.BOOL:
return ts.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
case rt.ScalarType.STRING:
return ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
case rt.ScalarType.BYTES:
return ts.createTypeReferenceNode('Uint8Array', undefined);
case rt.ScalarType.DOUBLE:
case rt.ScalarType.FLOAT:
case rt.ScalarType.INT32:
case rt.ScalarType.FIXED32:
case rt.ScalarType.UINT32:
case rt.ScalarType.SFIXED32:
case rt.ScalarType.SINT32:
return ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
case rt.ScalarType.SFIXED64:
case rt.ScalarType.INT64:
case rt.ScalarType.UINT64:
case rt.ScalarType.FIXED64:
case rt.ScalarType.SINT64:
switch (longType !== null && longType !== void 0 ? longType : rt.LongType.STRING) {
case rt.LongType.STRING:
return ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
case rt.LongType.NUMBER:
return ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
case rt.LongType.BIGINT:
return ts.createKeywordTypeNode(ts.SyntaxKind.BigIntKeyword);
}
}
}
createMessageTypeNode(source, type) {
let messageDescriptor = this.registry.resolveTypeName(type.typeName);
runtime_1.assert(plugin_framework_1.DescriptorProto.is(messageDescriptor));
return ts.createTypeReferenceNode(this.imports.type(source, messageDescriptor), undefined);
}
createEnumTypeNode(source, ei) {
let [enumTypeName] = ei;
let enumDescriptor = this.registry.resolveTypeName(enumTypeName);
runtime_1.assert(plugin_framework_1.EnumDescriptorProto.is(enumDescriptor));
return ts.createTypeReferenceNode(this.imports.type(source, enumDescriptor), undefined);
}
}
exports.MessageInterfaceGenerator = MessageInterfaceGenerator;

View file

@ -0,0 +1,49 @@
import * as ts from "typescript";
import { LongType } from "@protobuf-ts/runtime";
import { DescriptorProto, DescriptorRegistry, FileOptions_OptimizeMode as OptimizeMode, SymbolTable, TypescriptFile, TypeScriptImports } from "@protobuf-ts/plugin-framework";
import { CommentGenerator } from "./comment-generator";
import { Interpreter } from "../interpreter";
import { GeneratorBase } from "./generator-base";
export interface CustomMethodGenerator {
make(source: TypescriptFile, descriptor: DescriptorProto): ts.MethodDeclaration[];
}
export declare class MessageTypeGenerator extends GeneratorBase {
private readonly options;
private readonly wellKnown;
private readonly googleTypes;
private readonly typeMethodCreate;
private readonly typeMethodInternalBinaryRead;
private readonly typeMethodInternalBinaryWrite;
private readonly fieldInfoGenerator;
constructor(symbols: SymbolTable, registry: DescriptorRegistry, imports: TypeScriptImports, comments: CommentGenerator, interpreter: Interpreter, options: {
runtimeImportPath: string;
normalLongType: LongType;
oneofKindDiscriminator: string;
useProtoFieldName: boolean;
});
/**
* Declare a handler for the message. The handler provides
* functions to read / write messages of the specific type.
*
* For the following .proto:
*
* package test;
* message MyMessage {
* string str_field = 1;
* }
*
* We generate the following variable declaration:
*
* import { H } from "R";
* const MyMessage: H<MyMessage> =
* new H<MyMessage>(
* ".test.MyMessage",
* [{ no: 0, name: "str_field", kind: "scalar", T: 9 }]
* );
*
* H is the concrete class imported from runtime R.
* Some field information is passed to the handler's
* constructor.
*/
generateMessageType(source: TypescriptFile, descriptor: DescriptorProto, optimizeFor: OptimizeMode): void;
}

View file

@ -0,0 +1,85 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageTypeGenerator = void 0;
const ts = require("typescript");
const plugin_framework_1 = require("@protobuf-ts/plugin-framework");
const well_known_types_1 = require("../message-type-extensions/well-known-types");
const google_types_1 = require("../message-type-extensions/google-types");
const create_1 = require("../message-type-extensions/create");
const internal_binary_read_1 = require("../message-type-extensions/internal-binary-read");
const internal_binary_write_1 = require("../message-type-extensions/internal-binary-write");
const field_info_generator_1 = require("./field-info-generator");
const generator_base_1 = require("./generator-base");
class MessageTypeGenerator extends generator_base_1.GeneratorBase {
constructor(symbols, registry, imports, comments, interpreter, options) {
super(symbols, registry, imports, comments, interpreter);
this.options = options;
this.fieldInfoGenerator = new field_info_generator_1.FieldInfoGenerator(this.registry, this.imports, this.options);
this.wellKnown = new well_known_types_1.WellKnownTypes(this.registry, this.imports, this.options);
this.googleTypes = new google_types_1.GoogleTypes(this.registry, this.imports, this.options);
this.typeMethodCreate = new create_1.Create(this.registry, this.imports, this.interpreter, this.options);
this.typeMethodInternalBinaryRead = new internal_binary_read_1.InternalBinaryRead(this.registry, this.imports, this.interpreter, this.options);
this.typeMethodInternalBinaryWrite = new internal_binary_write_1.InternalBinaryWrite(this.registry, this.imports, this.interpreter, this.options);
}
/**
* Declare a handler for the message. The handler provides
* functions to read / write messages of the specific type.
*
* For the following .proto:
*
* package test;
* message MyMessage {
* string str_field = 1;
* }
*
* We generate the following variable declaration:
*
* import { H } from "R";
* const MyMessage: H<MyMessage> =
* new H<MyMessage>(
* ".test.MyMessage",
* [{ no: 0, name: "str_field", kind: "scalar", T: 9 }]
* );
*
* H is the concrete class imported from runtime R.
* Some field information is passed to the handler's
* constructor.
*/
generateMessageType(source, descriptor, optimizeFor) {
const
// identifier for the message
MyMessage = this.imports.type(source, descriptor), Message$Type = ts.createIdentifier(this.imports.type(source, descriptor) + '$Type'), MessageType = ts.createIdentifier(this.imports.name(source, "MessageType", this.options.runtimeImportPath)), interpreterType = this.interpreter.getMessageType(descriptor), classDecMembers = [], classDecSuperArgs = [
// arg 0: type name
ts.createStringLiteral(this.registry.makeTypeName(descriptor)),
// arg 1: field infos
this.fieldInfoGenerator.createFieldInfoLiterals(source, interpreterType.fields)
];
// if present, add message options in json format to MessageType CTOR args
if (Object.keys(interpreterType.options).length) {
classDecSuperArgs.push(plugin_framework_1.typescriptLiteralFromValue(interpreterType.options));
}
// "MyMessage$Type" constructor() { super(...) }
classDecMembers.push(ts.createConstructor(undefined, undefined, [], ts.createBlock([ts.createExpressionStatement(ts.createCall(ts.createSuper(), undefined, classDecSuperArgs))], true)));
// "MyMessage$Type" members for supported standard types
classDecMembers.push(...this.wellKnown.make(source, descriptor));
classDecMembers.push(...this.googleTypes.make(source, descriptor));
// "MyMessage$Type" members for optimized binary format
if (optimizeFor === plugin_framework_1.FileOptions_OptimizeMode.SPEED) {
classDecMembers.push(...this.typeMethodCreate.make(source, descriptor), ...this.typeMethodInternalBinaryRead.make(source, descriptor), ...this.typeMethodInternalBinaryWrite.make(source, descriptor));
}
// class "MyMessage$Type" extends "MessageType"<"MyMessage"> {
const classDec = ts.createClassDeclaration(undefined, undefined, Message$Type, undefined, [ts.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [ts.createExpressionWithTypeArguments([ts.createTypeReferenceNode(MyMessage, undefined)], MessageType)])], classDecMembers);
// export const "messageId" = new "MessageTypeId"();
const exportConst = ts.createVariableStatement([ts.createModifier(ts.SyntaxKind.ExportKeyword)], ts.createVariableDeclarationList([ts.createVariableDeclaration(MyMessage, undefined, ts.createNew(Message$Type, undefined, []))], ts.NodeFlags.Const));
// add to our file
source.addStatement(classDec);
source.addStatement(exportConst);
// add comments
ts.addSyntheticLeadingComment(classDec, ts.SyntaxKind.SingleLineCommentTrivia, " @generated message type with reflection information, may provide speed optimized methods", false);
let comment = this.comments.makeDeprecatedTag(descriptor);
comment += this.comments.makeGeneratedTag(descriptor).replace("@generated from ", "@generated MessageType for ");
plugin_framework_1.addCommentBlockAsJsDoc(exportConst, comment);
return;
}
}
exports.MessageTypeGenerator = MessageTypeGenerator;

View file

@ -0,0 +1,19 @@
import * as rpc from "@protobuf-ts/runtime-rpc";
import * as ts from "typescript";
import { DescriptorRegistry, TypescriptFile, TypeScriptImports } from "@protobuf-ts/plugin-framework";
/**
* Generates TypeScript code for runtime method information,
* from method field information.
*/
export declare class MethodInfoGenerator {
private readonly registry;
private readonly imports;
constructor(registry: DescriptorRegistry, imports: TypeScriptImports);
createMethodInfoLiterals(source: TypescriptFile, methodInfos: readonly rpc.PartialMethodInfo[]): ts.ArrayLiteralExpression;
createMethodInfoLiteral(source: TypescriptFile, methodInfo: rpc.PartialMethodInfo): ts.ObjectLiteralExpression;
/**
* Turn normalized method info returned by normalizeMethodInfo() back into
* the minimized form.
*/
private static denormalizeMethodInfo;
}

View file

@ -0,0 +1,67 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MethodInfoGenerator = void 0;
const rt = require("@protobuf-ts/runtime");
const ts = require("typescript");
const plugin_framework_1 = require("@protobuf-ts/plugin-framework");
/**
* Generates TypeScript code for runtime method information,
* from method field information.
*/
class MethodInfoGenerator {
constructor(registry, imports) {
this.registry = registry;
this.imports = imports;
}
createMethodInfoLiterals(source, methodInfos) {
const mi = methodInfos
.map(mi => MethodInfoGenerator.denormalizeMethodInfo(mi))
.map(mi => this.createMethodInfoLiteral(source, mi));
return ts.createArrayLiteral(mi, true);
}
createMethodInfoLiteral(source, methodInfo) {
methodInfo = MethodInfoGenerator.denormalizeMethodInfo(methodInfo);
const properties = [];
// name: The name of the method as declared in .proto
// localName: The name of the method in the runtime.
// idempotency: The idempotency level as specified in .proto.
// serverStreaming: Was the rpc declared with server streaming?
// clientStreaming: Was the rpc declared with client streaming?
// options: Contains custom method options from the .proto source in JSON format.
for (let key of ["name", "localName", "idempotency", "serverStreaming", "clientStreaming", "options"]) {
if (methodInfo[key] !== undefined) {
properties.push(ts.createPropertyAssignment(key, plugin_framework_1.typescriptLiteralFromValue(methodInfo[key])));
}
}
// I: The generated type handler for the input message.
properties.push(ts.createPropertyAssignment(ts.createIdentifier('I'), ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.I.typeName)))));
// O: The generated type handler for the output message.
properties.push(ts.createPropertyAssignment(ts.createIdentifier('O'), ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.O.typeName)))));
return ts.createObjectLiteral(properties, false);
}
/**
* Turn normalized method info returned by normalizeMethodInfo() back into
* the minimized form.
*/
static denormalizeMethodInfo(info) {
let partial = Object.assign({}, info);
delete partial.service;
if (info.localName === rt.lowerCamelCase(info.name)) {
delete partial.localName;
}
if (!info.serverStreaming) {
delete partial.serverStreaming;
}
if (!info.clientStreaming) {
delete partial.clientStreaming;
}
if (info.options && Object.keys(info.options).length) {
delete partial.info;
}
if (info.idempotency === undefined) {
delete partial.idempotency;
}
return partial;
}
}
exports.MethodInfoGenerator = MethodInfoGenerator;

View file

@ -0,0 +1,68 @@
import { DescriptorRegistry, ServiceDescriptorProto, SymbolTable, TypescriptFile, TypeScriptImports } from "@protobuf-ts/plugin-framework";
import * as ts from "typescript";
import * as rpc from "@protobuf-ts/runtime-rpc";
import { CommentGenerator } from "./comment-generator";
import { Interpreter } from "../interpreter";
import { GeneratorBase } from "./generator-base";
export declare abstract class ServiceClientGeneratorBase extends GeneratorBase {
protected readonly options: {
runtimeImportPath: string;
runtimeRpcImportPath: string;
};
abstract readonly symbolKindInterface: string;
abstract readonly symbolKindImplementation: string;
constructor(symbols: SymbolTable, registry: DescriptorRegistry, imports: TypeScriptImports, comments: CommentGenerator, interpreter: Interpreter, options: {
runtimeImportPath: string;
runtimeRpcImportPath: string;
});
registerSymbols(source: TypescriptFile, descriptor: ServiceDescriptorProto): void;
/**
* For the following .proto:
*
* service SimpleService {
* rpc Get (GetRequest) returns (GetResponse);
* }
*
* We generate the following interface:
*
* interface ISimpleServiceClient {
* get(request: GetRequest, options?: RpcOptions): UnaryCall<ExampleRequest, ExampleResponse>;
* }
*
*/
generateInterface(source: TypescriptFile, descriptor: ServiceDescriptorProto): ts.InterfaceDeclaration;
protected createMethodSignatures(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodSignature[];
protected createUnarySignatures(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodSignature[];
protected createServerStreamingSignatures(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodSignature[];
protected createClientStreamingSignatures(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodSignature[];
protected createDuplexStreamingSignatures(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodSignature[];
/**
* For the following .proto:
*
* service SimpleService {
* rpc Get (GetRequest) returns (GetResponse);
* }
*
* We generate:
*
* class SimpleService implements ISimpleService {
* readonly typeName = ".spec.SimpleService";
* readonly methods: MethodInfo[] = [
* {name: 'Get', localName: 'get', I: GetRequest, O: GetResponse}
* ];
* ...
* }
*
*/
generateImplementationClass(source: TypescriptFile, descriptor: ServiceDescriptorProto): ts.ClassDeclaration;
/**
* Create any method type, switching to specific methods.
*/
protected createMethod(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodDeclaration;
protected abstract createUnary(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodDeclaration;
protected abstract createServerStreaming(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodDeclaration;
protected abstract createClientStreaming(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodDeclaration;
protected abstract createDuplexStreaming(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodDeclaration;
protected makeI(source: TypescriptFile, methodInfo: rpc.MethodInfo, isTypeOnly?: boolean): ts.TypeReferenceNode;
protected makeO(source: TypescriptFile, methodInfo: rpc.MethodInfo, isTypeOnly?: boolean): ts.TypeReferenceNode;
}

View file

@ -0,0 +1,164 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceClientGeneratorBase = void 0;
const ts = require("typescript");
const generator_base_1 = require("./generator-base");
const local_type_name_1 = require("./local-type-name");
const runtime_1 = require("@protobuf-ts/runtime");
class ServiceClientGeneratorBase extends generator_base_1.GeneratorBase {
constructor(symbols, registry, imports, comments, interpreter, options) {
super(symbols, registry, imports, comments, interpreter);
this.options = options;
}
registerSymbols(source, descriptor) {
const basename = local_type_name_1.createLocalTypeName(descriptor, this.registry);
const interfaceName = `I${basename}Client`;
const implementationName = `${basename}Client`;
this.symbols.register(interfaceName, descriptor, source, this.symbolKindInterface);
this.symbols.register(implementationName, descriptor, source, this.symbolKindImplementation);
}
/**
* For the following .proto:
*
* service SimpleService {
* rpc Get (GetRequest) returns (GetResponse);
* }
*
* We generate the following interface:
*
* interface ISimpleServiceClient {
* get(request: GetRequest, options?: RpcOptions): UnaryCall<ExampleRequest, ExampleResponse>;
* }
*
*/
generateInterface(source, descriptor) {
const interpreterType = this.interpreter.getServiceType(descriptor), IServiceClient = this.imports.type(source, descriptor, this.symbolKindInterface), signatures = [];
for (let mi of interpreterType.methods) {
const sig = this.createMethodSignatures(source, mi);
// add comment to the first signature
if (sig.length > 0) {
const methodDescriptor = descriptor.method.find(md => md.name === mi.name);
runtime_1.assert(methodDescriptor);
this.comments.addCommentsForDescriptor(sig[0], methodDescriptor, 'appendToLeadingBlock');
}
signatures.push(...sig);
}
// export interface MyService {...
let statement = ts.createInterfaceDeclaration(undefined, [ts.createModifier(ts.SyntaxKind.ExportKeyword)], IServiceClient, undefined, undefined, [...signatures]);
// add to our file
this.comments.addCommentsForDescriptor(statement, descriptor, 'appendToLeadingBlock');
source.addStatement(statement);
return statement;
}
createMethodSignatures(source, methodInfo) {
let signatures;
if (methodInfo.serverStreaming && methodInfo.clientStreaming) {
signatures = this.createDuplexStreamingSignatures(source, methodInfo);
}
else if (methodInfo.serverStreaming) {
signatures = this.createServerStreamingSignatures(source, methodInfo);
}
else if (methodInfo.clientStreaming) {
signatures = this.createClientStreamingSignatures(source, methodInfo);
}
else {
signatures = this.createUnarySignatures(source, methodInfo);
}
return signatures;
}
createUnarySignatures(source, methodInfo) {
const method = this.createUnary(source, methodInfo);
return [ts.createMethodSignature(method.typeParameters, method.parameters, method.type, method.name, method.questionToken)];
}
createServerStreamingSignatures(source, methodInfo) {
const method = this.createServerStreaming(source, methodInfo);
return [ts.createMethodSignature(method.typeParameters, method.parameters, method.type, method.name, method.questionToken)];
}
createClientStreamingSignatures(source, methodInfo) {
const method = this.createClientStreaming(source, methodInfo);
return [ts.createMethodSignature(method.typeParameters, method.parameters, method.type, method.name, method.questionToken)];
}
createDuplexStreamingSignatures(source, methodInfo) {
const method = this.createDuplexStreaming(source, methodInfo);
return [ts.createMethodSignature(method.typeParameters, method.parameters, method.type, method.name, method.questionToken)];
}
/**
* For the following .proto:
*
* service SimpleService {
* rpc Get (GetRequest) returns (GetResponse);
* }
*
* We generate:
*
* class SimpleService implements ISimpleService {
* readonly typeName = ".spec.SimpleService";
* readonly methods: MethodInfo[] = [
* {name: 'Get', localName: 'get', I: GetRequest, O: GetResponse}
* ];
* ...
* }
*
*/
generateImplementationClass(source, descriptor) {
const interpreterType = this.interpreter.getServiceType(descriptor), ServiceType = this.imports.type(source, descriptor), ServiceClient = this.imports.type(source, descriptor, this.symbolKindImplementation), IServiceClient = this.imports.type(source, descriptor, this.symbolKindInterface), ServiceInfo = this.imports.name(source, 'ServiceInfo', this.options.runtimeRpcImportPath, true), RpcTransport = this.imports.name(source, 'RpcTransport', this.options.runtimeRpcImportPath, true);
const classDecorators = [];
const constructorDecorators = [];
const members = [
// typeName = Haberdasher.typeName;
ts.createProperty(undefined, undefined, ts.createIdentifier("typeName"), undefined, undefined, ts.createPropertyAccess(ts.createIdentifier(ServiceType), ts.createIdentifier("typeName"))),
// methods = Haberdasher.methods;
ts.createProperty(undefined, undefined, ts.createIdentifier("methods"), undefined, undefined, ts.createPropertyAccess(ts.createIdentifier(ServiceType), ts.createIdentifier("methods"))),
// options = Haberdasher.options;
ts.createProperty(undefined, undefined, ts.createIdentifier("options"), undefined, undefined, ts.createPropertyAccess(ts.createIdentifier(ServiceType), ts.createIdentifier("options"))),
// constructor(@Inject(RPC_TRANSPORT) private readonly _transport: RpcTransport) {}
ts.createConstructor(undefined, undefined, [ts.createParameter(constructorDecorators, [
ts.createModifier(ts.SyntaxKind.PrivateKeyword),
ts.createModifier(ts.SyntaxKind.ReadonlyKeyword)
], undefined, ts.createIdentifier("_transport"), undefined, ts.createTypeReferenceNode(ts.createIdentifier(RpcTransport), undefined), undefined)], ts.createBlock([], true)),
...interpreterType.methods.map(mi => {
const declaration = this.createMethod(source, mi);
const methodDescriptor = descriptor.method.find(md => md.name === mi.name);
runtime_1.assert(methodDescriptor);
this.comments.addCommentsForDescriptor(declaration, methodDescriptor, 'appendToLeadingBlock');
return declaration;
})
];
// export class MyService implements MyService, ServiceInfo
const statement = ts.createClassDeclaration(classDecorators, [ts.createModifier(ts.SyntaxKind.ExportKeyword)], ServiceClient, undefined, [
ts.createHeritageClause(ts.SyntaxKind.ImplementsKeyword, [
ts.createExpressionWithTypeArguments(undefined, ts.createIdentifier(IServiceClient)),
ts.createExpressionWithTypeArguments(undefined, ts.createIdentifier(ServiceInfo)),
]),
], members);
source.addStatement(statement);
this.comments.addCommentsForDescriptor(statement, descriptor, 'appendToLeadingBlock');
return statement;
}
/**
* Create any method type, switching to specific methods.
*/
createMethod(source, methodInfo) {
let declaration;
if (methodInfo.serverStreaming && methodInfo.clientStreaming) {
declaration = this.createDuplexStreaming(source, methodInfo);
}
else if (methodInfo.serverStreaming) {
declaration = this.createServerStreaming(source, methodInfo);
}
else if (methodInfo.clientStreaming) {
declaration = this.createClientStreaming(source, methodInfo);
}
else {
declaration = this.createUnary(source, methodInfo);
}
return declaration;
}
makeI(source, methodInfo, isTypeOnly = false) {
return ts.createTypeReferenceNode(ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.I.typeName), 'default', isTypeOnly)), undefined);
}
makeO(source, methodInfo, isTypeOnly = false) {
return ts.createTypeReferenceNode(ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.O.typeName), 'default', isTypeOnly)), undefined);
}
}
exports.ServiceClientGeneratorBase = ServiceClientGeneratorBase;

View file

@ -0,0 +1,12 @@
import * as ts from "typescript";
import { ServiceClientGeneratorBase } from "./service-client-generator-base";
import * as rpc from "@protobuf-ts/runtime-rpc";
import { TypescriptFile } from "@protobuf-ts/plugin-framework";
export declare class ServiceClientGeneratorGeneric extends ServiceClientGeneratorBase {
readonly symbolKindInterface = "call-client-interface";
readonly symbolKindImplementation = "call-client";
createUnary(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodDeclaration;
createServerStreaming(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodDeclaration;
createClientStreaming(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodDeclaration;
createDuplexStreaming(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodDeclaration;
}

View file

@ -0,0 +1,130 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceClientGeneratorGeneric = void 0;
const ts = require("typescript");
const service_client_generator_base_1 = require("./service-client-generator-base");
const runtime_1 = require("@protobuf-ts/runtime");
class ServiceClientGeneratorGeneric extends service_client_generator_base_1.ServiceClientGeneratorBase {
constructor() {
super(...arguments);
this.symbolKindInterface = 'call-client-interface';
this.symbolKindImplementation = 'call-client';
}
createUnary(source, methodInfo) {
let RpcOptions = this.imports.name(source, 'RpcOptions', this.options.runtimeRpcImportPath, true);
let UnaryCall = this.imports.name(source, 'UnaryCall', this.options.runtimeRpcImportPath, true);
let methodIndex = methodInfo.service.methods.indexOf(methodInfo);
runtime_1.assert(methodIndex >= 0);
return ts.createMethod(undefined, undefined, undefined, ts.createIdentifier(methodInfo.localName), undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, this.makeI(source, methodInfo, true)),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createIdentifier(RpcOptions), undefined), undefined)
], ts.createTypeReferenceNode(UnaryCall, [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true),
]), ts.createBlock([
// const method = this.methods[0], opt = this._transport.mergeOptions(options);
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([
ts.createVariableDeclaration(ts.createIdentifier("method"), undefined, ts.createElementAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("methods")), ts.createNumericLiteral(methodIndex.toString()))),
ts.createVariableDeclaration(ts.createIdentifier("opt"), undefined, ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")), ts.createIdentifier("mergeOptions")), undefined, [ts.createIdentifier("options")])),
], ts.NodeFlags.Const)),
// return stackIntercept("unary", this._transport, method, opt, input);
ts.createReturn(ts.createCall(ts.createIdentifier(this.imports.name(source, 'stackIntercept', this.options.runtimeRpcImportPath)), [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true)
], [
ts.createStringLiteral("unary"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")),
ts.createIdentifier("method"),
ts.createIdentifier("opt"),
ts.createIdentifier("input"),
])),
], true));
}
createServerStreaming(source, methodInfo) {
let RpcOptions = this.imports.name(source, 'RpcOptions', this.options.runtimeRpcImportPath, true);
let ServerStreamingCall = this.imports.name(source, 'ServerStreamingCall', this.options.runtimeRpcImportPath, true);
let methodIndex = methodInfo.service.methods.indexOf(methodInfo);
runtime_1.assert(methodIndex >= 0);
return ts.createMethod(undefined, undefined, undefined, ts.createIdentifier(methodInfo.localName), undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, this.makeI(source, methodInfo, true)),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createIdentifier(RpcOptions), undefined), undefined)
], ts.createTypeReferenceNode(ServerStreamingCall, [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true),
]), ts.createBlock([
// const method = this.methods[0], opt = this._transport.mergeOptions(options);
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([
ts.createVariableDeclaration(ts.createIdentifier("method"), undefined, ts.createElementAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("methods")), ts.createNumericLiteral(methodIndex.toString()))),
ts.createVariableDeclaration(ts.createIdentifier("opt"), undefined, ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")), ts.createIdentifier("mergeOptions")), undefined, [ts.createIdentifier("options")])),
], ts.NodeFlags.Const)),
// return stackIntercept("serverStreaming", this._transport, method, opt, i);
ts.createReturn(ts.createCall(ts.createIdentifier(this.imports.name(source, 'stackIntercept', this.options.runtimeRpcImportPath)), [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true)
], [
ts.createStringLiteral("serverStreaming"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")),
ts.createIdentifier("method"),
ts.createIdentifier("opt"),
ts.createIdentifier("input"),
])),
], true));
}
createClientStreaming(source, methodInfo) {
let RpcOptions = this.imports.name(source, 'RpcOptions', this.options.runtimeRpcImportPath, true);
let ClientStreamingCall = this.imports.name(source, 'ClientStreamingCall', this.options.runtimeRpcImportPath, true);
let methodIndex = methodInfo.service.methods.indexOf(methodInfo);
runtime_1.assert(methodIndex >= 0);
return ts.createMethod(undefined, undefined, undefined, ts.createIdentifier(methodInfo.localName), undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createIdentifier(RpcOptions), undefined), undefined)
], ts.createTypeReferenceNode(ClientStreamingCall, [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true),
]), ts.createBlock([
// const method = this.methods[0], opt = this._transport.mergeOptions(options)
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([
ts.createVariableDeclaration(ts.createIdentifier("method"), undefined, ts.createElementAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("methods")), ts.createNumericLiteral(methodIndex.toString()))),
ts.createVariableDeclaration(ts.createIdentifier("opt"), undefined, ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")), ts.createIdentifier("mergeOptions")), undefined, [ts.createIdentifier("options")]))
], ts.NodeFlags.Const)),
// return stackIntercept("clientStreaming", this._transport, methods, opt);
ts.createReturn(ts.createCall(ts.createIdentifier(this.imports.name(source, 'stackIntercept', this.options.runtimeRpcImportPath)), [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true)
], [
ts.createStringLiteral("clientStreaming"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")),
ts.createIdentifier("method"),
ts.createIdentifier("opt")
])),
], true));
}
createDuplexStreaming(source, methodInfo) {
let RpcOptions = this.imports.name(source, 'RpcOptions', this.options.runtimeRpcImportPath, true);
let DuplexStreamingCall = this.imports.name(source, 'DuplexStreamingCall', this.options.runtimeRpcImportPath, true);
let methodIndex = methodInfo.service.methods.indexOf(methodInfo);
runtime_1.assert(methodIndex >= 0);
return ts.createMethod(undefined, undefined, undefined, ts.createIdentifier(methodInfo.localName), undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createIdentifier(RpcOptions), undefined), undefined)
], ts.createTypeReferenceNode(DuplexStreamingCall, [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true),
]), ts.createBlock([
// const method = this.methods[0], opt = this._transport.mergeOptions(options)
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([
ts.createVariableDeclaration(ts.createIdentifier("method"), undefined, ts.createElementAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("methods")), ts.createNumericLiteral(methodIndex.toString()))),
ts.createVariableDeclaration(ts.createIdentifier("opt"), undefined, ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")), ts.createIdentifier("mergeOptions")), undefined, [ts.createIdentifier("options")]))
], ts.NodeFlags.Const)),
// return stackIntercept("duplex", this._transport, this, methods, opt);
ts.createReturn(ts.createCall(ts.createIdentifier(this.imports.name(source, 'stackIntercept', this.options.runtimeRpcImportPath)), [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true)
], [
ts.createStringLiteral("duplex"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_transport")),
ts.createIdentifier("method"),
ts.createIdentifier("opt")
])),
], true));
}
}
exports.ServiceClientGeneratorGeneric = ServiceClientGeneratorGeneric;

View file

@ -0,0 +1,17 @@
import { ServiceClientGeneratorBase } from "./service-client-generator-base";
import { ServiceDescriptorProto, TypescriptFile } from "@protobuf-ts/plugin-framework";
import * as ts from "typescript";
import * as rpc from "@protobuf-ts/runtime-rpc";
export declare class ServiceClientGeneratorGrpc extends ServiceClientGeneratorBase {
readonly symbolKindInterface = "grpc1-client-interface";
readonly symbolKindImplementation = "grpc1-client";
generateImplementationClass(source: TypescriptFile, descriptor: ServiceDescriptorProto): ts.ClassDeclaration;
protected createUnarySignatures(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodSignature[];
protected createServerStreamingSignatures(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodSignature[];
protected createClientStreamingSignatures(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodSignature[];
protected createDuplexStreamingSignatures(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodSignature[];
protected createUnary(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodDeclaration;
protected createServerStreaming(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodDeclaration;
protected createClientStreaming(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodDeclaration;
protected createDuplexStreaming(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodDeclaration;
}

View file

@ -0,0 +1,371 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceClientGeneratorGrpc = void 0;
const service_client_generator_base_1 = require("./service-client-generator-base");
const ts = require("typescript");
const runtime_1 = require("@protobuf-ts/runtime");
class ServiceClientGeneratorGrpc extends service_client_generator_base_1.ServiceClientGeneratorBase {
constructor() {
super(...arguments);
this.symbolKindInterface = 'grpc1-client-interface';
this.symbolKindImplementation = 'grpc1-client';
}
generateImplementationClass(source, descriptor) {
const interpreterType = this.interpreter.getServiceType(descriptor), ServiceClient = this.imports.type(source, descriptor, this.symbolKindImplementation), IServiceClient = this.imports.type(source, descriptor, this.symbolKindInterface), BinaryReadOptions = this.imports.name(source, 'BinaryReadOptions', this.options.runtimeImportPath, true), BinaryWriteOptions = this.imports.name(source, 'BinaryWriteOptions', this.options.runtimeImportPath, true), grpc = this.imports.namespace(source, 'grpc', '@grpc/grpc-js');
const members = [
// private readonly _binaryOptions: Partial<BinaryReadOptions & BinaryWriteOptions>;
ts.createProperty(undefined, [
ts.createModifier(ts.SyntaxKind.PrivateKeyword),
ts.createModifier(ts.SyntaxKind.ReadonlyKeyword)
], ts.createIdentifier("_binaryOptions"), undefined, ts.createTypeReferenceNode(ts.createIdentifier("Partial"), [ts.createIntersectionTypeNode([
ts.createTypeReferenceNode(ts.createIdentifier(BinaryReadOptions), undefined),
ts.createTypeReferenceNode(ts.createIdentifier(BinaryWriteOptions), undefined)
])]), undefined),
//
ts.createConstructor(undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("address"), undefined, ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("credentials"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ChannelCredentials")), undefined), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientOptions")), undefined), ts.createObjectLiteral([], false)),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("binaryOptions"), undefined, ts.createTypeReferenceNode(ts.createIdentifier("Partial"), [ts.createIntersectionTypeNode([
ts.createTypeReferenceNode(ts.createIdentifier(BinaryReadOptions), undefined),
ts.createTypeReferenceNode(ts.createIdentifier(BinaryWriteOptions), undefined)
])]), ts.createObjectLiteral([], false))
], ts.createBlock([
ts.createExpressionStatement(ts.createCall(ts.createSuper(), undefined, [
ts.createIdentifier("address"),
ts.createIdentifier("credentials"),
ts.createIdentifier("options")
])),
ts.createExpressionStatement(ts.createBinary(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_binaryOptions")), ts.createToken(ts.SyntaxKind.EqualsToken), ts.createIdentifier("binaryOptions")))
], true)),
...interpreterType.methods.map(mi => {
const declaration = this.createMethod(source, mi);
const methodDescriptor = descriptor.method.find(md => md.name === mi.name);
runtime_1.assert(methodDescriptor);
this.comments.addCommentsForDescriptor(declaration, methodDescriptor, 'appendToLeadingBlock');
return declaration;
})
];
// export class MyService implements MyService, ServiceInfo
const statement = ts.createClassDeclaration(undefined, [ts.createModifier(ts.SyntaxKind.ExportKeyword)], ServiceClient, undefined, [
ts.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [ts.createExpressionWithTypeArguments(undefined, ts.createPropertyAccess(ts.createIdentifier(grpc), ts.createIdentifier("Client")))]),
ts.createHeritageClause(ts.SyntaxKind.ImplementsKeyword, [ts.createExpressionWithTypeArguments(undefined, ts.createIdentifier(IServiceClient))])
], members);
source.addStatement(statement);
this.comments.addCommentsForDescriptor(statement, descriptor, 'appendToLeadingBlock');
return statement;
}
createUnarySignatures(source, methodInfo) {
let grpc = this.imports.namespace(source, 'grpc', '@grpc/grpc-js');
return [
ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, this.makeI(source, methodInfo, true), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("metadata"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("Metadata")), undefined), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("callback"), undefined, ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientUnaryCall")), undefined), ts.createIdentifier(methodInfo.localName), undefined),
ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, this.makeI(source, methodInfo, true), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("metadata"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("Metadata")), undefined), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("callback"), undefined, ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientUnaryCall")), undefined), ts.createIdentifier(methodInfo.localName), undefined),
ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, this.makeI(source, methodInfo, true), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("callback"), undefined, ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientUnaryCall")), undefined), ts.createIdentifier(methodInfo.localName), undefined),
ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, this.makeI(source, methodInfo, true), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("callback"), undefined, ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientUnaryCall")), undefined), ts.createIdentifier(methodInfo.localName), undefined)
];
}
createServerStreamingSignatures(source, methodInfo) {
let grpc = this.imports.namespace(source, 'grpc', '@grpc/grpc-js');
return [
ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, this.makeI(source, methodInfo, true), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("metadata"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("Metadata")), undefined), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientReadableStream")), [this.makeO(source, methodInfo, true)]), ts.createIdentifier(methodInfo.localName), undefined),
ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, this.makeI(source, methodInfo, true), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientReadableStream")), [this.makeO(source, methodInfo, true)]), ts.createIdentifier(methodInfo.localName), undefined)
];
}
createClientStreamingSignatures(source, methodInfo) {
let grpc = this.imports.namespace(source, 'grpc', '@grpc/grpc-js');
return [
ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("metadata"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("Metadata")), undefined), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("callback"), undefined, ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientWritableStream")), [this.makeI(source, methodInfo, true)]), ts.createIdentifier(methodInfo.localName), undefined),
ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("metadata"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("Metadata")), undefined), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("callback"), undefined, ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientWritableStream")), [this.makeI(source, methodInfo, true)]), ts.createIdentifier(methodInfo.localName), undefined),
ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("callback"), undefined, ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientWritableStream")), [
this.makeI(source, methodInfo, true),
]), ts.createIdentifier(methodInfo.localName), undefined),
ts.createMethodSignature(undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("callback"), undefined, ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)), undefined)], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientWritableStream")), [
this.makeI(source, methodInfo, true),
]), ts.createIdentifier(methodInfo.localName), undefined)
];
}
createDuplexStreamingSignatures(source, methodInfo) {
let grpc = this.imports.namespace(source, 'grpc', '@grpc/grpc-js');
return [
ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("metadata"), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("Metadata")), undefined), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientDuplexStream")), [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true),
]), ts.createIdentifier(methodInfo.localName), undefined),
ts.createMethodSignature(undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined), undefined)], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientDuplexStream")), [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true),
]), ts.createIdentifier(methodInfo.localName), undefined)
];
}
createUnary(source, methodInfo) {
let grpc = this.imports.namespace(source, 'grpc', '@grpc/grpc-js');
let ServiceType = this.imports.type(source, this.registry.resolveTypeName(methodInfo.service.typeName));
let methodIndex = methodInfo.service.methods.indexOf(methodInfo);
return ts.createMethod(undefined, undefined, undefined, ts.createIdentifier(methodInfo.localName), undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, this.makeI(source, methodInfo, true), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("metadata"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("Metadata")), undefined),
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined),
ts.createParenthesizedType(ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)))
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined),
ts.createParenthesizedType(ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)))
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("callback"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createParenthesizedType(ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword))), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientUnaryCall")), undefined), ts.createBlock([
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("method"), undefined, ts.createElementAccess(ts.createPropertyAccess(ts.createIdentifier(ServiceType), ts.createIdentifier("methods")), ts.createNumericLiteral(methodIndex.toString())))], ts.NodeFlags.Const)),
ts.createReturn(ts.createCall(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("makeUnaryRequest")), [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true)
], [
ts.createTemplateExpression(ts.createTemplateHead("/", "/"), [
ts.createTemplateSpan(ts.createPropertyAccess(ts.createIdentifier(ServiceType), ts.createIdentifier("typeName")), ts.createTemplateMiddle("/", "/")),
ts.createTemplateSpan(ts.createPropertyAccess(ts.createIdentifier("method"), ts.createIdentifier("name")), ts.createTemplateTail("", ""))
]),
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), undefined, this.makeI(source, methodInfo, true), undefined)], ts.createTypeReferenceNode(ts.createIdentifier("Buffer"), undefined), ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Buffer"), ts.createIdentifier("from")), undefined, [ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("method"), ts.createIdentifier("I")), ts.createIdentifier("toBinary")), undefined, [
ts.createIdentifier("value"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_binaryOptions"))
])])),
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), undefined, ts.createTypeReferenceNode(ts.createIdentifier("Buffer"), undefined), undefined)], this.makeO(source, methodInfo, true), ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("method"), ts.createIdentifier("O")), ts.createIdentifier("fromBinary")), undefined, [
ts.createIdentifier("value"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_binaryOptions"))
])),
ts.createIdentifier("input"),
ts.createAsExpression(ts.createIdentifier("metadata"), ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)),
ts.createAsExpression(ts.createIdentifier("options"), ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)),
ts.createAsExpression(ts.createIdentifier("callback"), ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword))
]))
], true));
}
createServerStreaming(source, methodInfo) {
let grpc = this.imports.namespace(source, 'grpc', '@grpc/grpc-js');
let ServiceType = this.imports.type(source, this.registry.resolveTypeName(methodInfo.service.typeName));
let methodIndex = methodInfo.service.methods.indexOf(methodInfo);
return ts.createMethod(undefined, undefined, undefined, ts.createIdentifier(methodInfo.localName), undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("input"), undefined, this.makeI(source, methodInfo, true), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("metadata"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("Metadata")), undefined),
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientReadableStream")), [this.makeO(source, methodInfo, true)]), ts.createBlock([
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("method"), undefined, ts.createElementAccess(ts.createPropertyAccess(ts.createIdentifier(ServiceType), ts.createIdentifier("methods")), ts.createNumericLiteral(methodIndex.toString())))], ts.NodeFlags.Const)),
ts.createReturn(ts.createCall(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("makeServerStreamRequest")), [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true)
], [
ts.createTemplateExpression(ts.createTemplateHead("/", "/"), [
ts.createTemplateSpan(ts.createPropertyAccess(ts.createIdentifier(ServiceType), ts.createIdentifier("typeName")), ts.createTemplateMiddle("/", "/")),
ts.createTemplateSpan(ts.createPropertyAccess(ts.createIdentifier("method"), ts.createIdentifier("name")), ts.createTemplateTail("", ""))
]),
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), undefined, this.makeI(source, methodInfo, true), undefined)], ts.createTypeReferenceNode(ts.createIdentifier("Buffer"), undefined), ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Buffer"), ts.createIdentifier("from")), undefined, [ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("method"), ts.createIdentifier("I")), ts.createIdentifier("toBinary")), undefined, [
ts.createIdentifier("value"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_binaryOptions"))
])])),
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), undefined, ts.createTypeReferenceNode(ts.createIdentifier("Buffer"), undefined), undefined)], this.makeO(source, methodInfo, true), ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("method"), ts.createIdentifier("O")), ts.createIdentifier("fromBinary")), undefined, [
ts.createIdentifier("value"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_binaryOptions"))
])),
ts.createIdentifier("input"),
ts.createAsExpression(ts.createIdentifier("metadata"), ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)),
ts.createIdentifier("options")
]))
], true));
}
createClientStreaming(source, methodInfo) {
let grpc = this.imports.namespace(source, 'grpc', '@grpc/grpc-js');
let ServiceType = this.imports.type(source, this.registry.resolveTypeName(methodInfo.service.typeName));
let methodIndex = methodInfo.service.methods.indexOf(methodInfo);
return ts.createMethod(undefined, undefined, undefined, ts.createIdentifier(methodInfo.localName), undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("metadata"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("Metadata")), undefined),
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined),
ts.createParenthesizedType(ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)))
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined),
ts.createParenthesizedType(ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)))
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("callback"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createParenthesizedType(ts.createFunctionTypeNode(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("err"), undefined, ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceError")), undefined),
ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), ts.createToken(ts.SyntaxKind.QuestionToken), this.makeO(source, methodInfo, true), undefined)
], ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword))), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientWritableStream")), [this.makeI(source, methodInfo, true)]), ts.createBlock([
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("method"), undefined, ts.createElementAccess(ts.createPropertyAccess(ts.createIdentifier(ServiceType), ts.createIdentifier("methods")), ts.createNumericLiteral(methodIndex.toString())))], ts.NodeFlags.Const)),
ts.createReturn(ts.createCall(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("makeClientStreamRequest")), [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true)
], [
ts.createTemplateExpression(ts.createTemplateHead("/", "/"), [
ts.createTemplateSpan(ts.createPropertyAccess(ts.createIdentifier(ServiceType), ts.createIdentifier("typeName")), ts.createTemplateMiddle("/", "/")),
ts.createTemplateSpan(ts.createPropertyAccess(ts.createIdentifier("method"), ts.createIdentifier("name")), ts.createTemplateTail("", ""))
]),
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), undefined, this.makeI(source, methodInfo, true), undefined)], ts.createTypeReferenceNode(ts.createIdentifier("Buffer"), undefined), ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Buffer"), ts.createIdentifier("from")), undefined, [ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("method"), ts.createIdentifier("I")), ts.createIdentifier("toBinary")), undefined, [
ts.createIdentifier("value"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_binaryOptions"))
])])),
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), undefined, ts.createTypeReferenceNode(ts.createIdentifier("Buffer"), undefined), undefined)], this.makeO(source, methodInfo, true), ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("method"), ts.createIdentifier("O")), ts.createIdentifier("fromBinary")), undefined, [
ts.createIdentifier("value"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_binaryOptions"))
])),
ts.createAsExpression(ts.createIdentifier("metadata"), ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)),
ts.createAsExpression(ts.createIdentifier("options"), ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)),
ts.createAsExpression(ts.createIdentifier("callback"), ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword))
]))
], true));
}
createDuplexStreaming(source, methodInfo) {
let grpc = this.imports.namespace(source, 'grpc', '@grpc/grpc-js');
let ServiceType = this.imports.type(source, this.registry.resolveTypeName(methodInfo.service.typeName));
return ts.createMethod(undefined, undefined, undefined, ts.createIdentifier(methodInfo.localName), undefined, undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("metadata"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createUnionTypeNode([
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("Metadata")), undefined),
ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined)
]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("options"), ts.createToken(ts.SyntaxKind.QuestionToken), ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("CallOptions")), undefined), undefined)
], ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ClientDuplexStream")), [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true)
]), ts.createBlock([
ts.createVariableStatement(undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier("method"), undefined, ts.createElementAccess(ts.createPropertyAccess(ts.createIdentifier(ServiceType), ts.createIdentifier("methods")), ts.createNumericLiteral(methodInfo.service.methods.indexOf(methodInfo).toString())))], ts.NodeFlags.Const)),
ts.createReturn(ts.createCall(ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("makeBidiStreamRequest")), [
this.makeI(source, methodInfo, true),
this.makeO(source, methodInfo, true)
], [
ts.createTemplateExpression(ts.createTemplateHead("/", "/"), [
ts.createTemplateSpan(ts.createPropertyAccess(ts.createIdentifier(ServiceType), ts.createIdentifier("typeName")), ts.createTemplateMiddle("/", "/")),
ts.createTemplateSpan(ts.createPropertyAccess(ts.createIdentifier("method"), ts.createIdentifier("name")), ts.createTemplateTail("", ""))
]),
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), undefined, this.makeI(source, methodInfo, true), undefined)], ts.createTypeReferenceNode(ts.createIdentifier("Buffer"), undefined), ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Buffer"), ts.createIdentifier("from")), undefined, [ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("method"), ts.createIdentifier("I")), ts.createIdentifier("toBinary")), undefined, [
ts.createIdentifier("value"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_binaryOptions"))
])])),
ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), undefined, ts.createTypeReferenceNode(ts.createIdentifier("Buffer"), undefined), undefined)], this.makeO(source, methodInfo, true), ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(ts.createIdentifier("method"), ts.createIdentifier("O")), ts.createIdentifier("fromBinary")), undefined, [
ts.createIdentifier("value"),
ts.createPropertyAccess(ts.createThis(), ts.createIdentifier("_binaryOptions"))
])),
ts.createAsExpression(ts.createIdentifier("metadata"), ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)),
ts.createIdentifier("options")
]))
], true));
}
}
exports.ServiceClientGeneratorGrpc = ServiceClientGeneratorGrpc;

View file

@ -0,0 +1,18 @@
import { GeneratorBase } from "./generator-base";
import { DescriptorRegistry, ServiceDescriptorProto, SymbolTable, TypescriptFile, TypeScriptImports } from "@protobuf-ts/plugin-framework";
import { Interpreter } from "../interpreter";
import * as ts from "typescript";
import { CommentGenerator } from "./comment-generator";
export declare class ServiceServerGeneratorGeneric extends GeneratorBase {
private readonly options;
private readonly symbolKindInterface;
constructor(symbols: SymbolTable, registry: DescriptorRegistry, imports: TypeScriptImports, comments: CommentGenerator, interpreter: Interpreter, options: {
runtimeRpcImportPath: string;
});
registerSymbols(source: TypescriptFile, descriptor: ServiceDescriptorProto): void;
generateInterface(source: TypescriptFile, descriptor: ServiceDescriptorProto): ts.InterfaceDeclaration;
private createUnary;
private createServerStreaming;
private createClientStreaming;
private createBidi;
}

View file

@ -0,0 +1,78 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceServerGeneratorGeneric = void 0;
const generator_base_1 = require("./generator-base");
const ts = require("typescript");
const runtime_1 = require("@protobuf-ts/runtime");
const local_type_name_1 = require("./local-type-name");
class ServiceServerGeneratorGeneric extends generator_base_1.GeneratorBase {
constructor(symbols, registry, imports, comments, interpreter, options) {
super(symbols, registry, imports, comments, interpreter);
this.options = options;
this.symbolKindInterface = 'generic-server-interface';
}
registerSymbols(source, descriptor) {
const basename = local_type_name_1.createLocalTypeName(descriptor, this.registry);
const interfaceName = `I${basename}`;
this.symbols.register(interfaceName, descriptor, source, this.symbolKindInterface);
}
generateInterface(source, descriptor) {
const interpreterType = this.interpreter.getServiceType(descriptor), IGenericServer = this.imports.type(source, descriptor, this.symbolKindInterface), ServerCallContext = this.imports.name(source, "ServerCallContext", this.options.runtimeRpcImportPath);
const statement = ts.createInterfaceDeclaration(undefined, [ts.createModifier(ts.SyntaxKind.ExportKeyword)], ts.createIdentifier(IGenericServer), [
ts.createTypeParameterDeclaration("T", undefined, ts.createTypeReferenceNode(ts.createIdentifier(ServerCallContext), undefined))
], undefined, interpreterType.methods.map(mi => {
const methodDescriptor = descriptor.method.find(md => md.name === mi.name);
runtime_1.assert(methodDescriptor);
let signature;
if (mi.serverStreaming && mi.clientStreaming) {
signature = this.createBidi(source, mi);
}
else if (mi.serverStreaming) {
signature = this.createServerStreaming(source, mi);
}
else if (mi.clientStreaming) {
signature = this.createClientStreaming(source, mi);
}
else {
signature = this.createUnary(source, mi);
}
this.comments.addCommentsForDescriptor(signature, methodDescriptor, 'appendToLeadingBlock');
return signature;
}));
// add to our file
this.comments.addCommentsForDescriptor(statement, descriptor, 'appendToLeadingBlock');
source.addStatement(statement);
return statement;
}
createUnary(source, methodInfo) {
const I = ts.createTypeReferenceNode(ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.I.typeName))), undefined), O = ts.createTypeReferenceNode(ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.O.typeName))), undefined);
return ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("request"), undefined, I, undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("context"), undefined, ts.createTypeReferenceNode(ts.createIdentifier("T"), undefined), undefined)
], ts.createTypeReferenceNode(ts.createIdentifier("Promise"), [O]), ts.createIdentifier(methodInfo.localName), undefined);
}
createServerStreaming(source, methodInfo) {
const I = ts.createTypeReferenceNode(ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.I.typeName))), undefined), O = ts.createTypeReferenceNode(ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.O.typeName))), undefined), RpcInputStream = this.imports.name(source, 'RpcInputStream', this.options.runtimeRpcImportPath);
return ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("request"), undefined, I, undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("responses"), undefined, ts.createTypeReferenceNode(ts.createIdentifier(RpcInputStream), [O]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("context"), undefined, ts.createTypeReferenceNode(ts.createIdentifier("T"), undefined), undefined)
], ts.createTypeReferenceNode(ts.createIdentifier("Promise"), [ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)]), ts.createIdentifier(methodInfo.localName), undefined);
}
createClientStreaming(source, methodInfo) {
const I = ts.createTypeReferenceNode(ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.I.typeName))), undefined), O = ts.createTypeReferenceNode(ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.O.typeName))), undefined), RpcOutputStream = this.imports.name(source, 'RpcOutputStream', this.options.runtimeRpcImportPath);
return ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("requests"), undefined, ts.createTypeReferenceNode(ts.createIdentifier(RpcOutputStream), [I]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("context"), undefined, ts.createTypeReferenceNode(ts.createIdentifier("T"), undefined), undefined)
], ts.createTypeReferenceNode(ts.createIdentifier("Promise"), [O]), ts.createIdentifier(methodInfo.localName), undefined);
}
createBidi(source, methodInfo) {
const I = ts.createTypeReferenceNode(ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.I.typeName))), undefined), O = ts.createTypeReferenceNode(ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.O.typeName))), undefined), RpcOutputStream = this.imports.name(source, 'RpcOutputStream', this.options.runtimeRpcImportPath), RpcInputStream = this.imports.name(source, 'RpcInputStream', this.options.runtimeRpcImportPath);
return ts.createMethodSignature(undefined, [
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("requests"), undefined, ts.createTypeReferenceNode(ts.createIdentifier(RpcOutputStream), [I]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("responses"), undefined, ts.createTypeReferenceNode(ts.createIdentifier(RpcInputStream), [O]), undefined),
ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("context"), undefined, ts.createTypeReferenceNode(ts.createIdentifier("T"), undefined), undefined)
], ts.createTypeReferenceNode(ts.createIdentifier("Promise"), [ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)]), ts.createIdentifier(methodInfo.localName), undefined);
}
}
exports.ServiceServerGeneratorGeneric = ServiceServerGeneratorGeneric;

View file

@ -0,0 +1,16 @@
import { GeneratorBase } from "./generator-base";
import { DescriptorRegistry, ServiceDescriptorProto, SymbolTable, TypescriptFile, TypeScriptImports } from "@protobuf-ts/plugin-framework";
import { Interpreter } from "../interpreter";
import * as ts from "typescript";
import { CommentGenerator } from "./comment-generator";
export declare class ServiceServerGeneratorGrpc extends GeneratorBase {
private readonly options;
private readonly symbolKindInterface;
private readonly symbolKindDefinition;
constructor(symbols: SymbolTable, registry: DescriptorRegistry, imports: TypeScriptImports, comments: CommentGenerator, interpreter: Interpreter, options: {});
registerSymbols(source: TypescriptFile, descriptor: ServiceDescriptorProto): void;
generateInterface(source: TypescriptFile, descriptor: ServiceDescriptorProto): ts.InterfaceDeclaration;
private createMethodPropertySignature;
generateDefinition(source: TypescriptFile, descriptor: ServiceDescriptorProto): ts.VariableStatement;
private makeDefinitionProperty;
}

View file

@ -0,0 +1,89 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceServerGeneratorGrpc = void 0;
const generator_base_1 = require("./generator-base");
const plugin_framework_1 = require("@protobuf-ts/plugin-framework");
const ts = require("typescript");
const runtime_1 = require("@protobuf-ts/runtime");
const local_type_name_1 = require("./local-type-name");
class ServiceServerGeneratorGrpc extends generator_base_1.GeneratorBase {
constructor(symbols, registry, imports, comments, interpreter, options) {
super(symbols, registry, imports, comments, interpreter);
this.options = options;
this.symbolKindInterface = 'grpc-server-interface';
this.symbolKindDefinition = 'grpc-server-definition';
}
registerSymbols(source, descriptor) {
const basename = local_type_name_1.createLocalTypeName(descriptor, this.registry);
const interfaceName = `I${basename}`;
const definitionName = `${basename[0].toLowerCase()}${basename.substring(1)}Definition`;
this.symbols.register(interfaceName, descriptor, source, this.symbolKindInterface);
this.symbols.register(definitionName, descriptor, source, this.symbolKindDefinition);
}
generateInterface(source, descriptor) {
const interpreterType = this.interpreter.getServiceType(descriptor), IGrpcServer = this.imports.type(source, descriptor, this.symbolKindInterface), grpc = this.imports.namespace(source, 'grpc', '@grpc/grpc-js', true);
const statement = ts.createInterfaceDeclaration(undefined, [ts.createModifier(ts.SyntaxKind.ExportKeyword)], ts.createIdentifier(IGrpcServer), undefined, [ts.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [ts.createExpressionWithTypeArguments(undefined, ts.createPropertyAccess(ts.createIdentifier(grpc), ts.createIdentifier("UntypedServiceImplementation")))])], interpreterType.methods.map(mi => {
const methodDescriptor = descriptor.method.find(md => md.name === mi.name);
runtime_1.assert(methodDescriptor);
return this.createMethodPropertySignature(source, mi, methodDescriptor);
}));
// add to our file
this.comments.addCommentsForDescriptor(statement, descriptor, 'appendToLeadingBlock');
source.addStatement(statement);
return statement;
}
createMethodPropertySignature(source, methodInfo, methodDescriptor) {
const grpc = this.imports.namespace(source, 'grpc', '@grpc/grpc-js', true);
let handler;
if (methodInfo.serverStreaming && methodInfo.clientStreaming) {
handler = 'handleBidiStreamingCall';
}
else if (methodInfo.serverStreaming) {
handler = 'handleServerStreamingCall';
}
else if (methodInfo.clientStreaming) {
handler = 'handleClientStreamingCall';
}
else {
handler = 'handleUnaryCall';
}
const signature = ts.createPropertySignature(undefined, ts.createIdentifier(methodInfo.localName), undefined, ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier(handler)), [
ts.createTypeReferenceNode(ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.I.typeName))), undefined),
ts.createTypeReferenceNode(ts.createIdentifier(this.imports.type(source, this.registry.resolveTypeName(methodInfo.O.typeName))), undefined),
]), undefined);
this.comments.addCommentsForDescriptor(signature, methodDescriptor, 'appendToLeadingBlock');
return signature;
}
generateDefinition(source, descriptor) {
const grpcServerDefinition = this.imports.type(source, descriptor, this.symbolKindDefinition), IGrpcServer = this.imports.type(source, descriptor, this.symbolKindInterface), interpreterType = this.interpreter.getServiceType(descriptor), grpc = this.imports.namespace(source, 'grpc', '@grpc/grpc-js', true);
const statement = ts.createVariableStatement([ts.createModifier(ts.SyntaxKind.ExportKeyword)], ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier(grpcServerDefinition), ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier(grpc), ts.createIdentifier("ServiceDefinition")), [ts.createTypeReferenceNode(ts.createIdentifier(IGrpcServer), undefined)]), ts.createObjectLiteral(interpreterType.methods.map(mi => this.makeDefinitionProperty(source, mi)), true))], ts.NodeFlags.Const));
// add to our file
const doc = `@grpc/grpc-js definition for the protobuf ${this.registry.formatQualifiedName(descriptor)}.\n` +
`\n` +
`Usage: Implement the interface ${IGrpcServer} and add to a grpc server.\n` +
`\n` +
'```typescript\n' +
`const server = new grpc.Server();\n` +
`const service: ${IGrpcServer} = ...\n` +
`server.addService(${grpcServerDefinition}, service);\n` +
'```';
plugin_framework_1.addCommentBlockAsJsDoc(statement, doc);
source.addStatement(statement);
return statement;
}
makeDefinitionProperty(source, methodInfo) {
const I = this.imports.type(source, this.registry.resolveTypeName(methodInfo.I.typeName));
const O = this.imports.type(source, this.registry.resolveTypeName(methodInfo.O.typeName));
return ts.createPropertyAssignment(ts.createIdentifier(methodInfo.localName), ts.createObjectLiteral([
ts.createPropertyAssignment(ts.createIdentifier("path"), ts.createStringLiteral(`/${methodInfo.service.typeName}/${methodInfo.name}`)),
ts.createPropertyAssignment(ts.createIdentifier("originalName"), ts.createStringLiteral(methodInfo.name)),
ts.createPropertyAssignment(ts.createIdentifier("requestStream"), methodInfo.clientStreaming ? ts.createTrue() : ts.createFalse()),
ts.createPropertyAssignment(ts.createIdentifier("responseStream"), methodInfo.serverStreaming ? ts.createTrue() : ts.createFalse()),
ts.createPropertyAssignment(ts.createIdentifier("responseDeserialize"), ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("bytes"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier(O), ts.createIdentifier("fromBinary")), undefined, [ts.createIdentifier("bytes")]))),
ts.createPropertyAssignment(ts.createIdentifier("requestDeserialize"), ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("bytes"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier(I), ts.createIdentifier("fromBinary")), undefined, [ts.createIdentifier("bytes")]))),
ts.createPropertyAssignment(ts.createIdentifier("responseSerialize"), ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Buffer"), ts.createIdentifier("from")), undefined, [ts.createCall(ts.createPropertyAccess(ts.createIdentifier(O), ts.createIdentifier("toBinary")), undefined, [ts.createIdentifier("value")])]))),
ts.createPropertyAssignment(ts.createIdentifier("requestSerialize"), ts.createArrowFunction(undefined, undefined, [ts.createParameter(undefined, undefined, undefined, ts.createIdentifier("value"), undefined, undefined, undefined)], undefined, ts.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Buffer"), ts.createIdentifier("from")), undefined, [ts.createCall(ts.createPropertyAccess(ts.createIdentifier(I), ts.createIdentifier("toBinary")), undefined, [ts.createIdentifier("value")])])))
], true));
}
}
exports.ServiceServerGeneratorGrpc = ServiceServerGeneratorGrpc;

View file

@ -0,0 +1,12 @@
import { DescriptorRegistry, ServiceDescriptorProto, SymbolTable, TypescriptFile, TypeScriptImports } from "@protobuf-ts/plugin-framework";
import { Interpreter } from "../interpreter";
import { CommentGenerator } from "./comment-generator";
import { GeneratorBase } from "./generator-base";
export declare class ServiceTypeGenerator extends GeneratorBase {
private readonly options;
private readonly methodInfoGenerator;
constructor(symbols: SymbolTable, registry: DescriptorRegistry, imports: TypeScriptImports, comments: CommentGenerator, interpreter: Interpreter, options: {
runtimeRpcImportPath: string;
});
generateServiceType(source: TypescriptFile, descriptor: ServiceDescriptorProto): void;
}

View file

@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceTypeGenerator = void 0;
const plugin_framework_1 = require("@protobuf-ts/plugin-framework");
const ts = require("typescript");
const method_info_generator_1 = require("./method-info-generator");
const generator_base_1 = require("./generator-base");
class ServiceTypeGenerator extends generator_base_1.GeneratorBase {
constructor(symbols, registry, imports, comments, interpreter, options) {
super(symbols, registry, imports, comments, interpreter);
this.options = options;
this.methodInfoGenerator = new method_info_generator_1.MethodInfoGenerator(this.registry, this.imports);
}
// export const Haberdasher = new ServiceType("spec.haberdasher.Haberdasher", [
// { name: "MakeHat", localName: "makeHat", I: Size, O: Hat },
// ], {});
generateServiceType(source, descriptor) {
const
// identifier for the service
MyService = this.imports.type(source, descriptor), ServiceType = this.imports.name(source, "ServiceType", this.options.runtimeRpcImportPath), interpreterType = this.interpreter.getServiceType(descriptor);
const args = [
ts.createStringLiteral(interpreterType.typeName),
this.methodInfoGenerator.createMethodInfoLiterals(source, interpreterType.methods)
];
if (Object.keys(interpreterType.options).length) {
args.push(plugin_framework_1.typescriptLiteralFromValue(interpreterType.options));
}
const exportConst = ts.createVariableStatement([ts.createModifier(ts.SyntaxKind.ExportKeyword)], ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier(MyService), undefined, ts.createNew(ts.createIdentifier(ServiceType), undefined, args))], ts.NodeFlags.Const));
// add to our file
source.addStatement(exportConst);
// add comments
let comment = this.comments.makeDeprecatedTag(descriptor);
comment += this.comments.makeGeneratedTag(descriptor).replace("@generated from ", "@generated ServiceType for ");
plugin_framework_1.addCommentBlockAsJsDoc(exportConst, comment);
return;
}
}
exports.ServiceTypeGenerator = ServiceTypeGenerator;