Add PrintTo method to BinaryHttpMessage::Field

This helps to make output from failed unit tests easier to read.  (Fields were
previously printed as byte strings in some places.)

PiperOrigin-RevId: 483463738
diff --git a/quiche/binary_http/binary_http_message.cc b/quiche/binary_http/binary_http_message.cc
index 93d25bf..24feedf 100644
--- a/quiche/binary_http/binary_http_message.cc
+++ b/quiche/binary_http/binary_http_message.cc
@@ -394,12 +394,12 @@
   for (const auto& field : GetHeaderFields()) {
     headers.emplace_back(field.DebugString());
   }
-  return absl::StrCat("BinaryHttpMessage{Headers{",
-                      absl::StrJoin(headers, ";;"), "}Body{", body(), "}}");
+  return absl::StrCat("BinaryHttpMessage{Headers{", absl::StrJoin(headers, ";"),
+                      "}Body{", body(), "}}");
 }
 
 std::string BinaryHttpMessage::Field::DebugString() const {
-  return absl::StrCat(name, "=", value);
+  return absl::StrCat("Field{", name, "=", value, "}");
 }
 
 std::string BinaryHttpResponse::InformationalResponse::DebugString() const {
@@ -407,7 +407,7 @@
   for (const auto& field : fields()) {
     fs.emplace_back(field.DebugString());
   }
-  return absl::StrCat("InformationalResponse{", absl::StrJoin(fs, ";;"), "}");
+  return absl::StrCat("InformationalResponse{", absl::StrJoin(fs, ";"), "}");
 }
 
 std::string BinaryHttpResponse::DebugString() const {
@@ -416,8 +416,8 @@
     irs.emplace_back(ir.DebugString());
   }
   return absl::StrCat("BinaryHttpResponse(", status_code_, "){",
-                      BinaryHttpMessage::DebugString(),
-                      absl::StrJoin(irs, ";;"), "}");
+                      BinaryHttpMessage::DebugString(), absl::StrJoin(irs, ";"),
+                      "}");
 }
 
 std::string BinaryHttpRequest::DebugString() const {
@@ -433,4 +433,8 @@
   *os << msg.DebugString();
 }
 
+void PrintTo(const BinaryHttpMessage::Field& msg, std::ostream* os) {
+  *os << msg.DebugString();
+}
+
 }  // namespace quiche
diff --git a/quiche/binary_http/binary_http_message.h b/quiche/binary_http/binary_http_message.h
index 250e109..91d5b1c 100644
--- a/quiche/binary_http/binary_http_message.h
+++ b/quiche/binary_http/binary_http_message.h
@@ -108,6 +108,9 @@
   bool has_host_ = false;
 };
 
+void QUICHE_EXPORT PrintTo(const BinaryHttpMessage::Field& msg,
+                           std::ostream* os);
+
 class QUICHE_EXPORT BinaryHttpRequest : public BinaryHttpMessage {
  public:
   // HTTP request must have all of the following fields.
diff --git a/quiche/binary_http/binary_http_message_test.cc b/quiche/binary_http/binary_http_message_test.cc
index dc6b279..1ecd9f9 100644
--- a/quiche/binary_http/binary_http_message_test.cc
+++ b/quiche/binary_http/binary_http_message_test.cc
@@ -74,10 +74,11 @@
   ASSERT_EQ(*result, expected);
   EXPECT_THAT(
       request.DebugString(),
-      StrEq(
-          "BinaryHttpRequest{BinaryHttpMessage{Headers{user-agent=curl/7.16.3 "
-          "libcurl/7.16.3 OpenSSL/0.9.7l "
-          "zlib/1.2.3;;host=www.example.com;;accept-language=en, mi}Body{}}}"));
+      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{Field{user-agent=curl/"
+            "7.16.3 "
+            "libcurl/7.16.3 OpenSSL/0.9.7l "
+            "zlib/1.2.3};Field{host=www.example.com};Field{accept-language=en, "
+            "mi}}Body{}}}"));
   TestPrintTo(request);
 }
 
@@ -102,14 +103,18 @@
       {"user-agent", "curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3"},
       {"host", "www.example.com"},
       {"accept-language", "en, mi"}};
