Feature-Einstellungen für Editionen

Protobuf-Editions-Features und wie sie das Verhalten von Protobuf beeinflussen.

Dieses Thema gibt einen Überblick über die Features, die in den veröffentlichten Editionen enthalten sind. Features nachfolgender Editionen werden diesem Thema hinzugefügt. Neue Editionen kündigen wir im Bereich Nachrichten an.

Bevor Sie Feature-Einstellungen in Ihrem neuen Schema-Definitionsinhalt konfigurieren, stellen Sie sicher, dass Sie verstehen, warum Sie sie verwenden. Vermeiden Sie Cargo-Culting mit Features.

Prototiller

Prototiller ist ein Befehlszeilentool, das Proto-Schema-Konfigurationsdateien zwischen Syntaxversionen und Editionen aktualisiert. Es wurde noch nicht veröffentlicht, wird aber in diesem Thema durchgängig referenziert.

Features

Die folgenden Abschnitte enthalten alle Verhaltensweisen, die mit Features in Editionen konfigurierbar sind. Proto2- oder Proto3-Verhalten beibehalten zeigt, wie Standardverhalten überschrieben wird, damit Ihre Proto-Definitionsdateien wie Proto2- oder Proto3-Dateien funktionieren. Weitere Informationen darüber, wie Editionen und Features zusammenarbeiten, um Verhalten festzulegen, finden Sie in Protobuf Editions Übersicht.

Feature-Einstellungen gelten auf verschiedenen Ebenen

Dateiebene: Diese Einstellungen gelten für alle Elemente (Nachrichten, Felder, Enums usw.), die keine überschreibende Einstellung haben.

Nicht-verschachtelt: Nachrichten, Enums und Services können Einstellungen auf Dateiebene überschreiben. Sie gelten für alles darin (Nachrichtenfelder, Enum-Werte), was nicht überschrieben wird, aber nicht für andere parallele Nachrichten und Enums.

Verschachtelt: Oneofs, Nachrichten und Enums können Einstellungen aus der Nachricht überschreiben, in der sie verschachtelt sind.

Niedrigste Ebene: Felder, Erweiterungen, Enum-Werte, Erweiterungsbereiche und Methoden sind die niedrigste Ebene, auf der Sie Einstellungen überschreiben können.

Jeder der folgenden Abschnitte enthält einen Kommentar, der angibt, auf welchen Geltungsbereich das Feature angewendet werden kann. Das folgende Beispiel zeigt ein Mock-Feature, das auf jeden Geltungsbereich angewendet wird

edition = "2024";

// File-level scope definition
option features.bar = BAZ;

enum Foo {
  // Enum (non-nested scope) definition
  option features.bar = QUX;

  A = 1;
  B = 2;
}

message Corge {
  // Message (non-nested scope) definition
  option features.bar = QUUX;

  message Garply {
    // Message (nested scope) definition
    option features.bar = WALDO;
    string id = 1;
  }

  // Field (lowest-level scope) definition
  Foo A = 1 [features.bar = GRAULT];
}

In diesem Beispiel überschreibt die Einstellung "GRAULT" im Feature-Definition der niedrigsten Ebene die Einstellung "QUUX" im nicht verschachtelten Geltungsbereich. Und innerhalb der Garply-Nachricht überschreibt "WALDO" "QUUX."

features.default_symbol_visibility

Dieses Feature ermöglicht die Einstellung der Standard-Sichtbarkeit für Nachrichten und Enums, wodurch sie beim Import durch andere Protoss verfügbar oder nicht verfügbar gemacht werden. Die Verwendung dieses Features reduziert tote Symbole, um kleinere Binärdateien zu erstellen.

Zusätzlich zur Einstellung der Standardwerte für die gesamte Datei können Sie die Schlüsselwörter local und export verwenden, um das Verhalten pro Feld festzulegen. Lesen Sie mehr dazu unter export / local Schlüsselwörter.

