Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .agents/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,42 @@
MetricType(HasSubstr("outstanding_rpcs")),
HasMetricLabel("channel_pool_lb_policy", Eq("RANDOM_TWO_LEAST_USED")))));
```

## Type Deduction and `auto` Guidelines (Abseil Tip #232)

Follow [Abseil Tip of the Week #232](https://abseil.io/tips/232) and the Google
C++ Style Guide: use `auto` only if it makes code clearer or safer, not merely
to avoid typing an explicit type.

- **Range-Based `for` Loops Over Maps and Associative Containers:**
- Use `auto` with structured bindings (`for (auto const& [key, value] : map)`)
when iterating over `std::map`, `absl::flat_hash_map`, protobuf maps (e.g.,
`metadata()`, `labels()`), and JSON `.items()`.
- *Why:* Iterating with `std::pair<Key, Value>` triggers implicit conversions
and unintentional deep copies because map elements are
`std::pair<const Key, Value>`. Structured bindings eliminate this hazard and
remove `kv.first` / `kv.second` noise.
- **Standard Factory Functions:**
- Use `auto` when the type is explicitly specified on the RHS with standard
factory functions (e.g., `auto client = std::make_shared<MockClient>();`,
`auto ptr = std::make_unique<T>(...);`).
- **Iterators:**
- Use `auto` for iterator variables when the container type is clearly
declared in the local scope (`auto it = local_vec.begin();`).
- When the container is not local (e.g., a class member variable), either
spell out the iterator type or explicitly bind the dereferenced element type
(e.g., `ElementType const& elem = *it;`).
- **Spell Out Domain Types, Protobufs, and Return Values:**
- Do not use `auto` where it obscures domain types, protobuf messages, or
function return types (e.g., avoid `auto actual = client.InsertObject(...)`;
use `StatusOr<ObjectMetadata> actual = ...`).
- Do not use `auto` for nested protobuf access (e.g., avoid
`auto const& field = proto.nested().field()`; spell out the protobuf/string
type).
- **Avoid `auto` for Primitive / Numeric Types:**
- Use explicit types (`std::size_t`, `std::int64_t`, `std::uint32_t`, etc.)
instead of bare `auto` initialized with integer literals.
- **Explicit Semantics (`const`, `&`, `*`):**
- When a reference or pointer is intended, always explicitly qualify as
`auto const&`, `auto&`, or `auto*` to prevent accidental copies (since bare
`auto` deduces by value) and to make ownership and mutability unambiguous.
28 changes: 28 additions & 0 deletions .gemini/styleguide.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,34 @@ When reviewing or generating code, apply rigorous scrutiny:
- **Documentation:** Document all public items in libraries with Doxygen style
comments using `///`.

## Type Deduction (`auto`)

Apply the type deduction rules from
[Abseil Tip #232](https://abseil.io/tips/232) and the Google C++ Style Guide
during code reviews:

- **Require Structured Bindings in Map Loops:** In range-based `for` loops over
maps, protobuf maps, and JSON `.items()`, require `auto` with structured
bindings (e.g., `for (auto const& [key, value] : map)`). Flag loops that use
`std::pair` or trigger implicit copy conversions.
- **Factory Functions:** Allow `auto` when the type is explicitly written on the
RHS (e.g., `auto ptr = std::make_unique<T>(...);`,
`auto client = std::make_shared<T>(...);`).
- **Iterators:** Allow `auto` for iterators only when the container type is
locally visible. When iterating over non-local/member containers, require
explicitly typed dereferences (e.g., `ElementType const& elem = *it;`).
- **Reject Obscured Domain & Return Types:** Flag and reject `auto` when it
hides `StatusOr<T>`, domain objects, protobuf messages/fields, or function
return types (e.g., demand
`StatusOr<ObjectMetadata> actual = client.InsertObject(...)` instead of
`auto actual = ...`).
- **Disallow `auto` for Primitives:** Require explicit numeric and scalar types
(`std::size_t`, `std::int64_t`, `bool`, etc.) rather than deducing them from
literals.
- **Enforce Explicit Qualifiers:** Ensure `auto` is explicitly qualified with
`const`, reference (`&`), or pointer (`*`) (e.g., `auto const&`, `auto&`,
`auto*`) to prevent unintended copies or ambiguous mutability.

## Google Cloud SDK Specifics

- **Generated Code:** Do not edit files with a "Generated by the Codegen C++
Expand Down
Loading