-
Notifications
You must be signed in to change notification settings - Fork 134
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#56 generate generic server interfaces
- Loading branch information
Showing
8 changed files
with
358 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 25 additions & 13 deletions
38
packages/example-node-generic-server/service-example.server.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,29 @@ | ||
import {ExampleRequest, ExampleResponse} from "./service-example"; | ||
import {RpcInputStream, RpcOutputStream, ServerCallContext} from "@protobuf-ts/runtime-rpc"; | ||
|
||
|
||
// TODO generate this interface if (ts.server) = GENERIC or --ts_opt server_generic | ||
// @generated by protobuf-ts 2.0.0-alpha.8 with parameters server_generic,client_none,generate_dependencies,optimize_code_size | ||
// @generated from protobuf file "service-example.proto" (package "spec", syntax proto3) | ||
// tslint:disable | ||
import { RpcOutputStream } from "@protobuf-ts/runtime-rpc"; | ||
import { RpcInputStream } from "@protobuf-ts/runtime-rpc"; | ||
import { ServerCallContext } from "@protobuf-ts/runtime-rpc"; | ||
import { ExampleResponse } from "./service-example"; | ||
import { ExampleRequest } from "./service-example"; | ||
/** | ||
* @generated from protobuf service spec.ExampleService | ||
*/ | ||
export interface IExampleService { | ||
|
||
/** | ||
* @generated from protobuf rpc: Unary(spec.ExampleRequest) returns (spec.ExampleResponse); | ||
*/ | ||
unary(request: ExampleRequest, context: ServerCallContext): Promise<ExampleResponse>; | ||
|
||
/** | ||
* @generated from protobuf rpc: ServerStream(spec.ExampleRequest) returns (stream spec.ExampleResponse); | ||
*/ | ||
serverStream(request: ExampleRequest, responses: RpcInputStream<ExampleResponse>, context: ServerCallContext): Promise<void>; | ||
|
||
clientStream(requests: RpcOutputStream, context: ServerCallContext): Promise<ExampleResponse>; | ||
|
||
bidi(requests: RpcOutputStream, responses: RpcInputStream<ExampleResponse>, context: ServerCallContext): Promise<void>; | ||
|
||
/** | ||
* @generated from protobuf rpc: ClientStream(stream spec.ExampleRequest) returns (spec.ExampleResponse); | ||
*/ | ||
clientStream(requests: RpcOutputStream<ExampleRequest>, context: ServerCallContext): Promise<ExampleResponse>; | ||
/** | ||
* @generated from protobuf rpc: Bidi(stream spec.ExampleRequest) returns (stream spec.ExampleResponse); | ||
*/ | ||
bidi(requests: RpcOutputStream<ExampleRequest>, responses: RpcInputStream<ExampleResponse>, context: ServerCallContext): Promise<void>; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
294 changes: 294 additions & 0 deletions
294
packages/plugin/src/code-gen/service-server-generator-generic.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,294 @@ | ||
import {GeneratorBase} from "./generator-base"; | ||
import * as rpc from "@protobuf-ts/runtime-rpc"; | ||
import { | ||
DescriptorRegistry, | ||
ServiceDescriptorProto, | ||
SymbolTable, | ||
TypescriptFile, | ||
TypeScriptImports | ||
} from "@protobuf-ts/plugin-framework"; | ||
import {Interpreter} from "../interpreter"; | ||
import * as ts from "typescript"; | ||
import {assert} from "@protobuf-ts/runtime"; | ||
import {CommentGenerator} from "./comment-generator"; | ||
import {createLocalTypeName} from "./local-type-name"; | ||
|
||
|
||
export class ServiceServerGeneratorGeneric extends GeneratorBase { | ||
|
||
|
||
private readonly symbolKindInterface = 'generic-server-interface'; | ||
|
||
|
||
constructor(symbols: SymbolTable, registry: DescriptorRegistry, imports: TypeScriptImports, comments: CommentGenerator, interpreter: Interpreter, | ||
private readonly options: { | ||
runtimeRpcImportPath: string; | ||
}) { | ||
super(symbols, registry, imports, comments, interpreter); | ||
} | ||
|
||
|
||
registerSymbols(source: TypescriptFile, descriptor: ServiceDescriptorProto): void { | ||
const basename = createLocalTypeName(descriptor, this.registry); | ||
const interfaceName = `I${basename}`; | ||
this.symbols.register(interfaceName, descriptor, source, this.symbolKindInterface); | ||
} | ||
|
||
|
||
generateInterface(source: TypescriptFile, descriptor: ServiceDescriptorProto) { | ||
const | ||
interpreterType = this.interpreter.getServiceType(descriptor), | ||
IGenericServer = this.imports.type(source, descriptor, this.symbolKindInterface) | ||
; | ||
|
||
const statement = ts.createInterfaceDeclaration( | ||
undefined, | ||
[ts.createModifier(ts.SyntaxKind.ExportKeyword)], | ||
ts.createIdentifier(IGenericServer), | ||
undefined, | ||
undefined, | ||
interpreterType.methods.map(mi => { | ||
const methodDescriptor = descriptor.method.find(md => md.name === mi.name); | ||
assert(methodDescriptor); | ||
let signature: ts.MethodSignature; | ||
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; | ||
} | ||
|
||
|
||
private createUnary(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodSignature { | ||
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), | ||
ServerCallContext = this.imports.name(source, 'ServerCallContext', 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("context"), | ||
undefined, | ||
ts.createTypeReferenceNode( | ||
ts.createIdentifier(ServerCallContext), | ||
undefined | ||
), | ||
undefined | ||
) | ||
], | ||
ts.createTypeReferenceNode( | ||
ts.createIdentifier("Promise"), | ||
[O] | ||
), | ||
ts.createIdentifier(methodInfo.localName), | ||
undefined | ||
); | ||
} | ||
|
||
|
||
private createServerStreaming(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodSignature { | ||
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), | ||
ServerCallContext = this.imports.name(source, 'ServerCallContext', this.options.runtimeRpcImportPath), | ||
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(ServerCallContext), | ||
undefined | ||
), | ||
undefined | ||
) | ||
], | ||
ts.createTypeReferenceNode( | ||
ts.createIdentifier("Promise"), | ||
[ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)] | ||
), | ||
ts.createIdentifier(methodInfo.localName), | ||
undefined | ||
); | ||
} | ||
|
||
|
||
|
||
private createClientStreaming(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodSignature { | ||
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), | ||
ServerCallContext = this.imports.name(source, 'ServerCallContext', this.options.runtimeRpcImportPath), | ||
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(ServerCallContext), | ||
undefined | ||
), | ||
undefined | ||
) | ||
], | ||
ts.createTypeReferenceNode( | ||
ts.createIdentifier("Promise"), | ||
[O] | ||
), | ||
ts.createIdentifier(methodInfo.localName), | ||
undefined | ||
); | ||
} | ||
|
||
|
||
private createBidi(source: TypescriptFile, methodInfo: rpc.MethodInfo): ts.MethodSignature { | ||
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), | ||
ServerCallContext = this.imports.name(source, 'ServerCallContext', this.options.runtimeRpcImportPath), | ||
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(ServerCallContext), | ||
undefined | ||
), | ||
undefined | ||
) | ||
], | ||
ts.createTypeReferenceNode( | ||
ts.createIdentifier("Promise"), | ||
[ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)] | ||
), | ||
ts.createIdentifier(methodInfo.localName), | ||
undefined | ||
); | ||
} | ||
|
||
|
||
} |
Oops, something went wrong.