Repository: carbon-language/carbon-lang
File: toolchain/sem_ir/formatter_chunks.h (C/C++)

Code before:
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef CARBON_TOOLCHAIN_SEM_IR_FORMATTER_CHUNKS_H_
#define CARBON_TOOLCHAIN_SEM_IR_FORMATTER_CHUNKS_H_

#include <string>

#include "common/check.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/raw_ostream.h"

namespace Carbon::SemIR {

// Manages the chunks created by the formatter.
//
// There are two kinds of `Chunk`s:
// - Parent `Chunk`s, with children in a vector.
// - Content `Chunk`s, with content in a string.
//
// Initially, `AddParent` is called one or more times. Then `StartContent` is
// called once to switch modes, and creates an initial content `Chunk`. After
// that, either content may be written to `out()` immediately (going to the
// current content `Chunk`), or `FormatChildContent` may be used to create a
// content `Chunk` which is a child of a parent.
//
// Content `Chunk`s that are created implicitly (not through
// `FormatChildContent`) are automatically included in output. Other `Chunk`s
// are included only when marked as a child of a `Chunk` that is included, using
// `AppendChildToCurrentParent`.
class FormatterChunks {
 public:
  // A type-safe index into `chunks_`.
  struct ChunkId {
    auto operator==(const ChunkId& other) const -> bool = default;

    size_t index;
  };

  // Either a parent or content.
  struct Chunk {
    // Whether this chunk is known to be included in the output.
    bool include_in_output;

    // Either children or content.
    std::variant<llvm::SmallVector<ChunkId>, std::string> data;
  };

  // An empty `ChunkId`.
  static constexpr ChunkId None = ChunkId(-1);

Review comment (suggestion):
This alludes to the concept of a "current content chunk", but doesn't explain how it's determined, or whether there always is one. Similarly, the name of `AppendChildToCurrentParent` alludes to the concept of a current parent chunk, but I don't see it mentioned in the documentation at all.

Code after:
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef CARBON_TOOLCHAIN_SEM_IR_FORMATTER_CHUNKS_H_
#define CARBON_TOOLCHAIN_SEM_IR_FORMATTER_CHUNKS_H_

#include <string>

#include "common/check.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/raw_ostream.h"

namespace Carbon::SemIR {

// Manages the chunks created by the formatter.
//
// There are two kinds of `Chunk`s:
// - Parent `Chunk`s, with children in a vector.
// - Content `Chunk`s, with content in a string.
//
// The high level usage is:
// 1. Calls to `AddParent` to prepare parent `Chunk`s.
// 2. One call to `StartContent` to switch modes.
// 3. Calls to `FormatChildContent`, `AppendChildToCurrentParent`, and `out`.
// 4. Calls to `Write`.
class FormatterChunks {
 public:
  // A type-safe index into `chunks_`.
  struct ChunkId {
    auto operator==(const ChunkId& other) const -> bool = default;

    size_t index;
  };

  // An empty `ChunkId`.
  static constexpr ChunkId None = ChunkId(-1);

  // Reserves space for at least `count` chunks.
  auto Reserve(size_t count) -> void { chunks_.reserve(count); }

  // Adds a parent `Chunk` and returns its `ChunkId`. If `child_chunk_id` isn't
  // `None`, it's added as a child. Must be called before `StartContent`.
  //
  // By default the parent `Chunk` will not be included in the output, and
  // `AppendChildToCurrentParent` must be called to include it.
  auto AddParent(ChunkId child_chunk_id = None) -> ChunkId;

  // Switches from adding parents to adding content.
  auto StartContent() -> void;