Verfügbare Werte

  • EXPORT_ALL: Dies ist der Standard vor Edition 2024. Alle Nachrichten und Enums werden standardmäßig exportiert.
  • EXPORT_TOP_LEVEL: Alle Top-Level-Symbole werden standardmäßig exportiert; verschachtelte Symbole standardmäßig lokal.
  • LOCAL_ALL: Alle Symbole sind standardmäßig lokal.
  • STRICT: Alle Symbole sind standardmäßig lokal. Verschachtelte Typen können nicht exportiert werden, mit Ausnahme einer speziellen Ausnahme für message { enum {} reserved 0 to max; }. Dies wird in einer zukünftigen Edition zum Standard.

Anwendbar auf folgenden Geltungsbereich: Enum, Nachricht

Hinzugefügt in: Edition 2024

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024EXPORT_TOP_LEVEL
2023EXPORT_ALL
proto3EXPORT_ALL
proto2EXPORT_ALL

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

Das folgende Beispiel zeigt, wie Sie das Feature auf Elemente in Ihren Proto-Schema-Definitionsdateien anwenden können

// foo.proto
edition = "2024";

// Symbol visibility defaults to EXPORT_TOP_LEVEL. Setting
// default_symbol_visibility overrides these defaults
option features.default_symbol_visibility = LOCAL_ALL;

// Top-level symbols are exported by default in Edition 2024; applying the local
// keyword overrides this
export message LocalMessage {
  int32 baz = 1;
  // Nested symbols are local by default in Edition 2024; applying the export
  // keyword overrides this
  enum ExportedNestedEnum {
    UNKNOWN_EXPORTED_NESTED_ENUM_VALUE = 0;
  }
}

// bar.proto
edition = "2024";

import "foo.proto";

message ImportedMessage {
  // The following is valid because the imported message explicitly overrides
  // the visibility setting in foo.proto
  LocalMessage bar = 1;

  // The following is not valid because default_symbol_visibility is set to
  // `LOCAL_ALL`
  // LocalMessage.ExportedNestedEnum qux = 2;
}

features.enforce_naming_style

Eingeführt in Edition 2024, erzwingt dieses Feature die strenge Einhaltung des Namensstils, wie in dem Styleguide definiert, um sicherzustellen, dass Protoss standardmäßig Round-Trippable sind, mit einem Feature-Wert zum Opt-out zur Verwendung

Verfügbare Werte

  • STYLE2024: Erzwingt die strenge Einhaltung des Styleguides für die Benennung.
  • STYLE_LEGACY: Wendet das Stilrichtlinien-Durchsetzungsniveau vor Edition 2024 an.

Anwendbar auf folgenden Geltungsbereich: Datei

Hinzugefügt in: Edition 2024

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024STYLE2024
2023STYLE_LEGACY
proto3STYLE_LEGACY
proto2STYLE_LEGACY

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

Das folgende Codebeispiel zeigt eine Datei der Edition 2023

Edition 2023 standardmäßig STYLE_LEGACY, daher ist ein nicht konformer Feldname in Ordnung

edition = "2023";

message Foo {
  // A non-conforming field name is not a problem
  int64 bar_1 = 1;
}

Edition 2024 standardmäßig STYLE2024, daher ist eine Überschreibung erforderlich, um den nicht konformen Feldnamen beizubehalten

edition = "2024";

// To keep the non-conformant field name, override the STYLE2024 setting
option features.enforce_naming_style = "STYLE_LEGACY";

message Foo {
  int64 bar_1 = 1;
}

features.enum_type

Dieses Feature legt das Verhalten fest, wie Enum-Werte behandelt werden, die nicht in der definierten Menge enthalten sind. Weitere Informationen zu offenen und geschlossenen Enums finden Sie unter Enum-Verhalten.

Dieses Feature hat keine Auswirkungen auf Proto3-Dateien, daher hat dieser Abschnitt keine Vorher- und Nachher-Darstellung einer Proto3-Datei.

Verfügbare Werte

  • CLOSED: Geschlossene Enums speichern Enum-Werte außerhalb des Bereichs im unbekannten Feld-Set.
  • OPEN: Offene Enums parsen Werte außerhalb des Bereichs direkt in ihre Felder.

Anwendbar auf folgende Geltungsbereiche: Datei, Enum

