Bump artifact dependencies if CODEQL_ACTION_ARTIFACT_V2_UPGRADE enabled (#2482)

Co-authored-by: Andrew Eisenberg <aeisenberg@github.com>
Co-authored-by: Henry Mercer <henrymercer@github.com>
This commit is contained in:
Angela P Wen 2024-10-01 09:59:05 -07:00 committed by GitHub
parent cf5b0a9041
commit a196a714b8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5388 changed files with 2176737 additions and 71701 deletions

View file

@ -0,0 +1,334 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DescriptorInfo = exports.isAnyTypeDescriptorProto = void 0;
const descriptor_1 = require("./google/protobuf/descriptor");
const runtime_1 = require("@protobuf-ts/runtime");
const string_format_1 = require("./string-format");
/**
* Is this a first-class type?
*/
function isAnyTypeDescriptorProto(arg) {
return descriptor_1.DescriptorProto.is(arg) || descriptor_1.EnumDescriptorProto.is(arg) || descriptor_1.ServiceDescriptorProto.is(arg);
}
exports.isAnyTypeDescriptorProto = isAnyTypeDescriptorProto;
class DescriptorInfo {
constructor(tree, nameLookup) {
this.tree = tree;
this.nameLookup = nameLookup;
}
getAllExtensions() {
if (!this.allExtensions) {
this.allExtensions = [];
for (let file of this.tree.allFiles()) {
this.allExtensions.push(...file.extension);
for (let msg of file.messageType) {
this.allExtensions.push(...msg.extension);
}
}
}
return this.allExtensions;
}
isExtension(fieldDescriptor) {
if (fieldDescriptor.extendee === undefined) {
return false;
}
const parent = this.tree.parentOf(fieldDescriptor);
return parent.extension.includes(fieldDescriptor);
}
extensionsFor(descriptorOrTypeName) {
let extendeeTypeName;
if (typeof descriptorOrTypeName === "string") {
extendeeTypeName = this.nameLookup.makeTypeName(this.nameLookup.resolveTypeName(descriptorOrTypeName));
}
else {
extendeeTypeName = this.nameLookup.makeTypeName(descriptorOrTypeName);
}
return this.getAllExtensions().filter(ext => this.nameLookup.normalizeTypeName(ext.extendee) === extendeeTypeName);
}
getExtensionName(fieldDescriptor) {
runtime_1.assert(this.isExtension(fieldDescriptor), `${string_format_1.StringFormat.formatName(fieldDescriptor)} is not an extension. use isExtension() before getExtensionName()`);
runtime_1.assert(fieldDescriptor.name);
let extensionName;
let parent = this.tree.parentOf(fieldDescriptor);
if (descriptor_1.FileDescriptorProto.is(parent)) {
extensionName = parent.package
? `${parent.package}.${fieldDescriptor.name}`
: `${fieldDescriptor.name}`;
}
else {
extensionName = `${this.nameLookup.makeTypeName(parent)}.${fieldDescriptor.name}`;
}
return extensionName;
}
getFieldCustomJsonName(fieldDescriptor) {
const name = runtime_1.lowerCamelCase(fieldDescriptor.name);
const jsonName = fieldDescriptor.jsonName;
if (jsonName !== undefined && jsonName !== '' && jsonName !== name) {
return jsonName;
}
return undefined;
}
isEnumField(fieldDescriptor) {
return fieldDescriptor.type === descriptor_1.FieldDescriptorProto_Type.ENUM;
}
getEnumFieldEnum(fieldDescriptor) {
if (fieldDescriptor.type !== descriptor_1.FieldDescriptorProto_Type.ENUM) {
throw new Error(`${string_format_1.StringFormat.formatName(fieldDescriptor)} is not a enum field. use isEnumField() before getEnumFieldEnum().`);
}
runtime_1.assert(fieldDescriptor.typeName !== undefined, `Missing enum type name for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
let enumType = this.nameLookup.peekTypeName(fieldDescriptor.typeName);
runtime_1.assert(enumType !== undefined, `Missing enum type ${fieldDescriptor.typeName} for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
runtime_1.assert(descriptor_1.EnumDescriptorProto.is(enumType), `Invalid enum type for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
return enumType;
}
isMessageField(fieldDescriptor) {
let msg = fieldDescriptor.type === descriptor_1.FieldDescriptorProto_Type.MESSAGE;
if (!msg) {
return false;
}
if (fieldDescriptor.name === undefined) {
return false;
}
if (this.isMapField(fieldDescriptor)) {
return false;
}
return true;
}
isGroupField(fieldDescriptor) {
return fieldDescriptor.type === descriptor_1.FieldDescriptorProto_Type.GROUP;
}
getMessageFieldMessage(fieldDescriptor) {
if (!this.isMessageField(fieldDescriptor)) {
throw new Error(`${string_format_1.StringFormat.formatName(fieldDescriptor)} is not a message field. use isMessageField() before getMessageFieldMessage().`);
}
runtime_1.assert(fieldDescriptor.typeName !== undefined, `Missing message type name for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
let messageType = this.nameLookup.peekTypeName(fieldDescriptor.typeName);
runtime_1.assert(messageType !== undefined, `Missing message type ${fieldDescriptor.typeName} for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
runtime_1.assert(descriptor_1.DescriptorProto.is(messageType), `Invalid message type for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
return messageType;
}
isScalarField(fieldDescriptor) {
switch (fieldDescriptor.type) {
case descriptor_1.FieldDescriptorProto_Type.ENUM:
case descriptor_1.FieldDescriptorProto_Type.MESSAGE:
case descriptor_1.FieldDescriptorProto_Type.GROUP:
case descriptor_1.FieldDescriptorProto_Type.UNSPECIFIED$:
return false;
}
return true;
}
getScalarFieldType(fieldDescriptor) {
if (!this.isScalarField(fieldDescriptor)) {
throw new Error(`${string_format_1.StringFormat.formatName(fieldDescriptor)} is not a scalar field. use isScalarField() before getScalarFieldType().`);
}
runtime_1.assert(fieldDescriptor.type !== undefined);
runtime_1.assert(fieldDescriptor.type !== descriptor_1.FieldDescriptorProto_Type.ENUM);
runtime_1.assert(fieldDescriptor.type !== descriptor_1.FieldDescriptorProto_Type.MESSAGE);
runtime_1.assert(fieldDescriptor.type !== descriptor_1.FieldDescriptorProto_Type.GROUP);
runtime_1.assert(fieldDescriptor.type !== descriptor_1.FieldDescriptorProto_Type.UNSPECIFIED$);
return fieldDescriptor.type;
}
isMapField(fieldDescriptor) {
return this.getMapEntryMessage(fieldDescriptor) !== undefined;
}
getMapKeyType(fieldDescriptor) {
let entry = this.getMapEntryMessage(fieldDescriptor);
if (!entry) {
throw new Error(`${string_format_1.StringFormat.formatName(fieldDescriptor)} is not a map field. use isMapField() before getMapKeyType().`);
}
let keyField = entry.field.find(fd => fd.number === 1);
runtime_1.assert(keyField !== undefined, `Missing map entry key field 1 for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
runtime_1.assert(keyField.type !== undefined, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
runtime_1.assert(keyField.type !== descriptor_1.FieldDescriptorProto_Type.UNSPECIFIED$, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
runtime_1.assert(keyField.type !== descriptor_1.FieldDescriptorProto_Type.GROUP, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
runtime_1.assert(keyField.type !== descriptor_1.FieldDescriptorProto_Type.MESSAGE, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
runtime_1.assert(keyField.type !== descriptor_1.FieldDescriptorProto_Type.ENUM, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
runtime_1.assert(keyField.type !== descriptor_1.FieldDescriptorProto_Type.FLOAT, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
runtime_1.assert(keyField.type !== descriptor_1.FieldDescriptorProto_Type.DOUBLE, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
runtime_1.assert(keyField.type !== descriptor_1.FieldDescriptorProto_Type.BYTES, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
return keyField.type;
}
getMapValueType(fieldDescriptor) {
let entry = this.getMapEntryMessage(fieldDescriptor);
if (!entry) {
throw new Error(`${string_format_1.StringFormat.formatName(fieldDescriptor)} is not a map field. use isMapField() before getMapValueType().`);
}
let valueField = entry.field.find(fd => fd.number === 2);
runtime_1.assert(valueField !== undefined, `Missing map entry value field 2 for ${string_format_1.StringFormat.formatName(fieldDescriptor)}`);
if (this.isScalarField(valueField)) {
return this.getScalarFieldType(valueField);
}
if (this.isEnumField(valueField)) {
return this.getEnumFieldEnum(valueField);
}
return this.getMessageFieldMessage(valueField);
}
getMapEntryMessage(fieldDescriptor) {
var _a;
if (fieldDescriptor.type !== descriptor_1.FieldDescriptorProto_Type.MESSAGE) {
return undefined;
}
if (fieldDescriptor.typeName === undefined || fieldDescriptor.typeName === "") {
return undefined;
}
let typeDescriptor = this.nameLookup.resolveTypeName(fieldDescriptor.typeName);
if (!descriptor_1.DescriptorProto.is(typeDescriptor)) {
return undefined;
}
if (((_a = typeDescriptor.options) === null || _a === void 0 ? void 0 : _a.mapEntry) !== true) {
return undefined;
}
return typeDescriptor;
}
isExplicitlyDeclaredDeprecated(descriptor) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
if (descriptor_1.FileDescriptorProto.is(descriptor)) {
return (_b = (_a = descriptor.options) === null || _a === void 0 ? void 0 : _a.deprecated) !== null && _b !== void 0 ? _b : false;
}
if (descriptor_1.DescriptorProto.is(descriptor)) {
return (_d = (_c = descriptor.options) === null || _c === void 0 ? void 0 : _c.deprecated) !== null && _d !== void 0 ? _d : false;
}
if (descriptor_1.FieldDescriptorProto.is(descriptor)) {
return (_f = (_e = descriptor.options) === null || _e === void 0 ? void 0 : _e.deprecated) !== null && _f !== void 0 ? _f : false;
}
if (descriptor_1.EnumDescriptorProto.is(descriptor)) {
return (_h = (_g = descriptor.options) === null || _g === void 0 ? void 0 : _g.deprecated) !== null && _h !== void 0 ? _h : false;
}
if (descriptor_1.EnumValueDescriptorProto.is(descriptor)) {
return (_k = (_j = descriptor.options) === null || _j === void 0 ? void 0 : _j.deprecated) !== null && _k !== void 0 ? _k : false;
}
if (descriptor_1.ServiceDescriptorProto.is(descriptor)) {
return (_m = (_l = descriptor.options) === null || _l === void 0 ? void 0 : _l.deprecated) !== null && _m !== void 0 ? _m : false;
}
if (descriptor_1.MethodDescriptorProto.is(descriptor)) {
return (_p = (_o = descriptor.options) === null || _o === void 0 ? void 0 : _o.deprecated) !== null && _p !== void 0 ? _p : false;
}
if (descriptor_1.OneofDescriptorProto.is(descriptor)) {
return false;
}
return false;
}
isSyntheticElement(descriptor) {
var _a;
if (descriptor_1.DescriptorProto.is(descriptor)) {
if ((_a = descriptor.options) === null || _a === void 0 ? void 0 : _a.mapEntry) {
return true;
}
if (descriptor.name && descriptor.name.startsWith("$synthetic.")) {
return true;
}
}
return false;
}
isUserDeclaredOneof(fieldDescriptor) {
if (fieldDescriptor.oneofIndex === undefined) {
return false;
}
return fieldDescriptor.proto3Optional !== true;
}
isUserDeclaredOptional(fieldDescriptor) {
if (this.isUserDeclaredOneof(fieldDescriptor)) {
return false;
}
if (fieldDescriptor.proto3Optional === true) {
return true;
}
if (fieldDescriptor.proto3Optional === false) {
return false;
}
const file = this.tree.fileOf(fieldDescriptor);
if (file.syntax === 'proto3') {
return false;
}
runtime_1.assert(file.syntax === undefined || file.syntax === 'proto2', `unsupported syntax "${file.syntax}"`);
return fieldDescriptor.label === descriptor_1.FieldDescriptorProto_Label.OPTIONAL;
}
isUserDeclaredRepeated(fieldDescriptor) {
var _a;
if (fieldDescriptor.label !== descriptor_1.FieldDescriptorProto_Label.REPEATED) {
return false;
}
const name = fieldDescriptor.typeName;
if (name === undefined || name === "") {
return true;
}
const typeDescriptor = this.nameLookup.resolveTypeName(name);
if (descriptor_1.DescriptorProto.is(typeDescriptor)) {
return !((_a = typeDescriptor.options) === null || _a === void 0 ? void 0 : _a.mapEntry);
}
return true;
}
shouldBePackedRepeated(fieldDescriptor) {
var _a;
let file = this.tree.fileOf(fieldDescriptor);
let standard, declared = (_a = fieldDescriptor.options) === null || _a === void 0 ? void 0 : _a.packed;
if (file.syntax === 'proto3') {
standard = true;
}
else {
runtime_1.assert(file.syntax === undefined || file.syntax === 'proto2', `unsupported syntax "${file.syntax}"`);
standard = false;
}
if (fieldDescriptor.type === descriptor_1.FieldDescriptorProto_Type.BYTES || fieldDescriptor.type === descriptor_1.FieldDescriptorProto_Type.STRING) {
runtime_1.assert(!declared, `repeated bytes | string cannot be packed. protoc should have caught this. probably unsupported protoc version.`);
standard = false;
}
return declared !== null && declared !== void 0 ? declared : standard;
}
findEnumSharedPrefix(enumDescriptor, enumLocalName) {
if (enumLocalName === undefined) {
enumLocalName = `${enumDescriptor.name}`;
}
// create possible prefix from local enum name
// for example, "MyEnum" => "MY_ENUM_"
let enumPrefix = enumLocalName;
enumPrefix = enumPrefix.replace(/[A-Z]/g, letter => "_" + letter.toLowerCase());
enumPrefix = (enumPrefix[0] === "_") ? enumPrefix.substring(1) : enumPrefix;
enumPrefix = enumPrefix.toUpperCase();
enumPrefix += '_';
// do all members share the prefix?
let names = enumDescriptor.value.map(enumValue => `${enumValue.name}`);
let allNamesSharePrefix = names.every(name => name.startsWith(enumPrefix));
// are the names with stripped prefix still valid?
// (start with uppercase letter, at least 2 chars long)
let strippedNames = names.map(name => name.substring(enumPrefix.length));
let strippedNamesAreValid = strippedNames.every(name => name.length > 0 && /^[A-Z].+/.test(name));
return (allNamesSharePrefix && strippedNamesAreValid) ? enumPrefix : undefined;
}
isFileUsed(file, inFiles) {
let used = false;
this.tree.visitTypes(file, typeDescriptor => {
if (used)
return;
if (this.isTypeUsed(typeDescriptor, inFiles)) {
used = true;
}
});
return used;
}
isTypeUsed(type, inFiles) {
const needle = this.nameLookup.makeTypeName(type);
let used = false;
for (let fd of inFiles) {
this.tree.visitTypes(fd, typeDescriptor => {
if (used)
return;
if (descriptor_1.DescriptorProto.is(typeDescriptor)) {
const usedInField = typeDescriptor.field.some(fd => fd.typeName !== undefined && this.nameLookup.normalizeTypeName(fd.typeName) === needle);
if (usedInField) {
used = true;
}
}
else if (descriptor_1.ServiceDescriptorProto.is(typeDescriptor)) {
const usedInMethodInput = typeDescriptor.method.some(md => md.inputType !== undefined && this.nameLookup.normalizeTypeName(md.inputType) === needle);
const usedInMethodOutput = typeDescriptor.method.some(md => md.outputType !== undefined && this.nameLookup.normalizeTypeName(md.outputType) === needle);
if (usedInMethodInput || usedInMethodOutput) {
used = true;
}
}
});
}
return used;
}
}
exports.DescriptorInfo = DescriptorInfo;

View file

@ -0,0 +1,154 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DescriptorRegistry = void 0;
const descriptor_1 = require("./google/protobuf/descriptor");
const plugin_1 = require("./google/protobuf/compiler/plugin");
const descriptor_info_1 = require("./descriptor-info");
const descriptor_tree_1 = require("./descriptor-tree");
const source_code_info_1 = require("./source-code-info");
const string_format_1 = require("./string-format");
const type_names_1 = require("./type-names");
class DescriptorRegistry {
constructor(tree, typeNames, sourceCode, stringFormat, descriptorInfo) {
this.tree = tree;
this.typeNames = typeNames;
this.sourceCode = sourceCode;
this.stringFormat = stringFormat;
this.descriptorInfo = descriptorInfo;
}
static createFrom(requestOrFile) {
const files = plugin_1.CodeGeneratorRequest.is(requestOrFile)
? requestOrFile.protoFile
: [requestOrFile], tree = descriptor_tree_1.DescriptorTree.from(...files), nameLookup = type_names_1.TypeNameLookup.from(tree), sourceCodeLookup = new source_code_info_1.SourceCodeInfoLookup(d => tree.parentOf(d)), descriptorInfo = new descriptor_info_1.DescriptorInfo(tree, nameLookup), stringFormat = new string_format_1.StringFormat(nameLookup, tree, sourceCodeLookup, descriptorInfo);
return new DescriptorRegistry(tree, nameLookup, sourceCodeLookup, stringFormat, descriptorInfo);
}
// ITypeNameLookup
normalizeTypeName(typeName) {
return this.typeNames.normalizeTypeName(typeName);
}
resolveTypeName(typeName) {
return this.typeNames.resolveTypeName(typeName);
}
peekTypeName(typeName) {
return this.typeNames.peekTypeName(typeName);
}
makeTypeName(descriptor) {
return this.typeNames.makeTypeName(descriptor);
}
// IDescriptorTree
ancestorsOf(descriptor) {
return this.tree.ancestorsOf(descriptor);
}
fileOf(descriptor) {
return this.tree.fileOf(descriptor);
}
allFiles() {
return this.tree.allFiles();
}
parentOf(descriptorOrOptions) {
return this.tree.parentOf(descriptorOrOptions);
}
visit(a, b) {
this.tree.visit(a, b);
}
visitTypes(a, b) {
this.tree.visitTypes(a, b);
}
// ISourceCodeInfoLookup
sourceCodeCursor(descriptor) {
return this.sourceCode.sourceCodeCursor(descriptor);
}
sourceCodeComments(descriptorOrFile, fileDescriptorFieldNumber) {
if (descriptor_1.FileDescriptorProto.is(descriptorOrFile) && fileDescriptorFieldNumber !== undefined) {
return this.sourceCode.sourceCodeComments(descriptorOrFile, fileDescriptorFieldNumber);
}
return this.sourceCode.sourceCodeComments(descriptorOrFile);
}
// IStringFormat
formatFieldDeclaration(descriptor) {
return this.stringFormat.formatFieldDeclaration(descriptor);
}
formatQualifiedName(descriptor, includeFileInfo = false) {
return this.stringFormat.formatQualifiedName(descriptor, includeFileInfo);
}
formatName(descriptor) {
return this.stringFormat.formatName(descriptor);
}
formatEnumValueDeclaration(descriptor) {
return this.stringFormat.formatEnumValueDeclaration(descriptor);
}
formatRpcDeclaration(descriptor) {
return this.stringFormat.formatRpcDeclaration(descriptor);
}
// IDescriptorInfo
isExtension(descriptor) {
return this.descriptorInfo.isExtension(descriptor);
}
extensionsFor(descriptorOrTypeName) {
return this.descriptorInfo.extensionsFor(descriptorOrTypeName);
}
getExtensionName(descriptor) {
return this.descriptorInfo.getExtensionName(descriptor);
}
getFieldCustomJsonName(descriptor) {
return this.descriptorInfo.getFieldCustomJsonName(descriptor);
}
isEnumField(fieldDescriptor) {
return this.descriptorInfo.isEnumField(fieldDescriptor);
}
getEnumFieldEnum(fieldDescriptor) {
return this.descriptorInfo.getEnumFieldEnum(fieldDescriptor);
}
isMessageField(fieldDescriptor) {
return this.descriptorInfo.isMessageField(fieldDescriptor);
}
isGroupField(fieldDescriptor) {
return this.descriptorInfo.isGroupField(fieldDescriptor);
}
getMessageFieldMessage(fieldDescriptor) {
return this.descriptorInfo.getMessageFieldMessage(fieldDescriptor);
}
isScalarField(fieldDescriptor) {
return this.descriptorInfo.isScalarField(fieldDescriptor);
}
getScalarFieldType(fieldDescriptor) {
return this.descriptorInfo.getScalarFieldType(fieldDescriptor);
}
isMapField(fieldDescriptor) {
return this.descriptorInfo.isMapField(fieldDescriptor);
}
getMapKeyType(fieldDescriptor) {
return this.descriptorInfo.getMapKeyType(fieldDescriptor);
}
getMapValueType(fieldDescriptor) {
return this.descriptorInfo.getMapValueType(fieldDescriptor);
}
isExplicitlyDeclaredDeprecated(descriptor) {
return this.descriptorInfo.isExplicitlyDeclaredDeprecated(descriptor);
}
isSyntheticElement(descriptor) {
return this.descriptorInfo.isSyntheticElement(descriptor);
}
findEnumSharedPrefix(descriptor, enumLocalName) {
return this.descriptorInfo.findEnumSharedPrefix(descriptor, enumLocalName);
}
isUserDeclaredOneof(descriptor) {
return this.descriptorInfo.isUserDeclaredOneof(descriptor);
}
isUserDeclaredOptional(descriptor) {
return this.descriptorInfo.isUserDeclaredOptional(descriptor);
}
isUserDeclaredRepeated(descriptor) {
return this.descriptorInfo.isUserDeclaredRepeated(descriptor);
}
shouldBePackedRepeated(descriptor) {
return this.descriptorInfo.shouldBePackedRepeated(descriptor);
}
isFileUsed(file, inFiles) {
return this.descriptorInfo.isFileUsed(file, inFiles);
}
isTypeUsed(type, inFiles) {
return this.descriptorInfo.isTypeUsed(type, inFiles);
}
}
exports.DescriptorRegistry = DescriptorRegistry;

View file

@ -0,0 +1,180 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.visitDescriptorTree = exports.DescriptorTree = void 0;
const descriptor_1 = require("./google/protobuf/descriptor");
const descriptor_info_1 = require("./descriptor-info");
const runtime_1 = require("@protobuf-ts/runtime");
class DescriptorTree {
constructor(descriptors, options) {
const descriptorMap = new Map();
const optionMap = new Map();
const files = [];
for (const [descriptor, info] of descriptors) {
// infos
runtime_1.assert(!descriptorMap.has(descriptor));
descriptorMap.set(descriptor, info);
// files
if (descriptor_1.FileDescriptorProto.is(descriptor)) {
files.push(descriptor);
}
}
for (const [option, descriptor] of options) {
optionMap.set(option, descriptor);
}
this._files = files;
this._descriptors = descriptorMap;
this._options = optionMap;
}
/**
* Create the tree from a list of root files.
*/
static from(...files) {
const descriptors = [];
const options = [];
for (const file of files) {
visitDescriptorTree(file, (descriptor, ancestors) => {
descriptors.push([descriptor, { ancestors, file, parent: ancestors[ancestors.length - 1] }]);
if (descriptor.options) {
options.push([descriptor.options, descriptor]);
}
});
}
return new DescriptorTree(descriptors, options);
}
ancestorsOf(descriptor) {
const v = this._descriptors.get(descriptor);
runtime_1.assert(v !== undefined);
return v.ancestors.concat();
}
fileOf(descriptor) {
const v = this._descriptors.get(descriptor);
runtime_1.assert(v !== undefined);
return v.file;
}
allFiles() {
return this._files;
}
parentOf(descriptorOrOptions) {
const optionParent = this._options.get(descriptorOrOptions);
if (optionParent) {
return optionParent;
}
const descriptorEntry = this._descriptors.get(descriptorOrOptions);
if (descriptorEntry) {
return descriptorEntry.parent;
}
runtime_1.assert(descriptor_1.FileDescriptorProto.is(descriptorOrOptions));
return undefined;
}
visit(a, b) {
if (b === undefined) {
for (const file of this._files) {
visitDescriptorTree(file, a);
}
}
else {
const startingFrom = a;
visitDescriptorTree(startingFrom, descriptor => {
if (descriptor === a) {
return; // visitDescriptorTree invokes on starting element. ignore.
}
b(descriptor);
});
}
}
visitTypes(a, b) {
if (b === undefined) {
for (const file of this._files) {
visitDescriptorTree(file, descriptor => {
if (descriptor_info_1.isAnyTypeDescriptorProto(descriptor)) {
a(descriptor);
}
});
}
}
else {
visitDescriptorTree(a, descriptor => {
if (descriptor === a) {
return; // visitDescriptorTree invokes on starting element. ignore.
}
if (descriptor_info_1.isAnyTypeDescriptorProto(descriptor)) {
b(descriptor);
}
});
}
}
}
exports.DescriptorTree = DescriptorTree;
/**
* Visit all logical children of the given descriptor proto.
*
* The "visitor" function is called for each element,
* including the input. It receives two arguments:
* 1) the current descriptor proto
* 2) the ancestors of the current descriptor proto (an array of descriptors)
*/
function visitDescriptorTree(input, visitor) {
visitWithCarry(input, [], visitor);
}
exports.visitDescriptorTree = visitDescriptorTree;
function visitWithCarry(input, carry, visitor) {
visitor(input, carry);
carry = carry.concat(input);
// noinspection SuspiciousTypeOfGuard
if (descriptor_1.EnumDescriptorProto.is(input)) {
for (const val of input.value) {
visitWithCarry(val, carry, visitor);
}
}
else if (descriptor_1.DescriptorProto.is(input)) {
for (const oneof of input.oneofDecl) {
visitWithCarry(oneof, carry, visitor);
}
for (const field of input.field) {
visitWithCarry(field, carry, visitor);
}
for (const message of input.nestedType) {
visitWithCarry(message, carry, visitor);
}
for (const enu of input.enumType) {
visitWithCarry(enu, carry, visitor);
}
for (const extensionField of input.extension) {
visitWithCarry(extensionField, carry, visitor);
}
}
else if (descriptor_1.FileDescriptorProto.is(input)) {
for (const message of input.messageType) {
visitWithCarry(message, carry, visitor);
}
for (const enu of input.enumType) {
visitWithCarry(enu, carry, visitor);
}
for (const service of input.service) {
visitWithCarry(service, carry, visitor);
}
for (const extensionField of input.extension) {
visitWithCarry(extensionField, carry, visitor);
}
}
else if (descriptor_1.ServiceDescriptorProto.is(input)) {
for (const method of input.method) {
visitWithCarry(method, carry, visitor);
}
}
else if (descriptor_1.EnumValueDescriptorProto.is(input)) {
//
}
else if (descriptor_1.FieldDescriptorProto.is(input)) {
//
}
else if (descriptor_1.MethodDescriptorProto.is(input)) {
//
}
else if (descriptor_1.OneofDescriptorProto.is(input)) {
//
}
else {
runtime_1.assertNever(input);
}
}

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,128 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CodeGeneratorResponse_File = exports.CodeGeneratorResponse = exports.CodeGeneratorRequest = exports.Version = exports.CodeGeneratorResponse_Feature = void 0;
// @generated by protobuf-ts 1.0.0-alpha.35 with parameters force_optimize_code_size,long_type_string
// @generated from protobuf file "google/protobuf/compiler/plugin.proto" (package "google.protobuf.compiler", syntax proto2)
// tslint:disable
//
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
// Author: kenton@google.com (Kenton Varda)
//
// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to
// change.
//
// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is
// just a program that reads a CodeGeneratorRequest from stdin and writes a
// CodeGeneratorResponse to stdout.
//
// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead
// of dealing with the raw protocol defined here.
//
// A plugin executable needs only to be placed somewhere in the path. The
// plugin should be named "protoc-gen-$NAME", and will then be used when the
// flag "--${NAME}_out" is passed to protoc.
//
const runtime_1 = require("@protobuf-ts/runtime");
const runtime_2 = require("@protobuf-ts/runtime");
const runtime_3 = require("@protobuf-ts/runtime");
const descriptor_1 = require("../descriptor");
/**
* Sync with code_generator.h.
*
* @generated from protobuf enum google.protobuf.compiler.CodeGeneratorResponse.Feature
*/
var CodeGeneratorResponse_Feature;
(function (CodeGeneratorResponse_Feature) {
/**
* @generated from protobuf enum value: FEATURE_NONE = 0;
*/
CodeGeneratorResponse_Feature[CodeGeneratorResponse_Feature["NONE"] = 0] = "NONE";
/**
* @generated from protobuf enum value: FEATURE_PROTO3_OPTIONAL = 1;
*/
CodeGeneratorResponse_Feature[CodeGeneratorResponse_Feature["PROTO3_OPTIONAL"] = 1] = "PROTO3_OPTIONAL";
})(CodeGeneratorResponse_Feature = exports.CodeGeneratorResponse_Feature || (exports.CodeGeneratorResponse_Feature = {}));
/**
* Type for protobuf message google.protobuf.compiler.Version
*/
class Version$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.compiler.Version", [
{ no: 1, name: "major", kind: "scalar", opt: true, T: runtime_2.ScalarType.INT32 },
{ no: 2, name: "minor", kind: "scalar", opt: true, T: runtime_2.ScalarType.INT32 },
{ no: 3, name: "patch", kind: "scalar", opt: true, T: runtime_2.ScalarType.INT32 },
{ no: 4, name: "suffix", kind: "scalar", opt: true, T: runtime_2.ScalarType.STRING }
]);
}
}
exports.Version = new Version$Type();
/**
* Type for protobuf message google.protobuf.compiler.CodeGeneratorRequest
*/
class CodeGeneratorRequest$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.compiler.CodeGeneratorRequest", [
{ no: 1, name: "file_to_generate", kind: "scalar", repeat: runtime_1.RepeatType.UNPACKED, T: runtime_2.ScalarType.STRING },
{ no: 2, name: "parameter", kind: "scalar", opt: true, T: runtime_2.ScalarType.STRING },
{ no: 15, name: "proto_file", kind: "message", repeat: runtime_1.RepeatType.UNPACKED, T: () => descriptor_1.FileDescriptorProto },
{ no: 3, name: "compiler_version", kind: "message", T: () => exports.Version }
]);
}
}
exports.CodeGeneratorRequest = new CodeGeneratorRequest$Type();
/**
* Type for protobuf message google.protobuf.compiler.CodeGeneratorResponse
*/
class CodeGeneratorResponse$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.compiler.CodeGeneratorResponse", [
{ no: 1, name: "error", kind: "scalar", opt: true, T: runtime_2.ScalarType.STRING },
{ no: 2, name: "supported_features", kind: "scalar", opt: true, T: runtime_2.ScalarType.UINT64 },
{ no: 15, name: "file", kind: "message", repeat: runtime_1.RepeatType.UNPACKED, T: () => exports.CodeGeneratorResponse_File }
]);
}
}
exports.CodeGeneratorResponse = new CodeGeneratorResponse$Type();
/**
* Type for protobuf message google.protobuf.compiler.CodeGeneratorResponse.File
*/
class CodeGeneratorResponse_File$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.compiler.CodeGeneratorResponse.File", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: runtime_2.ScalarType.STRING },
{ no: 2, name: "insertion_point", kind: "scalar", opt: true, T: runtime_2.ScalarType.STRING },
{ no: 15, name: "content", kind: "scalar", opt: true, T: runtime_2.ScalarType.STRING }
]);
}
}
exports.CodeGeneratorResponse_File = new CodeGeneratorResponse_File$Type();

View file

@ -0,0 +1,674 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GeneratedCodeInfo_Annotation = exports.GeneratedCodeInfo = exports.SourceCodeInfo_Location = exports.SourceCodeInfo = exports.UninterpretedOption_NamePart = exports.UninterpretedOption = exports.MethodOptions = exports.ServiceOptions = exports.EnumValueOptions = exports.EnumOptions = exports.OneofOptions = exports.FieldOptions = exports.MessageOptions = exports.FileOptions = exports.MethodDescriptorProto = exports.ServiceDescriptorProto = exports.EnumValueDescriptorProto = exports.EnumDescriptorProto_EnumReservedRange = exports.EnumDescriptorProto = exports.OneofDescriptorProto = exports.FieldDescriptorProto = exports.ExtensionRangeOptions = exports.DescriptorProto_ReservedRange = exports.DescriptorProto_ExtensionRange = exports.DescriptorProto = exports.FileDescriptorProto = exports.FileDescriptorSet = exports.MethodOptions_IdempotencyLevel = exports.FieldOptions_JSType = exports.FieldOptions_CType = exports.FileOptions_OptimizeMode = exports.FieldDescriptorProto_Label = exports.FieldDescriptorProto_Type = void 0;
// @generated by protobuf-ts 1.0.0-alpha.35 with parameters force_optimize_code_size,long_type_string
// @generated from protobuf file "google/protobuf/descriptor.proto" (package "google.protobuf", syntax proto2)
// tslint:disable
//
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// The messages in this file describe the definitions found in .proto files.
// A valid .proto file can be translated directly to a FileDescriptorProto
// without any other information (e.g. without reading its imports).
//
const runtime_1 = require("@protobuf-ts/runtime");
const runtime_2 = require("@protobuf-ts/runtime");
const runtime_3 = require("@protobuf-ts/runtime");
/**
* @generated from protobuf enum google.protobuf.FieldDescriptorProto.Type
*/
var FieldDescriptorProto_Type;
(function (FieldDescriptorProto_Type) {
/**
* @generated synthetic value - protobuf-ts requires all enums to have a 0 value
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["UNSPECIFIED$"] = 0] = "UNSPECIFIED$";
/**
* 0 is reserved for errors.
* Order is weird for historical reasons.
*
* @generated from protobuf enum value: TYPE_DOUBLE = 1;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["DOUBLE"] = 1] = "DOUBLE";
/**
* @generated from protobuf enum value: TYPE_FLOAT = 2;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["FLOAT"] = 2] = "FLOAT";
/**
* Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
* negative values are likely.
*
* @generated from protobuf enum value: TYPE_INT64 = 3;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["INT64"] = 3] = "INT64";
/**
* @generated from protobuf enum value: TYPE_UINT64 = 4;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["UINT64"] = 4] = "UINT64";
/**
* Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
* negative values are likely.
*
* @generated from protobuf enum value: TYPE_INT32 = 5;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["INT32"] = 5] = "INT32";
/**
* @generated from protobuf enum value: TYPE_FIXED64 = 6;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["FIXED64"] = 6] = "FIXED64";
/**
* @generated from protobuf enum value: TYPE_FIXED32 = 7;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["FIXED32"] = 7] = "FIXED32";
/**
* @generated from protobuf enum value: TYPE_BOOL = 8;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["BOOL"] = 8] = "BOOL";
/**
* @generated from protobuf enum value: TYPE_STRING = 9;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["STRING"] = 9] = "STRING";
/**
* Tag-delimited aggregate.
* Group type is deprecated and not supported in proto3. However, Proto3
* implementations should still be able to parse the group wire format and
* treat group fields as unknown fields.
*
* @generated from protobuf enum value: TYPE_GROUP = 10;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["GROUP"] = 10] = "GROUP";
/**
* Length-delimited aggregate.
*
* @generated from protobuf enum value: TYPE_MESSAGE = 11;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["MESSAGE"] = 11] = "MESSAGE";
/**
* New in version 2.
*
* @generated from protobuf enum value: TYPE_BYTES = 12;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["BYTES"] = 12] = "BYTES";
/**
* @generated from protobuf enum value: TYPE_UINT32 = 13;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["UINT32"] = 13] = "UINT32";
/**
* @generated from protobuf enum value: TYPE_ENUM = 14;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["ENUM"] = 14] = "ENUM";
/**
* @generated from protobuf enum value: TYPE_SFIXED32 = 15;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["SFIXED32"] = 15] = "SFIXED32";
/**
* @generated from protobuf enum value: TYPE_SFIXED64 = 16;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["SFIXED64"] = 16] = "SFIXED64";
/**
* Uses ZigZag encoding.
*
* @generated from protobuf enum value: TYPE_SINT32 = 17;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["SINT32"] = 17] = "SINT32";
/**
* Uses ZigZag encoding.
*
* @generated from protobuf enum value: TYPE_SINT64 = 18;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["SINT64"] = 18] = "SINT64";
})(FieldDescriptorProto_Type = exports.FieldDescriptorProto_Type || (exports.FieldDescriptorProto_Type = {}));
/**
* @generated from protobuf enum google.protobuf.FieldDescriptorProto.Label
*/
var FieldDescriptorProto_Label;
(function (FieldDescriptorProto_Label) {
/**
* @generated synthetic value - protobuf-ts requires all enums to have a 0 value
*/
FieldDescriptorProto_Label[FieldDescriptorProto_Label["UNSPECIFIED$"] = 0] = "UNSPECIFIED$";
/**
* 0 is reserved for errors
*
* @generated from protobuf enum value: LABEL_OPTIONAL = 1;
*/
FieldDescriptorProto_Label[FieldDescriptorProto_Label["OPTIONAL"] = 1] = "OPTIONAL";
/**
* @generated from protobuf enum value: LABEL_REQUIRED = 2;
*/
FieldDescriptorProto_Label[FieldDescriptorProto_Label["REQUIRED"] = 2] = "REQUIRED";
/**
* @generated from protobuf enum value: LABEL_REPEATED = 3;
*/
FieldDescriptorProto_Label[FieldDescriptorProto_Label["REPEATED"] = 3] = "REPEATED";
})(FieldDescriptorProto_Label = exports.FieldDescriptorProto_Label || (exports.FieldDescriptorProto_Label = {}));
/**
* Generated classes can be optimized for speed or code size.
*
* @generated from protobuf enum google.protobuf.FileOptions.OptimizeMode
*/
var FileOptions_OptimizeMode;
(function (FileOptions_OptimizeMode) {
/**
* @generated synthetic value - protobuf-ts requires all enums to have a 0 value
*/
FileOptions_OptimizeMode[FileOptions_OptimizeMode["UNSPECIFIED$"] = 0] = "UNSPECIFIED$";
/**
* Generate complete code for parsing, serialization,
*
* @generated from protobuf enum value: SPEED = 1;
*/
FileOptions_OptimizeMode[FileOptions_OptimizeMode["SPEED"] = 1] = "SPEED";
/**
* etc.
*
* Use ReflectionOps to implement these methods.
*
* @generated from protobuf enum value: CODE_SIZE = 2;
*/
FileOptions_OptimizeMode[FileOptions_OptimizeMode["CODE_SIZE"] = 2] = "CODE_SIZE";
/**
* Generate code using MessageLite and the lite runtime.
*
* @generated from protobuf enum value: LITE_RUNTIME = 3;
*/
FileOptions_OptimizeMode[FileOptions_OptimizeMode["LITE_RUNTIME"] = 3] = "LITE_RUNTIME";
})(FileOptions_OptimizeMode = exports.FileOptions_OptimizeMode || (exports.FileOptions_OptimizeMode = {}));
/**
* @generated from protobuf enum google.protobuf.FieldOptions.CType
*/
var FieldOptions_CType;
(function (FieldOptions_CType) {
/**
* Default mode.
*
* @generated from protobuf enum value: STRING = 0;
*/
FieldOptions_CType[FieldOptions_CType["STRING"] = 0] = "STRING";
/**
* @generated from protobuf enum value: CORD = 1;
*/
FieldOptions_CType[FieldOptions_CType["CORD"] = 1] = "CORD";
/**
* @generated from protobuf enum value: STRING_PIECE = 2;
*/
FieldOptions_CType[FieldOptions_CType["STRING_PIECE"] = 2] = "STRING_PIECE";
})(FieldOptions_CType = exports.FieldOptions_CType || (exports.FieldOptions_CType = {}));
/**
* @generated from protobuf enum google.protobuf.FieldOptions.JSType
*/
var FieldOptions_JSType;
(function (FieldOptions_JSType) {
/**
* Use the default type.
*
* @generated from protobuf enum value: JS_NORMAL = 0;
*/
FieldOptions_JSType[FieldOptions_JSType["JS_NORMAL"] = 0] = "JS_NORMAL";
/**
* Use JavaScript strings.
*
* @generated from protobuf enum value: JS_STRING = 1;
*/
FieldOptions_JSType[FieldOptions_JSType["JS_STRING"] = 1] = "JS_STRING";
/**
* Use JavaScript numbers.
*
* @generated from protobuf enum value: JS_NUMBER = 2;
*/
FieldOptions_JSType[FieldOptions_JSType["JS_NUMBER"] = 2] = "JS_NUMBER";
})(FieldOptions_JSType = exports.FieldOptions_JSType || (exports.FieldOptions_JSType = {}));
/**
* Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
* or neither? HTTP based RPC implementation may choose GET verb for safe
* methods, and PUT verb for idempotent methods instead of the default POST.
*
* @generated from protobuf enum google.protobuf.MethodOptions.IdempotencyLevel
*/
var MethodOptions_IdempotencyLevel;
(function (MethodOptions_IdempotencyLevel) {
/**
* @generated from protobuf enum value: IDEMPOTENCY_UNKNOWN = 0;
*/
MethodOptions_IdempotencyLevel[MethodOptions_IdempotencyLevel["IDEMPOTENCY_UNKNOWN"] = 0] = "IDEMPOTENCY_UNKNOWN";
/**
* implies idempotent
*
* @generated from protobuf enum value: NO_SIDE_EFFECTS = 1;
*/
MethodOptions_IdempotencyLevel[MethodOptions_IdempotencyLevel["NO_SIDE_EFFECTS"] = 1] = "NO_SIDE_EFFECTS";
/**
* idempotent, but may have side effects
*
* @generated from protobuf enum value: IDEMPOTENT = 2;
*/
MethodOptions_IdempotencyLevel[MethodOptions_IdempotencyLevel["IDEMPOTENT"] = 2] = "IDEMPOTENT";
})(MethodOptions_IdempotencyLevel = exports.MethodOptions_IdempotencyLevel || (exports.MethodOptions_IdempotencyLevel = {}));
/**
* Type for protobuf message google.protobuf.FileDescriptorSet
*/
class FileDescriptorSet$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.FileDescriptorSet", [
{ no: 1, name: "file", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.FileDescriptorProto }
]);
}
}
exports.FileDescriptorSet = new FileDescriptorSet$Type();
/**
* Type for protobuf message google.protobuf.FileDescriptorProto
*/
class FileDescriptorProto$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.FileDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 2, name: "package", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 3, name: "dependency", kind: "scalar", repeat: runtime_2.RepeatType.UNPACKED, T: runtime_1.ScalarType.STRING },
{ no: 10, name: "public_dependency", kind: "scalar", repeat: runtime_2.RepeatType.UNPACKED, T: runtime_1.ScalarType.INT32 },
{ no: 11, name: "weak_dependency", kind: "scalar", repeat: runtime_2.RepeatType.UNPACKED, T: runtime_1.ScalarType.INT32 },
{ no: 4, name: "message_type", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.DescriptorProto },
{ no: 5, name: "enum_type", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.EnumDescriptorProto },
{ no: 6, name: "service", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.ServiceDescriptorProto },
{ no: 7, name: "extension", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.FieldDescriptorProto },
{ no: 8, name: "options", kind: "message", T: () => exports.FileOptions },
{ no: 9, name: "source_code_info", kind: "message", T: () => exports.SourceCodeInfo },
{ no: 12, name: "syntax", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING }
]);
}
}
exports.FileDescriptorProto = new FileDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.DescriptorProto
*/
class DescriptorProto$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.DescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 2, name: "field", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.FieldDescriptorProto },
{ no: 6, name: "extension", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.FieldDescriptorProto },
{ no: 3, name: "nested_type", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.DescriptorProto },
{ no: 4, name: "enum_type", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.EnumDescriptorProto },
{ no: 5, name: "extension_range", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.DescriptorProto_ExtensionRange },
{ no: 8, name: "oneof_decl", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.OneofDescriptorProto },
{ no: 7, name: "options", kind: "message", T: () => exports.MessageOptions },
{ no: 9, name: "reserved_range", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.DescriptorProto_ReservedRange },
{ no: 10, name: "reserved_name", kind: "scalar", repeat: runtime_2.RepeatType.UNPACKED, T: runtime_1.ScalarType.STRING }
]);
}
}
exports.DescriptorProto = new DescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.DescriptorProto.ExtensionRange
*/
class DescriptorProto_ExtensionRange$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.DescriptorProto.ExtensionRange", [
{ no: 1, name: "start", kind: "scalar", opt: true, T: runtime_1.ScalarType.INT32 },
{ no: 2, name: "end", kind: "scalar", opt: true, T: runtime_1.ScalarType.INT32 },
{ no: 3, name: "options", kind: "message", T: () => exports.ExtensionRangeOptions }
]);
}
}
exports.DescriptorProto_ExtensionRange = new DescriptorProto_ExtensionRange$Type();
/**
* Type for protobuf message google.protobuf.DescriptorProto.ReservedRange
*/
class DescriptorProto_ReservedRange$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.DescriptorProto.ReservedRange", [
{ no: 1, name: "start", kind: "scalar", opt: true, T: runtime_1.ScalarType.INT32 },
{ no: 2, name: "end", kind: "scalar", opt: true, T: runtime_1.ScalarType.INT32 }
]);
}
}
exports.DescriptorProto_ReservedRange = new DescriptorProto_ReservedRange$Type();
/**
* Type for protobuf message google.protobuf.ExtensionRangeOptions
*/
class ExtensionRangeOptions$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.ExtensionRangeOptions", [
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.UninterpretedOption }
]);
}
}
exports.ExtensionRangeOptions = new ExtensionRangeOptions$Type();
/**
* Type for protobuf message google.protobuf.FieldDescriptorProto
*/
class FieldDescriptorProto$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.FieldDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 3, name: "number", kind: "scalar", opt: true, T: runtime_1.ScalarType.INT32 },
{ no: 4, name: "label", kind: "enum", opt: true, T: () => ["google.protobuf.FieldDescriptorProto.Label", FieldDescriptorProto_Label, "LABEL_"] },
{ no: 5, name: "type", kind: "enum", opt: true, T: () => ["google.protobuf.FieldDescriptorProto.Type", FieldDescriptorProto_Type, "TYPE_"] },
{ no: 6, name: "type_name", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 2, name: "extendee", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 7, name: "default_value", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 9, name: "oneof_index", kind: "scalar", opt: true, T: runtime_1.ScalarType.INT32 },
{ no: 10, name: "json_name", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 8, name: "options", kind: "message", T: () => exports.FieldOptions },
{ no: 17, name: "proto3_optional", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL }
]);
}
}
exports.FieldDescriptorProto = new FieldDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.OneofDescriptorProto
*/
class OneofDescriptorProto$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.OneofDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 2, name: "options", kind: "message", T: () => exports.OneofOptions }
]);
}
}
exports.OneofDescriptorProto = new OneofDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.EnumDescriptorProto
*/
class EnumDescriptorProto$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.EnumDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 2, name: "value", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.EnumValueDescriptorProto },
{ no: 3, name: "options", kind: "message", T: () => exports.EnumOptions },
{ no: 4, name: "reserved_range", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.EnumDescriptorProto_EnumReservedRange },
{ no: 5, name: "reserved_name", kind: "scalar", repeat: runtime_2.RepeatType.UNPACKED, T: runtime_1.ScalarType.STRING }
]);
}
}
exports.EnumDescriptorProto = new EnumDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.EnumDescriptorProto.EnumReservedRange
*/
class EnumDescriptorProto_EnumReservedRange$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.EnumDescriptorProto.EnumReservedRange", [
{ no: 1, name: "start", kind: "scalar", opt: true, T: runtime_1.ScalarType.INT32 },
{ no: 2, name: "end", kind: "scalar", opt: true, T: runtime_1.ScalarType.INT32 }
]);
}
}
exports.EnumDescriptorProto_EnumReservedRange = new EnumDescriptorProto_EnumReservedRange$Type();
/**
* Type for protobuf message google.protobuf.EnumValueDescriptorProto
*/
class EnumValueDescriptorProto$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.EnumValueDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 2, name: "number", kind: "scalar", opt: true, T: runtime_1.ScalarType.INT32 },
{ no: 3, name: "options", kind: "message", T: () => exports.EnumValueOptions }
]);
}
}
exports.EnumValueDescriptorProto = new EnumValueDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.ServiceDescriptorProto
*/
class ServiceDescriptorProto$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.ServiceDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 2, name: "method", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.MethodDescriptorProto },
{ no: 3, name: "options", kind: "message", T: () => exports.ServiceOptions }
]);
}
}
exports.ServiceDescriptorProto = new ServiceDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.MethodDescriptorProto
*/
class MethodDescriptorProto$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.MethodDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 2, name: "input_type", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 3, name: "output_type", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 4, name: "options", kind: "message", T: () => exports.MethodOptions },
{ no: 5, name: "client_streaming", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 6, name: "server_streaming", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL }
]);
}
}
exports.MethodDescriptorProto = new MethodDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.FileOptions
*/
class FileOptions$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.FileOptions", [
{ no: 1, name: "java_package", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 8, name: "java_outer_classname", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 10, name: "java_multiple_files", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 20, name: "java_generate_equals_and_hash", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 27, name: "java_string_check_utf8", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 9, name: "optimize_for", kind: "enum", opt: true, T: () => ["google.protobuf.FileOptions.OptimizeMode", FileOptions_OptimizeMode] },
{ no: 11, name: "go_package", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 16, name: "cc_generic_services", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 17, name: "java_generic_services", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 18, name: "py_generic_services", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 42, name: "php_generic_services", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 23, name: "deprecated", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 31, name: "cc_enable_arenas", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 36, name: "objc_class_prefix", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 37, name: "csharp_namespace", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 39, name: "swift_prefix", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 40, name: "php_class_prefix", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 41, name: "php_namespace", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 44, name: "php_metadata_namespace", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 45, name: "ruby_package", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.UninterpretedOption }
]);
}
}
exports.FileOptions = new FileOptions$Type();
/**
* Type for protobuf message google.protobuf.MessageOptions
*/
class MessageOptions$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.MessageOptions", [
{ no: 1, name: "message_set_wire_format", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 2, name: "no_standard_descriptor_accessor", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 3, name: "deprecated", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 7, name: "map_entry", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.UninterpretedOption }
]);
}
}
exports.MessageOptions = new MessageOptions$Type();
/**
* Type for protobuf message google.protobuf.FieldOptions
*/
class FieldOptions$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.FieldOptions", [
{ no: 1, name: "ctype", kind: "enum", opt: true, T: () => ["google.protobuf.FieldOptions.CType", FieldOptions_CType] },
{ no: 2, name: "packed", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 6, name: "jstype", kind: "enum", opt: true, T: () => ["google.protobuf.FieldOptions.JSType", FieldOptions_JSType] },
{ no: 5, name: "lazy", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 3, name: "deprecated", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 10, name: "weak", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.UninterpretedOption }
]);
}
}
exports.FieldOptions = new FieldOptions$Type();
/**
* Type for protobuf message google.protobuf.OneofOptions
*/
class OneofOptions$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.OneofOptions", [
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.UninterpretedOption }
]);
}
}
exports.OneofOptions = new OneofOptions$Type();
/**
* Type for protobuf message google.protobuf.EnumOptions
*/
class EnumOptions$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.EnumOptions", [
{ no: 2, name: "allow_alias", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 3, name: "deprecated", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.UninterpretedOption }
]);
}
}
exports.EnumOptions = new EnumOptions$Type();
/**
* Type for protobuf message google.protobuf.EnumValueOptions
*/
class EnumValueOptions$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.EnumValueOptions", [
{ no: 1, name: "deprecated", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.UninterpretedOption }
]);
}
}
exports.EnumValueOptions = new EnumValueOptions$Type();
/**
* Type for protobuf message google.protobuf.ServiceOptions
*/
class ServiceOptions$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.ServiceOptions", [
{ no: 33, name: "deprecated", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.UninterpretedOption }
]);
}
}
exports.ServiceOptions = new ServiceOptions$Type();
/**
* Type for protobuf message google.protobuf.MethodOptions
*/
class MethodOptions$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.MethodOptions", [
{ no: 33, name: "deprecated", kind: "scalar", opt: true, T: runtime_1.ScalarType.BOOL },
{ no: 34, name: "idempotency_level", kind: "enum", opt: true, T: () => ["google.protobuf.MethodOptions.IdempotencyLevel", MethodOptions_IdempotencyLevel] },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.UninterpretedOption }
]);
}
}
exports.MethodOptions = new MethodOptions$Type();
/**
* Type for protobuf message google.protobuf.UninterpretedOption
*/
class UninterpretedOption$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.UninterpretedOption", [
{ no: 2, name: "name", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.UninterpretedOption_NamePart },
{ no: 3, name: "identifier_value", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 4, name: "positive_int_value", kind: "scalar", opt: true, T: runtime_1.ScalarType.UINT64 },
{ no: 5, name: "negative_int_value", kind: "scalar", opt: true, T: runtime_1.ScalarType.INT64 },
{ no: 6, name: "double_value", kind: "scalar", opt: true, T: runtime_1.ScalarType.DOUBLE },
{ no: 7, name: "string_value", kind: "scalar", opt: true, T: runtime_1.ScalarType.BYTES },
{ no: 8, name: "aggregate_value", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING }
]);
}
}
exports.UninterpretedOption = new UninterpretedOption$Type();
/**
* Type for protobuf message google.protobuf.UninterpretedOption.NamePart
*/
class UninterpretedOption_NamePart$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.UninterpretedOption.NamePart", [
{ no: 1, name: "name_part", kind: "scalar", T: runtime_1.ScalarType.STRING },
{ no: 2, name: "is_extension", kind: "scalar", T: runtime_1.ScalarType.BOOL }
]);
}
}
exports.UninterpretedOption_NamePart = new UninterpretedOption_NamePart$Type();
/**
* Type for protobuf message google.protobuf.SourceCodeInfo
*/
class SourceCodeInfo$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.SourceCodeInfo", [
{ no: 1, name: "location", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.SourceCodeInfo_Location }
]);
}
}
exports.SourceCodeInfo = new SourceCodeInfo$Type();
/**
* Type for protobuf message google.protobuf.SourceCodeInfo.Location
*/
class SourceCodeInfo_Location$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.SourceCodeInfo.Location", [
{ no: 1, name: "path", kind: "scalar", repeat: runtime_2.RepeatType.PACKED, T: runtime_1.ScalarType.INT32 },
{ no: 2, name: "span", kind: "scalar", repeat: runtime_2.RepeatType.PACKED, T: runtime_1.ScalarType.INT32 },
{ no: 3, name: "leading_comments", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 4, name: "trailing_comments", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 6, name: "leading_detached_comments", kind: "scalar", repeat: runtime_2.RepeatType.UNPACKED, T: runtime_1.ScalarType.STRING }
]);
}
}
exports.SourceCodeInfo_Location = new SourceCodeInfo_Location$Type();
/**
* Type for protobuf message google.protobuf.GeneratedCodeInfo
*/
class GeneratedCodeInfo$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.GeneratedCodeInfo", [
{ no: 1, name: "annotation", kind: "message", repeat: runtime_2.RepeatType.UNPACKED, T: () => exports.GeneratedCodeInfo_Annotation }
]);
}
}
exports.GeneratedCodeInfo = new GeneratedCodeInfo$Type();
/**
* Type for protobuf message google.protobuf.GeneratedCodeInfo.Annotation
*/
class GeneratedCodeInfo_Annotation$Type extends runtime_3.MessageType {
constructor() {
super("google.protobuf.GeneratedCodeInfo.Annotation", [
{ no: 1, name: "path", kind: "scalar", repeat: runtime_2.RepeatType.PACKED, T: runtime_1.ScalarType.INT32 },
{ no: 2, name: "source_file", kind: "scalar", opt: true, T: runtime_1.ScalarType.STRING },
{ no: 3, name: "begin", kind: "scalar", opt: true, T: runtime_1.ScalarType.INT32 },
{ no: 4, name: "end", kind: "scalar", opt: true, T: runtime_1.ScalarType.INT32 }
]);
}
}
exports.GeneratedCodeInfo_Annotation = new GeneratedCodeInfo_Annotation$Type();

View file

@ -0,0 +1,31 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./descriptor-info"), exports);
__exportStar(require("./descriptor-registry"), exports);
__exportStar(require("./descriptor-tree"), exports);
__exportStar(require("./generated-file"), exports);
__exportStar(require("./plugin-base"), exports);
__exportStar(require("./source-code-info"), exports);
__exportStar(require("./string-format"), exports);
__exportStar(require("./symbol-table"), exports);
__exportStar(require("./type-names"), exports);
__exportStar(require("./google/protobuf/descriptor"), exports);
__exportStar(require("./google/protobuf/compiler/plugin"), exports);
__exportStar(require("./typescript-compile"), exports);
__exportStar(require("./typescript-comments"), exports);
__exportStar(require("./typescript-import-manager"), exports);
__exportStar(require("./typescript-method-from-text"), exports);
__exportStar(require("./typescript-literal-from-value"), exports);
__exportStar(require("./typescript-enum-builder"), exports);
__exportStar(require("./typescript-file"), exports);
__exportStar(require("./typescript-imports"), exports);

View file

@ -0,0 +1,203 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PluginBase = void 0;
const plugin_1 = require("./google/protobuf/compiler/plugin");
const util_1 = require("util");
const runtime_1 = require("@protobuf-ts/runtime");
/**
* Base class for a protobuf plugin.
*
* Implement the abstract `generate()` method to create a plugin.
* The method takes a `CodeGeneratorRequest` and returns an
* array of `GeneratedFile` or a promise thereof.
*
*
* Usage:
*
* #!/usr/bin/env node
* const {MyPlugin} = require( ... );
* new MyPlugin.run().catch(_ => {
* process.stderr.write('failed to run plugin');
* process.exit(1);
* });
*
* Reads a `CodeGeneratorRequest` created by `protoc` from stdin,
* passes it to the plugin-function and writes a
* `CodeGeneratorResponse` to stdout.
*
*
* Options:
*
* Use the `parseOptions()` method the parse the parameter
* of a `CodeGeneratorRequest` to a map of flags. Options are
* validated and usage is generated on error.
*
*
* Error handling:
*
* `generate()` may raise an error, reject it's promise or
* return an `GeneratedFile` with an attached error.
*
* Throwing `new Error("hello")` will result in the output:
*
* $ protoc --xx_out=/tmp -I protos protos/*
* --xx_out: Error: hello
* at /path/to/your-plugin.js:69
* ...
*
*
*/
class PluginBase {
run() {
return __awaiter(this, void 0, void 0, function* () {
try {
let response, bytes = yield this.readBytes(process.stdin), request = plugin_1.CodeGeneratorRequest.fromBinary(bytes);
try {
const files = yield this.generate(request);
response = this.createResponse(files);
}
catch (error) {
response = plugin_1.CodeGeneratorResponse.create({
error: this.errorToString(error)
});
}
this.setBlockingStdout();
process.stdout.write(plugin_1.CodeGeneratorResponse.toBinary(response));
}
catch (error) {
process.stderr.write('Plugin failed to read CodeGeneratorRequest from stdin or write CodeGeneratorResponse to stdout.\n');
process.stderr.write(this.errorToString(error));
process.stderr.write('\n');
process.exit(1);
}
});
}
getSupportedFeatures() {
return [];
}
parseOptions(spec, parameter) {
var _a, _b, _c, _d;
this.validateOptionsSpec(spec);
let given = parameter ? parameter.split(',') : [];
let known = Object.keys(spec);
let excess = given.filter(i => !known.includes(i));
if (excess.length > 0) {
this.throwOptionError(spec, `Option "${excess.join('", "')}" not recognized.`);
}
for (let [key, val] of Object.entries(spec)) {
if (given.includes(key)) {
let missing = (_b = (_a = val.requires) === null || _a === void 0 ? void 0 : _a.filter(i => !given.includes(i))) !== null && _b !== void 0 ? _b : [];
if (missing.length > 0) {
this.throwOptionError(spec, `Option "${key}" requires option "${missing.join('", "')}" to be set.`);
}
let excess = (_d = (_c = val.excludes) === null || _c === void 0 ? void 0 : _c.filter(i => given.includes(i))) !== null && _d !== void 0 ? _d : [];
if (excess.length > 0) {
this.throwOptionError(spec, `If option "${key}" is set, option "${excess.join('", "')}" cannot be set.`);
}
}
}
let resolved = {};
for (let key of Object.keys(spec)) {
resolved[key] = given.includes(key);
}
return resolved;
}
throwOptionError(spec, error) {
let text = '';
text += error + '\n';
text += `\n`;
text += `Available options:\n`;
text += `\n`;
for (let [key, val] of Object.entries(spec)) {
text += `- "${key}"\n`;
for (let l of val.description.split('\n')) {
text += ` ${l}\n`;
}
text += `\n`;
}
let err = new Error(text);
err.name = `ParameterError`;
throw err;
}
validateOptionsSpec(spec) {
var _a, _b;
let known = Object.keys(spec);
for (let [key, { excludes, requires }] of Object.entries(spec)) {
let r = (_a = requires === null || requires === void 0 ? void 0 : requires.filter(i => !known.includes(i))) !== null && _a !== void 0 ? _a : [];
if (r.length > 0) {
throw new Error(`Invalid parameter spec for parameter "${key}". "requires" points to unknown parameters: ${r.join(', ')}`);
}
let e = (_b = excludes === null || excludes === void 0 ? void 0 : excludes.filter(i => !known.includes(i))) !== null && _b !== void 0 ? _b : [];
if (e.length > 0) {
throw new Error(`Invalid parameter spec for parameter "${key}". "excludes" points to unknown parameters: ${e.join(', ')}`);
}
}
}
readBytes(stream) {
return new Promise(resolve => {
const chunks = [];
stream.on('data', chunk => chunks.push(chunk));
stream.on('end', () => {
resolve(Buffer.concat(chunks));
});
});
}
createResponse(files) {
// we have to respond with an xor of all of our supported features.
// we should be working on a ulong here, but we cannot rely on bigint support.
let feat = 0;
for (let f of this.getSupportedFeatures()) {
feat = feat ^ f;
}
return plugin_1.CodeGeneratorResponse.create({
file: files
.map(f => plugin_1.CodeGeneratorResponse_File.create({
name: f.getFilename(),
content: f.getContent()
}))
.filter(f => f.content && f.content.length > 0),
supportedFeatures: runtime_1.PbULong.from(feat).toString()
});
}
errorToString(error) {
var _a;
if (error && typeof error.name == 'string' && error.name == 'ParameterError') {
return error.name + '\n\n' + error.message;
}
if (error && typeof error.name == 'string' && error.name == 'PluginMessageError') {
return error.message;
}
if (util_1.types.isNativeError(error)) {
return (_a = error.stack) !== null && _a !== void 0 ? _a : error.toString();
}
let text;
try {
text = error.toString();
}
catch (e) {
text = 'unknown error';
}
return text;
}
setBlockingStdout() {
// Fixes https://github.com/timostamm/protobuf-ts/issues/134
// Node is buffering chunks to stdout, meaning that for big generated
// files the CodeGeneratorResponse will not reach protoc completely.
// To fix this, we set stdout to block using the internal private
// method setBlocking(true)
const stdoutHandle = process.stdout._handle;
if (stdoutHandle) {
stdoutHandle.setBlocking(true);
}
}
}
exports.PluginBase = PluginBase;

View file

@ -0,0 +1,249 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileDescriptorProtoFields = exports.makeSourceCodePathComponent = exports.makeSourceCodePath = exports.filterSourceCodeLocations = exports.sourceCodeLocationToComment = exports.sourceCodeLocationToCursor = exports.SourceCodeInfoLookup = void 0;
const descriptor_1 = require("./google/protobuf/descriptor");
const runtime_1 = require("@protobuf-ts/runtime");
class SourceCodeInfoLookup {
constructor(parentResolver) {
this._parentResolver = parentResolver;
}
sourceCodeCursor(descriptor) {
var _a, _b;
const path = makeSourceCodePath(x => this._parentResolver(x), descriptor);
runtime_1.assert(path !== undefined, `Cannot create source code path`);
const all = (_b = (_a = this._findFile(descriptor).sourceCodeInfo) === null || _a === void 0 ? void 0 : _a.location) !== null && _b !== void 0 ? _b : [];
const hit = filterSourceCodeLocations(all, path);
return sourceCodeLocationToCursor(hit);
}
sourceCodeComments(descriptorOrFile, fileDescriptorFieldNumber) {
var _a, _b;
const path = makeSourceCodePath(x => this._parentResolver(x), descriptorOrFile);
runtime_1.assert(path !== undefined, `Cannot create source code path`);
if (fileDescriptorFieldNumber !== undefined) {
path.push(fileDescriptorFieldNumber);
}
const all = (_b = (_a = this._findFile(descriptorOrFile).sourceCodeInfo) === null || _a === void 0 ? void 0 : _a.location) !== null && _b !== void 0 ? _b : [];
const hit = filterSourceCodeLocations(all, path);
return sourceCodeLocationToComment(hit);
}
_findFile(d) {
let c = d;
while (c) {
if (descriptor_1.FileDescriptorProto.is(c)) {
return c;
}
c = this._parentResolver(c);
}
runtime_1.assert(false);
}
}
exports.SourceCodeInfoLookup = SourceCodeInfoLookup;
/**
* Return cursor position of the given source code location
* as line number and column, both starting at 1.
*
* If more than one location is given, only the first one
* is evaluated, the others are discarded.
*/
function sourceCodeLocationToCursor(locations) {
if (locations.length === 0) {
return emptyCursor;
}
const span = locations[0].span;
if (span === undefined || span.length < 3 || span.length > 4) {
return emptyCursor;
}
return [
span[0] + 1,
span[1] + 1
];
}
exports.sourceCodeLocationToCursor = sourceCodeLocationToCursor;
const emptyCursor = [undefined, undefined];
/**
* Return the comments for the given source code location.
*
* If more than one location is given, only the first one
* is evaluated, the others are discarded.
*
* If no comments found, empty (not undefined) object
* is returned.
*
* Trailing newlines are removed.
*/
function sourceCodeLocationToComment(locations) {
if (locations.length === 0) {
return emptyComment;
}
const location = locations[0], leadingDetached = location.leadingDetachedComments.map(stripTrailingNewline), leadingComments = location.leadingComments, leading = leadingComments === ''
? undefined
: (leadingComments === undefined
? undefined
: stripTrailingNewline(leadingComments)), trailingComments = location.trailingComments, trailing = trailingComments === ''
? undefined
: (trailingComments === undefined
? undefined
: stripTrailingNewline(trailingComments));
return (leadingDetached.length === 0 && leading === undefined && trailing === undefined)
? emptyComment
: { leadingDetached, leading, trailing };
}
exports.sourceCodeLocationToComment = sourceCodeLocationToComment;
function stripTrailingNewline(block) {
return block.endsWith('\n')
? block.slice(0, -1)
: block;
}
const emptyComment = {
leadingDetached: [],
leading: undefined,
trailing: undefined,
};
/**
* Find the source code locations that match the given path.
*/
function filterSourceCodeLocations(locations, path) {
return locations.filter(l => {
const p = l.path;
if (p.length !== path.length) {
return false;
}
for (let i = 0; i < p.length; i++) {
if (p[i] !== path[i]) {
return false;
}
}
return true;
});
}
exports.filterSourceCodeLocations = filterSourceCodeLocations;
/**
* Create the path to the source code location where the
* given element was declared.
*
* Returns `undefined` if we don't know how to make the path.
*
* For example, the path [4, 0, 2, 3] points to the 4th field
* of the first message of a .proto file:
*
* file
* .messageType // FileDescriptorProto.message_type = 3;
* [0] // first message
* .field // FileDescriptorProto.field = 2;
* [3] // 4th field
*
* See https://github.com/protocolbuffers/protobuf/blob/f1ce8663ac88df54cf212d29ce5123b69203b135/src/google/protobuf/descriptor.proto#L799
*/
function makeSourceCodePath(parentProvider, descriptor) {
const path = [];
let parent = parentProvider(descriptor);
let component;
while (parent) {
component = makeSourceCodePathComponent(parent, descriptor);
if (component === undefined) {
return undefined;
}
path.unshift(...component);
descriptor = parent;
parent = parentProvider(parent);
}
return path;
}
exports.makeSourceCodePath = makeSourceCodePath;
/**
* Make a path from the parent to the immediate child.
*
* Returns `undefined` if we don't know how to make the path.
*/
function makeSourceCodePathComponent(parent, child) {
if (descriptor_1.FileDescriptorProto.is(parent) && descriptor_1.DescriptorProto.is(child)) {
return [
FileDescriptorProtoFields.message_type,
parent.messageType.indexOf(child)
];
}
if (descriptor_1.FileDescriptorProto.is(parent) && descriptor_1.EnumDescriptorProto.is(child)) {
return [
FileDescriptorProtoFields.enum_type,
parent.enumType.indexOf(child)
];
}
if (descriptor_1.FileDescriptorProto.is(parent) && descriptor_1.ServiceDescriptorProto.is(child)) {
return [
FileDescriptorProtoFields.service,
parent.service.indexOf(child)
];
}
if (descriptor_1.DescriptorProto.is(parent) && descriptor_1.EnumDescriptorProto.is(child)) {
return [
DescriptorProtoFields.enum_type,
parent.enumType.indexOf(child)
];
}
if (descriptor_1.DescriptorProto.is(parent) && descriptor_1.DescriptorProto.is(child)) {
return [
DescriptorProtoFields.nested_type,
parent.nestedType.indexOf(child)
];
}
if (descriptor_1.DescriptorProto.is(parent) && descriptor_1.FieldDescriptorProto.is(child)) {
return [
DescriptorProtoFields.field,
parent.field.indexOf(child)
];
}
if (descriptor_1.DescriptorProto.is(parent) && descriptor_1.OneofDescriptorProto.is(child)) {
return [
DescriptorProtoFields.oneof_decl,
parent.oneofDecl.indexOf(child)
];
}
if (descriptor_1.EnumDescriptorProto.is(parent) && descriptor_1.EnumValueDescriptorProto.is(child)) {
return [
EnumDescriptorProtoFields.value,
parent.value.indexOf(child)
];
}
if (descriptor_1.ServiceDescriptorProto.is(parent) && descriptor_1.MethodDescriptorProto.is(child)) {
return [
ServiceDescriptorProtoFields.method,
parent.method.indexOf(child)
];
}
return undefined;
}
exports.makeSourceCodePathComponent = makeSourceCodePathComponent;
var FileDescriptorProtoFields;
(function (FileDescriptorProtoFields) {
FileDescriptorProtoFields[FileDescriptorProtoFields["syntax"] = 12] = "syntax";
FileDescriptorProtoFields[FileDescriptorProtoFields["package"] = 2] = "package";
FileDescriptorProtoFields[FileDescriptorProtoFields["message_type"] = 4] = "message_type";
FileDescriptorProtoFields[FileDescriptorProtoFields["enum_type"] = 5] = "enum_type";
FileDescriptorProtoFields[FileDescriptorProtoFields["service"] = 6] = "service";
})(FileDescriptorProtoFields = exports.FileDescriptorProtoFields || (exports.FileDescriptorProtoFields = {}));
var DescriptorProtoFields;
(function (DescriptorProtoFields) {
DescriptorProtoFields[DescriptorProtoFields["field"] = 2] = "field";
DescriptorProtoFields[DescriptorProtoFields["nested_type"] = 3] = "nested_type";
DescriptorProtoFields[DescriptorProtoFields["enum_type"] = 4] = "enum_type";
DescriptorProtoFields[DescriptorProtoFields["options"] = 7] = "options";
DescriptorProtoFields[DescriptorProtoFields["oneof_decl"] = 8] = "oneof_decl";
})(DescriptorProtoFields || (DescriptorProtoFields = {}));
// enum FieldDescriptorProtoFields {
// name = 1, // optional string name = 1;
// number = 3, // optional int32 number = 3;
// label = 4, // optional Label label = 4;
// type = 5, // optional Type type = 5;
// }
var EnumDescriptorProtoFields;
(function (EnumDescriptorProtoFields) {
// name = 1, // optional string name = 1;
EnumDescriptorProtoFields[EnumDescriptorProtoFields["value"] = 2] = "value";
// options = 3, // optional EnumOptions options = 3;
})(EnumDescriptorProtoFields || (EnumDescriptorProtoFields = {}));
var ServiceDescriptorProtoFields;
(function (ServiceDescriptorProtoFields) {
// name = 1, // optional string name = 1;
ServiceDescriptorProtoFields[ServiceDescriptorProtoFields["method"] = 2] = "method";
// options = 3, // optional ServiceOptions options = 3;
})(ServiceDescriptorProtoFields || (ServiceDescriptorProtoFields = {}));

View file

@ -0,0 +1,220 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StringFormat = void 0;
const descriptor_1 = require("./google/protobuf/descriptor");
const descriptor_info_1 = require("./descriptor-info");
const runtime_1 = require("@protobuf-ts/runtime");
class StringFormat {
constructor(a, b, c, d) {
if (b === undefined) {
this.nameLookup = a;
this.treeLookup = a;
this.sourceCodeLookup = a;
this.descriptorInfo = a;
}
else {
this.nameLookup = a;
this.treeLookup = b;
this.sourceCodeLookup = c;
this.descriptorInfo = d;
}
}
/**
* Returns name of a scalar value type like it would
* appear in a .proto.
*
* For example, `FieldDescriptorProto_Type.UINT32` -> `"uint32"`.
*/
static formatScalarType(type) {
let name = descriptor_1.FieldDescriptorProto_Type[type];
runtime_1.assert(name !== undefined, "unexpected ScalarValueType " + type);
return name.toLowerCase();
}
/**
* Returns type ('message', 'field', etc.) and descriptor name.
*
* Examples:
* message Bar
* field value = 2
* rpc Fetch()
*/
static formatName(descriptor) {
if (descriptor_1.FileDescriptorProto.is(descriptor)) {
return `file ${descriptor.name}`;
}
else if (descriptor_1.DescriptorProto.is(descriptor)) {
return `message ${descriptor.name}`;
}
else if (descriptor_1.FieldDescriptorProto.is(descriptor)) {
if (descriptor.extendee !== undefined) {
return `extension field ${descriptor.name} = ${descriptor.number}`;
}
return `field ${descriptor.name} = ${descriptor.number}`;
}
else if (descriptor_1.EnumDescriptorProto.is(descriptor)) {
return `enum ${descriptor.name}`;
}
else if (descriptor_1.EnumValueDescriptorProto.is(descriptor)) {
return `enum value ${descriptor.name} = ${descriptor.number}`;
}
else if (descriptor_1.ServiceDescriptorProto.is(descriptor)) {
return `service ${descriptor.name}`;
}
else if (descriptor_1.MethodDescriptorProto.is(descriptor)) {
return `rpc ${descriptor.name}()`;
}
else
// noinspection SuspiciousTypeOfGuard
if (descriptor_1.OneofDescriptorProto.is(descriptor)) {
return `oneof ${descriptor.name}`;
}
runtime_1.assertNever(descriptor);
runtime_1.assert(false);
}
formatQualifiedName(descriptor, includeFileInfo) {
if (descriptor_1.FileDescriptorProto.is(descriptor)) {
return `file ${descriptor.name}`;
}
const file = includeFileInfo ? ' in ' + getSourceWithLineNo(descriptor, this.treeLookup, this.sourceCodeLookup) : '';
if (descriptor_1.DescriptorProto.is(descriptor)) {
return `message ${this.nameLookup.makeTypeName(descriptor)}${file}`;
}
if (descriptor_1.EnumDescriptorProto.is(descriptor)) {
return `enum ${this.nameLookup.makeTypeName(descriptor)}${file}`;
}
if (descriptor_1.ServiceDescriptorProto.is(descriptor)) {
return `service ${this.nameLookup.makeTypeName(descriptor)}${file}`;
}
let parent = this.treeLookup.parentOf(descriptor);
if (descriptor_1.FieldDescriptorProto.is(descriptor) && this.descriptorInfo.isExtension(descriptor)) {
let extensionName = this.descriptorInfo.getExtensionName(descriptor);
runtime_1.assert(descriptor.extendee);
let extendeeTypeName = this.nameLookup.normalizeTypeName(descriptor.extendee);
return `extension ${extendeeTypeName}.(${extensionName})${file}`;
}
runtime_1.assert(descriptor_info_1.isAnyTypeDescriptorProto(parent));
let parentTypeName = this.nameLookup.makeTypeName(parent);
if (descriptor_1.FieldDescriptorProto.is(descriptor)) {
return `field ${parentTypeName}.${descriptor.name}${file}`;
}
if (descriptor_1.EnumValueDescriptorProto.is(descriptor)) {
return `enum value ${parentTypeName}.${descriptor.name}${file}`;
}
if (descriptor_1.MethodDescriptorProto.is(descriptor)) {
return `rpc ${parentTypeName}.${descriptor.name}()${file}`;
}
return `oneof ${parentTypeName}.${descriptor.name}${file}`;
}
formatName(descriptor) {
return StringFormat.formatName(descriptor);
}
formatFieldDeclaration(descriptor) {
var _a, _b, _c, _d, _e;
let text = '';
// repeated ?
if (this.descriptorInfo.isUserDeclaredRepeated(descriptor)) {
text += 'repeated ';
}
// optional ?
if (this.descriptorInfo.isUserDeclaredOptional(descriptor)) {
text += 'optional ';
}
switch (descriptor.type) {
case descriptor_1.FieldDescriptorProto_Type.ENUM:
text += this.nameLookup.makeTypeName(this.descriptorInfo.getEnumFieldEnum(descriptor));
break;
case descriptor_1.FieldDescriptorProto_Type.MESSAGE:
if (this.descriptorInfo.isMapField(descriptor)) {
let mapK = StringFormat.formatScalarType(this.descriptorInfo.getMapKeyType(descriptor));
let mapVType = this.descriptorInfo.getMapValueType(descriptor);
let mapV = typeof mapVType === "number"
? StringFormat.formatScalarType(mapVType)
: this.nameLookup.makeTypeName(mapVType);
text += `map<${mapK}, ${mapV}>`;
}
else {
text += this.nameLookup.makeTypeName(this.descriptorInfo.getMessageFieldMessage(descriptor));
}
break;
case descriptor_1.FieldDescriptorProto_Type.DOUBLE:
case descriptor_1.FieldDescriptorProto_Type.FLOAT:
case descriptor_1.FieldDescriptorProto_Type.INT64:
case descriptor_1.FieldDescriptorProto_Type.UINT64:
case descriptor_1.FieldDescriptorProto_Type.INT32:
case descriptor_1.FieldDescriptorProto_Type.FIXED64:
case descriptor_1.FieldDescriptorProto_Type.FIXED32:
case descriptor_1.FieldDescriptorProto_Type.BOOL:
case descriptor_1.FieldDescriptorProto_Type.STRING:
case descriptor_1.FieldDescriptorProto_Type.BYTES:
case descriptor_1.FieldDescriptorProto_Type.UINT32:
case descriptor_1.FieldDescriptorProto_Type.SFIXED32:
case descriptor_1.FieldDescriptorProto_Type.SFIXED64:
case descriptor_1.FieldDescriptorProto_Type.SINT32:
case descriptor_1.FieldDescriptorProto_Type.SINT64:
text += StringFormat.formatScalarType(descriptor.type);
break;
case descriptor_1.FieldDescriptorProto_Type.GROUP:
text += "group";
break;
case descriptor_1.FieldDescriptorProto_Type.UNSPECIFIED$:
text += "???";
break;
}
// name
text += ' ' + descriptor.name;
// number
text += ' = ' + descriptor.number;
// options
let options = [];
if (this.descriptorInfo.isExplicitlyDeclaredDeprecated(descriptor)) {
options.push('deprecated = true');
}
if (this.descriptorInfo.getFieldCustomJsonName(descriptor)) {
options.push(`json_name = "${this.descriptorInfo.getFieldCustomJsonName(descriptor)}"`);
}
if (((_a = descriptor.options) === null || _a === void 0 ? void 0 : _a.jstype) == descriptor_1.FieldOptions_JSType.JS_STRING) {
options.push(`jstype = JS_STRING`);
}
if (((_b = descriptor.options) === null || _b === void 0 ? void 0 : _b.jstype) == descriptor_1.FieldOptions_JSType.JS_NUMBER) {
options.push(`jstype = JS_NUMBER`);
}
if (((_c = descriptor.options) === null || _c === void 0 ? void 0 : _c.jstype) == descriptor_1.FieldOptions_JSType.JS_NORMAL) {
options.push(`jstype = JS_NORMAL`);
}
if (((_d = descriptor.options) === null || _d === void 0 ? void 0 : _d.packed) === true) {
options.push(`packed = true`);
}
if (((_e = descriptor.options) === null || _e === void 0 ? void 0 : _e.packed) === false) {
options.push(`packed = false`);
}
if (options.length) {
text += ' [' + options.join(', ') + ']';
}
// semicolon
text += ';';
return text;
}
formatEnumValueDeclaration(descriptor) {
let text = `${descriptor.name} = ${descriptor.number}`;
if (this.descriptorInfo.isExplicitlyDeclaredDeprecated(descriptor)) {
text += ' [deprecated = true]';
}
return text + ';';
}
formatRpcDeclaration(descriptor) {
this.descriptorInfo.isExplicitlyDeclaredDeprecated(descriptor);
let m = descriptor.name, i = descriptor.inputType, is = descriptor.clientStreaming ? 'stream ' : '', o = descriptor.outputType, os = descriptor.serverStreaming ? 'stream ' : '';
if (i.startsWith('.')) {
i = i.substring(1);
}
if (o.startsWith('.')) {
o = o.substring(1);
}
return `${m}(${is}${i}) returns (${os}${o});`;
}
}
exports.StringFormat = StringFormat;
function getSourceWithLineNo(descriptor, treeLookup, sourceCodeLookup) {
let file = treeLookup.fileOf(descriptor), [l] = sourceCodeLookup.sourceCodeCursor(descriptor);
return `${file.name}:${l}`;
}

View file

@ -0,0 +1,97 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SymbolTable = void 0;
const string_format_1 = require("./string-format");
/**
* A table for unique symbols (for any DescriptorProto, EnumDescriptorProto
* or ServiceDescriptorProto) in files (GeneratedFile).
*/
class SymbolTable {
constructor(clashResolver) {
this.entries = [];
this.clashResolveMaxTries = 100;
this.hasNameInFile = (name, file) => this.entries.some(e => e.file === file && e.name === name);
this.clashResolver = clashResolver !== null && clashResolver !== void 0 ? clashResolver : SymbolTable.defaultClashResolver;
}
/**
* Register a symbol in the given file for the given descriptor.
*
* If the name is already taken in the file, an alternative name
* is automatically generated by appending '$' and a running
* number to the requested name. You can change the behaviour by
* providing your own `clashResolver`.
*
* Only one symbol per kind can be registered for a descriptor.
*
* If you want to generate an interface *and* a class for a
* message, use a different `kind` for each.
*
* Returns the actual name registered.
*/
register(requestedName, descriptor, file, kind = 'default') {
// Only one symbol per kind can be registered for a descriptor.
if (this.has(descriptor, kind)) {
let { file, name } = this.get(descriptor, kind);
let msg = `Cannot register name "${requestedName}" of kind "${kind}" for ${string_format_1.StringFormat.formatName(descriptor)}. `
+ `The descriptor is already registered in file "${file.getFilename()}" with name "${name}". `
+ `Use a different 'kind' to register multiple symbols for a descriptor.`;
throw new Error(msg);
}
// find a free name within the file
let name = requestedName;
let count = 0;
while (this.hasNameInFile(name, file) && count < this.clashResolveMaxTries) {
name = this.clashResolver(descriptor, file, requestedName, kind, ++count, name);
}
if (this.hasNameInFile(name, file)) {
let msg = `Failed to register name "${requestedName}" for ${string_format_1.StringFormat.formatName(descriptor)}. `
+ `Gave up finding alternative name after ${this.clashResolveMaxTries} tries. `
+ `There is something wrong with the clash resolver.`;
throw new Error(msg);
}
// add the entry and return name
this.entries.push({ file, descriptor, kind, name });
return name;
}
/**
* Find a symbol (of the given kind) for the given descriptor.
* Return `undefined` if not found.
*/
find(descriptor, kind = 'default') {
return this.entries.find(e => e.descriptor === descriptor && e.kind === kind);
}
/**
* Find a symbol (of the given kind) for the given descriptor.
* Raises error if not found.
*/
get(descriptor, kind = 'default') {
const found = this.find(descriptor, kind);
if (!found) {
let files = this.entries.map(e => e.file)
.filter((value, index, array) => array.indexOf(value) === index);
let msg = `Failed to find name for ${string_format_1.StringFormat.formatName(descriptor)} of kind "${kind}". `
+ `Searched in ${files.length} files.`;
throw new Error(msg);
}
return found;
}
/**
* Is a name (of the given kind) registered for the the given descriptor?
*/
has(descriptor, kind = 'default') {
return !!this.find(descriptor, kind);
}
list(file, kind) {
let matches = this.entries.filter(e => e.file === file);
if (kind !== undefined) {
matches = matches.filter(e => e.kind === kind);
}
return matches;
}
static defaultClashResolver(descriptor, file, requestedName, kind, tryCount) {
let n = requestedName;
n = n.endsWith('$') ? n.substring(1) : n;
return n + '$' + tryCount;
}
}
exports.SymbolTable = SymbolTable;

View file

@ -0,0 +1,90 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TypeNameLookup = void 0;
const descriptor_info_1 = require("./descriptor-info");
const descriptor_1 = require("./google/protobuf/descriptor");
const runtime_1 = require("@protobuf-ts/runtime");
class TypeNameLookup {
constructor(data) {
const names = new Map();
const reverse = new Map();
for (let { descriptor, ancestors } of data) {
let name = composeTypeName([...ancestors, descriptor]);
runtime_1.assert(!names.has(name));
names.set(name, descriptor);
reverse.set(descriptor, name);
}
this._names = names;
this._reverse = reverse;
}
static from(a, b) {
let data = [];
if (Array.isArray(a) && b) {
for (let descriptor of a) {
if (!descriptor_info_1.isAnyTypeDescriptorProto(descriptor)) {
continue;
}
let ancestors = [];
let p = b(descriptor);
while (p) {
ancestors.unshift(p);
p = b(descriptor);
}
data.push({ descriptor, ancestors });
}
}
else if (!Array.isArray(a) && !b) {
a.visitTypes(descriptor => {
data.push({ descriptor, ancestors: a.ancestorsOf(descriptor) });
});
}
else {
runtime_1.assert(false);
}
return new TypeNameLookup(data);
}
normalizeTypeName(typeName) {
return typeName.startsWith(".") ? typeName.substring(1) : typeName;
}
resolveTypeName(typeName) {
typeName = this.normalizeTypeName(typeName);
const d = this._names.get(typeName);
runtime_1.assert(d !== undefined, `Unable to resolve type name "${typeName}"`);
return d;
}
peekTypeName(typeName) {
typeName = this.normalizeTypeName(typeName);
return this._names.get(typeName);
}
makeTypeName(descriptor) {
const n = this._reverse.get(descriptor);
runtime_1.assert(n !== undefined);
return n;
}
}
exports.TypeNameLookup = TypeNameLookup;
/**
* Compose a fully qualified type name for enum,
* message or service.
*
* Example:
* my_package.MyMessage.MyNestedMessage
*
* Throws if given array is invalid.
*/
function composeTypeName(descriptors) {
runtime_1.assert(descriptors.length > 0);
const parts = [], mid = descriptors.concat(), first = mid.shift(), last = mid.pop();
runtime_1.assert(descriptor_1.FileDescriptorProto.is(first));
runtime_1.assert(descriptor_info_1.isAnyTypeDescriptorProto(last), "expected any type descriptor, got: " + typeof (last));
const pkg = first.package;
if (pkg !== undefined && pkg !== '') {
parts.push(pkg);
}
for (const item of [...mid, last]) {
let part = item.name;
runtime_1.assert(part !== undefined);
parts.push(part);
}
return parts.join('.');
}

View file

@ -0,0 +1,52 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.addCommentBlockAsJsDoc = exports.addCommentBlocksAsLeadingDetachedLines = void 0;
const ts = require("typescript");
/**
* Adds multiple comment blocks as line comments
* in front of the given node.
*
* Applies a dirty hack to enforce newlines
* between each block.
*/
function addCommentBlocksAsLeadingDetachedLines(node, ...texts) {
for (let text of texts) {
let lines = text.split('\n').map(l => l[0] !== ' ' ? ` ${l}` : l);
for (let j = 0; j < lines.length; j++) {
const line = lines[j];
if (j === lines.length - 1) {
ts.addSyntheticLeadingComment(node, ts.SyntaxKind.SingleLineCommentTrivia, line + '\n\n', false);
}
else {
ts.addSyntheticLeadingComment(node, ts.SyntaxKind.SingleLineCommentTrivia, line, true);
}
}
}
}
exports.addCommentBlocksAsLeadingDetachedLines = addCommentBlocksAsLeadingDetachedLines;
/**
* Adds a JSDoc comment block in front of the given node.
*
* A JSDoc comment looks like this:
* /**
* * body text
* *\/
*
* A regular block comment looks like this:
* /* body text *\/
*
*/
function addCommentBlockAsJsDoc(node, text) {
let lines = text
.split('\n')
.map(line => {
if (line[0] === ' ') {
return ' *' + line;
}
return ' * ' + line;
});
text = '*\n' + lines.join('\n') + '\n ';
text = text.split('*/').join('*\\/'); // need to escape a comment in the comment
ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, text, true);
}
exports.addCommentBlockAsJsDoc = addCommentBlockAsJsDoc;

View file

@ -0,0 +1,123 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setupCompiler = void 0;
const ts = require("typescript");
const path = require("path");
function setupCompiler(options, files, rootFileNames) {
const original = ts.createCompilerHost(options, true), host = new VirtualCompilerHost(original, files), libs = options.lib ? options.lib.map(lib => require.resolve(`typescript/lib/lib.${lib.toLowerCase()}.d.ts`)) : [], roots = rootFileNames.concat(libs), program = ts.createProgram(roots, options, host);
return [program, host];
}
exports.setupCompiler = setupCompiler;
class VirtualCompilerHost {
constructor(wrapped, files) {
this.wrapped = wrapped;
this._sourceFiles = new Map();
this._files = new Map();
this._dirs = new Set();
for (let vf of files) {
// create map from path to file
if (this._files.has(vf.getFilename())) {
throw new Error('Duplicate file paths in virtual files: ' + vf.getFilename());
}
this._files.set(vf.getFilename(), vf);
// create set of directory paths
let path = vf.getFilename().split('/');
while (path.length > 1) {
path.pop();
this._dirs.add(path.join('/'));
}
}
}
lookupVirtualFile(fileName) {
let vf = this._files.get(fileName);
if (vf)
return vf;
let cwd = process.cwd();
if (fileName.startsWith(cwd)) {
let relativePath = path.relative(cwd, fileName);
vf = this._files.get(relativePath);
if (vf)
return vf;
if (!relativePath.endsWith('.ts')) {
relativePath = relativePath += '.ts';
vf = this._files.get(relativePath);
if (vf)
return vf;
}
}
return undefined;
}
lookupVirtualDirectory(directoryName) {
let cwd = process.cwd();
if (directoryName.startsWith(cwd)) {
let relativePath = path.relative(cwd, directoryName);
return this._dirs.has(relativePath);
}
return false;
}
// noinspection JSUnusedGlobalSymbols
getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) {
const vf = this.lookupVirtualFile(fileName);
if (vf) {
let sf = this._sourceFiles.get(vf);
if (!sf) {
this._sourceFiles.set(vf, sf = ts.createSourceFile(vf.getFilename(), vf.getContent(), ts.ScriptTarget.Latest));
}
return sf;
}
return this.wrapped.getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
}
// noinspection JSUnusedGlobalSymbols
getDefaultLibFileName(options) {
return this.wrapped.getDefaultLibFileName(options);
}
// noinspection JSUnusedGlobalSymbols,JSUnusedLocalSymbols
writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles) {
// this.wrapped.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles);
}
// noinspection JSUnusedGlobalSymbols
getCurrentDirectory() {
return this.wrapped.getCurrentDirectory();
}
// noinspection JSUnusedGlobalSymbols
getCanonicalFileName(fileName) {
return this.wrapped.getCanonicalFileName(fileName);
}
// noinspection JSUnusedGlobalSymbols
useCaseSensitiveFileNames() {
return this.wrapped.useCaseSensitiveFileNames();
}
// noinspection JSUnusedGlobalSymbols
getNewLine() {
return this.wrapped.getNewLine();
}
// resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[], redirectedReference: ts.ResolvedProjectReference, options: ts.CompilerOptions): (ts.ResolvedModule | undefined)[] {
// resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string, redirectedReference: ts.ResolvedProjectReference, options: ts.CompilerOptions): ts.ResolvedTypeReferenceDirective[] {
// noinspection JSUnusedGlobalSymbols
fileExists(fileName) {
return !!this.lookupVirtualFile(fileName) || this.wrapped.fileExists(fileName);
}
// noinspection JSUnusedGlobalSymbols
readFile(fileName) {
const vf = this.lookupVirtualFile(fileName);
if (vf)
return vf.getContent();
this.wrapped.readFile(fileName);
}
// noinspection JSUnusedGlobalSymbols
directoryExists(directoryName) {
if (this.lookupVirtualDirectory(directoryName))
return true;
const f = this.wrapped.directoryExists;
if (!f)
throw new Error('wrapped.directoryExists is undefined');
return f(directoryName);
}
// noinspection JSUnusedGlobalSymbols
getDirectories(path) {
const f = this.wrapped.getDirectories;
if (!f)
throw new Error('wrapped.getDirectories is undefined');
return f(path);
}
}

View file

@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TypescriptEnumBuilder = void 0;
const ts = require("typescript");
const rt = require("@protobuf-ts/runtime");
const typescript_comments_1 = require("./typescript-comments");
/**
* Creates an enum declaration.
*/
class TypescriptEnumBuilder {
constructor() {
this.values = [];
}
add(name, number, comment) {
this.values.push({ name, number, comment });
}
build(name, modifiers) {
this.validate();
const members = [];
for (let { name, number, comment } of this.values) {
let member = ts.createEnumMember(ts.createIdentifier(name), ts.createNumericLiteral(number.toString()));
if (comment) {
typescript_comments_1.addCommentBlockAsJsDoc(member, comment);
}
members.push(member);
}
return ts.createEnumDeclaration(undefined, modifiers, name, members);
}
validate() {
if (this.values.map(v => v.name).some((name, i, a) => a.indexOf(name) !== i))
throw new Error("duplicate names");
let ei = {};
for (let v of this.values) {
ei[v.number] = v.name;
ei[v.name] = v.number;
}
if (!rt.isEnumObject(ei)) {
throw new Error("not a typescript enum object");
}
}
}
exports.TypescriptEnumBuilder = TypescriptEnumBuilder;

View file

@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TypescriptFile = void 0;
const ts = require("typescript");
class TypescriptFile {
constructor(filename) {
this.sf = ts.createSourceFile(filename, "", ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
}
getFilename() {
return this.sf.fileName;
}
/**
* Add the new statement to the file.
*/
addStatement(statement, atTop = false) {
const newStatements = atTop
? [statement, ...this.sf.statements]
: this.sf.statements.concat(statement);
this.sf = ts.updateSourceFileNode(this.sf, newStatements);
}
/**
* The underlying SourceFile
*/
getSourceFile() {
return this.sf;
}
/**
* Are there any statements in this file?
*/
isEmpty() {
return this.sf.statements.length === 0;
}
/**
* The full content of this file.
* Returns an empty string if there are no statements.
*/
getContent() {
let printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
return printer.printFile(this.sf);
}
}
exports.TypescriptFile = TypescriptFile;

View file

@ -0,0 +1,206 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TypescriptImportManager = void 0;
const runtime_1 = require("@protobuf-ts/runtime");
const ts = require("typescript");
const path = require("path");
/** @deprecated */
class TypescriptImportManager {
constructor(generatedFile, symbols, source) {
this.file = generatedFile;
this.symbols = symbols;
this.source = source;
}
/**
* Import {importName} from "importFrom";
*
* Automatically finds a free name if the
* `importName` would collide with another
* identifier.
*
* Returns imported name.
*/
name(importName, importFrom) {
const blackListedNames = this.symbols.list(this.file).map(e => e.name);
return ensureNamedImportPresent(this.source.getSourceFile(), importName, importFrom, blackListedNames, statementToAdd => this.source.addStatement(statementToAdd, true));
}
/**
* Import * as importAs from "importFrom";
*
* Returns name for `importAs`.
*/
namespace(importAs, importFrom) {
return ensureNamespaceImportPresent(this.source.getSourceFile(), importAs, importFrom, statementToAdd => this.source.addStatement(statementToAdd, true));
}
/**
* Import a previously registered identifier for a message
* or other descriptor.
*
* Uses the symbol table to look for the type, adds an
* import statement if necessary and automatically finds a
* free name if the identifier would clash in this file.
*
* If you have multiple representations for a descriptor
* in your generated code, use `kind` to discriminate.
*/
type(descriptor, kind = 'default') {
const symbolReg = this.symbols.get(descriptor, kind);
// symbol in this file?
if (symbolReg.file === this.file) {
return symbolReg.name;
}
// symbol not in file
// add an import statement
const importPath = createRelativeImportPath(this.source.getSourceFile().fileName, symbolReg.file.getFilename());
const blackListedNames = this.symbols.list(this.file).map(e => e.name);
return ensureNamedImportPresent(this.source.getSourceFile(), symbolReg.name, importPath, blackListedNames, statementToAdd => this.source.addStatement(statementToAdd, true));
}
}
exports.TypescriptImportManager = TypescriptImportManager;
/**
* Import * as asName from "importFrom";
*
* If the import is already present, just return the
* identifier.
*
* If the import is not present, create the import
* statement and call `addStatementFn`.
*
* Does *not* check for collisions.
*/
function ensureNamespaceImportPresent(currentFile, asName, importFrom, addStatementFn) {
const all = findNamespaceImports(currentFile), match = all.find(ni => ni.as === asName && ni.from === importFrom);
if (match) {
return match.as;
}
const statementToAdd = createNamespaceImport(asName, importFrom);
addStatementFn(statementToAdd);
return asName;
}
/**
* import * as <asName> from "<importFrom>";
*/
function createNamespaceImport(asName, importFrom) {
return ts.createImportDeclaration(undefined, undefined, ts.createImportClause(undefined, ts.createNamespaceImport(ts.createIdentifier(asName))), ts.createStringLiteral(importFrom));
}
/**
* import * as <as> from "<from>";
*/
function findNamespaceImports(sourceFile) {
let r = [];
for (let s of sourceFile.statements) {
if (ts.isImportDeclaration(s) && s.importClause) {
let namedBindings = s.importClause.namedBindings;
if (namedBindings && ts.isNamespaceImport(namedBindings)) {
runtime_1.assert(ts.isStringLiteral(s.moduleSpecifier));
r.push({
as: namedBindings.name.escapedText.toString(),
from: s.moduleSpecifier.text
});
}
}
}
return r;
}
/**
* Import {importName} from "importFrom";
*
* If the import is already present, just return the
* identifier.
*
* If the import is not present, create the import
* statement and call `addStatementFn`.
*
* If the import name is taken by another named import
* or is in the list of blacklisted names, an
* alternative name is used:
*
* Import {importName as alternativeName} from "importFrom";
*
* Returns the imported name or the alternative name.
*/
function ensureNamedImportPresent(currentFile, importName, importFrom, blacklistedNames, addStatementFn, escapeCharacter = '$') {
var _a;
const all = findNamedImports(currentFile), taken = all.map(ni => { var _a; return (_a = ni.as) !== null && _a !== void 0 ? _a : ni.name; }).concat(blacklistedNames), match = all.find(ni => ni.name === importName && ni.from === importFrom);
if (match) {
return (_a = match.as) !== null && _a !== void 0 ? _a : match.name;
}
let as;
if (taken.includes(importName)) {
let i = 0;
as = importName;
while (taken.includes(as)) {
as = importName + escapeCharacter;
if (i++ > 0) {
as += i;
}
}
}
const statementToAdd = createNamedImport(importName, importFrom, as);
addStatementFn(statementToAdd);
return as !== null && as !== void 0 ? as : importName;
}
/**
* import {<name>} from '<from>';
* import {<name> as <as>} from '<from>';
*/
function createNamedImport(name, from, as) {
if (as) {
return ts.createImportDeclaration(undefined, undefined, ts.createImportClause(undefined, ts.createNamedImports([ts.createImportSpecifier(ts.createIdentifier(name), ts.createIdentifier(as))]), false), ts.createStringLiteral(from));
}
return ts.createImportDeclaration(undefined, undefined, ts.createImportClause(undefined, ts.createNamedImports([
ts.createImportSpecifier(undefined, ts.createIdentifier(name))
])), ts.createStringLiteral(from));
}
/**
* import {<name>} from '<from>';
* import {<name> as <as>} from '<from>';
*/
function findNamedImports(sourceFile) {
let r = [];
for (let s of sourceFile.statements) {
if (ts.isImportDeclaration(s) && s.importClause) {
let namedBindings = s.importClause.namedBindings;
if (namedBindings && ts.isNamedImports(namedBindings)) {
for (let importSpecifier of namedBindings.elements) {
runtime_1.assert(ts.isStringLiteral(s.moduleSpecifier));
if (importSpecifier.propertyName) {
r.push({
name: importSpecifier.propertyName.escapedText.toString(),
as: importSpecifier.name.escapedText.toString(),
from: s.moduleSpecifier.text
});
}
else {
r.push({
name: importSpecifier.name.escapedText.toString(),
as: undefined,
from: s.moduleSpecifier.text
});
}
}
}
}
}
return r;
}
/**
* Create a relative path for an import statement like
* `import {Foo} from "./foo"`
*/
function createRelativeImportPath(currentPath, pathToImportFrom) {
// create relative path to the file to import
let fromPath = path.relative(path.dirname(currentPath), pathToImportFrom);
// on windows, this may add backslash directory separators.
// we replace them with forward slash.
if (path.sep !== "/") {
fromPath = fromPath.split(path.sep).join("/");
}
// drop file extension
fromPath = fromPath.replace(/\.[a-z]+$/, '');
// make sure to start with './' to signal relative path to module resolution
if (!fromPath.startsWith('../') && !fromPath.startsWith('./')) {
fromPath = './' + fromPath;
}
return fromPath;
}

View file

@ -0,0 +1,214 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.findNamedImports = exports.createNamedImport = exports.ensureNamedImportPresent = exports.TypeScriptImports = void 0;
const runtime_1 = require("@protobuf-ts/runtime");
const ts = require("typescript");
const path = require("path");
class TypeScriptImports {
constructor(symbols) {
this.symbols = symbols;
}
/**
* Import {importName} from "importFrom";
*
* Automatically finds a free name if the
* `importName` would collide with another
* identifier.
*
* Returns imported name.
*/
name(source, importName, importFrom, isTypeOnly = false) {
const blackListedNames = this.symbols.list(source).map(e => e.name);
return ensureNamedImportPresent(source.getSourceFile(), importName, importFrom, isTypeOnly, blackListedNames, statementToAdd => source.addStatement(statementToAdd, true));
}
/**
* Import * as importAs from "importFrom";
*
* Returns name for `importAs`.
*/
namespace(source, importAs, importFrom, isTypeOnly = false) {
return ensureNamespaceImportPresent(source.getSourceFile(), importAs, importFrom, isTypeOnly, statementToAdd => source.addStatement(statementToAdd, true));
}
/**
* Import a previously registered identifier for a message
* or other descriptor.
*
* Uses the symbol table to look for the type, adds an
* import statement if necessary and automatically finds a
* free name if the identifier would clash in this file.
*
* If you have multiple representations for a descriptor
* in your generated code, use `kind` to discriminate.
*/
type(source, descriptor, kind = 'default', isTypeOnly = false) {
const symbolReg = this.symbols.get(descriptor, kind);
// symbol in this file?
if (symbolReg.file === source) {
return symbolReg.name;
}
// symbol not in file
// add an import statement
const importPath = createRelativeImportPath(source.getSourceFile().fileName, symbolReg.file.getFilename());
const blackListedNames = this.symbols.list(source).map(e => e.name);
return ensureNamedImportPresent(source.getSourceFile(), symbolReg.name, importPath, isTypeOnly, blackListedNames, statementToAdd => source.addStatement(statementToAdd, true));
}
}
exports.TypeScriptImports = TypeScriptImports;
/**
* Import * as asName from "importFrom";
*
* If the import is already present, just return the
* identifier.
*
* If the import is not present, create the import
* statement and call `addStatementFn`.
*
* Does *not* check for collisions.
*/
function ensureNamespaceImportPresent(currentFile, asName, importFrom, isTypeOnly, addStatementFn) {
const all = findNamespaceImports(currentFile), match = all.find(ni => ni.as === asName && ni.from === importFrom && ni.isTypeOnly === isTypeOnly);
if (match) {
return match.as;
}
const statementToAdd = createNamespaceImport(asName, importFrom, isTypeOnly);
addStatementFn(statementToAdd);
return asName;
}
/**
* import * as <asName> from "<importFrom>";
*/
function createNamespaceImport(asName, importFrom, isTypeOnly) {
return ts.createImportDeclaration(undefined, undefined, ts.createImportClause(undefined, ts.createNamespaceImport(ts.createIdentifier(asName)), isTypeOnly), ts.createStringLiteral(importFrom));
}
/**
* import * as <as> from "<from>";
*/
function findNamespaceImports(sourceFile) {
let r = [];
for (let s of sourceFile.statements) {
if (ts.isImportDeclaration(s) && s.importClause) {
let namedBindings = s.importClause.namedBindings;
if (namedBindings && ts.isNamespaceImport(namedBindings)) {
runtime_1.assert(ts.isStringLiteral(s.moduleSpecifier));
r.push({
as: namedBindings.name.escapedText.toString(),
from: s.moduleSpecifier.text,
isTypeOnly: s.importClause.isTypeOnly,
});
}
}
}
return r;
}
/**
* import {importName} from "importFrom";
* import type {importName} from "importFrom";
*
* If the import is already present, just return the
* identifier.
*
* If the import is not present, create the import
* statement and call `addStatementFn`.
*
* If the import name is taken by another named import
* or is in the list of blacklisted names, an
* alternative name is used:
*
* Import {importName as alternativeName} from "importFrom";
*
* Returns the imported name or the alternative name.
*/
function ensureNamedImportPresent(currentFile, importName, importFrom, isTypeOnly, blacklistedNames, addStatementFn, escapeCharacter = '$') {
var _a;
const all = findNamedImports(currentFile), taken = all.map(ni => { var _a; return (_a = ni.as) !== null && _a !== void 0 ? _a : ni.name; }).concat(blacklistedNames), match = all.find(ni => ni.name === importName && ni.from === importFrom && ni.isTypeOnly === isTypeOnly);
if (match) {
return (_a = match.as) !== null && _a !== void 0 ? _a : match.name;
}
let as;
if (taken.includes(importName)) {
let i = 0;
as = importName;
while (taken.includes(as)) {
as = importName + escapeCharacter;
if (i++ > 0) {
as += i;
}
}
}
const statementToAdd = createNamedImport(importName, importFrom, as, isTypeOnly);
addStatementFn(statementToAdd);
return as !== null && as !== void 0 ? as : importName;
}
exports.ensureNamedImportPresent = ensureNamedImportPresent;
/**
* import {<name>} from '<from>';
* import {<name> as <as>} from '<from>';
* import type {<name>} from '<from>';
* import type {<name> as <as>} from '<from>';
*/
function createNamedImport(name, from, as, isTypeOnly = false) {
if (as) {
return ts.createImportDeclaration(undefined, undefined, ts.createImportClause(undefined, ts.createNamedImports([ts.createImportSpecifier(ts.createIdentifier(name), ts.createIdentifier(as))]), isTypeOnly), ts.createStringLiteral(from));
}
return ts.createImportDeclaration(undefined, undefined, ts.createImportClause(undefined, ts.createNamedImports([
ts.createImportSpecifier(undefined, ts.createIdentifier(name))
]), isTypeOnly), ts.createStringLiteral(from));
}
exports.createNamedImport = createNamedImport;
/**
* import {<name>} from '<from>';
* import {<name> as <as>} from '<from>';
* import type {<name>} from '<from>';
* import type {<name> as <as>} from '<from>';
*/
function findNamedImports(sourceFile) {
let r = [];
for (let s of sourceFile.statements) {
if (ts.isImportDeclaration(s) && s.importClause) {
let namedBindings = s.importClause.namedBindings;
if (namedBindings && ts.isNamedImports(namedBindings)) {
for (let importSpecifier of namedBindings.elements) {
runtime_1.assert(ts.isStringLiteral(s.moduleSpecifier));
if (importSpecifier.propertyName) {
r.push({
name: importSpecifier.propertyName.escapedText.toString(),
as: importSpecifier.name.escapedText.toString(),
from: s.moduleSpecifier.text,
isTypeOnly: s.importClause.isTypeOnly
});
}
else {
r.push({
name: importSpecifier.name.escapedText.toString(),
as: undefined,
from: s.moduleSpecifier.text,
isTypeOnly: s.importClause.isTypeOnly
});
}
}
}
}
}
return r;
}
exports.findNamedImports = findNamedImports;
/**
* Create a relative path for an import statement like
* `import {Foo} from "./foo"`
*/
function createRelativeImportPath(currentPath, pathToImportFrom) {
// create relative path to the file to import
let fromPath = path.relative(path.dirname(currentPath), pathToImportFrom);
// on windows, this may add backslash directory separators.
// we replace them with forward slash.
if (path.sep !== "/") {
fromPath = fromPath.split(path.sep).join("/");
}
// drop file extension
fromPath = fromPath.replace(/\.[a-z]+$/, '');
// make sure to start with './' to signal relative path to module resolution
if (!fromPath.startsWith('../') && !fromPath.startsWith('./')) {
fromPath = './' + fromPath;
}
return fromPath;
}

View file

@ -0,0 +1,107 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.typescriptLiteralFromValue = void 0;
const runtime_1 = require("@protobuf-ts/runtime");
const ts = require("typescript");
const validPropertyKey = /^(?![0-9])[a-zA-Z0-9$_]+$/;
/**
* Creates nodes for simple JavaScript values.
*
* Simple JavaScript values include:
* - all primitives: number, bigint, string, boolean
* - undefined, null
* - plain objects containing only simple JavaScript values
* - arrays containing only simple JavaScript values
* - typed arrays
*/
function typescriptLiteralFromValue(value) {
switch (typeof value) {
case "undefined":
return ts.createIdentifier("undefined");
case "boolean":
return value ? ts.createTrue() : ts.createFalse();
case "string":
return ts.createStringLiteral(value);
case "bigint":
return ts.createNumericLiteral(`${value}n`);
case "number":
if (isNaN(value)) {
return ts.createPropertyAccess(ts.createIdentifier("Number"), ts.createIdentifier("Nan"));
}
else if (value === Number.POSITIVE_INFINITY) {
return ts.createPropertyAccess(ts.createIdentifier("Number"), ts.createIdentifier("POSITIVE_INFINITY"));
}
else if (value === Number.NEGATIVE_INFINITY) {
return ts.createPropertyAccess(ts.createIdentifier("Number"), ts.createIdentifier("NEGATIVE_INFINITY"));
}
return ts.createNumericLiteral(`${value}`);
case "object":
if (value === null) {
return ts.createNull();
}
if (isTypedArray(value)) {
if (value.length == 0) {
return ts.createNew(ts.createIdentifier(typedArrayName(value)), undefined, [ts.createNumericLiteral("0")]);
}
let values = [];
for (let i = 0; i < value.length; i++) {
values.push(ts.createNumericLiteral(value.toString()));
}
return ts.createNew(ts.createIdentifier(typedArrayName(value)), undefined, [ts.createArrayLiteral(values, false)]);
}
if (Array.isArray(value)) {
let elements = value.map(ele => typescriptLiteralFromValue(ele));
return ts.createArrayLiteral(elements, false);
}
if (value.constructor !== Object) {
throw new Error(`got a non-plain object ${value.constructor}`);
}
let props = [];
for (let key of Object.keys(value)) {
let propName = validPropertyKey.test(key) ? key : ts.createStringLiteral(key);
let propVal = typescriptLiteralFromValue(value[key]);
props.push(ts.createPropertyAssignment(propName, propVal));
}
return ts.createObjectLiteral(props, false);
}
runtime_1.assertNever(value);
}
exports.typescriptLiteralFromValue = typescriptLiteralFromValue;
function isTypedArray(arg) {
return arg instanceof Uint8Array
|| arg instanceof Int8Array
|| arg instanceof Uint8ClampedArray
|| arg instanceof Int16Array
|| arg instanceof Uint16Array
|| arg instanceof Int32Array
|| arg instanceof Uint32Array
|| arg instanceof Float32Array
|| arg instanceof Float64Array;
}
function typedArrayName(arg) {
if (arg instanceof Uint8Array) {
return 'Uint8Array';
}
if (arg instanceof Int8Array) {
return 'Int8Array';
}
if (arg instanceof Uint8ClampedArray) {
return 'Uint8ClampedArray';
}
if (arg instanceof Int16Array) {
return 'Int16Array';
}
if (arg instanceof Uint16Array) {
return 'Uint16Array';
}
if (arg instanceof Int32Array) {
return 'Int32Array';
}
if (arg instanceof Uint32Array) {
return 'Uint32Array';
}
if (arg instanceof Float32Array) {
return 'Float32Array';
}
return 'Float64Array';
}

View file

@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.typescriptMethodFromText = void 0;
const ts = require("typescript");
const typescript_comments_1 = require("./typescript-comments");
/**
* Provide a function statement as plain text, receive a
* method declaration.
*/
function typescriptMethodFromText(functionText) {
const sourceFile = ts.createSourceFile('temp.ts', functionText, ts.ScriptTarget.Latest);
if (sourceFile.statements.length !== 1) {
throw new Error('Expected exactly one statement, got ' + sourceFile.statements.length);
}
const node = sourceFile.statements[0];
if (!ts.isFunctionDeclaration(node)) {
throw new Error('Expected a function declaration');
}
if (node.name === undefined) {
throw new Error('function needs a name');
}
const method = ts.createMethod(node.decorators /*decorators*/, node.modifiers /*modifiers*/, node.asteriskToken /*asteriskToken*/, node.name, node.questionToken /*questionToken*/, node.typeParameters /*typeParameters*/, node.parameters, node.type /*return type*/, node.body);
ts.forEachLeadingCommentRange(functionText, node.getFullStart(), (pos, end) => {
let text = functionText.substring(pos, end);
text = text.trim();
if (text.startsWith('/*'))
text = text.substring(2);
if (text.endsWith('*/'))
text = text.substring(0, text.length - 2);
text = text.split('\n').map(l => l.replace(/^\s*\*/, '')).join('\n');
text = text.trim();
typescript_comments_1.addCommentBlockAsJsDoc(method, text);
});
return method;
}
exports.typescriptMethodFromText = typescriptMethodFromText;

View file

@ -0,0 +1,329 @@
import { DescriptorProto, EnumDescriptorProto, EnumValueDescriptorProto, FieldDescriptorProto, FieldDescriptorProto_Label, FieldDescriptorProto_Type, FileDescriptorProto, MethodDescriptorProto, OneofDescriptorProto, ServiceDescriptorProto } from "./google/protobuf/descriptor";
import { assert, lowerCamelCase } from "@protobuf-ts/runtime";
import { StringFormat } from "./string-format";
/**
* Is this a first-class type?
*/
export function isAnyTypeDescriptorProto(arg) {
return DescriptorProto.is(arg) || EnumDescriptorProto.is(arg) || ServiceDescriptorProto.is(arg);
}
export class DescriptorInfo {
constructor(tree, nameLookup) {
this.tree = tree;
this.nameLookup = nameLookup;
}
getAllExtensions() {
if (!this.allExtensions) {
this.allExtensions = [];
for (let file of this.tree.allFiles()) {
this.allExtensions.push(...file.extension);
for (let msg of file.messageType) {
this.allExtensions.push(...msg.extension);
}
}
}
return this.allExtensions;
}
isExtension(fieldDescriptor) {
if (fieldDescriptor.extendee === undefined) {
return false;
}
const parent = this.tree.parentOf(fieldDescriptor);
return parent.extension.includes(fieldDescriptor);
}
extensionsFor(descriptorOrTypeName) {
let extendeeTypeName;
if (typeof descriptorOrTypeName === "string") {
extendeeTypeName = this.nameLookup.makeTypeName(this.nameLookup.resolveTypeName(descriptorOrTypeName));
}
else {
extendeeTypeName = this.nameLookup.makeTypeName(descriptorOrTypeName);
}
return this.getAllExtensions().filter(ext => this.nameLookup.normalizeTypeName(ext.extendee) === extendeeTypeName);
}
getExtensionName(fieldDescriptor) {
assert(this.isExtension(fieldDescriptor), `${StringFormat.formatName(fieldDescriptor)} is not an extension. use isExtension() before getExtensionName()`);
assert(fieldDescriptor.name);
let extensionName;
let parent = this.tree.parentOf(fieldDescriptor);
if (FileDescriptorProto.is(parent)) {
extensionName = parent.package
? `${parent.package}.${fieldDescriptor.name}`
: `${fieldDescriptor.name}`;
}
else {
extensionName = `${this.nameLookup.makeTypeName(parent)}.${fieldDescriptor.name}`;
}
return extensionName;
}
getFieldCustomJsonName(fieldDescriptor) {
const name = lowerCamelCase(fieldDescriptor.name);
const jsonName = fieldDescriptor.jsonName;
if (jsonName !== undefined && jsonName !== '' && jsonName !== name) {
return jsonName;
}
return undefined;
}
isEnumField(fieldDescriptor) {
return fieldDescriptor.type === FieldDescriptorProto_Type.ENUM;
}
getEnumFieldEnum(fieldDescriptor) {
if (fieldDescriptor.type !== FieldDescriptorProto_Type.ENUM) {
throw new Error(`${StringFormat.formatName(fieldDescriptor)} is not a enum field. use isEnumField() before getEnumFieldEnum().`);
}
assert(fieldDescriptor.typeName !== undefined, `Missing enum type name for ${StringFormat.formatName(fieldDescriptor)}`);
let enumType = this.nameLookup.peekTypeName(fieldDescriptor.typeName);
assert(enumType !== undefined, `Missing enum type ${fieldDescriptor.typeName} for ${StringFormat.formatName(fieldDescriptor)}`);
assert(EnumDescriptorProto.is(enumType), `Invalid enum type for ${StringFormat.formatName(fieldDescriptor)}`);
return enumType;
}
isMessageField(fieldDescriptor) {
let msg = fieldDescriptor.type === FieldDescriptorProto_Type.MESSAGE;
if (!msg) {
return false;
}
if (fieldDescriptor.name === undefined) {
return false;
}
if (this.isMapField(fieldDescriptor)) {
return false;
}
return true;
}
isGroupField(fieldDescriptor) {
return fieldDescriptor.type === FieldDescriptorProto_Type.GROUP;
}
getMessageFieldMessage(fieldDescriptor) {
if (!this.isMessageField(fieldDescriptor)) {
throw new Error(`${StringFormat.formatName(fieldDescriptor)} is not a message field. use isMessageField() before getMessageFieldMessage().`);
}
assert(fieldDescriptor.typeName !== undefined, `Missing message type name for ${StringFormat.formatName(fieldDescriptor)}`);
let messageType = this.nameLookup.peekTypeName(fieldDescriptor.typeName);
assert(messageType !== undefined, `Missing message type ${fieldDescriptor.typeName} for ${StringFormat.formatName(fieldDescriptor)}`);
assert(DescriptorProto.is(messageType), `Invalid message type for ${StringFormat.formatName(fieldDescriptor)}`);
return messageType;
}
isScalarField(fieldDescriptor) {
switch (fieldDescriptor.type) {
case FieldDescriptorProto_Type.ENUM:
case FieldDescriptorProto_Type.MESSAGE:
case FieldDescriptorProto_Type.GROUP:
case FieldDescriptorProto_Type.UNSPECIFIED$:
return false;
}
return true;
}
getScalarFieldType(fieldDescriptor) {
if (!this.isScalarField(fieldDescriptor)) {
throw new Error(`${StringFormat.formatName(fieldDescriptor)} is not a scalar field. use isScalarField() before getScalarFieldType().`);
}
assert(fieldDescriptor.type !== undefined);
assert(fieldDescriptor.type !== FieldDescriptorProto_Type.ENUM);
assert(fieldDescriptor.type !== FieldDescriptorProto_Type.MESSAGE);
assert(fieldDescriptor.type !== FieldDescriptorProto_Type.GROUP);
assert(fieldDescriptor.type !== FieldDescriptorProto_Type.UNSPECIFIED$);
return fieldDescriptor.type;
}
isMapField(fieldDescriptor) {
return this.getMapEntryMessage(fieldDescriptor) !== undefined;
}
getMapKeyType(fieldDescriptor) {
let entry = this.getMapEntryMessage(fieldDescriptor);
if (!entry) {
throw new Error(`${StringFormat.formatName(fieldDescriptor)} is not a map field. use isMapField() before getMapKeyType().`);
}
let keyField = entry.field.find(fd => fd.number === 1);
assert(keyField !== undefined, `Missing map entry key field 1 for ${StringFormat.formatName(fieldDescriptor)}`);
assert(keyField.type !== undefined, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${StringFormat.formatName(fieldDescriptor)}`);
assert(keyField.type !== FieldDescriptorProto_Type.UNSPECIFIED$, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${StringFormat.formatName(fieldDescriptor)}`);
assert(keyField.type !== FieldDescriptorProto_Type.GROUP, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${StringFormat.formatName(fieldDescriptor)}`);
assert(keyField.type !== FieldDescriptorProto_Type.MESSAGE, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${StringFormat.formatName(fieldDescriptor)}`);
assert(keyField.type !== FieldDescriptorProto_Type.ENUM, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${StringFormat.formatName(fieldDescriptor)}`);
assert(keyField.type !== FieldDescriptorProto_Type.FLOAT, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${StringFormat.formatName(fieldDescriptor)}`);
assert(keyField.type !== FieldDescriptorProto_Type.DOUBLE, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${StringFormat.formatName(fieldDescriptor)}`);
assert(keyField.type !== FieldDescriptorProto_Type.BYTES, `Unexpected map key type ${keyField === null || keyField === void 0 ? void 0 : keyField.type} for ${StringFormat.formatName(fieldDescriptor)}`);
return keyField.type;
}
getMapValueType(fieldDescriptor) {
let entry = this.getMapEntryMessage(fieldDescriptor);
if (!entry) {
throw new Error(`${StringFormat.formatName(fieldDescriptor)} is not a map field. use isMapField() before getMapValueType().`);
}
let valueField = entry.field.find(fd => fd.number === 2);
assert(valueField !== undefined, `Missing map entry value field 2 for ${StringFormat.formatName(fieldDescriptor)}`);
if (this.isScalarField(valueField)) {
return this.getScalarFieldType(valueField);
}
if (this.isEnumField(valueField)) {
return this.getEnumFieldEnum(valueField);
}
return this.getMessageFieldMessage(valueField);
}
getMapEntryMessage(fieldDescriptor) {
var _a;
if (fieldDescriptor.type !== FieldDescriptorProto_Type.MESSAGE) {
return undefined;
}
if (fieldDescriptor.typeName === undefined || fieldDescriptor.typeName === "") {
return undefined;
}
let typeDescriptor = this.nameLookup.resolveTypeName(fieldDescriptor.typeName);
if (!DescriptorProto.is(typeDescriptor)) {
return undefined;
}
if (((_a = typeDescriptor.options) === null || _a === void 0 ? void 0 : _a.mapEntry) !== true) {
return undefined;
}
return typeDescriptor;
}
isExplicitlyDeclaredDeprecated(descriptor) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
if (FileDescriptorProto.is(descriptor)) {
return (_b = (_a = descriptor.options) === null || _a === void 0 ? void 0 : _a.deprecated) !== null && _b !== void 0 ? _b : false;
}
if (DescriptorProto.is(descriptor)) {
return (_d = (_c = descriptor.options) === null || _c === void 0 ? void 0 : _c.deprecated) !== null && _d !== void 0 ? _d : false;
}
if (FieldDescriptorProto.is(descriptor)) {
return (_f = (_e = descriptor.options) === null || _e === void 0 ? void 0 : _e.deprecated) !== null && _f !== void 0 ? _f : false;
}
if (EnumDescriptorProto.is(descriptor)) {
return (_h = (_g = descriptor.options) === null || _g === void 0 ? void 0 : _g.deprecated) !== null && _h !== void 0 ? _h : false;
}
if (EnumValueDescriptorProto.is(descriptor)) {
return (_k = (_j = descriptor.options) === null || _j === void 0 ? void 0 : _j.deprecated) !== null && _k !== void 0 ? _k : false;
}
if (ServiceDescriptorProto.is(descriptor)) {
return (_m = (_l = descriptor.options) === null || _l === void 0 ? void 0 : _l.deprecated) !== null && _m !== void 0 ? _m : false;
}
if (MethodDescriptorProto.is(descriptor)) {
return (_p = (_o = descriptor.options) === null || _o === void 0 ? void 0 : _o.deprecated) !== null && _p !== void 0 ? _p : false;
}
if (OneofDescriptorProto.is(descriptor)) {
return false;
}
return false;
}
isSyntheticElement(descriptor) {
var _a;
if (DescriptorProto.is(descriptor)) {
if ((_a = descriptor.options) === null || _a === void 0 ? void 0 : _a.mapEntry) {
return true;
}
if (descriptor.name && descriptor.name.startsWith("$synthetic.")) {
return true;
}
}
return false;
}
isUserDeclaredOneof(fieldDescriptor) {
if (fieldDescriptor.oneofIndex === undefined) {
return false;
}
return fieldDescriptor.proto3Optional !== true;
}
isUserDeclaredOptional(fieldDescriptor) {
if (this.isUserDeclaredOneof(fieldDescriptor)) {
return false;
}
if (fieldDescriptor.proto3Optional === true) {
return true;
}
if (fieldDescriptor.proto3Optional === false) {
return false;
}
const file = this.tree.fileOf(fieldDescriptor);
if (file.syntax === 'proto3') {
return false;
}
assert(file.syntax === undefined || file.syntax === 'proto2', `unsupported syntax "${file.syntax}"`);
return fieldDescriptor.label === FieldDescriptorProto_Label.OPTIONAL;
}
isUserDeclaredRepeated(fieldDescriptor) {
var _a;
if (fieldDescriptor.label !== FieldDescriptorProto_Label.REPEATED) {
return false;
}
const name = fieldDescriptor.typeName;
if (name === undefined || name === "") {
return true;
}
const typeDescriptor = this.nameLookup.resolveTypeName(name);
if (DescriptorProto.is(typeDescriptor)) {
return !((_a = typeDescriptor.options) === null || _a === void 0 ? void 0 : _a.mapEntry);
}
return true;
}
shouldBePackedRepeated(fieldDescriptor) {
var _a;
let file = this.tree.fileOf(fieldDescriptor);
let standard, declared = (_a = fieldDescriptor.options) === null || _a === void 0 ? void 0 : _a.packed;
if (file.syntax === 'proto3') {
standard = true;
}
else {
assert(file.syntax === undefined || file.syntax === 'proto2', `unsupported syntax "${file.syntax}"`);
standard = false;
}
if (fieldDescriptor.type === FieldDescriptorProto_Type.BYTES || fieldDescriptor.type === FieldDescriptorProto_Type.STRING) {
assert(!declared, `repeated bytes | string cannot be packed. protoc should have caught this. probably unsupported protoc version.`);
standard = false;
}
return declared !== null && declared !== void 0 ? declared : standard;
}
findEnumSharedPrefix(enumDescriptor, enumLocalName) {
if (enumLocalName === undefined) {
enumLocalName = `${enumDescriptor.name}`;
}
// create possible prefix from local enum name
// for example, "MyEnum" => "MY_ENUM_"
let enumPrefix = enumLocalName;
enumPrefix = enumPrefix.replace(/[A-Z]/g, letter => "_" + letter.toLowerCase());
enumPrefix = (enumPrefix[0] === "_") ? enumPrefix.substring(1) : enumPrefix;
enumPrefix = enumPrefix.toUpperCase();
enumPrefix += '_';
// do all members share the prefix?
let names = enumDescriptor.value.map(enumValue => `${enumValue.name}`);
let allNamesSharePrefix = names.every(name => name.startsWith(enumPrefix));
// are the names with stripped prefix still valid?
// (start with uppercase letter, at least 2 chars long)
let strippedNames = names.map(name => name.substring(enumPrefix.length));
let strippedNamesAreValid = strippedNames.every(name => name.length > 0 && /^[A-Z].+/.test(name));
return (allNamesSharePrefix && strippedNamesAreValid) ? enumPrefix : undefined;
}
isFileUsed(file, inFiles) {
let used = false;
this.tree.visitTypes(file, typeDescriptor => {
if (used)
return;
if (this.isTypeUsed(typeDescriptor, inFiles)) {
used = true;
}
});
return used;
}
isTypeUsed(type, inFiles) {
const needle = this.nameLookup.makeTypeName(type);
let used = false;
for (let fd of inFiles) {
this.tree.visitTypes(fd, typeDescriptor => {
if (used)
return;
if (DescriptorProto.is(typeDescriptor)) {
const usedInField = typeDescriptor.field.some(fd => fd.typeName !== undefined && this.nameLookup.normalizeTypeName(fd.typeName) === needle);
if (usedInField) {
used = true;
}
}
else if (ServiceDescriptorProto.is(typeDescriptor)) {
const usedInMethodInput = typeDescriptor.method.some(md => md.inputType !== undefined && this.nameLookup.normalizeTypeName(md.inputType) === needle);
const usedInMethodOutput = typeDescriptor.method.some(md => md.outputType !== undefined && this.nameLookup.normalizeTypeName(md.outputType) === needle);
if (usedInMethodInput || usedInMethodOutput) {
used = true;
}
}
});
}
return used;
}
}

View file

@ -0,0 +1,150 @@
import { FileDescriptorProto } from "./google/protobuf/descriptor";
import { CodeGeneratorRequest } from "./google/protobuf/compiler/plugin";
import { DescriptorInfo } from "./descriptor-info";
import { DescriptorTree } from "./descriptor-tree";
import { SourceCodeInfoLookup } from "./source-code-info";
import { StringFormat } from "./string-format";
import { TypeNameLookup } from "./type-names";
export class DescriptorRegistry {
constructor(tree, typeNames, sourceCode, stringFormat, descriptorInfo) {
this.tree = tree;
this.typeNames = typeNames;
this.sourceCode = sourceCode;
this.stringFormat = stringFormat;
this.descriptorInfo = descriptorInfo;
}
static createFrom(requestOrFile) {
const files = CodeGeneratorRequest.is(requestOrFile)
? requestOrFile.protoFile
: [requestOrFile], tree = DescriptorTree.from(...files), nameLookup = TypeNameLookup.from(tree), sourceCodeLookup = new SourceCodeInfoLookup(d => tree.parentOf(d)), descriptorInfo = new DescriptorInfo(tree, nameLookup), stringFormat = new StringFormat(nameLookup, tree, sourceCodeLookup, descriptorInfo);
return new DescriptorRegistry(tree, nameLookup, sourceCodeLookup, stringFormat, descriptorInfo);
}
// ITypeNameLookup
normalizeTypeName(typeName) {
return this.typeNames.normalizeTypeName(typeName);
}
resolveTypeName(typeName) {
return this.typeNames.resolveTypeName(typeName);
}
peekTypeName(typeName) {
return this.typeNames.peekTypeName(typeName);
}
makeTypeName(descriptor) {
return this.typeNames.makeTypeName(descriptor);
}
// IDescriptorTree
ancestorsOf(descriptor) {
return this.tree.ancestorsOf(descriptor);
}
fileOf(descriptor) {
return this.tree.fileOf(descriptor);
}
allFiles() {
return this.tree.allFiles();
}
parentOf(descriptorOrOptions) {
return this.tree.parentOf(descriptorOrOptions);
}
visit(a, b) {
this.tree.visit(a, b);
}
visitTypes(a, b) {
this.tree.visitTypes(a, b);
}
// ISourceCodeInfoLookup
sourceCodeCursor(descriptor) {
return this.sourceCode.sourceCodeCursor(descriptor);
}
sourceCodeComments(descriptorOrFile, fileDescriptorFieldNumber) {
if (FileDescriptorProto.is(descriptorOrFile) && fileDescriptorFieldNumber !== undefined) {
return this.sourceCode.sourceCodeComments(descriptorOrFile, fileDescriptorFieldNumber);
}
return this.sourceCode.sourceCodeComments(descriptorOrFile);
}
// IStringFormat
formatFieldDeclaration(descriptor) {
return this.stringFormat.formatFieldDeclaration(descriptor);
}
formatQualifiedName(descriptor, includeFileInfo = false) {
return this.stringFormat.formatQualifiedName(descriptor, includeFileInfo);
}
formatName(descriptor) {
return this.stringFormat.formatName(descriptor);
}
formatEnumValueDeclaration(descriptor) {
return this.stringFormat.formatEnumValueDeclaration(descriptor);
}
formatRpcDeclaration(descriptor) {
return this.stringFormat.formatRpcDeclaration(descriptor);
}
// IDescriptorInfo
isExtension(descriptor) {
return this.descriptorInfo.isExtension(descriptor);
}
extensionsFor(descriptorOrTypeName) {
return this.descriptorInfo.extensionsFor(descriptorOrTypeName);
}
getExtensionName(descriptor) {
return this.descriptorInfo.getExtensionName(descriptor);
}
getFieldCustomJsonName(descriptor) {
return this.descriptorInfo.getFieldCustomJsonName(descriptor);
}
isEnumField(fieldDescriptor) {
return this.descriptorInfo.isEnumField(fieldDescriptor);
}
getEnumFieldEnum(fieldDescriptor) {
return this.descriptorInfo.getEnumFieldEnum(fieldDescriptor);
}
isMessageField(fieldDescriptor) {
return this.descriptorInfo.isMessageField(fieldDescriptor);
}
isGroupField(fieldDescriptor) {
return this.descriptorInfo.isGroupField(fieldDescriptor);
}
getMessageFieldMessage(fieldDescriptor) {
return this.descriptorInfo.getMessageFieldMessage(fieldDescriptor);
}
isScalarField(fieldDescriptor) {
return this.descriptorInfo.isScalarField(fieldDescriptor);
}
getScalarFieldType(fieldDescriptor) {
return this.descriptorInfo.getScalarFieldType(fieldDescriptor);
}
isMapField(fieldDescriptor) {
return this.descriptorInfo.isMapField(fieldDescriptor);
}
getMapKeyType(fieldDescriptor) {
return this.descriptorInfo.getMapKeyType(fieldDescriptor);
}
getMapValueType(fieldDescriptor) {
return this.descriptorInfo.getMapValueType(fieldDescriptor);
}
isExplicitlyDeclaredDeprecated(descriptor) {
return this.descriptorInfo.isExplicitlyDeclaredDeprecated(descriptor);
}
isSyntheticElement(descriptor) {
return this.descriptorInfo.isSyntheticElement(descriptor);
}
findEnumSharedPrefix(descriptor, enumLocalName) {
return this.descriptorInfo.findEnumSharedPrefix(descriptor, enumLocalName);
}
isUserDeclaredOneof(descriptor) {
return this.descriptorInfo.isUserDeclaredOneof(descriptor);
}
isUserDeclaredOptional(descriptor) {
return this.descriptorInfo.isUserDeclaredOptional(descriptor);
}
isUserDeclaredRepeated(descriptor) {
return this.descriptorInfo.isUserDeclaredRepeated(descriptor);
}
shouldBePackedRepeated(descriptor) {
return this.descriptorInfo.shouldBePackedRepeated(descriptor);
}
isFileUsed(file, inFiles) {
return this.descriptorInfo.isFileUsed(file, inFiles);
}
isTypeUsed(type, inFiles) {
return this.descriptorInfo.isTypeUsed(type, inFiles);
}
}

View file

@ -0,0 +1,175 @@
import { DescriptorProto, EnumDescriptorProto, EnumValueDescriptorProto, FieldDescriptorProto, FileDescriptorProto, MethodDescriptorProto, OneofDescriptorProto, ServiceDescriptorProto } from "./google/protobuf/descriptor";
import { isAnyTypeDescriptorProto } from "./descriptor-info";
import { assert, assertNever } from "@protobuf-ts/runtime";
export class DescriptorTree {
constructor(descriptors, options) {
const descriptorMap = new Map();
const optionMap = new Map();
const files = [];
for (const [descriptor, info] of descriptors) {
// infos
assert(!descriptorMap.has(descriptor));
descriptorMap.set(descriptor, info);
// files
if (FileDescriptorProto.is(descriptor)) {
files.push(descriptor);
}
}
for (const [option, descriptor] of options) {
optionMap.set(option, descriptor);
}
this._files = files;
this._descriptors = descriptorMap;
this._options = optionMap;
}
/**
* Create the tree from a list of root files.
*/
static from(...files) {
const descriptors = [];
const options = [];
for (const file of files) {
visitDescriptorTree(file, (descriptor, ancestors) => {
descriptors.push([descriptor, { ancestors, file, parent: ancestors[ancestors.length - 1] }]);
if (descriptor.options) {
options.push([descriptor.options, descriptor]);
}
});
}
return new DescriptorTree(descriptors, options);
}
ancestorsOf(descriptor) {
const v = this._descriptors.get(descriptor);
assert(v !== undefined);
return v.ancestors.concat();
}
fileOf(descriptor) {
const v = this._descriptors.get(descriptor);
assert(v !== undefined);
return v.file;
}
allFiles() {
return this._files;
}
parentOf(descriptorOrOptions) {
const optionParent = this._options.get(descriptorOrOptions);
if (optionParent) {
return optionParent;
}
const descriptorEntry = this._descriptors.get(descriptorOrOptions);
if (descriptorEntry) {
return descriptorEntry.parent;
}
assert(FileDescriptorProto.is(descriptorOrOptions));
return undefined;
}
visit(a, b) {
if (b === undefined) {
for (const file of this._files) {
visitDescriptorTree(file, a);
}
}
else {
const startingFrom = a;
visitDescriptorTree(startingFrom, descriptor => {
if (descriptor === a) {
return; // visitDescriptorTree invokes on starting element. ignore.
}
b(descriptor);
});
}
}
visitTypes(a, b) {
if (b === undefined) {
for (const file of this._files) {
visitDescriptorTree(file, descriptor => {
if (isAnyTypeDescriptorProto(descriptor)) {
a(descriptor);
}
});
}
}
else {
visitDescriptorTree(a, descriptor => {
if (descriptor === a) {
return; // visitDescriptorTree invokes on starting element. ignore.
}
if (isAnyTypeDescriptorProto(descriptor)) {
b(descriptor);
}
});
}
}
}
/**
* Visit all logical children of the given descriptor proto.
*
* The "visitor" function is called for each element,
* including the input. It receives two arguments:
* 1) the current descriptor proto
* 2) the ancestors of the current descriptor proto (an array of descriptors)
*/
export function visitDescriptorTree(input, visitor) {
visitWithCarry(input, [], visitor);
}
function visitWithCarry(input, carry, visitor) {
visitor(input, carry);
carry = carry.concat(input);
// noinspection SuspiciousTypeOfGuard
if (EnumDescriptorProto.is(input)) {
for (const val of input.value) {
visitWithCarry(val, carry, visitor);
}
}
else if (DescriptorProto.is(input)) {
for (const oneof of input.oneofDecl) {
visitWithCarry(oneof, carry, visitor);
}
for (const field of input.field) {
visitWithCarry(field, carry, visitor);
}
for (const message of input.nestedType) {
visitWithCarry(message, carry, visitor);
}
for (const enu of input.enumType) {
visitWithCarry(enu, carry, visitor);
}
for (const extensionField of input.extension) {
visitWithCarry(extensionField, carry, visitor);
}
}
else if (FileDescriptorProto.is(input)) {
for (const message of input.messageType) {
visitWithCarry(message, carry, visitor);
}
for (const enu of input.enumType) {
visitWithCarry(enu, carry, visitor);
}
for (const service of input.service) {
visitWithCarry(service, carry, visitor);
}
for (const extensionField of input.extension) {
visitWithCarry(extensionField, carry, visitor);
}
}
else if (ServiceDescriptorProto.is(input)) {
for (const method of input.method) {
visitWithCarry(method, carry, visitor);
}
}
else if (EnumValueDescriptorProto.is(input)) {
//
}
else if (FieldDescriptorProto.is(input)) {
//
}
else if (MethodDescriptorProto.is(input)) {
//
}
else if (OneofDescriptorProto.is(input)) {
//
}
else {
assertNever(input);
}
}

View file

@ -0,0 +1,125 @@
// @generated by protobuf-ts 1.0.0-alpha.35 with parameters force_optimize_code_size,long_type_string
// @generated from protobuf file "google/protobuf/compiler/plugin.proto" (package "google.protobuf.compiler", syntax proto2)
// tslint:disable
//
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
// Author: kenton@google.com (Kenton Varda)
//
// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to
// change.
//
// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is
// just a program that reads a CodeGeneratorRequest from stdin and writes a
// CodeGeneratorResponse to stdout.
//
// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead
// of dealing with the raw protocol defined here.
//
// A plugin executable needs only to be placed somewhere in the path. The
// plugin should be named "protoc-gen-$NAME", and will then be used when the
// flag "--${NAME}_out" is passed to protoc.
//
import { RepeatType } from "@protobuf-ts/runtime";
import { ScalarType } from "@protobuf-ts/runtime";
import { MessageType } from "@protobuf-ts/runtime";
import { FileDescriptorProto } from "../descriptor";
/**
* Sync with code_generator.h.
*
* @generated from protobuf enum google.protobuf.compiler.CodeGeneratorResponse.Feature
*/
export var CodeGeneratorResponse_Feature;
(function (CodeGeneratorResponse_Feature) {
/**
* @generated from protobuf enum value: FEATURE_NONE = 0;
*/
CodeGeneratorResponse_Feature[CodeGeneratorResponse_Feature["NONE"] = 0] = "NONE";
/**
* @generated from protobuf enum value: FEATURE_PROTO3_OPTIONAL = 1;
*/
CodeGeneratorResponse_Feature[CodeGeneratorResponse_Feature["PROTO3_OPTIONAL"] = 1] = "PROTO3_OPTIONAL";
})(CodeGeneratorResponse_Feature || (CodeGeneratorResponse_Feature = {}));
/**
* Type for protobuf message google.protobuf.compiler.Version
*/
class Version$Type extends MessageType {
constructor() {
super("google.protobuf.compiler.Version", [
{ no: 1, name: "major", kind: "scalar", opt: true, T: ScalarType.INT32 },
{ no: 2, name: "minor", kind: "scalar", opt: true, T: ScalarType.INT32 },
{ no: 3, name: "patch", kind: "scalar", opt: true, T: ScalarType.INT32 },
{ no: 4, name: "suffix", kind: "scalar", opt: true, T: ScalarType.STRING }
]);
}
}
export const Version = new Version$Type();
/**
* Type for protobuf message google.protobuf.compiler.CodeGeneratorRequest
*/
class CodeGeneratorRequest$Type extends MessageType {
constructor() {
super("google.protobuf.compiler.CodeGeneratorRequest", [
{ no: 1, name: "file_to_generate", kind: "scalar", repeat: RepeatType.UNPACKED, T: ScalarType.STRING },
{ no: 2, name: "parameter", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 15, name: "proto_file", kind: "message", repeat: RepeatType.UNPACKED, T: () => FileDescriptorProto },
{ no: 3, name: "compiler_version", kind: "message", T: () => Version }
]);
}
}
export const CodeGeneratorRequest = new CodeGeneratorRequest$Type();
/**
* Type for protobuf message google.protobuf.compiler.CodeGeneratorResponse
*/
class CodeGeneratorResponse$Type extends MessageType {
constructor() {
super("google.protobuf.compiler.CodeGeneratorResponse", [
{ no: 1, name: "error", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 2, name: "supported_features", kind: "scalar", opt: true, T: ScalarType.UINT64 },
{ no: 15, name: "file", kind: "message", repeat: RepeatType.UNPACKED, T: () => CodeGeneratorResponse_File }
]);
}
}
export const CodeGeneratorResponse = new CodeGeneratorResponse$Type();
/**
* Type for protobuf message google.protobuf.compiler.CodeGeneratorResponse.File
*/
class CodeGeneratorResponse_File$Type extends MessageType {
constructor() {
super("google.protobuf.compiler.CodeGeneratorResponse.File", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 2, name: "insertion_point", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 15, name: "content", kind: "scalar", opt: true, T: ScalarType.STRING }
]);
}
}
export const CodeGeneratorResponse_File = new CodeGeneratorResponse_File$Type();

View file

@ -0,0 +1,671 @@
// @generated by protobuf-ts 1.0.0-alpha.35 with parameters force_optimize_code_size,long_type_string
// @generated from protobuf file "google/protobuf/descriptor.proto" (package "google.protobuf", syntax proto2)
// tslint:disable
//
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// The messages in this file describe the definitions found in .proto files.
// A valid .proto file can be translated directly to a FileDescriptorProto
// without any other information (e.g. without reading its imports).
//
import { ScalarType } from "@protobuf-ts/runtime";
import { RepeatType } from "@protobuf-ts/runtime";
import { MessageType } from "@protobuf-ts/runtime";
/**
* @generated from protobuf enum google.protobuf.FieldDescriptorProto.Type
*/
export var FieldDescriptorProto_Type;
(function (FieldDescriptorProto_Type) {
/**
* @generated synthetic value - protobuf-ts requires all enums to have a 0 value
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["UNSPECIFIED$"] = 0] = "UNSPECIFIED$";
/**
* 0 is reserved for errors.
* Order is weird for historical reasons.
*
* @generated from protobuf enum value: TYPE_DOUBLE = 1;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["DOUBLE"] = 1] = "DOUBLE";
/**
* @generated from protobuf enum value: TYPE_FLOAT = 2;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["FLOAT"] = 2] = "FLOAT";
/**
* Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
* negative values are likely.
*
* @generated from protobuf enum value: TYPE_INT64 = 3;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["INT64"] = 3] = "INT64";
/**
* @generated from protobuf enum value: TYPE_UINT64 = 4;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["UINT64"] = 4] = "UINT64";
/**
* Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
* negative values are likely.
*
* @generated from protobuf enum value: TYPE_INT32 = 5;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["INT32"] = 5] = "INT32";
/**
* @generated from protobuf enum value: TYPE_FIXED64 = 6;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["FIXED64"] = 6] = "FIXED64";
/**
* @generated from protobuf enum value: TYPE_FIXED32 = 7;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["FIXED32"] = 7] = "FIXED32";
/**
* @generated from protobuf enum value: TYPE_BOOL = 8;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["BOOL"] = 8] = "BOOL";
/**
* @generated from protobuf enum value: TYPE_STRING = 9;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["STRING"] = 9] = "STRING";
/**
* Tag-delimited aggregate.
* Group type is deprecated and not supported in proto3. However, Proto3
* implementations should still be able to parse the group wire format and
* treat group fields as unknown fields.
*
* @generated from protobuf enum value: TYPE_GROUP = 10;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["GROUP"] = 10] = "GROUP";
/**
* Length-delimited aggregate.
*
* @generated from protobuf enum value: TYPE_MESSAGE = 11;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["MESSAGE"] = 11] = "MESSAGE";
/**
* New in version 2.
*
* @generated from protobuf enum value: TYPE_BYTES = 12;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["BYTES"] = 12] = "BYTES";
/**
* @generated from protobuf enum value: TYPE_UINT32 = 13;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["UINT32"] = 13] = "UINT32";
/**
* @generated from protobuf enum value: TYPE_ENUM = 14;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["ENUM"] = 14] = "ENUM";
/**
* @generated from protobuf enum value: TYPE_SFIXED32 = 15;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["SFIXED32"] = 15] = "SFIXED32";
/**
* @generated from protobuf enum value: TYPE_SFIXED64 = 16;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["SFIXED64"] = 16] = "SFIXED64";
/**
* Uses ZigZag encoding.
*
* @generated from protobuf enum value: TYPE_SINT32 = 17;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["SINT32"] = 17] = "SINT32";
/**
* Uses ZigZag encoding.
*
* @generated from protobuf enum value: TYPE_SINT64 = 18;
*/
FieldDescriptorProto_Type[FieldDescriptorProto_Type["SINT64"] = 18] = "SINT64";
})(FieldDescriptorProto_Type || (FieldDescriptorProto_Type = {}));
/**
* @generated from protobuf enum google.protobuf.FieldDescriptorProto.Label
*/
export var FieldDescriptorProto_Label;
(function (FieldDescriptorProto_Label) {
/**
* @generated synthetic value - protobuf-ts requires all enums to have a 0 value
*/
FieldDescriptorProto_Label[FieldDescriptorProto_Label["UNSPECIFIED$"] = 0] = "UNSPECIFIED$";
/**
* 0 is reserved for errors
*
* @generated from protobuf enum value: LABEL_OPTIONAL = 1;
*/
FieldDescriptorProto_Label[FieldDescriptorProto_Label["OPTIONAL"] = 1] = "OPTIONAL";
/**
* @generated from protobuf enum value: LABEL_REQUIRED = 2;
*/
FieldDescriptorProto_Label[FieldDescriptorProto_Label["REQUIRED"] = 2] = "REQUIRED";
/**
* @generated from protobuf enum value: LABEL_REPEATED = 3;
*/
FieldDescriptorProto_Label[FieldDescriptorProto_Label["REPEATED"] = 3] = "REPEATED";
})(FieldDescriptorProto_Label || (FieldDescriptorProto_Label = {}));
/**
* Generated classes can be optimized for speed or code size.
*
* @generated from protobuf enum google.protobuf.FileOptions.OptimizeMode
*/
export var FileOptions_OptimizeMode;
(function (FileOptions_OptimizeMode) {
/**
* @generated synthetic value - protobuf-ts requires all enums to have a 0 value
*/
FileOptions_OptimizeMode[FileOptions_OptimizeMode["UNSPECIFIED$"] = 0] = "UNSPECIFIED$";
/**
* Generate complete code for parsing, serialization,
*
* @generated from protobuf enum value: SPEED = 1;
*/
FileOptions_OptimizeMode[FileOptions_OptimizeMode["SPEED"] = 1] = "SPEED";
/**
* etc.
*
* Use ReflectionOps to implement these methods.
*
* @generated from protobuf enum value: CODE_SIZE = 2;
*/
FileOptions_OptimizeMode[FileOptions_OptimizeMode["CODE_SIZE"] = 2] = "CODE_SIZE";
/**
* Generate code using MessageLite and the lite runtime.
*
* @generated from protobuf enum value: LITE_RUNTIME = 3;
*/
FileOptions_OptimizeMode[FileOptions_OptimizeMode["LITE_RUNTIME"] = 3] = "LITE_RUNTIME";
})(FileOptions_OptimizeMode || (FileOptions_OptimizeMode = {}));
/**
* @generated from protobuf enum google.protobuf.FieldOptions.CType
*/
export var FieldOptions_CType;
(function (FieldOptions_CType) {
/**
* Default mode.
*
* @generated from protobuf enum value: STRING = 0;
*/
FieldOptions_CType[FieldOptions_CType["STRING"] = 0] = "STRING";
/**
* @generated from protobuf enum value: CORD = 1;
*/
FieldOptions_CType[FieldOptions_CType["CORD"] = 1] = "CORD";
/**
* @generated from protobuf enum value: STRING_PIECE = 2;
*/
FieldOptions_CType[FieldOptions_CType["STRING_PIECE"] = 2] = "STRING_PIECE";
})(FieldOptions_CType || (FieldOptions_CType = {}));
/**
* @generated from protobuf enum google.protobuf.FieldOptions.JSType
*/
export var FieldOptions_JSType;
(function (FieldOptions_JSType) {
/**
* Use the default type.
*
* @generated from protobuf enum value: JS_NORMAL = 0;
*/
FieldOptions_JSType[FieldOptions_JSType["JS_NORMAL"] = 0] = "JS_NORMAL";
/**
* Use JavaScript strings.
*
* @generated from protobuf enum value: JS_STRING = 1;
*/
FieldOptions_JSType[FieldOptions_JSType["JS_STRING"] = 1] = "JS_STRING";
/**
* Use JavaScript numbers.
*
* @generated from protobuf enum value: JS_NUMBER = 2;
*/
FieldOptions_JSType[FieldOptions_JSType["JS_NUMBER"] = 2] = "JS_NUMBER";
})(FieldOptions_JSType || (FieldOptions_JSType = {}));
/**
* Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
* or neither? HTTP based RPC implementation may choose GET verb for safe
* methods, and PUT verb for idempotent methods instead of the default POST.
*
* @generated from protobuf enum google.protobuf.MethodOptions.IdempotencyLevel
*/
export var MethodOptions_IdempotencyLevel;
(function (MethodOptions_IdempotencyLevel) {
/**
* @generated from protobuf enum value: IDEMPOTENCY_UNKNOWN = 0;
*/
MethodOptions_IdempotencyLevel[MethodOptions_IdempotencyLevel["IDEMPOTENCY_UNKNOWN"] = 0] = "IDEMPOTENCY_UNKNOWN";
/**
* implies idempotent
*
* @generated from protobuf enum value: NO_SIDE_EFFECTS = 1;
*/
MethodOptions_IdempotencyLevel[MethodOptions_IdempotencyLevel["NO_SIDE_EFFECTS"] = 1] = "NO_SIDE_EFFECTS";
/**
* idempotent, but may have side effects
*
* @generated from protobuf enum value: IDEMPOTENT = 2;
*/
MethodOptions_IdempotencyLevel[MethodOptions_IdempotencyLevel["IDEMPOTENT"] = 2] = "IDEMPOTENT";
})(MethodOptions_IdempotencyLevel || (MethodOptions_IdempotencyLevel = {}));
/**
* Type for protobuf message google.protobuf.FileDescriptorSet
*/
class FileDescriptorSet$Type extends MessageType {
constructor() {
super("google.protobuf.FileDescriptorSet", [
{ no: 1, name: "file", kind: "message", repeat: RepeatType.UNPACKED, T: () => FileDescriptorProto }
]);
}
}
export const FileDescriptorSet = new FileDescriptorSet$Type();
/**
* Type for protobuf message google.protobuf.FileDescriptorProto
*/
class FileDescriptorProto$Type extends MessageType {
constructor() {
super("google.protobuf.FileDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 2, name: "package", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 3, name: "dependency", kind: "scalar", repeat: RepeatType.UNPACKED, T: ScalarType.STRING },
{ no: 10, name: "public_dependency", kind: "scalar", repeat: RepeatType.UNPACKED, T: ScalarType.INT32 },
{ no: 11, name: "weak_dependency", kind: "scalar", repeat: RepeatType.UNPACKED, T: ScalarType.INT32 },
{ no: 4, name: "message_type", kind: "message", repeat: RepeatType.UNPACKED, T: () => DescriptorProto },
{ no: 5, name: "enum_type", kind: "message", repeat: RepeatType.UNPACKED, T: () => EnumDescriptorProto },
{ no: 6, name: "service", kind: "message", repeat: RepeatType.UNPACKED, T: () => ServiceDescriptorProto },
{ no: 7, name: "extension", kind: "message", repeat: RepeatType.UNPACKED, T: () => FieldDescriptorProto },
{ no: 8, name: "options", kind: "message", T: () => FileOptions },
{ no: 9, name: "source_code_info", kind: "message", T: () => SourceCodeInfo },
{ no: 12, name: "syntax", kind: "scalar", opt: true, T: ScalarType.STRING }
]);
}
}
export const FileDescriptorProto = new FileDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.DescriptorProto
*/
class DescriptorProto$Type extends MessageType {
constructor() {
super("google.protobuf.DescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 2, name: "field", kind: "message", repeat: RepeatType.UNPACKED, T: () => FieldDescriptorProto },
{ no: 6, name: "extension", kind: "message", repeat: RepeatType.UNPACKED, T: () => FieldDescriptorProto },
{ no: 3, name: "nested_type", kind: "message", repeat: RepeatType.UNPACKED, T: () => DescriptorProto },
{ no: 4, name: "enum_type", kind: "message", repeat: RepeatType.UNPACKED, T: () => EnumDescriptorProto },
{ no: 5, name: "extension_range", kind: "message", repeat: RepeatType.UNPACKED, T: () => DescriptorProto_ExtensionRange },
{ no: 8, name: "oneof_decl", kind: "message", repeat: RepeatType.UNPACKED, T: () => OneofDescriptorProto },
{ no: 7, name: "options", kind: "message", T: () => MessageOptions },
{ no: 9, name: "reserved_range", kind: "message", repeat: RepeatType.UNPACKED, T: () => DescriptorProto_ReservedRange },
{ no: 10, name: "reserved_name", kind: "scalar", repeat: RepeatType.UNPACKED, T: ScalarType.STRING }
]);
}
}
export const DescriptorProto = new DescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.DescriptorProto.ExtensionRange
*/
class DescriptorProto_ExtensionRange$Type extends MessageType {
constructor() {
super("google.protobuf.DescriptorProto.ExtensionRange", [
{ no: 1, name: "start", kind: "scalar", opt: true, T: ScalarType.INT32 },
{ no: 2, name: "end", kind: "scalar", opt: true, T: ScalarType.INT32 },
{ no: 3, name: "options", kind: "message", T: () => ExtensionRangeOptions }
]);
}
}
export const DescriptorProto_ExtensionRange = new DescriptorProto_ExtensionRange$Type();
/**
* Type for protobuf message google.protobuf.DescriptorProto.ReservedRange
*/
class DescriptorProto_ReservedRange$Type extends MessageType {
constructor() {
super("google.protobuf.DescriptorProto.ReservedRange", [
{ no: 1, name: "start", kind: "scalar", opt: true, T: ScalarType.INT32 },
{ no: 2, name: "end", kind: "scalar", opt: true, T: ScalarType.INT32 }
]);
}
}
export const DescriptorProto_ReservedRange = new DescriptorProto_ReservedRange$Type();
/**
* Type for protobuf message google.protobuf.ExtensionRangeOptions
*/
class ExtensionRangeOptions$Type extends MessageType {
constructor() {
super("google.protobuf.ExtensionRangeOptions", [
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: RepeatType.UNPACKED, T: () => UninterpretedOption }
]);
}
}
export const ExtensionRangeOptions = new ExtensionRangeOptions$Type();
/**
* Type for protobuf message google.protobuf.FieldDescriptorProto
*/
class FieldDescriptorProto$Type extends MessageType {
constructor() {
super("google.protobuf.FieldDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 3, name: "number", kind: "scalar", opt: true, T: ScalarType.INT32 },
{ no: 4, name: "label", kind: "enum", opt: true, T: () => ["google.protobuf.FieldDescriptorProto.Label", FieldDescriptorProto_Label, "LABEL_"] },
{ no: 5, name: "type", kind: "enum", opt: true, T: () => ["google.protobuf.FieldDescriptorProto.Type", FieldDescriptorProto_Type, "TYPE_"] },
{ no: 6, name: "type_name", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 2, name: "extendee", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 7, name: "default_value", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 9, name: "oneof_index", kind: "scalar", opt: true, T: ScalarType.INT32 },
{ no: 10, name: "json_name", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 8, name: "options", kind: "message", T: () => FieldOptions },
{ no: 17, name: "proto3_optional", kind: "scalar", opt: true, T: ScalarType.BOOL }
]);
}
}
export const FieldDescriptorProto = new FieldDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.OneofDescriptorProto
*/
class OneofDescriptorProto$Type extends MessageType {
constructor() {
super("google.protobuf.OneofDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 2, name: "options", kind: "message", T: () => OneofOptions }
]);
}
}
export const OneofDescriptorProto = new OneofDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.EnumDescriptorProto
*/
class EnumDescriptorProto$Type extends MessageType {
constructor() {
super("google.protobuf.EnumDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 2, name: "value", kind: "message", repeat: RepeatType.UNPACKED, T: () => EnumValueDescriptorProto },
{ no: 3, name: "options", kind: "message", T: () => EnumOptions },
{ no: 4, name: "reserved_range", kind: "message", repeat: RepeatType.UNPACKED, T: () => EnumDescriptorProto_EnumReservedRange },
{ no: 5, name: "reserved_name", kind: "scalar", repeat: RepeatType.UNPACKED, T: ScalarType.STRING }
]);
}
}
export const EnumDescriptorProto = new EnumDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.EnumDescriptorProto.EnumReservedRange
*/
class EnumDescriptorProto_EnumReservedRange$Type extends MessageType {
constructor() {
super("google.protobuf.EnumDescriptorProto.EnumReservedRange", [
{ no: 1, name: "start", kind: "scalar", opt: true, T: ScalarType.INT32 },
{ no: 2, name: "end", kind: "scalar", opt: true, T: ScalarType.INT32 }
]);
}
}
export const EnumDescriptorProto_EnumReservedRange = new EnumDescriptorProto_EnumReservedRange$Type();
/**
* Type for protobuf message google.protobuf.EnumValueDescriptorProto
*/
class EnumValueDescriptorProto$Type extends MessageType {
constructor() {
super("google.protobuf.EnumValueDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 2, name: "number", kind: "scalar", opt: true, T: ScalarType.INT32 },
{ no: 3, name: "options", kind: "message", T: () => EnumValueOptions }
]);
}
}
export const EnumValueDescriptorProto = new EnumValueDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.ServiceDescriptorProto
*/
class ServiceDescriptorProto$Type extends MessageType {
constructor() {
super("google.protobuf.ServiceDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 2, name: "method", kind: "message", repeat: RepeatType.UNPACKED, T: () => MethodDescriptorProto },
{ no: 3, name: "options", kind: "message", T: () => ServiceOptions }
]);
}
}
export const ServiceDescriptorProto = new ServiceDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.MethodDescriptorProto
*/
class MethodDescriptorProto$Type extends MessageType {
constructor() {
super("google.protobuf.MethodDescriptorProto", [
{ no: 1, name: "name", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 2, name: "input_type", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 3, name: "output_type", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 4, name: "options", kind: "message", T: () => MethodOptions },
{ no: 5, name: "client_streaming", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 6, name: "server_streaming", kind: "scalar", opt: true, T: ScalarType.BOOL }
]);
}
}
export const MethodDescriptorProto = new MethodDescriptorProto$Type();
/**
* Type for protobuf message google.protobuf.FileOptions
*/
class FileOptions$Type extends MessageType {
constructor() {
super("google.protobuf.FileOptions", [
{ no: 1, name: "java_package", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 8, name: "java_outer_classname", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 10, name: "java_multiple_files", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 20, name: "java_generate_equals_and_hash", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 27, name: "java_string_check_utf8", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 9, name: "optimize_for", kind: "enum", opt: true, T: () => ["google.protobuf.FileOptions.OptimizeMode", FileOptions_OptimizeMode] },
{ no: 11, name: "go_package", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 16, name: "cc_generic_services", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 17, name: "java_generic_services", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 18, name: "py_generic_services", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 42, name: "php_generic_services", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 23, name: "deprecated", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 31, name: "cc_enable_arenas", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 36, name: "objc_class_prefix", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 37, name: "csharp_namespace", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 39, name: "swift_prefix", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 40, name: "php_class_prefix", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 41, name: "php_namespace", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 44, name: "php_metadata_namespace", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 45, name: "ruby_package", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: RepeatType.UNPACKED, T: () => UninterpretedOption }
]);
}
}
export const FileOptions = new FileOptions$Type();
/**
* Type for protobuf message google.protobuf.MessageOptions
*/
class MessageOptions$Type extends MessageType {
constructor() {
super("google.protobuf.MessageOptions", [
{ no: 1, name: "message_set_wire_format", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 2, name: "no_standard_descriptor_accessor", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 3, name: "deprecated", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 7, name: "map_entry", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: RepeatType.UNPACKED, T: () => UninterpretedOption }
]);
}
}
export const MessageOptions = new MessageOptions$Type();
/**
* Type for protobuf message google.protobuf.FieldOptions
*/
class FieldOptions$Type extends MessageType {
constructor() {
super("google.protobuf.FieldOptions", [
{ no: 1, name: "ctype", kind: "enum", opt: true, T: () => ["google.protobuf.FieldOptions.CType", FieldOptions_CType] },
{ no: 2, name: "packed", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 6, name: "jstype", kind: "enum", opt: true, T: () => ["google.protobuf.FieldOptions.JSType", FieldOptions_JSType] },
{ no: 5, name: "lazy", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 3, name: "deprecated", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 10, name: "weak", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: RepeatType.UNPACKED, T: () => UninterpretedOption }
]);
}
}
export const FieldOptions = new FieldOptions$Type();
/**
* Type for protobuf message google.protobuf.OneofOptions
*/
class OneofOptions$Type extends MessageType {
constructor() {
super("google.protobuf.OneofOptions", [
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: RepeatType.UNPACKED, T: () => UninterpretedOption }
]);
}
}
export const OneofOptions = new OneofOptions$Type();
/**
* Type for protobuf message google.protobuf.EnumOptions
*/
class EnumOptions$Type extends MessageType {
constructor() {
super("google.protobuf.EnumOptions", [
{ no: 2, name: "allow_alias", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 3, name: "deprecated", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: RepeatType.UNPACKED, T: () => UninterpretedOption }
]);
}
}
export const EnumOptions = new EnumOptions$Type();
/**
* Type for protobuf message google.protobuf.EnumValueOptions
*/
class EnumValueOptions$Type extends MessageType {
constructor() {
super("google.protobuf.EnumValueOptions", [
{ no: 1, name: "deprecated", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: RepeatType.UNPACKED, T: () => UninterpretedOption }
]);
}
}
export const EnumValueOptions = new EnumValueOptions$Type();
/**
* Type for protobuf message google.protobuf.ServiceOptions
*/
class ServiceOptions$Type extends MessageType {
constructor() {
super("google.protobuf.ServiceOptions", [
{ no: 33, name: "deprecated", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: RepeatType.UNPACKED, T: () => UninterpretedOption }
]);
}
}
export const ServiceOptions = new ServiceOptions$Type();
/**
* Type for protobuf message google.protobuf.MethodOptions
*/
class MethodOptions$Type extends MessageType {
constructor() {
super("google.protobuf.MethodOptions", [
{ no: 33, name: "deprecated", kind: "scalar", opt: true, T: ScalarType.BOOL },
{ no: 34, name: "idempotency_level", kind: "enum", opt: true, T: () => ["google.protobuf.MethodOptions.IdempotencyLevel", MethodOptions_IdempotencyLevel] },
{ no: 999, name: "uninterpreted_option", kind: "message", repeat: RepeatType.UNPACKED, T: () => UninterpretedOption }
]);
}
}
export const MethodOptions = new MethodOptions$Type();
/**
* Type for protobuf message google.protobuf.UninterpretedOption
*/
class UninterpretedOption$Type extends MessageType {
constructor() {
super("google.protobuf.UninterpretedOption", [
{ no: 2, name: "name", kind: "message", repeat: RepeatType.UNPACKED, T: () => UninterpretedOption_NamePart },
{ no: 3, name: "identifier_value", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 4, name: "positive_int_value", kind: "scalar", opt: true, T: ScalarType.UINT64 },
{ no: 5, name: "negative_int_value", kind: "scalar", opt: true, T: ScalarType.INT64 },
{ no: 6, name: "double_value", kind: "scalar", opt: true, T: ScalarType.DOUBLE },
{ no: 7, name: "string_value", kind: "scalar", opt: true, T: ScalarType.BYTES },
{ no: 8, name: "aggregate_value", kind: "scalar", opt: true, T: ScalarType.STRING }
]);
}
}
export const UninterpretedOption = new UninterpretedOption$Type();
/**
* Type for protobuf message google.protobuf.UninterpretedOption.NamePart
*/
class UninterpretedOption_NamePart$Type extends MessageType {
constructor() {
super("google.protobuf.UninterpretedOption.NamePart", [
{ no: 1, name: "name_part", kind: "scalar", T: ScalarType.STRING },
{ no: 2, name: "is_extension", kind: "scalar", T: ScalarType.BOOL }
]);
}
}
export const UninterpretedOption_NamePart = new UninterpretedOption_NamePart$Type();
/**
* Type for protobuf message google.protobuf.SourceCodeInfo
*/
class SourceCodeInfo$Type extends MessageType {
constructor() {
super("google.protobuf.SourceCodeInfo", [
{ no: 1, name: "location", kind: "message", repeat: RepeatType.UNPACKED, T: () => SourceCodeInfo_Location }
]);
}
}
export const SourceCodeInfo = new SourceCodeInfo$Type();
/**
* Type for protobuf message google.protobuf.SourceCodeInfo.Location
*/
class SourceCodeInfo_Location$Type extends MessageType {
constructor() {
super("google.protobuf.SourceCodeInfo.Location", [
{ no: 1, name: "path", kind: "scalar", repeat: RepeatType.PACKED, T: ScalarType.INT32 },
{ no: 2, name: "span", kind: "scalar", repeat: RepeatType.PACKED, T: ScalarType.INT32 },
{ no: 3, name: "leading_comments", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 4, name: "trailing_comments", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 6, name: "leading_detached_comments", kind: "scalar", repeat: RepeatType.UNPACKED, T: ScalarType.STRING }
]);
}
}
export const SourceCodeInfo_Location = new SourceCodeInfo_Location$Type();
/**
* Type for protobuf message google.protobuf.GeneratedCodeInfo
*/
class GeneratedCodeInfo$Type extends MessageType {
constructor() {
super("google.protobuf.GeneratedCodeInfo", [
{ no: 1, name: "annotation", kind: "message", repeat: RepeatType.UNPACKED, T: () => GeneratedCodeInfo_Annotation }
]);
}
}
export const GeneratedCodeInfo = new GeneratedCodeInfo$Type();
/**
* Type for protobuf message google.protobuf.GeneratedCodeInfo.Annotation
*/
class GeneratedCodeInfo_Annotation$Type extends MessageType {
constructor() {
super("google.protobuf.GeneratedCodeInfo.Annotation", [
{ no: 1, name: "path", kind: "scalar", repeat: RepeatType.PACKED, T: ScalarType.INT32 },
{ no: 2, name: "source_file", kind: "scalar", opt: true, T: ScalarType.STRING },
{ no: 3, name: "begin", kind: "scalar", opt: true, T: ScalarType.INT32 },
{ no: 4, name: "end", kind: "scalar", opt: true, T: ScalarType.INT32 }
]);
}
}
export const GeneratedCodeInfo_Annotation = new GeneratedCodeInfo_Annotation$Type();

