I think I have this covered, because the schema can be
defined/extended in Lua, so if the user wants to extend the struct
they just extend the schema.
Ahh yes. Your use case is very unique, in that it is pretty much all about putting Lua values into a very strict buffer/message passing system.
In that case, take all of my answers and assume that my advice would be to do almost the opposite! :) I'm only kind of kidding here, but hopefully you take my meaning...
It's an interesting and tricky design choice that you're facing. Imagine that I'm a sure and I've got a fancy metatable that makes my content bend into a specific protobuf... I assume that you're doing normal table access and not raw, correct? I'm only curious.
Anyway, it sounds like, under the circumstances, a more type-oriented approach is appropriate here, than would otherwise normally be. Perhaps "idiomatic" is not what you're after here?