Migrationsleitfaden

Eine Liste der Änderungen, die Breaking Changes für Versionen der Bibliotheken darstellen, und wie Sie Ihren Code anpassen, um diese Änderungen zu berücksichtigen.

Änderungen in v30.0

Die folgende Liste enthält die Änderungen, die Breaking Changes für Versionen der Bibliotheken darstellen, und wie Sie Ihren Code anpassen, um diese Änderungen zu berücksichtigen.

Dies umfasst Breaking Changes, die in den Nachrichtenankündigungen für v30.x und Versionshinweisen für v30.0 angekündigt wurden.

CMake-Submodule durch abgerufene Abhängigkeiten ersetzt

Zuvor war unser Standard-CMake-Verhalten die Verwendung von Git-Submodulen, um angepinnte Abhängigkeiten abzurufen. Die Angabe von -Dprotobuf_ABSL_PROVIDER=package würde unsere CMake-Konfigurationen umschalten, um nach lokalen Installationen von Abseil (mit ähnlichen Optionen für jsoncpp und gtest) zu suchen. Diese Optionen existieren nicht mehr, und das Standardverhalten ist, zuerst nach Installationen aller unserer Abhängigkeiten zu suchen und bei Bedarf auf das Herunterladen von angepinnten Versionen von GitHub zurückzugreifen.

Um das Zurückfallen auf das Herunterladen zu verhindern (ähnlich dem alten package-Verhalten), können Sie CMake aufrufen mit

cmake . -Dprotobuf_LOCAL_DEPENDENCIES_ONLY=ON

Um Abhängigkeiten immer von einer festen Version herunterzuladen (ähnlich dem alten Standardverhalten), können Sie CMake aufrufen mit

cmake . -Dprotobuf_FORCE_FETCH_DEPENDENCIES=ON

Rückgabetyp string_view

Rückgabetypen sind jetzt absl::string_view für die folgenden Descriptor-APIs, was Speicherplatz spart

  • MessageLite::GetTypeName
  • UnknownField::length_delimited
  • Descriptor-API-Namensfunktionen, wie z. B. FieldDescriptor::full_name

Wir erwarten, dass zukünftige Breaking Releases weitere APIs auf absl::string_view migrieren werden.

In den meisten Fällen sollten Sie versuchen, Typen auf die Verwendung von absl::string_view umzustellen, wo dies sicher ist, oder explizit in den ursprünglichen Typ zu kopieren, wo dies erforderlich ist. Möglicherweise müssen Sie auch Aufrufer aktualisieren, wenn dies in einer Funktion zurückgegeben wird.

Wenn der von den betroffenen API-Methoden zurückgegebene String verwendet wird als

TypMigration

std::string

Konvertieren Sie explizit in std::string, um das bestehende Verhalten beizubehalten.

Oder steigen Sie auf das performantere absl::string_view um

const std::string&

Migrieren Sie zu absl::string_view

Wenn nicht möglich (z. B. aufgrund einer großen Anzahl von Abhängigkeiten), kann das Kopieren in eine std::string einfacher sein.

const std::string*

const char*

Wenn nullfähig, migrieren Sie zu std::optional<absl::string_view>.

Andernfalls migrieren Sie zu absl::string_view.

Seien Sie vorsichtig beim Aufrufen von data(), da absl::string_view nicht garantiert nullterminiert ist.

Für gängige Container und andere APIs können Sie möglicherweise auf Varianten umstellen, die mit absl::string_view kompatibel sind. Nachfolgend finden Sie einige gängige Beispiele.

KategorieVor der MigrationMigration
Einfügen in std::vector<std::string>

push_back()

push_front()

push()

emplace_back()

emplace_front()

emplace()

Einfügen für Maps oder Sets

set.insert(key)

map.insert({key, value})

map.insert({key,
{value_params...}})

set.emplace(key)

map.emplace(key, value)

map.try_emplace(key,
value_params...)

Suche für Maps oder Sets

find()

count()

contains()

Migrieren Sie zu Abseil-Containern.

