UNPKG

grpc_tools_node_protoc_ts

Version:

Generate d.ts definitions for generated js files from grpc_tools_node_protoc

232 lines 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MessageFormatter = exports.OBJECT_TYPE_NAME = void 0; const descriptor_pb_1 = require("google-protobuf/google/protobuf/descriptor_pb"); const Utility_1 = require("../../Utility"); const FieldTypesFormatter_1 = require("./FieldTypesFormatter"); const EnumFormatter_1 = require("./EnumFormatter"); const ExtensionFormatter_1 = require("./ExtensionFormatter"); const OneofFormatter_1 = require("./OneofFormatter"); const TplEngine_1 = require("../../TplEngine"); exports.OBJECT_TYPE_NAME = "AsObject"; var MessageFormatter; (function (MessageFormatter) { MessageFormatter.defaultMessageType = JSON.stringify({ messageName: "", oneofGroups: [], oneofDeclList: [], fields: [], nestedTypes: [], formattedEnumListStr: [], formattedOneofListStr: [], formattedExtListStr: [], }); MessageFormatter.defaultMessageFieldType = JSON.stringify({ snakeCaseName: "", camelCaseName: "", camelUpperName: "", fieldObjectType: "", type: undefined, exportType: "", isMapField: false, mapFieldInfo: undefined, isRepeatField: false, isOptionalValue: false, canBeUndefined: false, hasClearMethodCreated: false, hasFieldPresence: false, }); function hasFieldPresence(field, descriptor) { if (field.getLabel() === descriptor_pb_1.FieldDescriptorProto.Label.LABEL_REPEATED) { return false; } if (field.hasProto3Optional()) { return true; } if (field.hasOneofIndex()) { return true; } if (field.getType() === FieldTypesFormatter_1.MESSAGE_TYPE) { return true; } return Utility_1.Utility.isProto2(descriptor); } function format(fileName, exportMap, descriptor, indent, fileDescriptor) { const nextIndent = `${indent} `; const messageData = JSON.parse(MessageFormatter.defaultMessageType); const proto3OptionalFields = new Set(); descriptor.getFieldList().forEach((field) => { if (field.hasName() && field.hasProto3Optional()) { proto3OptionalFields.add(field.getName()); } }); messageData.messageName = descriptor.getName(); messageData.oneofDeclList = descriptor.getOneofDeclList().filter((oneOfDecl) => { const name = oneOfDecl.getName(); return !(name && name.length > 1 && proto3OptionalFields.has(name.substring(1))); }); const messageOptions = descriptor.getOptions(); if (messageOptions !== undefined && messageOptions.getMapEntry()) { // this message type is the entry tuple for a map - don't output it return null; } const oneofGroups = []; descriptor.getFieldList().forEach((field) => { const fieldData = JSON.parse(MessageFormatter.defaultMessageFieldType); if (field.hasOneofIndex()) { const oneOfIndex = field.getOneofIndex(); let existing = oneofGroups[oneOfIndex]; if (existing === undefined) { existing = []; oneofGroups[oneOfIndex] = existing; } existing.push(field); } fieldData.snakeCaseName = field.getName().toLowerCase(); fieldData.camelCaseName = Utility_1.Utility.snakeToCamel(fieldData.snakeCaseName); fieldData.camelUpperName = Utility_1.Utility.uppercaseFirst(fieldData.camelCaseName); // handle reserved keywords in field names like Javascript generator // see: https://github.com/google/protobuf/blob/ed4321d1cb33199984118d801956822842771e7e/src/google/protobuf/compiler/js/js_generator.cc#L508-L510 if (Utility_1.Utility.isReserved(fieldData.camelCaseName)) { fieldData.camelCaseName = `pb_${fieldData.camelCaseName}`; } fieldData.type = field.getType(); fieldData.isMapField = false; fieldData.canBeUndefined = false; let exportType; const fullTypeName = field.getTypeName().slice(1); if (fieldData.type === FieldTypesFormatter_1.MESSAGE_TYPE) { const fieldMessageType = exportMap.getMessage(fullTypeName); if (fieldMessageType === undefined) { throw new Error("No message export for: " + fullTypeName); } fieldData.isMapField = fieldMessageType.messageOptions !== undefined && fieldMessageType.messageOptions.getMapEntry(); if (fieldData.isMapField) { const mapData = {}; const keyTuple = fieldMessageType.mapFieldOptions.key; const keyType = keyTuple[0]; const keyTypeName = FieldTypesFormatter_1.FieldTypesFormatter.getFieldType(keyType, keyTuple[1], fileName, exportMap); const valueTuple = fieldMessageType.mapFieldOptions.value; const valueType = valueTuple[0]; let valueTypeName = FieldTypesFormatter_1.FieldTypesFormatter.getFieldType(valueType, valueTuple[1], fileName, exportMap); if (valueType === FieldTypesFormatter_1.BYTES_TYPE) { valueTypeName = "Uint8Array | string"; } mapData.keyType = keyType; mapData.keyTypeName = keyTypeName; mapData.valueType = valueType; mapData.valueTypeName = valueTypeName; fieldData.mapFieldInfo = mapData; messageData.fields.push(fieldData); return; } const withinNamespace = Utility_1.Utility.withinNamespaceFromExportEntry(fullTypeName, fieldMessageType); if (fieldMessageType.fileName === fileName) { exportType = withinNamespace; } else { exportType = Utility_1.Utility.filePathToPseudoNamespace(fieldMessageType.fileName) + "." + withinNamespace; } fieldData.exportType = exportType; } else if (fieldData.type === FieldTypesFormatter_1.ENUM_TYPE) { const fieldEnumType = exportMap.getEnum(fullTypeName); if (fieldEnumType === undefined) { throw new Error("No enum export for: " + fullTypeName); } const withinNamespace = Utility_1.Utility.withinNamespaceFromExportEntry(fullTypeName, fieldEnumType); if (fieldEnumType.fileName === fileName) { exportType = withinNamespace; } else { exportType = Utility_1.Utility.filePathToPseudoNamespace(fieldEnumType.fileName) + "." + withinNamespace; } fieldData.exportType = exportType; } else { let type = FieldTypesFormatter_1.FieldTypesFormatter.getTypeName(fieldData.type); // Check for [jstype = JS_STRING] overrides const options = field.getOptions(); if (options && options.hasJstype()) { const jstype = FieldTypesFormatter_1.FieldTypesFormatter.getJsTypeName(options.getJstype()); if (jstype) { type = jstype; } } exportType = fieldData.exportType = type; } fieldData.isOptionalValue = field.getType() === FieldTypesFormatter_1.MESSAGE_TYPE; fieldData.isRepeatField = field.getLabel() === descriptor_pb_1.FieldDescriptorProto.Label.LABEL_REPEATED; if (!fieldData.isRepeatField && fieldData.type !== FieldTypesFormatter_1.BYTES_TYPE) { let fieldObjectType = exportType; let canBeUndefined = false; if (fieldData.type === FieldTypesFormatter_1.MESSAGE_TYPE) { fieldObjectType += ".AsObject"; if (!Utility_1.Utility.isProto2(fileDescriptor) || (field.getLabel() === descriptor_pb_1.FieldDescriptorProto.Label.LABEL_OPTIONAL)) { canBeUndefined = true; } } else if (field.getProto3Optional()) { canBeUndefined = true; } else { if (Utility_1.Utility.isProto2(fileDescriptor)) { canBeUndefined = true; } } fieldData.fieldObjectType = fieldObjectType; fieldData.canBeUndefined = canBeUndefined; } fieldData.hasFieldPresence = hasFieldPresence(field, fileDescriptor); messageData.fields.push(fieldData); }); descriptor.getNestedTypeList().forEach((nested) => { const msgOutput = format(fileName, exportMap, nested, nextIndent, fileDescriptor); if (msgOutput !== null) { // If the message class is a Map entry then it isn't output, so don't print the namespace block messageData.nestedTypes.push(msgOutput); } }); descriptor.getEnumTypeList().forEach((enumType) => { messageData.formattedEnumListStr.push(EnumFormatter_1.EnumFormatter.format(enumType, nextIndent)); }); descriptor.getOneofDeclList().forEach((oneOfDecl, index) => { const name = oneOfDecl.getName(); if (name && name.length > 1 && proto3OptionalFields.has(name.substring(1))) { // Skip synthetic one-ofs for proto3 optional fields return; } messageData.formattedOneofListStr.push(OneofFormatter_1.OneofFormatter.format(oneOfDecl, oneofGroups[index] || [], nextIndent)); }); descriptor.getExtensionList().forEach((extension) => { messageData.formattedExtListStr.push(ExtensionFormatter_1.ExtensionFormatter.format(fileName, exportMap, extension, nextIndent)); }); TplEngine_1.TplEngine.registerHelper("printClearIfNotPresent", (fieldData) => { if (!fieldData.hasClearMethodCreated) { fieldData.hasClearMethodCreated = true; if (fieldData.isRepeatField) { return `clear${fieldData.camelUpperName}List(): void;`; } else { return `clear${Utility_1.Utility.formatOccupiedName(fieldData.camelUpperName)}(): void;`; } } }); TplEngine_1.TplEngine.registerHelper("printRepeatedAddMethod", (fieldData, valueType) => { return `add${Utility_1.Utility.formatOccupiedName(fieldData.camelUpperName)}(value${fieldData.isOptionalValue ? "?" : ""}: ${valueType}, index?: number): ${valueType};`; }); TplEngine_1.TplEngine.registerHelper("oneOfName", (oneOfDecl) => { return Utility_1.Utility.oneOfName(oneOfDecl.getName()); }); return { indent, objectTypeName: exports.OBJECT_TYPE_NAME, BYTES_TYPE: FieldTypesFormatter_1.BYTES_TYPE, MESSAGE_TYPE: FieldTypesFormatter_1.MESSAGE_TYPE, message: messageData, }; } MessageFormatter.format = format; })(MessageFormatter = exports.MessageFormatter || (exports.MessageFormatter = {})); //# sourceMappingURL=MessageFormatter.js.map