UNPKG

@azure-tools/typespec-java

Version:

TypeSpec library for emitting Java client from the TypeSpec REST protocol binding

167 lines 7.66 kB
import { getNormalizedAbsolutePath, NoTarget, resolvePath, } from "@typespec/compiler"; import { promises } from "fs"; import { dump } from "js-yaml"; import { dirname } from "path"; import { fileURLToPath } from "url"; import { CodeModelBuilder } from "./code-model-builder.js"; import { LibName, reportDiagnostic } from "./lib.js"; import { DiagnosticError, spawnAsync, SpawnError, trace } from "./utils.js"; import { validateDependencies } from "./validate.js"; export async function $onEmit(context) { var _a, _b, _c, _d, _e, _f, _g, _h, _j; const program = context.program; if (!program.compilerOptions.noEmit) { await validateDependencies(program, true); } if (!program.hasError()) { const options = context.options; if (!options["flavor"]) { if (LibName === "@azure-tools/typespec-java") { options["flavor"] = "azure"; } } let codeModel; try { const builder = new CodeModelBuilder(program, context); codeModel = await builder.build(); } catch (error) { if (error instanceof DiagnosticError) { // diagnostic thrown as error program.reportDiagnostic(error.diagnostic); } else { // unknown error reportDiagnostic(program, { code: "unknown-error", format: { errorMessage: `The emitter was unable to generate client code from this TypeSpec, please open an issue on https://github.com/microsoft/typespec, include TypeSpec source and all the diagnostic information in your submission.\nStack: error.stack`, }, target: NoTarget, }); trace(program, error.stack); } } if (codeModel && !program.hasError() && !program.compilerOptions.noEmit) { const __dirname = dirname(fileURLToPath(import.meta.url)); const moduleRoot = resolvePath(__dirname, "..", ".."); const outputPath = context.emitterOutputDir; options["output-dir"] = getNormalizedAbsolutePath(outputPath, undefined); options.arm = codeModel.arm; if ((_c = (_b = (_a = codeModel.info) === null || _a === void 0 ? void 0 : _a.license) === null || _b === void 0 ? void 0 : _b.extensions) === null || _c === void 0 ? void 0 : _c.header) { options["license-header"] = codeModel.info.license.extensions.header; } const codeModelFileName = resolvePath(outputPath, "./code-model.yaml"); await promises.mkdir(outputPath, { recursive: true }).catch((err) => { if (err.code !== "EISDIR" && err.code !== "EEXIST") { reportDiagnostic(program, { code: "unknown-error", format: { errorMessage: `Failed to create output directory: ${outputPath}.` }, target: NoTarget, }); return; } }); await program.host.writeFile(codeModelFileName, dump(codeModel)); trace(program, `Code model file written to ${codeModelFileName}`); const emitterOptions = JSON.stringify(options); trace(program, `Emitter options ${emitterOptions}`); const jarFileName = resolvePath(moduleRoot, "generator/http-client-generator/target", "emitter.jar"); trace(program, `Exec JAR ${jarFileName}`); const javaArgs = []; javaArgs.push(`-DemitterOptions=${emitterOptions}`); if ((_d = options["dev-options"]) === null || _d === void 0 ? void 0 : _d.debug) { javaArgs.push("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005"); } if ((_e = options["dev-options"]) === null || _e === void 0 ? void 0 : _e.loglevel) { javaArgs.push("-Dorg.slf4j.simpleLogger.defaultLogLevel=" + ((_f = options["dev-options"]) === null || _f === void 0 ? void 0 : _f.loglevel)); } if ((_g = options["dev-options"]) === null || _g === void 0 ? void 0 : _g["java-temp-dir"]) { javaArgs.push("-Dcodegen.java.temp.directory=" + ((_h = options["dev-options"]) === null || _h === void 0 ? void 0 : _h["java-temp-dir"])); } javaArgs.push("-jar"); javaArgs.push(jarFileName); javaArgs.push(codeModelFileName); try { const result = await spawnAsync("java", javaArgs, { stdio: "pipe" }); reportJarOutput(program, result.stdout); // trace(program, `Code generation log: ${result.stdout}`); } catch (error) { if (error && "code" in error && error["code"] === "ENOENT") { reportDiagnostic(program, { code: "invalid-java-sdk-dependency", target: NoTarget, }); } else { if (error instanceof SpawnError) { reportJarOutput(program, error.stdout); // trace(program, `Code generation log: ${error.stdout}`); } // error in Java codegen, report as unknown error reportDiagnostic(program, { code: "unknown-error", format: { errorMessage: `The emitter was unable to generate client code from this TypeSpec, please open an issue on https://github.com/microsoft/typespec, include TypeSpec source and all the diagnostic information in your submission.`, }, target: NoTarget, }); } } if (!((_j = options["dev-options"]) === null || _j === void 0 ? void 0 : _j["generate-code-model"])) { await program.host.rm(codeModelFileName); } } } } function reportJarOutput(program, jarOutput) { const lines = jarOutput.split("\n"); const logs = []; // parse stdout to array of logs let currentLog = undefined; for (const line of lines) { if (line.startsWith("TRACE ") || line.startsWith("DEBUG ") || line.startsWith("INFO ") || line.startsWith("WARN ") || line.startsWith("ERROR ")) { if (currentLog) { logs.push(currentLog); } currentLog = line; } else if (currentLog) { currentLog = currentLog + "\n" + line; } } if (currentLog) { logs.push(currentLog); } // trace or report the logs, according to log level for (const log of logs) { if (log.startsWith("ERROR ")) { reportDiagnostic(program, { code: "generator-error", format: { errorMessage: log.substring(6), }, target: NoTarget, }); } else if (log.startsWith("WARN ")) { reportDiagnostic(program, { code: "generator-warning", format: { warningMessage: log.substring(5), }, target: NoTarget, }); } else { const index = log.indexOf(" "); trace(program, log.substring(index + 1)); } } } //# sourceMappingURL=emitter.js.map