Oder definieren Sie einen transparenten Komparator.

std::set<std::string, std::less<>>
std::map<std::string, T, std::less<>>

Siehe https://abseil.io/tips/144

String-Verkettung

operator+

operator+=

absl::StrCat()

absl::StrAppend()

Diese werden ohnehin aus Leistungsgründen empfohlen. Siehe https://abseil.io/tips/3.

Siehe auch https://abseil.io/tips/1 für allgemeine Tipps zur Verwendung von absl::string_view.

Poison MSVC + Bazel

Bazel-Benutzer unter Windows sollten zu clang-cl wechseln, indem sie Folgendes zu ihrem Projekt hinzufügen, wie in diesem Beispiel.

.bazelrc

common --enable_platform_specific_config build:windows
--extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl
--extra_execution_platforms=//:x64_windows-clang-cl

MODULE.bazel

bazel_dep(name = "platforms", version = "0.0.10")
bazel_dep(name = "rules_cc", version = "0.0.17")

# For clang-cl configuration
cc_configure = use_extension("@rules_cc//cc:extensions.bzl", "cc_configure_extension")
use_repo(cc_configure, "local_config_cc")

WORKSPACE

load("//:protobuf_deps.bzl", "PROTOBUF_MAVEN_ARTIFACTS", "protobuf_deps")

protobuf_deps()

load("@rules_cc//cc:repositories.bzl", "rules_cc_dependencies", "rules_cc_toolchains")

rules_cc_dependencies()

rules_cc_toolchains()

BUILD

Für Benutzer, die nur Kompatibilität mit Bazel 8 benötigen.

platform(
    name = "x64_windows-clang-cl",
    constraint_values = [
        "@platforms//cpu:x86_64",
        "@platforms//os:windows",
        "@bazel_tools//tools/cpp:clang-cl",
    ],
)

Für Benutzer, die Kompatibilität mit Bazel 7 und 8 benötigen.

platform(
    name = "x64_windows-clang-cl",
    constraint_values = [
        "@platforms//cpu:x86_64",
        "@platforms//os:windows",
        # See https://github.com/bazelbuild/rules_cc/issues/330.
        "@rules_cc//cc/private/toolchain:clang-cl",
    ],
)

Benutzer können den Fehler auch vorübergehend unterdrücken, indem sie die Opt-out-Flagge --define=protobuf_allow_msvc=true bis zur nächsten Breaking-Version setzen.

Alternativ können Benutzer, die MSVC weiterhin verwenden möchten, zu CMake wechseln. Dies kann mit Visual Studio erfolgen oder durch Angabe eines MSVC-Generators in der CMake-Kommandozeile. Zum Beispiel

cmake -G "Visual Studio 17 2022" -A Win64 .

ctype aus FieldDescriptor-Optionen entfernt

Wir haben die ctype aus FieldDescriptor-Optionen nicht mehr verfügbar gemacht. Sie können stattdessen die API FieldDescriptor::cpp_string_type() verwenden, die in der v28-Version hinzugefügt wurde.

Debug-APIs modifiziert, um sensible Felder zu schwärzen

Die Protobuf C++ Debug-APIs (einschließlich Protobuf AbslStringify, proto2::ShortFormat, proto2::Utf8Format, Message::DebugString, Message::ShortDebugString, Message::Utf8DebugString) wurden geändert, um sensible Felder, die mit debug_redact annotiert sind, zu schwärzen; die Ausgaben dieser APIs enthalten ein pro-Prozess randomisiertes Präfix und sind nicht mehr von Protobuf TextFormat Parsers parsbar. Benutzer sollten das neue geschwärzte Debug-Format für die meisten Fälle übernehmen, die eine menschenlesbare Ausgabe erfordern (z. B. Logging), oder erwägen, auf das binäre Format für Serialisierung und Deserialisierung umzusteigen. Benutzer, die das alte parsable Format benötigen, können TextFormat.printer().printToString(proto) verwenden, dies schwärzt jedoch keine sensiblen Felder und sollte daher mit Vorsicht verwendet werden.

