protoc-gen-tsd
Version:
Protocol Buffers Compiler(protoc) plugin for TypeScript - Generate definition file(d.ts)
188 lines (187 loc) • 8.98 kB
JavaScript
;
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;