View file

@ -0,0 +1,19 @@
export * from './descriptor-info';
export * from './descriptor-registry';
export * from './descriptor-tree';
export * from './generated-file';
export * from './plugin-base';
export * from './source-code-info';
export * from './string-format';
export * from './symbol-table';
export * from './type-names';
export * from './google/protobuf/descriptor';
export * from './google/protobuf/compiler/plugin';
export * from './typescript-compile';
export * from './typescript-comments';
export * from './typescript-import-manager';
export * from './typescript-method-from-text';
export * from './typescript-literal-from-value';
export * from './typescript-enum-builder';
export * from "./typescript-file";
export * from "./typescript-imports";

View file

@ -0,0 +1,199 @@
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { CodeGeneratorRequest, CodeGeneratorResponse, CodeGeneratorResponse_File } from "./google/protobuf/compiler/plugin";
import { types } from "util";
import { PbULong } from "@protobuf-ts/runtime";
/**
* Base class for a protobuf plugin.
*
* Implement the abstract `generate()` method to create a plugin.
* The method takes a `CodeGeneratorRequest` and returns an
* array of `GeneratedFile` or a promise thereof.
*
*
* Usage:
*
* #!/usr/bin/env node
* const {MyPlugin} = require( ... );
* new MyPlugin.run().catch(_ => {
* process.stderr.write('failed to run plugin');
* process.exit(1);
* });
*
* Reads a `CodeGeneratorRequest` created by `protoc` from stdin,
* passes it to the plugin-function and writes a
* `CodeGeneratorResponse` to stdout.
*
*
* Options:
*
* Use the `parseOptions()` method the parse the parameter
* of a `CodeGeneratorRequest` to a map of flags. Options are
* validated and usage is generated on error.
*
*
* Error handling:
*
* `generate()` may raise an error, reject it's promise or
* return an `GeneratedFile` with an attached error.
*
* Throwing `new Error("hello")` will result in the output:
*
* $ protoc --xx_out=/tmp -I protos protos/*
* --xx_out: Error: hello
* at /path/to/your-plugin.js:69
* ...
*
*
*/
export class PluginBase {
run() {
return __awaiter(this, void 0, void 0, function* () {
try {
let response, bytes = yield this.readBytes(process.stdin), request = CodeGeneratorRequest.fromBinary(bytes);
try {
const files = yield this.generate(request);
response = this.createResponse(files);
}
catch (error) {
response = CodeGeneratorResponse.create({
error: this.errorToString(error)
});
}
this.setBlockingStdout();
process.stdout.write(CodeGeneratorResponse.toBinary(response));
}
catch (error) {
process.stderr.write('Plugin failed to read CodeGeneratorRequest from stdin or write CodeGeneratorResponse to stdout.\n');
process.stderr.write(this.errorToString(error));
process.stderr.write('\n');
process.exit(1);
}
});
}
getSupportedFeatures() {
return [];
}
parseOptions(spec, parameter) {
var _a, _b, _c, _d;
this.validateOptionsSpec(spec);
let given = parameter ? parameter.split(',') : [];
let known = Object.keys(spec);
let excess = given.filter(i => !known.includes(i));
if (excess.length > 0) {
this.throwOptionError(spec, `Option "${excess.join('", "')}" not recognized.`);
}
for (let [key, val] of Object.entries(spec)) {
if (given.includes(key)) {
let missing = (_b = (_a = val.requires) === null || _a === void 0 ? void 0 : _a.filter(i => !given.includes(i))) !== null && _b !== void 0 ? _b : [];
if (missing.length > 0) {
this.throwOptionError(spec, `Option "${key}" requires option "${missing.join('", "')}" to be set.`);
}
let excess = (_d = (_c = val.excludes) === null || _c === void 0 ? void 0 : _c.filter(i => given.includes(i))) !== null && _d !== void 0 ? _d : [];
if (excess.length > 0) {
this.throwOptionError(spec, `If option "${key}" is set, option "${excess.join('", "')}" cannot be set.`);
}
}
}
let resolved = {};
for (let key of Object.keys(spec)) {
resolved[key] = given.includes(key);
}
return resolved;
}
throwOptionError(spec, error) {
let text = '';
text += error + '\n';
text += `\n`;
text += `Available options:\n`;
text += `\n`;
for (let [key, val] of Object.entries(spec)) {
text += `- "${key}"\n`;
for (let l of val.description.split('\n')) {
text += ` ${l}\n`;
}
text += `\n`;
}
let err = new Error(text);
err.name = `ParameterError`;
throw err;
}
validateOptionsSpec(spec) {
var _a, _b;
let known = Object.keys(spec);
for (let [key, { excludes, requires }] of Object.entries(spec)) {
let r = (_a = requires === null || requires === void 0 ? void 0 : requires.filter(i => !known.includes(i))) !== null && _a !== void 0 ? _a : [];
if (r.length > 0) {
throw new Error(`Invalid parameter spec for parameter "${key}". "requires" points to unknown parameters: ${r.join(', ')}`);
}
let e = (_b = excludes === null || excludes === void 0 ? void 0 : excludes.filter(i => !known.includes(i))) !== null && _b !== void 0 ? _b : [];
if (e.length > 0) {
throw new Error(`Invalid parameter spec for parameter "${key}". "excludes" points to unknown parameters: ${e.join(', ')}`);
}
}
}
readBytes(stream) {
return new Promise(resolve => {
const chunks = [];
stream.on('data', chunk => chunks.push(chunk));
stream.on('end', () => {
resolve(Buffer.concat(chunks));
});
});
}
createResponse(files) {
// we have to respond with an xor of all of our supported features.
// we should be working on a ulong here, but we cannot rely on bigint support.
let feat = 0;
for (let f of this.getSupportedFeatures()) {
feat = feat ^ f;
}
return CodeGeneratorResponse.create({
file: files
.map(f => CodeGeneratorResponse_File.create({
name: f.getFilename(),
content: f.getContent()
}))
.filter(f => f.content && f.content.length > 0),
supportedFeatures: PbULong.from(feat).toString()
});
}
errorToString(error) {
var _a;
if (error && typeof error.name == 'string' && error.name == 'ParameterError') {
return error.name + '\n\n' + error.message;
}
if (error && typeof error.name == 'string' && error.name == 'PluginMessageError') {
return error.message;
}
if (types.isNativeError(error)) {
return (_a = error.stack) !== null && _a !== void 0 ? _a : error.toString();
}
let text;
try {
text = error.toString();
}
catch (e) {
text = 'unknown error';
}
return text;
}
setBlockingStdout() {
// Fixes https://github.com/timostamm/protobuf-ts/issues/134
// Node is buffering chunks to stdout, meaning that for big generated
// files the CodeGeneratorResponse will not reach protoc completely.
// To fix this, we set stdout to block using the internal private
// method setBlocking(true)
const stdoutHandle = process.stdout._handle;
if (stdoutHandle) {
stdoutHandle.setBlocking(true);
}
}
}

