This is similar to the way Gson does its type adapters: factories that
can delegate and compose.
It's different because annotations are fundamental to the design.
It's also different because there are no APIs to convert to and from
JSON on the central object: instead callers must get the JSON adapter
they're interested in and do that there. This is potentially more
efficient because applications can hold the adapter they need.