Lesen Sie mehr darüber im Nachrichtenartikel vom 4. Dezember 2024.

Veraltete APIs entfernt

Wir haben die folgenden öffentlichen Runtime-APIs entfernt, die seit mindestens einer Minor- oder Major-Version als veraltet (z. B. ABSL_DEPRECATED) gekennzeichnet waren und die obsolet oder ersetzt sind.

API: Arena::CreateMessage

Ersatz: Arena::Create

API: Arena::GetArena

Ersatz: value->GetArena()

API: RepeatedPtrField::ClearedCount

Ersatz: Migration zu Arenen (Migrationsleitfaden).

API: JsonOptions

Ersatz: JsonPrintOptions

C++14-Unterstützung eingestellt

Diese Version hat C++14 als Mindestunterstützungsversion gestrichen und auf 17 angehoben, gemäß der Foundational C++ Support Matrix.

Benutzer sollten auf C++17 aktualisieren.

ASAN-Poisoning nach dem Löschen von Oneof-Nachrichten auf Arena eingeführt

Diese Änderung fügte eine Härtungsprüfung hinzu, die C++-Protobufs mit Arenen betrifft. Oneof-Nachrichten, die auf der Protobuf-Arena allokiert sind, werden jetzt in Debug-Modus gelöscht und im ASAN-Modus vergiftet. Nach dem Aufruf von clear führen zukünftige Versuche, den Speicherbereich zu verwenden, zu einem Absturz in ASAN als Use-after-free-Fehler.

Diese Implementierung erfordert C++17.

Unsere C++ CocoaPods-Veröffentlichung eingestellt

Wir haben unsere C++ CocoaPods-Veröffentlichung eingestellt, die seit v4.x.x fehlerhaft war. C++-Benutzer sollten stattdessen direkt unsere GitHub-Veröffentlichung verwenden.

Änderungen in Python

Python hat seine Hauptversion von 5.29.x auf 6.30.x hochgestuft.

Unterstützung für Python 3.8 eingestellt

Die minimale unterstützte Python-Version ist 3.9. Benutzer sollten aktualisieren.

Alias bazel/system_python.bzl entfernt

Wir haben den alten Alias bazel/system_python.bzl entfernt.

Entfernen Sie direkte Verweise auf system_python.bzl zugunsten der Verwendung von protobuf_deps.bzl. Verwenden Sie python/dist/system_python.bzl, wohin es in v5.27.0 verschoben wurde, wenn Sie einen direkten Verweis benötigen.

Änderungen bei der Validierung von Feldsettern

Die Feldsetter von Python und upb validieren nun geschlossene Enums unter Edition 2023. Aktualisierte geschlossene Enum-Felder mit ungültigen Werten generieren Fehler.

Veraltetes Makro py_proto_library entfernt

Das veraltete interne py_proto_library Bazel-Makro in protobuf.bzl wurde entfernt. Es wurde durch das offizielle py_proto_library ersetzt, das in v29.x nach protobuf in bazel/py_proto_library verschoben wurde. Diese Implementierung war vor v29.x in rules_python verfügbar.

Veraltete APIs entfernt

Wir haben die folgenden öffentlichen Runtime-APIs entfernt, die seit mindestens einer Minor- oder Major-Version als veraltet gekennzeichnet waren.

Reflection-Methoden

APIs: reflection.ParseMessage, reflection.MakeClass

Ersatz: message_factory.GetMessageClass()

RPC-Dienstschnittstellen

APIs: service.RpcException, service.Service, service.RpcController und service.RpcChannel

Ersatz: Ab Version 2.3.0 sollten RPC-Implementierungen nicht versuchen, darauf aufzubauen, sondern stattdessen Code-Generator-Plugins bereitstellen, die Code für die jeweilige RPC-Implementierung generieren.

MessageFactory- und SymbolDatabase-Methoden

APIs: MessageFactory.GetPrototype, MessageFactory.CreatePrototype, MessageFactory.GetMessages, SymbolDatabase.GetPrototype, SymbolDatabase.CreatePrototype und SymbolDatabase.GetMessages