View file

@ -0,0 +1,240 @@
import { DescriptorProto, EnumDescriptorProto, EnumValueDescriptorProto, FieldDescriptorProto, FileDescriptorProto, MethodDescriptorProto, OneofDescriptorProto, ServiceDescriptorProto } from "./google/protobuf/descriptor";
import { assert } from "@protobuf-ts/runtime";
export class SourceCodeInfoLookup {
constructor(parentResolver) {
this._parentResolver = parentResolver;
}
sourceCodeCursor(descriptor) {
var _a, _b;
const path = makeSourceCodePath(x => this._parentResolver(x), descriptor);
assert(path !== undefined, `Cannot create source code path`);
const all = (_b = (_a = this._findFile(descriptor).sourceCodeInfo) === null || _a === void 0 ? void 0 : _a.location) !== null && _b !== void 0 ? _b : [];
const hit = filterSourceCodeLocations(all, path);
return sourceCodeLocationToCursor(hit);
}
sourceCodeComments(descriptorOrFile, fileDescriptorFieldNumber) {
var _a, _b;
const path = makeSourceCodePath(x => this._parentResolver(x), descriptorOrFile);
assert(path !== undefined, `Cannot create source code path`);
if (fileDescriptorFieldNumber !== undefined) {
path.push(fileDescriptorFieldNumber);
}
const all = (_b = (_a = this._findFile(descriptorOrFile).sourceCodeInfo) === null || _a === void 0 ? void 0 : _a.location) !== null && _b !== void 0 ? _b : [];
const hit = filterSourceCodeLocations(all, path);
return sourceCodeLocationToComment(hit);
}
_findFile(d) {
let c = d;
while (c) {
if (FileDescriptorProto.is(c)) {
return c;
}
c = this._parentResolver(c);
}
assert(false);
}
}
/**
* Return cursor position of the given source code location
* as line number and column, both starting at 1.
*
* If more than one location is given, only the first one
* is evaluated, the others are discarded.
*/
export function sourceCodeLocationToCursor(locations) {
if (locations.length === 0) {
return emptyCursor;
}
const span = locations[0].span;
if (span === undefined || span.length < 3 || span.length > 4) {
return emptyCursor;
}
return [
span[0] + 1,
span[1] + 1
];
}
const emptyCursor = [undefined, undefined];
/**
* Return the comments for the given source code location.
*
* If more than one location is given, only the first one
* is evaluated, the others are discarded.
*
* If no comments found, empty (not undefined) object
* is returned.
*
* Trailing newlines are removed.
*/
export function sourceCodeLocationToComment(locations) {
if (locations.length === 0) {
return emptyComment;
}
const location = locations[0], leadingDetached = location.leadingDetachedComments.map(stripTrailingNewline), leadingComments = location.leadingComments, leading = leadingComments === ''
? undefined
: (leadingComments === undefined
? undefined
: stripTrailingNewline(leadingComments)), trailingComments = location.trailingComments, trailing = trailingComments === ''
? undefined
: (trailingComments === undefined
? undefined
: stripTrailingNewline(trailingComments));
return (leadingDetached.length === 0 && leading === undefined && trailing === undefined)
? emptyComment
: { leadingDetached, leading, trailing };
}
function stripTrailingNewline(block) {
return block.endsWith('\n')
? block.slice(0, -1)
: block;
}
const emptyComment = {
leadingDetached: [],
leading: undefined,
trailing: undefined,
};
/**
* Find the source code locations that match the given path.
*/
export function filterSourceCodeLocations(locations, path) {
return locations.filter(l => {
const p = l.path;
if (p.length !== path.length) {
return false;
}
for (let i = 0; i < p.length; i++) {
if (p[i] !== path[i]) {
return false;
}
}
return true;
});
}
/**
* Create the path to the source code location where the
* given element was declared.
*
* Returns `undefined` if we don't know how to make the path.
*
* For example, the path [4, 0, 2, 3] points to the 4th field
* of the first message of a .proto file:
*
* file
* .messageType // FileDescriptorProto.message_type = 3;
* [0] // first message
* .field // FileDescriptorProto.field = 2;
* [3] // 4th field
*
* See https://github.com/protocolbuffers/protobuf/blob/f1ce8663ac88df54cf212d29ce5123b69203b135/src/google/protobuf/descriptor.proto#L799
*/
export function makeSourceCodePath(parentProvider, descriptor) {
const path = [];
let parent = parentProvider(descriptor);
let component;
while (parent) {
component = makeSourceCodePathComponent(parent, descriptor);
if (component === undefined) {
return undefined;
}
path.unshift(...component);
descriptor = parent;
parent = parentProvider(parent);
}
return path;
}
/**
* Make a path from the parent to the immediate child.
*
* Returns `undefined` if we don't know how to make the path.
*/
export function makeSourceCodePathComponent(parent, child) {
if (FileDescriptorProto.is(parent) && DescriptorProto.is(child)) {
return [
FileDescriptorProtoFields.message_type,
parent.messageType.indexOf(child)
];
}
if (FileDescriptorProto.is(parent) && EnumDescriptorProto.is(child)) {
return [
FileDescriptorProtoFields.enum_type,
parent.enumType.indexOf(child)
];
}
if (FileDescriptorProto.is(parent) && ServiceDescriptorProto.is(child)) {
return [
FileDescriptorProtoFields.service,
parent.service.indexOf(child)
];
}
if (DescriptorProto.is(parent) && EnumDescriptorProto.is(child)) {
return [
DescriptorProtoFields.enum_type,
parent.enumType.indexOf(child)
];
}
if (DescriptorProto.is(parent) && DescriptorProto.is(child)) {
return [
DescriptorProtoFields.nested_type,
parent.nestedType.indexOf(child)
];
}
if (DescriptorProto.is(parent) && FieldDescriptorProto.is(child)) {
return [
DescriptorProtoFields.field,
parent.field.indexOf(child)
];
}
if (DescriptorProto.is(parent) && OneofDescriptorProto.is(child)) {
return [
DescriptorProtoFields.oneof_decl,
parent.oneofDecl.indexOf(child)
];
}
if (EnumDescriptorProto.is(parent) && EnumValueDescriptorProto.is(child)) {
return [
EnumDescriptorProtoFields.value,
parent.value.indexOf(child)
];
}
if (ServiceDescriptorProto.is(parent) && MethodDescriptorProto.is(child)) {
return [
ServiceDescriptorProtoFields.method,
parent.method.indexOf(child)
];
}
return undefined;
}
export var FileDescriptorProtoFields;
(function (FileDescriptorProtoFields) {
FileDescriptorProtoFields[FileDescriptorProtoFields["syntax"] = 12] = "syntax";
FileDescriptorProtoFields[FileDescriptorProtoFields["package"] = 2] = "package";
FileDescriptorProtoFields[FileDescriptorProtoFields["message_type"] = 4] = "message_type";
FileDescriptorProtoFields[FileDescriptorProtoFields["enum_type"] = 5] = "enum_type";
FileDescriptorProtoFields[FileDescriptorProtoFields["service"] = 6] = "service";
})(FileDescriptorProtoFields || (FileDescriptorProtoFields = {}));
var DescriptorProtoFields;
(function (DescriptorProtoFields) {
DescriptorProtoFields[DescriptorProtoFields["field"] = 2] = "field";
DescriptorProtoFields[DescriptorProtoFields["nested_type"] = 3] = "nested_type";
DescriptorProtoFields[DescriptorProtoFields["enum_type"] = 4] = "enum_type";
DescriptorProtoFields[DescriptorProtoFields["options"] = 7] = "options";
DescriptorProtoFields[DescriptorProtoFields["oneof_decl"] = 8] = "oneof_decl";
})(DescriptorProtoFields || (DescriptorProtoFields = {}));
// enum FieldDescriptorProtoFields {
// name = 1, // optional string name = 1;
// number = 3, // optional int32 number = 3;
// label = 4, // optional Label label = 4;
// type = 5, // optional Type type = 5;
// }
var EnumDescriptorProtoFields;
(function (EnumDescriptorProtoFields) {
// name = 1, // optional string name = 1;
EnumDescriptorProtoFields[EnumDescriptorProtoFields["value"] = 2] = "value";
// options = 3, // optional EnumOptions options = 3;
})(EnumDescriptorProtoFields || (EnumDescriptorProtoFields = {}));
var ServiceDescriptorProtoFields;
(function (ServiceDescriptorProtoFields) {
// name = 1, // optional string name = 1;
ServiceDescriptorProtoFields[ServiceDescriptorProtoFields["method"] = 2] = "method";
// options = 3, // optional ServiceOptions options = 3;
})(ServiceDescriptorProtoFields || (ServiceDescriptorProtoFields = {}));

