diff --git a/BUILD b/BUILD
index 8713d760b58..da2de3c321b 100644
--- a/BUILD
+++ b/BUILD
@@ -1517,6 +1517,7 @@ grpc_cc_library(
"//src/core:map",
"//src/core:match",
"//src/core:memory_quota",
+ "//src/core:metadata_compression_traits",
"//src/core:no_destruct",
"//src/core:notification",
"//src/core:packed_table",
@@ -3672,6 +3673,7 @@ grpc_cc_library(
"http_trace",
"//src/core:hpack_constants",
"//src/core:hpack_encoder_table",
+ "//src/core:metadata_compression_traits",
"//src/core:slice",
"//src/core:slice_buffer",
"//src/core:time",
diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml
index cb910eb4989..5dc74baa585 100644
--- a/build_autogenerated.yaml
+++ b/build_autogenerated.yaml
@@ -953,6 +953,7 @@ libs:
- src/core/lib/transport/http2_errors.h
- src/core/lib/transport/http_connect_handshaker.h
- src/core/lib/transport/metadata_batch.h
+ - src/core/lib/transport/metadata_compression_traits.h
- src/core/lib/transport/parsed_metadata.h
- src/core/lib/transport/pid_controller.h
- src/core/lib/transport/simple_slice_based_metadata.h
@@ -2279,6 +2280,7 @@ libs:
- src/core/lib/transport/http2_errors.h
- src/core/lib/transport/http_connect_handshaker.h
- src/core/lib/transport/metadata_batch.h
+ - src/core/lib/transport/metadata_compression_traits.h
- src/core/lib/transport/parsed_metadata.h
- src/core/lib/transport/pid_controller.h
- src/core/lib/transport/simple_slice_based_metadata.h
@@ -3748,6 +3750,7 @@ libs:
- src/core/lib/transport/handshaker_registry.h
- src/core/lib/transport/http2_errors.h
- src/core/lib/transport/metadata_batch.h
+ - src/core/lib/transport/metadata_compression_traits.h
- src/core/lib/transport/parsed_metadata.h
- src/core/lib/transport/simple_slice_based_metadata.h
- src/core/lib/transport/status_conversion.h
@@ -7658,6 +7661,7 @@ targets:
- src/core/lib/transport/handshaker_registry.h
- src/core/lib/transport/http2_errors.h
- src/core/lib/transport/metadata_batch.h
+ - src/core/lib/transport/metadata_compression_traits.h
- src/core/lib/transport/parsed_metadata.h
- src/core/lib/transport/simple_slice_based_metadata.h
- src/core/lib/transport/status_conversion.h
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index f5b198c3cb0..8bd8f893c09 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -1048,6 +1048,7 @@ Pod::Spec.new do |s|
'src/core/lib/transport/http2_errors.h',
'src/core/lib/transport/http_connect_handshaker.h',
'src/core/lib/transport/metadata_batch.h',
+ 'src/core/lib/transport/metadata_compression_traits.h',
'src/core/lib/transport/parsed_metadata.h',
'src/core/lib/transport/pid_controller.h',
'src/core/lib/transport/simple_slice_based_metadata.h',
@@ -2070,6 +2071,7 @@ Pod::Spec.new do |s|
'src/core/lib/transport/http2_errors.h',
'src/core/lib/transport/http_connect_handshaker.h',
'src/core/lib/transport/metadata_batch.h',
+ 'src/core/lib/transport/metadata_compression_traits.h',
'src/core/lib/transport/parsed_metadata.h',
'src/core/lib/transport/pid_controller.h',
'src/core/lib/transport/simple_slice_based_metadata.h',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 76f6dab4cb8..06f70780baf 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -1740,6 +1740,7 @@ Pod::Spec.new do |s|
'src/core/lib/transport/http_connect_handshaker.h',
'src/core/lib/transport/metadata_batch.cc',
'src/core/lib/transport/metadata_batch.h',
+ 'src/core/lib/transport/metadata_compression_traits.h',
'src/core/lib/transport/parsed_metadata.cc',
'src/core/lib/transport/parsed_metadata.h',
'src/core/lib/transport/pid_controller.cc',
@@ -2788,6 +2789,7 @@ Pod::Spec.new do |s|
'src/core/lib/transport/http2_errors.h',
'src/core/lib/transport/http_connect_handshaker.h',
'src/core/lib/transport/metadata_batch.h',
+ 'src/core/lib/transport/metadata_compression_traits.h',
'src/core/lib/transport/parsed_metadata.h',
'src/core/lib/transport/pid_controller.h',
'src/core/lib/transport/simple_slice_based_metadata.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index f0241edc19a..96bbf8cf97a 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -1646,6 +1646,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/transport/http_connect_handshaker.h )
s.files += %w( src/core/lib/transport/metadata_batch.cc )
s.files += %w( src/core/lib/transport/metadata_batch.h )
+ s.files += %w( src/core/lib/transport/metadata_compression_traits.h )
s.files += %w( src/core/lib/transport/parsed_metadata.cc )
s.files += %w( src/core/lib/transport/parsed_metadata.h )
s.files += %w( src/core/lib/transport/pid_controller.cc )
diff --git a/package.xml b/package.xml
index b18f1c7fa86..9aba1739886 100644
--- a/package.xml
+++ b/package.xml
@@ -1628,6 +1628,7 @@
+
diff --git a/src/core/BUILD b/src/core/BUILD
index 3a7531c17cd..1bb970e0490 100644
--- a/src/core/BUILD
+++ b/src/core/BUILD
@@ -98,6 +98,14 @@ grpc_cc_library(
deps = ["//:gpr"],
)
+grpc_cc_library(
+ name = "metadata_compression_traits",
+ hdrs = [
+ "lib/transport/metadata_compression_traits.h",
+ ],
+ deps = ["//:gpr_platform"],
+)
+
grpc_cc_library(
name = "experiments",
srcs = [
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
index 4e149f1ca7d..07a924edd06 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
@@ -40,6 +40,7 @@
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/slice/slice_buffer.h"
#include "src/core/lib/transport/metadata_batch.h"
+#include "src/core/lib/transport/metadata_compression_traits.h"
#include "src/core/lib/transport/timeout_encoding.h"
#include "src/core/lib/transport/transport.h"
diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h
index 2290baf1233..4783c81dee9 100644
--- a/src/core/lib/transport/metadata_batch.h
+++ b/src/core/lib/transport/metadata_batch.h
@@ -46,52 +46,12 @@
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/transport/custom_metadata.h"
+#include "src/core/lib/transport/metadata_compression_traits.h"
#include "src/core/lib/transport/parsed_metadata.h"
#include "src/core/lib/transport/simple_slice_based_metadata.h"
namespace grpc_core {
-///////////////////////////////////////////////////////////////////////////////
-// Compression traits.
-//
-// Each metadata trait exposes exactly one compression trait.
-// This type directs how transports might choose to compress the metadata.
-// Adding a value here typically involves editing all transports to support the
-// trait, and so should not be done lightly.
-
-// No compression.
-struct NoCompressionCompressor {};
-
-// Expect a single value for this metadata key, but we don't know apriori its
-// value.
-// It's ok if it changes over time, but it should be mostly stable.
-// This is used for things like user-agent, which is expected to be the same
-// for all requests.
-struct StableValueCompressor {};
-
-// Expect a single value for this metadata key, and we know apriori its value.
-template
-struct KnownValueCompressor {};
-
-// Values are uncompressible, but expect the key to be in most requests and try
-// and compress that.
-struct FrequentKeyWithNoValueCompressionCompressor {};
-
-// Expect a small set of values for this metadata key.
-struct SmallSetOfValuesCompressor {};
-
-// Expect integral values up to N for this metadata key.
-template
-struct SmallIntegralValuesCompressor {};
-
-// Specialty compressor for grpc-timeout metadata.
-struct TimeoutCompressor {};
-
-// Specialty compressors for HTTP/2 psuedo headers.
-struct HttpSchemeCompressor {};
-struct HttpMethodCompressor {};
-struct HttpStatusCompressor {};
-
///////////////////////////////////////////////////////////////////////////////
// Metadata traits
diff --git a/src/core/lib/transport/metadata_compression_traits.h b/src/core/lib/transport/metadata_compression_traits.h
new file mode 100644
index 00000000000..002caf069d5
--- /dev/null
+++ b/src/core/lib/transport/metadata_compression_traits.h
@@ -0,0 +1,67 @@
+// Copyright 2023 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_COMPRESSION_TRAITS_H
+#define GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_COMPRESSION_TRAITS_H
+
+#include
+
+#include
+
+namespace grpc_core {
+
+///////////////////////////////////////////////////////////////////////////////
+// Compression traits.
+//
+// Each metadata trait exposes exactly one compression trait.
+// This type directs how transports might choose to compress the metadata.
+// Adding a value here typically involves editing all transports to support the
+// trait, and so should not be done lightly.
+
+// No compression.
+struct NoCompressionCompressor {};
+
+// Expect a single value for this metadata key, but we don't know apriori its
+// value.
+// It's ok if it changes over time, but it should be mostly stable.
+// This is used for things like user-agent, which is expected to be the same
+// for all requests.
+struct StableValueCompressor {};
+
+// Expect a single value for this metadata key, and we know apriori its value.
+template
+struct KnownValueCompressor {};
+
+// Values are uncompressible, but expect the key to be in most requests and try
+// and compress that.
+struct FrequentKeyWithNoValueCompressionCompressor {};
+
+// Expect a small set of values for this metadata key.
+struct SmallSetOfValuesCompressor {};
+
+// Expect integral values up to N for this metadata key.
+template
+struct SmallIntegralValuesCompressor {};
+
+// Specialty compressor for grpc-timeout metadata.
+struct TimeoutCompressor {};
+
+// Specialty compressors for HTTP/2 psuedo headers.
+struct HttpSchemeCompressor {};
+struct HttpMethodCompressor {};
+struct HttpStatusCompressor {};
+
+} // namespace grpc_core
+
+#endif // GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_COMPRESSION_TRAITS_H
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index a02873896d1..167b262149a 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -2641,6 +2641,7 @@ src/core/lib/transport/http_connect_handshaker.cc \
src/core/lib/transport/http_connect_handshaker.h \
src/core/lib/transport/metadata_batch.cc \
src/core/lib/transport/metadata_batch.h \
+src/core/lib/transport/metadata_compression_traits.h \
src/core/lib/transport/parsed_metadata.cc \
src/core/lib/transport/parsed_metadata.h \
src/core/lib/transport/pid_controller.cc \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index c1b20e05e16..a3b3d112374 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -2425,6 +2425,7 @@ src/core/lib/transport/http_connect_handshaker.cc \
src/core/lib/transport/http_connect_handshaker.h \
src/core/lib/transport/metadata_batch.cc \
src/core/lib/transport/metadata_batch.h \
+src/core/lib/transport/metadata_compression_traits.h \
src/core/lib/transport/parsed_metadata.cc \
src/core/lib/transport/parsed_metadata.h \
src/core/lib/transport/pid_controller.cc \