KAFKA-9825 Kafka protocol BNF format should have some way to display tagged fields (#20536)
CI / build (push) Waiting to run Details

# 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 <aschofield@confluent.io>
This commit is contained in:
Chang-Yu Huang 2025-10-02 06:01:53 -04:00 committed by GitHub
parent 7f65b1fa96
commit 33cd114375
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 28 additions and 21 deletions

View File

@ -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 + "&lt;tag: " + tag.toString() + "&gt;", taggedField.type.arrayElementType().get());
} else {
b.append(taggedField.name);
if (!subTypes.containsKey(taggedField.name))
subTypes.put(taggedField.name + "&lt;tag: " + tag.toString() + "&gt;", taggedField.type);
}
b.append("&lt;tag: ");
b.append(tag);
b.append("&gt; ");
});
} 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 + "&lt;tag: " + tag.toString() + "&gt;", 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>");