View file

@ -0,0 +1,216 @@
import { DescriptorProto, EnumDescriptorProto, EnumValueDescriptorProto, FieldDescriptorProto, FieldDescriptorProto_Type, FieldOptions_JSType, FileDescriptorProto, MethodDescriptorProto, OneofDescriptorProto, ServiceDescriptorProto } from "./google/protobuf/descriptor";
import { isAnyTypeDescriptorProto } from "./descriptor-info";
import { assert, assertNever } from "@protobuf-ts/runtime";
export class StringFormat {
constructor(a, b, c, d) {
if (b === undefined) {
this.nameLookup = a;
this.treeLookup = a;
this.sourceCodeLookup = a;
this.descriptorInfo = a;
}
else {
this.nameLookup = a;
this.treeLookup = b;
this.sourceCodeLookup = c;
this.descriptorInfo = d;
}
}
/**
* Returns name of a scalar value type like it would
* appear in a .proto.
*
* For example, `FieldDescriptorProto_Type.UINT32` -> `"uint32"`.
*/
static formatScalarType(type) {
let name = FieldDescriptorProto_Type[type];
assert(name !== undefined, "unexpected ScalarValueType " + type);
return name.toLowerCase();
}
/**
* Returns type ('message', 'field', etc.) and descriptor name.
*
* Examples:
* message Bar
* field value = 2
* rpc Fetch()
*/
static formatName(descriptor) {
if (FileDescriptorProto.is(descriptor)) {
return `file ${descriptor.name}`;
}
else if (DescriptorProto.is(descriptor)) {
return `message ${descriptor.name}`;
}
else if (FieldDescriptorProto.is(descriptor)) {
if (descriptor.extendee !== undefined) {
return `extension field ${descriptor.name} = ${descriptor.number}`;
}
return `field ${descriptor.name} = ${descriptor.number}`;
}
else if (EnumDescriptorProto.is(descriptor)) {
return `enum ${descriptor.name}`;
}
else if (EnumValueDescriptorProto.is(descriptor)) {
return `enum value ${descriptor.name} = ${descriptor.number}`;
}
else if (ServiceDescriptorProto.is(descriptor)) {
return `service ${descriptor.name}`;
}
else if (MethodDescriptorProto.is(descriptor)) {
return `rpc ${descriptor.name}()`;
}
else
// noinspection SuspiciousTypeOfGuard
if (OneofDescriptorProto.is(descriptor)) {
return `oneof ${descriptor.name}`;
}
assertNever(descriptor);
assert(false);
}
formatQualifiedName(descriptor, includeFileInfo) {
if (FileDescriptorProto.is(descriptor)) {
return `file ${descriptor.name}`;
}
const file = includeFileInfo ? ' in ' + getSourceWithLineNo(descriptor, this.treeLookup, this.sourceCodeLookup) : '';
if (DescriptorProto.is(descriptor)) {
return `message ${this.nameLookup.makeTypeName(descriptor)}${file}`;
}
if (EnumDescriptorProto.is(descriptor)) {
return `enum ${this.nameLookup.makeTypeName(descriptor)}${file}`;
}
if (ServiceDescriptorProto.is(descriptor)) {
return `service ${this.nameLookup.makeTypeName(descriptor)}${file}`;
}
let parent = this.treeLookup.parentOf(descriptor);
if (FieldDescriptorProto.is(descriptor) && this.descriptorInfo.isExtension(descriptor)) {
let extensionName = this.descriptorInfo.getExtensionName(descriptor);
assert(descriptor.extendee);
let extendeeTypeName = this.nameLookup.normalizeTypeName(descriptor.extendee);
return `extension ${extendeeTypeName}.(${extensionName})${file}`;
}
assert(isAnyTypeDescriptorProto(parent));
let parentTypeName = this.nameLookup.makeTypeName(parent);
if (FieldDescriptorProto.is(descriptor)) {
return `field ${parentTypeName}.${descriptor.name}${file}`;
}
if (EnumValueDescriptorProto.is(descriptor)) {
return `enum value ${parentTypeName}.${descriptor.name}${file}`;
}
if (MethodDescriptorProto.is(descriptor)) {
return `rpc ${parentTypeName}.${descriptor.name}()${file}`;
}
return `oneof ${parentTypeName}.${descriptor.name}${file}`;
}
formatName(descriptor) {
return StringFormat.formatName(descriptor);
}
formatFieldDeclaration(descriptor) {
var _a, _b, _c, _d, _e;
let text = '';
// repeated ?
if (this.descriptorInfo.isUserDeclaredRepeated(descriptor)) {
text += 'repeated ';
}
// optional ?
if (this.descriptorInfo.isUserDeclaredOptional(descriptor)) {
text += 'optional ';
}
switch (descriptor.type) {
case FieldDescriptorProto_Type.ENUM:
text += this.nameLookup.makeTypeName(this.descriptorInfo.getEnumFieldEnum(descriptor));
break;
case FieldDescriptorProto_Type.MESSAGE:
if (this.descriptorInfo.isMapField(descriptor)) {
let mapK = StringFormat.formatScalarType(this.descriptorInfo.getMapKeyType(descriptor));
let mapVType = this.descriptorInfo.getMapValueType(descriptor);
let mapV = typeof mapVType === "number"
? StringFormat.formatScalarType(mapVType)
: this.nameLookup.makeTypeName(mapVType);
text += `map<${mapK}, ${mapV}>`;
}
else {
text += this.nameLookup.makeTypeName(this.descriptorInfo.getMessageFieldMessage(descriptor));
}
break;
case FieldDescriptorProto_Type.DOUBLE:
case FieldDescriptorProto_Type.FLOAT:
case FieldDescriptorProto_Type.INT64:
case FieldDescriptorProto_Type.UINT64:
case FieldDescriptorProto_Type.INT32:
case FieldDescriptorProto_Type.FIXED64:
case FieldDescriptorProto_Type.FIXED32:
case FieldDescriptorProto_Type.BOOL:
case FieldDescriptorProto_Type.STRING:
case FieldDescriptorProto_Type.BYTES:
case FieldDescriptorProto_Type.UINT32:
case FieldDescriptorProto_Type.SFIXED32:
case FieldDescriptorProto_Type.SFIXED64:
case FieldDescriptorProto_Type.SINT32:
case FieldDescriptorProto_Type.SINT64:
text += StringFormat.formatScalarType(descriptor.type);
break;
case FieldDescriptorProto_Type.GROUP:
text += "group";
break;
case FieldDescriptorProto_Type.UNSPECIFIED$:
text += "???";
break;
}
// name
text += ' ' + descriptor.name;
// number
text += ' = ' + descriptor.number;
// options
let options = [];
if (this.descriptorInfo.isExplicitlyDeclaredDeprecated(descriptor)) {
options.push('deprecated = true');
}
if (this.descriptorInfo.getFieldCustomJsonName(descriptor)) {
options.push(`json_name = "${this.descriptorInfo.getFieldCustomJsonName(descriptor)}"`);
}
if (((_a = descriptor.options) === null || _a === void 0 ? void 0 : _a.jstype) == FieldOptions_JSType.JS_STRING) {
options.push(`jstype = JS_STRING`);
}
if (((_b = descriptor.options) === null || _b === void 0 ? void 0 : _b.jstype) == FieldOptions_JSType.JS_NUMBER) {
options.push(`jstype = JS_NUMBER`);
}
if (((_c = descriptor.options) === null || _c === void 0 ? void 0 : _c.jstype) == FieldOptions_JSType.JS_NORMAL) {
options.push(`jstype = JS_NORMAL`);
}
if (((_d = descriptor.options) === null || _d === void 0 ? void 0 : _d.packed) === true) {
options.push(`packed = true`);
}
if (((_e = descriptor.options) === null || _e === void 0 ? void 0 : _e.packed) === false) {
options.push(`packed = false`);
}
if (options.length) {
text += ' [' + options.join(', ') + ']';
}
// semicolon
text += ';';
return text;
}
formatEnumValueDeclaration(descriptor) {
let text = `${descriptor.name} = ${descriptor.number}`;
if (this.descriptorInfo.isExplicitlyDeclaredDeprecated(descriptor)) {
text += ' [deprecated = true]';
}
return text + ';';
}
formatRpcDeclaration(descriptor) {
this.descriptorInfo.isExplicitlyDeclaredDeprecated(descriptor);
let m = descriptor.name, i = descriptor.inputType, is = descriptor.clientStreaming ? 'stream ' : '', o = descriptor.outputType, os = descriptor.serverStreaming ? 'stream ' : '';
if (i.startsWith('.')) {
i = i.substring(1);
}
if (o.startsWith('.')) {
o = o.substring(1);
}
return `${m}(${is}${i}) returns (${os}${o});`;
}
}
function getSourceWithLineNo(descriptor, treeLookup, sourceCodeLookup) {
let file = treeLookup.fileOf(descriptor), [l] = sourceCodeLookup.sourceCodeCursor(descriptor);
return `${file.name}:${l}`;
}

