initial commit of actions

This commit is contained in:
Dominik Polakovics Polakovics 2026-01-31 18:56:04 +01:00
commit 949ece5785
44660 changed files with 12034344 additions and 0 deletions

View file

@ -0,0 +1,174 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.

View file

@ -0,0 +1,61 @@
@protobuf-ts/plugin-framework
=============================
A framework to create protoc plugins in typescript.
The google protocol buffer compiler (protoc) has a plugin system. With a
protoc plugin, it is possible to generate code for .proto files in any
language, not just the ones supported directly by protoc.
A protoc plugin receives a `CodeGeneratorRequest` (a protobuf message)
via stdin and returns a `CodeGeneratorResponse` via stdout.
This framework aims to make it as easy as possible to write a protoc
plugin in typescript. It has special support for generating typescript
code, but can be used to generate code in other languages.
### Features
- provides a symbol table that can be used to track generated types
in any language
- has special support for generating typescript code using the
typescript compiler API. For example, it has a simple API to import
objects from a package, or from the symbol table.
- provides a base class for plugins that supports parameters, error
handling, supported features and easy setup.
- builds a tree of descriptors so that it is trivial to lookup the
parent of a nested message, for example.
- builds a lookup object to find the descriptor for a given type name
- provides a string format object that can print a message field like
it was typed by the user.
- provides a source code comment lookup that can be used to easily
find comments for a given element in a .proto
- provides convenience methods to check if a field was declared
optional or as a oneof member
### Getting started
- Check the types and comments of [descriptor.proto](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/descriptor.proto)
and [plugin.proto](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/compiler/plugin.proto)
to get familiar with the plugin system of protoc.
- Take a look at `descriptor-registry.ts` to see the if it can help you work with the
descriptor protos that the compiler sends you.
- Take a look at `plugin-base.ts` for a base class that can help with some plumbing.
- Take a look at the source code of [protobuf-ts](https://github.com/timostamm/protobuf-ts/), which uses this framework.
### Copyright
- The files [plugin.ts](https://github.com/timostamm/protobuf-ts/blob/master/packages/plugin-framework/src/google/protobuf/compiler/plugin.ts) and [descriptor.ts](https://github.com/timostamm/protobuf-ts/blob/master/packages/plugin-framework/src/google/protobuf/descriptor.ts) are Copyright 2008 Google Inc., licensed under BSD-3-Clause
- All other files are licensed under Apache-2.0, see [LICENSE](https://github.com/timostamm/protobuf-ts/blob/master/packages/plugin-framework/LICENSE).

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 {};

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;

View file

@ -0,0 +1,40 @@
{
"name": "@protobuf-ts/plugin-framework",
"version": "2.9.3",
"description": "framework to create protoc plugins",
"license": "(Apache-2.0 AND BSD-3-Clause)",
"author": "Timo Stamm <ts@timostamm.com>",
"homepage": "https://github.com/timostamm/protobuf-ts",
"keywords": [
"Protocol Buffers",
"protobuf",
"TypeScript",
"protoc"
],
"repository": {
"type": "git",
"url": "https://github.com/timostamm/protobuf-ts.git",
"directory": "packages/plugin-framework"
},
"publishConfig": {
"access": "public"
},
"main": "./build/commonjs/index.js",
"module": "./build/es2015/index.js",
"typings": "./build/types/index.d.ts",
"sideEffects": false,
"devDependencies": {
"@types/jasmine": "^3.5.10",
"@types/node": "^14.0.13",
"jasmine": "^3.5.0",
"jasmine-spec-reporter": "^5.0.2",
"ts-node": "^8.10.2",
"tsconfig-paths": "^3.9.0",
"tslib": ">=1.6.1"
},
"dependencies": {
"@protobuf-ts/runtime": "^2.9.3",
"typescript": "^3.9"
},
"gitHead": "bbda0c30ecc8e826c07a41105e93e05dbb9638b2"
}