Ersatz: message_factory.GetMessageClass() und message_factory.GetMessageClassesForFiles().

GetDebugString

APIs: GetDebugString

Ersatz

Kein Ersatz. Nur in Python C++, das nicht mehr veröffentlicht wird. Es wird in reinem Python oder UPB nicht unterstützt.

Änderung des setdefault-Verhaltens in Python für Map-Felder

setdefault ähnelt dict für ScalarMap, mit der Ausnahme, dass sowohl Schlüssel als auch Wert gesetzt werden müssen. setdefault wird für MessageMaps abgelehnt.

Python verschachtelte Nachrichtenklasse __qualname__ enthält den Namen der äußeren Nachricht

Die Python-verschachtelte Nachrichtenklasse __qualname__ enthält nun den Namen der äußeren Nachricht. Zuvor hatte __qualname__ dasselbe Ergebnis wie __name__ für verschachtelte Nachrichten, da der Name der äußeren Nachricht nicht enthalten war.

Zum Beispiel

message Foo {
  message Bar {
    bool bool_field = 1;
  }
}
nested = test_pb2.Foo.Bar()
self.assertEqual('Bar', nested.__class__.__name__)
self.assertEqual('Foo.Bar', nested.__class__.__qualname__) # It was 'Bar' before

Änderungen in Objective-C

Dies ist die erste Breaking-Version für Objective-C.

Objective-C hat seine Hauptversion von 3.x.x auf 4.30.x hochgestuft.

Überarbeitete Unknown Field Handling APIs, die die meisten bestehenden APIs veralten lassen

Wir haben GPBUnknownFieldSet veraltet und durch GPBUnknownFields ersetzt. Der neue Typ bewahrt die Reihenfolge der unbekannten Felder aus der ursprünglichen Eingabe oder den API-Aufrufen, um sicherzustellen, dass die semantische Bedeutung der Reihenfolge erhalten bleibt, wenn eine Nachricht wieder ausgegeben wird.

Als Teil dessen hat der Typ GPBUnknownField ebenfalls API-Änderungen erfahren, wobei fast alle bestehenden APIs veraltet und neue hinzugefügt wurden.

Veraltete Property-APIs

  • varintList
  • fixed32List
  • fixed64List
  • lengthDelimitedList
  • groupList

Veraltete Modifizierungs-APIs

  • addVarint
  • addFixed32
  • addFixed64
  • addLengthDelimited
  • addGroup

Veralteter Initialisierer initWithNumber:.

Neue Property-APIs

  • type
  • varint
  • fixed32
  • fixed64
  • lengthDelimited
  • group

Dieser Typ modelliert eine einzelne Feldnummer in ihrem Wert, anstatt alle Werte für eine gegebene Feldnummer zu gruppieren. Die APIs zum Erstellen neuer Felder sind die add* APIs der Klasse GPBUnknownFields.

Wir haben auch -[GPBMessage unknownFields] veraltet. An seiner Stelle gibt es neue APIs zum Extrahieren und Aktualisieren der unbekannten Felder der Nachricht.

Veraltete APIs entfernt

Wir haben die folgenden öffentlichen Runtime-APIs entfernt, die seit mindestens einer Minor- oder Major-Version als veraltet gekennzeichnet waren.

GPBFileDescriptor

API: -[GPBFileDescriptor syntax]

Ersatz: Obsolet.

GPBMessage mergeFrom:extensionRegistry

API: -[GPBMessage mergeFrom:extensionRegistry:]

Ersatz: -[GPBMessage mergeFrom:extensionRegistry:error:]

GPBDuration timeIntervalSince1970

API: -[GPBDuration timeIntervalSince1970]

Ersatz: -[GPBDuration timeInterval]

GPBTextFormatForUnknownFieldSet

API: GPBTextFormatForUnknownFieldSet()

Ersatz: Obsolet - Verwenden Sie GPBTextFormatForMessage(), das alle unbekannten Felder enthält.