View file

@ -0,0 +1,93 @@
import { StringFormat } from "./string-format";
/**
* A table for unique symbols (for any DescriptorProto, EnumDescriptorProto
* or ServiceDescriptorProto) in files (GeneratedFile).
*/
export class SymbolTable {
constructor(clashResolver) {
this.entries = [];
this.clashResolveMaxTries = 100;
this.hasNameInFile = (name, file) => this.entries.some(e => e.file === file && e.name === name);
this.clashResolver = clashResolver !== null && clashResolver !== void 0 ? clashResolver : SymbolTable.defaultClashResolver;
}
/**
* Register a symbol in the given file for the given descriptor.
*
* If the name is already taken in the file, an alternative name
* is automatically generated by appending '$' and a running
* number to the requested name. You can change the behaviour by
* providing your own `clashResolver`.
*
* Only one symbol per kind can be registered for a descriptor.
*
* If you want to generate an interface *and* a class for a
* message, use a different `kind` for each.
*
* Returns the actual name registered.
*/
register(requestedName, descriptor, file, kind = 'default') {
// Only one symbol per kind can be registered for a descriptor.
if (this.has(descriptor, kind)) {
let { file, name } = this.get(descriptor, kind);
let msg = `Cannot register name "${requestedName}" of kind "${kind}" for ${StringFormat.formatName(descriptor)}. `
+ `The descriptor is already registered in file "${file.getFilename()}" with name "${name}". `
+ `Use a different 'kind' to register multiple symbols for a descriptor.`;
throw new Error(msg);
}
// find a free name within the file
let name = requestedName;
let count = 0;
while (this.hasNameInFile(name, file) && count < this.clashResolveMaxTries) {
name = this.clashResolver(descriptor, file, requestedName, kind, ++count, name);
}
if (this.hasNameInFile(name, file)) {
let msg = `Failed to register name "${requestedName}" for ${StringFormat.formatName(descriptor)}. `
+ `Gave up finding alternative name after ${this.clashResolveMaxTries} tries. `
+ `There is something wrong with the clash resolver.`;
throw new Error(msg);
}
// add the entry and return name
this.entries.push({ file, descriptor, kind, name });
return name;
}
/**
* Find a symbol (of the given kind) for the given descriptor.
* Return `undefined` if not found.
*/
find(descriptor, kind = 'default') {
return this.entries.find(e => e.descriptor === descriptor && e.kind === kind);
}
/**
* Find a symbol (of the given kind) for the given descriptor.
* Raises error if not found.
*/
get(descriptor, kind = 'default') {
const found = this.find(descriptor, kind);
if (!found) {
let files = this.entries.map(e => e.file)
.filter((value, index, array) => array.indexOf(value) === index);
let msg = `Failed to find name for ${StringFormat.formatName(descriptor)} of kind "${kind}". `
+ `Searched in ${files.length} files.`;
throw new Error(msg);
}
return found;
}
/**
* Is a name (of the given kind) registered for the the given descriptor?
*/
has(descriptor, kind = 'default') {
return !!this.find(descriptor, kind);
}
list(file, kind) {
let matches = this.entries.filter(e => e.file === file);
if (kind !== undefined) {
matches = matches.filter(e => e.kind === kind);
}
return matches;
}
static defaultClashResolver(descriptor, file, requestedName, kind, tryCount) {
let n = requestedName;
n = n.endsWith('$') ? n.substring(1) : n;
return n + '$' + tryCount;
}
}