+  for (const auto& field : expected_fields) {
+    TestPrintTo(field);
+  }
   ASSERT_THAT(request.GetHeaderFields(), ContainerEq(expected_fields));
   ASSERT_EQ(request.body(), "");
   EXPECT_THAT(
       request.DebugString(),
-      StrEq(
-          "BinaryHttpRequest{BinaryHttpMessage{Headers{user-agent=curl/7.16.3 "
-          "libcurl/7.16.3 OpenSSL/0.9.7l "
-          "zlib/1.2.3;;host=www.example.com;;accept-language=en, mi}Body{}}}"));
+      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{Field{user-agent=curl/"
+            "7.16.3 "
+            "libcurl/7.16.3 OpenSSL/0.9.7l "
+            "zlib/1.2.3};Field{host=www.example.com};Field{accept-language=en, "
+            "mi}}Body{}}}"));
   TestPrintTo(request);
 }
 
@@ -151,9 +156,9 @@
   ASSERT_EQ(*result, expected);
   EXPECT_THAT(
       request.DebugString(),
-      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{user-agent=curl/"
+      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{Field{user-agent=curl/"
             "7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l "
-            "zlib/1.2.3;;accept-language=en, mi}Body{}}}"));
+            "zlib/1.2.3};Field{accept-language=en, mi}}Body{}}}"));
 }
 
 TEST(BinaryHttpRequest, DecodeGetWithAuthority) {
@@ -180,9 +185,9 @@
   ASSERT_EQ(request.body(), "");
   EXPECT_THAT(
       request.DebugString(),
-      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{user-agent=curl/"
+      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{Field{user-agent=curl/"
             "7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l "
-            "zlib/1.2.3;;accept-language=en, mi}Body{}}}"));
+            "zlib/1.2.3};Field{accept-language=en, mi}}Body{}}}"));
 }
 
 TEST(BinaryHttpRequest, EncodePostBody) {
@@ -227,8 +232,9 @@
   ASSERT_EQ(*result, expected);
   EXPECT_THAT(
       request.DebugString(),
-      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{user-agent=not/"
-            "telling;;host=www.example.com;;accept-language=en}Body{Some "
+      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{Field{user-agent=not/"
+            "telling};Field{host=www.example.com};Field{accept-language=en}}"
+            "Body{Some "
             "body that I used to post.\r\n}}}"));
 }
 
@@ -257,8 +263,9 @@
   ASSERT_EQ(request.body(), "Some body that I used to post.\r\n");
   EXPECT_THAT(
       request.DebugString(),
-      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{user-agent=not/"
-            "telling;;host=www.example.com;;accept-language=en}Body{Some "
+      StrEq("BinaryHttpRequest{BinaryHttpMessage{Headers{Field{user-agent=not/"
+            "telling};Field{host=www.example.com};Field{accept-language=en}}"
+            "Body{Some "
             "body that I used to post.\r\n}}}"));
 }
 
@@ -328,9 +335,10 @@
   const auto result = response.Serialize();
   ASSERT_TRUE(result.ok());
   ASSERT_EQ(*result, expected);
-  EXPECT_THAT(response.DebugString(),
-              StrEq("BinaryHttpResponse(404){BinaryHttpMessage{Headers{server="
-                    "Apache}Body{}}}"));
+  EXPECT_THAT(
+      response.DebugString(),
+      StrEq("BinaryHttpResponse(404){BinaryHttpMessage{Headers{Field{server="
+            "Apache}}Body{}}}"));
 }
 
 TEST(BinaryHttpResponse, DecodeNoBody) {
@@ -353,9 +361,10 @@
   ASSERT_THAT(response.GetHeaderFields(), ContainerEq(expected_fields));
   ASSERT_EQ(response.body(), "");
   ASSERT_TRUE(response.informational_responses().empty());
-  EXPECT_THAT(response.DebugString(),
-              StrEq("BinaryHttpResponse(404){BinaryHttpMessage{Headers{server="
-                    "Apache}Body{}}}"));
+  EXPECT_THAT(
+      response.DebugString(),
+      StrEq("BinaryHttpResponse(404){BinaryHttpMessage{Headers{Field{server="
+            "Apache}}Body{}}}"));
 }
 
 TEST(BinaryHttpResponse, EncodeBody) {
@@ -386,9 +395,10 @@
   const auto result = response.Serialize();
   ASSERT_TRUE(result.ok());
   ASSERT_EQ(*result, expected);
-  EXPECT_THAT(response.DebugString(),
-              StrEq("BinaryHttpResponse(200){BinaryHttpMessage{Headers{server="
-                    "Apache}Body{Hello, world!\r\n}}}"));
+  EXPECT_THAT(
+      response.DebugString(),
+      StrEq("BinaryHttpResponse(200){BinaryHttpMessage{Headers{Field{server="
+            "Apache}}Body{Hello, world!\r\n}}}"));
 }
 
 TEST(BinaryHttpResponse, DecodeBody) {
@@ -413,9 +423,10 @@
   ASSERT_THAT(response.GetHeaderFields(), ContainerEq(expected_fields));
   ASSERT_EQ(response.body(), "Hello, world!\r\n");
   ASSERT_TRUE(response.informational_responses().empty());
-  EXPECT_THAT(response.DebugString(),
-              StrEq("BinaryHttpResponse(200){BinaryHttpMessage{Headers{server="
-                    "Apache}Body{Hello, world!\r\n}}}"));
+  EXPECT_THAT(
+      response.DebugString(),
+      StrEq("BinaryHttpResponse(200){BinaryHttpMessage{Headers{Field{server="
+            "Apache}}Body{Hello, world!\r\n}}}"));
 }
 
 TEST(BHttpResponse, AddBadInformationalResponseCode) {
@@ -515,15 +526,18 @@
   ASSERT_EQ(*result, expected);
   EXPECT_THAT(
       response.DebugString(),
-      StrEq("BinaryHttpResponse(200){BinaryHttpMessage{Headers{date=Mon, "
-            "27 Jul 2009 12:28:53 GMT;;server=Apache;;last-modified=Wed, "
-            "22 Jul 2009 19:15:56 "
-            "GMT;;etag=\"34aa387-d-1568eb00\";;accept-ranges=bytes;;"
-            "content-length=51;;vary=Accept-Encoding;;content-type=text/"
-            "plain}Body{Hello World! My content includes a trailing "
-            "CRLF.\r\n}}InformationalResponse{running=\"sleep "
-            "15\"};;InformationalResponse{link=</style.css>; rel=preload; "
-            "as=style;;link=</script.js>; rel=preload; as=script}}"));
+      StrEq(
+          "BinaryHttpResponse(200){BinaryHttpMessage{Headers{Field{date=Mon, "
+          "27 Jul 2009 12:28:53 "
+          "GMT};Field{server=Apache};Field{last-modified=Wed, 22 Jul 2009 "
+          "19:15:56 "
+          "GMT};Field{etag=\"34aa387-d-1568eb00\"};Field{accept-ranges=bytes};"
+          "Field{"
+          "content-length=51};Field{vary=Accept-Encoding};Field{content-type="
+          "text/plain}}Body{Hello World! My content includes a trailing "
+          "CRLF.\r\n}}InformationalResponse{Field{running=\"sleep "
+          "15\"}};InformationalResponse{Field{link=</style.css>; rel=preload; "
+          "as=style};Field{link=</script.js>; rel=preload; as=script}}}"));
   TestPrintTo(response);
 }
 
