The annotation processor scans @Command classes at compile time and generates wrapper classes. Each platform has its
own processor that produces platform-specific wrappers.
- Parse —
CommandParserreads@Command,@Default,@Resolveannotations into aCommandModeltree - Template —
BaseCommandProcessor.buildWrapperClassruns a 7-phase template - Anchors — Platform processor fills in platform-specific code at each anchor
- Generate — JavaPoet writes the wrapper
.javafile
Phase 1: anchorConfigureType() → class declaration
Phase 2: anchorAdditionalFields() → extra fields
Phase 3: anchorConstructorTop/Bottom() → constructor
Phase 4: anchorBuildEntryMethods() → execute/tabComplete
Phase 5: anchorAdditionalHelpers() → platform helpers
Phase 6: buildCommandInfoExposer() → shared
Phase 7: anchorExtraMethods() → Brigadier tree (Paper only)
Platform-specific parameter resolution:
- ArrayExecutionSource — Bukkit/Standalone:
args[index]array access - PaperExecutionSource — Paper: Brigadier
ctx.getArgument()retrieval
| Component | Purpose |
|---|---|
CommandParser |
Reads annotations into CommandModel |
TypeSupport |
Maps types to parse/literal/suggestion lambdas |
ResolverLookup |
Finds @Resolve methods and suggest providers |
SpiLoader |
Loads ParameterAnnotationHandler, MethodAnnotationHandler, etc. |
Naming |
Generates unique identifiers for methods/fields |
All validation errors throw CommandException. The CommandManager.formatMessage() method handles i18n. Override it
for translation support.
Each @Command class produces a single wrapper:
| Platform | Suffix | Extends/Implements |
|---|---|---|
| Bukkit | _Executor |
Command, CommandInfoExposer |
| Paper | _Paper |
PaperCommand, CommandInfoExposer |
| Standalone | _Standalone |
StandaloneCommand, CommandInfoExposer |