View file

@ -0,0 +1,86 @@
import { isAnyTypeDescriptorProto } from "./descriptor-info";
import { FileDescriptorProto } from "./google/protobuf/descriptor";
import { assert } from "@protobuf-ts/runtime";
export class TypeNameLookup {
constructor(data) {
const names = new Map();
const reverse = new Map();
for (let { descriptor, ancestors } of data) {
let name = composeTypeName([...ancestors, descriptor]);
assert(!names.has(name));
names.set(name, descriptor);
reverse.set(descriptor, name);
}
this._names = names;
this._reverse = reverse;
}
static from(a, b) {
let data = [];
if (Array.isArray(a) && b) {
for (let descriptor of a) {
if (!isAnyTypeDescriptorProto(descriptor)) {
continue;
}
let ancestors = [];
let p = b(descriptor);
while (p) {
ancestors.unshift(p);
p = b(descriptor);
}
data.push({ descriptor, ancestors });
}
}
else if (!Array.isArray(a) && !b) {
a.visitTypes(descriptor => {
data.push({ descriptor, ancestors: a.ancestorsOf(descriptor) });
});
}
else {
assert(false);
}
return new TypeNameLookup(data);
}
normalizeTypeName(typeName) {
return typeName.startsWith(".") ? typeName.substring(1) : typeName;
}
resolveTypeName(typeName) {
typeName = this.normalizeTypeName(typeName);
const d = this._names.get(typeName);
assert(d !== undefined, `Unable to resolve type name "${typeName}"`);
return d;
}
peekTypeName(typeName) {
typeName = this.normalizeTypeName(typeName);
return this._names.get(typeName);
}
makeTypeName(descriptor) {
const n = this._reverse.get(descriptor);
assert(n !== undefined);
return n;
}
}
/**
* Compose a fully qualified type name for enum,
* message or service.
*
* Example:
* my_package.MyMessage.MyNestedMessage
*
* Throws if given array is invalid.
*/
function composeTypeName(descriptors) {
assert(descriptors.length > 0);
const parts = [], mid = descriptors.concat(), first = mid.shift(), last = mid.pop();
assert(FileDescriptorProto.is(first));
assert(isAnyTypeDescriptorProto(last), "expected any type descriptor, got: " + typeof (last));
const pkg = first.package;
if (pkg !== undefined && pkg !== '') {
parts.push(pkg);
}
for (const item of [...mid, last]) {
let part = item.name;
assert(part !== undefined);
parts.push(part);
}
return parts.join('.');
}

View file

@ -0,0 +1,47 @@
import * as ts from "typescript";
/**
* Adds multiple comment blocks as line comments
* in front of the given node.
*
* Applies a dirty hack to enforce newlines
* between each block.
*/
export function addCommentBlocksAsLeadingDetachedLines(node, ...texts) {
for (let text of texts) {
let lines = text.split('\n').map(l => l[0] !== ' ' ? ` ${l}` : l);
for (let j = 0; j < lines.length; j++) {
const line = lines[j];
if (j === lines.length - 1) {
ts.addSyntheticLeadingComment(node, ts.SyntaxKind.SingleLineCommentTrivia, line + '\n\n', false);
}
else {
ts.addSyntheticLeadingComment(node, ts.SyntaxKind.SingleLineCommentTrivia, line, true);
}
}
}
}
/**
* Adds a JSDoc comment block in front of the given node.
*
* A JSDoc comment looks like this:
* /**
* * body text
* *\/
*
* A regular block comment looks like this:
* /* body text *\/
*
*/
export function addCommentBlockAsJsDoc(node, text) {
let lines = text
.split('\n')
.map(line => {
if (line[0] === ' ') {
return ' *' + line;
}
return ' * ' + line;
});
text = '*\n' + lines.join('\n') + '\n ';
text = text.split('*/').join('*\\/'); // need to escape a comment in the comment
ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, text, true);
}

View file

@ -0,0 +1,119 @@
import * as ts from "typescript";
import * as path from "path";
export function setupCompiler(options, files, rootFileNames) {
const original = ts.createCompilerHost(options, true), host = new VirtualCompilerHost(original, files), libs = options.lib ? options.lib.map(lib => require.resolve(`typescript/lib/lib.${lib.toLowerCase()}.d.ts`)) : [], roots = rootFileNames.concat(libs), program = ts.createProgram(roots, options, host);
return [program, host];
}
class VirtualCompilerHost {
constructor(wrapped, files) {
this.wrapped = wrapped;
this._sourceFiles = new Map();
this._files = new Map();
this._dirs = new Set();
for (let vf of files) {
// create map from path to file
if (this._files.has(vf.getFilename())) {
throw new Error('Duplicate file paths in virtual files: ' + vf.getFilename());
}
this._files.set(vf.getFilename(), vf);
// create set of directory paths
let path = vf.getFilename().split('/');
while (path.length > 1) {
path.pop();
this._dirs.add(path.join('/'));
}
}
}
lookupVirtualFile(fileName) {
let vf = this._files.get(fileName);
if (vf)
return vf;
let cwd = process.cwd();
if (fileName.startsWith(cwd)) {
let relativePath = path.relative(cwd, fileName);
vf = this._files.get(relativePath);
if (vf)
return vf;
if (!relativePath.endsWith('.ts')) {
relativePath = relativePath += '.ts';
vf = this._files.get(relativePath);
if (vf)
return vf;
}
}
return undefined;
}
lookupVirtualDirectory(directoryName) {
let cwd = process.cwd();
if (directoryName.startsWith(cwd)) {
let relativePath = path.relative(cwd, directoryName);
return this._dirs.has(relativePath);
}
return false;
}
// noinspection JSUnusedGlobalSymbols
getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) {
const vf = this.lookupVirtualFile(fileName);
if (vf) {
let sf = this._sourceFiles.get(vf);
if (!sf) {
this._sourceFiles.set(vf, sf = ts.createSourceFile(vf.getFilename(), vf.getContent(), ts.ScriptTarget.Latest));
}
return sf;
}
return this.wrapped.getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
}
// noinspection JSUnusedGlobalSymbols
getDefaultLibFileName(options) {
return this.wrapped.getDefaultLibFileName(options);
}
// noinspection JSUnusedGlobalSymbols,JSUnusedLocalSymbols
writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles) {
// this.wrapped.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles);
}
// noinspection JSUnusedGlobalSymbols
getCurrentDirectory() {
return this.wrapped.getCurrentDirectory();
}
// noinspection JSUnusedGlobalSymbols
getCanonicalFileName(fileName) {
return this.wrapped.getCanonicalFileName(fileName);
}
// noinspection JSUnusedGlobalSymbols
useCaseSensitiveFileNames() {
return this.wrapped.useCaseSensitiveFileNames();
}
// noinspection JSUnusedGlobalSymbols
getNewLine() {
return this.wrapped.getNewLine();
}
// resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[], redirectedReference: ts.ResolvedProjectReference, options: ts.CompilerOptions): (ts.ResolvedModule | undefined)[] {
// resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string, redirectedReference: ts.ResolvedProjectReference, options: ts.CompilerOptions): ts.ResolvedTypeReferenceDirective[] {
// noinspection JSUnusedGlobalSymbols
fileExists(fileName) {
return !!this.lookupVirtualFile(fileName) || this.wrapped.fileExists(fileName);
}
// noinspection JSUnusedGlobalSymbols
readFile(fileName) {
const vf = this.lookupVirtualFile(fileName);
if (vf)
return vf.getContent();
this.wrapped.readFile(fileName);
}
// noinspection JSUnusedGlobalSymbols
directoryExists(directoryName) {
if (this.lookupVirtualDirectory(directoryName))
return true;
const f = this.wrapped.directoryExists;
if (!f)
throw new Error('wrapped.directoryExists is undefined');
return f(directoryName);
}
// noinspection JSUnusedGlobalSymbols
getDirectories(path) {
const f = this.wrapped.getDirectories;
if (!f)
throw new Error('wrapped.getDirectories is undefined');
return f(path);
}
}

View file

@ -0,0 +1,38 @@
import * as ts from "typescript";
import * as rt from "@protobuf-ts/runtime";
import { addCommentBlockAsJsDoc } from "./typescript-comments";
/**
* Creates an enum declaration.
*/
export class TypescriptEnumBuilder {
constructor() {
this.values = [];
}
add(name, number, comment) {
this.values.push({ name, number, comment });
}
build(name, modifiers) {
this.validate();
const members = [];
for (let { name, number, comment } of this.values) {
let member = ts.createEnumMember(ts.createIdentifier(name), ts.createNumericLiteral(number.toString()));
if (comment) {
addCommentBlockAsJsDoc(member, comment);
}
members.push(member);
}
return ts.createEnumDeclaration(undefined, modifiers, name, members);
}
validate() {
if (this.values.map(v => v.name).some((name, i, a) => a.indexOf(name) !== i))
throw new Error("duplicate names");
let ei = {};
for (let v of this.values) {
ei[v.number] = v.name;
ei[v.name] = v.number;
}
if (!rt.isEnumObject(ei)) {
throw new Error("not a typescript enum object");
}
}
}

