static RoutableFactory createUpdateDocumentMessageFactory() {
        return ProtobufCodecBuilder
                .of(UpdateDocumentMessage.class, DocapiFeed.UpdateDocumentRequest.class)
                .encoder((apiMsg) -> {
                    var builder = DocapiFeed.UpdateDocumentRequest.newBuilder()
                            .setUpdate(toProtoUpdate(apiMsg.getDocumentUpdate()))
                            .setExpectedOldTimestamp(apiMsg.getOldTimestamp())
                            .setForceAssignTimestamp(apiMsg.getNewTimestamp());
                    if (apiMsg.getCondition().isPresent()) {
                        builder.setCondition(toProtoTasCondition(apiMsg.getCondition()));
                    }
                    builder.setCreateIfMissing(apiMsg.createIfMissing() ? DocapiFeed.UpdateDocumentRequest.CreateIfMissing.TRUE
                                                                        : DocapiFeed.UpdateDocumentRequest.CreateIfMissing.FALSE);
                    return builder.build();
                })
                .decoderWithRepo(DocapiFeed.UpdateDocumentRequest.parser(), (protoMsg, repo) -> {
                    var msg = new UpdateDocumentMessage(fromProtoUpdate(protoMsg.getUpdate(), repo));
                    msg.setOldTimestamp(protoMsg.getExpectedOldTimestamp());
                    msg.setNewTimestamp(protoMsg.getForceAssignTimestamp());
                    if (protoMsg.hasCondition()) {
                        msg.setCondition(fromProtoTasCondition(protoMsg.getCondition()));
                    }
                    // We ignore the createIfMissing field here since it can always be fetched eagerly
                    // from the DocumentUpdate instance itself.
                    return msg;
                })
                .build();
    }
Implementation of MessageBus message request/response serialization built around Protocol Buffers.
documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/RoutableFactories80.java