GPBUnknownFieldSet

API: GPBUnknownFieldSet

Ersatz: GPBUnknownFields

GPBMessage unknownFields

API: GPBMessage unknownFields Property

Ersatz: -[GPBUnknownFields initFromMessage:], -[GPBMessage mergeUnknownFields:extensionRegistry:error:] und -[GPBMessage clearUnknownFields]

Veraltete Runtime-APIs für alten Gencode entfernt

Diese Version hat veraltete Runtime-Methoden entfernt, die den Objective-C-Gencode vor der Version 3.22.x unterstützten. Die Bibliothek gibt auch eine Protokollnachricht zur Laufzeit aus, wenn alter generierter Code gestartet wird.

API: +[GPBFileDescriptor allocDescriptorForClass:file:fields:fieldCount:storageSize:flags:]

Ersatz: Mit einer aktuellen Version der Bibliothek neu generieren.

API: +[GPBFileDescriptor allocDescriptorForClass:rootClass:file:fields:fieldCount:storageSize:flags:]

Ersatz: Mit einer aktuellen Version der Bibliothek neu generieren.

API: +[GPBEnumDescriptor allocDescriptorForName:valueNames:values:count:enumVerifier:]

Ersatz: Mit einer aktuellen Version der Bibliothek neu generieren.

API: +[GPBEnumDescriptor allocDescriptorForName:valueNames:values:count:enumVerifier:extraTextFormatInfo:]

Ersatz: Mit einer aktuellen Version der Bibliothek neu generieren.

API: -[GPBExtensionDescriptor initWithExtensionDescription:]

Ersatz: Mit einer aktuellen Version der Bibliothek neu generieren.

Poison-Pill-Warnungen

Wir haben Poison Pills aktualisiert, um Warnungen für alte Gencode + neue Runtime-Kombinationen auszugeben, die unter der neuen Rolling-Upgrade-Richtlinie funktionieren, aber im nächsten Major-Bump fehlschlagen werden. Zum Beispiel sollte Python 4.x.x Gencode gegen die Runtime 5.x.x funktionieren, aber vor zukünftigen Problemen mit der Runtime 6.x.x warnen.

Änderungen an der UTF-8-Erzwingung in C# und Ruby

Wir haben eine Korrektur aufgenommen, um die UTF-8-Erzwingung sprachübergreifend konsistent zu gestalten. Benutzer mit schlechten Nicht-UTF8-Daten in String-Feldern sehen möglicherweise früher aufgetretene UTF-8-Erzwingungsfehler.

Ruby- und PHP-Fehler bei der JSON-Analyse

Wir haben Nichtkonformitäten bei der JSON-Analyse von Strings in numerischen Feldern gemäß der JSON-Spezifikation behoben.

Diese Korrektur ist nicht mit einem Major-Versionssprung verbunden, aber Ruby und PHP lösen nun Fehler für nicht-numerische Strings (wie "", "12abc", "abc") in numerischen Feldern aus. v29.x enthält eine Warnung für diese Fehlerfälle.

Compiler-Änderungen in v22.0

JSON-Feldnamenskonflikte

Änderungsquelle: PR #11349, PR #10750

Wir haben einige subtile Änderungen an der Handhabung von Feldnamenskonflikten in Bezug auf JSON-Mappings vorgenommen. In proto3 haben wir die Einschränkungen teilweise gelockert und geben nur dann Fehler aus, wenn Feldnamen fallinsensitive JSON-Mappings ergeben (Camelcase des Originalnamens). Wir prüfen nun auch die json_name-Option und geben Fehler für fallinsensitive Konflikte aus. In proto2 haben wir die Einschränkungen etwas verschärft und geben Fehler aus, wenn zwei json_name-Spezifikationen kollidieren. Wenn implizite JSON-Mappings (Camelcase) Konflikte aufweisen, geben wir in proto2 Warnungen aus.