View file

@ -0,0 +1,38 @@
import * as ts from "typescript";
export class TypescriptFile {
constructor(filename) {
this.sf = ts.createSourceFile(filename, "", ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
}
getFilename() {
return this.sf.fileName;
}
/**
* Add the new statement to the file.
*/
addStatement(statement, atTop = false) {
const newStatements = atTop
? [statement, ...this.sf.statements]
: this.sf.statements.concat(statement);
this.sf = ts.updateSourceFileNode(this.sf, newStatements);
}
/**
* The underlying SourceFile
*/
getSourceFile() {
return this.sf;
}
/**
* Are there any statements in this file?
*/
isEmpty() {
return this.sf.statements.length === 0;
}
/**
* The full content of this file.
* Returns an empty string if there are no statements.
*/
getContent() {
let printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
return printer.printFile(this.sf);
}
}

View file

@ -0,0 +1,202 @@
import { assert } from "@protobuf-ts/runtime";
import * as ts from "typescript";
import * as path from "path";
/** @deprecated */
export class TypescriptImportManager {
constructor(generatedFile, symbols, source) {
this.file = generatedFile;
this.symbols = symbols;
this.source = source;
}
/**
* Import {importName} from "importFrom";
*
* Automatically finds a free name if the
* `importName` would collide with another
* identifier.
*
* Returns imported name.
*/
name(importName, importFrom) {
const blackListedNames = this.symbols.list(this.file).map(e => e.name);
return ensureNamedImportPresent(this.source.getSourceFile(), importName, importFrom, blackListedNames, statementToAdd => this.source.addStatement(statementToAdd, true));
}
/**
* Import * as importAs from "importFrom";
*
* Returns name for `importAs`.
*/
namespace(importAs, importFrom) {
return ensureNamespaceImportPresent(this.source.getSourceFile(), importAs, importFrom, statementToAdd => this.source.addStatement(statementToAdd, true));
}
/**
* Import a previously registered identifier for a message
* or other descriptor.
*
* Uses the symbol table to look for the type, adds an
* import statement if necessary and automatically finds a
* free name if the identifier would clash in this file.
*
* If you have multiple representations for a descriptor
* in your generated code, use `kind` to discriminate.
*/
type(descriptor, kind = 'default') {
const symbolReg = this.symbols.get(descriptor, kind);
// symbol in this file?
if (symbolReg.file === this.file) {
return symbolReg.name;
}
// symbol not in file
// add an import statement
const importPath = createRelativeImportPath(this.source.getSourceFile().fileName, symbolReg.file.getFilename());
const blackListedNames = this.symbols.list(this.file).map(e => e.name);
return ensureNamedImportPresent(this.source.getSourceFile(), symbolReg.name, importPath, blackListedNames, statementToAdd => this.source.addStatement(statementToAdd, true));
}
}
/**
* Import * as asName from "importFrom";
*
* If the import is already present, just return the
* identifier.
*
* If the import is not present, create the import
* statement and call `addStatementFn`.
*
* Does *not* check for collisions.
*/
function ensureNamespaceImportPresent(currentFile, asName, importFrom, addStatementFn) {
const all = findNamespaceImports(currentFile), match = all.find(ni => ni.as === asName && ni.from === importFrom);
if (match) {
return match.as;
}
const statementToAdd = createNamespaceImport(asName, importFrom);
addStatementFn(statementToAdd);
return asName;
}
/**
* import * as <asName> from "<importFrom>";
*/
function createNamespaceImport(asName, importFrom) {
return ts.createImportDeclaration(undefined, undefined, ts.createImportClause(undefined, ts.createNamespaceImport(ts.createIdentifier(asName))), ts.createStringLiteral(importFrom));
}
/**
* import * as <as> from "<from>";
*/
function findNamespaceImports(sourceFile) {
let r = [];
for (let s of sourceFile.statements) {
if (ts.isImportDeclaration(s) && s.importClause) {
let namedBindings = s.importClause.namedBindings;
if (namedBindings && ts.isNamespaceImport(namedBindings)) {
assert(ts.isStringLiteral(s.moduleSpecifier));
r.push({
as: namedBindings.name.escapedText.toString(),
from: s.moduleSpecifier.text
});
}
}
}
return r;
}
/**
* Import {importName} from "importFrom";
*
* If the import is already present, just return the
* identifier.
*
* If the import is not present, create the import
* statement and call `addStatementFn`.
*
* If the import name is taken by another named import
* or is in the list of blacklisted names, an
* alternative name is used:
*
* Import {importName as alternativeName} from "importFrom";
*
* Returns the imported name or the alternative name.
*/
function ensureNamedImportPresent(currentFile, importName, importFrom, blacklistedNames, addStatementFn, escapeCharacter = '$') {
var _a;
const all = findNamedImports(currentFile), taken = all.map(ni => { var _a; return (_a = ni.as) !== null && _a !== void 0 ? _a : ni.name; }).concat(blacklistedNames), match = all.find(ni => ni.name === importName && ni.from === importFrom);
if (match) {
return (_a = match.as) !== null && _a !== void 0 ? _a : match.name;
}
let as;
if (taken.includes(importName)) {
let i = 0;
as = importName;
while (taken.includes(as)) {
as = importName + escapeCharacter;
if (i++ > 0) {
as += i;
}
}
}
const statementToAdd = createNamedImport(importName, importFrom, as);
addStatementFn(statementToAdd);
return as !== null && as !== void 0 ? as : importName;
}
/**
* import {<name>} from '<from>';
* import {<name> as <as>} from '<from>';
*/
function createNamedImport(name, from, as) {
if (as) {
return ts.createImportDeclaration(undefined, undefined, ts.createImportClause(undefined, ts.createNamedImports([ts.createImportSpecifier(ts.createIdentifier(name), ts.createIdentifier(as))]), false), ts.createStringLiteral(from));
}
return ts.createImportDeclaration(undefined, undefined, ts.createImportClause(undefined, ts.createNamedImports([
ts.createImportSpecifier(undefined, ts.createIdentifier(name))
])), ts.createStringLiteral(from));
}
/**
* import {<name>} from '<from>';
* import {<name> as <as>} from '<from>';
*/
function findNamedImports(sourceFile) {
let r = [];
for (let s of sourceFile.statements) {
if (ts.isImportDeclaration(s) && s.importClause) {
let namedBindings = s.importClause.namedBindings;
if (namedBindings && ts.isNamedImports(namedBindings)) {
for (let importSpecifier of namedBindings.elements) {
assert(ts.isStringLiteral(s.moduleSpecifier));
if (importSpecifier.propertyName) {
r.push({
name: importSpecifier.propertyName.escapedText.toString(),
as: importSpecifier.name.escapedText.toString(),
from: s.moduleSpecifier.text
});
}
else {
r.push({
name: importSpecifier.name.escapedText.toString(),
as: undefined,
from: s.moduleSpecifier.text
});
}
}
}
}
}
return r;
}
/**
* Create a relative path for an import statement like
* `import {Foo} from "./foo"`
*/
function createRelativeImportPath(currentPath, pathToImportFrom) {
// create relative path to the file to import
let fromPath = path.relative(path.dirname(currentPath), pathToImportFrom);
// on windows, this may add backslash directory separators.
// we replace them with forward slash.
if (path.sep !== "/") {
fromPath = fromPath.split(path.sep).join("/");
}
// drop file extension
fromPath = fromPath.replace(/\.[a-z]+$/, '');
// make sure to start with './' to signal relative path to module resolution
if (!fromPath.startsWith('../') && !fromPath.startsWith('./')) {
fromPath = './' + fromPath;
}
return fromPath;
}

View file

@ -0,0 +1,207 @@
import { assert } from "@protobuf-ts/runtime";
import * as ts from "typescript";
import * as path from "path";
export class TypeScriptImports {
constructor(symbols) {
this.symbols = symbols;
}
/**
* Import {importName} from "importFrom";
*
* Automatically finds a free name if the
* `importName` would collide with another
* identifier.
*
* Returns imported name.
*/
name(source, importName, importFrom, isTypeOnly = false) {
const blackListedNames = this.symbols.list(source).map(e => e.name);
return ensureNamedImportPresent(source.getSourceFile(), importName, importFrom, isTypeOnly, blackListedNames, statementToAdd => source.addStatement(statementToAdd, true));
}
/**
* Import * as importAs from "importFrom";
*
* Returns name for `importAs`.
*/
namespace(source, importAs, importFrom, isTypeOnly = false) {
return ensureNamespaceImportPresent(source.getSourceFile(), importAs, importFrom, isTypeOnly, statementToAdd => source.addStatement(statementToAdd, true));
}
/**
* Import a previously registered identifier for a message
* or other descriptor.
*
* Uses the symbol table to look for the type, adds an
* import statement if necessary and automatically finds a
* free name if the identifier would clash in this file.
*
* If you have multiple representations for a descriptor
* in your generated code, use `kind` to discriminate.
*/
type(source, descriptor, kind = 'default', isTypeOnly = false) {
const symbolReg = this.symbols.get(descriptor, kind);
// symbol in this file?
if (symbolReg.file === source) {
return symbolReg.name;
}
// symbol not in file
// add an import statement
const importPath = createRelativeImportPath(source.getSourceFile().fileName, symbolReg.file.getFilename());
const blackListedNames = this.symbols.list(source).map(e => e.name);
return ensureNamedImportPresent(source.getSourceFile(), symbolReg.name, importPath, isTypeOnly, blackListedNames, statementToAdd => source.addStatement(statementToAdd, true));
}
}
/**
* Import * as asName from "importFrom";
*
* If the import is already present, just return the
* identifier.
*
* If the import is not present, create the import
* statement and call `addStatementFn`.
*
* Does *not* check for collisions.
*/
function ensureNamespaceImportPresent(currentFile, asName, importFrom, isTypeOnly, addStatementFn) {
const all = findNamespaceImports(currentFile), match = all.find(ni => ni.as === asName && ni.from === importFrom && ni.isTypeOnly === isTypeOnly);
if (match) {
return match.as;
}
const statementToAdd = createNamespaceImport(asName, importFrom, isTypeOnly);
addStatementFn(statementToAdd);
return asName;
}
/**
* import * as <asName> from "<importFrom>";
*/
function createNamespaceImport(asName, importFrom, isTypeOnly) {
return ts.createImportDeclaration(undefined, undefined, ts.createImportClause(undefined, ts.createNamespaceImport(ts.createIdentifier(asName)), isTypeOnly), ts.createStringLiteral(importFrom));
}
/**
* import * as <as> from "<from>";
*/
function findNamespaceImports(sourceFile) {
let r = [];
for (let s of sourceFile.statements) {
if (ts.isImportDeclaration(s) && s.importClause) {
let namedBindings = s.importClause.namedBindings;
if (namedBindings && ts.isNamespaceImport(namedBindings)) {
assert(ts.isStringLiteral(s.moduleSpecifier));
r.push({
as: namedBindings.name.escapedText.toString(),
from: s.moduleSpecifier.text,
isTypeOnly: s.importClause.isTypeOnly,
});
}
}
}
return r;
}
/**
* import {importName} from "importFrom";
* import type {importName} from "importFrom";
*
* If the import is already present, just return the
* identifier.
*
* If the import is not present, create the import
* statement and call `addStatementFn`.
*
* If the import name is taken by another named import
* or is in the list of blacklisted names, an
* alternative name is used:
*
* Import {importName as alternativeName} from "importFrom";
*
* Returns the imported name or the alternative name.
*/
export function ensureNamedImportPresent(currentFile, importName, importFrom, isTypeOnly, blacklistedNames, addStatementFn, escapeCharacter = '$') {
var _a;
const all = findNamedImports(currentFile), taken = all.map(ni => { var _a; return (_a = ni.as) !== null && _a !== void 0 ? _a : ni.name; }).concat(blacklistedNames), match = all.find(ni => ni.name === importName && ni.from === importFrom && ni.isTypeOnly === isTypeOnly);
if (match) {
return (_a = match.as) !== null && _a !== void 0 ? _a : match.name;
}
let as;
if (taken.includes(importName)) {
let i = 0;
as = importName;
while (taken.includes(as)) {
as = importName + escapeCharacter;
if (i++ > 0) {
as += i;
}
}
}
const statementToAdd = createNamedImport(importName, importFrom, as, isTypeOnly);
addStatementFn(statementToAdd);
return as !== null && as !== void 0 ? as : importName;
}
/**
* import {<name>} from '<from>';
* import {<name> as <as>} from '<from>';
* import type {<name>} from '<from>';
* import type {<name> as <as>} from '<from>';
*/
export function createNamedImport(name, from, as, isTypeOnly = false) {
if (as) {
return ts.createImportDeclaration(undefined, undefined, ts.createImportClause(undefined, ts.createNamedImports([ts.createImportSpecifier(ts.createIdentifier(name), ts.createIdentifier(as))]), isTypeOnly), ts.createStringLiteral(from));
}
return ts.createImportDeclaration(undefined, undefined, ts.createImportClause(undefined, ts.createNamedImports([
ts.createImportSpecifier(undefined, ts.createIdentifier(name))
]), isTypeOnly), ts.createStringLiteral(from));
}
/**
* import {<name>} from '<from>';
* import {<name> as <as>} from '<from>';
* import type {<name>} from '<from>';
* import type {<name> as <as>} from '<from>';
*/
export function findNamedImports(sourceFile) {
let r = [];
for (let s of sourceFile.statements) {
if (ts.isImportDeclaration(s) && s.importClause) {
let namedBindings = s.importClause.namedBindings;
if (namedBindings && ts.isNamedImports(namedBindings)) {
for (let importSpecifier of namedBindings.elements) {
assert(ts.isStringLiteral(s.moduleSpecifier));
if (importSpecifier.propertyName) {
r.push({
name: importSpecifier.propertyName.escapedText.toString(),
as: importSpecifier.name.escapedText.toString(),
from: s.moduleSpecifier.text,
isTypeOnly: s.importClause.isTypeOnly
});
}
else {
r.push({
name: importSpecifier.name.escapedText.toString(),
as: undefined,
from: s.moduleSpecifier.text,
isTypeOnly: s.importClause.isTypeOnly
});
}
}
}
}
}
return r;
}
/**
* Create a relative path for an import statement like
* `import {Foo} from "./foo"`
*/
function createRelativeImportPath(currentPath, pathToImportFrom) {
// create relative path to the file to import
let fromPath = path.relative(path.dirname(currentPath), pathToImportFrom);
// on windows, this may add backslash directory separators.
// we replace them with forward slash.
if (path.sep !== "/") {
fromPath = fromPath.split(path.sep).join("/");
}
// drop file extension
fromPath = fromPath.replace(/\.[a-z]+$/, '');
// make sure to start with './' to signal relative path to module resolution
if (!fromPath.startsWith('../') && !fromPath.startsWith('./')) {
fromPath = './' + fromPath;
}
return fromPath;
}

View file

@ -0,0 +1,103 @@
import { assertNever } from "@protobuf-ts/runtime";
import * as ts from "typescript";
const validPropertyKey = /^(?![0-9])[a-zA-Z0-9$_]+$/;
/**
* Creates nodes for simple JavaScript values.
*
* Simple JavaScript values include:
* - all primitives: number, bigint, string, boolean
* - undefined, null
* - plain objects containing only simple JavaScript values
* - arrays containing only simple JavaScript values
* - typed arrays
*/
export function typescriptLiteralFromValue(value) {
switch (typeof value) {
case "undefined":
return ts.createIdentifier("undefined");
case "boolean":
return value ? ts.createTrue() : ts.createFalse();
case "string":
return ts.createStringLiteral(value);
case "bigint":
return ts.createNumericLiteral(`${value}n`);
case "number":
if (isNaN(value)) {
return ts.createPropertyAccess(ts.createIdentifier("Number"), ts.createIdentifier("Nan"));
}
else if (value === Number.POSITIVE_INFINITY) {
return ts.createPropertyAccess(ts.createIdentifier("Number"), ts.createIdentifier("POSITIVE_INFINITY"));
}
else if (value === Number.NEGATIVE_INFINITY) {
return ts.createPropertyAccess(ts.createIdentifier("Number"), ts.createIdentifier("NEGATIVE_INFINITY"));
}
return ts.createNumericLiteral(`${value}`);
case "object":
if (value === null) {
return ts.createNull();
}
if (isTypedArray(value)) {
if (value.length == 0) {
return ts.createNew(ts.createIdentifier(typedArrayName(value)), undefined, [ts.createNumericLiteral("0")]);
}
let values = [];
for (let i = 0; i < value.length; i++) {
values.push(ts.createNumericLiteral(value.toString()));
}
return ts.createNew(ts.createIdentifier(typedArrayName(value)), undefined, [ts.createArrayLiteral(values, false)]);
}
if (Array.isArray(value)) {
let elements = value.map(ele => typescriptLiteralFromValue(ele));
return ts.createArrayLiteral(elements, false);
}
if (value.constructor !== Object) {
throw new Error(`got a non-plain object ${value.constructor}`);
}
let props = [];
for (let key of Object.keys(value)) {
let propName = validPropertyKey.test(key) ? key : ts.createStringLiteral(key);
let propVal = typescriptLiteralFromValue(value[key]);
props.push(ts.createPropertyAssignment(propName, propVal));
}
return ts.createObjectLiteral(props, false);
}
assertNever(value);
}
function isTypedArray(arg) {
return arg instanceof Uint8Array
|| arg instanceof Int8Array
|| arg instanceof Uint8ClampedArray
|| arg instanceof Int16Array
|| arg instanceof Uint16Array
|| arg instanceof Int32Array
|| arg instanceof Uint32Array
|| arg instanceof Float32Array
|| arg instanceof Float64Array;
}
function typedArrayName(arg) {
if (arg instanceof Uint8Array) {
return 'Uint8Array';
}
if (arg instanceof Int8Array) {
return 'Int8Array';
}
if (arg instanceof Uint8ClampedArray) {
return 'Uint8ClampedArray';
}
if (arg instanceof Int16Array) {
return 'Int16Array';
}
if (arg instanceof Uint16Array) {
return 'Uint16Array';
}
if (arg instanceof Int32Array) {
return 'Int32Array';
}
if (arg instanceof Uint32Array) {
return 'Uint32Array';
}
if (arg instanceof Float32Array) {
return 'Float32Array';
}
return 'Float64Array';
}

View file

@ -0,0 +1,32 @@
import * as ts from "typescript";
import { addCommentBlockAsJsDoc } from "./typescript-comments";
/**
* Provide a function statement as plain text, receive a
* method declaration.
*/
export function typescriptMethodFromText(functionText) {
const sourceFile = ts.createSourceFile('temp.ts', functionText, ts.ScriptTarget.Latest);
if (sourceFile.statements.length !== 1) {
throw new Error('Expected exactly one statement, got ' + sourceFile.statements.length);
}
const node = sourceFile.statements[0];
if (!ts.isFunctionDeclaration(node)) {
throw new Error('Expected a function declaration');
}
if (node.name === undefined) {
throw new Error('function needs a name');
}
const method = ts.createMethod(node.decorators /*decorators*/, node.modifiers /*modifiers*/, node.asteriskToken /*asteriskToken*/, node.name, node.questionToken /*questionToken*/, node.typeParameters /*typeParameters*/, node.parameters, node.type /*return type*/, node.body);
ts.forEachLeadingCommentRange(functionText, node.getFullStart(), (pos, end) => {
let text = functionText.substring(pos, end);
text = text.trim();
if (text.startsWith('/*'))
text = text.substring(2);
if (text.endsWith('*/'))
text = text.substring(0, text.length - 2);
text = text.split('\n').map(l => l.replace(/^\s*\*/, '')).join('\n');
text = text.trim();
addCommentBlockAsJsDoc(method, text);
});
return method;
}

View file

@ -0,0 +1,239 @@
import { DescriptorProto, EnumDescriptorProto, EnumOptions, EnumValueDescriptorProto, EnumValueOptions, FieldDescriptorProto, FieldDescriptorProto_Type, FieldOptions, FileDescriptorProto, FileOptions, MessageOptions, MethodDescriptorProto, MethodOptions, OneofDescriptorProto, OneofOptions, ServiceDescriptorProto, ServiceOptions } from "./google/protobuf/descriptor";
import { ITypeNameLookup } from "./type-names";
import { IDescriptorTree } from "./descriptor-tree";
/**
* Union of all known descriptor proto.
*/
export declare type AnyDescriptorProto = FileDescriptorProto | DescriptorProto | FieldDescriptorProto | OneofDescriptorProto | EnumDescriptorProto | EnumValueDescriptorProto | ServiceDescriptorProto | MethodDescriptorProto;
/**
* Messages, enums and services are the only first-class
* types in the protobuf world.
*
* We assume that it should be possible to lookup these
* types by name.
*/
export declare type AnyTypeDescriptorProto = DescriptorProto | EnumDescriptorProto | ServiceDescriptorProto;
/**
* Union of all known descriptor options.
*/
export declare type AnyOptions = FileOptions | MessageOptions | FieldOptions | EnumOptions | OneofOptions | EnumValueOptions | ServiceOptions | MethodOptions;
/**
* Is this a first-class type?
*/
export declare function isAnyTypeDescriptorProto(arg: any): arg is AnyTypeDescriptorProto;
/**
* All scalar values types (which includes bytes)
* https://developers.google.com/protocol-buffers/docs/proto3#scalar_value_types
*/
export declare type ScalarValueType = Exclude<FieldDescriptorProto_Type, typeof FieldDescriptorProto_Type.UNSPECIFIED$ | typeof FieldDescriptorProto_Type.MESSAGE | typeof FieldDescriptorProto_Type.ENUM | typeof FieldDescriptorProto_Type.GROUP>;
/**
* Map field key type.
*
* The key_type can be any integral or string type
* (so, any scalar type except for floating point
* types and bytes)
*/
export declare type MapFieldKeyType = Exclude<FieldDescriptorProto_Type, typeof FieldDescriptorProto_Type.FLOAT | typeof FieldDescriptorProto_Type.DOUBLE | typeof FieldDescriptorProto_Type.BYTES | typeof FieldDescriptorProto_Type.UNSPECIFIED$ | typeof FieldDescriptorProto_Type.MESSAGE | typeof FieldDescriptorProto_Type.ENUM | typeof FieldDescriptorProto_Type.GROUP>;
/**
* Map field value type.
*
* Can be any scalar type, enum, or message.
*/
export declare type MapFieldValueType = DescriptorProto | EnumDescriptorProto | ScalarValueType;
export interface IDescriptorInfo {
/**
* Is this an extension field?
*/
isExtension(descriptor: FieldDescriptorProto): boolean;
/**
* Finds all extension fields extending the given message descriptor.
*/
extensionsFor(descriptorOrTypeName: DescriptorProto | string): FieldDescriptorProto[];
/**
* Get the name of an extension field, including the namespace
* where it was defined.
*
* For example, an extension field defined in the package "foo":
*
* ```proto
* extend google.protobuf.FieldOptions {
* bool opt = 1001;
* }
* ```
*
* Will have the extension name "foo.opt".
*
*/
getExtensionName(fieldDescriptor: FieldDescriptorProto): string;
/**
* Return the user-specified JSON name.
* Returns `undefined` if no name was specified or name
* equals lowerCamelCaseName.
*/
getFieldCustomJsonName(fieldDescriptor: FieldDescriptorProto): string | undefined;
/**
* Is this a enum field?
*/
isEnumField(fieldDescriptor: FieldDescriptorProto): boolean;
/**
* Get the enum descriptor for a enum field.
*/
getEnumFieldEnum(fieldDescriptor: FieldDescriptorProto): EnumDescriptorProto;
/**
* Is this a message field?
*
* Returns false if this is a map field, even though map fields have type MESSAGE.
*
* Before v2.0.0-alpha.23, this method returned true for group fields (type GROUP).
*/
isMessageField(fieldDescriptor: FieldDescriptorProto): boolean;
/**
* Is this a group field?
*
* Note that groups are deprecated and not supported in proto3.
*/
isGroupField(fieldDescriptor: FieldDescriptorProto): boolean;
/**
* Get the message descriptor for a message field.
*/
getMessageFieldMessage(fieldDescriptor: FieldDescriptorProto): DescriptorProto;
/**
* Is this a scalar field?
*/
isScalarField(fieldDescriptor: FieldDescriptorProto): boolean;
/**
* Get the scalar type of a scalar field.
*/
getScalarFieldType(fieldDescriptor: FieldDescriptorProto): ScalarValueType;
/**
* Is this a map field?
*/
isMapField(fieldDescriptor: FieldDescriptorProto): boolean;
/**
* Get the key type of a map field.
*/
getMapKeyType(fieldDescriptor: FieldDescriptorProto): MapFieldKeyType;
/**
* Get the value type (can be enum or message) of a map field.
*/
getMapValueType(fieldDescriptor: FieldDescriptorProto): DescriptorProto | EnumDescriptorProto | ScalarValueType;
/**
* Determines whether the user declared the field
* with `optional`.
*
* For proto2, the field descriptor's `label` is
* `LABEL_OPTIONAL`.
*
* For proto3, the field descriptor's `proto3_optional`
* is `true` and the field will be the sole member
* of a "synthetic" oneof.
*/
isUserDeclaredOptional(fieldDescriptor: FieldDescriptorProto): boolean;
/**
* Is this field declared as a oneof member by the user?
*
* When a field is declared `optional` in proto3, a
* "synthetic" oneof is generated by the compiler.
*/
isUserDeclaredOneof(fieldDescriptor: FieldDescriptorProto): boolean;
/**
* Determines whether the user declared the field
* with `repeated`.
*
* A map<K,V> for example cannot be repeated, but
* is internally represented as a repeated
* entry-message. This function recognizes this
* and returns false.
*/
isUserDeclaredRepeated(fieldDescriptor: FieldDescriptorProto): boolean;
/**
* Should this (repeated) field be encoded packed?
*
* Returns true if the user set [packed = true] or if syntax is proto3
* (and user did not explicitly disable default behaviour of proto3).
*
* Returns false if:
* - the field is not declared with `repeated`.
* - the user set [packed = false].
* - syntax is proto2 and there is no [packed = true].
*
* Throws if the field is `repeated` and type is `bytes` or `string`.
* This should have been a parse failure by protoc.
*/
shouldBePackedRepeated(fieldDescriptor: FieldDescriptorProto): boolean;
/**
* Is this element marked deprecated by the user?
*/
isExplicitlyDeclaredDeprecated(descriptor: AnyDescriptorProto): boolean;
/**
* Is the element intentionally created by the user
* or synthesized by the protobuf compiler?
*
* For example, the compiler generates an entry
* message for each map.
*/
isSyntheticElement(descriptor: AnyDescriptorProto): boolean;
/**
* Determine whether all enum value names start with the snake_case
* version of the enums name (enumLocalName or descriptor.name).
* If so, return the shared prefix. Otherwise, return undefined.
*
* For example, the following enum...
*
* ```proto
* enum MyEnum {
* MY_ENUM_FOO = 0;
* MY_ENUM_BAR = 1;
* }
* ```
*
* ... has the shared prefix "MY_ENUM_".
*/
findEnumSharedPrefix(enumDescriptor: EnumDescriptorProto, enumLocalName?: string): string | undefined;
/**
* Is a top-level type declared in the given file used anywhere the given
* "inFiles"?
*
* Returns true if a type from the file is used in a message field or
* method input or output.
*/
isFileUsed(file: FileDescriptorProto, inFiles: FileDescriptorProto[]): boolean;
/**
* Is the given type used anywhere in the given "inFiles"?
*
* Returns true if the type is used in a message field or method input or
* output.
*/
isTypeUsed(type: AnyTypeDescriptorProto, inFiles: FileDescriptorProto[]): boolean;
}
export declare class DescriptorInfo implements IDescriptorInfo {
private readonly tree;
private readonly nameLookup;
constructor(tree: IDescriptorTree, nameLookup: ITypeNameLookup);
private allExtensions;
private getAllExtensions;
isExtension(fieldDescriptor: FieldDescriptorProto): boolean;
extensionsFor(descriptorOrTypeName: DescriptorProto | string): FieldDescriptorProto[];
getExtensionName(fieldDescriptor: FieldDescriptorProto): string;
getFieldCustomJsonName(fieldDescriptor: FieldDescriptorProto): string | undefined;
isEnumField(fieldDescriptor: FieldDescriptorProto): boolean;
getEnumFieldEnum(fieldDescriptor: FieldDescriptorProto): EnumDescriptorProto;
isMessageField(fieldDescriptor: FieldDescriptorProto): boolean;
isGroupField(fieldDescriptor: FieldDescriptorProto): boolean;
getMessageFieldMessage(fieldDescriptor: FieldDescriptorProto): DescriptorProto;
isScalarField(fieldDescriptor: FieldDescriptorProto): boolean;
getScalarFieldType(fieldDescriptor: FieldDescriptorProto): ScalarValueType;
isMapField(fieldDescriptor: FieldDescriptorProto): boolean;
getMapKeyType(fieldDescriptor: FieldDescriptorProto): MapFieldKeyType;
getMapValueType(fieldDescriptor: FieldDescriptorProto): MapFieldValueType;
private getMapEntryMessage;
isExplicitlyDeclaredDeprecated(descriptor: AnyDescriptorProto): boolean;
isSyntheticElement(descriptor: AnyDescriptorProto): boolean;
isUserDeclaredOneof(fieldDescriptor: FieldDescriptorProto): boolean;
isUserDeclaredOptional(fieldDescriptor: FieldDescriptorProto): boolean;
isUserDeclaredRepeated(fieldDescriptor: FieldDescriptorProto): boolean;
shouldBePackedRepeated(fieldDescriptor: FieldDescriptorProto): boolean;
findEnumSharedPrefix(enumDescriptor: EnumDescriptorProto, enumLocalName?: string): string | undefined;
isFileUsed(file: FileDescriptorProto, inFiles: FileDescriptorProto[]): boolean;
isTypeUsed(type: AnyTypeDescriptorProto, inFiles: FileDescriptorProto[]): boolean;
}

View file

@ -0,0 +1,75 @@
import { DescriptorProto, EnumDescriptorProto, EnumOptions, EnumValueDescriptorProto, EnumValueOptions, FieldDescriptorProto, FieldOptions, FileDescriptorProto, FileOptions, MessageOptions, MethodDescriptorProto, MethodOptions, OneofDescriptorProto, OneofOptions, ServiceDescriptorProto, ServiceOptions } from "./google/protobuf/descriptor";
import { CodeGeneratorRequest } from "./google/protobuf/compiler/plugin";
import { AnyDescriptorProto, AnyTypeDescriptorProto, IDescriptorInfo, MapFieldKeyType, ScalarValueType } from "./descriptor-info";
import { IDescriptorTree } from "./descriptor-tree";
import { FileDescriptorProtoFields, ISourceCodeInfoLookup, SourceCodeComment, SourceCodeCursor } from "./source-code-info";
import { IStringFormat } from "./string-format";
import { ITypeNameLookup } from "./type-names";
export declare class DescriptorRegistry implements IDescriptorTree, ITypeNameLookup, ISourceCodeInfoLookup, IStringFormat, IDescriptorInfo {
private readonly tree;
private readonly typeNames;
private readonly sourceCode;
private readonly stringFormat;
private readonly descriptorInfo;
/**
* Create new registry from a FileDescriptorProto.
*/
static createFrom(file: FileDescriptorProto): DescriptorRegistry;
/**
* Create new registry from a CodeGeneratorRequest.
*/
static createFrom(request: CodeGeneratorRequest): DescriptorRegistry;
constructor(tree: IDescriptorTree, typeNames: ITypeNameLookup, sourceCode: ISourceCodeInfoLookup, stringFormat: IStringFormat, descriptorInfo: IDescriptorInfo);
normalizeTypeName(typeName: string): string;
resolveTypeName(typeName: string): AnyTypeDescriptorProto;
peekTypeName(typeName: string): AnyTypeDescriptorProto | undefined;
makeTypeName(descriptor: AnyTypeDescriptorProto): string;
ancestorsOf(descriptor: AnyDescriptorProto): AnyDescriptorProto[];
fileOf(descriptor: AnyDescriptorProto): FileDescriptorProto;
allFiles(): readonly FileDescriptorProto[];
parentOf(descriptor: FieldDescriptorProto): DescriptorProto;
parentOf(descriptor: AnyDescriptorProto): AnyDescriptorProto | undefined;
parentOf(options: FileOptions): FileDescriptorProto;
parentOf(options: MessageOptions): DescriptorProto;
parentOf(options: FieldOptions): FileDescriptorProto;
parentOf(options: OneofOptions): OneofDescriptorProto;
parentOf(options: EnumOptions): FieldDescriptorProto;
parentOf(options: EnumValueOptions): EnumValueDescriptorProto;
parentOf(options: ServiceOptions): ServiceDescriptorProto;
parentOf(options: MethodOptions): MethodDescriptorProto;
visit(visitor: (descriptor: AnyTypeDescriptorProto) => void): void;
visit(startingFrom: AnyDescriptorProto, visitor: (descriptor: AnyTypeDescriptorProto) => void): void;
visitTypes(visitor: (descriptor: AnyTypeDescriptorProto) => void): void;
visitTypes(startingFrom: AnyDescriptorProto, visitor: (descriptor: AnyTypeDescriptorProto) => void): void;
sourceCodeCursor(descriptor: AnyDescriptorProto): SourceCodeCursor;
sourceCodeComments(descriptor: AnyDescriptorProto): SourceCodeComment;
sourceCodeComments(file: FileDescriptorProto, field: FileDescriptorProtoFields): SourceCodeComment;
formatFieldDeclaration(descriptor: FieldDescriptorProto): string;
formatQualifiedName(descriptor: AnyDescriptorProto, includeFileInfo?: boolean): string;
formatName(descriptor: AnyDescriptorProto): string;
formatEnumValueDeclaration(descriptor: EnumValueDescriptorProto): string;
formatRpcDeclaration(descriptor: MethodDescriptorProto): string;
isExtension(descriptor: FieldDescriptorProto): boolean;
extensionsFor(descriptorOrTypeName: DescriptorProto | string): FieldDescriptorProto[];
getExtensionName(descriptor: FieldDescriptorProto): string;
getFieldCustomJsonName(descriptor: FieldDescriptorProto): string | undefined;
isEnumField(fieldDescriptor: FieldDescriptorProto): boolean;
getEnumFieldEnum(fieldDescriptor: FieldDescriptorProto): EnumDescriptorProto;
isMessageField(fieldDescriptor: FieldDescriptorProto): boolean;
isGroupField(fieldDescriptor: FieldDescriptorProto): boolean;
getMessageFieldMessage(fieldDescriptor: FieldDescriptorProto): DescriptorProto;
isScalarField(fieldDescriptor: FieldDescriptorProto): boolean;
getScalarFieldType(fieldDescriptor: FieldDescriptorProto): ScalarValueType;
isMapField(fieldDescriptor: FieldDescriptorProto): boolean;
getMapKeyType(fieldDescriptor: FieldDescriptorProto): MapFieldKeyType;
getMapValueType(fieldDescriptor: FieldDescriptorProto): DescriptorProto | EnumDescriptorProto | ScalarValueType;
isExplicitlyDeclaredDeprecated(descriptor: AnyDescriptorProto): boolean;
isSyntheticElement(descriptor: AnyDescriptorProto): boolean;
findEnumSharedPrefix(descriptor: EnumDescriptorProto, enumLocalName?: string): string | undefined;
isUserDeclaredOneof(descriptor: FieldDescriptorProto): boolean;
isUserDeclaredOptional(descriptor: FieldDescriptorProto): boolean;
isUserDeclaredRepeated(descriptor: FieldDescriptorProto): boolean;
shouldBePackedRepeated(descriptor: FieldDescriptorProto): boolean;
isFileUsed(file: FileDescriptorProto, inFiles: FileDescriptorProto[]): boolean;
isTypeUsed(type: AnyTypeDescriptorProto, inFiles: FileDescriptorProto[]): boolean;
}

View file

@ -0,0 +1,103 @@
import { DescriptorProto, EnumOptions, EnumValueDescriptorProto, EnumValueOptions, FieldDescriptorProto, FieldOptions, FileDescriptorProto, FileOptions, MessageOptions, MethodDescriptorProto, MethodOptions, OneofDescriptorProto, OneofOptions, ServiceDescriptorProto, ServiceOptions } from "./google/protobuf/descriptor";
import { AnyDescriptorProto, AnyTypeDescriptorProto } from "./descriptor-info";
/**
* Return the logical parent of the given descriptor.
*
* If there is no parent, return `undefined`. This should
* only be the case for `FileDescriptorProto`.
*/
export declare type DescriptorParentFn = (descriptor: AnyDescriptorProto) => AnyDescriptorProto | undefined;
/**
* Can lookup the ancestry of a descriptor.
*/
export interface IDescriptorTree {
/**
* Lists known files.
*/
allFiles(): readonly FileDescriptorProto[];
/**
* Return the immediate parent of the given descriptor.
*
* Returns `undefined` for a file descriptor.
*
* Returns the parent descriptor for an option.
*/
parentOf(descriptor: FieldDescriptorProto): DescriptorProto;
parentOf(descriptor: AnyDescriptorProto): AnyDescriptorProto | undefined;
parentOf(options: FileOptions): FileDescriptorProto;
parentOf(options: MessageOptions): DescriptorProto;
parentOf(options: FieldOptions): FileDescriptorProto;
parentOf(options: OneofOptions): OneofDescriptorProto;
parentOf(options: EnumOptions): FieldDescriptorProto;
parentOf(options: EnumValueOptions): EnumValueDescriptorProto;
parentOf(options: ServiceOptions): ServiceDescriptorProto;
parentOf(options: MethodOptions): MethodDescriptorProto;
/**
* Return the file where the descriptor was declared.
*
* If a file descriptor is passed, returns the
* file descriptor itself.
*/
fileOf(descriptor: AnyDescriptorProto): FileDescriptorProto;
/**
* Returns all ancestors of the given descriptor, up to
* the file descriptor where the descriptor was declared.
*/
ancestorsOf(descriptor: AnyDescriptorProto): AnyDescriptorProto[];
/**
* Visit all known descriptors and all their descendants.
*/
visit(visitor: (descriptor: AnyDescriptorProto) => void): void;
/**
* Visit all descendants of the given descriptor.
*/
visit(startingFrom: AnyDescriptorProto, visitor: (descriptor: AnyDescriptorProto) => void): void;
/**
* Visit all known type descriptors and their
* descendant types.
*/
visitTypes(visitor: (descriptor: AnyTypeDescriptorProto) => void): void;
/**
* Visit the type children of the descriptor
* and their descendant types.
*/
visitTypes(startingFrom: AnyDescriptorProto, visitor: (descriptor: AnyTypeDescriptorProto) => void): void;
}
export declare class DescriptorTree implements IDescriptorTree {
private readonly _files;
private readonly _descriptors;
private readonly _options;
/**
* Create the tree from a list of root files.
*/
static from(...files: FileDescriptorProto[]): DescriptorTree;
private constructor();
ancestorsOf(descriptor: AnyDescriptorProto): AnyDescriptorProto[];
fileOf(descriptor: AnyDescriptorProto): FileDescriptorProto;
allFiles(): readonly FileDescriptorProto[];
parentOf(descriptor: FieldDescriptorProto): DescriptorProto;
parentOf(descriptor: AnyDescriptorProto): AnyDescriptorProto | undefined;
parentOf(options: FileOptions): FileDescriptorProto;
parentOf(options: MessageOptions): DescriptorProto;
parentOf(options: FieldOptions): FileDescriptorProto;
parentOf(options: OneofOptions): OneofDescriptorProto;
parentOf(options: EnumOptions): FieldDescriptorProto;
parentOf(options: EnumValueOptions): EnumValueDescriptorProto;
parentOf(options: ServiceOptions): ServiceDescriptorProto;
parentOf(options: MethodOptions): MethodDescriptorProto;
visit(visitor: (descriptor: AnyDescriptorProto) => void): void;
visit(startingFrom: AnyDescriptorProto, visitor: (descriptor: AnyDescriptorProto) => void): void;
visitTypes(visitor: (descriptor: AnyTypeDescriptorProto) => void): void;
visitTypes(startingFrom: AnyDescriptorProto, visitor: (descriptor: AnyTypeDescriptorProto) => void): void;
}
declare type VisitorFn = (descriptor: AnyDescriptorProto, carry: readonly AnyDescriptorProto[]) => void;
/**
* Visit all logical children of the given descriptor proto.
*
* The "visitor" function is called for each element,
* including the input. It receives two arguments:
* 1) the current descriptor proto
* 2) the ancestors of the current descriptor proto (an array of descriptors)
*/
export declare function visitDescriptorTree(input: AnyDescriptorProto, visitor: VisitorFn): void;
export {};

View file

@ -0,0 +1,7 @@
/**
* A file generated by a plugin. See `PluginBase`.
*/
export interface GeneratedFile {
getFilename(): string;
getContent(): string;
}

View file

@ -0,0 +1,220 @@
import { MessageType } from "@protobuf-ts/runtime";
import { FileDescriptorProto } from "../descriptor";
/**
* The version number of protocol compiler.
*
* @generated from protobuf message google.protobuf.compiler.Version
*/
export interface Version {
/**
* @generated from protobuf field: optional int32 major = 1;
*/
major?: number;
/**
* @generated from protobuf field: optional int32 minor = 2;
*/
minor?: number;
/**
* @generated from protobuf field: optional int32 patch = 3;
*/
patch?: number;
/**
* A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
* be empty for mainline stable releases.
*
* @generated from protobuf field: optional string suffix = 4;
*/
suffix?: string;
}
/**
* An encoded CodeGeneratorRequest is written to the plugin's stdin.
*
* @generated from protobuf message google.protobuf.compiler.CodeGeneratorRequest
*/
export interface CodeGeneratorRequest {
/**
* The .proto files that were explicitly listed on the command-line. The
* code generator should generate code only for these files. Each file's
* descriptor will be included in proto_file, below.
*
* @generated from protobuf field: repeated string file_to_generate = 1;
*/
fileToGenerate: string[];
/**
* The generator parameter passed on the command-line.
*
* @generated from protobuf field: optional string parameter = 2;
*/
parameter?: string;
/**
* FileDescriptorProtos for all files in files_to_generate and everything
* they import. The files will appear in topological order, so each file
* appears before any file that imports it.
*
* protoc guarantees that all proto_files will be written after
* the fields above, even though this is not technically guaranteed by the
* protobuf wire format. This theoretically could allow a plugin to stream
* in the FileDescriptorProtos and handle them one by one rather than read
* the entire set into memory at once. However, as of this writing, this
* is not similarly optimized on protoc's end -- it will store all fields in
* memory at once before sending them to the plugin.
*
* Type names of fields and extensions in the FileDescriptorProto are always
* fully qualified.
*
* @generated from protobuf field: repeated google.protobuf.FileDescriptorProto proto_file = 15;
*/
protoFile: FileDescriptorProto[];
/**
* The version number of protocol compiler.
*
* @generated from protobuf field: optional google.protobuf.compiler.Version compiler_version = 3;
*/
compilerVersion?: Version;
}
/**
* The plugin writes an encoded CodeGeneratorResponse to stdout.
*
* @generated from protobuf message google.protobuf.compiler.CodeGeneratorResponse
*/
export interface CodeGeneratorResponse {
/**
* Error message. If non-empty, code generation failed. The plugin process
* should exit with status code zero even if it reports an error in this way.
*
* This should be used to indicate errors in .proto files which prevent the
* code generator from generating correct code. Errors which indicate a
* problem in protoc itself -- such as the input CodeGeneratorRequest being
* unparseable -- should be reported by writing a message to stderr and
* exiting with a non-zero status code.
*
* @generated from protobuf field: optional string error = 1;
*/
error?: string;
/**
* A bitmask of supported features that the code generator supports.
* This is a bitwise "or" of values from the Feature enum.
*
* @generated from protobuf field: optional uint64 supported_features = 2;
*/
supportedFeatures?: string;
/**
* @generated from protobuf field: repeated google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
*/
file: CodeGeneratorResponse_File[];
}
/**
* Represents a single generated file.
*
* @generated from protobuf message google.protobuf.compiler.CodeGeneratorResponse.File
*/
export interface CodeGeneratorResponse_File {
/**
* The file name, relative to the output directory. The name must not
* contain "." or ".." components and must be relative, not be absolute (so,
* the file cannot lie outside the output directory). "/" must be used as
* the path separator, not "\".
*
* If the name is omitted, the content will be appended to the previous
* file. This allows the generator to break large files into small chunks,
* and allows the generated text to be streamed back to protoc so that large
* files need not reside completely in memory at one time. Note that as of
* this writing protoc does not optimize for this -- it will read the entire
* CodeGeneratorResponse before writing files to disk.
*
* @generated from protobuf field: optional string name = 1;
*/
name?: string;
/**
* If non-empty, indicates that the named file should already exist, and the
* content here is to be inserted into that file at a defined insertion
* point. This feature allows a code generator to extend the output
* produced by another code generator. The original generator may provide
* insertion points by placing special annotations in the file that look
* like:
* @@protoc_insertion_point(NAME)
* The annotation can have arbitrary text before and after it on the line,
* which allows it to be placed in a comment. NAME should be replaced with
* an identifier naming the point -- this is what other generators will use
* as the insertion_point. Code inserted at this point will be placed
* immediately above the line containing the insertion point (thus multiple
* insertions to the same point will come out in the order they were added).
* The double-@ is intended to make it unlikely that the generated code
* could contain things that look like insertion points by accident.
*
* For example, the C++ code generator places the following line in the
* .pb.h files that it generates:
* // @@protoc_insertion_point(namespace_scope)
* This line appears within the scope of the file's package namespace, but
* outside of any particular class. Another plugin can then specify the
* insertion_point "namespace_scope" to generate additional classes or
* other declarations that should be placed in this scope.
*
* Note that if the line containing the insertion point begins with
* whitespace, the same whitespace will be added to every line of the
* inserted text. This is useful for languages like Python, where
* indentation matters. In these languages, the insertion point comment
* should be indented the same amount as any inserted code will need to be
* in order to work correctly in that context.
*
* The code generator that generates the initial file and the one which
* inserts into it must both run as part of a single invocation of protoc.
* Code generators are executed in the order in which they appear on the
* command line.
*
* If |insertion_point| is present, |name| must also be present.
*
* @generated from protobuf field: optional string insertion_point = 2;
*/
insertionPoint?: string;
/**
* The file contents.
*
* @generated from protobuf field: optional string content = 15;
*/
content?: string;
}
/**
* Sync with code_generator.h.
*
* @generated from protobuf enum google.protobuf.compiler.CodeGeneratorResponse.Feature
*/
export declare enum CodeGeneratorResponse_Feature {
/**
* @generated from protobuf enum value: FEATURE_NONE = 0;
*/
NONE = 0,
/**
* @generated from protobuf enum value: FEATURE_PROTO3_OPTIONAL = 1;
*/
PROTO3_OPTIONAL = 1
}
/**
* Type for protobuf message google.protobuf.compiler.Version
*/
declare class Version$Type extends MessageType<Version> {
constructor();
}
export declare const Version: Version$Type;
/**
* Type for protobuf message google.protobuf.compiler.CodeGeneratorRequest
*/
declare class CodeGeneratorRequest$Type extends MessageType<CodeGeneratorRequest> {
constructor();
}
export declare const CodeGeneratorRequest: CodeGeneratorRequest$Type;
/**
* Type for protobuf message google.protobuf.compiler.CodeGeneratorResponse
*/
declare class CodeGeneratorResponse$Type extends MessageType<CodeGeneratorResponse> {
constructor();
}
export declare const CodeGeneratorResponse: CodeGeneratorResponse$Type;
/**
* Type for protobuf message google.protobuf.compiler.CodeGeneratorResponse.File
*/
declare class CodeGeneratorResponse_File$Type extends MessageType<CodeGeneratorResponse_File> {
constructor();
}
export declare const CodeGeneratorResponse_File: CodeGeneratorResponse_File$Type;
export {};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,19 @@
export * from './descriptor-info';
export * from './descriptor-registry';
export * from './descriptor-tree';
export * from './generated-file';
export * from './plugin-base';
export * from './source-code-info';
export * from './string-format';
export * from './symbol-table';
export * from './type-names';
export * from './google/protobuf/descriptor';
export * from './google/protobuf/compiler/plugin';
export * from './typescript-compile';
export * from './typescript-comments';
export * from './typescript-import-manager';
export * from './typescript-method-from-text';
export * from './typescript-literal-from-value';
export * from './typescript-enum-builder';
export * from "./typescript-file";
export * from "./typescript-imports";

View file

@ -0,0 +1,69 @@
/// <reference types="node" />
import { CodeGeneratorRequest, CodeGeneratorResponse, CodeGeneratorResponse_Feature } from "./google/protobuf/compiler/plugin";
import { ReadStream } from "tty";
import { GeneratedFile } from "./generated-file";
export declare type OptionsSpec = {
[key: string]: {
description: string;
excludes?: string[];
requires?: string[];
};
};
export declare type ResolvedOptions<T extends OptionsSpec> = {
[P in keyof T]: boolean;
};
/**
* Base class for a protobuf plugin.
*
* Implement the abstract `generate()` method to create a plugin.
* The method takes a `CodeGeneratorRequest` and returns an
* array of `GeneratedFile` or a promise thereof.
*
*
* Usage:
*
* #!/usr/bin/env node
* const {MyPlugin} = require( ... );
* new MyPlugin.run().catch(_ => {
* process.stderr.write('failed to run plugin');
* process.exit(1);
* });
*
* Reads a `CodeGeneratorRequest` created by `protoc` from stdin,
* passes it to the plugin-function and writes a
* `CodeGeneratorResponse` to stdout.
*
*
* Options:
*
* Use the `parseOptions()` method the parse the parameter
* of a `CodeGeneratorRequest` to a map of flags. Options are
* validated and usage is generated on error.
*
*
* Error handling:
*
* `generate()` may raise an error, reject it's promise or
* return an `GeneratedFile` with an attached error.
*
* Throwing `new Error("hello")` will result in the output:
*
* $ protoc --xx_out=/tmp -I protos protos/*
* --xx_out: Error: hello
* at /path/to/your-plugin.js:69
* ...
*
*
*/
export declare abstract class PluginBase<T extends GeneratedFile = GeneratedFile> {
abstract generate(request: CodeGeneratorRequest): Promise<T[]> | T[];
run(): Promise<void>;
protected getSupportedFeatures(): CodeGeneratorResponse_Feature[];
protected parseOptions<T extends OptionsSpec>(spec: T, parameter: string | undefined): ResolvedOptions<T>;
private throwOptionError;
private validateOptionsSpec;
protected readBytes(stream: ReadStream): Promise<Uint8Array>;
protected createResponse(files: GeneratedFile[]): CodeGeneratorResponse;
protected errorToString(error: any): string;
private setBlockingStdout;
}

View file

@ -0,0 +1,102 @@
import { FileDescriptorProto, SourceCodeInfo_Location } from "./google/protobuf/descriptor";
import { AnyDescriptorProto } from "./descriptor-info";
import { DescriptorParentFn } from "./descriptor-tree";
export interface ISourceCodeInfoLookup {
/**
* Return the comments for the given descriptor.
*
* If no comments found, empty (not undefined) object
* is returned.
*
* Trailing newlines are removed.
*/
sourceCodeComments(descriptor: AnyDescriptorProto): SourceCodeComment;
/**
* Return the comments for the specified element
* of the file descriptor.
*/
sourceCodeComments(file: FileDescriptorProto, field: FileDescriptorProtoFields): SourceCodeComment;
/**
* Return cursor position of the given element in the source
* code as line number and column, both starting at 1.
*/
sourceCodeCursor(descriptor: AnyDescriptorProto): SourceCodeCursor;
}
export declare class SourceCodeInfoLookup implements ISourceCodeInfoLookup {
private readonly _parentResolver;
constructor(parentResolver: DescriptorParentFn);
sourceCodeCursor(descriptor: AnyDescriptorProto): SourceCodeCursor;
sourceCodeComments(file: FileDescriptorProto, field: FileDescriptorProtoFields): SourceCodeComment;
sourceCodeComments(descriptor: AnyDescriptorProto): SourceCodeComment;
private _findFile;
}
/**
* Return cursor position of the given source code location
* as line number and column, both starting at 1.
*
* If more than one location is given, only the first one
* is evaluated, the others are discarded.
*/
export declare function sourceCodeLocationToCursor(locations: readonly SourceCodeInfo_Location[]): SourceCodeCursor;
/**
* Represents line number and column within a source file,
* both starting at 1.
*/
export declare type SourceCodeCursor = readonly [number, number] | typeof emptyCursor;
declare const emptyCursor: readonly [undefined, undefined];
/**
* Return the comments for the given source code location.
*
* If more than one location is given, only the first one
* is evaluated, the others are discarded.
*
* If no comments found, empty (not undefined) object
* is returned.
*
* Trailing newlines are removed.
*/
export declare function sourceCodeLocationToComment(locations: readonly SourceCodeInfo_Location[]): SourceCodeComment;
/**
* Comments for a specific source code location.
*/
export declare type SourceCodeComment = {
readonly leadingDetached: readonly string[];
readonly leading: string | undefined;
readonly trailing: string | undefined;
};
/**
* Find the source code locations that match the given path.
*/
export declare function filterSourceCodeLocations(locations: readonly SourceCodeInfo_Location[], path: readonly number[]): SourceCodeInfo_Location[];
/**
* Create the path to the source code location where the
* given element was declared.
*
* Returns `undefined` if we don't know how to make the path.
*
* For example, the path [4, 0, 2, 3] points to the 4th field
* of the first message of a .proto file:
*
* file
* .messageType // FileDescriptorProto.message_type = 3;
* [0] // first message
* .field // FileDescriptorProto.field = 2;
* [3] // 4th field
*
* See https://github.com/protocolbuffers/protobuf/blob/f1ce8663ac88df54cf212d29ce5123b69203b135/src/google/protobuf/descriptor.proto#L799
*/
export declare function makeSourceCodePath(parentProvider: DescriptorParentFn, descriptor: AnyDescriptorProto): number[] | undefined;
/**
* Make a path from the parent to the immediate child.
*
* Returns `undefined` if we don't know how to make the path.
*/
export declare function makeSourceCodePathComponent(parent: AnyDescriptorProto, child: AnyDescriptorProto): readonly [number, number] | undefined;
export declare enum FileDescriptorProtoFields {
syntax = 12,
package = 2,
message_type = 4,
enum_type = 5,
service = 6
}
export {};

View file

@ -0,0 +1,89 @@
import { EnumValueDescriptorProto, FieldDescriptorProto, MethodDescriptorProto } from "./google/protobuf/descriptor";
import { AnyDescriptorProto, IDescriptorInfo, ScalarValueType } from "./descriptor-info";
import { IDescriptorTree } from "./descriptor-tree";
import { ISourceCodeInfoLookup } from "./source-code-info";
import { ITypeNameLookup } from "./type-names";
export interface IStringFormat {
/**
* Returns type ('message', 'field', etc.) and descriptor name.
*
* Examples:
* message Bar
* field value = 2
* rpc Fetch()
*/
formatName(descriptor: AnyDescriptorProto): string;
/**
* Returns qualified name, consisting of:
* - keyword like "message", "enum", etc. followed by " "
* - package name followed by "."
* - parent type descriptor names separated by "."
* - descriptor name
*
* Examples:
* message .foo.Bar
* field .foo.Bar.value = 2
* rpc .foo.Service.Fetch()
*
* If `includeFileInfo` is set, the name of the file containing
* the descriptor is added, including line number.
*/
formatQualifiedName(descriptor: AnyDescriptorProto, includeFileInfo?: boolean): string;
/**
* Returns field declaration, similar to how it appeared
* in the .proto file.
*
* Examples:
* repeated string foo = 1 [deprecated = true];
* .foo.Bar bar = 2 [json_name = "baz"];
* map<string, .foo.Bar> map = 3;
* uint64 foo = 4 [jstype = JS_NUMBER];
*/
formatFieldDeclaration(descriptor: FieldDescriptorProto): string;
/**
* Returns declaration of enum value, similar to how it
* appeared in the .proto file.
*
* Examples:
* STATE_UNKNOWN = 0;
* STATE_READY = 1 [deprecated = true];
*/
formatEnumValueDeclaration(descriptor: EnumValueDescriptorProto): string;
/**
* Returns declaration of an rpc method, similar to how
* it appeared in the .proto file, but does not show any options.
*
* Examples:
* rpc Fetch(FetchRequest) returns (stream FetchResponse);
*/
formatRpcDeclaration(descriptor: MethodDescriptorProto): string;
}
export declare class StringFormat implements IStringFormat {
private readonly nameLookup;
private readonly treeLookup;
private readonly sourceCodeLookup;
private readonly descriptorInfo;
constructor(lookup: ITypeNameLookup & IDescriptorTree & ISourceCodeInfoLookup & IDescriptorInfo);
constructor(nameLookup: ITypeNameLookup, treeLookup: IDescriptorTree, sourceCodeLookup: ISourceCodeInfoLookup, descriptorInfo: IDescriptorInfo);
/**
* Returns name of a scalar value type like it would
* appear in a .proto.
*
* For example, `FieldDescriptorProto_Type.UINT32` -> `"uint32"`.
*/
static formatScalarType(type: ScalarValueType): string;
/**
* Returns type ('message', 'field', etc.) and descriptor name.
*
* Examples:
* message Bar
* field value = 2
* rpc Fetch()
*/
static formatName(descriptor: AnyDescriptorProto): string;
formatQualifiedName(descriptor: AnyDescriptorProto, includeFileInfo: boolean): string;
formatName(descriptor: AnyDescriptorProto): string;
formatFieldDeclaration(descriptor: FieldDescriptorProto): string;
formatEnumValueDeclaration(descriptor: EnumValueDescriptorProto): string;
formatRpcDeclaration(descriptor: MethodDescriptorProto): string;
}

View file

@ -0,0 +1,60 @@
import { AnyTypeDescriptorProto } from "./descriptor-info";
import { GeneratedFile } from "./generated-file";
/**
* A table for unique symbols (for any DescriptorProto, EnumDescriptorProto
* or ServiceDescriptorProto) in files (GeneratedFile).
*/
export declare class SymbolTable {
private readonly entries;
private readonly clashResolveMaxTries;
private readonly clashResolver;
constructor(clashResolver?: ClashResolver);
/**
* Register a symbol in the given file for the given descriptor.
*
* If the name is already taken in the file, an alternative name
* is automatically generated by appending '$' and a running
* number to the requested name. You can change the behaviour by
* providing your own `clashResolver`.
*
* Only one symbol per kind can be registered for a descriptor.
*
* If you want to generate an interface *and* a class for a
* message, use a different `kind` for each.
*
* Returns the actual name registered.
*/
register(requestedName: string, descriptor: AnyTypeDescriptorProto, file: GeneratedFile, kind?: string): string;
/**
* Find a symbol (of the given kind) for the given descriptor.
* Return `undefined` if not found.
*/
find(descriptor: AnyTypeDescriptorProto, kind?: string): SymbolTableEntry | undefined;
/**
* Find a symbol (of the given kind) for the given descriptor.
* Raises error if not found.
*/
get(descriptor: AnyTypeDescriptorProto, kind?: string): SymbolTableEntry;
/**
* Is a name (of the given kind) registered for the the given descriptor?
*/
has(descriptor: AnyTypeDescriptorProto, kind?: string): boolean;
/**
* List all names of any kind registered in the given file.
*/
list(file: GeneratedFile): SymbolTableEntry[];
/**
* List all names of the given kind registered in the given file.
*/
list(file: GeneratedFile, kind: string): SymbolTableEntry[];
protected hasNameInFile: (name: string, file: GeneratedFile) => boolean;
static defaultClashResolver(descriptor: AnyTypeDescriptorProto, file: GeneratedFile, requestedName: string, kind: string, tryCount: number): string;
}
interface SymbolTableEntry {
file: GeneratedFile;
descriptor: AnyTypeDescriptorProto;
name: string;
kind: string;
}
declare type ClashResolver = (descriptor: AnyTypeDescriptorProto, file: GeneratedFile, requestedName: string, kind: string, tryCount: number, failedName: string) => string;
export {};

View file

@ -0,0 +1,49 @@
import { AnyDescriptorProto, AnyTypeDescriptorProto } from "./descriptor-info";
import { DescriptorParentFn, IDescriptorTree } from "./descriptor-tree";
/**
* Can lookup a type name.
*
* Type names are normalized, the leading period generated by
* protoc is removed.
*/
export interface ITypeNameLookup {
/**
* Removes leading period from name.
*/
normalizeTypeName(typeName: string): string;
/**
* Return the descriptor for the given type name.
*
* Throws if not found.
*/
resolveTypeName(typeName: string): AnyTypeDescriptorProto;
/**
* Return the descriptor for the given type name - or `undefined`.
*/
peekTypeName(typeName: string): AnyTypeDescriptorProto | undefined;
/**
* Get the type name for the given descriptor.
*/
makeTypeName(descriptor: AnyTypeDescriptorProto): string;
}
export declare class TypeNameLookup implements ITypeNameLookup {
/**
* Create the lookup from a list of descriptors and a function
* that provides the parent of a descriptor.
*/
static from(descriptors: AnyDescriptorProto[], parentProvider: DescriptorParentFn): TypeNameLookup;
/**
* Create the lookup from an existing tree.
*/
static from(tree: IDescriptorTree): TypeNameLookup;
private readonly _names;
private readonly _reverse;
constructor(data: Array<{
descriptor: AnyTypeDescriptorProto;
ancestors: AnyDescriptorProto[];
}>);
normalizeTypeName(typeName: string): string;
resolveTypeName(typeName: string): AnyTypeDescriptorProto;
peekTypeName(typeName: string): AnyTypeDescriptorProto | undefined;
makeTypeName(descriptor: AnyTypeDescriptorProto): string;
}

View file

@ -0,0 +1,22 @@
import * as ts from "typescript";
/**
* Adds multiple comment blocks as line comments
* in front of the given node.
*
* Applies a dirty hack to enforce newlines
* between each block.
*/
export declare function addCommentBlocksAsLeadingDetachedLines<T extends ts.Node>(node: T, ...texts: string[]): void;
/**
* Adds a JSDoc comment block in front of the given node.
*
* A JSDoc comment looks like this:
* /**
* * body text
* *\/
*
* A regular block comment looks like this:
* /* body text *\/
*
*/
export declare function addCommentBlockAsJsDoc<T extends ts.Node>(node: T, text: string): void;

View file

@ -0,0 +1,24 @@
import * as ts from "typescript";
import { GeneratedFile } from "./generated-file";
export declare function setupCompiler(options: ts.CompilerOptions, files: GeneratedFile[], rootFileNames: string[]): [ts.Program, VirtualCompilerHost];
declare class VirtualCompilerHost implements ts.CompilerHost {
private readonly wrapped;
private readonly _sourceFiles;
private readonly _files;
private readonly _dirs;
constructor(wrapped: ts.CompilerHost, files: readonly GeneratedFile[]);
protected lookupVirtualFile(fileName: string): GeneratedFile | undefined;
protected lookupVirtualDirectory(directoryName: string): boolean;
getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): ts.SourceFile | undefined;
getDefaultLibFileName(options: ts.CompilerOptions): string;
writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void, sourceFiles?: readonly ts.SourceFile[]): void;
getCurrentDirectory(): string;
getCanonicalFileName(fileName: string): string;
useCaseSensitiveFileNames(): boolean;
getNewLine(): string;
fileExists(fileName: string): boolean;
readFile(fileName: string): string | undefined;
directoryExists(directoryName: string): boolean;
getDirectories(path: string): string[];
}
export {};

