diff --git a/content/best-practices/api.md b/content/best-practices/api.md
index c954ec119..0b37d27d8 100644
--- a/content/best-practices/api.md
+++ b/content/best-practices/api.md
@@ -294,7 +294,7 @@ More generally, choose the right primitive type. See the Scalar Value Types
table in the
[Protocol Buffer Language Guide](/programming-guides/proto2#scalar).
-### Returning HTML in a Front-End Proto {#returning-html}
+### Don't Return HTML in a Front-End Proto {#returning-html}
With a JavaScript client, it's tempting to return HTML or
JSON in a field of your API. This is a slippery
@@ -408,7 +408,7 @@ message InternalPaginationToken {
}
```
-## Group Related Fields into a New Message. Nest Only Fields with High Cohesion {#group-related-fields}
+## Group Related Fields into a new `message`. Nest Only Fields with High Cohesion {#group-related-fields}
```proto
message Foo {
diff --git a/content/best-practices/dos-donts.md b/content/best-practices/dos-donts.md
index df9610aec..c89701585 100644
--- a/content/best-practices/dos-donts.md
+++ b/content/best-practices/dos-donts.md
@@ -38,6 +38,29 @@ no one accidentally re-uses it in the future. Just `reserved 2, 3;` is enough.
You can also reserve names to avoid recycling now-deleted value names: `reserved
"FOO", "BAR";`.
+
+
+## **Do** Put New Enum Aliases Last {#enum-aliases-last}
+
+When you add a new enum alias, put the new name last to give
+services time to pick it up.
+
+To safely remove the original name (if it's being used for interchange, which it
+[shouldn't](#text-format-interchange)), you must do the following:
+
+* Add the new name below the old name and deprecate the old one (serializers
+ will continue to use the old name)
+
+* After every parser has the schema rolled out, swap the order of the two
+ names (serializers will begin using the new name, parsers accept both)
+
+* After every serializer has that version of the schema, you can delete the
+ deprecated name.
+
+> **Note:** While in theory clients shouldn't be using the old name for
+> interchange, it's still polite to follow the above steps, especially for
+> widely-used enum names.
+
## **Don't** Change the Type of a Field {#change-type}
diff --git a/content/design-decisions/_index.md b/content/design-decisions/_index.md
new file mode 100644
index 000000000..2e1468b22
--- /dev/null
+++ b/content/design-decisions/_index.md
@@ -0,0 +1,17 @@
++++
+title = "Protobuf Team Design Decisions"
+weight = 88
+description = "Covers the design decisions the Protobuf team has made"
+type = "docs"
+no_list = "true"
+linkTitle = "Design Decisions"
++++
+
+This section contains some positions of the Protobuf team that inform our design
+and implementation decisions.
+
+These positions were taken after careful consideration and won't be overturned
+on a whim, but are open to being revisited as we gain new information, and as
+things develop in the broader ecosystem context.
+
+* [No Nullable Setters/Getters](/design-decisions/nullable-getters-setters)
diff --git a/content/programming-guides/nullable-getters-setters.md b/content/design-decisions/nullable-getters-setters.md
similarity index 90%
rename from content/programming-guides/nullable-getters-setters.md
rename to content/design-decisions/nullable-getters-setters.md
index e73766dcc..c0a427d23 100644
--- a/content/programming-guides/nullable-getters-setters.md
+++ b/content/design-decisions/nullable-getters-setters.md
@@ -3,6 +3,7 @@ title = "No Nullable Setters/Getters Support"
weight = 89
description = "Covers why Protobuf doesn't support nullable setters and getters"
type = "docs"
+aliases = "/programming-guides/nullable-getters-setters/"
+++
We have heard feedback that some folks would like protobuf to support nullable
@@ -15,6 +16,11 @@ The biggest reason not to have nullable fields is the intended behavior of
default values specified in a `.proto` file. By design, calling a getter on an
unset field will return the default value of that field.
+**Note:** C# does treat *message* fields as nullable. This inconsistency with
+other languages stems from the lack of immutable messages, which makes it
+impossible to create shared immutable default instances. Because message fields
+can't have defaults, there's no functional problem with this.
+
As an example, consider this `.proto` file:
```proto
diff --git a/content/installation.md b/content/installation.md
new file mode 100644
index 000000000..22781a227
--- /dev/null
+++ b/content/installation.md
@@ -0,0 +1,83 @@
++++
+title = "Protocol Buffer Compiler Installation"
+weight = 15
+description = "How to install the protocol buffer compiler."
+type = "docs"
+no_list = "true"
+linkTitle = "Protoc Installation"
++++
+
+The protocol buffer compiler, `protoc`, is used to compile `.proto` files, which
+contain service and message definitions. Choose one of the methods given below
+to install `protoc`.
+
+### Install Pre-compiled Binaries (Any OS) {#binary-install}
+
+To install the latest release of the protocol compiler from pre-compiled
+binaries, follow these instructions:
+
+1. From https://github.com/google/protobuf/releases, manually download the zip
+ file corresponding to your operating system and computer architecture
+ (`protoc---.zip`), or fetch the file using commands such
+ as the following:
+
+ ```sh
+ PB_REL="https://github.com/protocolbuffers/protobuf/releases"
+ curl -LO $PB_REL/download/v< param protoc-version >/protoc-< param protoc-version >-linux-x86_64.zip
+ ```
+
+2. Unzip the file under `$HOME/.local` or a directory of your choice. For
+ example:
+
+ ```sh
+ unzip protoc-< param protoc-version >-linux-x86_64.zip -d $HOME/.local
+ ```
+
+3. Update your environment's path variable to include the path to the `protoc`
+ executable. For example:
+
+ ```sh
+ export PATH="$PATH:$HOME/.local/bin"
+ ```
+
+### Install Using a Package Manager {#package-manager}
+
+{{% alert title="Warning" color="warning" %}} Run
+`protoc --version` to check the version of `protoc` after using a package
+manager for installation to ensure that it is sufficiently recent. The versions
+of `protoc` installed by some package managers can be quite dated. See the
+[Version Support page](https://protobuf.dev/support/version-support) to compare
+the output of the version check to the minor version number of the supported
+version of the language(s) you are
+using.{{% /alert %}}
+
+You can install the protocol compiler, `protoc`, with a package manager under
+Linux, macOS, or Windows using the following commands.
+
+- Linux, using `apt` or `apt-get`, for example:
+
+ ```sh
+ apt install -y protobuf-compiler
+ protoc --version # Ensure compiler version is 3+
+ ```
+
+- MacOS, using [Homebrew](https://brew.sh):
+
+ ```sh
+ brew install protobuf
+ protoc --version # Ensure compiler version is 3+
+ ```
+
+- Windows, using
+ [Winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/)
+
+ ```sh
+ > winget install protobuf
+ > protoc --version # Ensure compiler version is 3+
+ ```
+
+### Other Installation Options {#other}
+
+If you'd like to build the protocol compiler from sources, or access older
+versions of the pre-compiled binaries, see
+[Download Protocol Buffers](https://protobuf.dev/downloads).
diff --git a/content/news/v30.md b/content/news/v30.md
index 17b235ca9..f35755b01 100644
--- a/content/news/v30.md
+++ b/content/news/v30.md
@@ -55,7 +55,7 @@ be parseable by Protobuf TextFormat Parsers.
Read more about this in the
[news article released November 21, 2024](/news/2024-11-21).
-### Removing a a Reflection-related Function {#removing-mutable-repeated}
+### Removing a Reflection-related Function {#removing-mutable-repeated}
We are removing the following reflection-related function:
`MutableRepeatedFieldRef::Reserve()`.
diff --git a/content/programming-guides/deserialize-debug.md b/content/programming-guides/deserialize-debug.md
index 89c555099..49b05e19c 100644
--- a/content/programming-guides/deserialize-debug.md
+++ b/content/programming-guides/deserialize-debug.md
@@ -5,13 +5,14 @@ description = "How to log debugging information in Protocol Buffers."
type = "docs"
+++
-From version 29.x, `DebugString` APIs (`proto2::DebugString`,
-`proto2::ShortDebugString`, `proto2::Utf8DebugString`) are deprecated.
-DebugString users should migrate to some Abseil string functions (such as
-`absl::StrCat`, `absl::StrFormat`, `absl::StrAppend`, AND `absl::Substitute`),
-Abseil logging API, and some Protobuf APIs (`proto2::ShortFormat`,
-`proto2::Utf8Format`) to automatically convert proto arguments into a new
-debugging format .
+From version 30.x, Protobuf `DebugString` APIs (`Message::DebugString`,
+`Message::ShortDebugString`, `Message::Utf8DebugString`), additional Protobuf
+APIs (`proto2::ShortFormat`, `proto2::Utf8Format`), Abseil string functions
+(such as `absl::StrCat`, `absl::StrFormat`, `absl::StrAppend`, and
+`absl::Substitute`), and Abseil logging API will begin to automatically convert
+proto arguments into a new debugging format
+. See the related announcement
+[here](/news/2024-12-04/).
Unlike the Protobuf DebugString output format, the new debugging format
automatically redacts sensitive fields by replacing their values with the string
@@ -36,8 +37,7 @@ DebugString format in two ways:
"[REDACTED]" (without the quotes)
The new debugging format never removes any field names; it only replaces the
-value with
-"[REDACTED]" if the field is considered sensitive.
+value with "[REDACTED]" if the field is considered sensitive.
**If you don't see certain fields in the output, it is because those fields are
not set in the proto.**
@@ -83,8 +83,8 @@ systems can change and code gets re-used.
This is intentional. Don't attempt to parse the output of this debug format. We
reserve the right to change the syntax without notice. The debug format syntax
randomly changes per process to prevent inadvertent dependencies. If a syntactic
-change in the debug format would break your system, chances are you shouldn't
-use the debug representation of a proto.
+change in the debug format would break your system, chances are you should be
+using a TextFormat API rather than using the debug representation of a proto.
## FAQ
diff --git a/content/programming-guides/field_presence.md b/content/programming-guides/field_presence.md
index 5e7b5b76c..df940f700 100644
--- a/content/programming-guides/field_presence.md
+++ b/content/programming-guides/field_presence.md
@@ -52,7 +52,6 @@ deserializing wire-formatted messages:
- For enums, the default is the zero-valued enumerator.
- For strings, bytes, and repeated fields, the default is the zero-length
value.
- - For messages, the default is the language-specific null value.
- "Empty" length-delimited values (such as empty strings) can be validly
represented in serialized values: the field is "present," in the sense that
it appears in the wire format. However, if the generated API does not track
@@ -588,7 +587,7 @@ if (m.hasFoo()) {
Implicit presence:
```objective-c
-Msg *m = [[Msg alloc] init];
+Msg *m = [Msg message];
if (m.foo != 0) {
// "Clear" the field:
m.foo = 0;
@@ -601,13 +600,13 @@ if (m.foo != 0) {
Explicit presence:
```objective-c
-Msg *m = [[Msg alloc] init];
-if (m.hasFoo()) {
+Msg *m = [Msg message];
+if ([m hasFoo]) {
// Clear the field:
[m clearFoo];
} else {
// Field is not present, so set it.
- [m setFoo:1];
+ m.foo = 1;
}
```
@@ -639,9 +638,9 @@ Repeated field & map | no
Is field presence tracked?
-Field type | Tracked?
--------------------------------------------------- | --------
-Default | yes
-`features.field_presence` set to `LEGACY_REQUIRED` | yes
-`features.field_presence` set to `IMPLICIT` | no
-Repeated field & map | no
+Field type (in descending prescendence) | Tracked?
+-------------------------------------------------------------------- | --------
+Repeated field & map | no
+Message and Oneof fields | yes
+Other singular fields if `features.field_presence` set to `IMPLICIT` | no
+All other fields | yes
diff --git a/content/programming-guides/proto2.md b/content/programming-guides/proto2.md
index 61f059feb..9fab35ebc 100644
--- a/content/programming-guides/proto2.md
+++ b/content/programming-guides/proto2.md
@@ -2008,12 +2008,12 @@ Here are a few of the most commonly used options:
numeric type, it causes a more compact
[encoding](/programming-guides/encoding#packed) to be
used. The only reason to not use this option is if you need compatibility
- with parsers prior to version 2.3.0. When these older parsers would ignore
- packed data when it was not expected. Therefore, it was not possible to
- change an existing field to packed format without breaking wire
- compatibility. In 2.3.0 and later, this change is safe, as parsers for
- packable fields will always accept both formats, but be careful if you have
- to deal with old programs using old protobuf versions.
+ with parsers prior to version 2.3.0. These older parsers would ignore packed
+ data when it was not expected. Therefore, it was not possible to change an
+ existing field to packed format without breaking wire compatibility. In
+ 2.3.0 and later, this change is safe, as parsers for packable fields will
+ always accept both formats, but be careful if you have to deal with old
+ programs using old protobuf versions.
```proto
repeated int32 samples = 4 [packed = true];
diff --git a/content/reference/cpp/cpp-generated.md b/content/reference/cpp/cpp-generated.md
index 8b9d58f1d..20466ee13 100644
--- a/content/reference/cpp/cpp-generated.md
+++ b/content/reference/cpp/cpp-generated.md
@@ -102,8 +102,8 @@ The `Message` interface defines methods that let you check, manipulate, read, or
write the entire message, including parsing from and serializing to binary
strings.
-- `bool ParseFromString(const string& data)`: Parse the message from the given
- serialized binary string (also known as wire format).
+- `bool ParseFromString(::absl::string_view data)`: Parse the message from the
+ given serialized binary string (also known as wire format).
- `bool SerializeToString(string* output) const`: Serialize the given message
to a binary string.
- `string DebugString()`: Return a string giving the `text_format`
@@ -270,6 +270,12 @@ corresponding C++ type according to the
### Optional String/Bytes Fields (proto2 and proto3) {#string}
+**Note:** As of edition 2023, if
+[`features.(pb.cpp).string_type`](/editions/features#string_type)
+is set to `VIEW`,
+[string_view](/reference/cpp/string-view#singular-view)
+APIs will be generated instead.
+
For any of these field definitions:
```proto
@@ -284,18 +290,22 @@ The compiler will generate the following accessor methods:
- `bool has_foo() const`: Returns `true` if the field is set.
- `const string& foo() const`: Returns the current value of the field. If the
field is not set, returns the default value.
+- `void set_foo(::absl::string_view value)`: Sets the value of the field.
+ After calling this, `has_foo()` will return `true` and `foo()` will return a
+ copy of `value`.
- `void set_foo(const string& value)`: Sets the value of the field. After
calling this, `has_foo()` will return `true` and `foo()` will return a copy
of `value`.
-- `void set_foo(string&& value)` (C++11 and beyond): Sets the value of the
- field, moving from the passed string. After calling this, `has_foo()` will
- return `true` and `foo()` will return a copy of `value`.
+- `void set_foo(string&& value)`: Sets the value of the field, moving from the
+ passed string. After calling this, `has_foo()` will return `true` and
+ `foo()` will return a copy of `value`.
- `void set_foo(const char* value)`: Sets the value of the field using a
C-style null-terminated string. After calling this, `has_foo()` will return
`true` and `foo()` will return a copy of `value`.
-- `void set_foo(const char* value, int size)`: Like above, but the string size
- is given explicitly rather than determined by looking for a null-terminator
- byte.
+- `void set_foo(const char* value, int size)`: Sets the value of the field
+ using a string with an explicit size specified, rather than determined by
+ looking for a null-terminator byte. After calling this, `has_foo()` will
+ return `true` and `foo()` will return a copy of `value`.
- `string* mutable_foo()`: Returns a pointer to the mutable `string` object
that stores the field's value. If the field was not set prior to the call,
then the returned string will be empty (*not* the default value). After
@@ -321,6 +331,12 @@ The compiler will generate the following accessor methods:
### Implicit Presence String/Bytes Fields (proto3) {#implicit-string}
+**Note:** As of edition 2023, if
+[`features.(pb.cpp).string_type`](/editions/features#string_type)
+is set to `VIEW`,
+[string_view](/reference/cpp/string-view#singular-view)
+APIs will be generated instead.
+
For either of these field definitions:
```proto
@@ -332,17 +348,19 @@ The compiler will generate the following accessor methods:
- `const string& foo() const`: Returns the current value of the field. If the
field is not set, returns the empty string/empty bytes.
+- `void set_foo(::absl::string_view value)`: Sets the value of the field.
+ After calling this, `foo()` will return a copy of `value`.
- `void set_foo(const string& value)`: Sets the value of the field. After
calling this, `foo()` will return a copy of `value`.
-- `void set_foo(string&& value)` (C++11 and beyond): Sets the value of the
- field, moving from the passed string. After calling this, `foo()` will
- return a copy of `value`.
+- `void set_foo(string&& value)`: Sets the value of the field, moving from the
+ passed string. After calling this, `foo()` will return a copy of `value`.
- `void set_foo(const char* value)`: Sets the value of the field using a
C-style null-terminated string. After calling this, `foo()` will return a
copy of `value`.
-- `void set_foo(const char* value, int size)`: Like above, but the string size
- is given explicitly rather than determined by looking for a null-terminator
- byte.
+- `void set_foo(const char* value, int size)`: Sets the value of the field
+ using a string with an explicit size specified, rather than determined by
+ looking for a null-terminator byte. After calling this, `foo()` will return
+ a copy of `value`.
- `string* mutable_foo()`: Returns a pointer to the mutable `string` object
that stores the field's value. If the field was not set prior to the call,
then the returned string will be empty. After calling this, `foo()` will
@@ -532,6 +550,12 @@ corresponding C++ type according to the
### Repeated String Fields {#repeatedstring}
+**Note:** As of edition 2023, if
+[`features.(pb.cpp).string_type`](/editions/features#string_type)
+is set to `VIEW`,
+[string_view](/reference/cpp/string-view#singular-view)
+APIs will be generated instead.
+
For either of these field definitions:
```proto
@@ -548,24 +572,33 @@ The compiler will generate the following accessor methods:
- `const string& foo(int index) const`: Returns the element at the given
zero-based index. Calling this method with index outside of [0,
foo_size()-1] yields undefined behavior.
+- `void set_foo(int index, ::absl::string_view value)`: Sets the value of the
+ element at the given zero-based index.
- `void set_foo(int index, const string& value)`: Sets the value of the
element at the given zero-based index.
+- `void set_foo(int index, string&& value)`: Sets the value of the element at
+ the given zero-based index, moving from the passed string.
- `void set_foo(int index, const char* value)`: Sets the value of the element
at the given zero-based index using a C-style null-terminated string.
-- `void set_foo(int index, const char* value, int size)`: Like above, but the
- string size is given explicitly rather than determined by looking for a
+- `void set_foo(int index, const char* value, int size)`: Sets the value of
+ the element at the given zero-based index using a C-style string with an
+ explicit size specified, rather than determined by looking for a
null-terminator byte.
- `string* mutable_foo(int index)`: Returns a pointer to the mutable `string`
object that stores the value of the element at the given zero-based index.
Calling this method with index outside of [0, foo_size()) yields undefined
behavior.
+- `void add_foo(::absl::string_view value)`: Appends a new element to the end
+ of the element at the given zero-based index.
- `void add_foo(const string& value)`: Appends a new element to the end of the
field with the given value.
+- `void add_foo(string&& value)`: Appends a new element to the end of the
+ field, moving from the passed string.
- `void add_foo(const char* value)`: Appends a new element to the end of the
field using a C-style null-terminated string.
-- `void add_foo(const char* value, int size)`: Like above, but the string size
- is given explicitly rather than determined by looking for a null-terminator
- byte.
+- `void add_foo(const char* value, int size)`: Appends a new element to the
+ end of the field using a string with an explicit size specified, rather than
+ determined by looking for a null-terminator byte.
- `string* add_foo()`: Adds a new empty string element to the end of the field
and returns a pointer to it.
- `void clear_foo()`: Removes all elements from the field. After calling this,
@@ -696,6 +729,10 @@ corresponding C++ type according to the
### Oneof String Fields {#oneof-string}
+**Note:** As of edition 2023
+[string_view](/reference/cpp/string-view#oneof-view) APIs
+may be generated instead
+
For any of these [oneof](#oneof) field definitions:
```proto
@@ -714,22 +751,21 @@ The compiler will generate the following accessor methods:
- `bool has_foo() const`: Returns `true` if the oneof case is `kFoo`.
- `const string& foo() const`: Returns the current value of the field if the
oneof case is `kFoo`. Otherwise, returns the default value.
-- `void set_foo(const string& value)`:
+- `void set_foo(::absl::string_view value)`:
- If any other oneof field in the same oneof is set, calls
`clear_example_name()`.
- Sets the value of this field and sets the oneof case to `kFoo`.
- `has_foo()` will return `true`, `foo()` will return a copy of `value`
and `example_name_case()` will return `kFoo`.
-- `void set_foo(const char* value)`:
- - If any other oneof field in the same oneof is set, calls
- `clear_example_name()`.
- - Sets the value of the field using a C-style null-terminated string and
- set the oneof case to `kFoo`.
- - `has_foo()` will return `true`, `foo()` will return a copy of `value`
- and `example_name_case()` will return `kFoo`.
-- `void set_foo(const char* value, int size)`: Like above, but the string size
- is given explicitly rather than determined by looking for a null-terminator
- byte.
+- `void set_foo(const string& value)`: Like the first `set_foo()`, but copies
+ from a const string reference.
+- `void set_foo(string&& value)`: Like the first `set_foo()`, but moving from
+ the passed string.
+- `void set_foo(const char* value)`: Like the first `set_foo()`, but copies
+ from a C-style null-terminated string.
+- `void set_foo(const char* value, int size)`: Like the first `set_foo()`, but
+ copies from a string with an explicit size specified, rather than determined
+ by looking for a null-terminator byte.
- `string* mutable_foo()`:
- If any other oneof field in the same oneof is set, calls
`clear_example_name()`.
@@ -1005,7 +1041,7 @@ class Any {
// Packs the given message into this Any using the given type URL
// prefix. Returns false if serializing the message failed.
bool PackFrom(const google::protobuf::Message& message,
- const string& type_url_prefix);
+ ::absl::string_view type_url_prefix);
// Unpacks this Any to a Message. Returns false if this Any
// represents a different protobuf type or parsing fails.
@@ -1048,6 +1084,11 @@ In addition, it will generate these methods:
## Enumerations {#enum}
+**Note:** As of edition 2024, `string_view` APIs may be generated with certain
+feature settings. See
+[Enumeration Name Helper](/reference/cpp/string-view#enum-name)
+for more on this topic.
+
Given an enum definition like:
```proto
@@ -1071,8 +1112,8 @@ functions:
value. Returns an empty string if no such value exists. If multiple values
have this number, the first one defined is returned. In the above example,
`Foo_Name(5)` would return `"VALUE_B"`.
-- `bool Foo_Parse(const string& name, Foo* value)`: If `name` is a valid value
- name for this enum, assigns that value into `value` and returns true.
+- `bool Foo_Parse(::absl::string_view name, Foo* value)`: If `name` is a valid
+ value name for this enum, assigns that value into `value` and returns true.
Otherwise returns false. In the above example, `Foo_Parse("VALUE_C",
&some_foo)` would return true and set `some_foo` to 1234.
- `const Foo Foo_MIN`: the smallest valid value of the enum (VALUE_A in the
diff --git a/content/reference/cpp/string-view.md b/content/reference/cpp/string-view.md
new file mode 100644
index 000000000..da38053c0
--- /dev/null
+++ b/content/reference/cpp/string-view.md
@@ -0,0 +1,185 @@
++++
+title = "String View APIs"
+weight = 510
+description = "Covers various string_view migrations"
+type = "docs"
++++
+
+C++ string field APIs that use `std::string` significantly constrain the
+internal protobuf implementation and its evolution. For example,
+`mutable_string_field()` returns `std::string*` that forces us to use
+`std::string` to store the field. This complicates its interaction on arenas and
+we have to maintain arena donation states to track whether string payload
+allocation is from arena or heap.
+
+Long-term, we would like to migrate all of our runtime and generated APIs to
+accept `string_view` as inputs and return them from accessors. This document
+describes the state of the migration as of our 30.x release.
+
+## String Field Accessors {#string-type}
+
+As part of edition 2023, the
+[`string_type`](/editions/features#string_type) feature
+was released with a `VIEW` option to allow for the incremental migration to
+generated `string_view` APIs. Using this feature will affect the
+[C++ Generated Code](/reference/cpp/cpp-generated) of
+`string` and `bytes` fields.
+
+### Interaction with ctype {#ctype}
+
+In edition 2023, you can still specify `ctype` at the field level, while you can
+specify `string_type` at either the file or field level. It is not allowed to
+specify both on the same field. If `string_type` is set at the file-level,
+`ctype` specified on fields will take precedent.
+
+Except for the `VIEW` option, all possible values of `string_type` have a
+corresponding `ctype` value that is spelled the same and gives the same
+behavior. For example, both enums have a `CORD` value.
+
+In edition 2024 and beyond, it will no longer be possible to specify `ctype`.
+
+### Generated Singular Fields {#singular-view}
+
+For either of these field definitions in edition 2023:
+
+```proto
+bytes foo = 1 [features.(pb.cpp).string_type=VIEW];
+string foo = 1 [features.(pb.cpp).string_type=VIEW];
+```
+
+The compiler will generate the following accessor methods:
+
+- `::absl::string_view foo() const`: Returns the current value of the field.
+ If the field is not set, returns the default value.
+- `void clear_foo()`: Clears the value of the field. After calling this,
+ `foo()` will return the default value.
+- `bool has_foo()`: Returns `true` if the field is set.
+- `void set_foo(::absl::string_view value)`: Sets the value of the field.
+ After calling this, `has_foo()` will return `true` and `foo()` will return a
+ copy of `value`.
+- `void set_foo(const string& value)`: Sets the value of the field. After
+ calling this, `has_foo()` will return `true` and `foo()` will return a copy
+ of `value`.
+- `void set_foo(string&& value)`: Sets the value of the field, moving from the
+ passed string. After calling this, `has_foo()` will return `true` and
+ `foo()` will return `value`.
+- `void set_foo(const char* value)`: Sets the value of the field using a
+ C-style null-terminated string. After calling this, `has_foo()` will return
+ `true` and `foo()` will return a copy of `value`.
+
+### Generated Repeated Fields {#repeated-view}
+
+For either of these field definitions:
+
+```proto
+repeated string foo = 1 [features.(pb.cpp).string_type=VIEW];
+repeated bytes foo = 1 [features.(pb.cpp).string_type=VIEW];
+```
+
+The compiler will generate the following accessor methods:
+
+- `int foo_size() const`: Returns the number of elements currently in the
+ field.
+- `::absl::string_view foo(int index) const`: Returns the element at the given
+ zero-based index. Calling this method with index outside of `[0,
+ foo_size()-1]` yields undefined behavior.
+- `void set_foo(int index, ::absl::string_view value)`: Sets the value of the
+ element at the given zero-based index.
+- `void set_foo(int index, const string& value)`: Sets the value of the
+ element at the given zero-based index.
+- `void set_foo(int index, string&& value)`: Sets the value of the element at
+ the given zero-based index, moving from the passed string.
+- `void set_foo(int index, const char* value)`: Sets the value of the element
+ at the given zero-based index using a C-style null-terminated string.
+- `void add_foo(::absl::string_view value)`: Appends a new element to the end
+ of the field with the given value.
+- `void add_foo(const string& value)`: Appends a new element to the end of the
+ field with the given value.
+- `void add_foo(string&& value)`: Appends a new element to the end of the
+ field, moving from the passed string.
+- `void add_foo(const char* value)`: Appends a new element to the end of the
+ field using a C-style null-terminated string.
+- `void clear_foo()`: Removes all elements from the field. After calling this,
+ `foo_size()` will return zero.
+- `const RepeatedPtrField& foo() const`: Returns the underlying
+ [`RepeatedPtrField`](/reference/cpp/api-docs/google.protobuf.repeated_field#RepeatedPtrField)
+ that stores the field's elements. This container class provides STL-like
+ iterators and other methods.
+- `RepeatedPtrField* mutable_foo()`: Returns a pointer to the
+ underlying mutable `RepeatedPtrField` that stores the field's elements. This
+ container class provides STL-like iterators and other methods.
+
+### Generated Oneof Fields {#oneof-view}
+
+For any of these [oneof](#oneof) field definitions:
+
+```proto
+oneof example_name {
+ string foo = 1 [features.(pb.cpp).string_type=VIEW];
+ ...
+}
+oneof example_name {
+ bytes foo = 1 [features.(pb.cpp).string_type=VIEW];
+ ...
+}
+```
+
+The compiler will generate the following accessor methods:
+
+- `bool has_foo() const`: Returns `true` if the oneof case is `kFoo`.
+- `::absl::string_view foo() const`: Returns the current value of the field if
+ the oneof case is `kFoo`. Otherwise, returns the default value.
+- `void set_foo(::absl::string_view value)`:
+ - If any other oneof field in the same oneof is set, calls
+ `clear_example_name()`.
+ - Sets the value of this field and sets the oneof case to `kFoo`.
+ - `has_foo()` will return `true`, `foo()` will return a copy of `value`
+ and `example_name_case()` will return `kFoo`.
+- `void set_foo(const string& value)`: Like the first `set_foo()`, but copies
+ from a `const string` reference.
+- `void set_foo(string&& value)`: Like the first `set_foo()`, but moving from
+ the passed string.
+- `void set_foo(const char* value)`: Like the first `set_foo()`, but copies
+ from a C-style null-terminated string.
+- `void clear_foo()`:
+ - If the oneof case is not `kFoo`, nothing will be changed.
+ - If the oneof case is `kFoo`, frees the field and clears the oneof case.
+ `has_foo()` will return `false`, `foo()` will return the default value,
+ and `example_name_case()` will return `EXAMPLE_NAME_NOT_SET`.
+
+## Enumeration Name Helper {#enum-name}
+
+Beginning in edition 2024, a new feature `enum_name_uses_string_view` is
+introduced and defaults to true. Unless disabled, for an enum like:
+
+```proto
+enum Foo {
+ VALUE_A = 0;
+ VALUE_B = 5;
+ VALUE_C = 1234;
+}
+```
+
+The protocol buffer compiler, in addition to the `Foo` enum, will generate the
+following new function in addition to the standard
+[generated code](/reference/cpp/cpp-generated#enum):
+
+- `::absl::string_view Foo_Name(int value)`: Returns the name for given
+ numeric value. Returns an empty string if no such value exists. If multiple
+ values have this number, the first one defined is returned. In the above
+ example, `Foo_Name(5)` would return `VALUE_B`.
+
+This can be reverted back to the old behavior by adding a feature override like:
+
+```proto
+enum Foo {
+ option features.(pb.cpp).enum_name_uses_string_view = false;
+
+ VALUE_A = 0;
+ VALUE_B = 5;
+ VALUE_C = 1234;
+}
+```
+
+In which case the name helper will switch back to `const string& Foo_Name(int
+value)`.
diff --git a/content/reference/rust/rust-generated.md b/content/reference/rust/rust-generated.md
index 5369b54a5..946dd9591 100644
--- a/content/reference/rust/rust-generated.md
+++ b/content/reference/rust/rust-generated.md
@@ -514,7 +514,7 @@ emitted for the `oneof` block:
#[non_exhaustive]
#[derive(Debug, Clone, Copy)]
- pub enum ExampleName<'msg> {
+ pub enum ExampleNameOneof<'msg> {
FooInt(i32) = 4,
FooString(&'msg protobuf::ProtoStr) = 9,
not_set(std::marker::PhantomData<&'msg ()>) = 0
@@ -533,7 +533,7 @@ emitted for the `oneof` block:
Additionally, it will generate the two accessors:
-* `fn example_name(&self) -> ExampleName<_>`: Returns the enum variant
+* `fn example_name(&self) -> ExampleNameOneof<_>`: Returns the enum variant
indicating which field is set and the field's value. Returns `not_set` if no
field is set.
* `fn example_name_case(&self) -> ExampleNameCase`: Returns the enum variant
diff --git a/go.mod b/go.mod
index 1000f68d3..3b0bc6188 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,6 @@ go 1.12
require (
github.com/FortAwesome/Font-Awesome v0.0.0-20220831210243-d3a7818c253f // indirect
- github.com/google/docsy v0.5.1 // indirect
+ github.com/google/docsy v0.11.0 // indirect
github.com/twbs/bootstrap v4.6.2+incompatible // indirect
)