Hinzugefügt in: Edition 2023

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024OPEN
2023OPEN
proto3OPEN
proto2CLOSED

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

Das folgende Codebeispiel zeigt eine Proto2-Datei

syntax = "proto2";

enum Foo {
  A = 2;
  B = 4;
  C = 6;
}

Nach dem Ausführen von Prototiller könnte der entsprechende Code wie folgt aussehen

edition = "2024";

enum Foo {
  // Setting the enum_type feature overrides the default OPEN enum
  option features.enum_type = CLOSED;
  A = 2;
  B = 4;
  C = 6;
}

features.field_presence

Dieses Feature legt das Verhalten für die Verfolgung der Feldpräsenz fest, also ob ein Protobuf-Feld einen Wert hat.

Verfügbare Werte

  • LEGACY_REQUIRED: Das Feld ist für Parsing und Serialisierung erforderlich. Jeder explizit gesetzte Wert wird auf den Draht serialisiert (auch wenn er mit dem Standardwert identisch ist).
  • EXPLICIT: Das Feld hat eine explizite Präsenzverfolgung. Jeder explizit gesetzte Wert wird auf den Draht serialisiert (auch wenn er mit dem Standardwert identisch ist). Für singuläre primitive Felder werden has_*-Funktionen für Felder generiert, die auf EXPLICIT gesetzt sind.
  • IMPLICIT: Das Feld hat keine Präsenzverfolgung. Der Standardwert wird nicht auf den Draht serialisiert (auch wenn er explizit gesetzt ist). has_*-Funktionen werden für Felder, die auf IMPLICIT gesetzt sind, nicht generiert.

Anwendbar auf folgende Geltungsbereiche: Datei, Feld

Hinzugefügt in: Edition 2023

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024EXPLICIT
2023EXPLICIT
proto3IMPLICIT*
proto2EXPLICIT

* proto3 ist IMPLICIT, es sei denn, das Feld hat das Label optional, in diesem Fall verhält es sich wie EXPLICIT. Siehe Präsenz in Proto3-APIs für weitere Informationen.

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

Das folgende Codebeispiel zeigt eine Proto2-Datei

syntax = "proto2";

message Foo {
  required int32 x = 1;
  optional int32 y = 2;
  repeated int32 z = 3;
}

Nach dem Ausführen von Prototiller könnte der entsprechende Code wie folgt aussehen

edition = "2024";

message Foo {
  // Setting the field_presence feature retains the proto2 required behavior
  int32 x = 1 [features.field_presence = LEGACY_REQUIRED];
  int32 y = 2;
  repeated int32 z = 3;
}

Das Folgende zeigt eine Proto3-Datei

syntax = "proto3";

message Bar {
  int32 x = 1;
  optional int32 y = 2;
  repeated int32 z = 3;
}

Nach dem Ausführen von Prototiller könnte der entsprechende Code wie folgt aussehen

edition = "2024";
// Setting the file-level field_presence feature matches the proto3 implicit default
option features.field_presence = IMPLICIT;

message Bar {
  int32 x = 1;
  // Setting the field_presence here retains the explicit state that the proto3
  // field has because of the optional syntax
  int32 y = 2 [features.field_presence = EXPLICIT];
  repeated int32 z = 3;
}

Beachten Sie, dass die Labels required und optional in Editionen nicht mehr existieren, da das entsprechende Verhalten explizit mit dem field_presence-Feature festgelegt wird.

features.json_format

Dieses Feature legt das Verhalten für das JSON-Parsing und die JSON-Serialisierung fest.

Dieses Feature hat keine Auswirkungen auf Proto3-Dateien, daher hat dieser Abschnitt keine Vorher- und Nachher-Darstellung einer Proto3-Datei. Das Verhalten von Editionen entspricht dem Verhalten in Proto3.

Verfügbare Werte

  • ALLOW: Eine Laufzeitumgebung muss JSON-Parsing und -Serialisierung zulassen. Prüfungen werden auf Proto-Ebene durchgeführt, um sicherzustellen, dass eine eindeutige Zuordnung zu JSON besteht.
  • LEGACY_BEST_EFFORT: Eine Laufzeitumgebung tut ihr Bestes, um JSON zu parsen und zu serialisieren. Bestimmte Protoss sind zulässig, die zu undefiniertem Verhalten zur Laufzeit führen können (z. B. Many:1- oder 1:Many-Zuordnungen).

