This is an automated email from the ASF dual-hosted git repository.
schofielaj pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/kafka.git
The following commit(s) were added to refs/heads/trunk by this push:
new 33cd1143756 KAFKA-9825 Kafka protocol BNF format should have some way
to display tagged fields (#20536)
33cd1143756 is described below
commit 33cd1143756a2eb31de81eaa8da8b38563f5927e
Author: Chang-Yu Huang <[email protected]>
AuthorDate: Thu Oct 2 06:01:53 2025 -0400
KAFKA-9825 Kafka protocol BNF format should have some way to display tagged
fields (#20536)
# Description
The [protocol guide](https://kafka.apache.org/protocol) 1) doesn't
display
tagged fields in BNF, and 2) includes empty tagged fields and redundant
nested tables in tables.
# Change
## BNF
Now tagged fields are displayed as FIELD_NAME<tag number>
Old: <img width="1316" height="275" alt="Screenshot 2025-09-13 at 5 34
28 PM"
src="https://github.com/user-attachments/assets/c3e59382-7a6b-43f3-bc7a-893fb27d524d"
/>
New: <img width="1386" height="328" alt="Screenshot 2025-09-24 at 12 50
34 PM"
src="https://github.com/user-attachments/assets/1ddbc95e-b0a7-4cd5-a5e0-e1303ffd2d06"
/>
Array Field: <img width="914" height="275" alt="Screenshot 2025-09-24 at
12 52 19 PM"
src="https://github.com/user-attachments/assets/cfe66a21-0d66-4f23-8e5d-1d5dac8e4c9b"
/>
## Table
Empty tagged fields are removed from the table.
Nested table for tagged fie Old: <img width="805" height="506"
alt="Screenshot 2025-09-28 at 11 07 01 PM"
src="https://github.com/user-attachments/assets/0669c2f3-150c-479d-b6ff-1d2857540fef"
/> lds are removed. Tag of the field is shown in the "Field" column.
New: <img width="1371" height="727" alt="Screenshot 2025-09-28 at 11
10 30 PM"
src="https://github.com/user-attachments/assets/030abde6-60ec-4195-9778-da48ebd01084"
/>
Reviewers: Andrew Schofield <[email protected]>
---
.../org/apache/kafka/common/protocol/Protocol.java | 49 ++++++++++++----------
1 file changed, 28 insertions(+), 21 deletions(-)
diff --git
a/clients/src/main/java/org/apache/kafka/common/protocol/Protocol.java
b/clients/src/main/java/org/apache/kafka/common/protocol/Protocol.java
index c23aa1782d6..1b051d58bf0 100644
--- a/clients/src/main/java/org/apache/kafka/common/protocol/Protocol.java
+++ b/clients/src/main/java/org/apache/kafka/common/protocol/Protocol.java
@@ -19,6 +19,7 @@ package org.apache.kafka.common.protocol;
import org.apache.kafka.common.message.RequestHeaderData;
import org.apache.kafka.common.message.ResponseHeaderData;
import org.apache.kafka.common.protocol.types.BoundField;
+import org.apache.kafka.common.protocol.types.Field;
import org.apache.kafka.common.protocol.types.Schema;
import org.apache.kafka.common.protocol.types.TaggedFields;
import org.apache.kafka.common.protocol.types.Type;
@@ -27,6 +28,7 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
public class Protocol {
@@ -49,7 +51,23 @@ public class Protocol {
subTypes.put(field.def.name,
type.arrayElementType().get());
}
} else if (type instanceof TaggedFields) {
- b.append("_tagged_fields ");
+ Map<Integer, Field> taggedFields = new
TreeMap<>(((TaggedFields) type).fields());
+ taggedFields.forEach((tag, taggedField) -> {
+ if (taggedField.type.isArray()) {
+ b.append("[");
+ b.append(taggedField.name);
+ b.append("]");
+ if (!subTypes.containsKey(taggedField.name))
+ subTypes.put(taggedField.name + "<tag: " +
tag.toString() + ">", taggedField.type.arrayElementType().get());
+ } else {
+ b.append(taggedField.name);
+ if (!subTypes.containsKey(taggedField.name))
+ subTypes.put(taggedField.name + "<tag: " +
tag.toString() + ">", taggedField.type);
+ }
+ b.append("<tag: ");
+ b.append(tag);
+ b.append("> ");
+ });
} else {
b.append(field.def.name);
b.append(" ");
@@ -90,6 +108,12 @@ public class Protocol {
}
}
+ private static void appendFieldNameToTable(String name, StringBuilder b) {
+ b.append("<td>");
+ b.append(name);
+ b.append("</td>");
+ }
+
private static void schemaToFieldTableHtml(Schema schema, StringBuilder b)
{
Set<BoundField> fields = new LinkedHashSet<>();
populateSchemaFields(schema, fields);
@@ -101,28 +125,12 @@ public class Protocol {
b.append("</tr>");
for (BoundField field : fields) {
b.append("<tr>\n");
- b.append("<td>");
- b.append(field.def.name);
- b.append("</td>");
- b.append("<td>");
if (field.def.type instanceof TaggedFields) {
TaggedFields taggedFields = (TaggedFields) field.def.type;
// Only include the field in the table if there are actually
tags defined
if (taggedFields.numFields() > 0) {
- b.append("<table class=\"data-table\"><tbody>\n");
- b.append("<tr>");
- b.append("<th>Tag</th>\n");
- b.append("<th>Tagged field</th>\n");
- b.append("<th>Description</th>\n");
- b.append("</tr>");
taggedFields.fields().forEach((tag, taggedField) -> {
- b.append("<tr>\n");
- b.append("<td>");
- b.append(tag);
- b.append("</td>");
- b.append("<td>");
- b.append(taggedField.name);
- b.append("</td>");
+ appendFieldNameToTable(taggedField.name + "<tag: "
+ tag.toString() + ">", b);
b.append("<td>");
b.append(taggedField.docString);
if (taggedField.type.isArray()) {
@@ -136,11 +144,10 @@ public class Protocol {
b.append("</td>");
b.append("</tr>\n");
});
- b.append("</tbody></table>\n");
- } else {
- b.append(field.def.docString);
}
} else {
+ appendFieldNameToTable(field.def.name, b);
+ b.append("<td>");
b.append(field.def.docString);
}
b.append("</td>");