static void writeProtocolsSection(DocGenerationContext context, DocWriter writer, Shape shape) {
        var protocols = ServiceIndex.of(context.model()).getProtocols(context.settings().service()).keySet();
        if (protocols.isEmpty()) {
            return;
        }
        writer.pushState(new ProtocolsSection(context, shape));

        AtomicReference<String> tabGroupContents = new AtomicReference<>();
        var tabGroup = capture(writer, tabGroupWriter -> {
            tabGroupWriter.openTabGroup();
            tabGroupContents.set(capture(tabGroupWriter, w -> {
                for (var protocol : protocols) {
                    writeProtocolSection(context, w, shape, protocol);
                }
            }));
            tabGroupWriter.closeTabGroup();
        });

        if (StringUtils.isBlank(tabGroupContents.get())) {
            // The extra newline is needed because the section intercepting logic actually adds one
            // by virtue of calling write instead of writeInline
            writer.unwrite("$L\n", tabGroup);
        }

        writer.popState();
    }
Provides common generation methods for services and resources.
smithy-docgen/src/main/java/software/amazon/smithy/docgen/generators/GeneratorUtils.java