Anwendbar auf folgende Geltungsbereiche: Datei, Nachricht, Enum

Hinzugefügt in: Edition 2023

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024ALLOW
2023ALLOW
proto3ALLOW
proto2LEGACY_BEST_EFFORT

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

Das folgende Codebeispiel zeigt eine Proto2-Datei

syntax = "proto2";

message Foo {
  // Warning only
  string bar = 1;
  string bar_ = 2;
}

Nach dem Ausführen von Prototiller könnte der entsprechende Code wie folgt aussehen

edition = "2024";
option features.json_format = LEGACY_BEST_EFFORT;

message Foo {
  string bar = 1;
  string bar_ = 2;
}

features.message_encoding

Dieses Feature legt das Verhalten für die Codierung von Feldern bei der Serialisierung fest.

Dieses Feature hat keine Auswirkungen auf Proto3-Dateien, daher hat dieser Abschnitt keine Vorher- und Nachher-Darstellung einer Proto3-Datei.

Abhängig von der Sprache können Felder, die "gruppenähnlich" sind, einige unerwartete Groß-/Kleinschreibung im generierten Code und im Textformat aufweisen, um die Abwärtskompatibilität mit proto2 zu gewährleisten. Nachrichtenfelder sind "gruppenähnlich", wenn alle folgenden Bedingungen erfüllt sind

  • Hat die DELIMITED-Nachrichtencodierung angegeben
  • Der Nachrichtentyp ist im selben Geltungsbereich wie das Feld definiert
  • Feldname ist exakt der kleingeschriebene Typname

Verfügbare Werte

  • LENGTH_PREFIXED: Felder werden mit dem LEN-Wire-Typ codiert, wie in Nachrichtenstruktur beschrieben.
  • DELIMITED: Nachrichten-Typ-Felder werden als Gruppen codiert.

Anwendbar auf folgende Geltungsbereiche: Datei, Feld

Hinzugefügt in: Edition 2023

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024LENGTH_PREFIXED
2023LENGTH_PREFIXED
proto3LENGTH_PREFIXED
proto2LENGTH_PREFIXED

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

Das folgende Codebeispiel zeigt eine Proto2-Datei

syntax = "proto2";

message Foo {
  group Bar = 1 {
    optional int32 x = 1;
    repeated int32 y = 2;
  }
}

Nach dem Ausführen von Prototiller könnte der entsprechende Code wie folgt aussehen

edition = "2024";

message Foo {
  message Bar {
    int32 x = 1;
    repeated int32 y = 2;
  }
  Bar bar = 1 [features.message_encoding = DELIMITED];
}

features.repeated_field_encoding

Dieses Feature ist das, worauf die proto2/proto3 packed Option für repeated Felder in Editionen migriert wurde.

Verfügbare Werte

  • PACKED: Repeated Felder eines primitiven Typs werden als ein einzelner LEN-Datensatz codiert, der jedes Element verkettet enthält.
  • EXPANDED: Repeated Felder werden jeweils mit der Feldnummer für jeden Wert codiert.

Anwendbar auf folgende Geltungsbereiche: Datei, Feld

Hinzugefügt in: Edition 2023

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024PACKED
2023PACKED
proto3PACKED
proto2EXPANDED

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

Das folgende Codebeispiel zeigt eine Proto2-Datei

syntax = "proto2";

message Foo {
  repeated int32 bar = 6 [packed=true];
  repeated int32 baz = 7;
}

Nach dem Ausführen von Prototiller könnte der entsprechende Code wie folgt aussehen

edition = "2024";
option features.repeated_field_encoding = EXPANDED;

message Foo {
  repeated int32 bar = 6 [features.repeated_field_encoding=PACKED];
  repeated int32 baz = 7;
}

Das Folgende zeigt eine Proto3-Datei

syntax = "proto3";

