forked from stephenh/ts-proto
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplugin.ts
95 lines (83 loc) · 3.37 KB
/
plugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import {
CodeGeneratorRequest,
CodeGeneratorResponse,
CodeGeneratorResponse_Feature,
FileDescriptorProto,
} from "ts-proto-descriptors";
import { promisify } from "util";
import { generateIndexFiles, getVersions, protoFilesToGenerate, readToBuffer } from "./utils";
import { generateFile, makeUtils } from "./main";
import { createTypeMap } from "./types";
import { BaseContext, createFileContext } from "./context";
import { getTsPoetOpts, optionsFromParameter } from "./options";
import { generateTypeRegistry } from "./generate-type-registry";
// this would be the plugin called by the protoc compiler
async function main() {
const stdin = await readToBuffer(process.stdin);
// const json = JSON.parse(stdin.toString());
// const request = CodeGeneratorRequest.fromObject(json);
const request = CodeGeneratorRequest.decode(stdin);
const { protocVersion, tsProtoVersion } = await getVersions(request);
const options = optionsFromParameter(request.parameter);
const typeMap = createTypeMap(request, options);
const utils = makeUtils(options);
const ctx: BaseContext = { typeMap, options, utils };
let filesToGenerate: FileDescriptorProto[];
if (options.emitImportedFiles) {
const fileSet = new Set();
function addFilesUnlessAliased(filenames: string[]) {
filenames
.filter((name) => !options.M[name])
.forEach((name) => {
if (fileSet.has(name)) return;
fileSet.add(name);
const file = request.protoFile.find((file) => file.name === name);
if (file && file.dependency.length > 0) {
addFilesUnlessAliased(file.dependency);
}
});
}
addFilesUnlessAliased(request.fileToGenerate);
filesToGenerate = request.protoFile.filter((file) => fileSet.has(file.name));
} else {
filesToGenerate = protoFilesToGenerate(request).filter((file) => !options.M[file.name]);
}
const files = await Promise.all(
filesToGenerate.map(async (file) => {
const [path, code] = generateFile({ ...ctx, currentFile: createFileContext(file) }, file);
const content = code.toString({ ...getTsPoetOpts(options, tsProtoVersion, protocVersion, file.name), path });
return { name: path, content };
}),
);
if (options.outputTypeRegistry) {
const utils = makeUtils(options);
const ctx: BaseContext = { options, typeMap, utils };
const path = "typeRegistry.ts";
const code = generateTypeRegistry(ctx);
const content = code.toString({ ...getTsPoetOpts(options, tsProtoVersion, protocVersion), path });
files.push({ name: path, content });
}
if (options.outputIndex) {
for (const [path, code] of generateIndexFiles(filesToGenerate, options)) {
const content = code.toString({ ...getTsPoetOpts(options, tsProtoVersion, protocVersion), path });
files.push({ name: path, content });
}
}
const response = CodeGeneratorResponse.fromPartial({
file: files,
supportedFeatures: CodeGeneratorResponse_Feature.FEATURE_PROTO3_OPTIONAL,
});
const buffer = CodeGeneratorResponse.encode(response).finish();
const write = promisify(process.stdout.write as (buffer: Buffer) => boolean).bind(process.stdout);
await write(Buffer.from(buffer));
}
main()
.then(() => {
process.exit(0);
})
.catch((e) => {
process.stderr.write("FAILED!");
process.stderr.write(e.message);
process.stderr.write(e.stack);
process.exit(1);
});