UNPKG

@protobuf-ts/plugin

Version:

The protocol buffer compiler plugin "protobuf-ts" generates TypeScript, gRPC-web, Twirp, and more.

90 lines (89 loc) 5.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MessageTypeGenerator = void 0; const ts = require("typescript"); 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 wkt_1 = require("@bufbuild/protobuf/wkt"); const typescript_comments_1 = require("../framework/typescript-comments"); const typescript_literal_from_value_1 = require("../framework/typescript-literal-from-value"); class MessageTypeGenerator { constructor(registry, imports, comments, interpreter, options) { this.registry = registry; this.imports = imports; this.comments = comments; this.interpreter = interpreter; this.options = options; this.fieldInfoGenerator = new field_info_generator_1.FieldInfoGenerator(this.registry, this.imports); this.wellKnown = new well_known_types_1.WellKnownTypes(this.imports, this.options); this.googleTypes = new google_types_1.GoogleTypes(this.imports, this.options); this.typeMethodCreate = new create_1.Create(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, descMessage, optimizeFor) { const // identifier for the message MyMessage = this.imports.type(source, descMessage), Message$Type = ts.createIdentifier(this.imports.type(source, descMessage) + '$Type'), MessageType = ts.createIdentifier(this.imports.name(source, "MessageType", this.options.runtimeImportPath)), interpreterType = this.interpreter.getMessageType(descMessage), classDecMembers = [], classDecSuperArgs = [ // arg 0: type name ts.createStringLiteral(descMessage.typeName), // 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(typescript_literal_from_value_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, descMessage)); classDecMembers.push(...this.googleTypes.make(source, descMessage)); // "MyMessage$Type" members for optimized binary format if (optimizeFor === wkt_1.FileOptions_OptimizeMode.SPEED) { classDecMembers.push(...this.typeMethodCreate.make(source, descMessage), ...this.typeMethodInternalBinaryRead.make(source, descMessage), ...this.typeMethodInternalBinaryWrite.make(source, descMessage)); } // 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(descMessage); comment += this.comments.makeGeneratedTag(descMessage).replace("@generated from ", "@generated MessageType for "); typescript_comments_1.addCommentBlockAsJsDoc(exportConst, comment); return; } } exports.MessageTypeGenerator = MessageTypeGenerator;