message Foo {
  repeated int32 bar = 6;
  repeated int32 baz = 7 [packed=false];
}

Nach dem Ausführen von Prototiller könnte der entsprechende Code wie folgt aussehen

edition = "2024";

message Foo {
  repeated int32 bar = 6;
  repeated int32 baz = 7 [features.repeated_field_encoding=EXPANDED];
}

features.utf8_validation

Dieses Feature legt fest, wie Strings validiert werden. Es gilt für alle Sprachen, außer wenn es ein sprachspezifisches utf8_validation-Feature gibt, das es überschreibt. Siehe features.(pb.java).utf8_validation für das sprachspezifische Java-Feature.

Dieses Feature hat keine Auswirkungen auf Proto3-Dateien, daher hat dieser Abschnitt keine Vorher- und Nachher-Darstellung einer Proto3-Datei.

Verfügbare Werte

  • VERIFY: Die Laufzeitumgebung sollte UTF-8 verifizieren. Dies ist das Standardverhalten von proto3.
  • NONE: Das Feld verhält sich auf dem Draht wie ein nicht verifiziertes bytes-Feld. Parser können diese Art von Feld unvorhersehbar behandeln, z. B. durch Ersetzen ungültiger Zeichen. Dies ist das Standardverhalten von proto2.

Anwendbar auf folgende Geltungsbereiche: Datei, Feld

Hinzugefügt in: Edition 2023

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024VERIFY
2023VERIFY
proto3VERIFY
proto2NONE

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

Das folgende Codebeispiel zeigt eine Proto2-Datei

syntax = "proto2";

message MyMessage {
  string foo = 1;
}

Nach dem Ausführen von Prototiller könnte der entsprechende Code wie folgt aussehen

edition = "2024";

message MyMessage {
  string foo = 1 [features.utf8_validation = NONE];
}

Sprachspezifische Features

Einige Features gelten für bestimmte Sprachen und nicht für dieselben Protoss in anderen Sprachen. Die Verwendung dieser Features erfordert den Import der entsprechenden *_features.proto-Datei aus der Laufzeitumgebung der Sprache. Die Beispiele in den folgenden Abschnitten zeigen diese Importe.

features.(pb.go).api_level

Sprachen: Go

Das Feature api_level ermöglicht es Ihnen, auszuwählen, für welche API-Version das Go-Protokollpuffer-Plugin Code generieren soll. Die Opaque API ist die neueste Version der Protokollpuffer-Implementierung für die Go-Programmiersprache. Die vorherige Version wird jetzt Open Struct API genannt. Sehen Sie sich den Go Protobuf: Releasing the Opaque API Blog-Post für eine Einführung an.

Verfügbare Werte

  • API_OPEN: Die Open Struct API generiert Strukturtypen, die für den direkten Zugriff offen sind.
  • API_HYBRID: Hybrid ist ein Schritt zwischen Open und Opaque: Die Hybrid-API enthält auch Zugriffsfunktionen (damit Sie Ihren Code aktualisieren können), exportiert aber weiterhin die Strukturfelder wie zuvor. Es gibt keinen Leistungsunterschied; diese API-Ebene hilft nur bei der Migration.
  • API_OPAQUE: Mit der Opaque API sind die Strukturfelder verborgen und können nicht mehr direkt zugegriffen werden. Stattdessen ermöglichen die neuen Zugriffsfunktionen das Abrufen, Setzen oder Löschen eines Feldes.

Anwendbar auf folgende Geltungsbereiche: Nachricht, Datei

Hinzugefügt in: Edition 2023

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2023API_OPEN
2024API_OPAQUE

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

Sie können das Feature api_level ab Edition 2023 festlegen

edition = "2023";

import "google/protobuf/go_features.proto";

// Remove this line after migrating the code to the Opaque API.
option features.(pb.go).api_level = API_HYBRID;

Siehe auch: Opaque API: Migration

features.(pb.cpp).enum_name_uses_string_view

Sprachen: C++

Vor Edition 2024 lieferten alle generierten Enum-Typen die folgende Funktion, um das Label aus einem Enum-Wert zu erhalten, was einen gewissen Overhead beim Erstellen der std::string-Instanzen zur Laufzeit verursacht

