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 (⚠️ NOT 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.java that tests schema generation. Since TypeMirror instances are hard to mock, use the compilation-testing approach: write small Java source snippets, compile them with javax.tools.JavaCompiler, and have a test processor that exercises SchemaGenerator during 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 required
Map<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:check passes.
-
Full test suite: mvn clean verify passes (existing tests and 4.1 tests not broken).
Constraints
-
✅✅ YOU MUST run mvn spotless:apply before every commit.
-
This class operates exclusively at compile time with javax.lang.model APIs.
-
Do NOT use java.lang.reflect anywhere 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() and java.util.List.of() (Java 9+ immutable collections) for the schema literals.
Overview
Create a compile-time schema generation utility that maps
javax.lang.modeltypes (TypeMirror,DeclaredType) to JSON Schema represented as Java source code literals (Map.of(...)expressions).Branch:⚠️ NOT
edburns/1682-java-tool-ergonomicsonupstream(main— PRs must target this branch)Prerequisites
1682-java-tool-ergonomics-prompts-remove-before-merge/dd-3018003-ignorance-reduction-for-implementation-plan.mdRelevant plan sections to carefully re-read
Deliverables
Files to create
java/src/main/java/com/github/copilot/tool/SchemaGenerator.javaFunctional specification
SchemaGeneratoris a compile-time utility invoked by the annotation processor. It receivesjavax.lang.model.type.TypeMirrorinstances and produces aStringcontaining the Java source code literal for the JSON SchemaMap. For example, given aStringtype, it should produce the source code string:Map.of("type", "string").Type mappings to implement (from Resolution 3.4)
StringMap.of("type", "string")int,IntegerMap.of("type", "integer")long,LongMap.of("type", "integer")double,DoubleMap.of("type", "number")float,FloatMap.of("type", "number")boolean,BooleanMap.of("type", "boolean")String[]Map.of("type", "array", "items", Map.of("type", "string"))enumtypesMap.of("type", "string", "enum", List.of("V1", "V2", ...))(enumerate all constants)UUIDMap.of("type", "string", "format", "uuid")OffsetDateTimeMap.of("type", "string", "format", "date-time")JsonNodeMap.of()(any)ObjectMap.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>>Map.of("type", "object", "properties", Map.of(...), "required", List.of(...))@JsonSubTypesMap.of("oneOf", List.of(...))with discriminatorOptional<T>OptionalIntMap.of("type", "integer"), excluded from requiredOptionalDoubleMap.of("type", "number"), excluded from requiredAPI design
The class should use
javax.lang.model.type.TypeKind,DeclaredType.getTypeArguments(),ElementKind.ENUM_CONSTANT, and related APIs. It does NOT usejava.lang.reflectat 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"}{"type": "string", "enum": [...]}List<String>→{"type": "array", "items": {"type": "string"}}{"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.