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

Code before:
  CARBON_CHECK(content_start_id_ != None, "Must call StartContent first");
  auto chunk_id = ChunkId{.index = chunks_.size()};
  chunks_.push_back(
      {.include_in_output = include_in_output, .data = std::string()});
  out_ = std::make_unique<llvm::raw_string_ostream>(
      std::get<std::string>(Get(chunk_id).data));
  return chunk_id;
}

auto FormatterChunks::AddParent(ChunkId child_chunk_id) -> ChunkId {
  CARBON_CHECK(content_start_id_ == None, "Already called StartContent");
  llvm::SmallVector<ChunkId> children;
  if (child_chunk_id != None) {
    children.push_back(child_chunk_id);
  }
  auto chunk_id = ChunkId{.index = chunks_.size()};
  chunks_.push_back({.include_in_output = false, .data = std::move(children)});
  return chunk_id;
}

auto FormatterChunks::FormatChildContent(
    ChunkId parent_chunk_id, llvm::function_ref<auto()->void> format) -> void {
  CARBON_CHECK(content_start_id_ != None, "Must call StartContent first");
  CARBON_CHECK(current_parent_id_ == None, "Cannot nest FormatChildContent");

  // If the parent is already included, we don't need to make a chunk.
  if (Get(parent_chunk_id).include_in_output) {
    format();
    return;
  }

  // Otherwise, create a new chunk and include it only if the parent is later
  // found to be used.
  AppendChildToParent(AddContent(/*include_in_output=*/false), parent_chunk_id);

  current_parent_id_ = parent_chunk_id;
  format();
  current_parent_id_ = None;

  // Reset the output stream so that the next call to `out()` creates a new
  // chunk.
  out_.reset();
}

auto FormatterChunks::AppendChildToParent(ChunkId child_chunk_id,
                                          ChunkId parent_chunk_id) -> void {
  CARBON_CHECK(!Get(parent_chunk_id).include_in_output);
  auto* children =
      std::get_if<llvm::SmallVector<ChunkId>>(&Get(parent_chunk_id).data);
  CARBON_CHECK(children);
  children->push_back(child_chunk_id);

Review comment (suggestion):
```suggestion
  // If the parent is already included, we don't need to make a chunk, because
  // `out()` will create one lazily if needed.
```

Code after:
  CARBON_CHECK(content_start_id_ != None, "Must call StartContent first");
  auto chunk_id = ChunkId{.index = chunks_.size()};
  chunks_.push_back(
      {.include_in_output = include_in_output, .data = std::string()});
  out_ = std::make_unique<llvm::raw_string_ostream>(
      std::get<std::string>(Get(chunk_id).data));
  return chunk_id;
}

auto FormatterChunks::AddParent(ChunkId child_chunk_id) -> ChunkId {
  CARBON_CHECK(content_start_id_ == None, "Already called StartContent");
  llvm::SmallVector<ChunkId> children;
  if (child_chunk_id != None) {
    children.push_back(child_chunk_id);
  }
  auto chunk_id = ChunkId{.index = chunks_.size()};
  chunks_.push_back({.include_in_output = false, .data = std::move(children)});
  return chunk_id;
}

auto FormatterChunks::FormatChildContent(
    ChunkId parent_chunk_id, llvm::function_ref<auto()->void> format) -> void {
  CARBON_CHECK(content_start_id_ != None, "Must call StartContent first");
  CARBON_CHECK(current_parent_id_ == None, "Cannot nest FormatChildContent");

  // We only need to call `AddContent` for non-included content because `out()`
  // is included by default.
  if (Get(parent_chunk_id).include_in_output) {
    format();
    return;
  }

  // Otherwise, create a content `Chunk` and include it only if the parent is
  // later found to be used.
  AppendChildToParent(AddContent(/*include_in_output=*/false), parent_chunk_id);

  current_parent_id_ = parent_chunk_id;
  format();
  current_parent_id_ = None;

  // Reset the output stream so that the next call to `out()` creates a new
  // chunk.
  out_.reset();
}

auto FormatterChunks::AppendChildToParent(ChunkId child_chunk_id,
                                          ChunkId parent_chunk_id) -> void {
  CARBON_CHECK(!Get(parent_chunk_id).include_in_output);
  auto* children =
      std::get_if<llvm::SmallVector<ChunkId>>(&Get(parent_chunk_id).data);
  CARBON_CHECK(children);