const std::string& Foo_Name(int);

Der Standard-Feature-Wert in Edition 2024 ändert diese Signatur so, dass absl::string_view zurückgegeben wird, um eine bessere Entkopplung der Speicherung und potenzielle Speicher-/CPU-Einsparungen zu ermöglichen. Wenn Sie noch nicht bereit sind zu migrieren, können Sie dies überschreiben, um es zu seinem vorherigen Verhalten zurückzusetzen. Siehe string_view Rückgabetyp im Migrationshandbuch für mehr zu diesem Thema.

Verfügbare Werte

  • true: Das Enum verwendet string_view für seine Werte.
  • false: Das Enum verwendet std::string für seine Werte.

Anwendbar auf folgende Geltungsbereiche: Enum, Datei

Hinzugefügt in: Edition 2024

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024true
2023false
proto3false
proto2false

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

features.(pb.java).large_enum

Sprachen: Java

Dieses sprachspezifische Feature ermöglicht es Ihnen, neue Funktionalitäten zu übernehmen, die mit großen Enums in Java umgehen, ohne Compilerfehler zu verursachen. Beachten Sie, dass dieses Feature Enum-ähnliches Verhalten repliziert, aber einige bemerkenswerte Unterschiede aufweist. Zum Beispiel werden Switch-Anweisungen nicht unterstützt.

Verfügbare Werte

  • true: Java-Enums verwenden die neue Funktionalität.
  • false: Java-Enums verwenden weiterhin Java-Enums.

Anwendbar auf folgenden Geltungsbereich: Enum

Hinzugefügt in: Edition 2024

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024false
2023false
proto3false
proto2false

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

features.(pb.cpp/pb.java).legacy_closed_enum

Sprachen: C++, Java

Dieses Feature bestimmt, ob ein Feld mit einem offenen Enum-Typ so behandelt werden soll, als wäre es ein geschlossenes Enum. Dies ermöglicht es Editionen, nicht-konformes Verhalten in Java und C++ aus proto2 und proto3 zu reproduzieren.

Dieses Feature hat keine Auswirkungen auf Proto3-Dateien und daher hat dieser Abschnitt keine Vorher- und Nachher-Darstellung einer Proto3-Datei.

Verfügbare Werte

  • true: Behandelt das Enum als geschlossen, unabhängig von enum_type.
  • false: Beachtet, was auch immer in enum_type eingestellt ist.

Anwendbar auf folgende Geltungsbereiche: Datei, Feld

Hinzugefügt in: Edition 2023

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024false
2023false
proto3false
proto2true

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

Das folgende Codebeispiel zeigt eine Proto2-Datei

syntax = "proto2";

import "myproject/proto3file.proto";

message Msg {
  myproject.proto3file.Proto3Enum name = 1;
}

Nach dem Ausführen von Prototiller könnte der entsprechende Code wie folgt aussehen

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

Sprachen: Java

Dieses Feature steuert, ob der Java-Generator die generierte Klasse in der Java-generierten Klassendatei verschachtelt. Das Setzen dieser Option auf NO ist äquivalent zum Setzen von java_multiple_files = true in proto2/proto3/Edition 2023.

Der Standard-Außenklassenname wird auch aktualisiert, um immer der kamelkasig geschriebene .proto-Dateiname zu sein, der standardmäßig mit Proto endet (z. B. wird foo/bar_baz.proto zu BarBazProto). Sie können dies immer noch mit der Dateioption java_outer_classname überschreiben und den Standard vor Edition 2024 von BarBaz oder BarBazOuterClass ersetzen, abhängig vom Vorhandensein von Konflikten.

Verfügbare Werte

  • NO: Verschachteln Sie die generierte Klasse nicht in der Klassendatei.
  • YES: Verschachteln Sie die generierte Klasse in der Klassendatei.
  • Legacy: Ein interner Wert, der verwendet wird, wenn die Option java_multiple_files gesetzt ist.

Anwendbar auf folgende Geltungsbereiche: Nachricht, Enum, Service

