merge.cpp 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. #include "merge.h"
  2. #include "simple_reflection.h"
  3. #include <google/protobuf/message.h>
  4. #include <library/cpp/protobuf/util/proto/merge.pb.h>
  5. namespace NProtoBuf {
  6. void RewriteMerge(const Message& src, Message& dst) {
  7. const Descriptor* d = src.GetDescriptor();
  8. Y_ASSERT(d == dst.GetDescriptor());
  9. for (int i = 0; i < d->field_count(); ++i) {
  10. if (TConstField(src, d->field(i)).Has())
  11. TMutableField(dst, d->field(i)).Clear();
  12. }
  13. dst.MergeFrom(src);
  14. }
  15. static void ClearNonMergeable(const Message& src, Message& dst) {
  16. const Descriptor* d = src.GetDescriptor();
  17. if (d->options().GetExtension(DontMerge)) {
  18. dst.Clear();
  19. return;
  20. }
  21. for (int i = 0; i < d->field_count(); ++i) {
  22. const FieldDescriptor* fd = d->field(i);
  23. TConstField srcField(src, fd);
  24. if (srcField.Has()) {
  25. TMutableField dstField(dst, fd);
  26. if (fd->options().GetExtension(DontMergeField))
  27. dstField.Clear();
  28. else if (!fd->is_repeated() && dstField.IsMessage() && dstField.Has())
  29. ClearNonMergeable(*srcField.Get<const Message*>(), *dstField.MutableMessage());
  30. }
  31. }
  32. }
  33. void CustomMerge(const Message& src, Message& dst) {
  34. ClearNonMergeable(src, dst);
  35. dst.MergeFrom(src);
  36. }
  37. }