private void addStructSpecs(Versions parentVersions, List<FieldSpec> fields) {
        for (FieldSpec field : fields) {
            String typeName = null;
            if (field.type().isStructArray()) {
                FieldType.ArrayType arrayType = (FieldType.ArrayType) field.type();
                typeName = arrayType.elementName();
            } else if (field.type().isStruct()) {
                FieldType.StructType structType = (FieldType.StructType) field.type();
                typeName = structType.typeName();
            }
            if (typeName != null) {
                if (commonStructNames.contains(typeName)) {
                    // If we're using a common structure, we can't specify its fields.
                    // The fields should be specified in the commonStructs area.
                    if (!field.fields().isEmpty()) {
                        throw new RuntimeException("Can't re-specify the common struct " +
                                typeName + " as an inline struct.");
                    }
                } else if (structs.containsKey(typeName)) {
                    // Inline structures should only appear once.
                    throw new RuntimeException("Struct " + typeName +
                        " was specified twice.");
                } else {
                    // Synthesize a StructSpec object out of the fields.
                    StructSpec spec = new StructSpec(typeName,
                        field.versions().toString(),
                        Versions.NONE_STRING, // version deprecations not supported at field level
                        field.fields());
                    structs.put(typeName, new StructInfo(spec, parentVersions));
                }

                addStructSpecs(parentVersions.intersect(field.versions()), field.fields());
            }
        }
    }
Register all the structures contained a message spec.
generator/src/main/java/org/apache/kafka/message/StructRegistry.java