Wir haben eine temporäre Nachrichten-/Enum-Option zur Wiederherstellung des Legacy-Verhaltens bereitgestellt. Wenn die Umbenennung der kollidierenden Felder keine sofort umsetzbare Option ist, setzen Sie die Option deprecated_legacy_json_field_conflicts für die spezifische Nachricht/das Enum. Diese Option wird in einer zukünftigen Version entfernt, gibt Ihnen aber mehr Zeit zur Migration.

C++-API-Änderungen in v22.0

4.22.0 hat Breaking Changes für C++ Runtime und protoc, wie im August angekündigt.

Autotools eingestellt

Änderungsquelle: PR #10132

In v22.0 haben wir die gesamte Autotools-Unterstützung aus dem Protobuf-Compiler und der C++-Laufzeit entfernt. Wenn Sie Autotools zum Erstellen eines dieser verwenden, müssen Sie zu CMake oder Bazel migrieren. Wir haben einige spezielle Anweisungen zur Einrichtung von Protobuf mit CMake.

Abseil-Abhängigkeit

Änderungsquelle: PR #10416

Mit v22.0 haben wir eine explizite Abhängigkeit von Abseil übernommen. Dies ermöglichte uns, die meisten unserer Stubs zu entfernen, die von altem internem Code abgeleitet waren, der später zu Abseil wurde. Es gibt eine Reihe von subtilen Verhaltensänderungen, aber die meisten sollten für die Benutzer transparent sein. Einige bemerkenswerte Änderungen sind

  • string_view - absl::string_view hat const std::string& in vielen unserer APIs ersetzt. Dies wird am häufigsten für Eingabeargumente verwendet, wo für Benutzer keine spürbare Änderung auftreten sollte. In einigen Fällen (z. B. virtuelle Methodenargumente oder Rückgabetypen) müssen Benutzer möglicherweise eine explizite Änderung vornehmen, um die neue Signatur zu verwenden.

  • Tabellen - Anstelle von STL-Sets/Maps verwenden wir jetzt Abseils flat_hash_map, flat_hash_set, btree_map und btree_set. Diese sind effizienter und ermöglichen heterogene Lookups. Dies sollte für Benutzer größtenteils unsichtbar sein, kann jedoch zu einigen subtilen Verhaltensänderungen in Bezug auf die Tabellenreihenfolge führen.

  • Logging - Abseils Logging-Bibliothek ist der alten Logging-Code sehr ähnlich, mit nur einer leicht unterschiedlichen Schreibweise (z. B. ABSL_CHECK anstelle von GOOGLE_CHECK). Der größte Unterschied ist, dass sie keine Ausnahmen unterstützt und immer abstürzen wird, wenn FATAL-Assertions fehlschlagen. (Zuvor hatten wir eine PROTOBUF_USE_EXCEPTIONS-Flagge, um auf Ausnahmen umzuschalten.) Da diese nur bei schwerwiegenden Problemen auftreten, sind wir der Meinung, dass ein bedingungsloser Absturz eine geeignete Reaktion ist.

    Quelle der Logging-Änderungen: PR #11623

  • Build-Abhängigkeit - Eine neue Build-Abhängigkeit kann immer zu Problemen für nachgelagerte Benutzer führen. Wir benötigen Abseil LTS 20230125 oder neuer zum Erstellen.

    • Für Bazel-Builds wird Abseil automatisch heruntergeladen und mit einer festgelegten LTS-Version kompiliert, wenn protobuf_deps aus Ihrem WORKSPACE ausgeführt wird. Dies sollte transparent sein, aber wenn Sie von einer älteren Version von Abseil abhängig sind, müssen Sie Ihre Abhängigkeit aktualisieren.

    • Für CMake-Builds suchen wir zuerst nach einer bestehenden Abseil-Installation, die von der Top-Level-CMake-Konfiguration eingebunden wird (siehe Anweisungen). Andernfalls, wenn protobuf_ABSL_PROVIDER auf module gesetzt ist (Standard), versuchen wir, Abseil aus unserem Git-Submodul zu erstellen und zu verknüpfen. Wenn protobuf_ABSL_PROVIDER auf package gesetzt ist, suchen wir nach einer vorinstallierten Systemversion von Abseil.

