This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
@azure-tools/typespec-java is the branded Java emitter. It wraps the unbranded emitter
@typespec/http-client-java, which lives in the core/ submodule at
core/packages/http-client-java.
Only src/options.ts (the Azure-specific emitter options) is committed in this package. The rest of
the emitter TypeScript (and tests) is copied from core/packages/http-client-java/emitter/{src,test}
at build time by Copy-Sources.ps1 (excluding options.ts). The Java emitter.jar is
built by Build-Generator.ps1 from a patched copy of core/packages/http-client-java/generator
(see below) and staged into generator/http-client-generator/target/.
Copy-Sources.ps1 copies the Java generator sources out of the core/ submodule into this
package's ./generator folder and applies core.patch to that copy — never to core/ itself.
The patch swaps the unbranded customization engine in http-client-generator-core for Azure's
com.azure.tools:azure-autorest-customization (resolved from Maven Central), so the
customization-class emitter option runs against the Azure customization base. Build-Generator.ps1
then builds emitter.jar from the patched ./generator. Because the patch is only ever applied to
the copy, the core/ submodule working tree stays clean. When the core/ submodule is bumped,
refresh core.patch if its context no longer applies.
# From the repo root, install workspace dependencies.
pnpm install
# From the repo root, build typespec-java along with all its dependencies.
# Use run-all so pnpm does not auto-install concurrently during the Turbo build.
pnpm run-all --filter "@azure-tools/typespec-java..." buildCopy-Sources.ps1 reads the emitter/generator sources from the core/ submodule's current checkout.
The optional core-commit.json pins a specific upstream core commit to read from instead:
{ "sha": "3cb616e4e8c3d5b6954bac9832b97445450a71af" }The pinned SHA is fetched if needed and used only when it is newer than the current checkout (the
submodule never moves backwards). When the pin is newer, those sources are extracted from that commit
into a temporary directory via git archive — the core/ submodule is never checked out or
otherwise modified. This keeps pnpm build safe to run alongside the parallel monorepo build (which
reads core/ concurrently) and keeps CI git-status checks clean. To advance the pin, update the
sha.
If pnpm turbo ... fails with 'turbo' is not recognized as an internal or external command
after pnpm install, the local install tree is missing Turbo's binary shim. From the repo root,
force pnpm to refresh the local install state and rerun the command:
pnpm install --force
pnpm run-all --filter "@azure-tools/typespec-java..." buildChanging the npm registry has been observed to clear this symptom, possibly because pnpm re-resolves packages or relinks local binaries after the registry setting changes.
Build the package first, then run the TypeSpec compiler under the Node.js debugger from
packages/typespec-java:
node --inspect-brk node_modules/@typespec/compiler/dist/src/core/cli/cli.js compile emitter-tests/<tsp-file>Attach a debugger to port 9229 and set breakpoints in src/emitter.ts,
src/code-model-builder.ts, or their compiled counterparts under dist/src.
TypeScript passes the code model and emitter options to Java through the generated
emitter-tests/tsp-output/code-model.yaml file. To debug the Java generator directly:
-
Build the package so
Copy-Sources.ps1creates the patched generator copy undergenerator/. -
Update
DEFAULT_OUTPUT_DIRingenerator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/Main.javato the directory containing thecode-model.yamlto debug. -
Run
com.microsoft.typespec.http.client.generator.Main.main()from an IDE with these VM options:--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
The copied generator is recreated on each build, so do not commit changes under generator/.
Emitter options used by Main are defined in
generator/http-client-generator/src/main/java/com/microsoft/typespec/http/client/generator/model/EmitterOptions.java.
When debugging this way, temporarily align them with the options in the relevant tspconfig.yaml;
for example, set flavor to azure.
Make sure to run the following commands:
pnpm format
TODO: The post-release process for @azure-tools/typespec-java has not been finalized yet.
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.