Hinzugefügt in: Edition 2024

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024NO
2023LEGACY
proto3LEGACY
proto2LEGACY

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

features.(pb.cpp).string_type

Sprachen: C++

Dieses Feature bestimmt, wie generierter Code mit String-Feldern umgeht. Dies ersetzt die ctype-Option von proto2 und proto3 und bietet ein neues string_type-Feature. In Edition 2023 können Sie entweder ctype oder string_type für ein Feld angeben, aber nicht beides. In Edition 2024 wird die ctype-Option entfernt.

Verfügbare Werte

  • VIEW: Generiert string_view-Zugriffsmethoden für das Feld.
  • CORD: Generiert Cord-Zugriffsmethoden für das Feld. Nicht für Erweiterungsfelder unterstützt.
  • STRING: Generiert string-Zugriffsmethoden für das Feld.

Anwendbar auf folgende Geltungsbereiche: Datei, Feld

Hinzugefügt in: Edition 2023

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024VIEW
2023STRING
proto3STRING
proto2STRING

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

Das folgende Codebeispiel zeigt eine Proto2-Datei

syntax = "proto2";

message Foo {
  optional string bar = 6;
  optional string baz = 7 [ctype = CORD];
}

Nach dem Ausführen von Prototiller könnte der entsprechende Code wie folgt aussehen

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];
}

Das Folgende zeigt eine Proto3-Datei

syntax = "proto3"

message Foo {
  string bar = 6;
  string baz = 7 [ctype = CORD];
}

Nach dem Ausführen von Prototiller könnte der entsprechende Code wie folgt aussehen

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

Sprachen: Java

Dieses sprachspezifische Feature ermöglicht es Ihnen, die Einstellungen auf Dateiebene auf Feldebene nur für Java zu überschreiben.

Dieses Feature hat keine Auswirkungen auf Proto3-Dateien und daher hat dieser Abschnitt keine Vorher- und Nachher-Darstellung einer Proto3-Datei.

Verfügbare Werte

  • DEFAULT: Das Verhalten entspricht dem von features.utf8_validation festgelegten Verhalten.
  • VERIFY: Überschreibt die features.utf8_validation-Einstellung auf Dateiebene, um sie nur für Java auf VERIFY zu erzwingen.

Anwendbar auf folgende Geltungsbereiche: Feld, Datei

Hinzugefügt in: Edition 2023

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024DEFAULT
2023DEFAULT
proto3DEFAULT
proto2DEFAULT

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

Das folgende Codebeispiel zeigt eine Proto2-Datei

syntax = "proto2";

option java_string_check_utf8=true;

message MyMessage {
  string foo = 1;
  string bar = 2;
}

Nach dem Ausführen von Prototiller könnte der entsprechende Code wie folgt aussehen

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

Sprachen: Go

Enum-Werte sind nicht nach ihrem enthaltenden Enum-Namen eingegrenzt, daher wird das Präfixieren jedes Wertes mit dem Enum-Namen empfohlen

edition = "2024";

enum Strip {
  STRIP_ZERO = 0;
  STRIP_ONE = 1;
}

Der generierte Go-Code enthält jedoch nun zwei Präfixe!

type Strip int32

const (
    Strip_STRIP_ZERO Strip = 0
    Strip_STRIP_ONE  Strip = 1
)

Das sprachspezifische Feature strip_enum_prefix bestimmt, ob der Go-Code-Generator das repetitive Präfix entfernt oder nicht.

Verfügbare Werte

  • STRIP_ENUM_PREFIX_KEEP: Behält den Namen bei, auch wenn er repetitiv ist.
  • STRIP_ENUM_PREFIX_GENERATE_BOTH: Generiert beide, einen vollständigen Namen und einen gestrippten Namen (um bei der Migration Ihres Go-Codes zu helfen).
  • STRIP_ENUM_PREFIX_STRIP: Entfernt das Enum-Namen-Präfix aus den Enum-Wertnamen.

Anwendbar auf folgende Geltungsbereiche: Enum, Datei

Hinzugefügt in: Edition 2024

Standardverhalten pro Syntax/Edition

Syntax/EditionStandard
2024STRIP_ENUM_PREFIX_KEEP