Änderungen in der GetCurrentTime-Methode

Unter Windows ist GetCurrentTime() der Name eines Makros, das vom System bereitgestellt wird. Vor v22.x hat Protobuf die Makrodefinition für GetCurrentTime() fälschlicherweise entfernt. Das machte das Makro für Windows-Entwickler nach dem Einbinden von <protobuf/util/time_util.h> unbrauchbar. Ab v22.x behält Protobuf die Makrodefinition bei. Dies kann Kunden-Code brechen, der sich auf das vorherige Verhalten verlässt, z. B. wenn sie den Ausdruck google::protobuf::util::TimeUtil::GetCurrentTime() verwenden.

Um Ihre App auf das neue Verhalten zu migrieren, ändern Sie Ihren Code wie folgt:

  • wenn das GetCurrent-Makro definiert ist, definieren Sie das GetCurrentTime-Makro explizit neu
  • verhindern Sie die Makroexpansion, indem Sie (google::protobuf::util::TimeUtil::GetCurrentTime)() oder einen ähnlichen Ausdruck verwenden

Beispiel: Undefinieren des Makros

Verwenden Sie diesen Ansatz, wenn Sie das Makro unter Windows nicht verwenden.

Vorher

#include <google/protobuf/util/time_util.h>

void F() {
  auto time = google::protobuf::util::TimeUtil::GetCurrentTime();
}

Nachher

#include <google/protobuf/util/time_util.h>
#ifdef GetCurrentTime
#undef GetCurrentTime
#endif

void F() {
  auto time = google::protobuf::util::TimeUtil::GetCurrentTime();
}

Beispiel 2: Verhindern der Makroexpansion

Vorher

#include <google/protobuf/util/time_util.h>

void F() {
  auto time = google::protobuf::util::TimeUtil::GetCurrentTime();
}

Nachher

#include <google/protobuf/util/time_util.h>

void F() {
  auto time = (google::protobuf::util::TimeUtil::GetCurrentTime)();
}

C++20-Unterstützung

Änderungsquelle: PR #10796

Zur Unterstützung von C++20 haben wir die neuen Schlüsselwörter in generiertem C++-Protobuf-Code reserviert. Wie bei anderen reservierten Schlüsselwörtern werden wir bei Verwendung für Felder, Enums oder Nachrichten einen Unterstrich hinzufügen, um sie als gültiges C++ zu kennzeichnen. Ein concept-Feld generiert beispielsweise einen concept_() Getter. Wenn Sie vorhandene Protos haben, die diese Schlüsselwörter verwenden, müssen Sie den C++-Code, der darauf verweist, aktualisieren, um die entsprechenden Unterstriche hinzuzufügen.

Finale Klassen

Änderungsquelle: PR #11604

Als Teil einer größeren Anstrengung zur Härtung von Annahmen in der Protobuf-Bibliothek haben wir einige Klassen als final markiert, von denen nie beabsichtigt war, dass sie vererbt werden. Es gibt keine bekannten Anwendungsfälle für die Vererbung von diesen, und dies würde wahrscheinlich Probleme verursachen. Es gibt keine Abhilfe, wenn Ihr Code von diesen Klassen erbt, aber wenn Sie der Meinung sind, dass Sie einen gültigen Grund für die von Ihnen verwendete Vererbung haben, können Sie ein Problem eröffnen.

Container-Assertions

Änderungsquelle: PR #11550

Als Teil einer größeren Anstrengung zur Härtung von Annahmen in der Protobuf-Bibliothek haben wir statische Assertions zu den Map-, RepeatedField- und RepeatedPtrField-Containern hinzugefügt. Diese stellen sicher, dass Sie diese Container nur mit erwarteten Typen verwenden, wie in unserer Dokumentation beschrieben. Wenn Sie auf diese statischen Assertions stoßen, sollten Sie Ihren Code migrieren, um Abseil- oder STL-Container zu verwenden. std::vector ist ein guter Drop-in-Ersatz für wiederholte Feldcontainer und std::unordered_map oder absl::flat_hash_map für Map (ersteres bietet ähnliche Zeigerstabilität, während letzteres effizienter ist).

