Настройки функций для редакций
Функции редакций Protobuf и как они влияют на поведение protobuf.
В этой теме представлен обзор функций, включенных в выпущенные версии редакций. Функции последующих редакций будут добавлены в эту тему. Мы анонсируем новые редакции в разделе Новости.
Прежде чем настраивать параметры функций в вашем новом содержимом определения схемы, убедитесь, что вы понимаете, зачем вы их используете. Избегайте карго-культа (cargo-culting) с функциями.
Prototiller
Prototiller — это инструмент командной строки, который обновляет файлы конфигурации схемы proto между версиями синтаксиса и редакциями. Он еще не выпущен, но на него ссылаются throughout этой теме.
Функции
В следующих разделах приведены все поведения, которые можно настроить с помощью функций в редакциях. Сохранение поведения Proto2 или Proto3 показывает, как переопределить поведения по умолчанию, чтобы ваши файлы определений proto вели себя как файлы proto2 или proto3. Для получения дополнительной информации о том, как редакции и функции вместе работают для установки поведения, см. Обзор редакций Protobuf.
Настройки функций применяются на разных уровнях:
На уровне файла: Эти настройки применяются ко всем элементам (сообщениям, полям, перечислениям и т.д.), которые не имеют переопределяющей настройки.
Не вложенные: Сообщения, перечисления и сервисы могут переопределять настройки, сделанные на уровне файла. Они применяются ко всему внутри них (полям сообщений, значениям перечислений), что не переопределено, но не применяются к другим параллельным сообщениям и перечислениям.
Вложенные: Oneof, сообщения и перечисления могут переопределять настройки из сообщения, в которое они вложены.
Самый низкий уровень: Поля, расширения, значения перечислений, диапазоны расширений и методы — это самый низкий уровень, на котором вы можете переопределять настройки.
Каждый из следующих разделов содержит комментарий, в котором указано, к какой области видимости функция может быть применена. Следующий пример показывает mock-функцию, примененную к каждой области видимости:
edition = "2024";
// Определение на уровне файла
option features.bar = BAZ;
enum Foo {
// Определение на уровне перечисления (не вложенная область)
option features.bar = QUX;
A = 1;
B = 2;
}
message Corge {
// Определение на уровне сообщения (не вложенная область)
option features.bar = QUUX;
message Garply {
// Определение на уровне сообщения (вложенная область)
option features.bar = WALDO;
string id = 1;
}
// Определение на уровне поля (самый низкий уровень)
Foo A = 1 [features.bar = GRAULT];
}
В этом примере настройка "GRAULT" в определении функции на самом низком уровне
переопределяет настройку "QUUX" в не вложенной области. И внутри
сообщения Garply "WALDO" переопределяет "QUUX".
features.default_symbol_visibility
Эта функция позволяет устанавливать видимость по умолчанию для сообщений и перечислений, делая их доступными или недоступными при импорте другими protobuf. Использование этой функции уменьшит количество мертвых символов, чтобы создавать меньшие бинарные файлы.
В дополнение к установке значений по умолчанию для всего файла, вы можете использовать ключевые слова local
и export для установки поведения для каждого поля. Подробнее об этом читайте в разделе
Ключевые слова export / local.
Доступные значения:
EXPORT_ALL: Это значение по умолчанию до Редакции 2024. Все сообщения и перечисления экспортируются по умолчанию.EXPORT_TOP_LEVEL: Все символы верхнего уровня по умолчанию экспортируются; вложенные по умолчанию являются локальными.LOCAL_ALL: Все символы по умолчанию являются локальными.STRICT: Все символы локальны по умолчанию. Вложенные типы не могут быть экспортированы, за исключением особого случая дляmessage { enum {} reserved 0 to max; }. Это станет значением по умолчанию в будущей редакции.
Применимо к следующей области видимости: Enum, Message
Добавлено в: Редакция 2024
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | EXPORT_TOP_LEVEL |
| 2023 | EXPORT_ALL |
| proto3 | EXPORT_ALL |
| proto2 | EXPORT_ALL |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
Следующий пример показывает, как вы можете применить функцию к элементам в ваших файлах определений схемы proto:
// foo.proto
edition = "2024";
// Видимость символов по умолчанию EXPORT_TOP_LEVEL. Установка
// default_symbol_visibility переопределяет эти значения по умолчанию
option features.default_symbol_visibility = LOCAL_ALL;
// Символы верхнего уровня экспортируются по умолчанию в Редакции 2024; применение ключевого слова local
// переопределяет это
export message LocalMessage {
int32 baz = 1;
// Вложенные символы являются локальными по умолчанию в Редакции 2024; применение ключевого слова export
// переопределяет это
enum ExportedNestedEnum {
UNKNOWN_EXPORTED_NESTED_ENUM_VALUE = 0;
}
}
// bar.proto
edition = "2024";
import "foo.proto";
message ImportedMessage {
// Следующее допустимо, потому что импортированное сообщение явно переопределяет
// настройку видимости в foo.proto
LocalMessage bar = 1;
// Следующее недопустимо, потому что default_symbol_visibility установлен в
// `LOCAL_ALL`
// LocalMessage.ExportedNestedEnum qux = 2;
}
features.enforce_naming_style
Введена в Редакции 2024, эта функция включает строгое соблюдение стиля именования, как определено в руководстве по стилю, чтобы гарантировать возможность кругового обмена (round-trippable) protobuf по умолчанию, с возможностью отказаться от этого с помощью значения функции.
Доступные значения:
STYLE2024: Обеспечивает строгое соблюдение руководства по стилю для именования.STYLE_LEGACY: Применяет уровень соблюдения руководства по стилю, действовавший до Редакции 2024.
Применимо к следующей области видимости: File
Добавлено в: Редакция 2024
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | STYLE2024 |
| 2023 | STYLE_LEGACY |
| proto3 | STYLE_LEGACY |
| proto2 | STYLE_LEGACY |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
Следующий пример кода показывает файл Редакции 2023:
Редакция 2023 по умолчанию использует STYLE_LEGACY, поэтому некорректное имя поля допустимо:
edition = "2023";
message Foo {
// Некорректное имя поля не является проблемой
int64 bar_1 = 1;
}
Редакция 2024 по умолчанию использует STYLE2024, поэтому требуется переопределение, чтобы сохранить
некорректное имя поля:
edition = "2024";
// Чтобы сохранить некорректное имя поля, переопределите настройку STYLE2024
option features.enforce_naming_style = STYLE_LEGACY;
message Foo {
int64 bar_1 = 1;
}
features.enum_type
Эта функция устанавливает поведение для обработки значений перечислений, которые не содержатся в определенном наборе. См. Поведение перечислений для получения дополнительной информации об открытых и закрытых перечислениях.
Эта функция не влияет на файлы proto3, поэтому в этом разделе нет примеров "до" и "после" для файла proto3.
Доступные значения:
CLOSED:Закрытые перечисления сохраняют значения перечислений, находящиеся вне диапазона, в наборе неизвестных полей.OPEN:Открытые перечисления разбирают значения вне диапазона непосредственно в их поля.
Применимо к следующим областям видимости: File, Enum
Добавлено в: Редакция 2023
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | OPEN |
| 2023 | OPEN |
| proto3 | OPEN |
| proto2 | CLOSED |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
Следующий пример кода показывает файл proto2:
syntax = "proto2";
enum Foo {
A = 2;
B = 4;
C = 6;
}
После запуска Prototiller эквивалентный код может выглядеть так:
edition = "2024";
enum Foo {
// Установка функции enum_type переопределяет перечисление OPEN по умолчанию
option features.enum_type = CLOSED;
A = 2;
B = 4;
C = 6;
}
features.field_presence
Эта функция устанавливает поведение для отслеживания присутствия поля, то есть концепции имеет ли поле protobuf значение.
Доступные значения:
LEGACY_REQUIRED: Поле является обязательным для разбора и сериализации. Любое явно установленное значение сериализуется в бинарный формат (даже если оно совпадает со значением по умолчанию).EXPLICIT: Поле имеет явное отслеживание присутствия. Любое явно установленное значение сериализуется в бинарный формат (даже если оно совпадает со значением по умолчанию). Для сингулярных примитивных полей генерируются функцииhas_*для полей, установленных вEXPLICIT.IMPLICIT: Поле не имеет отслеживания присутствия. Значение по умолчанию не сериализуется в бинарный формат (даже если оно явно установлено). Функцииhas_*не генерируются для полей, установленных вIMPLICIT.
Применимо к следующим областям видимости: File, Field
Добавлено в: Редакция 2023
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | EXPLICIT |
| 2023 | EXPLICIT |
| proto3 | IMPLICIT* |
| proto2 | EXPLICIT |
* proto3 использует IMPLICIT, если только у поля нет метки optional, в этом случае
оно ведет себя как EXPLICIT. См.
Присутствие в API Proto3
для получения дополнительной информации.
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
Следующий пример кода показывает файл proto2:
syntax = "proto2";
message Foo {
required int32 x = 1;
optional int32 y = 2;
repeated int32 z = 3;
}
После запуска Prototiller эквивалентный код может выглядеть так:
edition = "2024";
message Foo {
// Установка функции field_presence сохраняет поведение required из proto2
int32 x = 1 [features.field_presence = LEGACY_REQUIRED];
int32 y = 2;
repeated int32 z = 3;
}
Следующий пример показывает файл proto3:
syntax = "proto3";
message Bar {
int32 x = 1;
optional int32 y = 2;
repeated int32 z = 3;
}
После запуска Prototiller эквивалентный код может выглядеть так:
edition = "2024";
// Установка функции field_presence на уровне файла соответствует неявному значению по умолчанию proto3
option features.field_presence = IMPLICIT;
message Bar {
int32 x = 1;
// Установка field_presence здесь сохраняет явное состояние, которое поле proto3
// имеет из-за синтаксиса optional
int32 y = 2 [features.field_presence = EXPLICIT];
repeated int32 z = 3;
}
Обратите внимание, что метки required и optional больше не существуют в Редакциях, так как
соответствующее поведение устанавливается явно с помощью функции field_presence.
features.json_format
Эта функция устанавливает поведение для разбора и сериализации JSON.
Эта функция не влияет на файлы proto3, поэтому в этом разделе нет примеров "до" и "после" для файла proto3. Поведение редакций соответствует поведению в proto3.
Доступные значения:
ALLOW: Среда выполнения должна разрешать разбор и сериализацию JSON. Проверки применяются на уровне proto, чтобы убедиться, что существует четко определенное отображение в JSON.LEGACY_BEST_EFFORT: Среда выполнения делает все возможное для разбора и сериализации JSON. Разрешены определенные protobuf, которые могут привести к неопределенному поведению во время выполнения (например, отображения многие:1 или 1:многие).
Применимо к следующим областям видимости: File, Message, Enum
Добавлено в: Редакция 2023
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | ALLOW |
| 2023 | ALLOW |
| proto3 | ALLOW |
| proto2 | LEGACY_BEST_EFFORT |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
Следующий пример кода показывает файл proto2:
syntax = "proto2";
message Foo {
// Только предупреждение
string bar = 1;
string bar_ = 2;
}
После запуска Prototiller эквивалентный код может выглядеть так:
edition = "2024";
option features.json_format = LEGACY_BEST_EFFORT;
message Foo {
string bar = 1;
string bar_ = 2;
}
features.message_encoding
Эта функция устанавливает поведение для кодирования полей при сериализации.
Эта функция не влияет на файлы proto3, поэтому в этом разделе нет примеров "до" и "после" для файла proto3.
В зависимости от языка, поля, которые являются "group-подобными", могут иметь неожиданное использование заглавных букв в сгенерированном коде и в текстовом формате, чтобы обеспечить обратную совместимость с proto2. Поля сообщений являются "group-подобными", если выполняются все следующие условия:
- Указано кодирование сообщения
DELIMITED - Тип сообщения определен в той же области видимости, что и поле
- Имя поля точно соответствует имени типа в нижнем регистре
Доступные значения:
LENGTH_PREFIXED: Поля кодируются с использованием типа бинарного формата LEN, описанного в Структура сообщения.DELIMITED: Поля типа message кодируются как groups.
Применимо к следующим областям видимости: File, Field
Добавлено в: Редакция 2023
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | LENGTH_PREFIXED |
| 2023 | LENGTH_PREFIXED |
| proto3 | LENGTH_PREFIXED |
| proto2 | LENGTH_PREFIXED |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
Следующий пример кода показывает файл proto2:
syntax = "proto2";
message Foo {
group Bar = 1 {
optional int32 x = 1;
repeated int32 y = 2;
}
}
После запуска Prototiller эквивалентный код может выглядеть так:
edition = "2024";
message Foo {
message Bar {
int32 x = 1;
repeated int32 y = 2;
}
Bar bar = 1 [features.message_encoding = DELIMITED];
}
features.repeated_field_encoding
Эта функция — это то, во что была мигрирована опция
packed
для repeated полей в proto2/proto3 в Редакциях.
Доступные значения:
PACKED:Repeatedполя примитивного типа кодируются как одна запись LEN, которая содержит каждый элемент, объединенный вместе.EXPANDED:Repeatedполя кодируются с номером поля для каждого значения.
Применимо к следующим областям видимости: File, Field
Добавлено в: Редакция 2023
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | PACKED |
| 2023 | PACKED |
| proto3 | PACKED |
| proto2 | EXPANDED |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
Следующий пример кода показывает файл proto2:
syntax = "proto2";
message Foo {
repeated int32 bar = 6 [packed=true];
repeated int32 baz = 7;
}
После запуска Prototiller эквивалентный код может выглядеть так:
edition = "2024";
option features.repeated_field_encoding = EXPANDED;
message Foo {
repeated int32 bar = 6 [features.repeated_field_encoding=PACKED];
repeated int32 baz = 7;
}
Следующий пример показывает файл proto3:
syntax = "proto3";
message Foo {
repeated int32 bar = 6;
repeated int32 baz = 7 [packed=false];
}
После запуска Prototiller эквивалентный код может выглядеть так:
edition = "2024";
message Foo {
repeated int32 bar = 6;
repeated int32 baz = 7 [features.repeated_field_encoding=EXPANDED];
}
features.utf8_validation
Эта функция устанавливает, как проверяются строки. Она применяется ко всем языкам, кроме
тех, для которых есть специфичная для языка функция utf8_validation, которая переопределяет ее.
См. features.(pb.java).utf8_validation для
специфичной для Java функции.
Эта функция не влияет на файлы proto3, поэтому в этом разделе нет примеров "до" и "после" для файла proto3.
Доступные значения:
VERIFY: Среда выполнения должна проверять UTF-8. Это поведение по умолчанию для proto3.NONE: Поле ведет себя как непроверенное полеbytesв бинарном формате. Парсеры могут обрабатывать этот тип поля непредсказуемым образом, например, заменяя недопустимые символы. Это поведение по умолчанию для proto2.
Применимо к следующим областям видимости: File, Field
Добавлено в: Редакция 2023
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | VERIFY |
| 2023 | VERIFY |
| proto3 | VERIFY |
| proto2 | NONE |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
Следующий пример кода показывает файл proto2:
syntax = "proto2";
message MyMessage {
string foo = 1;
}
После запуска Prototiller эквивалентный код может выглядеть так:
edition = "2024";
message MyMessage {
string foo = 1 [features.utf8_validation = NONE];
}
Специфичные для языка функции
Некоторые функции применяются к определенным языкам и не применяются к тем же protobuf на других языках. Использование этих функций требует от вас импорта соответствующего файла *_features.proto из среды выполнения языка. Примеры в следующих разделах показывают эти импорты.
features.(pb.go).api_level
Языки: Go
Функция api_level позволяет выбрать, для какой версии API плагин Go protobuf
должен генерировать код. Opaque API — это последняя версия реализации
Protocol Buffers для языка программирования Go. Предыдущая
версия теперь называется Open Struct API. См.
Go Protobuf: выпуск Opaque API
(блог пост) для введения.
Доступные значения:
API_OPEN: Open Struct API генерирует типы структур, которые открыты для прямого доступа.API_HYBRID: Hybrid — это шаг между Open и Opaque: Hybrid API также включает методы доступа (так что вы можете обновить свой код), но все еще экспортирует поля структуры как раньше. Нет разницы в производительности; этот уровень API только помогает с миграцией.API_OPAQUE: С Opaque API поля структуры скрыты и больше не могут быть доступны напрямую. Вместо этого новые методы доступа позволяют получать, устанавливать или очищать поле.
Применимо к следующим областям видимости: Message, File
Добавлено в: Редакция 2023
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2023 | API_OPEN |
| 2024 | API_OPAQUE |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
Вы можете установить функцию api_level, начиная с редакции 2023:
edition = "2023";
import "google/protobuf/go_features.proto";
// Удалите эту строку после миграции кода на Opaque API.
option features.(pb.go).api_level = API_HYBRID;
См. также: Opaque API: Миграция
features.(pb.cpp).enum_name_uses_string_view
Языки: C++
До Редакции 2024 все сгенерированные типы перечислений предоставляли следующую функцию для
получения метки из значения перечисления, что создавало некоторые накладные расходы на создание
экземпляров std::string во время выполнения:
const std::string& Foo_Name(int);
Значение функции по умолчанию в Редакции 2024 изменяет эту сигнатуру на возврат
absl::string_view, чтобы позволить лучшее разделение хранилища и потенциальную
экономию памяти/ЦП. Если вы еще не готовы к миграции, вы можете переопределить это,
чтобы вернуть предыдущее поведение. См.
Тип возвращаемого значения string_view
в руководстве по миграции для получения дополнительной информации по этой теме.
Доступные значения:
true: Перечисление используетstring_viewдля своих значений.false: Перечисление используетstd::stringдля своих значений.
Применимо к следующим областям видимости: Enum, File
Добавлено в: Редакция 2024
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | true |
| 2023 | false |
| proto3 | false |
| proto2 | false |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
features.(pb.java).large_enum
Языки: Java
Эта специфичная для языка функция позволяет использовать новую функциональность, которая обрабатывает большие перечисления в Java, не вызывая ошибок компилятора. Обратите внимание, что эта функция воспроизводит поведение, подобное перечислению, но имеет некоторые заметные различия. Например, операторы switch не поддерживаются.
Доступные значения:
true: Java перечисления будут использовать новую функциональность.false: Java перечисления будут продолжать использовать Java перечисления.
Применимо к следующим областям видимости: Enum
Добавлено в: Редакция 2024
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | false |
| 2023 | false |
| proto3 | false |
| proto2 | false |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
features.(pb.cpp/pb.java).legacy_closed_enum
Языки: C++, Java
Эта функция определяет, должно ли поле с открытым типом перечисления вести себя так, как если бы оно было закрытым перечислением. Это позволяет редакциям воспроизводить несоответствующее поведение в Java и C++ из proto2 и proto3.
Эта функция не влияет на файлы proto3, и поэтому в этом разделе нет примеров "до" и "после" для файла proto3.
Доступные значения:
true: Рассматривает перечисление как закрытое независимо отenum_type.false: Уважает то, что установлено вenum_type.
Применимо к следующим областям видимости: File, Field
Добавлено в: Редакция 2023
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | false |
| 2023 | false |
| proto3 | false |
| proto2 | true |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
Следующий пример кода показывает файл proto2:
syntax = "proto2";
import "myproject/proto3file.proto";
message Msg {
myproject.proto3file.Proto3Enum name = 1;
}
После запуска Prototiller эквивалентный код может выглядеть так:
edition = "2024";
import "myproject/proto3file.proto";
import "google/protobuf/cpp_features.proto";
import "google/protobuf/java_features.proto";
message Msg {
myproject.proto3file.Proto3Enum name = 1 [
features.(pb.cpp).legacy_closed_enum = true,
features.(pb.java).legacy_closed_enum = true
];
}
features.(pb.java).nest_in_file_class
Языки: Java
Эта функция управляет тем, будет ли генератор Java вкладывать сгенерированный класс
в класс сгенерированного файла Java. Установка этой опции в NO эквивалентна
установке java_multiple_files = true в proto2/proto3/редакции 2023.
Имя внешнего класса по умолчанию также обновлено, чтобы всегда быть именем файла .proto в верблюжьем регистре
с суффиксом Proto по умолчанию (например, foo/bar_baz.proto
становится BarBazProto). Вы все еще можете переопределить это, используя опцию файла
java_outer_classname и заменить значение по умолчанию до Редакции 2024, которое было
BarBaz или BarBazOuterClass в зависимости от наличия конфликтов.
Доступные значения:
NO: Не вкладывать сгенерированный класс в класс файла.YES: Вкладывать сгенерированный класс в класс файла.- Legacy: Внутреннее значение, используемое когда установлена опция
java_multiple_files.
Применимо к следующим областям видимости: Message, Enum, Service
Добавлено в: Редакция 2024
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | NO |
| 2023 | LEGACY |
| proto3 | LEGACY |
| proto2 | LEGACY |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
features.(pb.cpp).string_type
Языки: C++
Эта функция определяет, как сгенерированный код должен обращаться со строковыми полями. Это
заменяет опцию ctype из proto2 и proto3 и предлагает новую
функцию string_type. В Редакции 2023 вы можете указать либо ctype, либо
string_type для поля, но не обе одновременно. В Редакции 2024 опция ctype
удалена.
Доступные значения:
VIEW: Генерирует методы доступаstring_viewдля поля.CORD: Генерирует методы доступаCordдля поля. Не поддерживается для полей расширений.STRING: Генерирует методы доступаstringдля поля.
Применимо к следующим областям видимости: File, Field
Добавлено в: Редакция 2023
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | VIEW |
| 2023 | STRING |
| proto3 | STRING |
| proto2 | STRING |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
Следующий пример кода показывает файл proto2:
syntax = "proto2";
message Foo {
optional string bar = 6;
optional string baz = 7 [ctype = CORD];
}
После запуска Prototiller эквивалентный код может выглядеть так:
edition = "2024";
import "google/protobuf/cpp_features.proto";
message Foo {
string bar = 6 [features.(pb.cpp).string_type = STRING];
string baz = 7 [features.(pb.cpp).string_type = CORD];
}
Следующий пример показывает файл proto3:
syntax = "proto3"
message Foo {
string bar = 6;
string baz = 7 [ctype = CORD];
}
После запуска Prototiller эквивалентный код может выглядеть так:
edition = "2024";
import "google/protobuf/cpp_features.proto";
message Foo {
string bar = 6 [features.(pb.cpp).string_type = STRING];
string baz = 7 [features.(pb.cpp).string_type = CORD];
}
features.(pb.java).utf8_validation
Языки: Java
Эта специфичная для языка функция позволяет переопределить настройки на уровне файла на уровне поля только для Java.
Эта функция не влияет на файлы proto3, и поэтому в этом разделе нет примеров "до" и "после" для файла proto3.
Доступные значения:
DEFAULT: Поведение соответствует установленномуfeatures.utf8_validation.VERIFY: Переопределяет настройкуfeatures.utf8_validationна уровне файла, чтобы принудительно установить ее вVERIFYтолько для Java.
Применимо к следующим областям видимости: Field, File
Добавлено в: Редакция 2023
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | DEFAULT |
| 2023 | DEFAULT |
| proto3 | DEFAULT |
| proto2 | DEFAULT |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
Следующий пример кода показывает файл proto2:
syntax = "proto2";
option java_string_check_utf8=true;
message MyMessage {
string foo = 1;
string bar = 2;
}
После запуска Prototiller эквивалентный код может выглядеть так:
edition = "2024";
import "google/protobuf/java_features.proto";
option features.utf8_validation = NONE;
option features.(pb.java).utf8_validation = VERIFY;
message MyMessage {
string foo = 1;
string bar = 2;
}
features.(pb.go).strip_enum_prefix
Языки: Go
Значения перечислений не ограничены областью видимости их содержащего имени перечисления, поэтому рекомендуется добавлять префикс каждого значения именем перечисления:
edition = "2024";
enum Strip {
STRIP_ZERO = 0;
STRIP_ONE = 1;
}
Однако сгенерированный код Go теперь будет содержать два префикса!
type Strip int32
const (
Strip_STRIP_ZERO Strip = 0
Strip_STRIP_ONE Strip = 1
)
Специфичная для языка функция strip_enum_prefix определяет, будет ли генератор кода Go
удалять повторяющийся префикс или нет.
Доступные значения:
STRIP_ENUM_PREFIX_KEEP: Сохранять имя как есть, даже если оно повторяющееся.STRIP_ENUM_PREFIX_GENERATE_BOTH: Генерировать оба, полное имя и сокращенное имя (чтобы помочь с миграцией вашего кода Go).STRIP_ENUM_PREFIX_STRIP: Удалять префикс имени перечисления из имен значений перечисления.
Применимо к следующим областям видимости: Enum, File
Добавлено в: Редакция 2024
Поведение по умолчанию для синтаксиса/редакции:
| Синтаксис/редакция | По умолчанию |
|---|---|
| 2024 | STRIP_ENUM_PREFIX_KEEP |
Примечание: Настройки функций на разных элементах схемы имеют разные области видимости.
Вы можете установить функцию strip_enum_prefix в файлах .proto редакции 2024 (или новее):
edition = "2024";
import "google/protobuf/go_features.proto";
option features.(pb.go).strip_enum_prefix = STRIP_ENUM_PREFIX_STRIP;
enum Strip {
STRIP_ZERO = 0;
STRIP_ONE = 1;
}
Сгенерированный код Go теперь будет удалять префикс STRIP:
type Strip int32
const (
Strip_ZERO Strip = 0
Strip_ONE Strip = 1
)
Сохранение поведения Proto2 или Proto3 в Редакции 2023
Вы можете захотеть перейти на формат редакций, но еще не разбираться с обновлениями в способе поведения сгенерированного кода. Этот раздел показывает изменения, которые инструмент Prototiller вносит в ваши .proto файлы, чтобы заставить protobuf на основе редакции 2023 вести себя как файл proto2 или proto3.
После того как эти изменения сделаны на уровне файла, вы получаете значения по умолчанию proto2 или proto3. Вы можете переопределить на более низких уровнях (уровень сообщения, уровень поля), чтобы учесть дополнительные различия в поведении (такие как required, proto3 optional) или если вы хотите, чтобы ваше определение было почти как proto2 или proto3.
Мы рекомендуем использовать Prototiller, если у вас нет конкретной причины не делать этого. Чтобы вручную применить все это вместо использования Prototiller, добавьте содержимое из следующих разделов в начало вашего .proto файла.
Поведение Proto2
Следующее показывает настройки для воспроизведения поведения proto2 с Редакцией 2023.
edition = "2023";
import "google/protobuf/cpp_features.proto";
import "google/protobuf/java_features.proto";
option features.field_presence = EXPLICIT;
option features.enum_type = CLOSED;
option features.repeated_field_encoding = EXPANDED;
option features.json_format = LEGACY_BEST_EFFORT;
option features.utf8_validation = NONE;
option features.(pb.cpp).legacy_closed_enum = true;
option features.(pb.java).legacy_closed_enum = true;
Поведение Proto3
Следующее показывает настройки для воспроизведения поведения proto3 с Редакцией 2023.
edition = "2023";
import "google/protobuf/cpp_features.proto";
import "google/protobuf/java_features.proto";
option features.field_presence = IMPLICIT;
option features.enum_type = OPEN;
// `packed=false` необходимо преобразовать в функции repeated_field_encoding на уровне поля
// в синтаксисе Редакций
option features.json_format = ALLOW;
option features.utf8_validation = VERIFY;
option features.(pb.cpp).legacy_closed_enum = false;
option features.(pb.java).legacy_closed_enum = false;
Редакция 2023 к 2024
Следующее показывает настройки для воспроизведения поведения Редакции 2023 с Редакцией 2024.
// foo/bar_baz.proto
edition = "2024";
import option "third_party/protobuf/cpp_features.proto";
import option "third_party/java/protobuf/java_features.proto";
import option "third_party/golang/protobuf/v2/src/google/protobuf/go_features.proto";
// Если ранее полагались на значение по умолчанию java_outer_classname редакции 2023.
option java_outer_classname = "BarBaz" // или BarBazOuterClass
option features.(pb.cpp).string_type = STRING;
option features.enforce_naming_style = STYLE_LEGACY;
option features.default_symbol_visibility = EXPORT_ALL;
option features.(pb.cpp).enum_name_uses_string_view = false;
option features.(pb.go).api_level = API_OPEN;
message MyMessage {
option features.(pb.java).nest_in_file_class = YES;
}
Предостережения и исключения
Этот раздел показывает изменения, которые вам нужно будет сделать вручную, если вы решите не использовать Prototiller.
Установка значений по умолчанию на уровне файла, показанных в предыдущем разделе, устанавливает поведение по умолчанию в большинстве случаев, но есть несколько исключений.
Редакция 2023 и позже
optional: Удалите все экземпляры меткиoptionalи изменитеfeatures.field_presenceнаEXPLICIT, если значение по умолчанию для файла —IMPLICIT.required: Удалите все экземпляры меткиrequiredи добавьте опциюfeatures.field_presence=LEGACY_REQUIREDна уровне поля.groups: Развернитеgroupsв отдельное сообщение и добавьте опциюfeatures.message_encoding = DELIMITEDна уровне поля. См.features.message_encodingдля получения дополнительной информации об этом.java_string_check_utf8: Удалите эту опцию файла и замените ее наfeatures.(pb.java).utf8_validation. Вам нужно будет импортировать функции Java, как описано в Специфичные для языка функции.packed: Для файлов proto2, преобразованных в формат редакций, удалите опцию поляpackedи добавьте[features.repeated_field_encoding=PACKED]на уровне поля, когда вы не хотите поведенияEXPANDED, которое вы установили в Поведение Proto2. Для файлов proto3, преобразованных в формат редакций, добавьте[features.repeated_field_encoding=EXPANDED]на уровне поля, когда вы не хотите поведения по умолчанию для proto3.
Редакция 2024 и позже
- (C++)
ctype: Удалите все экземпляры опцииctypeи установите значениеfeatures.(pb.cpp).string_type. - (C++ и Go)
weak: Удалите слабый импорт. Используйтеimport optionвместо этого. - (Java)
java_multiple_files: Удалитеjava_multiple_filesи используйтеfeatures.(pb.java).nest_in_file_classвместо этого.