The GAS pattern and message passing are not mutually exclusive. The GAS pattern takes a Pregel vertex program and breaks it into three phases, which helps with parallelization (high-degree vertices can be broken up and gather/scatter run on different machines). A lot of examples write data to edges because that's what works, but message passing can be implemented too.
There's an example of Pregel PageRank in the comments of ivertexprogram.hpp. You have to implement a message type with a += operator. Messages are automatically combined (like a Pregel combiner) so they must be commutative and associative. Messages are received in the vertexprogram::init() function. Messages are created and sent during the scatter phase, and then I believe sent though a context.signal() to the destination vertex.