View file

@ -0,0 +1,10 @@
import * as ts from "typescript";
/**
* Creates an enum declaration.
*/
export declare class TypescriptEnumBuilder {
private readonly values;
add(name: string, number: number, comment?: string): void;
build(name: string | ts.Identifier, modifiers?: readonly ts.Modifier[]): ts.EnumDeclaration;
private validate;
}

View file

@ -0,0 +1,23 @@
import * as ts from "typescript";
export declare class TypescriptFile {
private sf;
constructor(filename: string);
getFilename(): string;
/**
* Add the new statement to the file.
*/
addStatement(statement: ts.Statement, atTop?: boolean): void;
/**
* The underlying SourceFile
*/
getSourceFile(): ts.SourceFile;
/**
* Are there any statements in this file?
*/
isEmpty(): boolean;
/**
* The full content of this file.
* Returns an empty string if there are no statements.
*/
getContent(): string;
}

View file

@ -0,0 +1,39 @@
import { GeneratedFile } from "./generated-file";
import { SymbolTable } from "./symbol-table";
import { AnyTypeDescriptorProto } from "./descriptor-info";
import { TypescriptFile } from "./typescript-file";
/** @deprecated */
export declare class TypescriptImportManager {
private readonly file;
private readonly symbols;
private readonly source;
constructor(generatedFile: GeneratedFile, symbols: SymbolTable, source: TypescriptFile);
/**
* Import {importName} from "importFrom";
*
* Automatically finds a free name if the
* `importName` would collide with another
* identifier.
*
* Returns imported name.
*/
name(importName: string, importFrom: string): string;
/**
* Import * as importAs from "importFrom";
*
* Returns name for `importAs`.
*/
namespace(importAs: string, importFrom: string): string;
/**
* Import a previously registered identifier for a message
* or other descriptor.
*
* Uses the symbol table to look for the type, adds an
* import statement if necessary and automatically finds a
* free name if the identifier would clash in this file.
*
* If you have multiple representations for a descriptor
* in your generated code, use `kind` to discriminate.
*/
type(descriptor: AnyTypeDescriptorProto, kind?: string): string;
}

View file

@ -0,0 +1,74 @@
import * as ts from "typescript";
import { SymbolTable } from "./symbol-table";
import { AnyTypeDescriptorProto } from "./descriptor-info";
import { TypescriptFile } from "./typescript-file";
export declare class TypeScriptImports {
private readonly symbols;
constructor(symbols: SymbolTable);
/**
* Import {importName} from "importFrom";
*
* Automatically finds a free name if the
* `importName` would collide with another
* identifier.
*
* Returns imported name.
*/
name(source: TypescriptFile, importName: string, importFrom: string, isTypeOnly?: boolean): string;
/**
* Import * as importAs from "importFrom";
*
* Returns name for `importAs`.
*/
namespace(source: TypescriptFile, importAs: string, importFrom: string, isTypeOnly?: boolean): string;
/**
* Import a previously registered identifier for a message
* or other descriptor.
*
* Uses the symbol table to look for the type, adds an
* import statement if necessary and automatically finds a
* free name if the identifier would clash in this file.
*
* If you have multiple representations for a descriptor
* in your generated code, use `kind` to discriminate.
*/
type(source: TypescriptFile, descriptor: AnyTypeDescriptorProto, kind?: string, isTypeOnly?: boolean): string;
}
/**
* import {importName} from "importFrom";
* import type {importName} from "importFrom";
*
* If the import is already present, just return the
* identifier.
*
* If the import is not present, create the import
* statement and call `addStatementFn`.
*
* If the import name is taken by another named import
* or is in the list of blacklisted names, an
* alternative name is used:
*
* Import {importName as alternativeName} from "importFrom";
*
* Returns the imported name or the alternative name.
*/
export declare function ensureNamedImportPresent(currentFile: ts.SourceFile, importName: string, importFrom: string, isTypeOnly: boolean, blacklistedNames: string[], addStatementFn: (statementToAdd: ts.ImportDeclaration) => void, escapeCharacter?: string): string;
/**
* import {<name>} from '<from>';
* import {<name> as <as>} from '<from>';
* import type {<name>} from '<from>';
* import type {<name> as <as>} from '<from>';
*/
export declare function createNamedImport(name: string, from: string, as?: string, isTypeOnly?: boolean): ts.ImportDeclaration;
/**
* import {<name>} from '<from>';
* import {<name> as <as>} from '<from>';
* import type {<name>} from '<from>';
* import type {<name> as <as>} from '<from>';
*/
export declare function findNamedImports(sourceFile: ts.SourceFile): {
name: string;
as: string | undefined;
from: string;
isTypeOnly: boolean;
}[];

View file

@ -0,0 +1,17 @@
import * as ts from "typescript";
export declare type SimpleJsValue = string | number | bigint | boolean | undefined | null | SimpleJsValue[] | {
[k: string]: SimpleJsValue;
} | TypedArray;
declare type TypedArray = Uint8Array | Int8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array;
/**
* Creates nodes for simple JavaScript values.
*
* Simple JavaScript values include:
* - all primitives: number, bigint, string, boolean
* - undefined, null
* - plain objects containing only simple JavaScript values
* - arrays containing only simple JavaScript values
* - typed arrays
*/
export declare function typescriptLiteralFromValue(value: SimpleJsValue): ts.Expression;
export {};

View file

@ -0,0 +1,6 @@
import * as ts from "typescript";
/**
* Provide a function statement as plain text, receive a
* method declaration.
*/
export declare function typescriptMethodFromText(functionText: string): ts.MethodDeclaration;