ProvidenceHelper { @SuppressWarnings("unchecked") public static <M extends PMessage<M, F>, F extends PField, B extends PMessageBuilder<M,F>> B getTargetModifications(M source, M target) { B builder = (B) target.mutate(); for (F field : source.descriptor().getFields()) { if (source.has(field) != target.has(field) || !Objects.equals(source.get(field), target.get(field))) { builder.set(field, target.get(field)); } } return builder; } private  ProvidenceHelper(); @SuppressWarnings("unchecked") static B getTargetModifications(M source, M target); @Nonnull static Message fromJsonResource(String path,
                             PMessageDescriptor<Message, Field> descriptor); @Nonnull static ArrayList<Message> arrayListFromJsonResource(String path,
                                                 PMessageDescriptor<Message, Field> descriptor); @Nonnull static Message fromResource(String resource,
                         PMessageDescriptor<Message, Field> descriptor,
                         Serializer serializer); @Nonnull static ArrayList<Message> arrayListFromResource(String path,
                                             PMessageDescriptor<Message, Field> descriptor,
                                             Serializer serializer); @Nonnull static String debugString(Message message); @Nonnull static Message parseDebugString(String string, PMessageDescriptor<Message, Field> descriptor); @SuppressWarnings("unchecked") @Nonnull static Optional<T> optionalInMessage(PMessage message, PField... fields);  }
@Test public void testGetTargetModifications() { OptionalFields._Builder b1 = getTargetModifications(OptionalFields.builder().build(), OptionalFields.builder().build()); assertThat(b1.modifiedFields(), is(empty())); OptionalFields source = OptionalFields.builder() .setBinaryValue(Binary.fromBase64("abcd")) .setStringValue("old") .setIntegerValue(321) .build(); OptionalFields target = OptionalFields.builder() .setStringValue("new") .setLongValue(1234L) .setIntegerValue(321) .build(); OptionalFields._Builder b2 = getTargetModifications(source, target); assertThat(b2.modifiedFields(), hasItems(OptionalFields._Field.BINARY_VALUE, OptionalFields._Field.STRING_VALUE, OptionalFields._Field.LONG_VALUE)); assertThat(b2.modifiedFields(), hasSize(3)); assertThat(b2.build(), is(target)); }