Skip to content

Commit 33cd114

Browse files
authored
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]>
1 parent 7f65b1f commit 33cd114

File tree

1 file changed

+28
-21
lines changed
  • clients/src/main/java/org/apache/kafka/common/protocol

1 file changed

+28
-21
lines changed

clients/src/main/java/org/apache/kafka/common/protocol/Protocol.java

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.apache.kafka.common.message.RequestHeaderData;
2020
import org.apache.kafka.common.message.ResponseHeaderData;
2121
import org.apache.kafka.common.protocol.types.BoundField;
22+
import org.apache.kafka.common.protocol.types.Field;
2223
import org.apache.kafka.common.protocol.types.Schema;
2324
import org.apache.kafka.common.protocol.types.TaggedFields;
2425
import org.apache.kafka.common.protocol.types.Type;
@@ -27,6 +28,7 @@
2728
import java.util.LinkedHashSet;
2829
import java.util.Map;
2930
import java.util.Set;
31+
import java.util.TreeMap;
3032

3133
public class Protocol {
3234

@@ -49,7 +51,23 @@ private static void schemaToBnfHtml(Schema schema, StringBuilder b, int indentSi
4951
subTypes.put(field.def.name, type.arrayElementType().get());
5052
}
5153
} else if (type instanceof TaggedFields) {
52-
b.append("_tagged_fields ");
54+
Map<Integer, Field> taggedFields = new TreeMap<>(((TaggedFields) type).fields());
55+
taggedFields.forEach((tag, taggedField) -> {
56+
if (taggedField.type.isArray()) {
57+
b.append("[");
58+
b.append(taggedField.name);
59+
b.append("]");
60+
if (!subTypes.containsKey(taggedField.name))
61+
subTypes.put(taggedField.name + "&lt;tag: " + tag.toString() + "&gt;", taggedField.type.arrayElementType().get());
62+
} else {
63+
b.append(taggedField.name);
64+
if (!subTypes.containsKey(taggedField.name))
65+
subTypes.put(taggedField.name + "&lt;tag: " + tag.toString() + "&gt;", taggedField.type);
66+
}
67+
b.append("&lt;tag: ");
68+
b.append(tag);
69+
b.append("&gt; ");
70+
});
5371
} else {
5472
b.append(field.def.name);
5573
b.append(" ");
@@ -90,6 +108,12 @@ private static void populateSchemaFields(Schema schema, Set<BoundField> fields)
90108
}
91109
}
92110

111+
private static void appendFieldNameToTable(String name, StringBuilder b) {
112+
b.append("<td>");
113+
b.append(name);
114+
b.append("</td>");
115+
}
116+
93117
private static void schemaToFieldTableHtml(Schema schema, StringBuilder b) {
94118
Set<BoundField> fields = new LinkedHashSet<>();
95119
populateSchemaFields(schema, fields);
@@ -101,28 +125,12 @@ private static void schemaToFieldTableHtml(Schema schema, StringBuilder b) {
101125
b.append("</tr>");
102126
for (BoundField field : fields) {
103127
b.append("<tr>\n");
104-
b.append("<td>");
105-
b.append(field.def.name);
106-
b.append("</td>");
107-
b.append("<td>");
108128
if (field.def.type instanceof TaggedFields) {
109129
TaggedFields taggedFields = (TaggedFields) field.def.type;
110130
// Only include the field in the table if there are actually tags defined
111131
if (taggedFields.numFields() > 0) {
112-
b.append("<table class=\"data-table\"><tbody>\n");
113-
b.append("<tr>");
114-
b.append("<th>Tag</th>\n");
115-
b.append("<th>Tagged field</th>\n");
116-
b.append("<th>Description</th>\n");
117-
b.append("</tr>");
118132
taggedFields.fields().forEach((tag, taggedField) -> {
119-
b.append("<tr>\n");
120-
b.append("<td>");
121-
b.append(tag);
122-
b.append("</td>");
123-
b.append("<td>");
124-
b.append(taggedField.name);
125-
b.append("</td>");
133+
appendFieldNameToTable(taggedField.name + "&lt;tag: " + tag.toString() + "&gt;", b);
126134
b.append("<td>");
127135
b.append(taggedField.docString);
128136
if (taggedField.type.isArray()) {
@@ -136,11 +144,10 @@ private static void schemaToFieldTableHtml(Schema schema, StringBuilder b) {
136144
b.append("</td>");
137145
b.append("</tr>\n");
138146
});
139-
b.append("</tbody></table>\n");
140-
} else {
141-
b.append(field.def.docString);
142147
}
143148
} else {
149+
appendFieldNameToTable(field.def.name, b);
150+
b.append("<td>");
144151
b.append(field.def.docString);
145152
}
146153
b.append("</td>");

0 commit comments

Comments
 (0)