That's exactly the problem. We don't. This issue first came up for us when writing code to copy data from one subtree to another of a protocol buffer. By passing in a field descriptor we were able to eliminate a LOT of duplicated code. In that case, we only needed the field access to write and so were able to get the descriptor. We anticipate the same issue coming up for reading, however.
We could define an interface with a 'get' and a 'set' method and avoid using getField/setField at all, but it seems unfortunate that the capability isn't in the API. The data appears to all be there; in fact, it appears that GeneratedMessage.SingularEnumFieldAccessor adds extra code to get the current behavior.