UNPKG

protoc-gen-tsd

Version:

Protocol Buffers Compiler(protoc) plugin for TypeScript - Generate definition file(d.ts)

188 lines (187 loc) 8.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.formatMessageTypeDescriptorProto = exports.DefaultMessageFieldType = exports.DefaultMessageType = void 0; const descriptor_pb_1 = require("google-protobuf/google/protobuf/descriptor_pb"); const field_descriptor_formatter_1 = require("./field-descriptor-formatter"); const enum_descriptor_formatter_1 = require("./enum-descriptor-formatter"); const extension_descriptor_formatter_1 = require("./extension-descriptor-formatter"); const oneof_descriptor_formatter_1 = require("./oneof-descriptor-formatter"); const util_1 = require("../util"); exports.DefaultMessageType = JSON.stringify({ messageName: '', oneofGroups: [], oneofDeclList: [], fields: [], nestedTypes: [], formattedEnumListStr: [], formattedOneofListStr: [], formattedExtListStr: [], }); exports.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, fileDescriptorProto) { if (field.getLabel() === descriptor_pb_1.FieldDescriptorProto.Label.LABEL_REPEATED) { return false; } if (field.hasOneofIndex()) { return true; } if (field.getType() === field_descriptor_formatter_1.MESSAGE_TYPE) { return true; } return util_1.isProto2Syntax(fileDescriptorProto); } function formatMessageTypeDescriptorProto(protoFileName, protoAbstractSyntaxTreeMap, messageTypeDescriptorProto, indent, fileDescriptorProto) { const nextIndent = `${indent} `; const messageData = JSON.parse(exports.DefaultMessageType); messageData.messageName = messageTypeDescriptorProto.getName(); messageData.oneofDeclList = messageTypeDescriptorProto.getOneofDeclList(); const messageOptions = messageTypeDescriptorProto.getOptions(); if (messageOptions !== undefined && messageOptions.getMapEntry()) { return null; } const oneofGroups = []; messageTypeDescriptorProto.getFieldList().forEach((field) => { const fieldData = JSON.parse(exports.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 = util_1.snakeToCamel(fieldData.snakeCaseName); fieldData.camelUpperName = util_1.uppercaseFirst(fieldData.camelCaseName); if (util_1.isReservedWord(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 === field_descriptor_formatter_1.MESSAGE_TYPE) { const fieldMessageType = protoAbstractSyntaxTreeMap.getMessage(fullTypeName); if (fieldMessageType === undefined) { throw new Error('No message export for: ' + fullTypeName); } fieldData.isMapField = fieldMessageType.messageDescriptorOptions !== undefined && fieldMessageType.messageDescriptorOptions.getMapEntry(); if (fieldData.isMapField) { const mapData = {}; const keyTuple = fieldMessageType.mapFieldOptions.key; const keyType = keyTuple[0]; const keyTypeName = field_descriptor_formatter_1.getFieldType(keyType, keyTuple[1], protoFileName, protoAbstractSyntaxTreeMap); const valueTuple = fieldMessageType.mapFieldOptions.value; const valueType = valueTuple[0]; let valueTypeName = field_descriptor_formatter_1.getFieldType(valueType, valueTuple[1], protoFileName, protoAbstractSyntaxTreeMap); if (valueType === field_descriptor_formatter_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 = util_1.withinNamespaceFromExportEntry(fullTypeName, fieldMessageType); if (fieldMessageType.protoFileName === protoFileName) { exportType = withinNamespace; } else { exportType = util_1.filePathToPseudoNamespace(fieldMessageType.protoFileName) + '.' + withinNamespace; } fieldData.exportType = exportType; } else if (fieldData.type === field_descriptor_formatter_1.ENUM_TYPE) { const fieldEnumType = protoAbstractSyntaxTreeMap.getEnum(fullTypeName); if (fieldEnumType === undefined) { throw new Error('No enum export for: ' + fullTypeName); } const withinNamespace = util_1.withinNamespaceFromExportEntry(fullTypeName, fieldEnumType); if (fieldEnumType.protoFileName === protoFileName) { exportType = withinNamespace; } else { exportType = util_1.filePathToPseudoNamespace(fieldEnumType.protoFileName) + '.' + withinNamespace; } fieldData.exportType = exportType; } else { let type = field_descriptor_formatter_1.getTypeName(fieldData.type); const options = field.getOptions(); if (options && options.hasJstype()) { const jstype = field_descriptor_formatter_1.getJsTypeName(options.getJstype()); if (jstype) { type = jstype; } } exportType = fieldData.exportType = type; } fieldData.isOptionalValue = field.getType() === field_descriptor_formatter_1.MESSAGE_TYPE; fieldData.isRepeatField = field.getLabel() === descriptor_pb_1.FieldDescriptorProto.Label.LABEL_REPEATED; if (!fieldData.isRepeatField && fieldData.type !== field_descriptor_formatter_1.BYTES_TYPE) { let fieldObjectType = exportType; let canBeUndefined = false; if (fieldData.type === field_descriptor_formatter_1.MESSAGE_TYPE) { if (!util_1.isProto2Syntax(fileDescriptorProto) || field.getLabel() === descriptor_pb_1.FieldDescriptorProto.Label.LABEL_OPTIONAL) { canBeUndefined = true; } } else { if (util_1.isProto2Syntax(fileDescriptorProto)) { canBeUndefined = true; } } fieldData.fieldObjectType = fieldObjectType; fieldData.canBeUndefined = canBeUndefined; } fieldData.hasFieldPresence = hasFieldPresence(field, fileDescriptorProto); messageData.fields.push(fieldData); }); messageTypeDescriptorProto.getNestedTypeList().forEach((nestedMessage) => { const msgOutput = formatMessageTypeDescriptorProto(protoFileName, protoAbstractSyntaxTreeMap, nestedMessage, nextIndent, fileDescriptorProto); if (msgOutput !== null) { messageData.nestedTypes.push(msgOutput); } }); messageTypeDescriptorProto.getEnumTypeList().forEach((enumType) => { messageData.formattedEnumListStr.push(enum_descriptor_formatter_1.formatEnumDescriptorProto(enumType, nextIndent)); }); messageTypeDescriptorProto .getOneofDeclList() .forEach((oneOfDecl, index) => { messageData.formattedOneofListStr.push(oneof_descriptor_formatter_1.formatOneofProto(oneOfDecl, oneofGroups[index] || [], nextIndent)); }); messageTypeDescriptorProto.getExtensionList().forEach((extension) => { messageData.formattedExtListStr.push(extension_descriptor_formatter_1.formatExtensionDescriptorProto(protoFileName, protoAbstractSyntaxTreeMap, extension, nextIndent)); }); return { indent, BYTES_TYPE: field_descriptor_formatter_1.BYTES_TYPE, MESSAGE_TYPE: field_descriptor_formatter_1.MESSAGE_TYPE, message: messageData, }; } exports.formatMessageTypeDescriptorProto = formatMessageTypeDescriptorProto;