# Protobuf files

Source: https://apigenie.pl/docs/reference/cli/format/protobuf
Part of the reference of [format](https://apigenie.pl/docs/reference/cli/format.md).
Its other pages: [Layout and YAML styles](https://apigenie.pl/docs/reference/cli/format/styles.md), [Property order](https://apigenie.pl/docs/reference/cli/format/property-order.md), [AsyncAPI documents](https://apigenie.pl/docs/reference/cli/format/asyncapi.md), [Swagger 2.0 documents](https://apigenie.pl/docs/reference/cli/format/swagger.md), [GraphQL documents](https://apigenie.pl/docs/reference/cli/format/graphql.md).

A file with the `.proto` extension is formatted as a proto3 file, with the `protobuf` section of
`commands.format`: every declaration gets a canonical layout, nested declarations are indented, and
imports, options, declarations, fields, enum values and methods are sorted as `sort` says. No
comment is lost.

## Layout

The formatter:

- writes every declaration in a canonical layout: one statement per line,
  normalized spacing, blank lines between top-level declarations and around
  nested messages, enums and extends
- indents nested declarations by the configured number of spaces
- optionally sorts imports, options and declarations

No comment is lost. Comments are written as `//` line comments and stay with
their declarations when declarations are sorted. Comments that protoc ignores,
such as those inside a declaration (`int32 /* type */ id = 1;`), are written
as `/* */` comments directly before the end of their declaration
(`int32 id = 1 /* type */;`).

Files that are syntactically correct but break proto3 rules, for example with
duplicate field numbers, are formatted. Files with syntax errors are reported
with the position of each error and left untouched. Editions and proto2 files
are not supported.

## Settings

| Key                 | Values                                  | Recommended | Description                                                                                                                                                                                                  |
| ------------------- | --------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `indent`            | 1 to 8                                  | 2           | Number of spaces for one level of nesting.                                                                                                                                                                   |
| `sort.imports`      | `original`, `sorted`                    | `sorted`    | Sorts imports by path.                                                                                                                                                                                       |
| `sort.options`      | `original`, `sorted`                    | `sorted`    | Sorts option statements and the options in brackets (`[deprecated = true, json_name = "x"]`) by name.                                                                                                        |
| `sort.declarations` | `original`, `grouped`, `sorted`         | `original`  | `grouped` puts top-level declarations in this order: package, imports, options, services, messages, enums, extends. `sorted` also sorts services, messages, enums and extends by name within their groups. |
| `sort.fields`       | `original`, `number`, `name`            | `original`  | Sorts the fields of messages, oneofs and extends. A oneof is placed by its lowest field number (or its name), and its fields are sorted too.                                                                 |
| `sort.enum_values`  | `original`, `number`, `name`            | `original`  | Sorts enum values. A first value of zero stays first, as proto3 requires.                                                                                                                                    |
| `sort.nested_types` | `original`, `sorted`                    | `original`  | Sorts the messages, enums and extends nested in a message by name.                                                                                                                                           |


Without a configuration file, the recommended settings are used. With
`extends: [original]`, nothing is sorted.

Each kind of declaration is sorted among the positions that declarations of
that kind take in its body, so sorting fields, for example, does not move
options, reserved statements or nested messages. Only the `grouped` and
`sorted` values of `sort.declarations` move top-level declarations between
kinds.

Changing the order of fields, enum values or methods does not change the wire
format, but it changes the order of declarations in generated code and
descriptors. For this reason, the recommended configuration sorts only imports
and options.

**Example** - Recommended settings with 4-space indentation, and fields sorted
by number

```yaml
commands:
  format:
    extends:
      - recommended
    protobuf:
      indent: 4
      sort:
        declarations: grouped
        fields: number
        enum_values: number
```

```sh
apigenie format api/store/v1/*.proto --config api-style-guide.yaml
```