Hinweis: Feature-Einstellungen für verschiedene Schemaelemente haben unterschiedliche Geltungsbereiche.

Sie können das Feature strip_enum_prefix in .proto-Dateien der Edition 2024 (oder neuer) festlegen

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;
}

Der generierte Go-Code entfernt nun das STRIP-Präfix

type Strip int32

const (
    Strip_ZERO Strip = 0
    Strip_ONE  Strip = 1
)

Proto2- oder Proto3-Verhalten in Edition 2023 beibehalten

Sie möchten möglicherweise zum Editionsformat wechseln, aber noch nicht die Änderungen am Verhalten des generierten Codes vornehmen. Dieser Abschnitt zeigt die Änderungen, die das Prototiller-Tool an Ihren .proto-Dateien vornimmt, um die auf Edition 2023 basierenden Protoss wie eine proto2- oder proto3-Datei zu verhalten.

Nachdem diese Änderungen auf Dateiebene vorgenommen wurden, erhalten Sie die Standardwerte von proto2 oder proto3. Sie können auf niedrigeren Ebenen (Nachrichtenebene, Feldebene) überschreiben, um zusätzliche Verhaltensunterschiede zu berücksichtigen (wie erforderlich, proto3 optional) oder wenn Sie möchten, dass Ihre Definition nur *fast* wie proto2 oder proto3 ist.

Wir empfehlen die Verwendung von Prototiller, es sei denn, Sie haben einen bestimmten Grund, dies nicht zu tun. Um all diese manuell anzuwenden, anstatt Prototiller zu verwenden, fügen Sie den Inhalt der folgenden Abschnitte am Anfang Ihrer .proto-Datei hinzu.

Proto2-Verhalten

Das Folgende zeigt die Einstellungen zur Reproduktion des proto2-Verhaltens mit Edition 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-Verhalten

Das Folgende zeigt die Einstellungen zur Reproduktion des proto3-Verhaltens mit Edition 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` needs to be transformed to field-level repeated_field_encoding
// features in Editions syntax
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;

Edition 2023 bis 2024

Das Folgende zeigt die Einstellungen zur Reproduktion des Verhaltens von Edition 2023 mit Edition 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";

// If previously relying on edition 2023 default java_outer_classname.
option java_outer_classname = "BarBaz" // or 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;
}

Hinweise und Ausnahmen

Dieser Abschnitt zeigt die Änderungen, die Sie manuell vornehmen müssen, wenn Sie sich entscheiden, Prototiller nicht zu verwenden.

Das Festlegen der Dateiebene-Standardwerte im vorherigen Abschnitt legt in den meisten Fällen das Standardverhalten fest, aber es gibt einige Ausnahmen.

Edition 2023 und später

  • optional: Entfernen Sie alle Instanzen des Labels optional und ändern Sie features.field_presence auf EXPLICIT, wenn der Standardwert der Datei IMPLICIT ist.
  • required: Entfernen Sie alle Instanzen des Labels required und fügen Sie die Option features.field_presence=LEGACY_REQUIRED auf Feldebene hinzu.
  • groups: Wickeln Sie die groups in eine separate Nachricht aus und fügen Sie die Option features.message_encoding = DELIMITED auf Feldebene hinzu. Siehe features.message_encoding für mehr dazu.
  • java_string_check_utf8: Entfernen Sie diese Dateioption und ersetzen Sie sie durch features.(pb.java).utf8_validation. Sie müssen Java-Features importieren, wie in Sprachspezifische Features behandelt.
  • packed: Bei Konvertierung von proto2-Dateien in das Editionsformat entfernen Sie die Feldoption packed und fügen Sie [features.repeated_field_encoding=PACKED] auf Feldebene hinzu, wenn Sie nicht das EXPANDED-Verhalten wünschen, das Sie in Proto2-Verhalten festgelegt haben. Bei Konvertierung von proto3-Dateien in das Editionsformat fügen Sie [features.repeated_field_encoding=EXPANDED] auf Feldebene hinzu, wenn Sie nicht das Standard-proto3-Verhalten wünschen.

Edition 2024 und später