@@ -581,6 +595,7 @@
       {"content-length", "51"},
       {"vary", "Accept-Encoding"},
       {"content-type", "text/plain"}};
+
   ASSERT_THAT(response.GetHeaderFields(), ContainerEq(expected_fields));
   ASSERT_EQ(response.body(),
             "Hello World! My content includes a trailing CRLF.\r\n");
@@ -595,15 +610,18 @@
               ContainerEq(expected_control));
   EXPECT_THAT(
       response.DebugString(),
-      StrEq("BinaryHttpResponse(200){BinaryHttpMessage{Headers{date=Mon, "
-            "27 Jul 2009 12:28:53 GMT;;server=Apache;;last-modified=Wed, "
-            "22 Jul 2009 19:15:56 "
-            "GMT;;etag=\"34aa387-d-1568eb00\";;accept-ranges=bytes;;"
-            "content-length=51;;vary=Accept-Encoding;;content-type=text/"
-            "plain}Body{Hello World! My content includes a trailing "
-            "CRLF.\r\n}}InformationalResponse{running=\"sleep "
-            "15\"};;InformationalResponse{link=</style.css>; rel=preload; "
-            "as=style;;link=</script.js>; rel=preload; as=script}}"));
+      StrEq(
+          "BinaryHttpResponse(200){BinaryHttpMessage{Headers{Field{date=Mon, "
+          "27 Jul 2009 12:28:53 "
+          "GMT};Field{server=Apache};Field{last-modified=Wed, 22 Jul 2009 "
+          "19:15:56 "
+          "GMT};Field{etag=\"34aa387-d-1568eb00\"};Field{accept-ranges=bytes};"
+          "Field{"
+          "content-length=51};Field{vary=Accept-Encoding};Field{content-type="
+          "text/plain}}Body{Hello World! My content includes a trailing "
+          "CRLF.\r\n}}InformationalResponse{Field{running=\"sleep "
+          "15\"}};InformationalResponse{Field{link=</style.css>; rel=preload; "
+          "as=style};Field{link=</script.js>; rel=preload; as=script}}}"));
   TestPrintTo(response);
 }