Repository navigation
[Java] @CopilotTool ergonomics 4.2: Schema generation utility (TypeMirror to JSON Schema) #1759
Description
Overview
Create a compile-time schema generation utility that maps javax.lang.model types (TypeMirror, DeclaredType) to JSON Schema represented as Java source code literals (Map.of(...) expressions).
Branch: edburns/1682-java-tool-ergonomics on upstream (main — PRs must target this branch)
Prerequisites
- Task 4.1 (annotations) must be complete and merged to the branch.
- Before writing any code, read the entire implementation plan at:
1682-java-tool-ergonomics-prompts-remove-before-merge/dd-3018003-ignorance-reduction-for-implementation-plan.md
Relevant plan sections to carefully re-read
- Section 3.4 — Type-to-JSON-Schema mapping (Resolution: maximum viable set of 23 type mappings with full table)
- Section 3.5 — Generated code shape (Resolution: how generated code uses schema maps)
- Section 4.2 — Schema generation utility (compile-time) (the primary task description)
Deliverables
Files to create
java/src/main/java/com/github/copilot/tool/SchemaGenerator.java
Functional specification
SchemaGenerator is a compile-time utility invoked by the annotation processor. It receives javax.lang.model.type.TypeMirror instances and produces a String containing the Java source code literal for the JSON Schema Map. For example, given a String type, it should produce the source code string: Map.of("type", "string").
Type mappings to implement (from Resolution 3.4)
| Java type | JSON Schema source literal |
|---|---|
String |
Map.of("type", "string") |
int, Integer |
Map.of("type", "integer") |
long, Long |
Map.of("type", "integer") |
double, Double |
Map.of("type", "number") |
float, Float |
Map.of("type", "number") |
boolean, Boolean |
Map.of("type", "boolean") |
String[] |
Map.of("type", "array", "items", Map.of("type", "string")) |
enum types |
Map.of("type", "string", "enum", List.of("V1", "V2", ...)) (enumerate all constants) |
UUID |
Map.of("type", "string", "format", "uuid") |
OffsetDateTime |
Map.of("type", "string", "format", "date-time") |
JsonNode |
Map.of() (any) |
Object |
Map.of() (any) |
List<T>, Collection<T> |
Map.of("type", "array", "items", <schema-of-T>) |
Map<String, String> |
Map.of("type", "object", "additionalProperties", Map.of("type", "string")) |
Map<String, Boolean> |
Map.of("type", "object", "additionalProperties", Map.of("type", "boolean")) |
Map<String, Long> |
Map.of("type", "object", "additionalProperties", Map.of("type", "integer")) |
Map<String, Object> |
Map.of("type", "object") (opaque) |
Map<String, T> (typed T) |
Map.of("type", "object", "additionalProperties", <schema-of-T>) |
Map<String, List<String>> |
nested as expected |
| Records / POJOs | Map.of("type", "object", "properties", Map.of(...), "required", List.of(...)) |
Sealed / @JsonSubTypes |
Map.of("oneOf", List.of(...)) with discriminator |
Optional<T> |
Schema of T, excluded from required array |
OptionalInt |
Map.of("type", "integer"), excluded from required |
OptionalDouble |
Map.of("type", "number"), excluded from required |
API design
public class SchemaGenerator {
/**
* Given a TypeMirror from the annotation processing environment,
* return a String containing Java source code for a Map literal
* representing the JSON Schema of that type.
*/
public String generateSchemaSource(TypeMirror type, Types typeUtils, Elements elementUtils) { ... }
/**
* Generate the full "parameters" schema source for a method's parameters.
* Produces a Map.of("type", "object", "properties", Map.of(...), "required", List.of(...)).
*/
public String generateParametersSchemaSource(List<? extends VariableElement> parameters,
Types typeUtils, Elements elementUtils) { ... }
}The class should use javax.lang.model.type.TypeKind, DeclaredType.getTypeArguments(), ElementKind.ENUM_CONSTANT, and related APIs. It does NOT use java.lang.reflect at all.
Gating tests and criteria
All of the following must pass before this task is considered complete:
-
Unit tests: Create
java/src/test/java/com/github/copilot/tool/SchemaGeneratorTest.javathat tests schema generation. SinceTypeMirrorinstances are hard to mock, use the compilation-testing approach: write small Java source snippets, compile them withjavax.tools.JavaCompiler, and have a test processor that exercisesSchemaGeneratorduring compilation. Alternatively, use a test annotation processor that logs generated schema and asserts correctness. -
Minimum type coverage tests: The test must verify correct schema generation for at minimum:
String→{"type": "string"}int/Integer→{"type": "integer"}boolean/Boolean→{"type": "boolean"}double/Double→{"type": "number"}- An enum type →
{"type": "string", "enum": [...]} List<String>→{"type": "array", "items": {"type": "string"}}- A simple record with 2-3 fields →
{"type": "object", "properties": {...}, "required": [...]} Optional<String>→ schema of String, NOT in requiredMap<String, String>→{"type": "object", "additionalProperties": {"type": "string"}}
-
Generated source validity: For each test case, verify the generated source code string is syntactically valid Java (it should compile if pasted into a method body).
-
Spotless format check:
mvn spotless:checkpasses. -
Full test suite:
mvn clean verifypasses (existing tests and 4.1 tests not broken).
Constraints
-
✅✅ YOU MUST run
mvn spotless:applybefore every commit. -
This class operates exclusively at compile time with
javax.lang.modelAPIs. -
Do NOT use
java.lang.reflectanywhere in this class. -
Do NOT modify any files outside the
java/directory. -
Follow existing code style (4-space indent, Javadoc on public APIs).
-
The generated source code strings must use
java.util.Map.of()andjava.util.List.of()(Java 9+ immutable collections) for the schema literals.
Activity
feat(java): add SchemaGenerator compile-time type-to-JSON-Schema utility
feat(java): add SchemaGenerator compile-time type-to-JSON-Schema util…
feat(java): add SchemaGenerator compile-time type-to-JSON-Schema util…
feat(java): add SchemaGenerator compile-time type-to-JSON-Schema util…
feat(java): Add CopilotToolProcessor annotation processor (task 4.3) (#…
feat(java): add SchemaGenerator compile-time type-to-JSON-Schema util…
feat(java): Add CopilotToolProcessor annotation processor (task 4.3) (#…
feat(java): add SchemaGenerator compile-time type-to-JSON-Schema util…
feat(java): Add CopilotToolProcessor annotation processor (task 4.3) (#…
feat(java): add SchemaGenerator compile-time type-to-JSON-Schema util…
feat(java): Add CopilotToolProcessor annotation processor (task 4.3) (#…
Java: Implement `@CopilotTool` ergonomics (#1792)
Java: Implement `@CopilotTool` ergonomics (#1792)
Java: Implement `@CopilotTool` ergonomics (#1792)