--- a
+++ b/third_party/nucleus/testing/protocol-buffer-matchers.h
@@ -0,0 +1,1139 @@
+/*
+ * Copyright 2018 Google LLC.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// gMock matchers used to validate protocol buffer arguments.
+
+// WHAT THIS IS
+// ============
+//
+// This library defines the following matchers in the ::nucleus namespace:
+//
+//   EqualsProto(pb)              The argument equals pb.
+//   EqualsInitializedProto(pb)   The argument is initialized and equals pb.
+//   EquivToProto(pb)             The argument is equivalent to pb.
+//   EquivToInitializedProto(pb)  The argument is initialized and equivalent
+//                                to pb.
+//   IsInitializedProto()         The argument is an initialized protobuf.
+//
+// where:
+//
+//   - pb can be either a protobuf value or a human-readable string
+//     representation of it.
+//   - When pb is a string, the matcher can optionally accept a
+//     template argument for the type of the protobuf,
+//     e.g. EqualsProto<Foo>("foo: 1").
+//   - "equals" is defined as the argument's Equals(pb) method returns true.
+//   - "equivalent to" is defined as the argument's Equivalent(pb) method
+//     returns true.
+//   - "initialized" means that the argument's IsInitialized() method returns
+//     true.
+//
+// These matchers can match either a protobuf value or a pointer to
+// it.  They make a copy of pb, and thus can out-live pb.  When the
+// match fails, the matchers print a detailed message (the value of
+// the actual protobuf, the value of the expected protobuf, and which
+// fields are different).
+//
+// This library also defines the following matcher transformer
+// functions in the ::nucleus::proto namespace:
+//
+//   Approximately(m, margin, fraction)
+//                     The same as m, except that it compares
+//                     floating-point fields approximately (using
+//                     google::protobuf::util::MessageDifferencer's APPROXIMATE
+//                     comparison option).  m can be any of the
+//                     Equals* and EquivTo* protobuf matchers above. If margin
+//                     is specified, floats and doubles will be considered
+//                     approximately equal if they are within that margin, i.e.
+//                     abs(expected - actual) <= margin. If fraction is
+//                     specified, floats and doubles will be considered
+//                     approximately equal if they are within a fraction of
+//                     their magnitude, i.e. abs(expected - actual) <=
+//                     fraction * max(abs(expected), abs(actual)). Two fields
+//                     will be considered equal if they're within the fraction
+//                     _or_ within the margin, so omitting or setting the
+//                     fraction to 0.0 will only check against the margin.
+//                     Similarly, setting the margin to 0.0 will only check
+//                     using the fraction. If margin and fraction are omitted,
+//                     MathLimits<T>::kStdError for that type (T=float or
+//                     T=double) is used for both the margin and fraction.
+//   TreatingNaNsAsEqual(m)
+//                     The same as m, except that treats floating-point fields
+//                     that are NaN as equal. m can be any of the Equals* and
+//                     EquivTo* protobuf matchers above.
+//   IgnoringFields(fields, m)
+//                     The same as m, except the specified fields will be
+//                     ignored when matching (using
+//                     google::protobuf::util::MessageDifferencer::IgnoreField). fields is
+//                     represented as a container or an initializer list of
+//                     strings and each element is specified by their fully
+//                     qualified names, i.e., the names corresponding to
+//                     FieldDescriptor.full_name().  m can be
+//                     any of the Equals* and EquivTo* protobuf matchers above.
+//                     It can also be any of the transformer matchers listed
+//                     here (e.g. Approximately, TreatingNaNsAsEqual) as long as
+//                     the intent of the each concatenated matcher is mutually
+//                     exclusive (e.g. using IgnoringFields in conjunction with
+//                     Partially can have different results depending on whether
+//                     the fields specified in IgnoringFields is part of the
+//                     fields covered by Partially).
+//   IgnoringFieldPaths(field_paths, m)
+//                     The same as m, except the specified fields will be
+//                     ignored when matching. field_paths is represented as a
+//                     container or an initializer list of strings and
+//                     each element is specified by their path relative to the
+//                     proto being matched by m. Paths can contain indices
+//                     and/or extensions. Examples:
+//                       Ignores field singular_field/repeated_field:
+//                         singular_field
+//                         repeated_field
+//                       Ignores just the third repeated_field instance:
+//                         repeated_field[2]
+//                       Ignores some_field in singular_nested/repeated_nested:
+//                         singular_nested.some_field
+//                         repeated_nested.some_field
+//                       Ignores some_field in instance 2 of repeated_nested:
+//                         repeated_nested[2].some_field
+//                       Ignores extension SomeExtension.msg of repeated_nested:
+//                         repeated_nested.(package.SomeExtension.msg)
+//                       Ignores subfield of extension:
+//                         repeated_nested.(package.SomeExtension.msg).subfield
+//                     The same restrictions as for IgnoringFields apply.
+//   IgnoringRepeatedFieldOrdering(m)
+//                     The same as m, except that it ignores the relative
+//                     ordering of elements within each repeated field in m.
+//                     See google::protobuf::util::MessageDifferencer::TreatAsSet() for
+//                     more details.
+//   Partially(m)
+//                     The same as m, except that only fields present in
+//                     the expected protobuf are considered (using
+//                     google::protobuf::util::MessageDifferencer's PARTIAL
+//                     comparison option).   m can be any of the
+//                     Equals* and EquivTo* protobuf matchers above.
+//   WhenDeserialized(typed_pb_matcher)
+//                     The string argument is a serialization of a
+//                     protobuf that matches typed_pb_matcher.
+//                     typed_pb_matcher can be an Equals* or EquivTo*
+//                     protobuf matcher (possibly with Approximately()
+//                     or Partially() modifiers) where the type of the
+//                     protobuf is known at run time (e.g. it cannot
+//                     be EqualsProto("...") as it's unclear what type
+//                     the string represents).
+//   WhenDeserializedAs<PB>(pb_matcher)
+//                     Like WhenDeserialized(), except that the type
+//                     of the deserialized protobuf must be PB.  Since
+//                     the protobuf type is known, pb_matcher can be *any*
+//                     valid protobuf matcher, including EqualsProto("...").
+//
+// Approximately(), TreatingNaNsAsEqual(), Partially(), IgnoringFields(), and
+// IgnoringRepeatedFieldOrdering() can be combined (nested)
+// and the composition order is irrelevant:
+//
+//   Approximately(Partially(EquivToProto(pb)))
+// and
+//   Partially(Approximately(EquivToProto(pb)))
+// are the same thing.
+//
+// EXAMPLES
+// ========
+//
+//   using ::nucleus::EqualsProto;
+//   using ::nucleus::EquivToProto;
+//   using ::nucleus::proto::Approximately;
+//   using ::nucleus::proto::Partially;
+//   using ::nucleus::proto::WhenDeserialized;
+//
+//   // my_pb.Equals(expected_pb).
+//   EXPECT_THAT(my_pb, EqualsProto(expected_pb));
+//
+//   // my_pb is equivalent to a protobuf whose foo field is 1 and
+//   // whose bar field is "x".
+//   EXPECT_THAT(my_pb, EquivToProto("foo: 1 "
+//                                   "bar: 'x'"));
+//
+//   // my_pb is equal to expected_pb, comparing all floating-point
+//   // fields approximately.
+//   EXPECT_THAT(my_pb, Approximately(EqualsProto(expected_pb)));
+//
+//   // my_pb is equivalent to expected_pb.  A field is ignored in the
+//   // comparison if it's present in my_pb but not in expected_pb.
+//   EXPECT_THAT(my_pb, Partially(EquivToProto(expected_pb)));
+//
+//   string data;
+//   my_pb.SerializeToString(&data);
+//   // data can be deserialized to a protobuf that equals expected_pb.
+//   EXPECT_THAT(data, WhenDeserialized(EqualsProto(expected_pb)));
+//   // The following line doesn't compile, as the matcher doesn't know
+//   // the type of the protobuf.
+//   // EXPECT_THAT(data, WhenDeserialized(EqualsProto("foo: 1")));
+
+#ifndef THIRD_PARTY_NUCLEUS_TESTING_PROTOCOL_BUFFER_MATCHERS_H_
+#define THIRD_PARTY_NUCLEUS_TESTING_PROTOCOL_BUFFER_MATCHERS_H_
+
+#include <initializer_list>
+#include <iostream>  // NOLINT
+#include <memory>
+#include <sstream>  // NOLINT
+#include <string>   // NOLINT
+#include <vector>   // NOLINT
+
+#include <gmock/gmock-generated-matchers.h>
+#include <gmock/gmock-matchers.h>
+#include <gmock/gmock-more-matchers.h>
+
+#include "absl/log/check.h"
+#include "absl/strings/string_view.h"
+#include "third_party/nucleus/platform/types.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/io/zero_copy_stream.h"
+#include "google/protobuf/io/zero_copy_stream_impl.h"
+#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
+#include "google/protobuf/message.h"
+#include "google/protobuf/text_format.h"
+#include "google/protobuf/util/field_comparator.h"
+#include "google/protobuf/util/message_differencer.h"
+
+namespace nucleus {
+
+
+namespace internal {
+
+// Utilities.
+
+// How to compare two fields (equal vs. equivalent).
+typedef google::protobuf::util::MessageDifferencer::MessageFieldComparison
+    ProtoFieldComparison;
+
+// How to compare two floating-points (exact vs. approximate).
+typedef google::protobuf::util::DefaultFieldComparator::FloatComparison
+    ProtoFloatComparison;
+
+// How to compare repeated fields (whether the order of elements matters).
+typedef google::protobuf::util::MessageDifferencer::RepeatedFieldComparison
+    RepeatedFieldComparison;
+
+// Whether to compare all fields (full) or only fields present in the
+// expected protobuf (partial).
+typedef google::protobuf::util::MessageDifferencer::Scope ProtoComparisonScope;
+
+const ProtoFieldComparison kProtoEqual =
+    google::protobuf::util::MessageDifferencer::EQUAL;
+const ProtoFieldComparison kProtoEquiv =
+    google::protobuf::util::MessageDifferencer::EQUIVALENT;
+const ProtoFloatComparison kProtoExact =
+    google::protobuf::util::DefaultFieldComparator::EXACT;
+const ProtoFloatComparison kProtoApproximate =
+    google::protobuf::util::DefaultFieldComparator::APPROXIMATE;
+const RepeatedFieldComparison kProtoCompareRepeatedFieldsRespectOrdering =
+    google::protobuf::util::MessageDifferencer::AS_LIST;
+const RepeatedFieldComparison kProtoCompareRepeatedFieldsIgnoringOrdering =
+    google::protobuf::util::MessageDifferencer::AS_SET;
+const ProtoComparisonScope kProtoFull = google::protobuf::util::MessageDifferencer::FULL;
+const ProtoComparisonScope kProtoPartial =
+    google::protobuf::util::MessageDifferencer::PARTIAL;
+
+// Options for comparing two protobufs.
+struct ProtoComparison {
+  ProtoComparison()
+      : field_comp(kProtoEqual),
+        float_comp(kProtoExact),
+        treating_nan_as_equal(false),
+        has_custom_margin(false),
+        has_custom_fraction(false),
+        repeated_field_comp(kProtoCompareRepeatedFieldsRespectOrdering),
+        scope(kProtoFull),
+        float_margin(0.0),
+        float_fraction(0.0) {}
+
+  ProtoFieldComparison field_comp;
+  ProtoFloatComparison float_comp;
+  bool treating_nan_as_equal;
+  bool has_custom_margin;    // only used when float_comp = APPROXIMATE
+  bool has_custom_fraction;  // only used when float_comp = APPROXIMATE
+  RepeatedFieldComparison repeated_field_comp;
+  ProtoComparisonScope scope;
+  double float_margin;       // only used when has_custom_margin is set.
+  double float_fraction;     // only used when has_custom_fraction is set.
+  std::vector<string> ignore_fields;
+  std::vector<string> ignore_field_paths;
+};
+
+// Whether the protobuf must be initialized.
+const bool kMustBeInitialized = true;
+const bool kMayBeUninitialized = false;
+
+// Parses the TextFormat representation of a protobuf, allowing required fields
+// to be missing.  Returns true iff successful.
+bool ParsePartialFromAscii(const string& pb_ascii, google::protobuf::Message* proto,
+                           string* error_text);
+
+// Returns a protobuf of type Proto by parsing the given TextFormat
+// representation of it.  Required fields can be missing, in which case the
+// returned protobuf will not be fully initialized.
+template <class Proto>
+Proto MakePartialProtoFromAscii(const string& str) {
+  Proto proto;
+  string error_text;
+  CHECK(ParsePartialFromAscii(str, &proto, &error_text))
+      << "Failed to parse \"" << str << "\" as a "
+      << proto.GetDescriptor()->full_name() << ":\n" << error_text;
+  return proto;
+}
+
+// Returns true iff p and q can be compared (i.e. have the same descriptor).
+bool ProtoComparable(const google::protobuf::Message& p, const google::protobuf::Message& q);
+
+// Returns true iff actual and expected are comparable and match.  The
+// comp argument specifies how the two are compared.
+bool ProtoCompare(const ProtoComparison& comp,
+                  const google::protobuf::Message& actual,
+                  const google::protobuf::Message& expected);
+
+// Overload for ProtoCompare where the expected message is specified as a text
+// proto.  If the text cannot be parsed as a message of the same type as the
+// actual message, a CHECK failure will cause the test to fail and no subsequent
+// tests will be run.
+template <typename Proto>
+inline bool ProtoCompare(const ProtoComparison& comp,
+                         const Proto& actual,
+                         const string& expected) {
+  return ProtoCompare(comp, actual, MakePartialProtoFromAscii<Proto>(expected));
+}
+
+// Describes the types of the expected and the actual protocol buffer.
+string DescribeTypes(const google::protobuf::Message& expected,
+                     const google::protobuf::Message& actual);
+
+// Prints the protocol buffer pointed to by proto.
+string PrintProtoPointee(const google::protobuf::Message* proto);
+
+// Describes the differences between the two protocol buffers.
+string DescribeDiff(const ProtoComparison& comp,
+                    const google::protobuf::Message& actual,
+                    const google::protobuf::Message& expected);
+
+// Common code for implementing EqualsProto, EquivToProto,
+// EqualsInitializedProto, and EquivToInitializedProto.
+class ProtoMatcherBase {
+ public:
+  ProtoMatcherBase(
+      bool must_be_initialized,     // Must the argument be fully initialized?
+      const ProtoComparison& comp)  // How to compare the two protobufs.
+      : must_be_initialized_(must_be_initialized),
+        comp_(new auto(comp)) {}
+
+  ProtoMatcherBase(const ProtoMatcherBase& other)
+      : must_be_initialized_(other.must_be_initialized_),
+        comp_(new auto(*other.comp_)) {}
+
+  ProtoMatcherBase(ProtoMatcherBase&& other) = default;
+
+  virtual ~ProtoMatcherBase() {}
+
+  // Prints the expected protocol buffer.
+  virtual void PrintExpectedTo(::std::ostream* os) const = 0;
+
+  // Returns the expected value as a protobuf object; if the object
+  // cannot be created (e.g. in ProtoStringMatcher), explains why to
+  // 'listener' and returns NULL.  The caller must call
+  // DeleteExpectedProto() on the returned value later.
+  virtual const google::protobuf::Message* CreateExpectedProto(
+      const google::protobuf::Message& arg,  // For determining the type of the
+                                   // expected protobuf.
+      ::testing::MatchResultListener* listener) const = 0;
+
+  // Deletes the given expected protobuf, which must be obtained from
+  // a call to CreateExpectedProto() earlier.
+  virtual void DeleteExpectedProto(const google::protobuf::Message* expected) const = 0;
+
+  // Makes this matcher compare floating-points approximately.
+  void SetCompareApproximately() { comp_->float_comp = kProtoApproximate; }
+
+  // Makes this matcher treating NaNs as equal when comparing floating-points.
+  void SetCompareTreatingNaNsAsEqual() { comp_->treating_nan_as_equal = true; }
+
+  // Makes this matcher ignore string elements specified by their fully
+  // qualified names, i.e., names corresponding to FieldDescriptor.full_name().
+  template <class Iterator>
+  void AddCompareIgnoringFields(Iterator first, Iterator last) {
+    comp_->ignore_fields.insert(comp_->ignore_fields.end(), first, last);
+  }
+
+  // Makes this matcher ignore string elements specified by their relative
+  // FieldPath.
+  template <class Iterator>
+  void AddCompareIgnoringFieldPaths(Iterator first, Iterator last) {
+    comp_->ignore_field_paths.insert(comp_->ignore_field_paths.end(), first,
+                                     last);
+  }
+
+  // Makes this matcher compare repeated fields ignoring ordering of elements.
+  void SetCompareRepeatedFieldsIgnoringOrdering() {
+    comp_->repeated_field_comp = kProtoCompareRepeatedFieldsIgnoringOrdering;
+  }
+
+  // Sets the margin of error for approximate floating point comparison.
+  void SetMargin(double margin) {
+    CHECK_GE(margin, 0.0) << "Using a negative margin for Approximately";
+    comp_->has_custom_margin = true;
+    comp_->float_margin = margin;
+  }
+
+  // Sets the relative fraction of error for approximate floating point
+  // comparison.
+  void SetFraction(double fraction) {
+    CHECK(0.0 <= fraction && fraction < 1.0) <<
+        "Fraction for Approximately must be >= 0.0 and < 1.0";
+    comp_->has_custom_fraction = true;
+    comp_->float_fraction = fraction;
+  }
+
+  // Makes this matcher compare protobufs partially.
+  void SetComparePartially() { comp_->scope = kProtoPartial; }
+
+  bool MatchAndExplain(const google::protobuf::Message& arg,
+                       ::testing::MatchResultListener* listener) const {
+    return MatchAndExplain(arg, false, listener);
+  }
+
+  bool MatchAndExplain(const google::protobuf::Message* arg,
+                       ::testing::MatchResultListener* listener) const {
+    return (arg != NULL) && MatchAndExplain(*arg, true, listener);
+  }
+
+  // Describes the expected relation between the actual protobuf and
+  // the expected one.
+  void DescribeRelationToExpectedProto(::std::ostream* os) const {
+    if (comp_->repeated_field_comp ==
+        kProtoCompareRepeatedFieldsIgnoringOrdering) {
+      *os << "(ignoring repeated field ordering) ";
+    }
+    if (!comp_->ignore_fields.empty()) {
+      *os << "(ignoring fields: ";
+      const char *sep = "";
+      for (size_t i = 0; i < comp_->ignore_fields.size(); ++i, sep = ", ")
+        *os << sep << comp_->ignore_fields[i];
+      *os << ") ";
+    }
+    if (comp_->float_comp == kProtoApproximate) {
+      *os << "approximately ";
+      if (comp_->has_custom_margin || comp_->has_custom_fraction) {
+        *os << "(";
+        if (comp_->has_custom_margin) {
+          std::stringstream ss;
+          ss << std::setprecision(std::numeric_limits<double>::digits10 + 2)
+             << comp_->float_margin;
+          *os << "absolute error of float or double fields <= " << ss.str();
+        }
+        if (comp_->has_custom_margin && comp_->has_custom_fraction) {
+          *os << " or ";
+        }
+        if (comp_->has_custom_fraction) {
+          std::stringstream ss;
+          ss << std::setprecision(std::numeric_limits<double>::digits10 + 2)
+             << comp_->float_fraction;
+          *os << "relative error of float or double fields <= " << ss.str();
+        }
+        *os << ") ";
+      }
+    }
+
+    *os << (comp_->scope == kProtoPartial ? "partially " : "")
+        << (comp_->field_comp == kProtoEqual ? "equal" : "equivalent")
+        << (comp_->treating_nan_as_equal ? " (treating NaNs as equal)" : "")
+        << " to ";
+    PrintExpectedTo(os);
+  }
+
+  void DescribeTo(::std::ostream* os) const {
+    *os << "is " << (must_be_initialized_ ? "fully initialized and " : "");
+    DescribeRelationToExpectedProto(os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "is " << (must_be_initialized_ ? "not fully initialized or " : "")
+        << "not ";
+    DescribeRelationToExpectedProto(os);
+  }
+
+  bool must_be_initialized() const { return must_be_initialized_; }
+
+  const ProtoComparison& comp() const { return *comp_; }
+
+ private:
+  bool MatchAndExplain(const google::protobuf::Message& arg, bool is_matcher_for_pointer,
+                       ::testing::MatchResultListener* listener) const;
+
+  const bool must_be_initialized_;
+  std::unique_ptr<ProtoComparison> comp_;
+};
+
+// Returns a copy of the given proto2 message.
+inline google::protobuf::Message* CloneProto2(const google::protobuf::Message& src) {
+  google::protobuf::Message* clone = src.New();
+  clone->CopyFrom(src);
+  return clone;
+}
+
+// Implements EqualsProto, EquivToProto, EqualsInitializedProto, and
+// EquivToInitializedProto, where the matcher parameter is a protobuf.
+class ProtoMatcher : public ProtoMatcherBase {
+ public:
+  ProtoMatcher(
+      const google::protobuf::Message& expected,  // The expected protobuf.
+      bool must_be_initialized,     // Must the argument be fully initialized?
+      const ProtoComparison& comp)  // How to compare the two protobufs.
+      : ProtoMatcherBase(must_be_initialized, comp),
+        expected_(CloneProto2(expected)) {
+    if (must_be_initialized) {
+      CHECK(expected.IsInitialized())
+          << "The protocol buffer given to *InitializedProto() "
+          << "must itself be initialized, but the following required fields "
+          << "are missing: " << expected.InitializationErrorString() << ".";
+    }
+  }
+
+  virtual void PrintExpectedTo(::std::ostream* os) const {
+    *os << expected_->GetDescriptor()->full_name() << " ";
+    ::testing::internal::UniversalPrint(*expected_, os);
+  }
+
+  virtual const google::protobuf::Message* CreateExpectedProto(
+      const google::protobuf::Message& /* arg */,
+      ::testing::MatchResultListener* /* listener */) const {
+    return expected_.get();
+  }
+
+  virtual void DeleteExpectedProto(const google::protobuf::Message* expected) const {}
+
+  const std::shared_ptr<const google::protobuf::Message>& expected()
+      const {
+    return expected_;
+  }
+
+ private:
+  const std::shared_ptr<const google::protobuf::Message> expected_;
+};
+
+// Implements EqualsProto, EquivToProto, EqualsInitializedProto, and
+// EquivToInitializedProto, where the matcher parameter is a string.
+class ProtoStringMatcher : public ProtoMatcherBase {
+ public:
+  ProtoStringMatcher(
+      const string& expected,  // The text representing the expected protobuf.
+      bool must_be_initialized,    // Must the argument be fully initialized?
+      const ProtoComparison comp)  // How to compare the two protobufs.
+      : ProtoMatcherBase(must_be_initialized, comp),
+        expected_(expected) {}
+
+  // Parses the expected string as a protobuf of the same type as arg,
+  // and returns the parsed protobuf (or NULL when the parse fails).
+  // The caller must call DeleteExpectedProto() on the return value
+  // later.
+  virtual const google::protobuf::Message* CreateExpectedProto(
+      const google::protobuf::Message& arg,
+      ::testing::MatchResultListener* listener) const {
+    google::protobuf::Message* expected_proto = arg.New();
+    // We don't insist that the expected string parses as an
+    // *initialized* protobuf.  Otherwise EqualsProto("...") may
+    // wrongfully fail when the actual protobuf is not fully
+    // initialized.  If the user wants to ensure that the actual
+    // protobuf is initialized, they should use
+    // EqualsInitializedProto("...") instead of EqualsProto("..."),
+    // and the MatchAndExplain() function in ProtoMatcherBase will
+    // enforce it.
+    string error_text;
+    if (ParsePartialFromAscii(expected_, expected_proto, &error_text)) {
+      return expected_proto;
+    } else {
+      delete expected_proto;
+      if (listener->IsInterested()) {
+        *listener << "where ";
+        PrintExpectedTo(listener->stream());
+        *listener << " doesn't parse as a " << arg.GetDescriptor()->full_name()
+                  << ":\n" << error_text;
+      }
+      return NULL;
+    }
+  }
+
+  virtual void DeleteExpectedProto(const google::protobuf::Message* expected) const {
+    delete expected;
+  }
+
+  virtual void PrintExpectedTo(::std::ostream* os) const {
+    *os << "<" << expected_ << ">";
+  }
+
+ private:
+  const string expected_;
+};
+
+typedef ::testing::PolymorphicMatcher<ProtoMatcher> PolymorphicProtoMatcher;
+
+// Common code for implementing WhenDeserialized(proto_matcher) and
+// WhenDeserializedAs<PB>(proto_matcher).
+template <class Proto>
+class WhenDeserializedMatcherBase {
+ public:
+  typedef ::testing::Matcher<const Proto&> InnerMatcher;
+
+  explicit WhenDeserializedMatcherBase(const InnerMatcher& proto_matcher)
+      : proto_matcher_(proto_matcher) {}
+
+  virtual ~WhenDeserializedMatcherBase() {}
+
+  // Creates an empty protobuf with the expected type.
+  virtual Proto* MakeEmptyProto() const = 0;
+
+  // Type name of the expected protobuf.
+  virtual string ExpectedTypeName() const = 0;
+
+  // Name of the type argument given to WhenDeserializedAs<>(), or
+  // "protobuf" for WhenDeserialized().
+  virtual string TypeArgName() const = 0;
+
+  // Deserializes the string as a protobuf of the same type as the expected
+  // protobuf.
+  Proto* Deserialize(google::protobuf::io::ZeroCopyInputStream* input) const {
+    Proto* proto = MakeEmptyProto();
+    // ParsePartialFromString() parses a serialized representation of a
+    // protobuf, allowing required fields to be missing.  This means
+    // that we don't insist on the parsed protobuf being fully
+    // initialized.  This allows the user to choose whether it should
+    // be initialized using EqualsProto vs EqualsInitializedProto, for
+    // example.
+    if (proto->ParsePartialFromZeroCopyStream(input)) {
+      return proto;
+    } else {
+      delete proto;
+      return NULL;
+    }
+  }
+
+  void DescribeTo(::std::ostream* os) const {
+    *os << "can be deserialized as a " << TypeArgName() << " that ";
+    proto_matcher_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "cannot be deserialized as a " << TypeArgName() << " that ";
+    proto_matcher_.DescribeTo(os);
+  }
+
+  bool MatchAndExplain(google::protobuf::io::ZeroCopyInputStream* arg,
+                       ::testing::MatchResultListener* listener) const {
+    // Deserializes the string arg as a protobuf of the same type as the
+    // expected protobuf.
+    ::std::unique_ptr<const Proto> deserialized_arg(Deserialize(arg));
+    if (!listener->IsInterested()) {
+      // No need to explain the match result.
+      return (deserialized_arg != NULL) &&
+          proto_matcher_.Matches(*deserialized_arg);
+    }
+
+    ::std::ostream* const os = listener->stream();
+    if (deserialized_arg == NULL) {
+      *os << "which cannot be deserialized as a " << ExpectedTypeName();
+      return false;
+    }
+
+    *os << "which deserializes to ";
+    UniversalPrint(*deserialized_arg, os);
+
+    ::testing::StringMatchResultListener inner_listener;
+    const bool match =
+        proto_matcher_.MatchAndExplain(*deserialized_arg, &inner_listener);
+    const string explain = inner_listener.str();
+    if (explain != "") {
+      *os << ",\n" << explain;
+    }
+
+    return match;
+  }
+
+  bool MatchAndExplain(const string& str,
+                       ::testing::MatchResultListener* listener) const {
+    google::protobuf::io::ArrayInputStream input(str.data(), str.size());
+    return MatchAndExplain(&input, listener);
+  }
+
+  bool MatchAndExplain(absl::string_view sp,
+                       ::testing::MatchResultListener* listener) const {
+    google::protobuf::io::ArrayInputStream input(sp.data(), sp.size());
+    return MatchAndExplain(&input, listener);
+  }
+
+  bool MatchAndExplain(const char* str,
+                       ::testing::MatchResultListener* listener) const {
+    google::protobuf::io::ArrayInputStream input(str, strlen(str));
+    return MatchAndExplain(&input, listener);
+  }
+
+ private:
+  const InnerMatcher proto_matcher_;
+};
+
+// Implements WhenDeserialized(proto_matcher).
+class WhenDeserializedMatcher
+    : public WhenDeserializedMatcherBase<google::protobuf::Message> {
+ public:
+  explicit WhenDeserializedMatcher(const PolymorphicProtoMatcher& proto_matcher)
+      : WhenDeserializedMatcherBase<google::protobuf::Message>(proto_matcher),
+        expected_proto_(proto_matcher.impl().expected()) {}
+
+  virtual google::protobuf::Message* MakeEmptyProto() const {
+    return expected_proto_->New();
+  }
+
+  virtual string ExpectedTypeName() const {
+    return expected_proto_->GetDescriptor()->full_name();
+  }
+
+  virtual string TypeArgName() const { return "protobuf"; }
+
+ private:
+  // The expected protobuf specified in the inner matcher
+  // (proto_matcher_).  We only need a std::shared_ptr to it instead of
+  // making a copy, as the expected protobuf will never be changed
+  // once created.
+  const std::shared_ptr<const google::protobuf::Message> expected_proto_;
+};
+
+// Implements WhenDeserializedAs<Proto>(proto_matcher).
+template <class Proto>
+class WhenDeserializedAsMatcher : public WhenDeserializedMatcherBase<Proto> {
+ public:
+  typedef ::testing::Matcher<const Proto&> InnerMatcher;
+
+  explicit WhenDeserializedAsMatcher(const InnerMatcher& inner_matcher)
+      : WhenDeserializedMatcherBase<Proto>(inner_matcher) {}
+
+  virtual Proto* MakeEmptyProto() const { return new Proto; }
+
+  virtual string ExpectedTypeName() const {
+    return Proto().GetDescriptor()->full_name();
+  }
+
+  virtual string TypeArgName() const { return ExpectedTypeName(); }
+};
+
+// Implements the IsInitializedProto matcher, which is used to verify that a
+// protocol buffer is valid using the IsInitialized method.
+class IsInitializedProtoMatcher {
+ public:
+  void DescribeTo(::std::ostream* os) const {
+    *os << "is a fully initialized protocol buffer";
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "is not a fully initialized protocol buffer";
+  }
+
+  template <typename T>
+  bool MatchAndExplain(T& arg,  // NOLINT
+                       ::testing::MatchResultListener* listener) const {
+    if (!arg.IsInitialized()) {
+      *listener << "which is missing the following required fields: "
+                << arg.InitializationErrorString();
+      return false;
+    }
+    return true;
+  }
+
+  // It's critical for this overload to take a T* instead of a const
+  // T*.  Otherwise the other version would be a better match when arg
+  // is a pointer to a non-const value.
+  template <typename T>
+  bool MatchAndExplain(T* arg, ::testing::MatchResultListener* listener) const {
+    if (listener->IsInterested() && arg != NULL) {
+      *listener << PrintProtoPointee(arg);
+    }
+    if (arg == NULL) {
+      *listener << "which is null";
+      return false;
+    } else if (!arg->IsInitialized()) {
+      *listener << ", which is missing the following required fields: "
+                << arg->InitializationErrorString();
+      return false;
+    } else {
+      return true;
+    }
+  }
+};
+
+// Implements EqualsProto and EquivToProto for 2-tuple matchers.
+class TupleProtoMatcher {
+ public:
+  explicit TupleProtoMatcher(const ProtoComparison& comp)
+      : comp_(new auto(comp)) {}
+
+  TupleProtoMatcher(const TupleProtoMatcher& other)
+      : comp_(new auto(*other.comp_)) {}
+  TupleProtoMatcher(TupleProtoMatcher&& other) = default;
+
+  template <typename T1, typename T2>
+  operator ::testing::Matcher< ::testing::tuple<T1, T2> >() const {
+    return MakeMatcher(new Impl< ::testing::tuple<T1, T2> >(*comp_));
+  }
+  template <typename T1, typename T2>
+  operator ::testing::Matcher<const ::testing::tuple<T1, T2>&>() const {
+    return MakeMatcher(new Impl<const ::testing::tuple<T1, T2>&>(*comp_));
+  }
+
+  // Allows matcher transformers, e.g., Approximately(), Partially(), etc. to
+  // change the behavior of this 2-tuple matcher.
+  TupleProtoMatcher& mutable_impl() { return *this; }
+
+  // Makes this matcher compare floating-points approximately.
+  void SetCompareApproximately() { comp_->float_comp = kProtoApproximate; }
+
+  // Makes this matcher treating NaNs as equal when comparing floating-points.
+  void SetCompareTreatingNaNsAsEqual() { comp_->treating_nan_as_equal = true; }
+
+  // Makes this matcher ignore string elements specified by their fully
+  // qualified names, i.e., names corresponding to FieldDescriptor.full_name().
+  template <class Iterator>
+  void AddCompareIgnoringFields(Iterator first, Iterator last) {
+    comp_->ignore_fields.insert(comp_->ignore_fields.end(), first, last);
+  }
+
+  // Makes this matcher ignore string elements specified by their relative
+  // FieldPath.
+  template <class Iterator>
+  void AddCompareIgnoringFieldPaths(Iterator first, Iterator last) {
+    comp_->ignore_field_paths.insert(comp_->ignore_field_paths.end(), first,
+                                     last);
+  }
+
+  // Makes this matcher compare repeated fields ignoring ordering of elements.
+  void SetCompareRepeatedFieldsIgnoringOrdering() {
+    comp_->repeated_field_comp = kProtoCompareRepeatedFieldsIgnoringOrdering;
+  }
+
+  // Sets the margin of error for approximate floating point comparison.
+  void SetMargin(double margin) {
+    CHECK_GE(margin, 0.0) << "Using a negative margin for Approximately";
+    comp_->has_custom_margin = true;
+    comp_->float_margin = margin;
+  }
+
+  // Sets the relative fraction of error for approximate floating point
+  // comparison.
+  void SetFraction(double fraction) {
+    CHECK(0.0 <= fraction && fraction <= 1.0) <<
+        "Fraction for Relatively must be >= 0.0 and < 1.0";
+    comp_->has_custom_fraction = true;
+    comp_->float_fraction = fraction;
+  }
+
+  // Makes this matcher compares protobufs partially.
+  void SetComparePartially() { comp_->scope = kProtoPartial; }
+
+ private:
+  template <typename Tuple>
+  class Impl : public ::testing::MatcherInterface<Tuple> {
+   public:
+    explicit Impl(const ProtoComparison& comp) : comp_(comp) {}
+    virtual bool MatchAndExplain(
+        Tuple args, ::testing::MatchResultListener* /* listener */) const {
+      using ::testing::get;
+      return ProtoCompare(comp_, get<0>(args), get<1>(args));
+    }
+    virtual void DescribeTo(::std::ostream* os) const {
+      *os << (comp_.field_comp == kProtoEqual ? "are equal"
+                                               : "are equivalent");
+    }
+    virtual void DescribeNegationTo(::std::ostream* os) const {
+      *os << (comp_.field_comp == kProtoEqual ? "are not equal"
+                                               : "are not equivalent");
+    }
+
+   private:
+    const ProtoComparison comp_;
+  };
+
+  std::unique_ptr<ProtoComparison> comp_;
+};
+
+}  // namespace internal
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// first.Equals(second) is true.
+inline internal::TupleProtoMatcher EqualsProto() {
+  internal::ProtoComparison comp;
+  comp.field_comp = internal::kProtoEqual;
+  return internal::TupleProtoMatcher(comp);
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// first.Equivalent(second) is true.
+inline internal::TupleProtoMatcher EquivToProto() {
+  internal::ProtoComparison comp;
+  comp.field_comp = internal::kProtoEquiv;
+  return internal::TupleProtoMatcher(comp);
+}
+
+// Constructs a matcher that matches the argument if
+// argument.Equals(x) or argument->Equals(x) returns true.
+inline internal::PolymorphicProtoMatcher EqualsProto(const google::protobuf::Message& x) {
+  internal::ProtoComparison comp;
+  comp.field_comp = internal::kProtoEqual;
+  return ::testing::MakePolymorphicMatcher(
+      internal::ProtoMatcher(x, internal::kMayBeUninitialized, comp));
+}
+inline ::testing::PolymorphicMatcher<internal::ProtoStringMatcher> EqualsProto(
+    const string& x) {
+  internal::ProtoComparison comp;
+  comp.field_comp = internal::kProtoEqual;
+  return ::testing::MakePolymorphicMatcher(
+      internal::ProtoStringMatcher(x, internal::kMayBeUninitialized, comp));
+}
+template <class Proto>
+inline internal::PolymorphicProtoMatcher EqualsProto(const string& str) {
+  return EqualsProto(internal::MakePartialProtoFromAscii<Proto>(str));
+}
+
+// Constructs a matcher that matches the argument if
+// argument.Equivalent(x) or argument->Equivalent(x) returns true.
+inline internal::PolymorphicProtoMatcher
+EquivToProto(const google::protobuf::Message& x) {
+  internal::ProtoComparison comp;
+  comp.field_comp = internal::kProtoEquiv;
+  return ::testing::MakePolymorphicMatcher(
+      internal::ProtoMatcher(x, internal::kMayBeUninitialized, comp));
+}
+inline ::testing::PolymorphicMatcher<internal::ProtoStringMatcher> EquivToProto(
+    const string& x) {
+  internal::ProtoComparison comp;
+  comp.field_comp = internal::kProtoEquiv;
+  return ::testing::MakePolymorphicMatcher(
+      internal::ProtoStringMatcher(x, internal::kMayBeUninitialized, comp));
+}
+template <class Proto>
+inline internal::PolymorphicProtoMatcher EquivToProto(const string& str) {
+  return EquivToProto(internal::MakePartialProtoFromAscii<Proto>(str));
+}
+
+// Constructs a matcher that matches the argument if
+// argument.IsInitialized() or argument->IsInitialized() returns true.
+inline ::testing::PolymorphicMatcher<internal::IsInitializedProtoMatcher>
+IsInitializedProto() {
+  return ::testing::MakePolymorphicMatcher(
+      internal::IsInitializedProtoMatcher());
+}
+
+// Constructs a matcher that matches an argument whose IsInitialized()
+// and Equals(x) methods both return true.  The argument can be either
+// a protocol buffer or a pointer to it.
+inline internal::PolymorphicProtoMatcher
+EqualsInitializedProto(const google::protobuf::Message& x) {
+  internal::ProtoComparison comp;
+  comp.field_comp = internal::kProtoEqual;
+  return ::testing::MakePolymorphicMatcher(
+      internal::ProtoMatcher(x, internal::kMustBeInitialized, comp));
+}
+inline ::testing::PolymorphicMatcher<internal::ProtoStringMatcher>
+EqualsInitializedProto(const string& x) {
+  internal::ProtoComparison comp;
+  comp.field_comp = internal::kProtoEqual;
+  return ::testing::MakePolymorphicMatcher(
+      internal::ProtoStringMatcher(x, internal::kMustBeInitialized, comp));
+}
+template <class Proto>
+inline internal::PolymorphicProtoMatcher EqualsInitializedProto(
+    const string& str) {
+  return EqualsInitializedProto(
+      internal::MakePartialProtoFromAscii<Proto>(str));
+}
+
+// Constructs a matcher that matches an argument whose IsInitialized()
+// and Equivalent(x) methods both return true.  The argument can be
+// either a protocol buffer or a pointer to it.
+inline internal::PolymorphicProtoMatcher
+EquivToInitializedProto(const google::protobuf::Message& x) {
+  internal::ProtoComparison comp;
+  comp.field_comp = internal::kProtoEquiv;
+  return ::testing::MakePolymorphicMatcher(
+      internal::ProtoMatcher(x, internal::kMustBeInitialized, comp));
+}
+inline ::testing::PolymorphicMatcher<internal::ProtoStringMatcher>
+EquivToInitializedProto(const string& x) {
+  internal::ProtoComparison comp;
+  comp.field_comp = internal::kProtoEquiv;
+  return ::testing::MakePolymorphicMatcher(
+      internal::ProtoStringMatcher(x, internal::kMustBeInitialized, comp));
+}
+template <class Proto>
+inline internal::PolymorphicProtoMatcher EquivToInitializedProto(
+    const string& str) {
+  return EquivToInitializedProto(
+      internal::MakePartialProtoFromAscii<Proto>(str));
+}
+
+namespace proto {
+
+// Approximately(m) returns a matcher that is the same as m, except
+// that it compares floating-point fields approximately (using
+// google::protobuf::util::MessageDifferencer's APPROXIMATE comparison option).
+// The inner matcher m can be any of the Equals* and EquivTo* protobuf
+// matchers above.
+template <class InnerProtoMatcher>
+inline InnerProtoMatcher Approximately(InnerProtoMatcher inner_proto_matcher) {
+  inner_proto_matcher.mutable_impl().SetCompareApproximately();
+  return inner_proto_matcher;
+}
+
+// Alternative version of Approximately which takes an explicit margin of error.
+template <class InnerProtoMatcher>
+inline InnerProtoMatcher Approximately(InnerProtoMatcher inner_proto_matcher,
+                                       double margin) {
+  inner_proto_matcher.mutable_impl().SetCompareApproximately();
+  inner_proto_matcher.mutable_impl().SetMargin(margin);
+  return inner_proto_matcher;
+}
+
+// Alternative version of Approximately which takes an explicit margin of error
+// and a relative fraction of error and will match if either is satisfied.
+template <class InnerProtoMatcher>
+inline InnerProtoMatcher Approximately(InnerProtoMatcher inner_proto_matcher,
+                                       double margin, double fraction) {
+  inner_proto_matcher.mutable_impl().SetCompareApproximately();
+  inner_proto_matcher.mutable_impl().SetMargin(margin);
+  inner_proto_matcher.mutable_impl().SetFraction(fraction);
+  return inner_proto_matcher;
+}
+
+// TreatingNaNsAsEqual(m) returns a matcher that is the same as m, except that
+// it compares floating-point fields such that NaNs are equal.
+// The inner matcher m can be any of the Equals* and EquivTo* protobuf matchers
+// above.
+template <class InnerProtoMatcher>
+inline InnerProtoMatcher TreatingNaNsAsEqual(
+    InnerProtoMatcher inner_proto_matcher) {
+  inner_proto_matcher.mutable_impl().SetCompareTreatingNaNsAsEqual();
+  return inner_proto_matcher;
+}
+
+// IgnoringFields(fields, m) returns a matcher that is the same as m, except the
+// specified fields will be ignored when matching
+// (using google::protobuf::util::MessageDifferencer::IgnoreField). Each element in fields
+// are specified by their fully qualified names, i.e., the names corresponding
+// to FieldDescriptor.full_name(). (e.g. testing.internal.FooProto2.member).
+// m can be any of the Equals* and EquivTo* protobuf matchers above.
+// It can also be any of the transformer matchers listed here (e.g.
+// Approximately, TreatingNaNsAsEqual) as long as the intent of the each
+// concatenated matcher is mutually exclusive (e.g. using IgnoringFields in
+// conjunction with Partially can have different results depending on whether
+// the fields specified in IgnoringFields is part of the fields covered by
+// Partially).
+template <class InnerProtoMatcher, class Container>
+inline InnerProtoMatcher IgnoringFields(const Container& ignore_fields,
+                                        InnerProtoMatcher inner_proto_matcher) {
+  inner_proto_matcher.mutable_impl().AddCompareIgnoringFields(
+      ignore_fields.begin(), ignore_fields.end());
+  return inner_proto_matcher;
+}
+
+// See top comment.
+template <class InnerProtoMatcher, class Container>
+inline InnerProtoMatcher IgnoringFieldPaths(
+    const Container& ignore_field_paths,
+    InnerProtoMatcher inner_proto_matcher) {
+  inner_proto_matcher.mutable_impl().AddCompareIgnoringFieldPaths(
+      ignore_field_paths.begin(), ignore_field_paths.end());
+  return inner_proto_matcher;
+}
+
+#ifdef LANG_CXX11
+template <class InnerProtoMatcher, class T>
+inline InnerProtoMatcher IgnoringFields(std::initializer_list<T> il,
+                                        InnerProtoMatcher inner_proto_matcher) {
+  inner_proto_matcher.mutable_impl().AddCompareIgnoringFields(
+      il.begin(), il.end());
+  return inner_proto_matcher;
+}
+
+template <class InnerProtoMatcher, class T>
+inline InnerProtoMatcher IgnoringFieldPaths(
+    std::initializer_list<T> il, InnerProtoMatcher inner_proto_matcher) {
+  inner_proto_matcher.mutable_impl().AddCompareIgnoringFieldPaths(il.begin(),
+                                                                  il.end());
+  return inner_proto_matcher;
+}
+#endif  // LANG_CXX11
+
+// IgnoringRepeatedFieldOrdering(m) returns a matcher that is the same as m,
+// except that it ignores the relative ordering of elements within each repeated
+// field in m. See google::protobuf::MessageDifferencer::TreatAsSet() for more details.
+template <class InnerProtoMatcher>
+inline InnerProtoMatcher IgnoringRepeatedFieldOrdering(
+    InnerProtoMatcher inner_proto_matcher) {
+  inner_proto_matcher.mutable_impl().SetCompareRepeatedFieldsIgnoringOrdering();
+  return inner_proto_matcher;
+}
+
+// Partially(m) returns a matcher that is the same as m, except that
+// only fields present in the expected protobuf are considered (using
+// google::protobuf::util::MessageDifferencer's PARTIAL comparison option).  For
+// example, Partially(EqualsProto(p)) will ignore any field that's
+// not set in p when comparing the protobufs. The inner matcher m can
+// be any of the Equals* and EquivTo* protobuf matchers above.
+template <class InnerProtoMatcher>
+inline InnerProtoMatcher Partially(InnerProtoMatcher inner_proto_matcher) {
+  inner_proto_matcher.mutable_impl().SetComparePartially();
+  return inner_proto_matcher;
+}
+
+// WhenDeserialized(m) is a matcher that matches a string that can be
+// deserialized as a protobuf that matches m.  m must be a protobuf
+// matcher where the expected protobuf type is known at run time.
+inline ::testing::PolymorphicMatcher<internal::WhenDeserializedMatcher>
+WhenDeserialized(const internal::PolymorphicProtoMatcher& proto_matcher) {
+  return ::testing::MakePolymorphicMatcher(
+      internal::WhenDeserializedMatcher(proto_matcher));
+}
+
+// WhenDeserializedAs<Proto>(m) is a matcher that matches a string
+// that can be deserialized as a protobuf of type Proto that matches
+// m, which can be any valid protobuf matcher.
+template <class Proto, class InnerMatcher>
+inline ::testing::PolymorphicMatcher<
+    internal::WhenDeserializedAsMatcher<Proto> >
+WhenDeserializedAs(const InnerMatcher& inner_matcher) {
+  return MakePolymorphicMatcher(internal::WhenDeserializedAsMatcher<Proto>(
+      ::testing::SafeMatcherCast<const Proto&>(inner_matcher)));
+}
+
+}  // namespace proto
+}  // namespace nucleus
+
+#endif  // THIRD_PARTY_NUCLEUS_TESTING_PROTOCOL_BUFFER_MATCHERS_H_