Gelöschte Element-Deprekation

Änderungsquelle: PR #11588, PR #11639

Die API von RepeatedPtrField für „gelöschte Felder“ wurde veraltet und wird in einer späteren Breaking-Version vollständig entfernt. Diese wurde ursprünglich als Optimierung zur Wiederverwendung von Elementen nach dem Löschen hinzugefügt, funktionierte aber nicht gut. Wenn Sie diese API verwenden, sollten Sie die Migration zu Arenen für eine bessere Wiederverwendung von Speicher in Betracht ziehen.

UnsafeArena-Deprekation

Änderungsquelle: PR #10325

Als Teil einer größeren Anstrengung zur Entfernung von Arena-unsicheren APIs haben wir RepeatedField::UnsafeArenaSwap ausgeblendet. Dies ist die einzige, die wir bisher entfernt haben, aber in späteren Versionen werden wir sie weiterhin entfernen und Helfer bereitstellen, um effiziente Borrowing-Muster zwischen Arenen zu handhaben. Innerhalb einer einzelnen Arena (oder Stack/Heap) ist Swap genauso effizient wie UnsafeArenaSwap. Der Vorteil ist, dass es keine ungültigen Speicheroperationen verursacht, wenn Sie es versehentlich zwischen verschiedenen Arenen aufrufen.

Map-Paar-Upgrades

Änderungsquelle: PR #11625

Für v22.0 haben wir mit der Bereinigung der Map-API begonnen, um sie konsistenter mit Abseil und STL zu machen. Insbesondere haben wir die MapPair-Klasse durch einen Alias für std::pair ersetzt. Dies sollte für die meisten Benutzer transparent sein, aber wenn Sie die Klasse direkt verwendet haben, müssen Sie möglicherweise Ihren Code aktualisieren.

Neuer JSON-Parser

Änderungsquelle: PR #10729

Wir haben den C++ JSON-Parser in dieser Version neu geschrieben. Dies sollte größtenteils eine verborgene Änderung sein, aber unvermeidlich könnten sich einige undokumentierte Eigenheiten geändert haben; testen Sie entsprechend. Die Analyse von Dokumenten, die kein gültiges RFC-8219 JSON sind (wie z. B. solche ohne Anführungszeichen oder mit nicht standardmäßigen Bools), ist veraltet und wird in einer zukünftigen Version entfernt. Die Serialisierungsreihenfolge der Felder entspricht nun garantiert der Reihenfolge der Feldnummern, während sie zuvor weniger deterministisch war.

Als Teil dieser Migration wurden alle Dateien unter util/internal gelöscht. Diese wurden im alten Parser verwendet und waren nie zur externen Nutzung vorgesehen.

Arena::Init

Änderungsquelle: PR #10623

Die Methode Init in Arena war Code, der nichts tat, und wurde nun entfernt. Wenn Sie diese Methode aufgerufen haben, meinten Sie wahrscheinlich, den Arena-Konstruktor direkt mit einem Satz von ArenaOptions aufzurufen. Sie sollten entweder den Aufruf löschen oder zu diesem Konstruktor migrieren.

ErrorCollector-Migration

Änderungsquelle: PR #11555

Als Teil unserer Abseil-Migration wechseln wir von const std::string& zu absl::string_view. Für unsere drei Fehlererfassungsklassen kann dies nicht ohne Breaking Changes für bestehenden Code geschehen. Für v22.0 haben wir beschlossen, beide Varianten zu veröffentlichen und die Methoden von AddError und AddWarning in RecordError und RecordWarning umzubenennen. Die alte Signatur wurde als veraltet gekennzeichnet und wird etwas weniger effizient sein (aufgrund von String-Kopien), aber ansonsten weiterhin funktionieren. Sie sollten diese auf die neue Version migrieren, da die Add*-Methoden in einer späteren Breaking-Version entfernt werden.